summaryrefslogtreecommitdiff
path: root/tools/glade/glade
diff options
context:
space:
mode:
Diffstat (limited to 'tools/glade/glade')
-rw-r--r--tools/glade/glade/Makefile.am105
-rw-r--r--tools/glade/glade/data/Makefile.am2
-rw-r--r--tools/glade/glade/data/gtk/Makefile.am11
-rw-r--r--tools/glade/glade/data/gtk/autogen.sh159
-rw-r--r--tools/glade/glade/debug.c106
-rw-r--r--tools/glade/glade/debug.h87
-rw-r--r--tools/glade/glade/editor.c3598
-rw-r--r--tools/glade/glade/editor.h107
-rw-r--r--tools/glade/glade/gb.c162
-rw-r--r--tools/glade/glade/gb.h426
-rw-r--r--tools/glade/glade/gbsource.c1222
-rw-r--r--tools/glade/glade/gbsource.h191
-rw-r--r--tools/glade/glade/gbwidget.c4434
-rw-r--r--tools/glade/glade/gbwidget.h626
-rw-r--r--tools/glade/glade/gbwidgets/Makefile.am93
-rw-r--r--tools/glade/glade/gbwidgets/gbaboutdialog.c602
-rw-r--r--tools/glade/glade/gbwidgets/gbaccellabel.c214
-rw-r--r--tools/glade/glade/gbwidgets/gbalignment.c268
-rw-r--r--tools/glade/glade/gbwidgets/gbarrow.c312
-rw-r--r--tools/glade/glade/gbwidgets/gbaspectframe.c335
-rw-r--r--tools/glade/glade/gbwidgets/gbbutton.c1612
-rw-r--r--tools/glade/glade/gbwidgets/gbcalendar.c280
-rw-r--r--tools/glade/glade/gbwidgets/gbcellview.c206
-rw-r--r--tools/glade/glade/gbwidgets/gbcheckbutton.c223
-rw-r--r--tools/glade/glade/gbwidgets/gbcheckmenuitem.c214
-rw-r--r--tools/glade/glade/gbwidgets/gbclist.c610
-rw-r--r--tools/glade/glade/gbwidgets/gbcolorbutton.c225
-rw-r--r--tools/glade/glade/gbwidgets/gbcolorselection.c186
-rw-r--r--tools/glade/glade/gbwidgets/gbcolorselectiondialog.c331
-rw-r--r--tools/glade/glade/gbwidgets/gbcombo.c439
-rw-r--r--tools/glade/glade/gbwidgets/gbcombobox.c303
-rw-r--r--tools/glade/glade/gbwidgets/gbcomboboxentry.c316
-rw-r--r--tools/glade/glade/gbwidgets/gbctree.c554
-rw-r--r--tools/glade/glade/gbwidgets/gbcurve.c263
-rw-r--r--tools/glade/glade/gbwidgets/gbcustom.c395
-rw-r--r--tools/glade/glade/gbwidgets/gbdialog.c621
-rw-r--r--tools/glade/glade/gbwidgets/gbdrawingarea.c159
-rw-r--r--tools/glade/glade/gbwidgets/gbentry.c331
-rw-r--r--tools/glade/glade/gbwidgets/gbeventbox.c180
-rw-r--r--tools/glade/glade/gbwidgets/gbexpander.c242
-rw-r--r--tools/glade/glade/gbwidgets/gbfilechooserbutton.c309
-rw-r--r--tools/glade/glade/gbwidgets/gbfilechooserdialog.c451
-rw-r--r--tools/glade/glade/gbwidgets/gbfilechooserwidget.c274
-rw-r--r--tools/glade/glade/gbwidgets/gbfileselection.c308
-rw-r--r--tools/glade/glade/gbwidgets/gbfixed.c246
-rw-r--r--tools/glade/glade/gbwidgets/gbfontbutton.c282
-rw-r--r--tools/glade/glade/gbwidgets/gbfontselection.c184
-rw-r--r--tools/glade/glade/gbwidgets/gbfontselectiondialog.c317
-rw-r--r--tools/glade/glade/gbwidgets/gbframe.c375
-rw-r--r--tools/glade/glade/gbwidgets/gbgammacurve.c269
-rw-r--r--tools/glade/glade/gbwidgets/gbhandlebox.c317
-rw-r--r--tools/glade/glade/gbwidgets/gbhbox.c587
-rw-r--r--tools/glade/glade/gbwidgets/gbhbuttonbox.c428
-rw-r--r--tools/glade/glade/gbwidgets/gbhpaned.c332
-rw-r--r--tools/glade/glade/gbwidgets/gbhruler.c260
-rw-r--r--tools/glade/glade/gbwidgets/gbhscale.c332
-rw-r--r--tools/glade/glade/gbwidgets/gbhscrollbar.c250
-rw-r--r--tools/glade/glade/gbwidgets/gbhseparator.c157
-rw-r--r--tools/glade/glade/gbwidgets/gbiconview.c322
-rw-r--r--tools/glade/glade/gbwidgets/gbimage.c662
-rw-r--r--tools/glade/glade/gbwidgets/gbimagemenuitem.c486
-rw-r--r--tools/glade/glade/gbwidgets/gbinputdialog.c273
-rw-r--r--tools/glade/glade/gbwidgets/gblabel.c885
-rw-r--r--tools/glade/glade/gbwidgets/gblayout.c399
-rw-r--r--tools/glade/glade/gbwidgets/gblist.c205
-rw-r--r--tools/glade/glade/gbwidgets/gblistitem.c182
-rw-r--r--tools/glade/glade/gbwidgets/gbmenu.c211
-rw-r--r--tools/glade/glade/gbwidgets/gbmenubar.c552
-rw-r--r--tools/glade/glade/gbwidgets/gbmenuitem.c393
-rw-r--r--tools/glade/glade/gbwidgets/gbmenutoolbutton.c269
-rw-r--r--tools/glade/glade/gbwidgets/gbnotebook.c954
-rw-r--r--tools/glade/glade/gbwidgets/gboptionmenu.c285
-rw-r--r--tools/glade/glade/gbwidgets/gbpreview.c175
-rw-r--r--tools/glade/glade/gbwidgets/gbprogressbar.c433
-rw-r--r--tools/glade/glade/gbwidgets/gbradiobutton.c477
-rw-r--r--tools/glade/glade/gbwidgets/gbradiomenuitem.c399
-rw-r--r--tools/glade/glade/gbwidgets/gbradiotoolbutton.c545
-rw-r--r--tools/glade/glade/gbwidgets/gbscrolledwindow.c366
-rw-r--r--tools/glade/glade/gbwidgets/gbseparatormenuitem.c166
-rw-r--r--tools/glade/glade/gbwidgets/gbseparatortoolitem.c218
-rw-r--r--tools/glade/glade/gbwidgets/gbspinbutton.c297
-rw-r--r--tools/glade/glade/gbwidgets/gbstatusbar.c169
-rw-r--r--tools/glade/glade/gbwidgets/gbtable.c1223
-rw-r--r--tools/glade/glade/gbwidgets/gbtextview.c479
-rw-r--r--tools/glade/glade/gbwidgets/gbtogglebutton.c211
-rw-r--r--tools/glade/glade/gbwidgets/gbtoggletoolbutton.c312
-rw-r--r--tools/glade/glade/gbwidgets/gbtoolbar.c696
-rw-r--r--tools/glade/glade/gbwidgets/gbtoolbutton.c602
-rw-r--r--tools/glade/glade/gbwidgets/gbtoolitem.c215
-rw-r--r--tools/glade/glade/gbwidgets/gbtreeview.c331
-rw-r--r--tools/glade/glade/gbwidgets/gbvbox.c261
-rw-r--r--tools/glade/glade/gbwidgets/gbvbuttonbox.c357
-rw-r--r--tools/glade/glade/gbwidgets/gbviewport.c253
-rw-r--r--tools/glade/glade/gbwidgets/gbvpaned.c209
-rw-r--r--tools/glade/glade/gbwidgets/gbvruler.c260
-rw-r--r--tools/glade/glade/gbwidgets/gbvscale.c332
-rw-r--r--tools/glade/glade/gbwidgets/gbvscrollbar.c249
-rw-r--r--tools/glade/glade/gbwidgets/gbvseparator.c157
-rw-r--r--tools/glade/glade/gbwidgets/gbwindow.c1246
-rw-r--r--tools/glade/glade/glade-parser.c1415
-rw-r--r--tools/glade/glade/glade-parser.h140
-rw-r--r--tools/glade/glade/glade.c482
-rw-r--r--tools/glade/glade/glade.h180
-rw-r--r--tools/glade/glade/glade_atk.c1662
-rw-r--r--tools/glade/glade/glade_atk.h71
-rw-r--r--tools/glade/glade/glade_clipboard.c654
-rw-r--r--tools/glade/glade/glade_clipboard.h77
-rw-r--r--tools/glade/glade/glade_gnome.c1032
-rw-r--r--tools/glade/glade/glade_gnome.h111
-rw-r--r--tools/glade/glade/glade_gnomedblib.c96
-rw-r--r--tools/glade/glade/glade_gnomedblib.h36
-rw-r--r--tools/glade/glade/glade_gnomelib.c127
-rw-r--r--tools/glade/glade/glade_gnomelib.h37
-rw-r--r--tools/glade/glade/glade_gtk12lib.c256
-rw-r--r--tools/glade/glade/glade_gtk12lib.h34
-rw-r--r--tools/glade/glade/glade_keys_dialog.c254
-rw-r--r--tools/glade/glade/glade_keys_dialog.h86
-rw-r--r--tools/glade/glade/glade_menu_editor.c3729
-rw-r--r--tools/glade/glade/glade_menu_editor.h138
-rw-r--r--tools/glade/glade/glade_palette.c544
-rw-r--r--tools/glade/glade/glade_palette.h150
-rw-r--r--tools/glade/glade/glade_plugin.c176
-rw-r--r--tools/glade/glade/glade_plugin.h52
-rw-r--r--tools/glade/glade/glade_project.c1992
-rw-r--r--tools/glade/glade/glade_project.h373
-rw-r--r--tools/glade/glade/glade_project_options.c1433
-rw-r--r--tools/glade/glade/glade_project_options.h142
-rw-r--r--tools/glade/glade/glade_project_view.c311
-rw-r--r--tools/glade/glade/glade_project_view.h85
-rw-r--r--tools/glade/glade/glade_project_window.c2108
-rw-r--r--tools/glade/glade/glade_project_window.h77
-rw-r--r--tools/glade/glade/glade_widget_data.c408
-rw-r--r--tools/glade/glade/glade_widget_data.h145
-rw-r--r--tools/glade/glade/gladeconfig.h64
-rw-r--r--tools/glade/glade/gnome-db/Makefile.am23
-rw-r--r--tools/glade/glade/gnome-db/gnomedbcombo.c136
-rw-r--r--tools/glade/glade/gnome-db/gnomedbconnectprop.c93
-rw-r--r--tools/glade/glade/gnome-db/gnomedbdsnconfig.c147
-rw-r--r--tools/glade/glade/gnome-db/gnomedbdsndruid.c161
-rw-r--r--tools/glade/glade/gnome-db/gnomedbeditor.c188
-rw-r--r--tools/glade/glade/gnome-db/gnomedberror.c148
-rw-r--r--tools/glade/glade/gnome-db/gnomedberrordlg.c232
-rw-r--r--tools/glade/glade/gnome-db/gnomedbform.c161
-rw-r--r--tools/glade/glade/gnome-db/gnomedbgraybar.c149
-rw-r--r--tools/glade/glade/gnome-db/gnomedbgrid.c144
-rw-r--r--tools/glade/glade/gnome-db/gnomedblogin.c148
-rw-r--r--tools/glade/glade/gnome-db/gnomedblogindlg.c234
-rw-r--r--tools/glade/glade/gnome-db/gnomedbprovidersel.c161
-rw-r--r--tools/glade/glade/gnome-db/gnomedbsourcesel.c161
-rw-r--r--tools/glade/glade/gnome-db/gnomedbtableeditor.c144
-rw-r--r--tools/glade/glade/gnome/Makefile.am33
-rw-r--r--tools/glade/glade/gnome/bonobodock.c510
-rw-r--r--tools/glade/glade/gnome/bonobodockitem.c786
-rw-r--r--tools/glade/glade/gnome/gnomeabout.c554
-rw-r--r--tools/glade/glade/gnome/gnomeapp.c461
-rw-r--r--tools/glade/glade/gnome/gnomeappbar.c198
-rw-r--r--tools/glade/glade/gnome/gnomecanvas.c263
-rw-r--r--tools/glade/glade/gnome/gnomecolorpicker.c233
-rw-r--r--tools/glade/glade/gnome/gnomecontrol.c757
-rw-r--r--tools/glade/glade/gnome/gnomedateedit.c313
-rw-r--r--tools/glade/glade/gnome/gnomedialog.c358
-rw-r--r--tools/glade/glade/gnome/gnomedruid.c499
-rw-r--r--tools/glade/glade/gnome/gnomedruidpageedge.c537
-rw-r--r--tools/glade/glade/gnome/gnomedruidpagestandard.c463
-rw-r--r--tools/glade/glade/gnome/gnomeentry.c225
-rw-r--r--tools/glade/glade/gnome/gnomefileentry.c382
-rw-r--r--tools/glade/glade/gnome/gnomefontpicker.c406
-rw-r--r--tools/glade/glade/gnome/gnomehref.c220
-rw-r--r--tools/glade/glade/gnome/gnomeiconentry.c222
-rw-r--r--tools/glade/glade/gnome/gnomeiconlist.c475
-rw-r--r--tools/glade/glade/gnome/gnomeiconselection.c168
-rw-r--r--tools/glade/glade/gnome/gnomemessagebox.c515
-rw-r--r--tools/glade/glade/gnome/gnomepixmap.c361
-rw-r--r--tools/glade/glade/gnome/gnomepixmapentry.c319
-rw-r--r--tools/glade/glade/gnome/gnomepropertybox.c383
-rw-r--r--tools/glade/glade/graphics/aboutdialog.xpm34
-rw-r--r--tools/glade/glade/graphics/accellabel.xpm26
-rw-r--r--tools/glade/glade/graphics/alignment.xpm33
-rw-r--r--tools/glade/glade/graphics/arrow.xpm32
-rw-r--r--tools/glade/glade/graphics/aspectframe.xpm33
-rw-r--r--tools/glade/glade/graphics/bonobo-dock-item.xpm29
-rw-r--r--tools/glade/glade/graphics/bonobo-dock.xpm29
-rw-r--r--tools/glade/glade/graphics/button.xpm29
-rw-r--r--tools/glade/glade/graphics/calendar.xpm29
-rw-r--r--tools/glade/glade/graphics/cellview.xpm27
-rw-r--r--tools/glade/glade/graphics/checkbutton.xpm30
-rw-r--r--tools/glade/glade/graphics/checkmenuitem.xpm28
-rw-r--r--tools/glade/glade/graphics/clist.xpm28
-rw-r--r--tools/glade/glade/graphics/colorbutton.xpm31
-rw-r--r--tools/glade/glade/graphics/colorseldialog.xpm39
-rw-r--r--tools/glade/glade/graphics/colorselection.xpm35
-rw-r--r--tools/glade/glade/graphics/combo.xpm34
-rw-r--r--tools/glade/glade/graphics/combobox.xpm33
-rw-r--r--tools/glade/glade/graphics/comboboxentry.xpm34
-rw-r--r--tools/glade/glade/graphics/ctree.xpm30
-rw-r--r--tools/glade/glade/graphics/curve.xpm32
-rw-r--r--tools/glade/glade/graphics/custom.xpm30
-rw-r--r--tools/glade/glade/graphics/custom_bg.xpm15
-rw-r--r--tools/glade/glade/graphics/dialog.xpm38
-rw-r--r--tools/glade/glade/graphics/drawingarea.xpm33
-rw-r--r--tools/glade/glade/graphics/entry.xpm33
-rw-r--r--tools/glade/glade/graphics/eventbox.xpm34
-rw-r--r--tools/glade/glade/graphics/expander.xpm27
-rw-r--r--tools/glade/glade/graphics/filechooserbutton.xpm30
-rw-r--r--tools/glade/glade/graphics/filechooserdialog.xpm34
-rw-r--r--tools/glade/glade/graphics/filechooserwidget.xpm29
-rw-r--r--tools/glade/glade/graphics/fileseldialog.xpm34
-rw-r--r--tools/glade/glade/graphics/fixed.xpm29
-rw-r--r--tools/glade/glade/graphics/fontbutton.xpm31
-rw-r--r--tools/glade/glade/graphics/fontsel.xpm35
-rw-r--r--tools/glade/glade/graphics/fontseldialog.xpm40
-rw-r--r--tools/glade/glade/graphics/frame.xpm33
-rw-r--r--tools/glade/glade/graphics/gammacurve.xpm33
-rw-r--r--tools/glade/glade/graphics/glade-atk.xpm112
-rw-r--r--tools/glade/glade/graphics/glade_logo.pngbin0 -> 11013 bytes
-rw-r--r--tools/glade/glade/graphics/gnome-about.xpm34
-rw-r--r--tools/glade/glade/graphics/gnome-animator.xpm32
-rw-r--r--tools/glade/glade/graphics/gnome-app.xpm34
-rw-r--r--tools/glade/glade/graphics/gnome-appbar.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-calculator.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-canvas.xpm31
-rw-r--r--tools/glade/glade/graphics/gnome-colorpicker.xpm31
-rw-r--r--tools/glade/glade/graphics/gnome-control.xpm30
-rw-r--r--tools/glade/glade/graphics/gnome-dateedit.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-browser.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-combo.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-connection-properties.xpm94
-rw-r--r--tools/glade/glade/graphics/gnome-db-connectsel.xpm30
-rw-r--r--tools/glade/glade/graphics/gnome-db-dataset.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-designer.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-dsn-druid.xpm32
-rw-r--r--tools/glade/glade/graphics/gnome-db-dsnconfig.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-editor.xpm32
-rw-r--r--tools/glade/glade/graphics/gnome-db-entry.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-error-dlg.xpm35
-rw-r--r--tools/glade/glade/graphics/gnome-db-error.xpm30
-rw-r--r--tools/glade/glade/graphics/gnome-db-export.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-form.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-graybar.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-grid.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-iconlist.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-label.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-list.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-log-viewer.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-login-dlg.xpm35
-rw-r--r--tools/glade/glade/graphics/gnome-db-login.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-provider-sel.xpm30
-rw-r--r--tools/glade/glade/graphics/gnome-db-query-builder.xpm60
-rw-r--r--tools/glade/glade/graphics/gnome-db-report.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-sourcesel.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-sql-editor.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-table-editor.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-db-window.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-dialog.xpm34
-rw-r--r--tools/glade/glade/graphics/gnome-dock-band.xpm49
-rw-r--r--tools/glade/glade/graphics/gnome-dock-item.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-dock.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-druid-page-finish.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-druid-page-standard.xpm31
-rw-r--r--tools/glade/glade/graphics/gnome-druid-page-start.xpm29
-rw-r--r--tools/glade/glade/graphics/gnome-druid.xpm31
-rw-r--r--tools/glade/glade/graphics/gnome-entry.xpm28
-rw-r--r--tools/glade/glade/graphics/gnome-fileentry.xpm31
-rw-r--r--tools/glade/glade/graphics/gnome-fontpicker.xpm31
-rw-r--r--tools/glade/glade/graphics/gnome-href.xpm32
-rw-r--r--tools/glade/glade/graphics/gnome-iconentry.xpm35
-rw-r--r--tools/glade/glade/graphics/gnome-iconlist.xpm33
-rw-r--r--tools/glade/glade/graphics/gnome-iconselection.xpm32
-rw-r--r--tools/glade/glade/graphics/gnome-less.xpm30
-rw-r--r--tools/glade/glade/graphics/gnome-messagebox.xpm34
-rw-r--r--tools/glade/glade/graphics/gnome-numberentry.xpm30
-rw-r--r--tools/glade/glade/graphics/gnome-papersel.xpm28
-rw-r--r--tools/glade/glade/graphics/gnome-pixmap.xpm39
-rw-r--r--tools/glade/glade/graphics/gnome-pixmapentry.xpm33
-rw-r--r--tools/glade/glade/graphics/gnome-print-papersel.xpm28
-rw-r--r--tools/glade/glade/graphics/gnome-propertybox.xpm34
-rw-r--r--tools/glade/glade/graphics/gnome-spell.xpm33
-rw-r--r--tools/glade/glade/graphics/gnome-stock.xpm39
-rw-r--r--tools/glade/glade/graphics/gtk-clock.xpm26
-rw-r--r--tools/glade/glade/graphics/gtk-dial.xpm28
-rw-r--r--tools/glade/glade/graphics/handlebox.xpm34
-rw-r--r--tools/glade/glade/graphics/hbox.xpm29
-rw-r--r--tools/glade/glade/graphics/hbuttonbox.xpm33
-rw-r--r--tools/glade/glade/graphics/hpaned.xpm29
-rw-r--r--tools/glade/glade/graphics/hruler.xpm30
-rw-r--r--tools/glade/glade/graphics/hscale.xpm34
-rw-r--r--tools/glade/glade/graphics/hscrollbar.xpm33
-rw-r--r--tools/glade/glade/graphics/hseparator.xpm31
-rw-r--r--tools/glade/glade/graphics/iconview.xpm33
-rw-r--r--tools/glade/glade/graphics/image.xpm39
-rw-r--r--tools/glade/glade/graphics/inputdialog.xpm39
-rw-r--r--tools/glade/glade/graphics/label.xpm30
-rw-r--r--tools/glade/glade/graphics/layout.xpm29
-rw-r--r--tools/glade/glade/graphics/list.xpm31
-rw-r--r--tools/glade/glade/graphics/listitem.xpm33
-rw-r--r--tools/glade/glade/graphics/menubar.xpm30
-rw-r--r--tools/glade/glade/graphics/menuitem.xpm26
-rw-r--r--tools/glade/glade/graphics/menutoolbutton.xpm29
-rw-r--r--tools/glade/glade/graphics/new.xpm116
-rw-r--r--tools/glade/glade/graphics/notebook.xpm33
-rw-r--r--tools/glade/glade/graphics/open.xpm32
-rw-r--r--tools/glade/glade/graphics/optionmenu.xpm33
-rw-r--r--tools/glade/glade/graphics/options.xpm140
-rw-r--r--tools/glade/glade/graphics/packer.xpm33
-rw-r--r--tools/glade/glade/graphics/pixmap.xpm39
-rw-r--r--tools/glade/glade/graphics/placeholder.xpm16
-rw-r--r--tools/glade/glade/graphics/popup.xpm32
-rw-r--r--tools/glade/glade/graphics/popupmenu.xpm32
-rw-r--r--tools/glade/glade/graphics/preview.xpm36
-rw-r--r--tools/glade/glade/graphics/progressbar.xpm34
-rw-r--r--tools/glade/glade/graphics/radiobutton.xpm28
-rw-r--r--tools/glade/glade/graphics/radiomenuitem.xpm28
-rw-r--r--tools/glade/glade/graphics/radiotoolbutton.xpm29
-rw-r--r--tools/glade/glade/graphics/save.xpm91
-rw-r--r--tools/glade/glade/graphics/scrolledwindow.xpm28
-rw-r--r--tools/glade/glade/graphics/selector.xpm30
-rw-r--r--tools/glade/glade/graphics/separatortoolitem.xpm29
-rw-r--r--tools/glade/glade/graphics/source.xpm107
-rw-r--r--tools/glade/glade/graphics/spinbutton.xpm33
-rw-r--r--tools/glade/glade/graphics/statusbar.xpm34
-rw-r--r--tools/glade/glade/graphics/table.xpm29
-rw-r--r--tools/glade/glade/graphics/text.xpm30
-rw-r--r--tools/glade/glade/graphics/togglebutton.xpm29
-rw-r--r--tools/glade/glade/graphics/toggletoolbutton.xpm30
-rw-r--r--tools/glade/glade/graphics/toolbar.xpm33
-rw-r--r--tools/glade/glade/graphics/toolbutton.xpm29
-rw-r--r--tools/glade/glade/graphics/toolitem.xpm29
-rw-r--r--tools/glade/glade/graphics/tree.xpm34
-rw-r--r--tools/glade/glade/graphics/treeitem.xpm35
-rw-r--r--tools/glade/glade/graphics/unknown.xpm33
-rw-r--r--tools/glade/glade/graphics/vbox.xpm29
-rw-r--r--tools/glade/glade/graphics/vbuttonbox.xpm33
-rw-r--r--tools/glade/glade/graphics/viewport.xpm34
-rw-r--r--tools/glade/glade/graphics/vpaned.xpm29
-rw-r--r--tools/glade/glade/graphics/vruler.xpm30
-rw-r--r--tools/glade/glade/graphics/vscale.xpm34
-rw-r--r--tools/glade/glade/graphics/vscrollbar.xpm33
-rw-r--r--tools/glade/glade/graphics/vseparator.xpm31
-rw-r--r--tools/glade/glade/graphics/window.xpm38
-rw-r--r--tools/glade/glade/keys.c1375
-rw-r--r--tools/glade/glade/keys.h44
-rw-r--r--tools/glade/glade/load.c603
-rw-r--r--tools/glade/glade/load.h85
-rw-r--r--tools/glade/glade/main.c608
-rw-r--r--tools/glade/glade/named_icons.c1026
-rw-r--r--tools/glade/glade/palette.c156
-rw-r--r--tools/glade/glade/palette.h41
-rw-r--r--tools/glade/glade/property.c5672
-rw-r--r--tools/glade/glade/property.h424
-rw-r--r--tools/glade/glade/save.c1039
-rw-r--r--tools/glade/glade/save.h156
-rw-r--r--tools/glade/glade/source.c2818
-rw-r--r--tools/glade/glade/source.h113
-rw-r--r--tools/glade/glade/source_os2.c116
-rw-r--r--tools/glade/glade/source_os2.h33
-rw-r--r--tools/glade/glade/styles.c208
-rw-r--r--tools/glade/glade/styles.h85
-rw-r--r--tools/glade/glade/tree.c471
-rw-r--r--tools/glade/glade/tree.h70
-rw-r--r--tools/glade/glade/utils.c2327
-rw-r--r--tools/glade/glade/utils.h386
361 files changed, 97342 insertions, 0 deletions
diff --git a/tools/glade/glade/Makefile.am b/tools/glade/glade/Makefile.am
new file mode 100644
index 00000000..c19069d0
--- /dev/null
+++ b/tools/glade/glade/Makefile.am
@@ -0,0 +1,105 @@
+## Process this file with automake to produce Makefile.in
+
+@SET_MAKE@
+
+bin_PROGRAMS = glade-2
+
+INCLUDES = \
+ -DGLADE_DATADIR=\""$(datadir)"\" \
+ -DGLADE_LOCALEDIR=\""$(prefix)/${DATADIRNAME}/locale"\" \
+ $(GLADE_CFLAGS) \
+ $(GLADE_DEPRECATION_CFLAGS)
+
+DIST_SUBDIRS = gbwidgets gnome gnome-db data
+
+SUBDIRS = gbwidgets $(GLADE_GNOME_DIR) $(GLADE_GNOME_DB_DIR) data
+
+glade_2_LDADD = \
+ gbwidgets/libgbwidgets.a \
+ $(GLADE_GNOME_LIB) \
+ $(GLADE_GNOME_DB_LIB) \
+ $(GLADE_LIBS) \
+ $(INTLLIBS)
+
+glade_2_DEPENDENCIES = \
+ gbwidgets/libgbwidgets.a \
+ $(GLADE_GNOME_LIB) \
+ $(GLADE_GNOME_DB_LIB)
+
+glade_2_SOURCES = \
+ debug.c \
+ editor.c \
+ gb.c \
+ gbwidget.c \
+ glade_widget_data.c \
+ gbsource.c \
+ glade.c \
+ glade_atk.c \
+ glade_clipboard.c \
+ glade_gnome.c \
+ glade_gnomelib.c \
+ glade_gnomedblib.c \
+ glade_gtk12lib.c \
+ glade_keys_dialog.c \
+ glade_menu_editor.c \
+ glade_palette.c \
+ glade-parser.c \
+ glade_plugin.c \
+ glade_project.c \
+ glade_project_options.c \
+ glade_project_view.c \
+ glade_project_window.c \
+ keys.c \
+ load.c \
+ main.c \
+ named_icons.c \
+ palette.c \
+ property.c \
+ save.c \
+ source.c \
+ source_os2.c \
+ styles.c \
+ tree.c \
+ utils.c
+
+noinst_HEADERS = \
+ debug.h \
+ editor.h \
+ gb.h \
+ gbwidget.h \
+ glade_widget_data.h \
+ gbsource.h \
+ glade.h \
+ glade_atk.h \
+ glade_clipboard.h \
+ glade_gnome.h \
+ glade_gnomelib.h \
+ glade_gnomedblib.h \
+ glade_gtk12lib.h \
+ glade_keys_dialog.h \
+ glade_menu_editor.h \
+ glade_palette.h \
+ glade-parser.h \
+ glade_plugin.h \
+ glade_project.h \
+ glade_project_options.h \
+ glade_project_view.h \
+ glade_project_window.h \
+ gladeconfig.h \
+ keys.h \
+ load.h \
+ palette.h \
+ property.h \
+ save.h \
+ source.h \
+ source_os2.h \
+ styles.h \
+ tree.h \
+ utils.h
+
+
+dist-hook:
+ mkdir $(distdir)/graphics
+ cp -p $(srcdir)/graphics/*.xpm $(distdir)/graphics
+ cp -p $(srcdir)/graphics/*.png $(distdir)/graphics
+
diff --git a/tools/glade/glade/data/Makefile.am b/tools/glade/glade/data/Makefile.am
new file mode 100644
index 00000000..c317934f
--- /dev/null
+++ b/tools/glade/glade/data/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = gtk
diff --git a/tools/glade/glade/data/gtk/Makefile.am b/tools/glade/glade/data/gtk/Makefile.am
new file mode 100644
index 00000000..82700ddd
--- /dev/null
+++ b/tools/glade/glade/data/gtk/Makefile.am
@@ -0,0 +1,11 @@
+EXTRA_DIST = \
+ autogen.sh
+
+# Install the autogen.sh script for GTK+ apps.
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)-2/gtk
+ $(INSTALL_DATA) $(srcdir)/autogen.sh $(DESTDIR)$(pkgdatadir)-2/gtk
+
+uninstall-local:
+ @rm -f $(DESTDIR)$(pkgdatadir)-2/gtk/autogen.sh
+
diff --git a/tools/glade/glade/data/gtk/autogen.sh b/tools/glade/glade/data/gtk/autogen.sh
new file mode 100644
index 00000000..9bbea2c0
--- /dev/null
+++ b/tools/glade/glade/data/gtk/autogen.sh
@@ -0,0 +1,159 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+DIE=0
+
+if [ -n "$GNOME2_DIR" ]; then
+ ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS"
+ LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH"
+ PATH="$GNOME2_DIR/bin:$PATH"
+ export PATH
+ export LD_LIBRARY_PATH
+fi
+
+(test -f $srcdir/configure.in) || {
+ echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+ echo " top-level package directory"
+ exit 1
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`autoconf' installed."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(grep "^AC_PROG_INTLTOOL" $srcdir/configure.in >/dev/null) && {
+ (intltoolize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`intltool' installed."
+ echo "You can get it from:"
+ echo " ftp://ftp.gnome.org/pub/GNOME/"
+ DIE=1
+ }
+}
+
+(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.in >/dev/null) && {
+ (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`xml-i18n-toolize' installed."
+ echo "You can get it from:"
+ echo " ftp://ftp.gnome.org/pub/GNOME/"
+ DIE=1
+ }
+}
+
+(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
+ (libtool --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`libtool' installed."
+ echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+ }
+}
+
+(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.in >/dev/null) && {
+ (grep "sed.*POTFILES" $srcdir/configure.in) > /dev/null || \
+ (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`glib' installed."
+ echo "You can get it from: ftp://ftp.gtk.org/pub/gtk"
+ DIE=1
+ }
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`automake' installed."
+ echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+ NO_AUTOMAKE=yes
+}
+
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: Missing \`aclocal'. The version of \`automake'"
+ echo "installed doesn't appear recent enough."
+ echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "**Warning**: I am going to run \`configure' with no arguments."
+ echo "If you wish to pass any to it, please specify them on the"
+ echo \`$0\'" command line."
+ echo
+fi
+
+case $CC in
+xlc )
+ am_opt=--include-deps;;
+esac
+
+for coin in `find $srcdir -name configure.in -print`
+do
+ dr=`dirname $coin`
+ if test -f $dr/NO-AUTO-GEN; then
+ echo skipping $dr -- flagged as no auto-gen
+ else
+ echo processing $dr
+ ( cd $dr
+
+ aclocalinclude="$ACLOCAL_FLAGS"
+
+ if grep "^AM_GLIB_GNU_GETTEXT" configure.in >/dev/null; then
+ echo "Creating $dr/aclocal.m4 ..."
+ test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
+ echo "Running glib-gettextize... Ignore non-fatal messages."
+ echo "no" | glib-gettextize --force --copy
+ echo "Making $dr/aclocal.m4 writable ..."
+ test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
+ fi
+ if grep "^AC_PROG_INTLTOOL" configure.in >/dev/null; then
+ echo "Running intltoolize..."
+ intltoolize --copy --force --automake
+ fi
+ if grep "^AM_PROG_XML_I18N_TOOLS" configure.in >/dev/null; then
+ echo "Running xml-i18n-toolize..."
+ xml-i18n-toolize --copy --force --automake
+ fi
+ if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
+ if test -z "$NO_LIBTOOLIZE" ; then
+ echo "Running libtoolize..."
+ libtoolize --force --copy
+ fi
+ fi
+ echo "Running aclocal $aclocalinclude ..."
+ aclocal $aclocalinclude
+ if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
+ echo "Running autoheader..."
+ autoheader
+ fi
+ echo "Running automake --gnu $am_opt ..."
+ automake --add-missing --gnu $am_opt
+ echo "Running autoconf ..."
+ autoconf
+ )
+ fi
+done
+
+conf_flags="--enable-maintainer-mode"
+
+if test x$NOCONFIGURE = x; then
+ echo Running $srcdir/configure $conf_flags "$@" ...
+ $srcdir/configure $conf_flags "$@" \
+ && echo Now type \`make\' to compile. || exit 1
+else
+ echo Skipping configure process.
+fi
diff --git a/tools/glade/glade/debug.c b/tools/glade/glade/debug.c
new file mode 100644
index 00000000..3b398bb0
--- /dev/null
+++ b/tools/glade/glade/debug.c
@@ -0,0 +1,106 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+
+#include <glib.h>
+#include <gdk/gdk.h>
+
+#include "gladeconfig.h"
+#include "debug.h"
+
+static GDebugKey glade_debug_keys[] = {
+ { "warnings", GLADE_DEBUG_WARNINGS },
+ { "messages", GLADE_DEBUG_MESSAGES },
+ { "properties", GLADE_DEBUG_PROPERTIES },
+};
+
+static guint glade_ndebug_keys = sizeof (glade_debug_keys) / sizeof (GDebugKey);
+
+guint glade_debug_flags = 0; /* Global Glade debug flags. */
+gboolean glade_debug_messages = FALSE; /* If debugging info is output. */
+gboolean glade_debug_properties = FALSE; /* If property info is output. */
+
+
+static void glade_log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer unused_data);
+
+void
+glade_debug_init ()
+{
+ gchar *env_string = NULL;
+
+ env_string = getenv ("GLADE_DEBUG");
+ if (env_string != NULL)
+ {
+ glade_debug_flags = g_parse_debug_string (env_string,
+ glade_debug_keys,
+ glade_ndebug_keys);
+ env_string = NULL;
+ if (glade_debug_flags & GLADE_DEBUG_MESSAGES)
+ glade_debug_messages = TRUE;
+
+ if (glade_debug_flags & GLADE_DEBUG_PROPERTIES)
+ glade_debug_properties = TRUE;
+ }
+
+ /* If the GLADE_DEBUG environment variable contains the 'warnings' option,
+ we tell GLib to abort() on warning and critical messages from Glade,
+ GTK, GDK and GLib. This can be handy for finding out exactly where the
+ WARNING/CRITICAL messages occur, with the help of a debugger. */
+ if (glade_debug_flags & GLADE_DEBUG_WARNINGS)
+ {
+ GLogLevelFlags fatal_mask;
+
+ fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+ fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+ g_log_set_always_fatal (fatal_mask);
+ g_log_set_handler ("GLib", G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL
+ | G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL,
+ glade_log_handler, NULL);
+ g_log_set_handler ("Gdk", G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL
+ | G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL,
+ glade_log_handler, NULL);
+ g_log_set_handler ("Gtk", G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL
+ | G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL,
+ glade_log_handler, NULL);
+ g_log_set_handler (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL
+ | G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL,
+ glade_log_handler, NULL);
+ }
+}
+
+
+/* We try to make sure that any X grab is dropped before an abort() is called,
+ so we can still use gdb to get a stack trace. */
+void
+glade_log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer unused_data)
+{
+ g_log_default_handler (log_domain, log_level, message, unused_data);
+ if (log_level & G_LOG_FLAG_FATAL)
+ {
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ gdk_flush ();
+ }
+}
diff --git a/tools/glade/glade/debug.h b/tools/glade/glade/debug.h
new file mode 100644
index 00000000..d79fc587
--- /dev/null
+++ b/tools/glade/glade/debug.h
@@ -0,0 +1,87 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_DEBUG_H
+#define GLADE_DEBUG_H
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* These allow debugging flags to be passed into Glade via the GLADE_DEBUG
+ environment variable. This is useful as you can change options without
+ recompiling Glade. Currently the only options supported are:
+ 'warnings' - will cause Glade to abort() on any WARNING messages.
+ This only works with GTK 1.1.x.
+ 'messages' - causes Glade to output debugging messages (though you must
+ configure Glade with --enable-debug to use this.
+ 'properties' - will cause Glade to create all widget properties on
+ start-up, and output info about them to stdout.
+ To use these, set GLADE_DEBUG to the option strings, with each option
+ separated by a ':'. e.g. export GLADE_DEBUG='warnings:messages'. */
+extern guint glade_debug_flags;
+extern gboolean glade_debug_messages;
+extern gboolean glade_debug_properties;
+
+typedef enum {
+ GLADE_DEBUG_WARNINGS = 1 << 0,
+ GLADE_DEBUG_MESSAGES = 1 << 1,
+ GLADE_DEBUG_PROPERTIES = 1 << 2
+} GladeDebugFlag;
+
+
+/* Debugging macros. These output messages if glade is compiled with
+ --enable-debug, and the 'messages' debugging option is on (i.e. the
+ 'GLADE_DEBUG' environment variable contains 'messages'. The advantage of
+ this is that you can turn the messages on/off without recompiling -
+ just change 'GLADE_DEBUG'. */
+#ifdef GLADE_DEBUG
+#define MSGIN if (glade_debug_messages) \
+ g_print("%s:%i: IN %s\n", __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION)
+#define MSGOUT if (glade_debug_messages) \
+ g_print("%s:%i: OUT %s\n", __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION)
+#define MSG(message) if (glade_debug_messages) \
+ g_print("%s:%i: %s\n", __FILE__, __LINE__, message)
+#define MSG1(message, arg) if (glade_debug_messages) \
+ g_print("%s:%i: " message "\n", __FILE__, __LINE__, arg)
+#define MSG2(message, arg, arg2) if (glade_debug_messages) \
+ g_print("%s:%i: " message "\n", __FILE__, __LINE__, arg, arg2)
+#define MSG3(message, arg, arg2, arg3) if (glade_debug_messages) \
+ g_print("%s:%i: " message "\n", __FILE__, __LINE__, arg, arg2, arg3)
+#define MSG4(message, arg, arg2, arg3, arg4) if (glade_debug_messages) \
+ g_print("%s:%i: " message "\n", __FILE__, __LINE__, arg, arg2, arg3, arg4)
+#else
+#define MSGIN
+#define MSGOUT
+#define MSG(message)
+#define MSG1(message, arg)
+#define MSG2(message, arg, arg2)
+#define MSG3(message, arg, arg2, arg3)
+#define MSG4(message, arg, arg2, arg3, arg4)
+#endif
+
+
+void glade_debug_init ();
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_DEBUG_H */
diff --git a/tools/glade/glade/editor.c b/tools/glade/glade/editor.c
new file mode 100644
index 00000000..424c9e43
--- /dev/null
+++ b/tools/glade/glade/editor.c
@@ -0,0 +1,3598 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#endif
+
+#include "glade_clipboard.h"
+#include "glade_palette.h"
+#include "glade_project.h"
+#include "glade_project_window.h"
+#include "property.h"
+#include "gbwidget.h"
+#include "utils.h"
+#include "editor.h"
+#include "tree.h"
+#include "gb.h"
+
+/* The pixmap to use for placeholders */
+#include "graphics/placeholder.xpm"
+
+#define MIN_WIDGET_WIDTH 16
+#define MIN_WIDGET_HEIGHT 16
+#define MAX_INITIAL_WIDGET_WIDTH 300
+#define MAX_INITIAL_WIDGET_HEIGHT 200
+#define DEFAULT_WIDGET_WIDTH 50
+#define DEFAULT_WIDGET_HEIGHT 50
+
+#define PLACEHOLDER_WIDTH 16
+#define PLACEHOLDER_HEIGHT 16
+
+
+/* The grid (for fixed containers) */
+#define GB_GRID_DOTS 1
+#define GB_GRID_LINES 2
+gboolean editor_show_grid = TRUE;
+static gint editor_grid_horz_spacing = 8;
+static gint editor_grid_vert_spacing = 8;
+static gboolean editor_grid_style = GB_GRID_DOTS;
+
+
+/* Snapping to the grid */
+#define GB_SNAP_TOP 1 << 1
+#define GB_SNAP_BOTTOM 1 << 2
+#define GB_SNAP_LEFT 1 << 3
+#define GB_SNAP_RIGHT 1 << 4
+/*#define GB_SNAP_CENTER 1 << 5 maybe in future */
+gboolean editor_snap_to_grid = TRUE;
+static gint editor_snap_to_grid_x = GB_SNAP_LEFT | GB_SNAP_RIGHT;
+static gint editor_snap_to_grid_y = GB_SNAP_TOP | GB_SNAP_BOTTOM;
+
+
+/* Dragging (in a fixed container) - remembers which part of the widget is
+ being dragged, the offset of the mouse (used when moving) and the initial
+ widget rectangle (used when resizing) */
+#define GB_DRAG_NONE 1
+#define GB_TOP_LEFT 2
+#define GB_TOP_RIGHT 3
+#define GB_BOTTOM_LEFT 4
+#define GB_BOTTOM_RIGHT 5
+#define GB_MIDDLE 6
+static gint drag_action;
+static gboolean drag_has_pointer_grab = FALSE;
+static GtkWidget *dragging_widget = NULL;
+static gint drag_offset_x;
+static gint drag_offset_y;
+static gint drag_widget_x1, drag_widget_y1, drag_widget_x2, drag_widget_y2;
+
+/* The list of selected widgets */
+static GList *selected_widgets = NULL;
+
+/* The cursors used when selecting/adding/moving/resizing widgets */
+static GdkCursor *cursor_selector;
+static GdkCursor *cursor_add_widget;
+static GdkCursor *cursor_add_to_fixed;
+static GdkCursor *cursor_move;
+static GdkCursor *cursor_top_left;
+static GdkCursor *cursor_top_right;
+static GdkCursor *cursor_bottom_left;
+static GdkCursor *cursor_bottom_right;
+
+/* Struct only used for find_child_at callback */
+typedef struct _GbFindChildAtData GbFindChildAtData;
+struct _GbFindChildAtData
+ {
+ gint x;
+ gint y;
+ GtkWidget *found_child;
+ };
+
+/* Experimental code to allow typing labels for widgets when the mouse is
+ over them. */
+GtkWidget *mouse_over_widget = NULL;
+
+
+/* Static functions */
+static void editor_on_widget_realize (GtkWidget *widget,
+ gpointer data);
+
+static gint editor_on_key_press_event (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data);
+static gint editor_on_key_release_event (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data);
+
+static void add_mouse_signals_recursive (GtkWidget *widget,
+ gpointer data);
+static gint editor_on_button_press (GtkWidget * signal_widget,
+ GdkEventButton * event,
+ gpointer data);
+static gint editor_on_button_release (GtkWidget * widget,
+ GdkEvent * event,
+ gpointer data);
+
+static gboolean editor_check_ignore_event (GtkWidget *widget,
+ GdkEventAny *event);
+
+static gint editor_on_motion_notify (GtkWidget * signal_widget,
+ GdkEventMotion * event,
+ gpointer data);
+static gint editor_set_cursor (GtkWidget * signal_widget,
+ GdkEventMotion * event);
+static gint editor_do_drag_action (GtkWidget * signal_widget,
+ GdkEventMotion * event);
+
+static gint editor_on_enter_notify (GtkWidget *widget,
+ GdkEventCrossing *event);
+static gint editor_on_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event);
+
+static void placeholder_replace (GtkWidget * placeholder);
+static void placeholder_finish_replace (GtkWidget * new_widget,
+ GbWidgetNewData * data);
+static void on_placeholder_destroy (GtkWidget * widget,
+ gpointer data);
+static void on_placeholder_size_request (GtkWidget * widget,
+ GtkRequisition *requisition,
+ gpointer data);
+
+static void add_widget_to_fixed (GtkWidget * parent,
+ gint x,
+ gint y);
+static void add_widget_to_fixed_finish (GtkWidget * new_widget,
+ GbWidgetNewData * data);
+#if GLADE_SUPPORTS_GTK_PACKER
+static void add_widget_to_container (GtkWidget * parent);
+static void add_widget_to_container_finish (GtkWidget * new_widget,
+ GbWidgetNewData * data);
+#endif
+static gint expose_widget (GtkWidget * widget,
+ GdkEventExpose * event,
+ GladeWidgetData * wdata);
+static void draw_grid (GtkWidget * widget);
+static void paint_widget (GtkWidget * widget, GdkEventExpose *event);
+static void clear_child_windows (GdkWindow * window,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
+static gint editor_idle_handler (GdkWindow *expose_win);
+
+static void delete (GtkWidget * widget);
+static void delete_placeholder (GtkWidget * widget);
+
+static void on_grid_settings_response (GtkWidget * widget,
+ gint response_id,
+ gpointer data);
+static void editor_redraw_component (GtkWidget * widget,
+ gpointer data);
+
+static void on_snap_settings_response (GtkWidget * widget,
+ gint response_id,
+ gpointer data);
+static gint snap_top_edge (gint y);
+static gint snap_bottom_edge (gint y);
+static gint snap_left_edge (gint x);
+static gint snap_right_edge (gint x);
+
+static gint get_position_in_widget (GtkWidget * widget,
+ gint x,
+ gint y);
+static void raise_fixed_child (GtkWidget * widget);
+
+static void find_child_at (GtkWidget * widget,
+ GbFindChildAtData * data);
+
+
+#if 0
+/* This is probably what we should have used to get all button presses and
+ releases on widget etc. But it may be too awkward to change now.
+ Note that we'll also get all signals for Glade's own widgets.
+
+ Actually I don't think this would help that much, since emission hooks
+ are run after RUN_FIRST class handlers, and you can't stop a signal from
+ them.
+
+ So we'd have to substitute a Glade function for all 'button_press' class
+ functions, and only call the original class functions when appropriate.
+ We'd still need to be able to stop signal handlers. Hmm. */
+static gboolean
+button_press_event_hook (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GdkEventButton *event;
+
+ widget = g_value_get_object (param_values + 0);
+ event = g_value_get_boxed (param_values + 1);
+
+ g_print ("Watch: \"%s\" emitted for %s at %g,%g\n",
+ gtk_signal_name (ihint->signal_id),
+ gtk_type_name (GTK_OBJECT_TYPE (widget)),
+ event->x, event->y);
+
+ /* Test: try to stop the emission. Can't! */
+ /*g_signal_stop_emission (widget, ihint->signal_id, 0);*/
+
+
+ /* If we return FALSE our emission hook is removed. */
+ return TRUE;
+}
+
+
+static gboolean
+button_release_event_hook (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GdkEvent *event;
+
+ widget = g_value_get_object (param_values + 0);
+ event = g_value_get_boxed (param_values + 1);
+
+ g_print ("Watch: \"%s\" emitted for %s type:%i\n",
+ gtk_signal_name (ihint->signal_id),
+ gtk_type_name (GTK_OBJECT_TYPE (widget)),
+ event->type);
+
+ /* If we return FALSE our emission hook is removed. */
+ return TRUE;
+}
+#endif
+
+void
+editor_init ()
+{
+ /* Create all cursors needed */
+ cursor_selector = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
+ cursor_add_widget = gdk_cursor_new (GDK_PLUS);
+ cursor_add_to_fixed = gdk_cursor_new (GDK_TCROSS);
+ cursor_move = gdk_cursor_new (GDK_FLEUR);
+ cursor_top_left = gdk_cursor_new (GDK_TOP_LEFT_CORNER);
+ cursor_top_right = gdk_cursor_new (GDK_TOP_RIGHT_CORNER);
+ cursor_bottom_left = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
+ cursor_bottom_right = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
+
+#if 0
+ {
+ guint button_press_signal_id, button_release_signal_id;
+
+ button_press_signal_id = gtk_signal_lookup ("button_press_event",
+ GTK_TYPE_WIDGET);
+ g_signal_add_emission_hook (button_press_signal_id, 0,
+ button_press_event_hook, NULL, NULL);
+
+ button_release_signal_id = gtk_signal_lookup ("button_release_event",
+ GTK_TYPE_WIDGET);
+ g_signal_add_emission_hook (button_release_signal_id, 0,
+ button_release_event_hook, NULL, NULL);
+ }
+#endif
+}
+
+gint
+editor_close_window (GtkWidget * widget,
+ GdkEvent * event,
+ gpointer data)
+{
+ glade_util_close_window (widget);
+ return TRUE;
+}
+
+
+/*
+ * Grid settings dialog
+ */
+gboolean
+editor_get_show_grid ()
+{
+ return editor_show_grid;
+}
+
+
+void
+editor_set_show_grid (gboolean show)
+{
+ if (editor_show_grid == show)
+ return;
+
+ editor_show_grid = show;
+ if (current_project != NULL)
+ glade_project_foreach_component (current_project, editor_redraw_component,
+ NULL);
+}
+
+
+void
+editor_show_grid_settings_dialog (GtkWidget *widget)
+{
+ GtkWidget *dialog, *vbox, *table, *label, *button, *spinbutton;
+ GtkObject *adjustment;
+ GSList *group;
+ GtkWindow *transient_parent;
+
+ transient_parent = (GtkWindow*) glade_util_get_toplevel (widget);
+ dialog = gtk_dialog_new_with_buttons (_("Grid Options"), transient_parent, 0,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "grid_options", "Glade");
+
+ vbox = GTK_DIALOG (dialog)->vbox;
+
+ table = gtk_table_new (2, 3, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 5);
+ gtk_widget_show (table);
+
+ label = gtk_label_new (_("Horizontal Spacing:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+ GTK_FILL, 0, 5, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (editor_grid_horz_spacing, 1, 1000, 1,
+ 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "spinbutton1",
+ GTK_ADJUSTMENT (adjustment), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 3, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (spinbutton);
+ gtk_widget_grab_focus (spinbutton);
+
+ label = gtk_label_new (_("Vertical Spacing:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
+ GTK_FILL, 0, 5, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (editor_grid_vert_spacing, 1, 1000, 1,
+ 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "spinbutton2",
+ GTK_ADJUSTMENT (adjustment), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 3, 1, 2,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (spinbutton);
+
+ table = gtk_table_new (1, 3, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
+ gtk_widget_show (table);
+
+ label = gtk_label_new (_("Grid Style:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+ GTK_FILL, 0, 5, 5);
+ gtk_widget_show (label);
+
+ button = gtk_radio_button_new_with_label (NULL, _("Dots"));
+ if (editor_grid_style == GB_GRID_DOTS)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (dialog), "button1", button);
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+
+ button = gtk_radio_button_new_with_label (group, _("Lines"));
+ if (editor_grid_style == GB_GRID_LINES)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, 5, 1);
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (dialog), "button2", button);
+
+ gtk_signal_connect (GTK_OBJECT (dialog), "response",
+ GTK_SIGNAL_FUNC (on_grid_settings_response),
+ NULL);
+
+ gtk_widget_show (dialog);
+}
+
+
+static void
+on_grid_settings_response (GtkWidget * widget, gint response_id, gpointer data)
+{
+ GtkWidget *dialog, *spinbutton, *button;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ if (response_id != GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ return;
+ }
+
+ spinbutton = gtk_object_get_data (GTK_OBJECT (dialog), "spinbutton1");
+ editor_grid_horz_spacing = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON
+ (spinbutton));
+ spinbutton = gtk_object_get_data (GTK_OBJECT (dialog), "spinbutton2");
+ editor_grid_vert_spacing = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON
+ (spinbutton));
+
+ button = gtk_object_get_data (GTK_OBJECT (dialog), "button1");
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ editor_grid_style = GB_GRID_DOTS;
+ else
+ editor_grid_style = GB_GRID_LINES;
+
+ gtk_widget_destroy (dialog);
+
+ /* redraw all windows */
+ if (current_project != NULL)
+ glade_project_foreach_component (current_project, editor_redraw_component,
+ NULL);
+}
+
+
+static void
+editor_redraw_component (GtkWidget * widget, gpointer data)
+{
+ gtk_widget_queue_draw (widget);
+}
+
+
+/*
+ * Snap settings
+ */
+gboolean
+editor_get_snap_to_grid ()
+{
+ return editor_snap_to_grid;
+}
+
+
+void
+editor_set_snap_to_grid (gboolean snap)
+{
+ editor_snap_to_grid = snap;
+}
+
+
+void
+editor_show_snap_settings_dialog (GtkWidget *widget)
+{
+ GtkWidget *dialog, *vbox, *table, *label, *button;
+ GtkWindow *transient_parent;
+
+ transient_parent = (GtkWindow*) glade_util_get_toplevel (widget);
+ dialog = gtk_dialog_new_with_buttons (_("Snap Options"), transient_parent, 0,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "snap_options", "Glade");
+
+ vbox = GTK_DIALOG (dialog)->vbox;
+
+ table = gtk_table_new (4, 2, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 5);
+ gtk_widget_show (table);
+
+ /* Horizontal snapping */
+ label = gtk_label_new (_("Horizontal Snapping:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+ GTK_FILL, 0, 5, 5);
+ gtk_widget_show (label);
+
+ button = gtk_check_button_new_with_label (_("Left"));
+ if (editor_snap_to_grid_x & GB_SNAP_LEFT)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (dialog), "button1", button);
+ gtk_widget_grab_focus (button);
+
+ button = gtk_check_button_new_with_label (_("Right"));
+ if (editor_snap_to_grid_x & GB_SNAP_RIGHT)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (dialog), "button2", button);
+
+ /* Vertical snapping */
+ label = gtk_label_new (_("Vertical Snapping:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
+ GTK_FILL, 0, 5, 5);
+ gtk_widget_show (label);
+
+ button = gtk_check_button_new_with_label (_("Top"));
+ if (editor_snap_to_grid_y & GB_SNAP_TOP)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (dialog), "button3", button);
+
+ button = gtk_check_button_new_with_label (_("Bottom"));
+ if (editor_snap_to_grid_y & GB_SNAP_BOTTOM)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 3, 4,
+ GTK_EXPAND | GTK_FILL, 0, 5, 5);
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (dialog), "button4", button);
+
+ gtk_signal_connect (GTK_OBJECT (dialog), "response",
+ GTK_SIGNAL_FUNC (on_snap_settings_response),
+ NULL);
+
+ gtk_widget_show (dialog);
+}
+
+
+static void
+on_snap_settings_response (GtkWidget * widget, gint response_id, gpointer data)
+{
+ GtkWidget *dialog, *button;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ if (response_id != GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ return;
+ }
+
+ editor_snap_to_grid_x = 0;
+ editor_snap_to_grid_y = 0;
+ button = gtk_object_get_data (GTK_OBJECT (dialog), "button1");
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ editor_snap_to_grid_x |= GB_SNAP_LEFT;
+ button = gtk_object_get_data (GTK_OBJECT (dialog), "button2");
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ editor_snap_to_grid_x |= GB_SNAP_RIGHT;
+ button = gtk_object_get_data (GTK_OBJECT (dialog), "button3");
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ editor_snap_to_grid_y |= GB_SNAP_TOP;
+ button = gtk_object_get_data (GTK_OBJECT (dialog), "button4");
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ editor_snap_to_grid_y |= GB_SNAP_BOTTOM;
+
+ gtk_widget_destroy (dialog);
+}
+
+
+static gint
+snap_top_edge (gint y)
+{
+ if (editor_snap_to_grid && (editor_snap_to_grid_y & GB_SNAP_TOP))
+ {
+ y += editor_grid_vert_spacing / 2;
+ y -= y % editor_grid_vert_spacing;
+ }
+ return y;
+}
+
+
+static gint
+snap_bottom_edge (gint y)
+{
+ if (editor_snap_to_grid && (editor_snap_to_grid_y & GB_SNAP_BOTTOM))
+ {
+ y += editor_grid_vert_spacing / 2;
+ y -= y % editor_grid_vert_spacing;
+ }
+ return y;
+}
+
+
+static gint
+snap_left_edge (gint x)
+{
+ if (editor_snap_to_grid && (editor_snap_to_grid_x & GB_SNAP_LEFT))
+ {
+ x += editor_grid_horz_spacing / 2;
+ x -= x % editor_grid_horz_spacing;
+ }
+ return x;
+}
+
+
+static gint
+snap_right_edge (gint x)
+{
+ if (editor_snap_to_grid && (editor_snap_to_grid_x & GB_SNAP_RIGHT))
+ {
+ x += editor_grid_horz_spacing / 2;
+ x -= x % editor_grid_horz_spacing;
+ }
+ return x;
+}
+
+
+
+
+static void
+on_placeholder_size_allocate (GtkWidget * widget,
+ GtkAllocation *allocation,
+ gpointer data)
+{
+#if 0
+ g_print ("In on_placeholder_size_allocate %i,%i %ix%i\n",
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+#endif
+}
+
+
+GtkWidget *
+editor_new_placeholder ()
+{
+ GtkWidget *placeholder = gtk_drawing_area_new ();
+ gtk_widget_set_events (placeholder,
+ gtk_widget_get_events (placeholder)
+ | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK | GDK_BUTTON1_MOTION_MASK);
+ gtk_widget_set_usize (placeholder, PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT);
+ gtk_widget_show (placeholder);
+ editor_add_draw_signals (placeholder);
+ editor_add_mouse_signals (placeholder);
+ gtk_object_set_data (GTK_OBJECT (placeholder), GB_PLACEHOLDER_KEY, "True");
+
+ /* GnomeDock workaround. */
+ gtk_signal_connect_after (GTK_OBJECT (placeholder), "size_request",
+ GTK_SIGNAL_FUNC (on_placeholder_size_request),
+ NULL);
+
+ /* FIXME: Just a test. */
+ gtk_signal_connect_after (GTK_OBJECT (placeholder), "size_allocate",
+ GTK_SIGNAL_FUNC (on_placeholder_size_allocate),
+ NULL);
+
+
+ gtk_signal_connect (GTK_OBJECT (placeholder), "destroy",
+ GTK_SIGNAL_FUNC (on_placeholder_destroy), NULL);
+ return placeholder;
+}
+
+
+static void
+on_placeholder_destroy (GtkWidget * widget,
+ gpointer data)
+{
+ MSG ("IN on_placeholder_destroy");
+ /* If the entire project is being destroyed, we don't need to update the
+ selection or the widget tree. */
+
+ /* FIXME: GTK+2 */
+ if (!(GTK_OBJECT_FLAGS (current_project) & GTK_IN_DESTRUCTION))
+ editor_remove_widget_from_selection (widget);
+}
+
+
+/* This is a gnome-libs 1.0.5 bug workaround - GnomeDockItem doesn't use
+ the child requisition properly. */
+static void
+on_placeholder_size_request (GtkWidget * widget,
+ GtkRequisition *requisition,
+ gpointer data)
+{
+ MSG ("IN on_placeholder_size_request");
+#ifdef USE_GNOME
+ if (BONOBO_IS_DOCK_ITEM (widget->parent))
+ {
+ requisition->width = PLACEHOLDER_WIDTH;
+ requisition->height = PLACEHOLDER_HEIGHT;
+ }
+#endif
+}
+
+
+static void
+placeholder_replace (GtkWidget * placeholder)
+{
+ char *class_name;
+
+ class_name = glade_palette_get_widget_class (GLADE_PALETTE (glade_palette));
+ g_return_if_fail (class_name != NULL);
+ glade_palette_reset_selection (GLADE_PALETTE (glade_palette), TRUE);
+ gb_widget_new_full (class_name, TRUE, placeholder->parent, placeholder, 0, 0,
+ placeholder_finish_replace, GB_CREATING, NULL);
+}
+
+
+static void
+placeholder_finish_replace (GtkWidget * new_widget, GbWidgetNewData * data)
+{
+ editor_clear_selection (NULL);
+
+ /* GtkToolItem widgets can only be added into toolbars and cause problems
+ inside other containers, so check that here. Note that we have to use
+ special tool items for placeholders so data->parent is usually a
+ GtkToolItem rather than a GtkToolbar. */
+ if (GTK_IS_TOOL_ITEM (new_widget)
+ && (!data->parent || (!GTK_IS_TOOLBAR (data->parent)
+ && !GTK_IS_TOOL_ITEM (data->parent))))
+ {
+ glade_util_show_message_box (_("GtkToolItem widgets can only be added to a GtkToolbar."), data->parent);
+ gtk_widget_destroy (new_widget);
+ return;
+ }
+
+ /* If a scrollable widget is added, we automatically add a parent scrolled
+ window, if there isn't one already. */
+ if (GTK_WIDGET_CLASS (G_OBJECT_GET_CLASS (new_widget))->set_scroll_adjustments_signal)
+ {
+ if (data->parent && !GTK_IS_SCROLLED_WINDOW (data->parent))
+ {
+ GtkWidget *scrolledwin;
+
+ scrolledwin = gb_widget_new ("GtkScrolledWindow", data->parent);
+ if (!gb_widget_replace_child (data->parent, data->current_child,
+ scrolledwin))
+ {
+ glade_util_show_message_box (_("Couldn't insert a GtkScrolledWindow widget."), data->parent);
+ gtk_widget_destroy (scrolledwin);
+ gtk_widget_destroy (new_widget);
+ return;
+ }
+
+ if (GTK_BIN (scrolledwin)->child)
+ gtk_container_remove (GTK_CONTAINER (scrolledwin),
+ GTK_BIN (scrolledwin)->child);
+ gtk_container_add (GTK_CONTAINER (scrolledwin), new_widget);
+
+ /* Set the shadow to In, since that is normal. */
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwin),
+ GTK_SHADOW_IN);
+
+ /* Set both scrollbar policies to automatic for GtkIconView. */
+ if (GTK_IS_ICON_VIEW (new_widget))
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ /* GtkText doesn't support horizontal scrolling, so we may as well
+ get rid of the scrollbar. */
+#if GLADE_SUPPORTS_GTK_TEXT
+ if (GTK_IS_TEXT (new_widget))
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_ALWAYS);
+#endif
+
+ tree_add_widget (scrolledwin);
+ tree_add_widget (new_widget);
+ gb_widget_show_properties (new_widget);
+ glade_project_set_changed (current_project, TRUE);
+ return;
+ }
+ }
+ /* If a non-scrollable widget is added to a GtkScrolledWindow, we add a
+ viewport automatically. */
+ else if (data->parent && GTK_IS_SCROLLED_WINDOW (data->parent))
+ {
+ GtkWidget *viewport;
+
+ viewport = gb_widget_new ("GtkViewport", data->parent);
+ if (!gb_widget_replace_child (data->parent, data->current_child,
+ viewport))
+ {
+ glade_util_show_message_box (_("Couldn't insert a GtkViewport widget."), data->parent);
+ gtk_widget_destroy (viewport);
+ gtk_widget_destroy (new_widget);
+ return;
+ }
+
+ if (GTK_BIN (viewport)->child)
+ gtk_container_remove (GTK_CONTAINER (viewport),
+ GTK_BIN (viewport)->child);
+ gtk_container_add (GTK_CONTAINER (viewport), new_widget);
+
+ tree_add_widget (viewport);
+ tree_add_widget (new_widget);
+ gb_widget_show_properties (new_widget);
+ glade_project_set_changed (current_project, TRUE);
+ return;
+ }
+
+ /* Replace placeholder in parent container */
+ if (gb_widget_replace_child (data->parent, data->current_child, new_widget))
+ {
+ gb_widget_show_properties (new_widget);
+ tree_add_widget (new_widget);
+ glade_project_set_changed (current_project, TRUE);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't add new widget."),
+ data->parent);
+
+ /* I think we can safely destroy the new widget. */
+ gtk_widget_destroy (new_widget);
+ }
+}
+
+
+
+
+
+/* Note: returns last found child if children overlap */
+static void
+find_child_at (GtkWidget * widget, GbFindChildAtData * data)
+{
+#if 0
+ g_print ("In find_child_at: %s X:%i Y:%i W:%i H:%i\n",
+ gtk_widget_get_name (widget),
+ widget->allocation.x, widget->allocation.y,
+ widget->allocation.width, widget->allocation.height);
+#endif
+ /* Notebook pages are visible but not mapped if they are not showing. */
+ if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget)
+ && (widget->allocation.x <= data->x)
+ && (widget->allocation.y <= data->y)
+ && (widget->allocation.x + widget->allocation.width > data->x)
+ && (widget->allocation.y + widget->allocation.height > data->y))
+ {
+#if 0
+ g_print ("found child:%s", gtk_widget_get_name (widget));
+#endif
+ data->found_child = widget;
+ }
+}
+
+
+/* Checks if point is in the given notebook's tabs. */
+static void
+find_notebook_tab (GtkWidget * widget, GbFindChildAtData * data)
+{
+ gint nchildren, i;
+ GtkWidget *child_page, *child_tab;
+
+ /* FIXME: Check this works. I had to change it for GTK+ 2. */
+ nchildren = g_list_length (GTK_NOTEBOOK (widget)->children);
+ for (i = 0; i < nchildren; i++)
+ {
+ child_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (widget), i);
+ child_tab = gtk_notebook_get_tab_label (GTK_NOTEBOOK (widget),
+ child_page);
+ if (child_tab
+ && (child_tab->allocation.x <= data->x)
+ && (child_tab->allocation.y <= data->y)
+ && (child_tab->allocation.x + child_tab->allocation.width > data->x)
+ && (child_tab->allocation.y + child_tab->allocation.height > data->y))
+ {
+ /* Make sure this is a GbWidget. */
+ /*if (GB_IS_GB_WIDGET (child_tab))*/
+ data->found_child = child_tab;
+ }
+ }
+}
+
+
+/* This function is passed a widget which has received a mouse event, and
+ the coordinates of that event. It returns the widget which the event is
+ really meant for (which could be a descendent of the given widget), and
+ the position of the event in the widget's allocated area. */
+static GtkWidget *
+editor_get_event_widget (GtkWidget *widget, GdkWindow *window, gint x, gint y,
+ gint * x_return, gint * y_return)
+{
+ GbFindChildAtData data;
+ gint win_x, win_y, saved_x, saved_y;
+ GtkWidget *found_gbwidget = NULL, *saved_widget;
+ gint found_x = 0, found_y = 0;
+ GdkWindow *parent_window = NULL;
+
+#if 0
+ g_print ("\n\nOriginal:%s X:%i Y:%i\n", gtk_widget_get_name (widget), x, y);
+ if (widget->parent)
+ g_print (" Parent: %s\n", gtk_widget_get_name (widget->parent));
+#endif
+
+ /* FIXME: GTK bug workaround? - need to translate coords if mouse button was
+ pressed in a child window. */
+ /* Remember widgets can have other windows besides their main one, and
+ when dragging the event may be sent to the parent's window? */
+ /* SPECIAL CODE: GnomeDockItem widgets which are floating use a different
+ window. */
+ if (widget->parent)
+ {
+ if (GTK_IS_LAYOUT (widget->parent))
+ parent_window = GTK_LAYOUT (widget->parent)->bin_window;
+
+#ifdef USE_GNOME
+ if (BONOBO_IS_DOCK_ITEM (widget)
+ && BONOBO_DOCK_ITEM (widget)->is_floating)
+ {
+ parent_window = BONOBO_DOCK_ITEM (widget)->float_window;
+ }
+ else if (BONOBO_IS_DOCK_ITEM (widget->parent)
+ && BONOBO_DOCK_ITEM (widget->parent)->is_floating)
+ {
+ parent_window = BONOBO_DOCK_ITEM (widget->parent)->float_window;
+ }
+#endif
+ }
+
+ if (!parent_window)
+ parent_window = widget->parent ? widget->parent->window : widget->window;
+
+ while (window && window != parent_window)
+ {
+ gdk_window_get_position (window, &win_x, &win_y);
+#if 0
+ g_print (" adding X:%i Y:%i\n", win_x, win_y);
+#endif
+ x += win_x;
+ y += win_y;
+ window = gdk_window_get_parent (window);
+ }
+ if (window != parent_window)
+ {
+ MSG (" editor_get_event_widget - unknown window");
+ return NULL;
+ }
+
+#if 0
+ g_print (" Translated X:%i Y:%i\n", x, y);
+#endif
+
+ /* We now have correct coordinates relative to the parent's window,
+ i.e. in the same coordinate space as the widget's allocation.
+ Now we find out which widget this event is really for.
+ We step down the widget tree, trying to find the widget at the given
+ position. We have to translate coordinates for children of widgets with
+ windows. We may need to use bin_window for viewport. */
+ if (GB_IS_GB_WIDGET (widget) || GB_IS_PLACEHOLDER (widget))
+ {
+#if 0
+ g_print ("Found child:%s\n", gtk_widget_get_name (widget));
+#endif
+ found_gbwidget = widget;
+ found_x = x;
+ found_y = y;
+ }
+
+ /* Save the widget and the x & y coords. */
+ saved_widget = widget;
+ saved_x = x;
+ saved_y = y;
+
+ /* Now we want to convert the coordinates into the widget's childrens'
+ coordinate space, so if the widget has a window, we have to subtract the
+ position of it (since the child coordinates are relative to that).
+ Viewports need special treatment. */
+ if (!GTK_WIDGET_NO_WINDOW (widget) && widget->parent)
+ {
+ gdk_window_get_position (widget->window, &win_x, &win_y);
+ x -= win_x;
+ y -= win_y;
+
+ /* SPECIAL CODE: need to translate to bin_window for a viewport. */
+ if (GTK_IS_VIEWPORT (widget))
+ {
+ gdk_window_get_position (GTK_VIEWPORT (widget)->bin_window,
+ &win_x, &win_y);
+ x -= win_x;
+ y -= win_y;
+ }
+
+ /* SPECIAL CODE: need to translate to bin_window for a layout. */
+ if (GTK_IS_LAYOUT (widget))
+ {
+ gdk_window_get_position (GTK_LAYOUT (widget)->bin_window,
+ &win_x, &win_y);
+ x -= win_x;
+ y -= win_y;
+ }
+#if 0
+ g_print (" Translated X:%i Y:%i\n", x, y);
+#endif
+ }
+
+ for (;;)
+ {
+ if (!GTK_IS_CONTAINER (widget) || GTK_IS_MENU_BAR (widget))
+ break;
+ data.x = x;
+ data.y = y;
+ data.found_child = NULL;
+#if 0
+ g_print ("...Finding child widget\n");
+#endif
+ gtk_container_forall (GTK_CONTAINER (widget),
+ (GtkCallback) find_child_at, &data);
+ /* SPECIAL CODE - Check for notebook tabs. */
+ if (GTK_IS_NOTEBOOK (widget))
+ find_notebook_tab (widget, &data);
+
+ if (data.found_child)
+ {
+#if 0
+ g_print ("Found child:%s\n", gtk_widget_get_name (data.found_child));
+#endif
+ widget = data.found_child;
+ if (GB_IS_GB_WIDGET (widget) || GB_IS_PLACEHOLDER (widget))
+ {
+ found_gbwidget = widget;
+ found_x = x;
+ found_y = y;
+ }
+ }
+ else
+ break;
+
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ gdk_window_get_position (widget->window, &win_x, &win_y);
+ x -= win_x;
+ y -= win_y;
+
+ /* SPECIAL CODE: need to translate to bin_window for a viewport. */
+ if (GTK_IS_VIEWPORT (widget))
+ {
+ gdk_window_get_position (GTK_VIEWPORT (widget)->bin_window,
+ &win_x, &win_y);
+ x -= win_x;
+ y -= win_y;
+ }
+#if 0
+ g_print (" Translated X:%i Y:%i\n", x, y);
+#endif
+ }
+ }
+
+ /* If we haven't found a GbWidget yet, try moving up the hierarchy. */
+ widget = saved_widget;
+ x = saved_x;
+ y = saved_y;
+ while (!found_gbwidget && widget->parent)
+ {
+ widget = widget->parent;
+#if 0
+ g_print (" Trying parent: %s X:%i Y:%i\n",
+ gtk_widget_get_name (widget), x, y);
+#endif
+ if (GB_IS_GB_WIDGET (widget) || GB_IS_PLACEHOLDER (widget))
+ {
+ found_gbwidget = widget;
+ found_x = x;
+ found_y = y;
+ }
+ else if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ gdk_window_get_position (widget->window, &win_x, &win_y);
+ x += win_x;
+ y += win_y;
+
+ /* SPECIAL CODE; use bin_window for viewport. */
+ if (GTK_IS_VIEWPORT (widget))
+ {
+ gdk_window_get_position (GTK_VIEWPORT (widget)->bin_window,
+ &win_x, &win_y);
+ x += win_x;
+ y += win_y;
+ }
+#if 0
+ g_print (" Translated X:%i Y:%i\n", x, y);
+#endif
+ }
+ }
+
+ if (!found_gbwidget)
+ return NULL;
+
+ *x_return = found_x - found_gbwidget->allocation.x;
+ *y_return = found_y - found_gbwidget->allocation.y;
+
+#if 0
+ g_print (" Event widget: %s X:%i Y:%i\n",
+ gtk_widget_get_name (found_gbwidget), *x_return, *y_return);
+#endif
+
+ return found_gbwidget;
+}
+
+
+/* We use the "event" signal since it is emitted before the "button_press"
+ or "button_release" signal is emitted. This means we can catch it and
+ stop the normal signal handlers. */
+static gint
+editor_on_event (GtkWidget * signal_widget,
+ GdkEvent * event,
+ gpointer user_data)
+{
+#if 0
+ g_print ("In editor_on_event widget: %s\n",
+ gtk_widget_get_name (signal_widget));
+#endif
+
+ if (event->type == GDK_BUTTON_PRESS
+ || event->type == GDK_2BUTTON_PRESS
+ || event->type == GDK_3BUTTON_PRESS)
+ return editor_on_button_press (signal_widget, (GdkEventButton*) event,
+ user_data);
+
+ if (event->type == GDK_BUTTON_RELEASE)
+ return editor_on_button_release (signal_widget, event, user_data);
+
+ return FALSE;
+}
+
+
+static gint
+editor_on_button_press (GtkWidget * signal_widget,
+ GdkEventButton * event,
+ gpointer user_data)
+{
+ GtkWidget *widget;
+ gint x, y;
+
+#if 0
+ g_print ("In editor_on_button_press widget: %s\n",
+ gtk_widget_get_name (signal_widget));
+#endif
+ widget = editor_get_event_widget (signal_widget, event->window,
+ event->x, event->y, &x, &y);
+ if (widget == NULL)
+ return FALSE;
+
+ if (editor_check_ignore_event (widget, (GdkEventAny*) event))
+ return FALSE;
+
+ MSG ("...Checking which button pressed");
+ /* We only want single button press events. */
+ if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
+ {
+ if (glade_palette_is_selector_on (GLADE_PALETTE (glade_palette)))
+ {
+ gboolean handled;
+ MSG ("...Selecting widget");
+ handled = editor_select_widget (widget, event, x, y);
+#if 0
+ if (handled)
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (signal_widget),
+ "button_press_event");
+#endif
+ return handled;
+ }
+#ifdef USE_GNOME
+ else if (GTK_IS_FIXED (widget)
+ || (GTK_IS_LAYOUT (widget) && !GNOME_IS_CANVAS (widget)))
+#else
+ else if (GTK_IS_FIXED (widget) || GTK_IS_LAYOUT (widget))
+#endif
+ {
+ add_widget_to_fixed (widget, x, y);
+#if 0
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (signal_widget),
+ "button_press_event");
+#endif
+ return TRUE;
+ }
+ else if (GB_IS_PLACEHOLDER (widget))
+ {
+ placeholder_replace (widget);
+#if 0
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (signal_widget),
+ "button_press_event");
+#endif
+ return TRUE;
+ }
+#if GLADE_SUPPORTS_GTK_PACKER
+ else if (GTK_IS_PACKER (widget))
+ {
+ add_widget_to_container (widget);
+#if 0
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (signal_widget),
+ "button_press_event");
+#endif
+ return TRUE;
+ }
+#endif
+ else
+ {
+ static gboolean already_shown = FALSE;
+ if (already_shown)
+ {
+ /* Beep if user does mistake of invalid positioning from second
+ * time.
+ */
+ gdk_beep ();
+ }
+ else
+ {
+ glade_util_show_message_box (_("You can't add a widget at the selected position.\n"
+ "\n"
+ "Tip: GTK+ uses containers to lay out widgets.\n"
+ "Try deleting the existing widget and using\n"
+ "a box or table container instead.\n"), widget);
+ already_shown = TRUE;
+ }
+ }
+ }
+ else if (event->button == 3)
+ {
+ gb_widget_show_popup_menu (widget, event);
+#if 0
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (signal_widget),
+ "button_press_event");
+#endif
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gint
+editor_on_button_release (GtkWidget * widget,
+ GdkEvent * event,
+ gpointer data)
+{
+ MSG ("In editor_on_button_release");
+ if (drag_has_pointer_grab)
+ {
+#if 0
+ g_print ("###### Releasing pointer grab\n");
+#endif
+ gdk_pointer_ungrab (event->button.time);
+ drag_has_pointer_grab = FALSE;
+ }
+
+ if (dragging_widget)
+ {
+ drag_action = GB_DRAG_NONE;
+ MSG (" removing grab");
+ gtk_grab_remove (dragging_widget);
+ dragging_widget = NULL;
+ }
+ return FALSE;
+}
+
+
+/* This adds a new widget to a GtkFixed or GtkLayout container. */
+static void
+add_widget_to_fixed (GtkWidget * parent, gint x, gint y)
+{
+ char *class_name;
+
+ class_name = glade_palette_get_widget_class (GLADE_PALETTE (glade_palette));
+ g_return_if_fail (class_name != NULL);
+ glade_palette_reset_selection (GLADE_PALETTE (glade_palette), TRUE);
+ gb_widget_new_full (class_name, TRUE, parent, NULL, x, y,
+ add_widget_to_fixed_finish, GB_CREATING, NULL);
+}
+
+
+/* This finishes off adding a new widget to a GtkFixed or GtkLayout container,
+ possibly after a dialog has been shown to set some initial properties of
+ the new widget (e.g. number of rows for a new GtkCList). */
+static void
+add_widget_to_fixed_finish (GtkWidget * new_widget, GbWidgetNewData * data)
+{
+ GtkRequisition requisition = {0, 0};
+ GladeWidgetData *wdata;
+ GtkWidget *parent = data->parent;
+ gint x = data->x;
+ gint y = data->y;
+ gint w, h;
+
+ g_return_if_fail (parent != NULL);
+ g_return_if_fail (GTK_IS_FIXED (parent) || GTK_IS_LAYOUT (parent));
+
+ /* I think we should do this first, in case the widget needs to be
+ realized in order to calculate its requisition. */
+ gtk_widget_hide (new_widget);
+
+ if (GTK_IS_FIXED (data->parent))
+ {
+ gtk_fixed_put (GTK_FIXED (data->parent), new_widget, x, y);
+ /*gtk_widget_set_uposition (new_widget, x, y);*/
+ }
+ else if (GTK_IS_LAYOUT (data->parent))
+ {
+ GtkLayout *layout = GTK_LAYOUT (data->parent);
+ x += layout->hadjustment->value;
+ y += layout->vadjustment->value;
+ gtk_layout_put (layout, new_widget, x, y);
+ /*gtk_widget_set_uposition (new_widget, x, y);*/
+ }
+
+
+ gtk_widget_size_request (new_widget, &requisition);
+ w = requisition.width;
+ h = requisition.height;
+ if (w < MIN_WIDGET_WIDTH || h < MIN_WIDGET_HEIGHT)
+ {
+ MSG3 ("Default widget size too small: %s W:%i H:%i\n",
+ gtk_widget_get_name (new_widget), w, h);
+ }
+ if (w > MAX_INITIAL_WIDGET_WIDTH || h > MAX_INITIAL_WIDGET_HEIGHT)
+ {
+ MSG3 ("Default widget size too big: %s W:%i H:%i\n",
+ gtk_widget_get_name (new_widget), w, h);
+ }
+
+ if (w == 0)
+ w = DEFAULT_WIDGET_WIDTH;
+ if (h == 0)
+ h = DEFAULT_WIDGET_HEIGHT;
+ w = MAX (w, MIN_WIDGET_WIDTH);
+ w = MIN (w, MAX_INITIAL_WIDGET_WIDTH);
+ h = MAX (h, MIN_WIDGET_HEIGHT);
+ h = MIN (h, MAX_INITIAL_WIDGET_HEIGHT);
+
+ /* FIXME: Make sure a gamma curve is a reasonable size. */
+ if (GTK_IS_GAMMA_CURVE (new_widget))
+ w = 80;
+
+ /* FIXME: Make sure a clist/ctree or notebook is a reasonable size. */
+ if (GTK_IS_CLIST (new_widget) || GTK_IS_NOTEBOOK (new_widget))
+ {
+ w = 200;
+ h = 100;
+ }
+
+ /* Children of fixed widgets always have their x, y, width & height set
+ explicitly. */
+ wdata = gtk_object_get_data (GTK_OBJECT (new_widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+ wdata->flags |= GLADE_WIDTH_SET | GLADE_HEIGHT_SET;
+
+ /* Calculate real position & size according to grid & snapping */
+ /* FIXME: only snaps top & left at present */
+ if (editor_snap_to_grid)
+ {
+ if (editor_snap_to_grid_x & GB_SNAP_LEFT)
+ {
+ /*x += editor_grid_horz_spacing / 2; */
+ x -= x % editor_grid_horz_spacing;
+ }
+ if (editor_snap_to_grid_y & GB_SNAP_TOP)
+ {
+ /*y += editor_grid_vert_spacing / 2; */
+ y -= y % editor_grid_vert_spacing;
+ }
+ }
+
+ gb_widget_set_usize (new_widget, w, h);
+ wdata->width = w;
+ wdata->height = h;
+
+ if (GTK_IS_FIXED (data->parent))
+ {
+ gtk_fixed_move (GTK_FIXED (data->parent), new_widget, x, y);
+ /*gtk_widget_set_uposition (new_widget, x, y);*/
+ }
+ else if (GTK_IS_LAYOUT (data->parent))
+ {
+ gtk_layout_move (GTK_LAYOUT (data->parent), new_widget, x, y);
+ /*gtk_widget_set_uposition (new_widget, x, y);*/
+ }
+
+ gtk_widget_show (new_widget);
+ gb_widget_show_properties (new_widget);
+ tree_add_widget (new_widget);
+ glade_project_set_changed (data->project, TRUE);
+}
+
+
+#if GLADE_SUPPORTS_GTK_PACKER
+static void
+add_widget_to_container (GtkWidget * parent)
+{
+ char *class_name;
+
+ class_name = glade_palette_get_widget_class (GLADE_PALETTE (glade_palette));
+ g_return_if_fail (class_name != NULL);
+ glade_palette_reset_selection (GLADE_PALETTE (glade_palette), TRUE);
+ gb_widget_new_full (class_name, TRUE, parent, NULL, 0, 0,
+ add_widget_to_container_finish, GB_CREATING, NULL);
+}
+
+
+static void
+add_widget_to_container_finish (GtkWidget * new_widget, GbWidgetNewData * data)
+{
+ gtk_container_add (GTK_CONTAINER (data->parent), new_widget);
+ gtk_widget_show (new_widget);
+ gb_widget_show_properties (new_widget);
+ tree_add_widget (new_widget);
+ glade_project_set_changed (data->project, TRUE);
+}
+#endif
+
+/*
+ * Clears all currently selected widgets, except the given widget.
+ * Returns TRUE if given widget is selected.
+ */
+gint
+editor_clear_selection (GtkWidget * leave_widget)
+{
+ GList *child = selected_widgets, *next_child;
+ GtkWidget *widget;
+ gint selected = FALSE;
+
+ while (child)
+ {
+ next_child = child->next;
+ widget = child->data;
+ if (widget == leave_widget)
+ {
+ selected = TRUE;
+ }
+ else
+ {
+ selected_widgets = g_list_remove (selected_widgets, widget);
+ tree_select_widget (widget, FALSE);
+ editor_refresh_widget_selection (widget);
+ }
+ child = next_child;
+ }
+ return selected;
+}
+
+
+void
+editor_remove_widget_from_selection (GtkWidget * widget)
+{
+ selected_widgets = g_list_remove (selected_widgets, widget);
+
+ /* If the widget is not being destroyed, we deselect it in the tree.
+ If it is being destroyed, it will get removed from the tree so we don't
+ have to bother. */
+ if (!(GTK_OBJECT_FLAGS (widget) & GTK_IN_DESTRUCTION))
+ tree_select_widget (widget, FALSE);
+}
+
+
+void
+editor_deselect_all_placeholders (void)
+{
+ GList *child, *next_child;
+ GtkWidget *widget;
+
+ child = selected_widgets;
+ while (child)
+ {
+ next_child = child->next;
+ widget = child->data;
+
+ if (GB_IS_PLACEHOLDER (widget))
+ {
+ selected_widgets = g_list_remove (selected_widgets, widget);
+ editor_refresh_widget_selection (widget);
+ }
+ child = next_child;
+ }
+}
+
+
+gboolean
+editor_is_selected (GtkWidget *widget)
+{
+ GList *elem = selected_widgets;
+
+ while (elem)
+ {
+ if (GTK_WIDGET (elem->data) == widget)
+ return TRUE;
+ elem = elem->next;
+ }
+ return FALSE;
+}
+
+
+void
+editor_dump_selection (void)
+{
+ GList *elem = selected_widgets;
+
+ g_print ("Selected widgets:\n");
+ while (elem)
+ {
+ g_print (" %p: %s\n", elem->data,
+ gtk_widget_get_name (GTK_WIDGET (elem->data)));
+ elem = elem->next;
+ }
+}
+
+
+static gint
+get_position_in_widget (GtkWidget * widget, gint x, gint y)
+{
+ gint width = widget->allocation.width;
+ gint height = widget->allocation.height;
+ if (x < GB_CORNER_WIDTH && y < GB_CORNER_HEIGHT)
+ return GB_TOP_LEFT;
+ if (x > width - GB_CORNER_WIDTH && y < GB_CORNER_HEIGHT)
+ return GB_TOP_RIGHT;
+ if (x < GB_CORNER_WIDTH && y > height - GB_CORNER_HEIGHT)
+ return GB_BOTTOM_LEFT;
+ if (x > width - GB_CORNER_WIDTH && y > height - GB_CORNER_HEIGHT)
+ return GB_BOTTOM_RIGHT;
+ return GB_MIDDLE;
+}
+
+
+static void
+raise_fixed_child (GtkWidget * widget)
+{
+ GtkFixed *fixed;
+
+ g_return_if_fail (GTK_IS_FIXED (widget->parent));
+ fixed = GTK_FIXED (widget->parent);
+ /* If widget hasn't got a window, move it to the back of the parent fixed's
+ children. If it has got a window, raise it. */
+ /* Note: this is slightly naughty as it changes the GtkFixed's GList of
+ children, but it's better than removing the widget and adding it again. */
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ {
+ GList *child;
+ GtkFixedChild *data;
+ child = fixed->children;
+ while (child)
+ {
+ data = child->data;
+ if (data->widget == widget)
+ {
+ fixed->children = g_list_remove (fixed->children, data);
+ fixed->children = g_list_append (fixed->children, data);
+ break;
+ }
+ child = child->next;
+ }
+ }
+ else
+ {
+ gdk_window_raise (widget->window);
+ }
+}
+
+
+gboolean
+editor_select_widget_control (GtkWidget * widget)
+{
+ MSG ("IN editor_select_widget_control");
+ /* If widget is currently selected, deslect it, else add it to
+ selected. */
+ if (g_list_find (selected_widgets, widget))
+ {
+ selected_widgets = g_list_remove (selected_widgets, widget);
+ }
+ else
+ {
+ gb_widget_show_properties (widget);
+ selected_widgets = g_list_append (selected_widgets, widget);
+ glade_project_view_clear_component_selection (current_project_view,
+ widget);
+ }
+ editor_refresh_widget_selection (widget);
+ return TRUE;
+}
+
+/* FIXME: handle widget-tree better now it has extended selection */
+GList *
+editor_get_selection ()
+{
+ return g_list_first (selected_widgets);
+}
+
+
+/* This sets the list of selected widgets, possibly NULL. It takes control
+ of the GList, so don't free it. */
+void
+editor_set_selection (GList *new_selection)
+{
+ GList *old_selection, *elem;
+
+ old_selection = selected_widgets;
+
+ selected_widgets = new_selection;
+
+ for (elem = old_selection; elem; elem = elem->next)
+ editor_refresh_widget_selection (elem->data);
+
+ for (elem = new_selection; elem; elem = elem->next)
+ {
+ /* Only refresh it if it wasn't already refreshed above. */
+ if (!g_list_find (old_selection, elem->data))
+ editor_refresh_widget_selection (elem->data);
+ }
+
+ /* If just one widget is selected, show its properties. */
+ if (g_list_length (new_selection) == 1)
+ gb_widget_show_properties (GTK_WIDGET (new_selection->data));
+
+ g_list_free (old_selection);
+}
+
+
+static gint
+get_notebook_page (GtkNotebook * notebook,
+ GtkWidget * widget)
+{
+ gint nchildren, page;
+
+ nchildren = g_list_length (notebook->children);
+
+ for (page = 0; page < nchildren; page++)
+ {
+ GtkWidget *child, *tab;
+
+ child = gtk_notebook_get_nth_page (notebook, page);
+ tab = gtk_notebook_get_tab_label (notebook, child);
+ if (tab == widget)
+ return page;
+ }
+
+ return -1;
+}
+
+
+
+/* FIXME: When the editor is rewritten as a GtkObject, we need simple
+ functions to select/deselect widgets separate from the complicated
+ stuff used for moving/resizing. */
+gboolean
+editor_select_widget (GtkWidget * widget, GdkEventButton * event,
+ gint x, gint y)
+{
+ gint already_selected, page;
+ GtkWidget *select_widget, *ancestor;
+ gboolean handled = FALSE;
+
+ MSG ("IN editor_select_widget");
+#if 0
+ g_print ("=+=+ widget: %s Alloc X:%i Y:%i W:%i H:%i\n",
+ gtk_widget_get_name (widget),
+ widget->allocation.x, widget->allocation.y,
+ widget->allocation.width, widget->allocation.height);
+#endif
+
+ /* reset any move/resize action */
+ drag_action = GB_DRAG_NONE;
+
+ /* Shift + selection. Step through parents of this widget, until a selected
+ widget is found. Then clear selection & select that widgets parent.
+ If no parents were selected, or the top-level parent was selected,
+ select this widget. */
+ if (event && event->state & GDK_SHIFT_MASK)
+ {
+ gint found = FALSE;
+ ancestor = widget;
+ while (ancestor)
+ {
+ if (g_list_find (selected_widgets, ancestor))
+ {
+ found = TRUE;
+ break;
+ }
+ ancestor = ancestor->parent;
+ }
+ if (found && ancestor->parent != NULL)
+ {
+ select_widget = ancestor->parent;
+ /* If widget is not a GbWidget, i.e. it has no GladeWidgetData,
+ skip it. */
+ while (select_widget)
+ {
+ if (GB_IS_GB_WIDGET (select_widget))
+ break;
+ select_widget = select_widget->parent;
+ }
+ }
+ else
+ {
+ select_widget = widget;
+ }
+ g_return_val_if_fail (select_widget != NULL, FALSE);
+ gb_widget_show_properties (select_widget);
+ already_selected = editor_clear_selection (select_widget);
+ if (already_selected)
+ return FALSE;
+ selected_widgets = g_list_append (selected_widgets, select_widget);
+ tree_select_widget (select_widget, TRUE);
+ glade_project_view_clear_component_selection (current_project_view,
+ widget);
+ editor_refresh_widget_selection (select_widget);
+ return TRUE;
+ }
+
+#if 0
+ /* Control + selection. If widget is currently selected, deslect it, else
+ add it to the selected widgets. */
+ /* I've taken this out as it can cause crashes and it isn't very useful. */
+ if (event && event->state & GDK_CONTROL_MASK)
+ {
+ /* If widget is currently selected, deselect it, else add it to
+ selected. */
+ editor_select_widget_control (widget);
+
+ if (g_list_find (selected_widgets, widget))
+ tree_select_widget (widget, TRUE);
+ else
+ tree_select_widget (widget, FALSE);
+
+ return TRUE;
+ }
+#endif
+
+ /* Normal selection. If the widget is currently selected, just get the
+ data for a possible resize/drag. If it is not selected, clear all
+ currently selected widgets, then select this one.
+ Also remember where the button press occurred, in case widget is being
+ moved or resized (in a fixed container). */
+ gb_widget_show_properties (widget);
+
+ if (!g_list_find (selected_widgets, widget))
+ {
+ editor_clear_selection (NULL);
+ selected_widgets = g_list_append (selected_widgets, widget);
+ tree_select_widget (widget, TRUE);
+ handled = TRUE;
+ glade_project_view_clear_component_selection (current_project_view,
+ widget);
+ /* If parent is a fixed container, move widget to front */
+ if (widget->parent && GTK_IS_FIXED (widget->parent))
+ raise_fixed_child (widget);
+
+ /* SPECIAL CODE: If the widget or an ancestor is a notebook tab,
+ show the page */
+ ancestor = widget;
+ while (ancestor->parent)
+ {
+ if (GTK_IS_NOTEBOOK (ancestor->parent))
+ {
+ page = get_notebook_page (GTK_NOTEBOOK (ancestor->parent),
+ ancestor);
+ if (page != -1)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (ancestor->parent),
+ page);
+ break;
+ }
+ ancestor = ancestor->parent;
+ }
+
+ editor_refresh_widget_selection (widget);
+ }
+
+
+ /* NOTE: this will only work in a GtkFixed or a GtkLayout. */
+ if (widget->parent && event
+ && (GTK_IS_FIXED (widget->parent) || GTK_IS_LAYOUT (widget->parent)))
+ {
+ if (gdk_pointer_grab (event->window, FALSE,
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON1_MOTION_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL, NULL, event->time))
+ return FALSE;
+
+#if 0
+ g_print ("###### Grabbed pointer\n");
+#endif
+ drag_has_pointer_grab = TRUE;
+ drag_action = get_position_in_widget (widget, x, y);
+ drag_offset_x = x;
+ drag_offset_y = y;
+
+ drag_widget_x1 = widget->allocation.x;
+ drag_widget_y1 = widget->allocation.y;
+
+ if (GTK_IS_FIXED (widget->parent))
+ {
+ drag_widget_x1 -= widget->parent->allocation.x;
+ drag_widget_y1 -= widget->parent->allocation.y;
+ }
+
+ drag_widget_x2 = drag_widget_x1 + widget->allocation.width;
+ drag_widget_y2 = drag_widget_y1 + widget->allocation.height;
+
+#if 0
+ g_print ("drag_action:%i, offset_x:%i offset_y:%i "
+ "x1:%i y1:%i x2:%i y2:%i\n",
+ drag_action, drag_offset_x, drag_offset_y,
+ drag_widget_x1, drag_widget_y1,
+ drag_widget_x2, drag_widget_y2);
+#endif
+
+ /* We return TRUE to make sure the signal is stopped so the widget
+ doesn't popup a menu or something, which would make moving/resizing
+ very difficult. */
+ return TRUE;
+ }
+ return handled;
+}
+
+
+/* This returns TRUE if the event should be ignored. Currently we only
+ ignore events in clist/ctree resize windows, but more may be added. */
+static gboolean
+editor_check_ignore_event (GtkWidget *widget,
+ GdkEventAny *event)
+{
+ GtkWidget *window_widget;
+
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ gdk_window_get_user_data (event->window, (gpointer) &window_widget);
+
+ if (GTK_IS_CLIST (window_widget))
+ {
+ gint i;
+ for (i = 0; i < GTK_CLIST (window_widget)->columns; i++)
+ {
+ GtkCListColumn *col = &GTK_CLIST (window_widget)->column[i];
+ if (event->window == col->window)
+ {
+ MSG ("Ignored event (clist resize window)");
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+static gint
+editor_on_motion_notify (GtkWidget * signal_widget,
+ GdkEventMotion * event,
+ gpointer data)
+{
+#if 0
+ g_print ("In editor_on_motion_notify: %s\n",
+ gtk_widget_get_name (signal_widget));
+#endif
+
+ if (event->state & GDK_BUTTON1_MASK)
+ return editor_do_drag_action (signal_widget, event);
+ else
+ return editor_set_cursor (signal_widget, event);
+}
+
+
+static gint
+editor_set_cursor (GtkWidget * signal_widget,
+ GdkEventMotion * event)
+{
+ /* We remember the last cursor set and the last window, so we don't set the
+ same cursor on the same window repeatedly. */
+ static GdkWindow *last_window = NULL;
+ static GdkCursor *last_cursor = NULL;
+
+ GtkWidget *widget, *event_widget;
+ GdkCursor *cursor = NULL;
+ gint x, y, event_x, event_y, pos;
+
+#if 0
+ g_print ("In editor_set_cursor %s hint:%i\n",
+ gtk_widget_get_name (signal_widget), event->is_hint);
+#endif
+
+ /* First of all, we find out which widget the event originated from.
+ We step up the parents until we find the current widget, checking if
+ any GbWidgets are children. If they are, we have already seen this event
+ so we just return. */
+ event_widget = gtk_get_event_widget ((GdkEvent*) event);
+ if (event_widget)
+ {
+ while (event_widget != signal_widget)
+ {
+ if (event_widget == NULL)
+ {
+ g_warning ("motion_notify - didn't find signal widget");
+ break;
+ }
+
+ if (GB_IS_GB_WIDGET (event_widget))
+ return FALSE;
+
+ event_widget = event_widget->parent;
+ }
+
+ }
+
+ if (event->is_hint)
+ gdk_window_get_pointer (event->window, &event_x, &event_y, NULL);
+ else
+ {
+ event_x = event->x;
+ event_y = event->y;
+ }
+
+ widget = editor_get_event_widget (signal_widget, event->window,
+ event_x, event_y, &x, &y);
+ if (widget == NULL)
+ return FALSE;
+
+ if (editor_check_ignore_event (widget, (GdkEventAny*) event))
+ return FALSE;
+
+ /* Remember the widget, so we can redirect key presses to it. But only
+ keep pointers to GbWidgets, as we can reset the pointer to NULL when the
+ widget is destroyed. */
+ if (GB_IS_GB_WIDGET (widget))
+ {
+#if 0
+ g_print (" mouse_over_widget: %s\n", gtk_widget_get_name (widget));
+#endif
+ mouse_over_widget = widget;
+ }
+
+#if 0
+ g_print ("editor_set_cursor widget: %s (%p) X:%i Y:%i\n",
+ gtk_widget_get_name (widget), widget, x, y);
+#endif
+ if (glade_palette_is_selector_on (GLADE_PALETTE (glade_palette)))
+ {
+#ifdef USE_GNOME
+ if (widget->parent
+ && (GTK_IS_FIXED (widget)
+ || (GTK_IS_LAYOUT (widget) && !GNOME_IS_CANVAS (widget))))
+#else
+ if (widget->parent
+ && (GTK_IS_FIXED (widget->parent)
+ || GTK_IS_LAYOUT (widget->parent)))
+#endif
+ {
+ pos = get_position_in_widget (widget, x, y);
+ switch (pos)
+ {
+ case GB_TOP_LEFT:
+#if 0
+ g_print ("TOP_LEFT\n");
+#endif
+ cursor = cursor_top_left;
+ break;
+ case GB_TOP_RIGHT:
+#if 0
+ g_print ("TOP_RIGHT\n");
+#endif
+ cursor = cursor_top_right;
+ break;
+ case GB_BOTTOM_LEFT:
+#if 0
+ g_print ("BOTTOM_LEFT\n");
+#endif
+ cursor = cursor_bottom_left;
+ break;
+ case GB_BOTTOM_RIGHT:
+#if 0
+ g_print ("BOTTOM_RIGHT\n");
+#endif
+ cursor = cursor_bottom_right;
+ break;
+ case GB_MIDDLE:
+#if 0
+ g_print ("MIDDLE\n");
+#endif
+ cursor = cursor_move;
+ break;
+ }
+ }
+ else
+ {
+ cursor = cursor_selector;
+ }
+ }
+ else
+ {
+ if (GTK_IS_FIXED (widget) || GTK_IS_LAYOUT (widget)
+ || (widget->parent && (GTK_IS_FIXED (widget->parent)
+ || GTK_IS_LAYOUT (widget->parent))))
+ cursor = cursor_add_to_fixed;
+ else
+ cursor = cursor_add_widget;
+ }
+
+ if (cursor)
+ {
+ if (last_window != event->window || last_cursor != cursor)
+ {
+ gdk_window_set_cursor (event->window, cursor);
+ last_window = event->window;
+ last_cursor = cursor;
+
+ }
+ }
+
+ return FALSE;
+}
+
+
+static gint
+editor_do_drag_action (GtkWidget * signal_widget, GdkEventMotion * event)
+{
+ GtkWidget *widget;
+ GladeWidgetData *wdata;
+ gint x, y, event_x, event_y;
+ gint mouse_x, mouse_y, new_x = 0, new_y = 0, new_width = 0, new_height = 0;
+ gint old_x, old_y, old_width, old_height;
+
+#if 0
+ g_print ("In editor_do_drag_action %s hint:%i\n",
+ gtk_widget_get_name (signal_widget), event->is_hint);
+#endif
+
+ /* If no move/resize action was started in the button_press event, return. */
+ if (drag_action == GB_DRAG_NONE)
+ return FALSE;
+
+ if (event->is_hint)
+ gdk_window_get_pointer (event->window, &event_x, &event_y, NULL);
+ else
+ {
+ event_x = event->x;
+ event_y = event->y;
+ }
+
+#if 0
+ g_print ("In editor_do_drag_action %s hint:%i %i,%i\n",
+ gtk_widget_get_name (signal_widget), event->is_hint,
+ event_x, event_y);
+#endif
+
+ /* Use our function to figure out which widget the mouse is in, and where
+ in the widget. */
+ widget = editor_get_event_widget (signal_widget, event->window,
+ event_x, event_y, &x, &y);
+ if (widget == NULL)
+ return FALSE;
+
+ if (editor_check_ignore_event (widget, (GdkEventAny*) event))
+ return FALSE;
+
+
+ if (!widget->parent
+ || (!GTK_IS_FIXED (widget->parent) && !GTK_IS_LAYOUT (widget->parent)))
+ return FALSE;
+
+ if (dragging_widget == NULL)
+ {
+ dragging_widget = widget;
+ gtk_grab_add (widget);
+ }
+ else
+ {
+ if (dragging_widget != widget)
+ return FALSE;
+ }
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_val_if_fail (wdata != NULL, FALSE);
+
+ old_x = widget->allocation.x;
+ old_y = widget->allocation.y;
+ old_width = widget->allocation.width;
+ old_height = widget->allocation.height;
+
+ /* GtkFixed doesn't normally have a window now, so we need to subtract its
+ position so our coordinates are relative to it. */
+ if (GTK_IS_FIXED (widget->parent))
+ {
+ old_x -= widget->parent->allocation.x;
+ old_y -= widget->parent->allocation.y;
+ }
+
+ gdk_window_get_pointer (widget->parent->window, &mouse_x, &mouse_y, NULL);
+ if (GTK_IS_FIXED (widget->parent))
+ {
+ mouse_x -= widget->parent->allocation.x;
+ mouse_y -= widget->parent->allocation.y;
+ }
+ if (GTK_IS_LAYOUT (widget->parent))
+ {
+ mouse_x += GTK_LAYOUT (widget->parent)->hadjustment->value;
+ mouse_y += GTK_LAYOUT (widget->parent)->vadjustment->value;
+ old_x += GTK_LAYOUT (widget->parent)->hadjustment->value;
+ old_y += GTK_LAYOUT (widget->parent)->vadjustment->value;
+ }
+
+ switch (drag_action)
+ {
+ case GB_TOP_LEFT:
+ new_x = snap_left_edge (mouse_x);
+ new_y = snap_top_edge (mouse_y);
+ new_width = drag_widget_x2 - new_x;
+ new_height = drag_widget_y2 - new_y;
+ if (new_width < MIN_WIDGET_WIDTH)
+ {
+ new_width = MIN_WIDGET_WIDTH;
+ new_x = drag_widget_x2 - new_width;
+ }
+ if (new_height < MIN_WIDGET_HEIGHT)
+ {
+ new_height = MIN_WIDGET_HEIGHT;
+ new_y = drag_widget_y2 - new_height;
+ }
+ break;
+
+ case GB_TOP_RIGHT:
+ new_x = drag_widget_x1;
+ new_y = snap_top_edge (mouse_y);
+ new_width = snap_right_edge (mouse_x) - new_x;
+ new_height = drag_widget_y2 - new_y;
+ if (new_width < MIN_WIDGET_WIDTH)
+ {
+ new_width = MIN_WIDGET_WIDTH;
+ }
+ if (new_height < MIN_WIDGET_HEIGHT)
+ {
+ new_height = MIN_WIDGET_HEIGHT;
+ new_y = drag_widget_y2 - new_height;
+ }
+ break;
+
+ case GB_BOTTOM_LEFT:
+ new_x = snap_left_edge (mouse_x);
+ new_y = drag_widget_y1;
+ new_width = drag_widget_x2 - new_x;
+ new_height = snap_bottom_edge (mouse_y) - new_y;
+ if (new_width < MIN_WIDGET_WIDTH)
+ {
+ new_width = MIN_WIDGET_WIDTH;
+ new_x = drag_widget_x2 - new_width;
+ }
+ if (new_height < MIN_WIDGET_HEIGHT)
+ new_height = MIN_WIDGET_HEIGHT;
+ break;
+
+ case GB_BOTTOM_RIGHT:
+ new_x = drag_widget_x1;
+ new_y = drag_widget_y1;
+ new_width = snap_right_edge (mouse_x) - new_x;
+ new_height = snap_bottom_edge (mouse_y) - new_y;
+ if (new_width < MIN_WIDGET_WIDTH)
+ new_width = MIN_WIDGET_WIDTH;
+ if (new_height < MIN_WIDGET_HEIGHT)
+ new_height = MIN_WIDGET_HEIGHT;
+ break;
+
+ case GB_MIDDLE:
+ new_x = snap_left_edge (mouse_x - drag_offset_x);
+ new_y = snap_top_edge (mouse_y - drag_offset_y);
+ new_width = widget->allocation.width;
+ new_height = widget->allocation.height;
+ if (new_x < 0)
+ new_x = 0;
+ if (new_y < 0)
+ new_y = 0;
+ break;
+ }
+
+#if 0
+ g_print ("old_x: %i old_y: %i new_x: %i new_y: %i w: %i h: %i\n",
+ widget->allocation.x, widget->allocation.y,
+ new_x, new_y, new_width, new_height);
+#endif
+
+ /* Only move/resize widget if values have changed */
+ if (new_width != widget->allocation.width
+ || new_height != widget->allocation.height)
+ {
+ wdata->width = new_width;
+ wdata->height = new_height;
+ gb_widget_set_usize (widget, new_width, new_height);
+ }
+
+ if (new_x != old_x || new_y != old_y)
+ {
+#if 0
+ g_print (" moving widget\n");
+#endif
+ if (GTK_IS_FIXED (widget->parent))
+ {
+ /* FIXME: GTK+ bug workaround. The widget doesn't move if we only
+ call gtk_fixed_move(). This is very slow as well. */
+ gtk_fixed_move (GTK_FIXED (widget->parent), widget, new_x, new_y);
+ /*gtk_widget_set_uposition (widget, new_x, new_y);*/
+ }
+ else if (GTK_IS_LAYOUT (widget->parent))
+ {
+ gtk_layout_move (GTK_LAYOUT (widget->parent), widget, new_x, new_y);
+ }
+
+ gtk_widget_queue_draw (widget->parent);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Adding signals to widgets to allow manipulation, e.g. selecting/drawing
+ */
+
+static void
+editor_on_widget_realize (GtkWidget *widget, gpointer data)
+{
+#if 0
+ static GdkPixmap *placeholder_pixmap = NULL;
+
+ g_print ("In editor_on_widget_realize widget:%s (%p)\n",
+ gtk_widget_get_name (widget), widget);
+
+ if (GB_IS_PLACEHOLDER (widget))
+ {
+ /* Create placeholder pixmap if it hasn't already been created.
+ There may be a problem with multi-depth displays. */
+ if (placeholder_pixmap == NULL)
+ {
+ placeholder_pixmap = gdk_pixmap_create_from_xpm_d (widget->window,
+ NULL, NULL,
+ placeholder_xpm);
+ if (!placeholder_pixmap)
+ {
+ g_warning ("Couldn't create placeholder pixmap\n");
+ /* FIXME: Use a color instead? */
+ }
+ }
+
+ if (placeholder_pixmap != NULL)
+ gdk_window_set_back_pixmap (widget->window, placeholder_pixmap, FALSE);
+ }
+#endif
+}
+
+
+/* This adds the button signals to an existing widget (currently only the
+ Clist title buttons). */
+void
+editor_add_mouse_signals_to_existing (GtkWidget * widget)
+{
+ gtk_signal_connect (GTK_OBJECT (widget), "event",
+ GTK_SIGNAL_FUNC (editor_on_event), NULL);
+#if 0
+ gtk_signal_connect (GTK_OBJECT (widget), "button_press_event",
+ GTK_SIGNAL_FUNC (editor_on_button_press), NULL);
+ gtk_signal_connect (GTK_OBJECT (widget), "button_release_event",
+ GTK_SIGNAL_FUNC (editor_on_button_release), NULL);
+#endif
+}
+
+
+static gint
+editor_on_enter_notify (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ /* We try to stop enter/leave notify events when moving/resizing widget in
+ a GtkFixed/GtkLayout as it causes flicker. */
+ return dragging_widget ? TRUE : FALSE;
+}
+
+
+static gint
+editor_on_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ /* We try to stop enter/leave notify events when moving/resizing widget in
+ a GtkFixed/GtkLayout as it causes flicker. */
+ return dragging_widget ? TRUE : FALSE;
+}
+
+
+static void
+add_mouse_signals_recursive (GtkWidget *widget, gpointer data)
+{
+#if 0
+ g_print ("Adding mouse signals to:%s (%s, %p)\n",
+ gtk_widget_get_name (widget),
+ gtk_type_name (GTK_OBJECT_TYPE (widget)),
+ widget);
+#endif
+
+ /* FIXME: We don't add signals to menu items, since it currently makes it
+ impossible to popup the menus in a menubar. */
+ if (GTK_IS_MENU_ITEM (widget))
+ return;
+
+ /* Ensure that the event mask is set so we get button press & release
+ events. */
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ if (!GTK_WIDGET_REALIZED (widget))
+ {
+ gtk_widget_set_events (widget, gtk_widget_get_events (widget)
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK);
+ }
+ else
+ {
+ GdkEventMask event_mask;
+
+ /* FIXME: Here we set the event mask for the main window of a widget,
+ but widgets can have more than one window. How do we get all the
+ windows of a widget? */
+ event_mask = gdk_window_get_events (widget->window);
+ gdk_window_set_events (widget->window, event_mask
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK);
+ }
+ }
+
+ gtk_signal_connect (GTK_OBJECT (widget), "event",
+ GTK_SIGNAL_FUNC (editor_on_event), NULL);
+#if 0
+ gtk_signal_connect (GTK_OBJECT (widget), "button_press_event",
+ GTK_SIGNAL_FUNC (editor_on_button_press), NULL);
+ gtk_signal_connect (GTK_OBJECT (widget), "button_release_event",
+ GTK_SIGNAL_FUNC (editor_on_button_release), NULL);
+#endif
+
+ /* We connect to these so we can stop widgets getting them while we are
+ dragging/resizing. It stops widgets changing state, i.e. normal/active
+ and so cuts down on flickering a bit. */
+ gtk_signal_connect (GTK_OBJECT (widget), "enter_notify_event",
+ GTK_SIGNAL_FUNC (editor_on_enter_notify), NULL);
+ gtk_signal_connect (GTK_OBJECT (widget), "leave_notify_event",
+ GTK_SIGNAL_FUNC (editor_on_leave_notify), NULL);
+
+ gb_widget_children_foreach (widget,
+ (GtkCallback) add_mouse_signals_recursive, NULL);
+}
+
+/* We need to be careful about passing events on to widgets, especially with
+ regard to mouse grabs - in a GtkEntry the mouse is grabbed while selecting
+ text, and this can cause all sorts of problems for Glade. */
+void
+editor_add_mouse_signals (GtkWidget * widget)
+{
+ /* Widgets without windows will not get events directly from X Windows,
+ but they may have child widgets which pass events up to them, e.g.
+ a GtkCombo has a GtkEntry which will get X events.
+ This doesn't matter too much since we have to call a function to figure
+ out which widget the event is for anyway. */
+ add_mouse_signals_recursive (widget, NULL);
+
+ gtk_signal_connect_after (GTK_OBJECT (widget), "realize",
+ GTK_SIGNAL_FUNC (editor_on_widget_realize), NULL);
+}
+
+void
+editor_add_key_signals (GtkWidget * widget)
+{
+ /* We only add key signal handlers to windows. */
+ if (!GTK_IS_WINDOW (widget))
+ return;
+
+ gtk_signal_connect (GTK_OBJECT (widget), "key_press_event",
+ GTK_SIGNAL_FUNC (editor_on_key_press_event), NULL);
+ gtk_signal_connect (GTK_OBJECT (widget), "key_release_event",
+ GTK_SIGNAL_FUNC (editor_on_key_release_event), NULL);
+}
+
+
+void
+on_size_allocate (GtkWidget * widget,
+ GtkAllocation *allocation,
+ GladeWidgetData * wdata)
+{
+ /* Reset the flag, since the size is allocated now. Note that wdata may be
+ NULL as widget may be a placeholder. */
+ if (wdata)
+ {
+ wdata->flags &= ~GLADE_SIZE_NOT_ALLOCATED;
+ }
+
+#if 0
+ g_print ("In on_size_allocate: %s (%p) x:%i y:%i w:%i h:%i\n",
+ gtk_widget_get_name (widget), widget, allocation->x, allocation->y,
+ allocation->width, allocation->height);
+#endif
+
+ if (property_get_widget () == widget)
+ {
+ gb_widget_show_position_properties (widget);
+
+ if (widget->parent && GTK_IS_FIXED (widget->parent))
+ {
+ property_set_auto_apply (FALSE);
+ property_set_int (GladeFixedChildX,
+ allocation->x - widget->parent->allocation.x);
+ property_set_int (GladeFixedChildY,
+ allocation->y - widget->parent->allocation.y);
+ property_set_auto_apply (TRUE);
+ }
+ else if (widget->parent && GTK_IS_LAYOUT (widget->parent))
+ {
+ property_set_auto_apply (FALSE);
+ property_set_int (GladeLayoutChildX, allocation->x);
+ property_set_int (GladeLayoutChildY, allocation->y);
+ property_set_auto_apply (TRUE);
+ }
+ }
+}
+
+
+void
+editor_add_draw_signals (GtkWidget * widget)
+{
+ GladeWidgetData *widget_data;
+
+ /* FIXME: Note that we set GDK_POINTER_MOTION_HINT_MASK here. This may not
+ be wise since widgets may be designed to work with normal motion events
+ only. Also this won't work if the widget is already realized. */
+ if (!GTK_WIDGET_NO_WINDOW (widget) && !GTK_WIDGET_REALIZED (widget))
+ gtk_widget_set_events (widget, gtk_widget_get_events (widget)
+ | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK);
+
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+
+ gtk_signal_connect (GTK_OBJECT (widget), "expose_event",
+ GTK_SIGNAL_FUNC (expose_widget), widget_data);
+ gtk_signal_connect_after (GTK_OBJECT (widget), "size_allocate",
+ GTK_SIGNAL_FUNC (on_size_allocate), widget_data);
+
+ /* FIXME: mouse signal - This also needs to be added to all children. */
+ gtk_signal_connect (GTK_OBJECT (widget), "motion_notify_event",
+ GTK_SIGNAL_FUNC (editor_on_motion_notify), NULL);
+
+ /* Needed for scrolled window, clist? & possibly other widgets */
+ if (GTK_IS_CONTAINER (widget))
+ gtk_container_forall (GTK_CONTAINER (widget),
+ (GtkCallback) editor_add_draw_signals, NULL);
+}
+
+
+
+static gint
+expose_widget (GtkWidget * widget, GdkEventExpose * event,
+ GladeWidgetData * widget_data)
+{
+ GtkWidgetClass *class;
+
+#if 0
+ g_print ("In expose_event widget:%s (%p)\n", gtk_widget_get_name (widget),
+ widget);
+ g_print ("Area x:%i y:%i w:%i h:%i\n", event->area.x, event->area.y,
+ event->area.width, event->area.height);
+#endif
+
+ /* Run the class handler here, then we return TRUE to stop the signal. */
+ class = GTK_WIDGET_GET_CLASS (widget);
+ if (class->expose_event)
+ class->expose_event (widget, event);
+
+ /* Ignore spurious exposes before widget is positioned. */
+ if (widget->allocation.x == -1 || widget->allocation.y == -1)
+ return TRUE;
+
+ paint_widget (widget, event);
+
+ return TRUE;
+}
+
+
+void
+paint_widget (GtkWidget * widget, GdkEventExpose *event)
+{
+ static GdkPixmap *placeholder_pixmap = NULL;
+ GType type;
+
+ MSG3 ("Painting widget: %s W:%i H:%i", gtk_widget_get_name (widget),
+ widget->allocation.width, widget->allocation.height);
+
+ /* Check widget is drawable in case it has been deleted. */
+ if (!GTK_WIDGET_DRAWABLE (widget))
+ return;
+
+ /* Don't try to draw anything if the width or height of the widget is 0. */
+ if (widget->allocation.width == 0 || widget->allocation.height == 0)
+ return;
+
+ /* If widget is a placeholder, draw the placeholder pixmap in it and a
+ 3D border around it. */
+ if (GB_IS_PLACEHOLDER (widget))
+ {
+ GdkGC *light_gc;
+ GdkGC *dark_gc;
+ gint w, h;
+
+ light_gc = widget->style->light_gc[GTK_STATE_NORMAL];
+ dark_gc = widget->style->dark_gc[GTK_STATE_NORMAL];
+ gdk_window_get_size (widget->window, &w, &h);
+
+ /* Draw the background pixmap. */
+ if (placeholder_pixmap == NULL)
+ {
+ /* FIXME: Use a hash of placeholder pixmaps? So we always use the
+ correct depth? */
+ placeholder_pixmap = gdk_pixmap_create_from_xpm_d (widget->window,
+ NULL, NULL,
+ placeholder_xpm);
+ if (!placeholder_pixmap)
+ {
+ g_warning ("Couldn't create placeholder pixmap\n");
+ /* FIXME: Use a color instead? */
+ }
+ }
+
+ if (placeholder_pixmap)
+ {
+ gdk_gc_set_fill (light_gc, GDK_TILED);
+ gdk_gc_set_tile (light_gc, placeholder_pixmap);
+ gdk_draw_rectangle (widget->window, light_gc, TRUE, 0, 0, w, h);
+ gdk_gc_set_fill (light_gc, GDK_SOLID);
+ }
+
+ gdk_draw_line (widget->window, light_gc, 0, 0, w - 1, 0);
+ gdk_draw_line (widget->window, light_gc, 0, 0, 0, h - 1);
+ gdk_draw_line (widget->window, dark_gc, 0, h - 1, w - 1, h - 1);
+ gdk_draw_line (widget->window, dark_gc, w - 1, 0, w - 1, h - 1);
+ }
+
+ if (event->window)
+ {
+ gpointer expose_widget;
+
+ gdk_window_get_user_data (event->window, &expose_widget);
+
+ if (expose_widget)
+ {
+ gtk_idle_add_priority (GTK_PRIORITY_DEFAULT + 10,
+ (GtkFunction)editor_idle_handler,
+ event->window);
+
+ /* We ref the window, to make sure it isn't freed before the idle
+ handler. We unref it there. */
+ gdk_window_ref (event->window);
+ }
+ }
+
+ /* Draw grid for fixed containers */
+ type = G_OBJECT_TYPE (widget);
+ if (GB_IS_GB_WIDGET (widget)
+ && (type == GTK_TYPE_FIXED || type == GTK_TYPE_LAYOUT))
+ draw_grid (widget);
+}
+
+
+/* This returns the window that the given widget's position is relative to.
+ Usually this is the widget's parent's window. But if the widget is a
+ toplevel, we use its own window, as it doesn't have a parent.
+ Some widgets also lay out widgets in different ways. */
+static GdkWindow*
+glade_util_get_window_positioned_in (GtkWidget *widget)
+{
+ GtkWidget *parent;
+
+ parent = widget->parent;
+
+#ifdef USE_GNOME
+ /* BonoboDockItem widgets use a different window when floating. */
+ if (BONOBO_IS_DOCK_ITEM (widget)
+ && BONOBO_DOCK_ITEM (widget)->is_floating) {
+ return BONOBO_DOCK_ITEM (widget)->float_window;
+ }
+
+ if (parent && BONOBO_IS_DOCK_ITEM (parent)
+ && BONOBO_DOCK_ITEM (parent)->is_floating) {
+ return BONOBO_DOCK_ITEM (parent)->float_window;
+ }
+#endif
+
+ if (parent)
+ return parent->window;
+
+ return widget->window;
+}
+
+static void
+glade_util_draw_nodes (GdkWindow *window, GdkGC *gc,
+ gint x, gint y,
+ gint width, gint height)
+{
+#if 0
+ g_print ("draw_nodes window: %p %i,%i %ix%i\n",
+ window, x, y, width, height);
+#endif
+ if (width > GB_CORNER_WIDTH && height > GB_CORNER_HEIGHT) {
+ gdk_draw_rectangle (window, gc, TRUE,
+ x, y,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ gdk_draw_rectangle (window, gc, TRUE,
+ x, y + height - GB_CORNER_HEIGHT,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ gdk_draw_rectangle (window, gc, TRUE,
+ x + width - GB_CORNER_WIDTH, y,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ gdk_draw_rectangle (window, gc, TRUE,
+ x + width - GB_CORNER_WIDTH,
+ y + height - GB_CORNER_HEIGHT,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ }
+
+ gdk_draw_rectangle (window, gc, FALSE, x, y, width - 1, height - 1);
+}
+
+/* This calculates the offset of the given window within its toplevel.
+ It also returns the toplevel. */
+static void
+glade_util_calculate_window_offset (GdkWindow *window,
+ gint *x, gint *y,
+ GdkWindow **toplevel)
+{
+ gint tmp_x, tmp_y;
+
+ /* Calculate the offset of the window within its toplevel. */
+ *x = 0;
+ *y = 0;
+
+ for (;;) {
+ if (gdk_window_get_window_type (window) != GDK_WINDOW_CHILD)
+ break;
+ gdk_window_get_position (window, &tmp_x, &tmp_y);
+ *x += tmp_x;
+ *y += tmp_y;
+ window = gdk_window_get_parent (window);
+ }
+
+ *toplevel = window;
+}
+
+/* This returns TRUE if it is OK to draw the selection nodes for the given
+ selected widget inside the given window that has received an expose event.
+ For most widgets it returns TRUE, but if a selected widget is inside a
+ widget like a viewport, that uses its own coordinate system, then it only
+ returns TRUE if the expose window is inside the viewport as well. */
+static gboolean
+glade_util_can_draw_nodes (GtkWidget *sel_widget, GdkWindow *sel_win,
+ GdkWindow *expose_win)
+{
+ GtkWidget *widget, *viewport = NULL;
+ GdkWindow *viewport_win = NULL;
+
+ /* Check if the selected widget is inside a viewport. */
+ for (widget = sel_widget->parent; widget; widget = widget->parent) {
+ if (GTK_IS_VIEWPORT (widget)) {
+ viewport = widget;
+ viewport_win = GTK_VIEWPORT (widget)->bin_window;
+ break;
+ }
+ }
+
+ /* If there is no viewport-type widget above the selected widget,
+ it is OK to draw the selection anywhere. */
+ if (!viewport)
+ return TRUE;
+
+ /* If we have a viewport-type widget, check if the expose_win is
+ beneath the viewport. If it is, we can draw in it. If not, we
+ can't.*/
+ for (;;) {
+ if (expose_win == sel_win)
+ return TRUE;
+ if (expose_win == viewport_win)
+ return FALSE;
+ if (gdk_window_get_window_type (expose_win) != GDK_WINDOW_CHILD)
+ break;
+ expose_win = gdk_window_get_parent (expose_win);
+ }
+
+ return FALSE;
+}
+
+
+/* This is coped from glade3/src/glade-utils.c glade_util_draw_nodes_idle(). */
+static gint
+editor_idle_handler (GdkWindow *expose_win)
+{
+ GtkWidget *expose_widget;
+ gint expose_win_x, expose_win_y;
+ gint expose_win_w, expose_win_h;
+ GdkWindow *expose_toplevel;
+ GdkGC *gc;
+ GList *elem;
+ gpointer expose_widget_ptr;
+
+ /* Find the corresponding GtkWidget. */
+ gdk_window_get_user_data (expose_win, &expose_widget_ptr);
+ expose_widget = GTK_WIDGET (expose_widget_ptr);
+
+ /* Check that the window is still alive. */
+ if (!expose_widget || !GTK_WIDGET_DRAWABLE (expose_widget)
+ || !gdk_window_is_viewable (expose_win))
+ goto out;
+
+ gc = expose_widget->style->black_gc;
+
+ /* Calculate the offset of the expose window within its toplevel. */
+ glade_util_calculate_window_offset (expose_win,
+ &expose_win_x,
+ &expose_win_y,
+ &expose_toplevel);
+
+#if 0
+ g_print ("expose_win: %p x: %i y: %i toplevel: %p\n",
+ expose_win, expose_win_x, expose_win_y, expose_toplevel);
+#endif
+ gdk_drawable_get_size (expose_win,
+ &expose_win_w, &expose_win_h);
+#if 0
+ g_print ("drawable size %ix%i\n", expose_win_w, expose_win_h);
+#endif
+ /* Step through all the selected widgets in the project. */
+ for (elem = selected_widgets; elem; elem = elem->next) {
+ GtkWidget *sel_widget;
+ GdkWindow *sel_win, *sel_toplevel;
+ gint sel_x, sel_y, x, y, w, h, sel_alloc_x, sel_alloc_y;
+
+ sel_widget = elem->data;
+
+ /* Skip the selected widget if it isn't realized. */
+ if (!GTK_WIDGET_REALIZED (sel_widget))
+ continue;
+
+ sel_win = glade_util_get_window_positioned_in (sel_widget);
+
+ /* Calculate the offset of the selected widget's window
+ within its toplevel. */
+ glade_util_calculate_window_offset (sel_win, &sel_x, &sel_y,
+ &sel_toplevel);
+
+#if 0
+ g_print ("sel_win: %p x: %i y: %i toplevel: %p allocation %i,%i\n",
+ sel_win, sel_x, sel_y, sel_toplevel,
+ sel_widget->allocation.x, sel_widget->allocation.y);
+#endif
+ /* Toplevel windows/dialogs may have their allocation set
+ relative to the root window, so we need to ignore that. */
+ if (sel_widget->parent)
+ {
+ sel_alloc_x = sel_widget->allocation.x;
+ sel_alloc_y = sel_widget->allocation.y;
+ }
+ else
+ {
+ sel_alloc_x = 0;
+ sel_alloc_y = 0;
+ }
+
+ /* We only draw the nodes if the window that got the expose
+ event is in the same toplevel as the selected widget. */
+ if (expose_toplevel == sel_toplevel
+ && glade_util_can_draw_nodes (sel_widget, sel_win,
+ expose_win)) {
+ x = sel_x + sel_alloc_x - expose_win_x;
+ y = sel_y + sel_alloc_y - expose_win_y;
+ w = sel_widget->allocation.width;
+ h = sel_widget->allocation.height;
+
+#if 0
+ g_print ("checking coords %i,%i %ix%i\n",
+ x, y, w, h);
+#endif
+ /* Draw the selection nodes if they intersect the
+ expose window bounds. */
+ if (x < expose_win_w && x + w >= 0
+ && y < expose_win_h && y + h >= 0) {
+ glade_util_draw_nodes (expose_win, gc,
+ x, y, w, h);
+ }
+ }
+ }
+
+ out:
+ /* Remove the reference added in glade_util_queue_draw_nodes(). */
+ gdk_window_unref (expose_win);
+
+ /* Return FALSE so the idle handler isn't called again. */
+ return FALSE;
+}
+
+
+static void
+draw_grid (GtkWidget * widget)
+{
+ GdkGC *gc = widget->style->dark_gc[GTK_STATE_NORMAL];
+ gint min_x = 0, max_x = widget->allocation.width - 1;
+ gint min_y = 0, max_y = widget->allocation.height - 1;
+ gint gridx, gridy, origin_x, origin_y;
+ GdkWindow *window;
+
+ if (!editor_show_grid)
+ return;
+
+ if (GTK_IS_LAYOUT (widget))
+ {
+ gint offset;
+
+ /* The window size is the entire size of the layout. The allocation is
+ the part that is showing. */
+ window = GTK_LAYOUT (widget)->bin_window;
+
+ origin_x = (int) GTK_LAYOUT (widget)->hadjustment->value;
+ min_x += origin_x;
+ max_x += origin_x;
+ offset = origin_x % editor_grid_horz_spacing;
+ if (offset != 0)
+ origin_x += editor_grid_horz_spacing - offset;
+
+ origin_y = (int) GTK_LAYOUT (widget)->vadjustment->value;
+ min_y += origin_y;
+ max_y += origin_y;
+ offset = origin_y % editor_grid_vert_spacing;
+ if (offset != 0)
+ origin_y += editor_grid_vert_spacing - offset;
+ }
+ else
+ {
+ /* The GtkFixed container doesn't have a window in GTK+ 2.0 (by default),
+ so we have to use the allocation. */
+ window = widget->window;
+ origin_x = widget->allocation.x;
+ origin_y = widget->allocation.y;
+ max_x += origin_x;
+ max_y += origin_y;
+ }
+
+ /* Note: should we take the border_width into account? - i.e. start the
+ grid inside the border. It makes it awkward if you change the border
+ size. */
+ if (editor_grid_style == GB_GRID_DOTS)
+ {
+ for (gridx = origin_x; gridx <= max_x; gridx += editor_grid_horz_spacing)
+ {
+ for (gridy = origin_y; gridy <= max_y;
+ gridy += editor_grid_vert_spacing)
+ gdk_draw_point (window, gc, gridx, gridy);
+ }
+ }
+ else
+ {
+ for (gridx = origin_x; gridx <= max_x; gridx += editor_grid_horz_spacing)
+ gdk_draw_line (window, gc, gridx, min_y, gridx, max_y);
+ for (gridy = origin_y; gridy <= max_y; gridy += editor_grid_vert_spacing)
+ gdk_draw_line (window, gc, min_x, gridy, max_x, gridy);
+ }
+}
+
+/*
+ * Redraw the given widget completely, including all space allocated by its
+ * parent (since this may be used for drawing the widget's selection).
+ * If widget has no parent (i.e. its a toplevel window) just clear
+ * it all and redraw.
+ */
+
+void
+editor_refresh_widget (GtkWidget * widget)
+{
+#if 0
+ g_print ("In editor_refresh_widget widget: %s (%p)\n",
+ gtk_widget_get_name (widget), widget);
+#endif
+
+ editor_refresh_widget_area (widget,
+ widget->allocation.x,
+ widget->allocation.y,
+ widget->allocation.width,
+ widget->allocation.height);
+ gtk_widget_draw (widget, NULL);
+}
+
+
+void
+editor_refresh_widget_selection (GtkWidget * widget)
+{
+ gint x, y, w, h;
+
+#if 0
+ g_print ("In editor_refresh_widget_selection widget: %s (%p)\n",
+ gtk_widget_get_name (widget), widget);
+#endif
+
+ x = widget->allocation.x;
+ y = widget->allocation.y;
+ w = widget->allocation.width;
+ h = widget->allocation.height;
+
+ /* Don't try to refresh an area if the width or height is 0. */
+ if (w == 0 || h == 0)
+ return;
+
+ /* Clear the four corners. */
+ editor_refresh_widget_area (widget,
+ x, y,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ editor_refresh_widget_area (widget,
+ x, y + h - GB_CORNER_HEIGHT,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ editor_refresh_widget_area (widget,
+ x + w - GB_CORNER_WIDTH, y,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ editor_refresh_widget_area (widget,
+ x + w - GB_CORNER_WIDTH,
+ y + h - GB_CORNER_HEIGHT,
+ GB_CORNER_WIDTH, GB_CORNER_HEIGHT);
+ /* Clear the four lines along the edges. */
+ editor_refresh_widget_area (widget,
+ x + GB_CORNER_WIDTH, y,
+ w - 2 * GB_CORNER_WIDTH, 1);
+ editor_refresh_widget_area (widget,
+ x + GB_CORNER_WIDTH, y + h - 1,
+ w - 2 * GB_CORNER_WIDTH, 1);
+ editor_refresh_widget_area (widget,
+ x, y + GB_CORNER_HEIGHT,
+ 1, h - 2 * GB_CORNER_HEIGHT);
+ editor_refresh_widget_area (widget,
+ x + w - 1,
+ y + GB_CORNER_HEIGHT,
+ 1, h - 2 * GB_CORNER_HEIGHT);
+
+ gtk_widget_draw (widget, NULL);
+}
+
+
+void
+editor_refresh_widget_area (GtkWidget * widget, gint x, gint y, gint w, gint h)
+{
+ GdkWindow *window;
+
+ if (!GTK_WIDGET_DRAWABLE (widget))
+ return;
+
+ /* Don't try to refresh an area if the width or height is 0. */
+ if (w <= 0 || h <= 0)
+ return;
+
+ window = glade_util_get_window_positioned_in (widget);
+ gdk_window_clear_area (window, x, y, w, h);
+ clear_child_windows (window, x, y, w, h);
+}
+
+
+/* This clears all child windows which fall within the given rectangle.
+ If the rectangle width is -1, then all children are cleared. */
+static void
+clear_child_windows (GdkWindow * window, gint x, gint y, gint w, gint h)
+{
+ GList *children, *orig_children;
+ GdkWindow *child_window;
+ gint win_x, win_y, win_w, win_h;
+ GdkRectangle area, child, intersection;
+
+ area.x = x;
+ area.y = y;
+ area.width = w;
+ area.height = h;
+
+ orig_children = children = gdk_window_get_children (window);
+ while (children)
+ {
+ child_window = children->data;
+ gdk_window_get_position (child_window, &win_x, &win_y);
+ gdk_window_get_size (child_window, &win_w, &win_h);
+
+ child.x = win_x;
+ child.y = win_y;
+ child.width = win_w;
+ child.height = win_h;
+
+ if (gdk_rectangle_intersect (&area, &child, &intersection))
+ {
+ /* We need to make sure this is not an InputOnly window, or we get
+ a BadMatch. CList uses InputOnly windows - for resizing columns.
+ */
+ if (! GDK_WINDOW_OBJECT(child_window)->input_only)
+ {
+ /* Convert to the child's coordinate space. */
+ intersection.x -= child.x;
+ intersection.y -= child.y;
+ gdk_window_clear_area (child_window,
+ intersection.x, intersection.y,
+ intersection.width, intersection.height);
+ clear_child_windows (child_window,
+ intersection.x, intersection.y,
+ intersection.width, intersection.height);
+ }
+ }
+ children = children->next;
+ }
+ g_list_free (orig_children);
+}
+
+
+
+/*
+ * Key events
+ */
+static gint
+editor_on_key_press_event (GtkWidget * widget, GdkEventKey * event,
+ gpointer data)
+{
+ gboolean handled = FALSE;
+ guint key = event->keyval;
+
+ MSG ("In on_key_press_event");
+ switch (key)
+ {
+ case GDK_Delete:
+ /* If we are typing over the widget, the delete key is used for that
+ rather than deleting the widget. */
+ if (!property_is_typing_over_widget ())
+ {
+ if (selected_widgets)
+ delete (selected_widgets->data);
+ handled = TRUE;
+ }
+ break;
+ case GDK_Escape:
+ editor_clear_selection (NULL);
+ handled = TRUE;
+ break;
+ case GDK_l:
+ /* Ctrl-L refreshes the entire window/dialog. */
+ if (event->state & GDK_CONTROL_MASK)
+ {
+ editor_refresh_widget (glade_util_get_toplevel (widget));
+ handled = TRUE;
+ }
+ break;
+ case GDK_r:
+ /* Ctrl-R hides the window and shows it again in the same position.
+ Hopefully it will appear at the 'real' size. */
+ if (event->state & GDK_CONTROL_MASK)
+ {
+ GtkWidget *toplevel;
+
+ /* See also gb_widget_redisplay_window() in gbwidget.c. */
+ toplevel = glade_util_get_toplevel (widget);
+ glade_util_close_window (toplevel);
+ gtk_window_reshow_with_initial_size (GTK_WINDOW (toplevel));
+ handled = TRUE;
+ }
+ break;
+ }
+
+#if 0
+ /* We don't want modifier keys to be redirected, since trying to use an
+ accelerator, e.g. Ctrl-X to cut the widget, would clear the label. */
+ if (!handled
+ && !(event->state & GDK_CONTROL_MASK)
+ && key != GDK_Caps_Lock
+ && key != GDK_Tab && key != GDK_KP_Tab
+ && key != GDK_Left && key != GDK_KP_Left
+ && key != GDK_Right && key != GDK_KP_Right
+ && key != GDK_Up && key != GDK_KP_Up
+ && key != GDK_Down && key != GDK_KP_Down
+ && key != GDK_Page_Up && key != GDK_KP_Page_Up
+ && key != GDK_Page_Down && key != GDK_KP_Page_Down
+ && key != GDK_Home && key != GDK_KP_Home
+ && key != GDK_End && key != GDK_KP_End
+ && key != GDK_Control_L && key != GDK_Control_R
+ && key != GDK_Shift_L && key != GDK_Shift_R
+ && key != GDK_Meta_L && key != GDK_Meta_R
+ && key != GDK_Alt_L && key != GDK_Alt_R
+ && key != GDK_Super_L && key != GDK_Super_R
+ && key != GDK_Hyper_L && key != GDK_Hyper_R)
+ {
+ /* Experimental code. */
+#if 0
+ g_print ("Set label? widget=%s\n",
+ mouse_over_widget ? gtk_widget_get_name (mouse_over_widget) : "NULL");
+#endif
+ if (mouse_over_widget
+ && (GTK_IS_ACCEL_LABEL (mouse_over_widget)
+ || GTK_IS_LABEL (mouse_over_widget)
+ || GTK_IS_BUTTON (mouse_over_widget)))
+ {
+ gb_widget_show_properties (mouse_over_widget);
+ property_redirect_key_press (event);
+ handled = TRUE;
+ }
+ }
+#endif
+
+ if (handled)
+ {
+#if 0
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
+#endif
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gint
+editor_on_key_release_event (GtkWidget * widget, GdkEventKey * event,
+ gpointer data)
+{
+ MSG ("In on_key_release_event");
+
+ return FALSE;
+}
+
+
+
+/* This is when the 'Select' menuitem on the popup menu is selected */
+void
+editor_on_select_activate (GtkWidget * menuitem, GtkWidget * widget)
+{
+ editor_select_widget (widget, NULL, 0, 0);
+}
+
+
+
+void
+editor_on_delete ()
+{
+ if (selected_widgets)
+ delete (selected_widgets->data);
+}
+
+
+/* This is when the 'Cut' menuitem on the popup menu is selected */
+void
+editor_on_cut_activate (GtkWidget * menuitem, GtkWidget * widget)
+{
+ glade_clipboard_cut (GLADE_CLIPBOARD (glade_clipboard), current_project,
+ widget);
+}
+
+
+/* This is when the 'Copy' menuitem on the popup menu is selected */
+void
+editor_on_copy_activate (GtkWidget * menuitem, GtkWidget * widget)
+{
+ glade_clipboard_copy (GLADE_CLIPBOARD (glade_clipboard), current_project,
+ widget);
+}
+
+
+/* This is when the 'Cut' menuitem on the popup menu is selected */
+void
+editor_on_paste_activate (GtkWidget * menuitem, GtkWidget * widget)
+{
+ glade_clipboard_paste (GLADE_CLIPBOARD (glade_clipboard), current_project,
+ widget);
+}
+
+
+/* This is when the 'Delete' menuitem on the popup menu is selected */
+void
+editor_on_delete_activate (GtkWidget * menuitem, GtkWidget * widget)
+{
+ delete (widget);
+}
+
+
+static void
+delete (GtkWidget * widget)
+{
+ if (GB_IS_PLACEHOLDER (widget))
+ delete_placeholder (widget);
+ else
+ editor_delete_widget (widget);
+}
+
+
+static void
+delete_placeholder (GtkWidget * placeholder)
+{
+ GtkWidget *parent = placeholder->parent;
+ gchar *child_name;
+
+ /* SPECIAL CODE: Don't allow placeholders in clist titles to be deleted. */
+ child_name = gb_widget_get_child_name (placeholder);
+ if (child_name)
+ {
+ if (!strcmp (child_name, GladeChildCListTitle))
+ {
+ MSG1 ("Not deleting special widget: %s\n", child_name);
+ return;
+ }
+ }
+
+ /* SPECIAL CODE: Don't allow placeholder in BonoboDock to be deleted. */
+#ifdef USE_GNOME
+ if (BONOBO_IS_DOCK (parent))
+ return;
+#endif
+
+ /* Remove widget from the selection */
+ editor_clear_selection (NULL);
+
+ /* Can't delete children of a paned or a viewport */
+ if (GTK_IS_PANED (parent) || GTK_IS_VIEWPORT (parent))
+ return;
+
+ /* For a Clist, we can delete everything except column title widgets */
+ if (GTK_IS_CLIST (parent))
+ {
+ g_warning ("Deleting a widget in a clist - not implemented yet");
+ return;
+ }
+
+ /* If the parent is a toolitem, delete that. */
+ if (GTK_IS_TOOL_ITEM (parent))
+ {
+ gtk_container_remove (GTK_CONTAINER (parent->parent), parent);
+ return;
+ }
+
+ /* Widgets with these parents can all be deleted OK */
+ if (GTK_IS_TOOLBAR (parent)
+#if GLADE_SUPPORTS_GTK_TREE
+ || GTK_IS_TREE (parent)
+#endif
+ || GTK_IS_LIST (parent))
+ {
+ gtk_widget_destroy (placeholder);
+ return;
+ }
+
+ /* For a frame we can delete a placeholder in the label widget on its own.
+ Otherwise we delete the parent, just like GtkBin. */
+ if (GTK_IS_FRAME (parent))
+ {
+ if (gtk_frame_get_label_widget (GTK_FRAME (parent)) == placeholder)
+ gtk_widget_destroy (placeholder);
+ else
+ editor_delete_widget (parent);
+ return;
+ }
+
+ /* For these widgets replace the parent with a placeholder, or delete the
+ component if parent is a toplevel widget */
+ if (GTK_IS_BIN (parent) || GTK_IS_BUTTON (parent))
+ {
+ editor_delete_widget (parent);
+ return;
+ }
+
+ /* For a box, if the placeholder is the only child then replace the box with
+ a placeholder, else just delete the placeholder */
+ if (GTK_IS_BOX (parent))
+ {
+ if (g_list_length (GTK_BOX (parent)->children) == 1)
+ {
+ editor_delete_widget (parent);
+ }
+ else
+ {
+ gtk_container_remove (GTK_CONTAINER (parent), placeholder);
+ /* Shouldn't really need to do this */
+ gtk_widget_queue_resize (parent);
+ }
+ return;
+ }
+
+ /* For a notebook, if placeholder is the only page, replace the notebook with
+ a placeholder, else delete the current notebook page (i.e. placeholder) */
+ if (GTK_IS_NOTEBOOK (parent))
+ {
+ if (g_list_length (GTK_NOTEBOOK (parent)->children) == 1)
+ {
+ editor_delete_widget (parent);
+ }
+ else
+ {
+ gtk_notebook_remove_page (GTK_NOTEBOOK (parent), gtk_notebook_get_current_page (GTK_NOTEBOOK (parent)));
+ }
+ return;
+ }
+
+ /* For a table, can't delete placeholder, unless there is only 1 row or
+ column. In this case delete the placeholder, and move all the other
+ children up/left. If the table is 1 x 1 then delete the table. */
+ if (GTK_IS_TABLE (parent))
+ {
+ gint nrows, ncols, position = 0, distance_to_move = 0;
+ GList *item;
+ GtkTableChild *table_child;
+
+ nrows = GTK_TABLE (parent)->nrows;
+ ncols = GTK_TABLE (parent)->ncols;
+ if (nrows > 1 && ncols > 1)
+ return;
+ if (nrows == 1 && ncols == 1)
+ {
+ editor_delete_widget (parent);
+ return;
+ }
+
+ /* Find out where placeholder is */
+ item = GTK_TABLE (parent)->children;
+ while (item)
+ {
+ table_child = (GtkTableChild *) item->data;
+
+ if (table_child->widget == placeholder)
+ {
+ /* Calculate how far up/left we will have to move the rest of the
+ children */
+ if (nrows == 1)
+ {
+ position = table_child->left_attach;
+ distance_to_move = table_child->right_attach
+ - table_child->left_attach;
+ }
+ else
+ {
+ position = table_child->top_attach;
+ distance_to_move = table_child->bottom_attach
+ - table_child->top_attach;
+ }
+ break;
+ }
+ item = item->next;
+ }
+ /* Shouldn't reach the end of the list */
+ g_return_if_fail (item != NULL);
+ gtk_widget_destroy (placeholder);
+
+ /* Now step through the table again, moving children up or left */
+ item = GTK_TABLE (parent)->children;
+ while (item)
+ {
+ table_child = (GtkTableChild *) item->data;
+ if (nrows == 1)
+ {
+ if (table_child->left_attach > position)
+ {
+ table_child->left_attach -= distance_to_move;
+ table_child->right_attach -= distance_to_move;
+ }
+ }
+ else
+ {
+ if (table_child->top_attach > position)
+ {
+ table_child->top_attach -= distance_to_move;
+ table_child->bottom_attach -= distance_to_move;
+ }
+ }
+ item = item->next;
+ }
+
+ /* Now update the tables nrows & ncols */
+ if (nrows == 1)
+ GTK_TABLE (parent)->ncols -= distance_to_move;
+ else
+ GTK_TABLE (parent)->nrows -= distance_to_move;
+
+ return;
+ }
+
+ g_warning ("Don't know how to delete widget");
+}
+
+
+void
+editor_delete_widget (GtkWidget * widget)
+{
+ GtkWidget *parent, *placeholder;
+ gchar *error;
+
+ MSG1 ("In editor_delete_widget: %s\n", gtk_widget_get_name (widget));
+
+ error = editor_can_delete_widget (widget);
+ if (error)
+ {
+ glade_util_show_message_box (error, widget);
+ return;
+ }
+
+ /* If we are deleting a GtkTextView set the text to "". This avoids an odd
+ crash. See bug #111604. */
+ if (GTK_IS_TEXT_VIEW (widget))
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)), "", 0);
+
+ /* Set properties widget to NULL, in case the widget or parent is deleted */
+ property_set_widget (NULL);
+
+ /* Remove widget from the selection */
+ editor_clear_selection (NULL);
+
+ if (GTK_IS_MENU (widget))
+ parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ else
+ parent = widget->parent;
+
+ /* If widget is a toplevel widget (i.e. a project component) delete the
+ component. */
+ if (parent == NULL)
+ {
+ glade_project_remove_component (current_project, widget);
+ return;
+ }
+
+ /* If the widget's parent is a fixed container or a packer remove the widget
+ completely. */
+ if (GTK_IS_FIXED (widget->parent)
+#if GLADE_SUPPORTS_GTK_PACKER
+ || GTK_IS_PACKER (widget->parent)
+#endif
+ || GTK_IS_LAYOUT (widget->parent))
+ {
+ gtk_widget_destroy (widget);
+ return;
+ }
+
+ /* If the widget's parent is a button box remove widget completely. */
+ if (GTK_IS_BUTTON_BOX (widget->parent))
+ {
+ gtk_widget_destroy (widget);
+ return;
+ }
+
+ /* If the widget is a menu item remove widget completely. */
+ if (GTK_IS_MENU_ITEM (widget))
+ {
+ gtk_widget_destroy (widget);
+ return;
+ }
+
+#ifdef USE_GNOME
+ /* GnomeDockItem widgets are also removed completely rather than being
+ replaced by a placeholder. */
+ if (BONOBO_IS_DOCK_ITEM (widget))
+ {
+ gtk_widget_destroy (widget);
+ return;
+ }
+
+ /* If this is a page in a GnomeDruid, then if it is the only page delete
+ the entire GnomeDruid, else delete the page. We need to make sure the
+ current page is set to something else before deleting the page. */
+ if (GNOME_IS_DRUID_PAGE (widget))
+ {
+ gint num_pages;
+ GList *children, *elem;
+ GnomeDruidPage *new_current_page;
+
+ g_return_if_fail (GNOME_IS_DRUID (parent));
+
+ children = gtk_container_get_children (GTK_CONTAINER (parent));
+ num_pages = g_list_length (children);
+ if (num_pages == 1)
+ {
+ editor_delete_widget (parent);
+ }
+ else
+ {
+ elem = g_list_find (children, widget);
+ g_return_if_fail (elem != NULL);
+
+ if (elem->next)
+ new_current_page = elem->next->data;
+ else
+ new_current_page = elem->prev->data;
+
+ gnome_druid_set_page (GNOME_DRUID (parent), new_current_page);
+
+ gtk_widget_destroy (widget);
+ }
+
+ g_list_free (children);
+
+ return;
+ }
+#endif
+
+ /* Replace normal widget's with a placeholder & select it so it can also
+ be deleted easily using the Delete key. But we must be careful since
+ there is a slight chance that the placeholder will be automatically
+ destroyed, e.g. if it is placed in a table which already has another
+ widget in the same position. */
+ placeholder = editor_new_placeholder ();
+ gtk_widget_ref (placeholder);
+ if (gb_widget_replace_child (widget->parent, widget, placeholder))
+ {
+ if (placeholder->parent)
+ editor_select_widget (placeholder, NULL, 0, 0);
+ gtk_widget_unref (placeholder);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't delete widget."), widget);
+ gtk_object_sink (GTK_OBJECT (placeholder));
+ gtk_widget_unref (placeholder);
+ }
+
+ MSG ("Out editor_delete_widget");
+}
+
+
+/* This sees if a widget can be deleted. It returns an appropriate error
+ message if it can't. */
+gchar*
+editor_can_delete_widget (GtkWidget * widget)
+{
+ gchar *child_name;
+
+ /* Button & item children are special - they can be deleted. */
+ if (widget->parent && GB_IS_GB_WIDGET (widget->parent)
+ && (GTK_IS_BUTTON (widget->parent) || GTK_IS_ITEM (widget->parent)))
+ return NULL;
+
+ /* Don't allow widgets which aren't GbWidgets to be deleted, since we know
+ nothing about them. */
+ if (!GB_IS_PLACEHOLDER (widget) && !GB_IS_GB_WIDGET (widget))
+ return _("The widget can't be deleted");
+
+ /* Non-toplevel menus are created automatically so we can't delete them. */
+ if (GTK_IS_MENU (widget) && gtk_menu_get_attach_widget (GTK_MENU (widget)))
+ return _("The widget can't be deleted");
+
+
+ /* SPECIAL CODE: Don't allow dialog buttons & widgets to be deleted. */
+ child_name = gb_widget_get_child_name (widget);
+ if (child_name)
+ {
+ if (!strcmp (child_name, GladeChildOKButton)
+ || !strcmp (child_name, GladeChildCancelButton)
+ || !strcmp (child_name, GladeChildHelpButton)
+ || !strcmp (child_name, GladeChildApplyButton)
+ || !strcmp (child_name, GladeChildSaveButton)
+ || !strcmp (child_name, GladeChildCloseButton)
+ || !strcmp (child_name, GladeChildDialogVBox)
+ || !strcmp (child_name, GladeChildDialogActionArea)
+ || !strcmp (child_name, GladeChildComboEntry)
+ || !strcmp (child_name, GladeChildComboList)
+ || !strcmp (child_name, GladeChildFontSelection)
+ || !strcmp (child_name, GladeChildColorSelection)
+#ifdef USE_GNOME
+ || !strcmp (child_name, GladeChildGnomeAppDock)
+ || !strcmp (child_name, GladeChildGnomeAppBar)
+ || !strcmp (child_name, GladeChildGnomeDruidVBox)
+ || !strcmp (child_name, GladeChildGnomeEntry)
+#endif
+ )
+ {
+ return _("The widget is created automatically as part of the parent widget, and it can't be deleted.");
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Called when a GbWidget is destroyed so the editor can remove any references
+ to it. */
+void
+editor_on_widget_destroyed (GtkWidget *widget)
+{
+#if 0
+ const char *name = gtk_widget_get_name (widget);
+ g_print ("In editor_on_widget_destroyed: %s\n", name ? name : "NULL");
+#endif
+
+ if (mouse_over_widget == widget)
+ {
+#if 0
+ g_print (" resetting mouse_over_widget to NULL\n");
+#endif
+ mouse_over_widget = NULL;
+ }
+}
+
diff --git a/tools/glade/glade/editor.h b/tools/glade/glade/editor.h
new file mode 100644
index 00000000..082f3c31
--- /dev/null
+++ b/tools/glade/glade/editor.h
@@ -0,0 +1,107 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_EDITOR_H
+#define GLADE_EDITOR_H
+
+#include <gtk/gtkwidget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* The size of the selection handles in the corners of widgets */
+#define GB_CORNER_WIDTH 7
+#define GB_CORNER_HEIGHT 7
+
+
+void editor_init (void);
+
+/* Grid and snap settings */
+gboolean editor_get_show_grid (void);
+void editor_set_show_grid (gboolean show);
+void editor_show_grid_settings_dialog (GtkWidget *widget);
+
+gboolean editor_get_snap_to_grid (void);
+void editor_set_snap_to_grid (gboolean snap);
+void editor_show_snap_settings_dialog (GtkWidget *widget);
+
+/* Signal handlers */
+gint editor_close_window (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data);
+
+void editor_on_delete (void);
+
+/* These are from the popup context-sensitive menus */
+void editor_on_select_activate (GtkWidget *menuitem,
+ GtkWidget *widget);
+void editor_on_cut_activate (GtkWidget *menuitem,
+ GtkWidget *widget);
+void editor_on_copy_activate (GtkWidget *menuitem,
+ GtkWidget *widget);
+void editor_on_paste_activate (GtkWidget *menuitem,
+ GtkWidget *widget);
+void editor_on_delete_activate (GtkWidget *menuitem,
+ GtkWidget *widget);
+
+/* General functions */
+gboolean editor_select_widget_control (GtkWidget *widget);
+gboolean editor_select_widget (GtkWidget *widget,
+ GdkEventButton *event,
+ gint x,
+ gint y);
+gboolean editor_is_selected (GtkWidget *widget);
+/* This sets the list of selected widgets, possibly NULL. It takes control
+ of the GList, so don't free it. */
+void editor_set_selection (GList *new_selection);
+void editor_dump_selection (void);
+
+/* Returns NULL if a widget can be deleted, or an error message. */
+gchar* editor_can_delete_widget (GtkWidget *widget);
+
+void editor_delete_widget (GtkWidget *widget);
+
+GtkWidget* editor_new_placeholder (void);
+
+void editor_add_key_signals (GtkWidget *widget);
+void editor_add_mouse_signals (GtkWidget *widget);
+void editor_add_mouse_signals_to_existing(GtkWidget *widget);
+void editor_add_draw_signals (GtkWidget *widget);
+
+void editor_refresh_widget (GtkWidget *widget);
+void editor_refresh_widget_selection (GtkWidget *widget);
+void editor_refresh_widget_area (GtkWidget *widget,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
+
+GList* editor_get_selection (void);
+gint editor_clear_selection (GtkWidget *leave_widget);
+void editor_remove_widget_from_selection (GtkWidget *widget);
+void editor_deselect_all_placeholders (void);
+
+/* Called when a GbWidget is destroyed so the editor can remove any references
+ to it. */
+void editor_on_widget_destroyed (GtkWidget *widget);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_EDITOR_H */
diff --git a/tools/glade/glade/gb.c b/tools/glade/glade/gb.c
new file mode 100644
index 00000000..7c5ed61c
--- /dev/null
+++ b/tools/glade/glade/gb.c
@@ -0,0 +1,162 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 2001 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Common data.
+ */
+
+#include <config.h>
+
+#include <gtk/gtkenums.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkstock.h>
+#include "gb.h"
+
+
+/* Keys used to store a pointer to the parent widget. Currently we only need
+ this for the GtkCombo popup window, as there is no way to step up to the
+ GtkCombo. */
+const gchar *GladeParentKey = "GladeParentKey";
+
+
+/* Keys used to store object data. */
+const gchar *GladeButtonStockIDKey = "GladeButtonStockIDKey";
+const gchar *GladeDialogResponseIDKey = "GladeDialogResponseIDKey";
+
+const gchar *GladeToolButtonStockIDKey = "GladeToolButtonStockIDKey";
+const gchar *GladeToolButtonIconKey = "GladeToolButtonIconKey";
+
+
+/* Special child names. */
+const gchar *GladeChildDialogVBox = "vbox";
+const gchar *GladeChildDialogActionArea = "action_area";
+
+const gchar *GladeChildOKButton = "ok_button";
+const gchar *GladeChildCancelButton = "cancel_button";
+const gchar *GladeChildApplyButton = "apply_button";
+const gchar *GladeChildHelpButton = "help_button";
+const gchar *GladeChildSaveButton = "save_button";
+const gchar *GladeChildCloseButton = "close_button";
+
+const gchar *GladeChildMenuItemImage = "image";
+
+const gchar *GladeChildComboEntry = "entry";
+const gchar *GladeChildComboList = "list";
+
+const gchar *GladeChildFontSelection = "font_selection";
+const gchar *GladeChildColorSelection = "color_selection";
+
+const gchar *GladeChildGnomeAppDock = "dock";
+const gchar *GladeChildGnomeAppBar = "appbar";
+const gchar *GladeChildGnomeEntry = "entry";
+const gchar *GladeChildGnomePBoxNotebook= "notebook";
+const gchar *GladeChildGnomeDruidVBox = "vbox";
+
+const gchar *GladeChildBonoboWindowDock = "dock";
+const gchar *GladeChildBonoboWindowAppBar = "appbar";
+
+/* These aren't saved in the XML. */
+const gchar *GladeChildCListTitle = "clist_title";
+
+
+/* Note the trailing NULL in Choices is for the property_add_choice() call,
+ though it isn't included in the ChoicesSize. */
+
+/*
+ * Relief Choices.
+ */
+const gchar *GladeReliefChoices[] =
+{
+ "Normal",
+ "Half",
+ "None",
+ NULL
+};
+const gint GladeReliefValues[] =
+{
+ GTK_RELIEF_NORMAL,
+ GTK_RELIEF_HALF,
+ GTK_RELIEF_NONE
+};
+const gchar *GladeReliefSymbols[] =
+{
+ "GTK_RELIEF_NORMAL",
+ "GTK_RELIEF_HALF",
+ "GTK_RELIEF_NONE"
+};
+const int GladeReliefChoicesSize = G_N_ELEMENTS (GladeReliefValues);
+
+
+/*
+ * Shadow Choices.
+ */
+const gchar *GladeShadowChoices[] =
+{ "None", "In", "Out", "Etched In", "Etched Out", NULL};
+const gint GladeShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+const gchar *GladeShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+const int GladeShadowChoicesSize = G_N_ELEMENTS (GladeShadowValues);
+
+
+/*
+ * Corner Choices.
+ */
+const gchar *GladeCornerChoices[] =
+{ "Top Left", "Bottom Left", "Top Right", "Bottom Right", NULL};
+const gint GladeCornerValues[] =
+{
+ GTK_CORNER_TOP_LEFT,
+ GTK_CORNER_BOTTOM_LEFT,
+ GTK_CORNER_TOP_RIGHT,
+ GTK_CORNER_BOTTOM_RIGHT
+};
+const gchar *GladeCornerSymbols[] =
+{
+ "GTK_CORNER_TOP_LEFT",
+ "GTK_CORNER_BOTTOM_LEFT",
+ "GTK_CORNER_TOP_RIGHT",
+ "GTK_CORNER_BOTTOM_RIGHT"
+};
+const int GladeCornerChoicesSize = G_N_ELEMENTS (GladeCornerValues);
+
+
+GladeDialogResponse GladeStockResponses[] = {
+ { "GTK_RESPONSE_OK", GTK_RESPONSE_OK, GTK_STOCK_OK },
+ { "GTK_RESPONSE_CANCEL", GTK_RESPONSE_CANCEL, GTK_STOCK_CANCEL },
+ { "GTK_RESPONSE_CLOSE", GTK_RESPONSE_CLOSE, GTK_STOCK_CLOSE },
+ { "GTK_RESPONSE_YES", GTK_RESPONSE_YES, GTK_STOCK_YES },
+ { "GTK_RESPONSE_NO", GTK_RESPONSE_NO, GTK_STOCK_NO },
+ { "GTK_RESPONSE_APPLY", GTK_RESPONSE_APPLY, GTK_STOCK_APPLY },
+ { "GTK_RESPONSE_HELP", GTK_RESPONSE_HELP, GTK_STOCK_HELP },
+ { "GTK_RESPONSE_REJECT", GTK_RESPONSE_REJECT, NULL },
+ { "GTK_RESPONSE_ACCEPT", GTK_RESPONSE_ACCEPT, NULL }
+};
+const gint GladeStockResponsesSize = G_N_ELEMENTS (GladeStockResponses);
diff --git a/tools/glade/glade/gb.h b/tools/glade/glade/gb.h
new file mode 100644
index 00000000..d827d7d2
--- /dev/null
+++ b/tools/glade/glade/gb.h
@@ -0,0 +1,426 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef GLADE_GB_H
+#define GLADE_GB_H
+
+/* This header file is included by all gbwidgets in the gbwidget directory,
+ so if we add any header files to Glade, we only have to change this. */
+
+#include "gladeconfig.h"
+
+#include <string.h>
+
+#include "editor.h"
+#include "gbwidget.h"
+#include "glade_project.h"
+#include "load.h"
+#include "property.h"
+#include "save.h"
+#include "source.h"
+#include "utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* The package name we need to pass to dgettext to get GTK+'s translated
+ strings. */
+#define GLADE_GTK_GETTEXT_PACKAGE "gtk20"
+
+
+ /* The index of the dialog hint in GbTypeHintChoices. */
+#define GLADE_TYPE_HINT_DIALOG_INDEX 1
+
+/* This is the error margin we use for floating-point comparisons. */
+#define GLADE_EPSILON 0.000001
+
+/* This value is copied from gnome-entry.c. */
+#define GLADE_DEFAULT_MAX_HISTORY_SAVED 10
+
+/* Keys used to store a pointer to the parent widget. Currently we only need
+ this for the GtkCombo popup window, as there is no way to step up to the
+ GtkCombo. */
+extern const gchar *GladeParentKey;
+
+/* Keys used to store object data. */
+extern const gchar *GladeButtonStockIDKey;
+extern const gchar *GladeDialogResponseIDKey;
+
+extern const gchar *GladeToolButtonStockIDKey;
+extern const gchar *GladeToolButtonIconKey;
+
+/* The moniker key, only used for Bonobo controls. */
+extern const gchar *Moniker;
+
+extern const gint GladeReliefChoicesSize;
+extern const gchar *GladeReliefChoices[];
+extern const gint GladeReliefValues[];
+extern const gchar *GladeReliefSymbols[];
+
+extern const gint GladeShadowChoicesSize;
+extern const gchar *GladeShadowChoices[];
+extern const gint GladeShadowValues[];
+extern const gchar *GladeShadowSymbols[];
+
+extern const gint GladeCornerChoicesSize;
+extern const gchar *GladeCornerChoices[];
+extern const gint GladeCornerValues[];
+extern const gchar *GladeCornerSymbols[];
+
+/* Special child names. */
+extern const gchar *GladeChildDialogVBox;
+extern const gchar *GladeChildDialogActionArea;
+
+extern const gchar *GladeChildOKButton;
+extern const gchar *GladeChildCancelButton;
+extern const gchar *GladeChildApplyButton;
+extern const gchar *GladeChildHelpButton;
+extern const gchar *GladeChildSaveButton;
+extern const gchar *GladeChildCloseButton;
+
+extern const gchar *GladeChildMenuItemImage;
+
+extern const gchar *GladeChildComboEntry;
+extern const gchar *GladeChildComboList;
+
+extern const gchar *GladeChildFontSelection;
+extern const gchar *GladeChildColorSelection;
+
+extern const gchar *GladeChildGnomeAppDock;
+extern const gchar *GladeChildGnomeAppBar;
+extern const gchar *GladeChildGnomeEntry;
+extern const gchar *GladeChildGnomePBoxNotebook;
+extern const gchar *GladeChildGnomeDruidVBox;
+
+extern const gchar *GladeChildBonoboWindowDock;
+extern const gchar *GladeChildBonoboWindowAppBar;
+
+/* These aren't saved in the XML. */
+extern const gchar *GladeChildCListTitle;
+
+
+
+/* GtkFixed/GtkLayout Child property names. */
+extern const gchar *GladeFixedChildX;
+extern const gchar *GladeFixedChildY;
+extern const gchar *GladeLayoutChildX;
+extern const gchar *GladeLayoutChildY;
+
+
+/* Information on the stock GTK+ responses. */
+typedef struct _GladeDialogResponse GladeDialogResponse;
+struct _GladeDialogResponse
+{
+ gchar *name;
+ gint response_id;
+ /* This is the stock id that usually goes with the response id. If the user
+ sets the stock id to this, then we automatically set the response id. */
+ gchar *stock_id;
+};
+
+typedef struct _GladeFindGroupData GladeFindGroupData;
+struct _GladeFindGroupData {
+ GSList *group;
+ GtkWidget *found_widget;
+};
+
+extern GladeDialogResponse GladeStockResponses[];
+extern const gint GladeStockResponsesSize;
+
+/* Some common functions. */
+void gb_box_set_size (GtkWidget *widget,
+ gint size);
+void gb_box_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data);
+void gb_box_get_child_properties (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetGetArgData *data);
+void gb_box_set_child_properties (GtkWidget * widget,
+ GtkWidget * child,
+ GbWidgetSetArgData * data);
+void gb_box_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data);
+void gb_box_write_add_child_source (GtkWidget * parent,
+ const gchar * parent_name,
+ GtkWidget * child,
+ GbWidgetWriteSourceData * data);
+
+void gb_button_get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *relief_p,
+ gchar *focus_on_click_p);
+void gb_button_set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *relief_p,
+ gchar *focus_on_click_p);
+void gb_button_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data);
+void gb_button_find_radio_group (GtkWidget *widget,
+ GladeFindGroupData *find_data);
+void gb_button_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data,
+ const gchar *label_p);
+void gb_button_destroy (GtkWidget * widget,
+ GbWidgetDestroyData * data);
+
+char* gb_dialog_response_id_to_string (gint response_id);
+gint gb_dialog_response_id_from_string (const gchar *response_id);
+
+
+void gb_frame_create_popup_menu (GtkWidget *widget,
+ GbWidgetCreateMenuData *data);
+void gb_frame_add_child (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetSetArgData *data);
+void gb_frame_get_child_properties (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetGetArgData *data);
+void gb_frame_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data);
+
+
+void gb_label_create_standard_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p);
+
+
+void gb_label_get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p);
+
+void gb_label_set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p);
+
+void gb_label_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData *data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p);
+
+
+
+void gb_paned_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data);
+void gb_paned_get_child_properties (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetGetArgData *data);
+void gb_paned_set_child_properties (GtkWidget * widget,
+ GtkWidget * child,
+ GbWidgetSetArgData * data);
+void gb_paned_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data);
+
+GSList * gb_radio_button_reset_radio_group (GtkWidget * widget);
+void gb_radio_button_update_radio_group (GSList * group);
+
+void gb_table_update_placeholders (GtkWidget * table,
+ gint rows,
+ gint cols);
+
+void gb_tool_button_get_standard_properties (GtkWidget *widget,
+ GbWidgetGetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *visible_horz_p,
+ gchar *visible_vert_p,
+ gchar *is_important_p);
+void gb_tool_button_set_standard_properties (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *visible_horz_p,
+ gchar *visible_vert_p,
+ gchar *is_important_p);
+void gb_tool_button_destroy (GtkWidget * widget,
+ GbWidgetDestroyData * data);
+
+
+void gb_window_create_standard_properties(GtkWidget * widget,
+ GbWidgetCreateArgData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p);
+void gb_window_get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p);
+void gb_window_set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p);
+void gb_window_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData *data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p);
+void gb_window_destroy (GtkWidget * widget,
+ GbWidgetDestroyData * data);
+
+
+gboolean gb_set_scroll_adjustments_hook (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_GB_H */
diff --git a/tools/glade/glade/gbsource.c b/tools/glade/glade/gbsource.c
new file mode 100644
index 00000000..6fcd1649
--- /dev/null
+++ b/tools/glade/glade/gbsource.c
@@ -0,0 +1,1222 @@
+#include <gtk/gtk.h>
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#include <bonobo.h>
+#endif
+
+#include "gb.h"
+#include "gbwidget.h"
+#include "source.h"
+#include "glade_gnome.h"
+#include "glade_atk.h"
+
+/* These are used for outputting signal handler prototypes. */
+#define GB_PARAM_INDENT 40
+#define GB_PARAM_TYPE_WIDTH 16
+
+static GHashTable *glade_signal_hash = NULL;
+
+static void gb_widget_write_signals_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data);
+static void gb_widget_write_signal_connection_source (GbWidgetWriteSourceData * data,
+ const gchar *signal_name,
+ const gchar *connect_object,
+ gboolean connect_after,
+ const gchar *handler_data,
+ const gchar *handler);
+static gchar *get_type_name (GtkType type, gboolean * is_pointer);
+static gchar *get_gdk_event (gchar * signal_name);
+static gchar **lookup_signal_arg_names (gchar * type, gchar * signal_name,
+ gint num_args_expected);
+static void gb_widget_write_accelerators_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data);
+
+/*************************************************************************
+ * Functions for writing C source code
+ *************************************************************************/
+
+void
+gb_widget_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GtkWidget *parent;
+ GbWidget *gbwidget;
+ GladeWidgetData *widget_data;
+ gchar *class_id, *child_name, *widget_name = NULL, *real_widget_name = NULL;
+ gint source_len;
+
+ /* This is a temporary(?) kludge so that the code for GtkDialogs is OK.
+ We stop the source code for the action_area from being written.
+ GtkDialog & GnomeDialog need to output the code for their vbox &
+ action_area children themselves, since they need to output special code
+ to access them, e.g. "GTK_DIALOG (dialog1)->vbox". However, the vbox
+ is the parent of the action_area, and so we have to stop the action_area
+ being output using the standard code since that won't work.
+ The problem is due to the dialogs having 2 special children, where one
+ is a descendant of the other. I don't think this occurs anywhere else. */
+ child_name = gb_widget_get_child_name (widget);
+ if (child_name && data->create_widget)
+ {
+ if (!strcmp (child_name, GladeChildDialogActionArea))
+ return;
+ }
+
+ parent = data->parent;
+
+ class_id = gb_widget_get_class_id (widget);
+#if 0
+ g_print ("class_id: %s\n", class_id ? class_id : "");
+#endif
+ data->write_children = TRUE;
+
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ /* If this isn't a gbwidget, skip it. */
+ if (widget_data)
+ {
+ gbwidget = gb_widget_lookup_class (class_id);
+ g_return_if_fail (gbwidget != NULL);
+
+ /* For custom widgets, we don't have a default widget to compare with,
+ so all properties should be set. */
+ if (GLADE_IS_CUSTOM_WIDGET (widget))
+ {
+ data->standard_widget = NULL;
+ }
+ else
+ {
+ /* This stores newly-created widgets, which we use to get default
+ values from. Though we don't use them much at present. */
+ data->standard_widget = (GtkWidget *) g_hash_table_lookup (data->standard_widgets, class_id);
+ if (data->standard_widget == NULL)
+ {
+#ifdef USE_GNOME
+ /* FIXME: GnomeLibs 1.0.1 workaround - gtk_object_newv doesn't
+ return a valid GnomeAppBar or GnomeDateEdit, so we create it
+ ourself. */
+ if (!strcmp (class_id, "GnomeAppBar"))
+ data->standard_widget = gnome_appbar_new (TRUE, TRUE, GNOME_PREFERENCES_NEVER);
+ else if (!strcmp (class_id, "GnomeDateEdit"))
+ data->standard_widget = gnome_date_edit_new ((time_t) 0, TRUE,
+ TRUE);
+ /* We don't create standard widgets for Bonobo controls, for
+ now. There may be a better way to get default values for
+ them. */
+ else if (!data->standard_widget && !BONOBO_IS_WIDGET (widget))
+ data->standard_widget = GTK_WIDGET (g_object_newv (gtk_type_from_name (class_id), 0, NULL));
+#else
+ if (!data->standard_widget)
+ data->standard_widget = GTK_WIDGET (g_object_newv (gtk_type_from_name (class_id), 0, NULL));
+#endif
+
+ if (data->standard_widget)
+ g_hash_table_insert (data->standard_widgets, class_id,
+ data->standard_widget);
+ }
+ }
+
+ real_widget_name = source_create_valid_identifier (gtk_widget_get_name (widget));
+ if (data->use_component_struct && widget_data->public_field)
+ widget_name = g_strdup_printf ("%s->%s", data->component_name,
+ real_widget_name);
+ else
+ widget_name = real_widget_name;
+
+ data->widget_data = widget_data;
+ data->real_wname = real_widget_name;
+ data->wname = widget_name;
+ if (gbwidget->gb_widget_write_source)
+ (gbwidget->gb_widget_write_source) (widget, data);
+ else
+ source_add (data, " /* Skipping %s: unimplemented. */\n", class_id);
+
+ /* Make sure there is a blank line after each widget, for readability. */
+ source_len = data->source_buffers[GLADE_SOURCE]->len;
+ if (source_len > 2
+ && (data->source_buffers[GLADE_SOURCE]->str[source_len - 1] != '\n'
+ || data->source_buffers[GLADE_SOURCE]->str[source_len - 2] != '\n'))
+ source_add (data, "\n");
+
+ data->wname = NULL;
+ data->real_wname = NULL;
+ data->parent = widget;
+ }
+ else if (GB_IS_PLACEHOLDER (widget) && parent)
+ {
+ if (GTK_IS_NOTEBOOK (parent))
+ {
+ /* SPECIAL CODE: If notebook pages are empty (i.e. placeholders),
+ we create dummy widgets instead, so it still runs OK. */
+ if (child_name == NULL)
+ {
+ gchar *wname, *parent_name;
+
+ wname = "empty_notebook_page";
+ /* Make sure the dummy widget is declared. */
+ source_ensure_decl (data, " GtkWidget *empty_notebook_page;\n");
+
+ parent_name = (char*) gtk_widget_get_name (parent);
+ parent_name = source_create_valid_identifier (parent_name);
+ source_add (data,
+ " %s = gtk_vbox_new (FALSE, 0);\n"
+ " gtk_widget_show (%s);\n"
+ " gtk_container_add (GTK_CONTAINER (%s), %s);\n"
+ "\n",
+ wname, wname, parent_name, wname);
+ g_free (parent_name);
+ }
+ else
+ {
+ /* For empty notebook tabs, we increment the 'last_child' written
+ value. */
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "last_child"));
+ gtk_object_set_data (GTK_OBJECT (parent), "last_child",
+ GINT_TO_POINTER (col + 1));
+ }
+ }
+ else if (GTK_IS_CLIST (parent))
+ {
+ /* For empty clist/ctree titles, we increment the 'last_child'
+ written value. */
+ if (child_name && !strcmp (child_name, GladeChildCListTitle))
+ {
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "last_child"));
+ gtk_object_set_data (GTK_OBJECT (parent), "last_child",
+ GINT_TO_POINTER (col + 1));
+ }
+ }
+ }
+
+ /* Recursively write source for children.
+ We need to reset the parent after the children have been written. */
+ data->create_widget = TRUE;
+ if (data->write_children)
+ gb_widget_children_foreach (widget, (GtkCallback) gb_widget_write_source, data);
+
+ /* We need to reset some of the members of the GbWidgetWriteSourceData struct
+ so that they work OK for the next sibling. */
+ data->parent = parent;
+
+ /* SPECIAL CODE: For GtkOptionMenu, we have to set the menu after all the
+ children are created. */
+ if (GTK_IS_OPTION_MENU (widget) && GB_IS_GB_WIDGET (widget)
+ && GTK_OPTION_MENU (widget)->menu
+ && GB_IS_GB_WIDGET (GTK_OPTION_MENU (widget)->menu))
+ {
+ gchar *menu_name = source_create_valid_identifier (gtk_widget_get_name (GTK_OPTION_MENU (widget)->menu));
+ source_add (data,
+ " gtk_option_menu_set_menu (GTK_OPTION_MENU (%s), %s);\n\n",
+ widget_name, menu_name);
+ g_free (menu_name);
+ }
+
+ /* SPECIAL CODE: Finish off the GnomeUIInfo struct if we are building a
+ Gnome menu. */
+#ifdef USE_GNOME
+ if (data->project->gnome_support && GTK_IS_MENU_SHELL (widget)
+ && GB_IS_GB_WIDGET (widget))
+ {
+ glade_gnome_finish_menu_source (GTK_MENU_SHELL (widget), data);
+ }
+#endif
+
+ if (widget_name != real_widget_name)
+ g_free (real_widget_name);
+ g_free (widget_name);
+}
+
+
+/* This is called by each GbWidget's write_source function to write all the
+ common source code, including code to add the widget to its parent. */
+void
+gb_widget_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gint i, width, height, can_focus, can_default;
+
+ /* FIXME: unfinished. public fields were to be added to the component struct.
+ Private fields would just be declared within the creation function. */
+ if (wdata->public_field)
+ source_add_decl (data, " GtkWidget *%s;\n", data->real_wname);
+ else
+ source_add_decl (data, " GtkWidget *%s;\n", data->real_wname);
+
+ if (data->set_widget_names)
+ source_add (data, " gtk_widget_set_name (%s, \"%s\");\n", data->wname,
+ data->real_wname);
+
+ if (!data->use_component_struct)
+ {
+ /* For toplevel widgets we don't ref the widget, since if we do it never
+ gets destroyed. This may be a bug in GTK+ 1.2.3. */
+ if (data->parent == NULL)
+ {
+ source_add_to_buffer (data, GLADE_OBJECT_HOOKUP,
+ " GLADE_HOOKUP_OBJECT_NO_REF (%s, %s, %s);\n",
+ data->component_name,
+ data->wname,
+ source_make_string (data->real_wname, FALSE));
+ }
+ else
+ {
+ source_add_to_buffer (data, GLADE_OBJECT_HOOKUP,
+ " GLADE_HOOKUP_OBJECT (%s, %s, %s);\n",
+ data->component_name,
+ data->wname,
+ source_make_string (data->real_wname, FALSE));
+ }
+ }
+
+ /* SPECIAL CODE: menus are not shown here. */
+ if (widget->parent && wdata->flags & GLADE_VISIBLE && !GTK_IS_MENU (widget))
+ {
+#ifdef USE_GNOME
+ /* FIXME: GnomeDruidPageStandard bug workaround. It needs show_all(). */
+ if (GNOME_IS_DRUID_PAGE_STANDARD (widget))
+ source_add (data, " gtk_widget_show_all (%s);\n", data->wname);
+ else
+ source_add (data, " gtk_widget_show (%s);\n", data->wname);
+#else
+ source_add (data, " gtk_widget_show (%s);\n", data->wname);
+#endif
+ }
+
+ /* Output code to add widget to parent. */
+ gb_widget_write_add_child_source (widget, data);
+
+ if (wdata->flags & (GLADE_WIDTH_SET | GLADE_HEIGHT_SET))
+ {
+ width = wdata->flags & GLADE_WIDTH_SET ? wdata->width : -1;
+ height = wdata->flags & GLADE_HEIGHT_SET ? wdata->height : -1;
+
+ /* GTK BUG WORKAROUND - a combo should manage the size of its entry.
+ I think this isn't needed any more (GTK+ 1.2.3). */
+#if 0
+ if (GTK_IS_COMBO (widget))
+ source_add(data,
+ " gtk_widget_set_size_request (GTK_COMBO (%s)->entry, %i, %i);\n",
+ data->wname, width - 16 < 0 ? -1 : width - 16, height);
+#endif
+
+ source_add (data, " gtk_widget_set_size_request (%s, %i, %i);\n",
+ data->wname, width, height);
+ }
+
+
+ if (glade_util_uses_border_width (widget))
+ {
+ if (GTK_CONTAINER (widget)->border_width != 0)
+ {
+ source_add (data,
+ " gtk_container_set_border_width (GTK_CONTAINER (%s), %i);\n",
+ data->wname, GTK_CONTAINER (widget)->border_width);
+ }
+ }
+
+
+ /* FIXME: Kludge to set separator menu items insensitive, so that they are
+ skipped when using the cursor keys to move up/down the menu. */
+ if (!(wdata->flags & GLADE_SENSITIVE)
+ || (GTK_IS_MENU_ITEM (widget) && GTK_BIN (widget)->child == NULL))
+ source_add (data, " gtk_widget_set_sensitive (%s, FALSE);\n", data->wname);
+
+ can_focus = GTK_WIDGET_CAN_FOCUS (widget);
+ if (!data->standard_widget
+ || can_focus != GTK_WIDGET_CAN_FOCUS (data->standard_widget))
+ {
+ if (can_focus)
+ source_add (data, " gtk_widget_set_can_focus(%s, TRUE);\n",
+ data->wname);
+ else
+ source_add (data, " gtk_widget_set_can_focus(%s, FALSE);\n",
+ data->wname);
+ }
+ can_default = GTK_WIDGET_CAN_DEFAULT (widget);
+ if (!data->standard_widget
+ || can_default != GTK_WIDGET_CAN_DEFAULT (data->standard_widget))
+ {
+ if (can_default)
+ source_add (data, " gtk_widget_set_can_default(%s, TRUE);\n",
+ data->wname);
+ else
+ source_add (data, " gtk_widget_set_can_default(%s, FALSE);\n",
+ data->wname);
+ }
+
+ if (wdata->flags & GLADE_GRAB_FOCUS)
+ {
+ if (data->focus_widget)
+ g_warning ("Multiple widgets with 'Has Focus' set: %s, %s",
+ data->focus_widget, data->real_wname);
+ else
+ data->focus_widget = g_strdup (data->wname);
+ }
+
+ if (wdata->flags & GLADE_GRAB_DEFAULT)
+ {
+ if (data->default_widget)
+ g_warning ("Multiple widgets with 'Has Default' set: %s, %s",
+ data->default_widget, data->real_wname);
+ else
+ data->default_widget = g_strdup (data->wname);
+ }
+
+ if (wdata->tooltip)
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, GbTooltip, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ data->need_tooltips = TRUE;
+
+ /* GtkToolItem subclasses use a special function, since otherwise they
+ wouldn't work as they don't have a window. */
+ if (GTK_IS_TOOL_ITEM (widget))
+ {
+ source_add (data,
+ " gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (%s), tooltips, %s, NULL);\n",
+ data->wname,
+ source_make_string_full (wdata->tooltip, data->use_gettext && translatable, context));
+ }
+ else
+ {
+ source_add (data,
+ " gtk_widget_set_tooltip_text (%s, %s);\n",
+ data->wname,
+ source_make_string_full (wdata->tooltip, data->use_gettext && translatable, context));
+ }
+ }
+
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ GdkExtensionMode ext_mode = gtk_widget_get_extension_events (widget);
+ gboolean written_first = FALSE;
+
+ if (wdata->events)
+ {
+ source_add (data, " gtk_widget_set_events (%s, ", data->wname);
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ if (wdata->events & GbEventMaskValues[i])
+ {
+ if (!written_first)
+ source_add (data, "%s", GbEventMaskSymbols[i]);
+ else
+ source_add (data, " | %s", GbEventMaskSymbols[i]);
+ written_first = TRUE;
+ }
+ }
+ source_add (data, ");\n");
+ }
+
+ if (ext_mode != GDK_EXTENSION_EVENTS_NONE)
+ {
+ for (i = 0; GbExtensionModeChoices[i]; i++)
+ {
+ if (GbExtensionModeValues[i] == ext_mode)
+ source_add (data, " gtk_widget_set_extension_events (%s, %s);\n",
+ data->wname, GbExtensionModeSymbols[i]);
+ }
+ }
+ }
+
+ gb_widget_write_signals_source (widget, data);
+ gb_widget_write_accelerators_source (widget, data);
+ glade_atk_write_source (widget, data);
+}
+
+
+void
+gb_widget_write_add_child_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GbWidget *gbparent;
+ GtkWidget *parent;
+ gchar *parent_name;
+
+ /* If the widget is created automatically by its parent, we don't need
+ to add source to add it. */
+ if (!data->create_widget)
+ return;
+
+ /* SPECIAL CODE: to handle menus. */
+ if (GTK_IS_MENU (widget))
+ parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ else
+ parent = data->parent;
+
+ /* Return if no parent exists */
+ if (!parent)
+ return;
+
+ parent_name = (char*) gtk_widget_get_name (parent);
+ parent_name = source_create_valid_identifier (parent_name);
+
+ MSG2 ("Adding %s to %s", data->wname, parent_name);
+
+ /* If the GbWidget has its own function to output source code to add a child,
+ we use that, else we just output the default "gtk_container_add ()". */
+ gbparent = gb_widget_lookup (parent);
+ if (gbparent && gbparent->gb_widget_write_add_child_source)
+ {
+ (gbparent->gb_widget_write_add_child_source) (parent, parent_name,
+ widget, data);
+ }
+ else
+ {
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+
+ g_free (parent_name);
+}
+
+
+static void
+gb_widget_write_signals_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GList *item;
+ GladeSignal *signal;
+ gboolean skip_handler_code;
+ gchar *handler;
+
+ item = data->widget_data->signals;
+ while (item)
+ {
+ signal = (GladeSignal *) item->data;
+ item = item->next;
+ skip_handler_code = FALSE;
+
+ /* If we're appending new/changed signals and this is an old one, then
+ skip it. Note that we also skip it if the last mod time is 0, which
+ will happen for XML files created before the last mod tag was added.*/
+ MSG2 ("Creating Signals:%s Handler: %s",
+ data->creating_callback_files ? "TRUE" : "FALSE", signal->handler);
+ MSG1 ("LastMod:%s", ctime (&signal->last_modification_time));
+ MSG1 ("LastWrite:%s", ctime (&data->last_write_time));
+
+ if (!data->creating_callback_files
+ && (signal->last_modification_time <= data->last_write_time))
+ {
+ MSG1 ("Skipping signal: %s", signal->handler);
+ skip_handler_code = TRUE;
+ }
+
+ if (!signal->name)
+ {
+ /* FIXME: store warnings */
+ g_warning ("Signal name not set");
+ continue;
+ }
+
+ if (!signal->handler)
+ {
+ /* FIXME: store warnings */
+ g_warning ("Signal handler not set");
+ continue;
+ }
+
+ /* Make sure handler function name is valid. */
+ handler = source_create_valid_identifier (signal->handler);
+
+ /* Output code to connect signal. */
+ gb_widget_write_signal_connection_source (data, signal->name,
+ signal->object, signal->after,
+ signal->data, handler);
+
+ /* We don't need to output code for standard GTK functions. */
+ if (!strcmp (handler, "gtk_widget_show")
+ || !strcmp (handler, "gtk_widget_hide")
+ || !strcmp (handler, "gtk_widget_grab_focus")
+ || !strcmp (handler, "gtk_widget_destroy")
+ || !strcmp (handler, "gtk_window_activate_default")
+ || !strcmp (handler, "gtk_true")
+ || !strcmp (handler, "gtk_false")
+ || !strcmp (handler, "gtk_main_quit"))
+ skip_handler_code = TRUE;
+
+
+ /* If we're appending new/changed signals and this is an old one, we
+ don't want to output the source code for it. */
+ if (!skip_handler_code)
+ {
+ gb_widget_write_signal_handler_source (widget, data, signal->name,
+ handler);
+ }
+ g_free (handler);
+ }
+}
+
+
+/* This outputs a signal handler declaration and empty function. handler
+ should be a valid identifier. */
+void
+gb_widget_write_signal_handler_source (GtkWidget *widget,
+ GbWidgetWriteSourceData * data,
+ const gchar *signal_name,
+ const gchar *handler)
+{
+ guint signal_id;
+ GSignalQuery query_info;
+ gint param, i;
+ gchar buffer[1024];
+ gchar *ret_type, *pos, *type_name, *arg_name, *object_name, *object_arg;
+ gchar *object_arg_start;
+ gboolean is_pointer;
+ gint param_num, widget_num, event_num, callback_num;
+ gint handler_len, object_name_len, type_name_len, num_spaces;
+ gint *arg_num;
+ gchar **arg_names;
+ gchar *signal_name_copy;
+
+ /* Check if we have already output the handler. */
+ if (g_hash_table_lookup (data->handlers_output, handler))
+ return;
+
+ /* Remember that we have output the handler. */
+ g_hash_table_insert (data->handlers_output, g_strdup (handler), "Output");
+
+
+ signal_id = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (widget));
+ /* If a project is converted from GTK+ 1.2.x to 2.x.x it may have some
+ signals which aren't valid any more. So we output a warning. */
+ if (signal_id == 0)
+ {
+ g_warning ("Invalid signal: '%s' for widget: '%s'", signal_name,
+ data->wname);
+ return;
+ }
+
+ g_signal_query (signal_id, &query_info);
+
+ /* Output the return type and function name. */
+ ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
+ pos = buffer;
+ sprintf (pos, "%s%s\n%s", ret_type, is_pointer ? "*" : "", handler);
+ pos += strlen (pos);
+
+ handler_len = strlen (handler);
+ if (handler_len >= GB_PARAM_INDENT - 1)
+ {
+ *pos++ = '\n';
+ for (i = 0; i < GB_PARAM_INDENT; i++)
+ *pos++ = ' ';
+ }
+ else
+ {
+ num_spaces = GB_PARAM_INDENT - handler_len - 1;
+ for (i = 0; i < num_spaces; i++)
+ *pos++ = ' ';
+ }
+
+ /* Convert signal name to use underscores rather than dashes '-'. */
+ signal_name_copy = g_strdup (query_info.signal_name);
+ for (i = 0; signal_name_copy[i]; i++)
+ {
+ if (signal_name_copy[i] == '-')
+ signal_name_copy[i] = '_';
+ }
+
+ /* Output the signal parameters. */
+ object_name = (char*) g_type_name (query_info.itype);
+ arg_names = lookup_signal_arg_names (object_name, signal_name_copy,
+ query_info.n_params + 1);
+
+
+ widget_num = 0;
+
+ /* Output the signal object type and the argument name. We assume the
+ type is a pointer - I think that is OK. We remove "Gtk" and convert
+ to lower case for the argument name. */
+ sprintf (pos, "(%s ", object_name);
+ pos += strlen (pos);
+ object_name_len = strlen (object_name);
+ if (object_name_len + 1 < GB_PARAM_TYPE_WIDTH)
+ {
+ num_spaces = GB_PARAM_TYPE_WIDTH - object_name_len - 1;
+ for (i = 0; i < num_spaces; i++)
+ *pos++ = ' ';
+ }
+
+ if (arg_names)
+ {
+ sprintf (pos, "*%s,\n", arg_names[0]);
+ pos += strlen (pos);
+ }
+ else
+ {
+ object_arg = (!strncmp (object_name, "Gtk", 3)) ? object_name + 3 : object_name;
+ object_arg_start = pos + 1;
+ sprintf (pos, "*%s", object_arg);
+ pos += strlen (pos);
+ g_strdown (object_arg_start);
+ if (!strncmp (object_arg_start, "widget", 6))
+ widget_num = 2;
+ sprintf (pos, ",\n");
+ pos += strlen (pos);
+ }
+
+
+ param_num = 1;
+ event_num = callback_num = 0;
+ for (param = 0; param < query_info.n_params; param++)
+ {
+ for (i = 0; i < GB_PARAM_INDENT; i++)
+ *pos++ = ' ';
+
+ /* If the arg name includes the type (with a space between!), just
+ output that. */
+ if (arg_names && strchr (arg_names[param + 1], ' '))
+ {
+ sprintf (pos, "%s,\n", arg_names[param + 1]);
+ pos += strlen (pos);
+ }
+ else
+ {
+ type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
+ /* Most arguments to the callback are called "arg1", "arg2", etc.
+ GtkWidgets are called "widget", "widget2", ...
+ GdkEvents are called "event", "event2", ...
+ GtkCallbacks are called "callback", "callback2", ... */
+ if (!strcmp (type_name, "GtkWidget"))
+ {
+ arg_name = "widget";
+ arg_num = &widget_num;
+ }
+ else if (!strcmp (type_name, "GdkEvent"))
+ {
+ type_name = get_gdk_event (signal_name_copy);
+ arg_name = "event";
+ arg_num = &event_num;
+ is_pointer = TRUE;
+ }
+ else if (!strcmp (type_name, "GtkCallback"))
+ {
+ arg_name = "callback";
+ arg_num = &callback_num;
+ }
+ else
+ {
+ arg_name = "arg";
+ arg_num = &param_num;
+ }
+ sprintf (pos, "%s ", type_name);
+ pos += strlen (pos);
+ type_name_len = strlen (type_name);
+ if (type_name_len + 1 < GB_PARAM_TYPE_WIDTH)
+ {
+ num_spaces = GB_PARAM_TYPE_WIDTH - type_name_len - 1;
+ for (i = 0; i < num_spaces; i++)
+ *pos++ = ' ';
+ }
+
+ if (arg_names)
+ {
+ sprintf (pos, "%s%s,\n", is_pointer ? "*" : " ",
+ arg_names[param + 1]);
+ pos += strlen (pos);
+ }
+ else
+ {
+ if (!arg_num || *arg_num == 0)
+ sprintf (pos, "%s%s,\n", is_pointer ? "*" : " ", arg_name);
+ else
+ sprintf (pos, "%s%s%i,\n", is_pointer ? "*" : " ", arg_name,
+ *arg_num);
+ pos += strlen (pos);
+
+ if (arg_num)
+ {
+ if (*arg_num == 0)
+ *arg_num = 2;
+ else
+ *arg_num += 1;
+ }
+ }
+ }
+ }
+
+ if (arg_names)
+ g_strfreev (arg_names);
+
+ /* Add the final user_data parameter, common to all handlers. */
+ for (i = 0; i < GB_PARAM_INDENT; i++)
+ *pos++ = ' ';
+ sprintf (pos, "gpointer user_data)");
+ pos += strlen (pos);
+
+ /* Output the declaration of the handler, which uses the same buffer. */
+ source_add_to_buffer (data, GLADE_CALLBACK_DECLARATIONS,
+ "\n%s;\n", buffer);
+
+ /* Output the empty handler function, returning FALSE if the return type is
+ bool (i.e. for the GdkEvent handlers). */
+ source_add_to_buffer (data, GLADE_CALLBACK_SOURCE,
+ "\n%s\n{\n\n%s}\n\n",
+ buffer,
+ query_info.return_type == GTK_TYPE_BOOL
+ ? " return FALSE;\n" : "");
+
+ g_free (signal_name_copy);
+}
+
+
+static void
+gb_widget_write_signal_connection_source (GbWidgetWriteSourceData * data,
+ const gchar *signal_name,
+ const gchar *connect_object,
+ gboolean connect_after,
+ const gchar *handler_data,
+ const gchar *handler)
+{
+ if (connect_object && connect_object[0])
+ {
+ if (connect_after)
+ {
+ source_add_to_buffer (data, GLADE_SIGNAL_CONNECTIONS,
+ " g_signal_connect_data ((gpointer) %s, \"%s\",\n"
+ " G_CALLBACK (%s),\n"
+ " GTK_OBJECT (%s),\n"
+ " NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n",
+ data->wname, signal_name, handler,
+ connect_object);
+ }
+ else
+ {
+ source_add_to_buffer (data, GLADE_SIGNAL_CONNECTIONS,
+ " g_signal_connect_swapped ((gpointer) %s, \"%s\",\n"
+ " G_CALLBACK (%s),\n"
+ " GTK_OBJECT (%s));\n",
+ data->wname, signal_name, handler,
+ connect_object);
+ }
+ }
+ else
+ {
+ if (connect_after)
+ {
+ source_add_to_buffer (data, GLADE_SIGNAL_CONNECTIONS,
+ " g_signal_connect_after ((gpointer) %s, \"%s\",\n"
+ " G_CALLBACK (%s),\n"
+ " %s);\n",
+ data->wname, signal_name, handler,
+ handler_data ? handler_data : "NULL");
+ }
+ else
+ {
+ source_add_to_buffer (data, GLADE_SIGNAL_CONNECTIONS,
+ " g_signal_connect ((gpointer) %s, \"%s\",\n"
+ " G_CALLBACK (%s),\n"
+ " %s);\n",
+ data->wname, signal_name, handler,
+ handler_data ? handler_data : "NULL");
+ }
+ }
+}
+
+
+/* Returns the type name to use for a signal argument or return value, given
+ the GtkType from the signal info. It also sets is_pointer to TRUE if the
+ argument needs a '*' since it is a pointer. */
+static gchar *
+get_type_name (GtkType type, gboolean * is_pointer)
+{
+ gchar *type_name;
+
+ *is_pointer = FALSE;
+ type_name = (char*) g_type_name (type);
+
+ switch (type) {
+ case G_TYPE_NONE:
+ case G_TYPE_CHAR:
+ case G_TYPE_UCHAR:
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ case G_TYPE_POINTER:
+ /* These all have normal C type names so they are OK. */
+ return type_name;
+
+ case G_TYPE_STRING:
+ /* A GtkString is really a gchar*. */
+ *is_pointer = TRUE;
+ return "gchar";
+
+ case G_TYPE_ENUM:
+ case G_TYPE_FLAGS:
+ /* We use a gint for both of these. Hopefully a subtype with a decent
+ name will be registered and used instead, as GTK+ does itself. */
+ return "gint";
+
+ case G_TYPE_BOXED:
+ /* The boxed type shouldn't be used itself, only subtypes. Though we
+ return 'gpointer' just in case. */
+ return "gpointer";
+
+ case G_TYPE_PARAM:
+ /* A GParam is really a GParamSpec*. */
+ *is_pointer = TRUE;
+ return "GParamSpec";
+
+ default:
+ break;
+ }
+
+ if (!strcmp (type_name, "GtkTypeTextIter"))
+ {
+ *is_pointer = TRUE;
+ return "GtkTextIter";
+ }
+
+ if (!strcmp (type_name, "GtkTypeTreeIter"))
+ {
+ *is_pointer = TRUE;
+ return "GtkTreeIter";
+ }
+
+ if (!strcmp (type_name, "GtkTypeTreePath"))
+ {
+ *is_pointer = TRUE;
+ return "GtkTreePath";
+ }
+
+ /* For all GtkObject subtypes we can use the class name with a "*",
+ e.g. 'GtkWidget *'. */
+ if (g_type_is_a (type, G_TYPE_OBJECT))
+ *is_pointer = TRUE;
+
+ /* All boxed subtypes will be pointers as well. */
+ if (g_type_is_a (type, G_TYPE_BOXED))
+ *is_pointer = TRUE;
+
+ /* All pointer subtypes will be pointers as well. */
+ if (g_type_is_a (type, G_TYPE_POINTER))
+ *is_pointer = TRUE;
+
+ return type_name;
+}
+
+
+/* Returns the type name to use for the GdkEvent arg of a signal handler,
+ based on the signal name. This assumes that there will only be one GdkEvent
+ arg to the signal handler, but that is OK since for the signals we support
+ here we know that is true. If any new signals come along with more than one
+ GdkEvent arg, it will just use "GdkEvent" for all of them, which is still
+ OK. */
+static gchar *
+get_gdk_event (gchar * signal_name)
+{
+ static gchar *GbGDKEvents[] =
+ {
+ "button_press_event", "GdkEventButton",
+ "button_release_event", "GdkEventButton",
+ "motion_notify_event", "GdkEventMotion",
+ "delete_event", "GdkEvent",
+ "destroy_event", "GdkEvent",
+ "expose_event", "GdkEventExpose",
+ "key_press_event", "GdkEventKey",
+ "key_release_event", "GdkEventKey",
+ "enter_notify_event", "GdkEventCrossing",
+ "leave_notify_event", "GdkEventCrossing",
+ "configure_event", "GdkEventConfigure",
+ "focus_in_event", "GdkEventFocus",
+ "focus_out_event", "GdkEventFocus",
+ "map_event", "GdkEvent",
+ "unmap_event", "GdkEvent",
+ "property_notify_event", "GdkEventProperty",
+ "selection_clear_event", "GdkEventSelection",
+ "selection_request_event", "GdkEventSelection",
+ "selection_notify_event", "GdkEventSelection",
+ "proximity_in_event", "GdkEventProximity",
+ "proximity_out_event", "GdkEventProximity",
+ "drag_begin_event", "GdkEventDragBegin",
+ "drag_request_event", "GdkEventDragRequest",
+ "drag_end_event", "GdkEventDragRequest",
+ "drop_enter_event", "GdkEventDropEnter",
+ "drop_leave_event", "GdkEventDropLeave",
+ "drop_data_available_event", "GdkEventDropDataAvailable",
+ "other_event", "GdkEventOther",
+ "client_event", "GdkEventClient",
+ "no_expose_event", "GdkEventNoExpose",
+ NULL
+ };
+
+ gint i;
+
+ for (i = 0; GbGDKEvents[i]; i += 2)
+ {
+ if (!strcmp (signal_name, GbGDKEvents[i]))
+ return GbGDKEvents[i + 1];
+ }
+ return "GdkEvent";
+}
+
+
+static void
+init_signal_hash (void)
+{
+ static const gchar *signal_data[][2] = {
+ /*
+ * GTK+ Signals.
+ */
+ { "GtkAccelGroup::accel_activate", "accelgroup,object,key,modifier" },
+ { "GtkAccelGroup::accel_changed", "accelgroup,key,modifier,closure" },
+ { "GtkCellRenderer::editing_started", "cellrenderer,editable,path" },
+ { "GtkCellRendererText::edited", "cellrenderertext,path,new_text" },
+ { "GtkCellRendererToggle::toggled", "cellrenderertoggle,path" },
+ { "GtkCList::click_column", "clist,column" },
+ { "GtkCList::extend_selection", "clist,scroll_type,position,auto_start_selection" },
+ { "GtkCList::resize_column", "clist,column,width" },
+ { "GtkCList::row_move", "clist,source_row,dest_row" },
+ { "GtkCList::scroll_horizontal", "clist,scroll_type,position" },
+ { "GtkCList::scroll_vertical", "clist,scroll_type,position" },
+ { "GtkCList::select_row", "clist,row,column,event" },
+ { "GtkCList::set_scroll_adjustments", "clist,hadjustment,vadjustment" },
+ { "GtkCList::unselect_row", "clist,row,column,event" },
+ { "GtkCTree::change_focus_row_expansion", "ctree,expansion" },
+ { "GtkCTree::tree_collapse", "ctree,node" },
+ { "GtkCTree::tree_expand", "ctree,node" },
+ { "GtkCTree::tree_move", "ctree,node,new_parent,new_sibling" },
+ { "GtkCTree::tree_select_row", "ctree,node,column" },
+ { "GtkCTree::tree_unselect_row", "ctree,node,column" },
+ { "GtkDialog::response", "dialog,response_id" },
+ { "GtkEditable::delete_text", "editable,start_pos,end_pos" },
+ { "GtkEditable::insert_text", "editable,new_text,new_text_length,position" },
+ { "GtkEntry::delete_from_cursor", "entry,type,count" },
+ { "GtkEntry::insert_at_cursor", "entry,string" },
+ { "GtkEntry::move_cursor", "entry,step,count,extend_selection" },
+ { "GtkEntry::populate_popup", "entry,menu" },
+ { "GtkIconView::item_activated", "iconview,path" },
+ { "GtkIconView::move_cursor", "iconview,step,count" },
+ { "GtkIconView::set_scroll_adjustments", "iconview,hadjustment,vadjustment" },
+ { "GtkInputDialog::disable_device", "inputdialog,device" },
+ { "GtkInputDialog::enable_device", "inputdialog,device" },
+ { "GtkIMContext::commit", "imcontext,string" },
+ { "GtkIMContext::delete_surrounding", "imcontext,offset,n_chars" },
+ { "GtkLabel::move_cursor", "label,step,count,extend_selection" },
+ { "GtkLabel::populate_popup", "label,menu" },
+ { "GtkLayout::set_scroll_adjustments", "layout,hadjustment,vadjustment" },
+ { "GtkListItem::extend_selection", "listitem,scroll_type,position,auto_start_selection" },
+ { "GtkListItem::scroll_horizontal", "listitem,scroll_type,position" },
+ { "GtkListItem::scroll_vertical", "listitem,scroll_type,position" },
+ { "GtkMenuItem::toggle_size_allocate", "menuitem,allocation" },
+ { "GtkMenuItem::toggle_size_request", "menuitem,gint *requisition" },
+ { "GtkMenuShell::activate_current", "menushell,force_hide" },
+ { "GtkMenuShell::cycle_focus", "menushell,direction" },
+ { "GtkMenuShell::move_current", "menushell,direction" },
+ { "GtkNotebook::change_current_page", "notebook,offset" },
+ { "GtkNotebook::focus_tab", "notebook,type" },
+ { "GtkNotebook::move_focus_out", "notebook,direction" },
+ { "GtkNotebook::select_page", "notebook,move_focus" },
+ { "GtkNotebook::switch_page", "notebook,GtkNotebookPage *page,page_num" },
+ { "GtkOldEditable::kill_char", "oldeditable,direction" },
+ { "GtkOldEditable::kill_line", "oldeditable,direction" },
+ { "GtkOldEditable::kill_word", "oldeditable,direction" },
+ { "GtkOldEditable::move_cursor", "oldeditable,x,y" },
+ { "GtkOldEditable::move_page", "oldeditable,x,y" },
+ { "GtkOldEditable::move_to_column", "oldeditable,column" },
+ { "GtkOldEditable::move_to_row", "oldeditable,row" },
+ { "GtkOldEditable::move_word", "oldeditable,offset" },
+ { "GtkOldEditable::set_editable", "oldeditable,is_editable" },
+ { "GtkPaned::cycle_child_focus", "paned,reverse" },
+ { "GtkPaned::cycle_handle_focus", "paned,reverse" },
+ { "GtkPaned::move_handle", "paned,scroll" },
+ { "GtkRange::adjust_bounds", "range,value" },
+ { "GtkRange::change_value", "range,scroll,value" },
+ { "GtkRange::move_slider", "range,scroll" },
+ { "GtkScale::format_value", "scale,value" },
+ { "GtkScrolledWindow::move_focus_out", "scrolledwindow,direction" },
+ { "GtkScrolledWindow::scroll_child", "scrolledwindow,scroll,horizontal" },
+ { "GtkSpinButton::change_value", "spinbutton,scroll" },
+ { "GtkSpinButton::input", "spinbutton,gdouble *new_value" },
+ { "GtkStatusbar::text_popped", "statusbar,context_id,text" },
+ { "GtkStatusbar::text_pushed", "statusbar,context_id,text" },
+ { "GtkTextBuffer::apply_tag", "textbuffer,tag,start,end" },
+ { "GtkTextBuffer::delete_range", "textbuffer,start,end" },
+ { "GtkTextBuffer::insert_child_anchor", "textbuffer,iter,anchor" },
+ { "GtkTextBuffer::insert_pixbuf", "textbuffer,iter,pixbuf" },
+ { "GtkTextBuffer::insert_text", "textbuffer,iter,text,length" },
+ { "GtkTextBuffer::mark_deleted", "textbuffer,mark" },
+ { "GtkTextBuffer::mark_set", "textbuffer,iter,mark" },
+ { "GtkTextBuffer::remove_tag", "textbuffer,tag,start,end" },
+ { "GtkText::set_scroll_adjustments", "text,hadjustment,vadjustment" },
+ { "GtkTextTag::event", "texttag,object,event,iter" },
+ { "GtkTextTagTable::tag_added", "texttagtable,tag" },
+ { "GtkTextTagTable::tag_changed", "texttagtable,tag,size_changed" },
+ { "GtkTextTagTable::tag_removed", "texttagtable,tag" },
+ { "GtkTextView::delete_from_cursor", "textview,type,count" },
+ { "GtkTextView::insert_at_cursor", "textview,string" },
+ { "GtkTextView::move_cursor", "textview,step,count,extend_selection" },
+ { "GtkTextView::move_focus", "textview,direction" },
+ { "GtkTextView::page_horizontally", "textview,count,extend_selection" },
+ { "GtkTextView::populate_popup", "textview,menu" },
+ { "GtkTextView::set_scroll_adjustments", "textview,hadjustment,vadjustment" },
+ { "GtkTipsQuery::widget_entered", "tipsquery,widget,tip_text,tip_private" },
+ { "GtkTipsQuery::widget_selected", "tipsquery,widget,tip_text,tip_private,event" },
+ { "GtkToolbar::orientation_changed", "toolbar,orientation" },
+ { "GtkToolbar::style_changed", "toolbar,style" },
+ { "GtkTreeModel::row_changed", "treemodel,path,iter" },
+ { "GtkTreeModel::row_deleted", "treemodel,path" },
+ { "GtkTreeModel::row_has_child_toggled", "treemodel,path,iter" },
+ { "GtkTreeModel::row_inserted", "treemodel,path,iter" },
+ { "GtkTreeModel::rows_reordered", "treemodel,path,iter,gint *new_order" },
+ { "GtkTreeView::expand_collapse_cursor_row", "treeview,logical,expand,open_all" },
+ { "GtkTreeView::move_cursor", "treeview,step,count" },
+ { "GtkTreeView::row_activated", "treeview,path,column" },
+ { "GtkTreeView::row_collapsed", "treeview,iter,path" },
+ { "GtkTreeView::row_expanded", "treeview,iter,path" },
+ { "GtkTreeView::select_cursor_row", "treeview,start_editing" },
+ { "GtkTreeView::set_scroll_adjustments", "treeview,hadjustment,vadjustment" },
+ { "GtkTreeView::test_collapse_row", "treeview,iter,path" },
+ { "GtkTreeView::test_expand_row", "treeview,iter,path" },
+ { "GtkViewport::set_scroll_adjustments", "viewport,hadjustment,vadjustment" },
+ { "GtkWidget::child_notify", "widget,pspec" },
+ { "GtkWidget::direction_changed", "widget,old_direction" },
+ { "GtkWidget::drag_begin", "widget,drag_context" },
+ { "GtkWidget::drag_data_delete", "widget,drag_context" },
+ { "GtkWidget::drag_data_get", "widget,drag_context,data,info,time" },
+ { "GtkWidget::drag_data_received", "widget,drag_context,x,y,data,info,time" },
+ { "GtkWidget::drag_drop", "widget,drag_context,x,y,time" },
+ { "GtkWidget::drag_end", "widget,drag_context" },
+ { "GtkWidget::drag_leave", "widget,drag_context,time" },
+ { "GtkWidget::drag_motion", "widget,drag_context,x,y,time" },
+ { "GtkWidget::focus", "widget,direction" },
+ { "GtkWidget::grab_notify", "widget,was_grabbed" },
+ { "GtkWidget::hierarchy_changed", "widget,previous_toplevel" },
+ { "GtkWidget::mnemonic_activate", "widget,group_cycling" },
+ { "GtkWidget::parent_set", "widget,old_parent" },
+ { "GtkWidget::selection_get", "widget,data,info,time" },
+ { "GtkWidget::selection_received", "widget,data,time" },
+ { "GtkWidget::show_help", "widget,help_type" },
+ { "GtkWidget::size_allocate", "widget,allocation" },
+ { "GtkWidget::size_request", "widget,requisition" },
+ { "GtkWidget::state_changed", "widget,state" },
+ { "GtkWidget::style_set", "widget,previous_style" },
+ { "GtkWindow::move_focus", "window,direction" },
+
+ /*
+ * libgnomeui Signals.
+ */
+ { "GnomeClient::connect", "client,restarted" },
+ { "GnomeClient::save_yourself", "client,phase,save_style,shutdown,interact_style,fast" },
+ { "GnomeColorPicker::color_set", "colorpicker,red,green,blue,alpha" },
+ { "GnomeDialog::clicked", "dialog,button_number" },
+ { "GnomeFontPicker::font_set", "fontpicker,font_name" },
+ { "GnomeIconList::focus_icon", "iconlist,num" },
+ { "GnomeIconList::move_cursor", "iconlist,direction,clear_selection" },
+ { "GnomeIconList::select_icon", "iconlist,num,event" },
+ { "GnomeIconList::text_changed", "iconlist,num,new_text" },
+ { "GnomeIconList::unselect_icon", "iconlist,num,event" },
+ { "GnomeMDI::add_child", "mdi,child" },
+ { "GnomeMDI::app_created", "mdi,app" },
+ { "GnomeMDI::child_changed", "mdi,child" },
+ { "GnomeMDI::remove_child", "mdi,child" },
+ { "GnomePropertyBox::apply", "propertybox,page_num" },
+ { "GnomePropertyBox::help", "propertybox,page_num" },
+
+ /*
+ * libgnomedb Signals.
+ */
+ { "GnomeDbBrowser::progress_message", "browser,message" },
+ { "GnomeDbDsnConfigDruid::finished", "druid,error" },
+ { "GnomeDbForm::model_changed", "form" },
+ { "GnomeDbGrid::row_selected", "grid,row" },
+ { "GnomeDbGrid::selection_cleared", "grid" },
+ { "GnomeDbList::row_selected", "list,row" },
+ { "GnomeDbList::selection_cleared", "list" },
+
+ { NULL, NULL }
+ };
+
+ gint i;
+
+ glade_signal_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (i = 0; signal_data[i][0]; i++)
+ {
+ g_hash_table_insert (glade_signal_hash, (char*) signal_data[i][0],
+ (char*) signal_data[i][1]);
+ }
+}
+
+
+/* This returns argument names to use for some known signals.
+ The returned array must be freed with g_str_freev(). */
+static gchar **
+lookup_signal_arg_names (gchar * type, gchar * signal_name,
+ gint num_args_expected)
+{
+ char *signal_id, *arg_names;
+ char **arg_array = NULL;
+
+ if (glade_signal_hash == NULL)
+ init_signal_hash ();
+
+ signal_id = g_strdup_printf ("%s::%s", type, signal_name);
+ arg_names = g_hash_table_lookup (glade_signal_hash, signal_id);
+#if 0
+ g_print ("Found signal: %s args: %s\n", signal_id, arg_names);
+#endif
+
+ if (arg_names)
+ {
+ gint num_args = 0;
+
+ arg_array = g_strsplit (arg_names, ",", -1);
+
+ while (arg_array[num_args])
+ num_args++;
+
+ /* Check we got the expected number of parameters. If not, output a
+ warning and return NULL. */
+ if (num_args != num_args_expected)
+ {
+ g_warning ("Internal error: argument names invalid for signal: %s."
+ "Expected %i arguments. Found %i",
+ signal_id, num_args_expected, num_args);
+ g_strfreev (arg_array);
+ arg_array = NULL;
+ }
+ }
+
+ g_free (signal_id);
+
+ return arg_array;
+}
+
+
+static void
+gb_widget_write_accelerators_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GList *item = data->widget_data->accelerators;
+ GladeAccelerator *accel;
+
+ while (item)
+ {
+ accel = (GladeAccelerator *) item->data;
+ item = item->next;
+
+ /* The code to create the accel_group is output in source.c */
+ data->need_accel_group = TRUE;
+ source_add (data,
+ " gtk_widget_add_accelerator (%s, \"%s\", accel_group,\n"
+ " GDK_%s, (GdkModifierType) %s,\n"
+ " GTK_ACCEL_VISIBLE);\n",
+ data->wname, accel->signal, accel->key,
+ glade_util_create_modifiers_string (accel->modifiers));
+ }
+}
+
diff --git a/tools/glade/glade/gbsource.h b/tools/glade/glade/gbsource.h
new file mode 100644
index 00000000..a5ff73fe
--- /dev/null
+++ b/tools/glade/glade/gbsource.h
@@ -0,0 +1,191 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_GBSOURCE_H
+#define GLADE_GBSOURCE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* These identify each of the source code buffers. New buffers can easily be
+ added by increasing GLADE_NUM_SOURCE_BUFFERS and adding an id here. */
+#define GLADE_NUM_SOURCE_BUFFERS 9
+typedef enum
+{
+ GLADE_UIINFO = 0, /* GnomeUIInfo structs, which are
+ output before the function as
+ static structs. */
+ GLADE_DECLARATIONS = 1, /* The declarations of the widgets
+ and temporary variables in the
+ function to create a component. */
+ GLADE_SOURCE = 2, /* The main code which creates the
+ widgets in a component. */
+ GLADE_SIGNAL_CONNECTIONS = 3, /* Code to connect signal handlers. */
+ GLADE_ACCELERATORS = 4, /* Code to setup accelerator keys, used
+ when the target widget is different
+ from the source (i.e. the label). */
+
+ GLADE_CALLBACK_DECLARATIONS = 5, /* Declarations of signal handler
+ functions and callbacks. */
+ GLADE_CALLBACK_SOURCE = 6, /* Source code of signal handlers or
+ callbacks. */
+ GLADE_OBJECT_HOOKUP = 7, /* Code to hookup pointers to widgets.
+ We put it all together so it can be
+ deleted easily if the user just
+ wants to pinch the source code. */
+ GLADE_ATK_SOURCE = 8 /* Code to set ATK properties, action
+ descriptions and relations. */
+} GladeSourceBuffer;
+
+
+typedef struct
+{
+ GladeProject *project;
+ GladeError *error; /* If an error occurs this will be
+ non-NULL, and will contain info
+ about the error. Note that we
+ abort the source generation as
+ soon as an error is encountered,
+ so there can only be one error. */
+ gchar *project_name;
+ gchar *program_name;
+ gchar *interface_c_filename; /* The full path of the source file
+ which creates the interface. */
+ gchar *interface_h_filename; /* The full path of the main header. */
+ gchar *callback_c_filename; /* The full path of the source file
+ where the empty callbacks/signal
+ handlers are added. */
+ gchar *callback_h_filename; /* The full path of callback header. */
+ gboolean set_widget_names; /* If gtk_widget_set_name (...) is
+ output to set the name of each
+ widget - useful for rc files. */
+ gboolean use_component_struct; /* TRUE if a struct is used to keep
+ pointers to all public widgets in a
+ component. (This is unfinished).
+ FALSE for the old behaviour of
+ using gtk_object_set_data () to
+ save pointers in the toplevel
+ widget's datalist. */
+ gboolean use_gettext; /* If strings in the source code are
+ marked with the standard gettext
+ macros _() or N_() so they can be
+ translated easily. */
+ gboolean creating_callback_files;/*TRUE if we are creating the files
+ containing the signal handlers and
+ callback functions. FALSE if we are
+ just appending new/updated
+ handlers and callbacks. */
+ time_t last_write_time; /* The last time that the source was
+ written. We need this to determine
+ exactly which signal handlers have
+ been added or updated. We get it
+ from one of the main source files.
+ */
+
+ gboolean need_tooltips; /* TRUE if any widgets in a component
+ have a tooltip set. If they do then
+ a GtkTooltips object has to be
+ created. */
+ gboolean need_accel_group; /* TRUE if any widgets have accelerator
+ keys set. If they do then an
+ accel_group needs to be created. */
+ gchar *wname; /* The C code to use to refer to the
+ widget currently being written.
+ This is the the name of the
+ variable holding the widget (which
+ is the same as the widget's name),
+ or if we are using structs to hold
+ pointers to all widgets this will
+ be something like "window1->label1".
+ See use_component_struct above. */
+ gchar *real_wname; /* This is the real name of the widget
+ currently being written, converted
+ so that it is a valid C identifier.
+ */
+ GtkWidget *component; /* This is the component currently
+ being output (i.e. a window/dialog).
+ */
+ gchar *component_name; /* This is the name of the component,
+ converted to a valid C identifier.
+ */
+ GladeWidgetData *widget_data; /* The GladeWidgetData of the widget
+ currently being output. */
+ GtkWidget *parent; /* The parent widget of the widget
+ currently being output. */
+ GHashTable *standard_widgets; /* A hash of GTK widgets used to
+ determine if values differ from
+ their default values. */
+ GtkWidget *standard_widget; /* This is the standard widget
+ corresponding to the widget being
+ written. It is used so we only
+ set properties which differ from the
+ standard setting. (It may be NULL,
+ in which case all properties should
+ be set). */
+ GHashTable *handlers_output; /* A hash of signal handlers we have
+ already output. */
+ gboolean create_widget; /* If TRUE then the code to create the
+ current widget needs to be output.
+ It is FALSE for widgets which are
+ created automatically by their
+ parents, e.g. filesel dialog
+ buttons. */
+ gboolean write_children; /* This is set to FALSE in a GbWidget
+ write_source() function to
+ indicate that the source code to
+ output the children has already
+ been written using explicit calls,
+ so the default recursive calls are
+ skipped. See gbwidgets/gbdialog.c */
+
+ gchar *focus_widget; /* Set to the name of the widget to
+ grab the focus. */
+ gchar *default_widget; /* Set to the name of the widget to
+ grab the default. We need to grab
+ the default after creating the
+ entire component, to overcome
+ problems with GnomeDialog. */
+
+ /* These buffers hold the code being generated for the current component
+ (window/dialog). When the component is finished they are all output
+ at once in the correct order, and with other necessary pieces of code
+ inserted. See source_write_component() in source.c. */
+ GString *source_buffers[GLADE_NUM_SOURCE_BUFFERS];
+} GbWidgetWriteSourceData;
+
+
+void gb_widget_write_source (GtkWidget *widget,
+ GbWidgetWriteSourceData *data);
+void gb_widget_write_standard_source
+ (GtkWidget *widget,
+ GbWidgetWriteSourceData *data);
+void gb_widget_write_add_child_source
+ (GtkWidget *widget,
+ GbWidgetWriteSourceData *data);
+void gb_widget_write_signal_handler_source
+ (GtkWidget *widget,
+ GbWidgetWriteSourceData *data,
+ const gchar *signal_name,
+ const gchar *handler);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_GBSOURCE_H */
diff --git a/tools/glade/glade/gbwidget.c b/tools/glade/glade/gbwidget.c
new file mode 100644
index 00000000..06969c46
--- /dev/null
+++ b/tools/glade/glade/gbwidget.c
@@ -0,0 +1,4434 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#endif
+
+#include "editor.h"
+#include "gb.h"
+#include "gbwidget.h"
+#include "glade.h"
+#include "glade_atk.h"
+#include "glade_gnome.h"
+#include "glade_gtk12lib.h"
+#include "glade_plugin.h"
+#include "glade_project.h"
+#include "load.h"
+#include "palette.h"
+#include "property.h"
+#include "save.h"
+#include "tree.h"
+#include "utils.h"
+
+#ifdef USE_GNOME
+#include "glade_gnomelib.h"
+#endif
+
+#ifdef USE_GNOME_DB
+#include "glade_gnomedblib.h"
+#endif
+
+/*
+ * The hash table associates a Gtk widget class name with a GbWidget struct,
+ * which contains a table of functions used by the builder, e.g. creating a
+ * new widget, saving the widget etc.
+ */
+static GHashTable *gb_widget_table = NULL;
+
+/* Tooltips for the created widgets */
+static GtkTooltips *gb_widget_tooltips;
+
+
+/* This is the GTK+ stock id string, used in GtkImageMenuItem widgets. */
+const gchar *GladeMenuItemStockIDKey = "GladeMenuItemStockIDKey";
+
+/* This is the old Gnome stock index key. */
+const gchar *GladeMenuItemStockIndexKey = "GladeMenuItemStockIndexKey";
+
+/* This is the key we use to store the stock icon name or full pathname. */
+const gchar *GladeIconKey = "GladeIconKey";
+
+/* This is used to save a pointer to the GladeWidgetInfo inside a widget while
+ loading, so we can resolve ATK relations afterwards. */
+const gchar *GladeWidgetInfoKey = "GladeWidgetInfoKey";
+
+
+static void gb_widget_init_widget_lib (GladePaletteSectionData *sections);
+
+static void on_widget_destroy (GtkWidget * widget,
+ gpointer data);
+
+#ifdef GLADE_STYLE_SUPPORT
+static void show_color_properties (GdkColor colors[],
+ gchar * name);
+#endif
+static void show_accelerators (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+static void show_signals (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+
+static void set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+static void set_position_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+static void set_special_child_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+static void set_lang_specific_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+#if 0
+static void apply_style (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+static gboolean apply_colors (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ GdkColor colors[],
+ GdkColor new_colors[],
+ gchar * name);
+#endif
+static void apply_accelerators (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+static void apply_signals (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+
+static void add_standard_top_menu_items (GtkWidget * widget,
+ GbWidgetCreateMenuData * data);
+static void add_standard_bottom_menu_items (GtkWidget * widget,
+ GbWidgetCreateMenuData * data);
+
+static void get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+
+static void get_position_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+static void get_lang_specific_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+
+static void save_accelerators (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+static void save_signals (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+
+
+static void gb_widget_add_alignment (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_widget_remove_alignment (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_widget_add_event_box (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_widget_remove_event_box (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_widget_redisplay_window (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_widget_add_scrolled_window (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_widget_remove_scrolled_window (GtkWidget * menuitem,
+ GtkWidget * widget);
+
+static void table_foreach (GtkTable * table,
+ GtkCallback callback,
+ gpointer callback_data);
+static void box_foreach (GtkBox *box,
+ GtkCallback callback,
+ gpointer callback_data);
+
+static gint find_notebook_page (GtkNotebook * notebook,
+ GtkWidget * current_child,
+ GtkWidget **page,
+ GtkWidget **tab_label);
+
+
+/* These aren't included in the Bonobo headers, so we declare them here to
+ avoid warnings. */
+#ifdef USE_GNOME
+void bonobo_dock_item_get_floating_position (BonoboDockItem *item,
+ gint *x, gint *y);
+gboolean bonobo_dock_item_detach (BonoboDockItem *item, gint x, gint y);
+#endif
+
+/*************************************************************************
+ * Initialization functions
+ *************************************************************************/
+
+void
+gb_widgets_init ()
+{
+ gb_widget_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+#ifdef GLADE_STYLE_SUPPORT
+ gb_widget_reset_gb_styles ();
+#endif
+
+ /* Create tooltips */
+ gb_widget_tooltips = gtk_tooltips_new ();
+
+ gb_widget_init_widget_lib (get_gtk_widgets());
+#ifdef USE_GNOME
+ gb_widget_init_widget_lib (get_gnome_widgets());
+#endif
+#ifdef USE_GNOME_DB
+ gb_widget_init_widget_lib (get_gnome_db_widgets());
+#endif
+
+ glade_plugin_load_plugins ();
+}
+
+static void
+gb_widget_init_widget_lib (GladePaletteSectionData *sections)
+{
+ gint index, j;
+ GladeWidgetInitData *gwid;
+ GladePaletteSectionData *palsec;
+ GbWidget *(*init_func) ();
+ GbWidget *gbwidget;
+
+ index = 0;
+ while (1)
+ {
+ j = 0;
+ palsec = &sections[index];
+ index++;
+ if (!palsec->section)
+ break;
+ while (1)
+ {
+ gwid = &palsec->widgets[j];
+ j++;
+ if (!gwid->name)
+ break;
+ init_func = gwid->init_func;
+ gbwidget = (*init_func) ();
+ gb_widget_register_gbwidget (gwid->name, gbwidget);
+ palette_add_gbwidget (gbwidget, palsec->section, gwid->name);
+ }
+ }
+}
+
+
+/* Adds a GbWidget to the hash of known GbWidgets. The class_id is copied. */
+void
+gb_widget_register_gbwidget (const gchar *class_id,
+ GbWidget *gbwidget)
+{
+ gbwidget->class_id = g_strdup (class_id);
+ g_hash_table_insert (gb_widget_table, gbwidget->class_id, gbwidget);
+}
+
+
+/* This returns the GbWidget struct corresponding to the given class name. */
+GbWidget *
+gb_widget_lookup_class (const gchar *class_id)
+{
+ GbWidget *gbwidget;
+
+ gbwidget = (GbWidget *) g_hash_table_lookup (gb_widget_table, class_id);
+
+ return gbwidget;
+}
+
+
+/* This returns the GbWidget struct corresponding to the given widget. */
+GbWidget *
+gb_widget_lookup (GtkWidget *widget)
+{
+ GladeWidgetData *wdata;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget),
+ GB_WIDGET_DATA_KEY);
+
+ if (!wdata) {
+ const gchar *class_name;
+
+ MSG ("Widget has no associated GladeWidgetData");
+
+ /* Fall back to the original way we used to get the GbWidget*, since
+ some widgets currently don't have a GladeWidgetData attached. */
+ class_name = gtk_type_name (GTK_OBJECT_TYPE (widget));
+ return (GbWidget *) g_hash_table_lookup (gb_widget_table, class_name);
+ }
+
+ return wdata->gbwidget;
+}
+
+
+gchar*
+gb_widget_get_class_id (GtkWidget *widget)
+{
+ GbWidget *gbwidget;
+
+ gbwidget = gb_widget_lookup (widget);
+
+ if (gbwidget)
+ return gbwidget->class_id;
+ else
+ return (char*) gtk_type_name (GTK_OBJECT_TYPE (widget));
+}
+
+
+void
+gb_widget_init_struct (GbWidget * gbwidget)
+{
+ gbwidget->pixmap_struct = NULL;
+ gbwidget->class_id = NULL;
+ gbwidget->gdkpixmap = NULL;
+ gbwidget->mask = NULL;
+ gbwidget->tooltip = NULL;
+ gbwidget->pixbuf = NULL;
+ gbwidget->properties_page_number = GB_PROPERTIES_NOT_CREATED;
+ gbwidget->child_properties_page_number = GB_PROPERTIES_NOT_CREATED;
+
+ gbwidget->gb_widget_new = NULL;
+ gbwidget->gb_widget_create_from_widget = NULL;
+
+ gbwidget->gb_widget_create_properties = NULL;
+ gbwidget->gb_widget_get_properties = NULL;
+ gbwidget->gb_widget_set_properties = NULL;
+
+ gbwidget->gb_widget_add_child = NULL;
+ gbwidget->gb_widget_get_child = NULL;
+
+ gbwidget->gb_widget_create_child_properties = NULL;
+ gbwidget->gb_widget_get_child_properties = NULL;
+ gbwidget->gb_widget_set_child_properties = NULL;
+
+ gbwidget->gb_widget_write_add_child_source = NULL;
+
+ gbwidget->gb_widget_create_popup_menu = NULL;
+
+ gbwidget->gb_widget_write_source = NULL;
+
+ gbwidget->gb_widget_destroy = NULL;
+}
+
+
+
+/*************************************************************************
+ * Functions for creating & destroying GbWidgets
+ *************************************************************************/
+
+GtkWidget *
+gb_widget_new (const gchar * class_id, GtkWidget * parent)
+{
+ return gb_widget_new_full (class_id, TRUE, parent, NULL, 0, 0, NULL,
+ GB_CREATING, NULL);
+}
+
+
+/* Creates a new widget.
+ * class_id is the name of the widget class, e.g. 'GtkLabel'
+ * create_default_name is TRUE if you want a default name to be created,
+ * e.g. 'label1'.
+ * parent is the widget that the new widget will be added beneath, so that
+ * the callback function knows where to put the widget.
+ * current_child is the widget that the new widget will replace, or NULL
+ * if the new widget is just being added. It is used when replacing
+ * placeholders.
+ * x & y are the coordinates of the new widget if it is being added to a
+ * GtkFixed container.
+ * callback is the function to call once the widget is created to actually
+ * add it to the parent. Some widgets require dialog boxes for creating
+ * them (e.g. the dialog box to set the number of rows/cols in a table).
+ * So we need to provide a function to be called after this is done
+ * (we could have possibly chosen to use modal dialogs instead.)
+ * action is either GB_CREATING or GB_LOADING. When loading widgets we don't
+ * want dialog boxes to pop up when they are being created.
+ * loading_data is set when action is GB_LOADING, and contains the data used
+ * while loading, so that the GbWidgets can get any properties they need to
+ * create the widget without popping up a dialog box.
+ */
+GtkWidget *
+gb_widget_new_full (const gchar * class_id, gboolean create_default_name,
+ GtkWidget * parent, GtkWidget * current_child,
+ gint x, gint y, GbWidgetNewCallback callback,
+ GbWidgetAction action, GbWidgetSetArgData * loading_data)
+{
+ GbWidgetNewData *data;
+ GtkWidget *new_widget;
+ GbWidget *gbwidget;
+ GType type;
+
+ gbwidget = gb_widget_lookup_class (class_id);
+ g_return_val_if_fail (gbwidget != NULL, NULL);
+
+ /* Note that for custom widgets this won't be found, and so will be 0. */
+ type = g_type_from_name (class_id);
+#if 0
+ g_print ("Class Name: %s Type: %i\n", class_id, type);
+#endif
+
+ data = g_new (GbWidgetNewData, 1);
+ /* Don't set data->name to NULL, since many widgets use it to set the label
+ of the new widget. */
+ data->project = current_project;
+ data->name = create_default_name ? glade_project_new_widget_name (data->project, class_id) : g_strdup ("");
+ data->callback = callback;
+ data->parent = parent;
+ if (parent) {
+ gtk_widget_ref (parent);
+ if (!gb_widget_lookup (parent))
+ MSG2 ("Registering unknown widget '%s' as parent of '%s'",
+ G_OBJECT_TYPE_NAME (parent), class_id);
+ }
+ data->current_child = current_child;
+ if (current_child)
+ gtk_widget_ref (current_child);
+ data->x = x;
+ data->y = y;
+ data->widget_data = glade_widget_data_new (gbwidget);
+ data->action = action;
+ data->loading_data = loading_data;
+
+ if (gbwidget->gb_widget_new)
+ new_widget = (gbwidget->gb_widget_new) (data);
+ else if (type != 0)
+ new_widget = gtk_widget_new (type, NULL);
+ else
+ g_return_val_if_fail ((new_widget = NULL), NULL);
+
+ /* If the widget has been created immediately, then we can finish it off now,
+ and free the GbWidgetNewData struct, otherwise we leave that to the
+ dialog. */
+ if (new_widget)
+ {
+ gb_widget_initialize (new_widget, data);
+ if (data->callback)
+ (*data->callback) (new_widget, data);
+ gb_widget_free_new_data (data);
+ }
+
+ return new_widget;
+}
+
+static void
+gb_widget_real_initialize (GtkWidget * widget, GladeWidgetData * wdata)
+{
+ g_return_if_fail (wdata != NULL);
+ g_return_if_fail (wdata->gbwidget != NULL);
+
+ /* Make sure GtkMenu widgets have visible set to FALSE. */
+ if (GTK_IS_MENU (widget) && wdata)
+ wdata->flags &= ~GLADE_VISIBLE;
+
+ gtk_object_set_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY, wdata);
+ gtk_signal_connect (GTK_OBJECT (widget), "destroy",
+ GTK_SIGNAL_FUNC (on_widget_destroy), NULL);
+
+ editor_add_mouse_signals (widget);
+ editor_add_draw_signals (widget);
+ editor_add_key_signals (widget);
+
+ if (GTK_IS_WINDOW (widget))
+ gtk_window_add_accel_group (GTK_WINDOW (widget),
+ glade_get_global_accel_group ());
+
+#ifdef USE_GNOME
+ /* FIXME: GnomeLibs 1.0.1 workaround - floating GnomeDockItem's don't work
+ properly if we show them before adding to the GnomeDock. */
+ if (!GTK_IS_WINDOW (widget) && !GTK_IS_MENU (widget)
+ && !BONOBO_IS_DOCK_ITEM (widget))
+ gtk_widget_show (widget);
+#else
+ if (!GTK_IS_WINDOW (widget) && !GTK_IS_MENU (widget))
+ gtk_widget_show (widget);
+#endif
+}
+
+/* This turns a normal widget into a GbWidget, adding a GladeWidgetData struct
+ and the necessary signals. The widget must have its parent set already.
+ If name is non-NULL, the widget's name will be set to the name with a
+ unique ID added on to it, e.g. "ok_button1".
+ NOTE: when loading, you should not create the names of any widgets,
+ since it may clash with a widget loaded later. Instead leave the name as
+ NULL. glade_project_ensure_widgets_named () will be called after the
+ project is loaded, and any widgets without names will have names
+ generated for them. */
+void
+gb_widget_create_from (GtkWidget *widget,
+ const gchar *name)
+{
+ gb_widget_create_from_full (widget, name, NULL);
+}
+
+
+void
+gb_widget_create_from_full (GtkWidget *widget,
+ const gchar *name,
+ GladeWidgetData *wdata)
+{
+ GbWidget *gbwidget;
+ const char *class_id;
+
+ MSG1 ("In create_from, widget name: %s", gtk_widget_get_name (widget));
+ if (name)
+ {
+ char *wname = glade_project_new_widget_name (current_project, name);
+ gtk_widget_set_name (widget, wname);
+ g_free (wname);
+ }
+
+ if (GLADE_IS_CUSTOM_WIDGET (widget))
+ class_id = "Custom";
+ else
+ class_id = gtk_type_name (GTK_OBJECT_TYPE (widget));
+
+ gbwidget = (GbWidget *) g_hash_table_lookup (gb_widget_table, class_id);
+ g_return_if_fail (gbwidget != NULL);
+
+ if (!wdata)
+ wdata = glade_widget_data_new (gbwidget);
+ gb_widget_real_initialize (widget, wdata);
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ /* Call any function the GbWidget has for setting up the widget to be used
+ within Glade. */
+ if (gbwidget->gb_widget_create_from_widget)
+ {
+ GbWidgetCreateFromData data;
+
+ data.project = current_project;
+ (gbwidget->gb_widget_create_from_widget) (widget, &data);
+ }
+}
+
+
+void
+gb_widget_initialize (GtkWidget * widget, GbWidgetNewData * data)
+{
+ if (data->name && data->name[0] != '\0')
+ gtk_widget_set_name (widget, data->name);
+ gb_widget_real_initialize (widget, data->widget_data);
+
+ /* Now we set the widget's real style */
+ /* FIXME: check if style should be propagated down from an ancestor? */
+#if 0
+ if (widget->style != data->widget_data->gbstyle->style)
+ {
+ gtk_widget_set_style (widget, data->widget_data->gbstyle->style);
+ }
+#endif
+
+ /* FIXME: GTK workarounds to make sure that some widgets have reasonable
+ sizes initially. Quite a few widgets default to a width and height of 0,
+ which means that if there is little space available they will disappear,
+ so we may need to do more here. */
+ if (GTK_IS_ARROW (widget))
+ gtk_widget_set_usize (widget, 16, 16);
+
+ /* Set this to NULL so we don't try to free it later. */
+ data->widget_data = NULL;
+}
+
+/* This returns TRUE if it is OK to complete the new() procedure, i.e. that
+ the widget to replace or the parent widget still exist. It is used after
+ the OK button is pressed in the dialog boxes for creating new tables/boxes.
+ FIXME: I'm not too sure what we should do here. */
+gboolean
+gb_widget_can_finish_new (GbWidgetNewData * data)
+{
+ if (data->current_child)
+ {
+ if (data->current_child->parent == NULL)
+ return FALSE;
+ }
+ else if (data->parent)
+ {
+ if (data->parent->parent == NULL && !GTK_IS_WINDOW (data->parent))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+void
+gb_widget_free_new_data (GbWidgetNewData * data)
+{
+ g_free (data->name);
+ g_free (data->widget_data);
+ if (data->parent)
+ gtk_widget_unref (data->parent);
+ if (data->current_child)
+ gtk_widget_unref (data->current_child);
+ g_free (data);
+}
+
+
+static void
+on_widget_destroy (GtkWidget * widget, gpointer user_data)
+{
+ GbWidget *gbwidget;
+ GladeWidgetData *widget_data;
+ GbWidgetDestroyData data;
+
+ MSG1 ("IN on_widget_destroy widget:%s", gtk_widget_get_name (widget));
+
+ /* Make sure we don't try to show its properties after it is destroyed. */
+ if (property_get_widget () == widget)
+ property_set_widget (NULL);
+
+ /* If the entire project is being destroyed, we don't need to update the
+ selection or the widget tree. */
+ if (!(GTK_OBJECT_FLAGS (current_project) & GTK_IN_DESTRUCTION))
+ {
+ editor_remove_widget_from_selection (widget);
+ tree_remove_widget (widget);
+ }
+
+ editor_on_widget_destroyed (widget);
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ /* Call the GbWidget destroy function, if it has one. */
+ data.project = current_project;
+ if (gbwidget->gb_widget_destroy)
+ (gbwidget->gb_widget_destroy) (widget, &data);
+
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+
+ /* Release the ID. */
+ if (widget->name)
+ glade_project_release_widget_name (current_project, widget->name);
+
+ glade_widget_data_free (widget_data);
+
+ g_free (gb_widget_get_child_name (widget));
+
+ MSG1 ("OUT on_widget_destroy widget:%s", gtk_widget_get_name (widget));
+}
+
+
+/*************************************************************************
+ * Functions for getting/setting the child name of a widget.
+ * The child name is used to identify special widgets which have to
+ * be treated differently. e.g. Dialog buttons.
+ *************************************************************************/
+
+static const gchar *glade_child_name_key = "glade-child-name";
+static GQuark glade_child_name_key_id = 0;
+
+
+/* Returns the child name of the widget. */
+gchar*
+gb_widget_get_child_name (GtkWidget *widget)
+{
+ if (!glade_child_name_key_id)
+ glade_child_name_key_id = g_quark_from_static_string (glade_child_name_key);
+ return gtk_object_get_data_by_id (GTK_OBJECT (widget),
+ glade_child_name_key_id);
+}
+
+
+/* Sets the child name of the widget. The child_name string is duplicated. */
+void
+gb_widget_set_child_name (GtkWidget *widget, const gchar *child_name)
+{
+ if (!glade_child_name_key_id)
+ glade_child_name_key_id = g_quark_from_static_string (glade_child_name_key);
+ /* Free any existing child name. */
+ g_free (gtk_object_get_data_by_id (GTK_OBJECT (widget),
+ glade_child_name_key_id));
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), glade_child_name_key_id,
+ g_strdup (child_name));
+}
+
+
+/*************************************************************************
+ * Functions for creating the page of properties specific to this widget
+ *************************************************************************/
+
+/* Returns the page number of the new page in the notebook which contains the
+ widget's specific properties, or GB_PROPERTIES_NOT_NEEDED if it has none. */
+gint
+gb_widget_create_properties (GtkWidget * widget)
+{
+ GtkWidget *page;
+ gint page_number;
+ GbWidgetCreateArgData data;
+ GbWidget *gbwidget;
+ gboolean add_border_width = FALSE;
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_val_if_fail (gbwidget != NULL, GB_PROPERTIES_NOT_NEEDED);
+
+ /* We always create the border width property, but hide it when it isn't
+ needed. Some specific widgets don't need it, e.g. GtkDialog action areas.
+ */
+ /*if (glade_util_uses_border_width (widget))*/
+ add_border_width = TRUE;
+
+ if (gbwidget->gb_widget_create_properties || add_border_width)
+ {
+ /* Create skeleton of properties page, so gbwidget just has to add
+ properties */
+ page = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (page), 1);
+ gtk_widget_show (page);
+ page_number = property_add_gbwidget_page (page);
+ property_set_table_position (page, 0);
+
+ /* If widget is a container add a border width property */
+ if (add_border_width)
+ {
+ gchar *class_id, buf[128];
+
+ class_id = gb_widget_get_class_id (widget);
+ sprintf (buf, "%s::border_width", class_id);
+ property_add_int_range (buf, _("Border Width:"),
+ _("The width of the border around the container"),
+ 0, 1000, 1, 10, 1);
+ }
+
+ data.project = current_project;
+ if (gbwidget->gb_widget_create_properties)
+ (gbwidget->gb_widget_create_properties) (widget, &data);
+ return page_number;
+ }
+ else
+ {
+ return GB_PROPERTIES_NOT_NEEDED;
+ }
+}
+
+
+/*************************************************************************
+ * Functions for creating the page of place properties specific to this
+ * widget.
+ *************************************************************************/
+
+/* Returns the page number of the new page in the notebook which contains the
+ widget's properties which applt to any children of the widget,
+ or GB_PROPERTIES_NOT_NEEDED if no extra properties are needed for its
+ children. */
+gint
+gb_widget_create_child_properties (GtkWidget * widget)
+{
+ static GHashTable *page_hash_table = NULL;
+
+ GtkWidget *page;
+ gint page_number;
+ GbWidgetCreateChildArgData data;
+ GbWidget *gbwidget;
+
+ /* Create a hash table to contain functions already called to create child
+ packing properties together with the page numbers they returned.
+ This lets us use the same functions for multiple widgets, e.g. GtkHBox
+ and GtkVBox, GtkHPaned and GtkVPaned. */
+ if (page_hash_table == NULL)
+ page_hash_table = g_hash_table_new (NULL, NULL);
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_val_if_fail (gbwidget != NULL, GB_PROPERTIES_NOT_NEEDED);
+
+ if (gbwidget->gb_widget_create_child_properties)
+ {
+ /* First see if the function has already been called. Note that the
+ page numbers in the hash have 1 added to them so we can detect empty
+ values (they won't clash with page 0). */
+ /* FIXME: ANSI forbids casting function pointer to data pointer. */
+ page_number = GPOINTER_TO_INT (g_hash_table_lookup (page_hash_table, (gconstpointer) gbwidget->gb_widget_create_child_properties));
+ if (page_number)
+ return page_number - 1;
+
+ /* Create skeleton of properties page, so gbwidget just has to add
+ properties */
+ page = gtk_table_new (10, 3, FALSE);
+ gtk_widget_show (page);
+ page_number = property_add_child_packing_page (page);
+ /* FIXME: ANSI forbids casting function pointer to data pointer. */
+ g_hash_table_insert (page_hash_table,
+ (gpointer) gbwidget->gb_widget_create_child_properties,
+ GINT_TO_POINTER (page_number + 1));
+ property_set_table_position (page, 0);
+
+ data.project = current_project;
+ (gbwidget->gb_widget_create_child_properties) (widget, &data);
+ return page_number;
+ }
+ else
+ {
+ return GB_PROPERTIES_NOT_NEEDED;
+ }
+}
+
+
+/*************************************************************************
+ * Functions for showing the widget's properties
+ *************************************************************************/
+
+void
+gb_widget_show_properties (GtkWidget * widget)
+{
+ GbWidgetGetArgData data;
+ GbWidget *gbwidget, *parent_gbwidget = NULL;
+ GladeWidgetData *widget_data;
+ gint page, child_packing_page;
+
+ /* If properties of widget are already shown, just return */
+ if (property_get_widget () == widget)
+ return;
+
+ /* If widget is a placeholder reset the properties window and return */
+ if (GB_IS_PLACEHOLDER (widget))
+ {
+ property_set_widget (NULL);
+ return;
+ }
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ /* Turn off auto-apply so we can set properties without the 'changed'
+ callbacks calling gb_widget_apply_properties (). */
+ property_set_auto_apply (FALSE);
+
+ /* Need this here to make sure properties notebook is sensitive */
+ property_set_widget (widget);
+
+ page = gbwidget->properties_page_number;
+ /* If widget's properties page hasn't been created, create it now */
+ if (page == GB_PROPERTIES_NOT_CREATED)
+ {
+ page = gb_widget_create_properties (widget);
+ gbwidget->properties_page_number = page;
+ }
+
+ /* Show the widget's own properties page if it has one.
+ Need to show the page before setting properties because of the
+ Text widget - it must be realized before setting the text :-( */
+ if (page == GB_PROPERTIES_NOT_NEEDED)
+ property_hide_gbwidget_page ();
+ else
+ property_show_gbwidget_page (page);
+
+ /* Now see if the parent has child packing properties that need to be
+ created or shown. */
+ if (widget->parent)
+ {
+ parent_gbwidget = gb_widget_lookup (widget->parent);
+
+ /* parent_gbwidget may be NULL, e.g. for GnomeDockItems. */
+ if (parent_gbwidget)
+ {
+ child_packing_page = parent_gbwidget->child_properties_page_number;
+ /* If widget's properties page hasn't been created, create it now */
+ if (child_packing_page == GB_PROPERTIES_NOT_CREATED)
+ {
+ child_packing_page = gb_widget_create_child_properties (widget->parent);
+ parent_gbwidget->child_properties_page_number = child_packing_page;
+ }
+
+ if (child_packing_page == GB_PROPERTIES_NOT_NEEDED)
+ property_hide_child_packing_page ();
+ else
+ property_show_child_packing_page (child_packing_page);
+ }
+ }
+ else
+ {
+ property_hide_child_packing_page ();
+ }
+
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (widget_data != NULL);
+ data.project = current_project;
+ data.action = GB_SHOWING;
+ data.widget_data = widget_data;
+ data.widget = widget;
+
+ get_standard_properties (widget, &data);
+
+ if (gbwidget->gb_widget_get_properties)
+ (gbwidget->gb_widget_get_properties) (widget, &data);
+
+ if (parent_gbwidget && parent_gbwidget->gb_widget_get_child_properties)
+ (parent_gbwidget->gb_widget_get_child_properties) (widget->parent, widget,
+ &data);
+
+ /* Turn auto-apply back on again */
+ property_set_auto_apply (TRUE);
+}
+
+
+/* This is called when the widget's size or position has changed, so that we
+ should update the values shown in the properties editor. */
+void
+gb_widget_show_position_properties (GtkWidget * widget)
+{
+ GbWidgetGetArgData data;
+ GladeWidgetData *widget_data;
+
+ /* Make sure this is the widget shown in the properties editor. */
+ if (property_get_widget () != widget)
+ return;
+
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (widget_data != NULL);
+ data.project = current_project;
+ data.action = GB_SHOWING;
+ data.widget_data = widget_data;
+
+ property_set_auto_apply (FALSE);
+ get_position_properties (widget, &data);
+ property_set_auto_apply (TRUE);
+}
+
+
+
+#ifdef GLADE_STYLE_SUPPORT
+void
+gb_widget_show_style (GtkWidget * widget)
+{
+ GladeWidgetData *wdata;
+ GbStyle *gbstyle;
+ GtkStyle *style = widget->style;
+ gchar buffer[128];
+ gint i;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+ gbstyle = wdata->gbstyle;
+
+ property_set_bool (GbStylePropagate, wdata->flags & GLADE_STYLE_PROPAGATE);
+
+ property_set_dialog (GbStyleName, wdata->flags & GLADE_STYLE_IS_UNNAMED ?
+ "" : gbstyle->name, NULL);
+ property_set_font (GbStyleFont, style->font, gbstyle->xlfd_fontname);
+
+ /* Colors */
+ show_color_properties (style->fg, "fg");
+ show_color_properties (style->bg, "bg");
+ show_color_properties (style->text, "text");
+ show_color_properties (style->base, "base");
+
+ /* Background pixmaps */
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ sprintf (buffer, "GtkStyle::%s[%s]", GbBgPixmapName, GbStateNames[i]);
+ property_set_bgpixmap (buffer, style->bg_pixmap[i],
+ gbstyle->bg_pixmap_filenames[i]);
+ }
+}
+
+
+static void
+show_color_properties (GdkColor colors[], gchar * name)
+{
+ gint state;
+ gchar buf[128];
+
+ for (state = 0; state < GB_NUM_STYLE_STATES; state++)
+ {
+ sprintf (buf, "GtkStyle::%s[%s]", name, GbStateNames[state]);
+ property_set_color (buf, &colors[state]);
+ }
+}
+#endif
+
+
+static void
+show_accelerators (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GList *element = data->widget_data->accelerators;
+ property_clear_accelerators ();
+ while (element)
+ {
+ property_add_accelerator ((GladeAccelerator *) element->data);
+ element = element->next;
+ }
+}
+
+
+static void
+show_signals (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GList *element = data->widget_data->signals;
+ property_clear_signals ();
+ MSG1 ("Num signals: %i", g_list_length (element));
+ while (element)
+ {
+ property_add_signal ((GladeSignal *) element->data);
+ element = element->next;
+ }
+}
+
+
+
+/*************************************************************************
+ * Functions for applying properties to a widget
+ *************************************************************************/
+
+void
+gb_widget_apply_properties (GtkWidget * widget, GtkWidget * property)
+{
+ GbWidgetSetArgData data;
+ GbWidget *gbwidget;
+ GladeWidgetData *widget_data;
+
+ MSG1 ("Applying properties: %s", gtk_widget_get_name (widget));
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (widget_data != NULL);
+
+ data.project = current_project;
+ data.action = GB_APPLYING;
+ data.widget_data = widget_data;
+ data.widget = widget;
+ data.property_to_apply = property;
+
+ set_standard_properties (widget, &data);
+
+ MSG ("Calling widget's own apply_properties");
+ if (gbwidget->gb_widget_set_properties)
+ (gbwidget->gb_widget_set_properties) (widget, &data);
+ MSG ("Called widget's own apply_properties");
+}
+
+
+/* Copies the signals from the GladeWidgetInfo into a list of GladeSignal
+ structs. */
+static GList*
+copy_signals (GbWidgetSetArgData * data, GladeWidgetInfo *widget_info)
+{
+ GList *signals = NULL;
+ GladeSignalInfo *signal_info;
+ gint i;
+
+ signal_info = widget_info->signals;
+ for (i = 0; i < widget_info->n_signals; i++)
+ {
+ GladeSignal *signal = g_new0 (GladeSignal, 1);
+
+ signal->name = g_strdup (signal_info[i].name);
+ signal->handler = g_strdup (signal_info[i].handler);
+ signal->object = g_strdup (signal_info[i].object);
+ signal->after = signal_info[i].after ? TRUE : FALSE;
+ signal->data = NULL; /* Not supported anymore. */
+ signal->last_modification_time = load_parse_date (data, signal_info[i].last_modification_time);
+
+ if (data->status == GLADE_STATUS_INVALID_VALUE)
+ {
+ g_warning ("Invalid date value: %s", signal_info[i].last_modification_time);
+ data->status = GLADE_STATUS_OK;
+ }
+
+ signals = g_list_prepend (signals, signal);
+ }
+
+ /* Reverse the list so it stays in the original order. */
+ return g_list_reverse (signals);
+}
+
+
+/* Copies the accelerators from the GladeWidgetInfo into a list of
+ GladeAccelerator structs. */
+static GList*
+copy_accels (GladeWidgetInfo *widget_info)
+{
+ GList *accels = NULL;
+ GladeAccelInfo *accel_info;
+ gint i;
+
+ accel_info = widget_info->accels;
+ for (i = 0; i < widget_info->n_accels; i++)
+ {
+ GladeAccelerator *accel = g_new0 (GladeAccelerator, 1);
+
+ accel->key = g_strdup (gdk_keyval_name (accel_info[i].key));
+ accel->modifiers = accel_info[i].modifiers;
+ accel->signal = g_strdup (accel_info[i].signal);
+
+ accels = g_list_prepend (accels, accel);
+ }
+
+ /* Reverse the list so it stays in the original order. */
+ return g_list_reverse (accels);
+}
+
+
+static void
+set_standard_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gchar *name, *tooltip, *events_str, *ext_events;
+ gboolean visible, sensitive, can_default, has_default, can_focus, has_focus;
+ gint events, i;
+
+ /* Properties on widget page */
+ /* When pasting, we may want to discard the names from the XML, and generate
+ a new name instead. */
+ if (data->action == GB_LOADING)
+ {
+ if (data->xml_buffer && data->discard_names)
+ {
+ gchar *class_id = gb_widget_get_class_id (widget);
+ name = glade_project_new_widget_name (data->project, class_id);
+ gtk_widget_set_name (widget, name);
+ g_free (name);
+ }
+ else
+ {
+ gtk_widget_set_name (widget, data->widget_info->name);
+ }
+
+ if (glade_util_is_component (widget))
+ glade_project_component_changed (data->project, widget);
+
+ /* We have to check if the name has a trailing ID and if so we reserve
+ it so no other widget can use it. */
+ glade_project_reserve_name (data->project, gtk_widget_get_name (widget));
+ }
+ else
+ {
+ name = gb_widget_input_string (data, GbName);
+ if (data->apply)
+ {
+ tree_rename_widget (widget, name);
+ gtk_widget_set_name (widget, name);
+ property_update_title ();
+
+ /* If widget is a toplevel window/dialog set the component's name in
+ the project window */
+ if (glade_util_is_component (widget))
+ glade_project_component_changed (data->project, widget);
+ }
+ }
+
+ /* If widget is a container, show the border width */
+ if (glade_util_uses_border_width (widget))
+ {
+ gchar buf[128];
+ gint border_width;
+ gchar *class_id;
+
+ class_id = gb_widget_get_class_id (widget);
+ sprintf (buf, "%s::border_width", class_id);
+ border_width = gb_widget_input_int (data, buf);
+ if (data->apply && GTK_CONTAINER (widget)->border_width != border_width)
+ {
+ gtk_container_set_border_width (GTK_CONTAINER (widget),
+ border_width);
+ if (data->action == GB_APPLYING)
+ editor_refresh_widget (widget);
+ }
+ }
+
+ /* Language-specific properties. */
+ set_lang_specific_properties (widget, data);
+
+ /* Special child properties page */
+ set_special_child_properties (widget, data);
+
+ /* Properties on standard page */
+ set_position_properties (widget, data);
+
+ /* Visible property. Note that we create widgets with visible set to TRUE
+ by default, but the property is FALSE by default in the XML file. So
+ when loading we make sure we set the flag to the appropriate value. */
+ visible = gb_widget_input_bool (data, GbVisible);
+ if (data->apply || data->action == GB_LOADING)
+ {
+ if (!data->apply)
+ visible = FALSE;
+ if (visible)
+ wdata->flags |= GLADE_VISIBLE;
+ else
+ wdata->flags &= ~GLADE_VISIBLE;
+ }
+
+ sensitive = gb_widget_input_bool (data, GbSensitive);
+ if (data->apply)
+ {
+ if (sensitive)
+ wdata->flags |= GLADE_SENSITIVE;
+ else
+ wdata->flags &= ~GLADE_SENSITIVE;
+ }
+
+ tooltip = gb_widget_input_string (data, GbTooltip);
+ if (data->apply)
+ {
+ g_free (wdata->tooltip);
+ if (tooltip && tooltip[0] == '\0')
+ tooltip = NULL;
+ wdata->tooltip = g_strdup (tooltip);
+
+ /* SPECIAL CODE: toolitems have a special function. */
+ if (GTK_IS_TOOL_ITEM (widget))
+ gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (widget),
+ gb_widget_tooltips, tooltip, NULL);
+ else
+ gtk_tooltips_set_tip (gb_widget_tooltips, widget, tooltip, NULL);
+ }
+
+ can_default = gb_widget_input_bool (data, GbCanDefault);
+ if (data->apply)
+ {
+ if (can_default)
+ GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
+ else
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT);
+ if (data->action == GB_APPLYING)
+ editor_refresh_widget (widget);
+ }
+
+ has_default = gb_widget_input_bool (data, GbHasDefault);
+ if (data->apply)
+ {
+ if (has_default)
+ wdata->flags |= GLADE_GRAB_DEFAULT;
+ else
+ wdata->flags &= ~GLADE_GRAB_DEFAULT;
+ }
+
+ /* Different widgets have different default values for CAN_FOCUS, so when
+ we load an XML file we must make sure that we always set it or unset it.
+ Also, since we don't save the can_focus flag if it is false, we must make
+ sure that we apply it anyway when loading. */
+ can_focus = gb_widget_input_bool (data, GbCanFocus);
+ if (!data->apply)
+ can_focus = FALSE;
+ if (data->apply || data->action == GB_LOADING)
+ {
+ if (can_focus)
+ GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+ else
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
+ }
+ has_focus = gb_widget_input_bool (data, GbHasFocus);
+ if (data->apply)
+ {
+ if (has_focus)
+ wdata->flags |= GLADE_GRAB_FOCUS;
+ else
+ wdata->flags &= ~GLADE_GRAB_FOCUS;
+ }
+
+ /* Events & ext events. */
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ if (data->action == GB_APPLYING)
+ {
+ events = property_events_string_to_value (gb_widget_input_string (data,
+ GbEvents));
+ if (data->apply)
+ wdata->events = events;
+ }
+ else
+ {
+ events_str = gb_widget_input_string (data, GbEvents);
+ if (data->apply)
+ {
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ if (glade_util_strstr (events_str, GbEventMaskSymbols[i]))
+ wdata->events |= GbEventMaskValues[i];
+ }
+ }
+ }
+
+ ext_events = gb_widget_input_choice (data, GbExtEvents);
+ if (data->apply)
+ {
+ for (i = 0; GbExtensionModeChoices[i]; i++)
+ {
+ if (!strcmp (ext_events, GbExtensionModeChoices[i])
+ || !strcmp (ext_events, GbExtensionModeSymbols[i]))
+ {
+ gtk_widget_set_extension_events (widget, GbExtensionModeValues
+ [i]);
+ break;
+ }
+ }
+ }
+ }
+
+ if (data->action == GB_APPLYING)
+ {
+#if 0
+ apply_style (widget, data);
+#endif
+ apply_accelerators (widget, data);
+ apply_signals (widget, data);
+
+ glade_atk_set_properties (widget, data);
+ }
+ else
+ {
+ data->widget_data->signals = copy_signals (data, data->widget_info);
+ data->widget_data->accelerators = copy_accels (data->widget_info);
+
+ /* ATK properties are loaded later, after all widgets are created. */
+ }
+}
+
+
+static void
+set_special_child_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ GtkWidget *parent = widget->parent;
+ GbWidget *gbparent;
+
+ if (!parent)
+ return;
+
+ /* When pasting a widget to replace an existing widget, the child properties
+ will already have been set, so we just return. */
+ if (data->action == GB_LOADING && data->xml_buffer && data->replacing_widget)
+ return;
+
+ gbparent = gb_widget_lookup (parent);
+ if (!gbparent)
+ {
+ MSG1 ("Unknown parent type %s", G_OBJECT_TYPE_NAME (parent));
+ }
+
+ /* Tell the load functions to use the child properties array. */
+ data->loading_type = GB_CHILD_PROPERTIES;
+
+ if (gbparent && gbparent->gb_widget_set_child_properties)
+ {
+ (gbparent->gb_widget_set_child_properties) (parent, widget, data);
+ }
+
+ data->loading_type = GB_STANDARD_PROPERTIES;
+}
+
+
+static void
+set_position_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gint w, h;
+ gboolean applyWidth, applyHeight;
+ gboolean set_usize = FALSE;
+
+ w = gb_widget_input_int (data, GbWidth);
+ applyWidth = data->apply;
+ h = gb_widget_input_int (data, GbHeight);
+ applyHeight = data->apply;
+
+ /* When loading we need to remember which values have been set explicitly. */
+ if (data->action == GB_LOADING)
+ {
+ if (applyWidth)
+ wdata->flags |= GLADE_WIDTH_SET;
+ if (applyHeight)
+ wdata->flags |= GLADE_HEIGHT_SET;
+ }
+
+#if 0
+ g_print ("In set_position_properties X:%i Y:%i W:%i H:%i\n", x, y, w, h);
+#endif
+ if (GTK_IS_WINDOW (widget))
+ {
+ if (applyWidth && wdata->width != w)
+ {
+ wdata->width = w;
+ set_usize = TRUE;
+ }
+ if (applyHeight && wdata->height != h)
+ {
+ wdata->height = h;
+ set_usize = TRUE;
+ }
+
+ if (set_usize)
+ {
+ gint w = wdata->flags & GLADE_WIDTH_SET ? wdata->width : -1;
+ gint h = wdata->flags & GLADE_HEIGHT_SET ? wdata->height : -1;
+ gb_widget_set_usize (widget, w, h);
+ }
+ }
+ else if (widget->parent && (GTK_IS_FIXED (widget->parent)
+ || GTK_IS_LAYOUT (widget->parent)))
+ {
+ /* When pasting a widget to replace an existing widget, the size &
+ position will be set in the replace_child function. */
+ if (data->action == GB_LOADING && data->xml_buffer
+ && data->replacing_widget)
+ {
+ return;
+ }
+
+
+ if (applyWidth && wdata->width != w)
+ {
+ wdata->width = w;
+ set_usize = TRUE;
+ }
+ if (applyHeight && wdata->height != h)
+ {
+ wdata->height = h;
+ set_usize = TRUE;
+ }
+ if (set_usize)
+ gb_widget_set_usize (widget, wdata->width, wdata->height);
+ }
+ else
+ {
+ if (applyWidth && wdata->width != w)
+ {
+ wdata->width = w;
+ set_usize = TRUE;
+ }
+ if (applyHeight && wdata->height != h)
+ {
+ wdata->height = h;
+ set_usize = TRUE;
+ }
+
+ if (set_usize)
+ {
+ gint w = wdata->flags & GLADE_WIDTH_SET ? wdata->width : -1;
+ gint h = wdata->flags & GLADE_HEIGHT_SET ? wdata->height : -1;
+ gb_widget_set_usize (widget, w, h);
+ }
+ MSG2 ("*** Width set:%i Height set:%i", wdata->flags & GLADE_WIDTH_SET,
+ wdata->flags & GLADE_HEIGHT_SET);
+ }
+}
+
+
+#if 0
+static void
+apply_style (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ GtkStyle *style = widget->style, *old_style = NULL;
+ GbStyle *gbstyle = wdata->gbstyle, *new_gbstyle;
+ GdkFont *font = NULL;
+ gchar *style_name, *xlfd_fontname;
+ GdkColor fg[GB_NUM_STYLE_STATES];
+ GdkColor bg[GB_NUM_STYLE_STATES];
+ GdkColor text[GB_NUM_STYLE_STATES];
+ GdkColor base[GB_NUM_STYLE_STATES];
+ GdkPixmap *bg_pixmap[GB_NUM_STYLE_STATES];
+ gchar *bg_pixmap_filenames[GB_NUM_STYLE_STATES];
+ gint recreate = FALSE, redraw = FALSE, i;
+ gchar buf[128], *filename;
+ gboolean named_style;
+
+ style_name = gb_widget_input_dialog (data, GbStyleName);
+ named_style = (style_name[0] == '\0') ? FALSE : TRUE;
+ if (data->apply)
+ {
+ if (named_style)
+ {
+ new_gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, style_name);
+ g_return_if_fail (new_gbstyle != NULL);
+ if (new_gbstyle != gbstyle)
+ {
+ gbstyle = new_gbstyle;
+ gb_widget_set_gb_style (widget, gbstyle);
+ wdata->flags &= ~GLADE_STYLE_IS_UNNAMED;
+ redraw = TRUE;
+ }
+ }
+ else
+ {
+ wdata->flags |= GLADE_STYLE_IS_UNNAMED;
+ }
+ }
+
+ font = gb_widget_input_font (data, GbStyleFont, &xlfd_fontname);
+ if (data->apply)
+ {
+ if (font != style->font)
+ recreate = TRUE;
+ }
+
+ recreate |= apply_colors (widget, data, style->fg, fg, "fg");
+ recreate |= apply_colors (widget, data, style->bg, bg, "bg");
+ recreate |= apply_colors (widget, data, style->text, text, "text");
+ recreate |= apply_colors (widget, data, style->base, base, "base");
+
+ /* Background pixmaps */
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ sprintf (buf, "GtkStyle::%s[%s]", GbBgPixmapName, GbStateNames[i]);
+ bg_pixmap[i] = gb_widget_input_bgpixmap (data, buf, &filename);
+ bg_pixmap_filenames[i] = filename;
+ if (data->apply)
+ {
+ if (bg_pixmap[i] != style->bg_pixmap[i])
+ recreate = TRUE;
+ }
+ }
+
+ if (recreate)
+ {
+ old_style = style;
+
+ /* If the widget is supposedly using an unnamed GbStyle, but currently is
+ actually using a named GbStyle (for convenience), then we need to
+ create a copy of the GbStyle and place our new style in it. */
+ if ((wdata->flags & GLADE_STYLE_IS_UNNAMED) && gbstyle->name)
+ {
+ gbstyle = gb_widget_copy_gb_style (gbstyle);
+ g_free (gbstyle->name);
+ gbstyle->name = NULL;
+ }
+
+ style = gtk_style_new ();
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ style->fg[i] = fg[i];
+ style->bg[i] = bg[i];
+ style->text[i] = text[i];
+ style->base[i] = base[i];
+ style->bg_pixmap[i] = bg_pixmap[i];
+ if (bg_pixmap[i])
+ gdk_pixmap_ref (bg_pixmap[i]);
+
+ if (gbstyle->bg_pixmap_filenames[i] != bg_pixmap_filenames[i])
+ {
+ g_free (gbstyle->bg_pixmap_filenames[i]);
+ gbstyle->bg_pixmap_filenames[i] = g_strdup (bg_pixmap_filenames
+ [i]);
+ }
+ }
+ if (font)
+ {
+ gdk_font_unref (style->font);
+ style->font = font;
+ gdk_font_ref (style->font);
+ }
+ if (strcmp (gbstyle->xlfd_fontname, xlfd_fontname))
+ {
+ g_free (gbstyle->xlfd_fontname);
+ gbstyle->xlfd_fontname = g_strdup (xlfd_fontname);
+ }
+
+ gbstyle->style = style;
+ gtk_style_ref (style);
+ gb_widget_set_gb_style (widget, gbstyle);
+ }
+
+
+ /* If a named style has been changed/recreated we have to update all
+ widget's that use it. */
+ if (recreate || redraw)
+ {
+ if (named_style)
+ {
+ gb_widget_update_gb_styles (gbstyle, gbstyle);
+ }
+ else
+ {
+ editor_refresh_widget (widget);
+ }
+ }
+
+ if (old_style)
+ gtk_style_unref (old_style);
+}
+
+
+/* This makes sure a widget's gbstyle & its style are up to date, and
+ if the propagate flag is set it also updates any children.
+ But it won't change a descendant's style if it has been set explicitly.
+ FIXME: only propagates one level at present, and always sets child's style,
+ even if it has a different GbStyle! */
+void
+gb_widget_set_gb_style (GtkWidget * widget,
+ GbStyle * gbstyle)
+{
+ GladeWidgetData *wdata;
+
+ if (!GB_IS_PLACEHOLDER (widget))
+ {
+ if (widget->style != gbstyle->style)
+ gtk_widget_set_style (widget, gbstyle->style);
+ }
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ if (wdata)
+ {
+ if (wdata->gbstyle != gbstyle)
+ {
+ gb_widget_unref_gb_style (wdata->gbstyle);
+ wdata->gbstyle = gbstyle;
+ gb_widget_ref_gb_style (gbstyle);
+ }
+ /* If propagate style flags is set, propagate style to children */
+ if (wdata->flags & GLADE_STYLE_PROPAGATE)
+ gb_widget_children_foreach (widget, (GtkCallback) gb_widget_set_gb_style,
+ gbstyle);
+ }
+}
+
+
+static gboolean
+apply_colors (GtkWidget * widget, GbWidgetSetArgData * data, GdkColor colors[],
+ GdkColor new_colors[], gchar * name)
+{
+ gint state;
+ gchar buf[128];
+ GdkColor *color;
+ gboolean need_redraw = FALSE;
+
+ for (state = 0; state < GB_NUM_STYLE_STATES; state++)
+ {
+ sprintf (buf, "GtkStyle::%s[%s]", name, GbStateNames[state]);
+
+ color = gb_widget_input_color (data, buf);
+ if (data->apply)
+ {
+ new_colors[state] = *color;
+ if (!gdk_color_equal (&new_colors[state], &colors[state]))
+ need_redraw = TRUE;
+ }
+ else
+ {
+ /* Copy the old values across. */
+ new_colors[state] = colors[state];
+ }
+ }
+ return need_redraw;
+}
+#endif
+
+
+/* Currently this frees all the GladeAccelerators and creates them from scratch */
+static void
+apply_accelerators (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GladeWidgetData *wdata;
+
+ if (data->property_to_apply == NULL
+ || property_is_accel_clist (data->property_to_apply))
+ {
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ glade_widget_data_set_accels (wdata, property_get_accelerators ());
+ }
+}
+
+
+/* Currently this frees all the GladeSignals and creates them from scratch. */
+static void
+apply_signals (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GladeWidgetData *wdata;
+
+ if (data->property_to_apply == NULL
+ || property_is_signal_clist (data->property_to_apply))
+ {
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ glade_widget_data_set_signals (wdata, property_get_signals ());
+ }
+}
+
+
+
+/*************************************************************************
+ * Functions for showing the popup context-sensitive menu of a widget
+ *************************************************************************/
+
+static void
+popup_done (GtkWidget *widget, gpointer data)
+{
+ gtk_widget_destroy (widget);
+}
+
+void
+gb_widget_show_popup_menu (GtkWidget * widget,
+ GdkEventButton * event)
+{
+ GtkWidget *menu = NULL;
+ GbWidget *gbwidget;
+ const gchar *name;
+ GtkWidget *menuitem, *ancestor, *submenu, *child;
+ GbWidgetCreateMenuData data;
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ name = gtk_widget_get_name (widget);
+ if (GB_IS_PLACEHOLDER (widget))
+ name = "Placeholder";
+
+ menu = gtk_menu_new ();
+ menuitem = gtk_menu_item_new_with_label (name);
+ gtk_widget_show (menuitem);
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ data.project = current_project;
+ data.menu = menu;
+ data.child = NULL;
+ add_standard_top_menu_items (widget, &data);
+
+ if (gbwidget->gb_widget_create_popup_menu)
+ (gbwidget->gb_widget_create_popup_menu) (widget, &data);
+
+ add_standard_bottom_menu_items (widget, &data);
+
+ child = widget;
+ ancestor = widget->parent;
+ while (ancestor)
+ {
+ name = gtk_widget_get_name (ancestor);
+ if (GB_IS_PLACEHOLDER (ancestor))
+ name = "Placeholder";
+
+ /* Skip widgets which aren't GbWidgets */
+ if (GB_IS_GB_WIDGET (ancestor))
+ {
+ /* Add a separator */
+ menuitem = gtk_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_menu_item_new_with_label (name);
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ /* Create submenu */
+ submenu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
+
+ data.menu = submenu;
+ data.child = child;
+ add_standard_top_menu_items (ancestor, &data);
+
+ /* Call ancestors function to add any menu items */
+ gbwidget = gb_widget_lookup (ancestor);
+ if (gbwidget != NULL && gbwidget->gb_widget_create_popup_menu)
+ (gbwidget->gb_widget_create_popup_menu) (ancestor, &data);
+
+ add_standard_bottom_menu_items (ancestor, &data);
+ }
+ child = ancestor;
+ ancestor = ancestor->parent;
+ }
+
+ /* Automatically destroy the menu when it is hidden. */
+ gtk_signal_connect_after (GTK_OBJECT (menu), "selection-done",
+ GTK_SIGNAL_FUNC (popup_done), menu);
+
+ MSG ("showing popup menu");
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+}
+
+
+static void
+add_standard_top_menu_items (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_label (_("Select"));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (editor_on_select_activate), widget);
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+}
+
+
+static void
+add_standard_bottom_menu_items (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+ gboolean can_delete;
+
+ can_delete = (editor_can_delete_widget (widget) == NULL) ? TRUE : FALSE;
+
+ /* For widgets which can handle scrolling, we add commands to add or remove
+ a parent scrolled window. */
+ if (GTK_WIDGET_CLASS (G_OBJECT_GET_CLASS (widget))->set_scroll_adjustments_signal)
+ {
+ if (widget->parent && GTK_IS_SCROLLED_WINDOW (widget->parent))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Remove Scrolled Window"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_remove_scrolled_window),
+ widget);
+ }
+ else
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Scrolled Window"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_add_scrolled_window),
+ widget);
+ }
+ }
+
+ /* We assume that we can only insert/remove alignments and event boxes if
+ the widget can be deleted. */
+ if (can_delete
+ && !GTK_IS_WINDOW (widget)
+ && !GTK_IS_MISC (widget)
+ && !GTK_IS_ALIGNMENT (widget)
+ && !GTK_IS_MENU (widget)
+ && !GTK_IS_MENU_ITEM (widget)
+ && !GB_IS_PLACEHOLDER (widget))
+ {
+ if (GTK_IS_ALIGNMENT (widget->parent))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Remove Alignment"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_remove_alignment), widget);
+ }
+ else
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Alignment"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_add_alignment), widget);
+ }
+ }
+
+ if (can_delete
+ && GTK_WIDGET_NO_WINDOW (widget)
+ && !GTK_IS_EVENT_BOX (widget)
+ && !GB_IS_PLACEHOLDER (widget))
+ {
+ if (GTK_IS_EVENT_BOX (widget->parent))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Remove Event Box"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_remove_event_box), widget);
+ }
+ else
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Event Box"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_add_event_box), widget);
+ }
+ }
+
+ if (GTK_IS_WINDOW (widget))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Redisplay"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_redisplay_window),
+ widget);
+ }
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+
+ /* Only show the 'Cut' item if the widget can be deleted. */
+ if (can_delete)
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Cut"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (editor_on_cut_activate), widget);
+ }
+
+ menuitem = gtk_menu_item_new_with_label (_("Copy"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (editor_on_copy_activate), widget);
+
+ /* Only show the 'Paste' item if the widget can be deleted. */
+ if (can_delete)
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Paste"));
+ gtk_widget_show (menuitem);
+ if (!widget->parent)
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (editor_on_paste_activate), widget);
+ }
+
+ /* Only show the 'Delete' item if the widget can be deleted. */
+ if (can_delete)
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Delete"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (editor_on_delete_activate), widget);
+ }
+}
+
+
+
+/*************************************************************************
+ * Functions for loading project files
+ *************************************************************************/
+
+/* This reads in a widget, and calls itself recursively to read it's children.
+ It assumes a '<widget>' has just been read, and reads up to and including
+ '</widget>'. The newly-created widget is returned, mainly so that
+ glade_clipboard_paste () can show any windows which are pasted. */
+GtkWidget*
+gb_widget_load (GtkWidget * widget, GbWidgetSetArgData * data, GtkWidget * parent)
+{
+ gchar *class_id;
+ const gchar *child_name;
+ GbWidget *gbwidget, *ancestor_gbwidget;
+ GtkWidget *ancestor;
+ GladeWidgetData *wdata;
+ GladeChildInfo *child_info;
+ GladeWidgetInfo *widget_info;
+ gint i;
+ gboolean skip_child;
+
+ data->action = GB_LOADING;
+ data->loading_type = GB_STANDARD_PROPERTIES;
+
+ child_info = data->child_info;
+ widget_info = data->widget_info;
+
+ class_id = widget_info ? widget_info->class : NULL;
+ MSG1 ("Reading Class: %s", class_id ? class_id : "(placeholder)");
+
+ child_name = child_info ? child_info->internal_child : NULL;
+
+ /* Migrate toolbar buttons from old XML files. See the set_properties
+ functions in gbtoolbutton.c etc. for the code that reads in the old
+ properties. */
+ if (class_id)
+ {
+ if (!strcmp (class_id, "button"))
+ {
+ class_id = "GtkToolButton";
+ }
+ else if (!strcmp (class_id, "toggle"))
+ {
+ class_id = "GtkToggleToolButton";
+ }
+ else if (!strcmp (class_id, "radio"))
+ {
+ class_id = "GtkRadioToolButton";
+ }
+ }
+
+ /* SPECIAL CODE: CList/CTree title buttons don't save the child name now, so
+ we have to add it. */
+ if (parent && GTK_IS_CLIST (parent))
+ child_name = GladeChildCListTitle;
+
+ /* SPECIAL CODE: Ignore the old 'BonoboDock:contents' child name. */
+ if (child_name && !strcmp (child_name, "BonoboDock:contents"))
+ child_name = NULL;
+
+ /* SPECIAL CODE: when pasting a widget to replace an existing widget, check
+ if the child name should be transferred to the new widget. */
+ if (data->xml_buffer && data->replacing_widget && child_name)
+ {
+ /* These child names should be removed from the widget when it is pasted,
+ since they identify the old position the widget. */
+ if (!strcmp (child_name, GladeChildOKButton)
+ || !strcmp (child_name, GladeChildCancelButton)
+ || !strcmp (child_name, GladeChildHelpButton)
+ || !strcmp (child_name, GladeChildApplyButton)
+ || !strcmp (child_name, GladeChildSaveButton)
+ || !strcmp (child_name, GladeChildCloseButton)
+ || !strcmp (child_name, GladeChildDialogVBox)
+ || !strcmp (child_name, GladeChildDialogActionArea)
+ || !strcmp (child_name, GladeChildComboEntry)
+ || !strcmp (child_name, GladeChildComboList)
+ || !strcmp (child_name, GladeChildFontSelection)
+ || !strcmp (child_name, GladeChildColorSelection)
+ || !strcmp (child_name, GladeChildGnomeAppDock)
+ || !strcmp (child_name, GladeChildGnomeAppBar)
+ || !strcmp (child_name, GladeChildGnomeEntry)
+ )
+ {
+ child_name = NULL;
+ }
+ }
+
+ if (!class_id)
+ {
+ MSG ("found placeholder");
+ widget = editor_new_placeholder ();
+ if (!gb_widget_add_child (parent, data, widget))
+ {
+ data->status = GLADE_STATUS_ERROR;
+ return NULL;
+ }
+ if (child_name)
+ gb_widget_set_child_name (widget, child_name);
+ return NULL;
+ }
+
+ gbwidget = gb_widget_lookup_class (class_id);
+ if (gbwidget == NULL)
+ {
+ MSG ("Load error");
+ data->status = GLADE_STATUS_CLASS_UNKNOWN;
+ g_warning ("Unknown widget class: %s", class_id);
+ return NULL;
+ }
+
+ /* If this is a special child of a widget, step through the ancestors of
+ the widget and try to find it. Note that some special child widgets
+ have to be created normally, and then added by the parent container,
+ e.g. notebook tabs and clist titles - see gb_widget_add_child(). */
+ if (child_name)
+ {
+ MSG1 ("Child name: %s", child_name);
+ ancestor = parent;
+ while (ancestor)
+ {
+ ancestor_gbwidget = gb_widget_lookup (ancestor);
+ if (ancestor_gbwidget && ancestor_gbwidget->gb_widget_get_child)
+ {
+ widget = (ancestor_gbwidget->gb_widget_get_child) (ancestor,
+ child_name);
+ if (widget)
+ break;
+ }
+
+ ancestor = ancestor->parent;
+ }
+
+#if 0
+ if (!widget)
+ g_print ("Child widget %s not found - may be a problem\n", child_name);
+#endif
+ }
+
+ /* If this is a standard widget, we need to create it and add it to its
+ parent. If the widget has already been created by its parent, we can
+ just set the properties. */
+ if (widget == NULL)
+ {
+ MSG ("widget == NULL, has not been created by parent.");
+ widget = gb_widget_new_full (class_id, FALSE, parent, NULL,
+ 0, 0, NULL, GB_LOADING, data);
+ if (!widget)
+ {
+ data->status = GLADE_STATUS_ERROR;
+ return NULL;
+ }
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ data->widget_data = wdata;
+ data->widget = widget;
+
+ /* We get the gbwidget from the widget data, as it may be different from
+ the original one. Currently only Bonobo controls do this. */
+ gbwidget = wdata->gbwidget;
+ g_assert (gbwidget);
+
+ if (parent == NULL)
+ {
+ glade_project_add_component (data->project, widget);
+ }
+ else
+ {
+ if (!gb_widget_add_child (parent, data, widget))
+ {
+ data->status = GLADE_STATUS_ERROR;
+ return NULL;
+ }
+ }
+
+ /* This must come after add_child so we can set special child properties,
+ and also we may need to realize the widget. It must also come after
+ glade_project_add_component(), in case setting any properties results
+ in a signal being emitted from the project. */
+ set_standard_properties (widget, data);
+
+ tree_add_widget (widget);
+ }
+ else
+ {
+ MSG ("widget != NULL, has been created by parent.");
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ if (wdata == NULL)
+ g_warning ("Null widget_data\n");
+ data->widget_data = wdata;
+ data->widget = widget;
+ set_standard_properties (widget, data);
+ tree_add_widget (widget);
+ }
+
+ if (child_name)
+ gb_widget_set_child_name (widget, child_name);
+
+ if (data->status != GLADE_STATUS_OK)
+ {
+ MSG ("Load error");
+ return NULL;
+ }
+
+ MSG ("Calling widgets set_properties()");
+ if (gbwidget->gb_widget_set_properties)
+ (gbwidget->gb_widget_set_properties) (widget, data);
+ MSG ("Called widgets set_properties()");
+
+ if (data->status != GLADE_STATUS_OK)
+ {
+ MSG ("Load error");
+ return NULL;
+ }
+
+ /* Save a pointer to the widget in the all_widgets hash, when loading and
+ when pasting. Note that when pasting we use the name before any renaming
+ is done, so ATK relation targets within the widget hierarchy being
+ pasted will still be correct. */
+ if (data->all_widgets)
+ {
+ const gchar *widget_name = widget_info->name;
+ if (widget_name && *widget_name)
+ {
+#if 0
+ g_print ("Saving pointer to widget: %s, %p\n", widget_name, widget);
+#endif
+ g_hash_table_insert (data->all_widgets, (gpointer) widget_name,
+ widget);
+ }
+ }
+
+ /* Save a pointer to the GladeWidgetInfo in the widget, which we use to
+ load the ATK properties after all widgets are created. */
+ gtk_object_set_data (GTK_OBJECT (widget), GladeWidgetInfoKey, widget_info);
+
+ /* When pasting, we only ever replace the top widget. All children are added
+ as normal. */
+ data->replacing_widget = NULL;
+
+ MSG ("Loading children");
+
+ /* load children. */
+ for (i = 0; i < widget_info->n_children; i++)
+ {
+ data->child_info = &widget_info->children[i];
+ data->widget_info = data->child_info->child;
+
+ /* We have to reset the widget_data since this may have been changed
+ while loading the last child (and its children) */
+ data->widget_data = wdata;
+ if (widget->parent && !gb_widget_lookup (widget->parent))
+ {
+ MSG1 ("Unusual widget here of type '%s'",
+ G_OBJECT_TYPE_NAME (widget->parent));
+ }
+
+ /* Skip the hscrollbar & vscrollbar internal children, from
+ GtkScrolledWindow. libglade-convert outputs these, but we don't
+ use them. */
+ skip_child = FALSE;
+ if (data->child_info && data->child_info->internal_child)
+ {
+ if (!strcmp (data->child_info->internal_child, "vscrollbar")
+ || !strcmp (data->child_info->internal_child, "hscrollbar"))
+ skip_child = TRUE;
+ }
+
+ if (!skip_child)
+ gb_widget_load (NULL, data, widget);
+
+ /* Reset these, just in case. */
+ data->child_info = child_info;
+ data->widget_info = widget_info;
+
+ if (data->status != GLADE_STATUS_OK)
+ {
+ MSG ("Load error");
+ return NULL;
+ }
+ }
+
+ /* If the widget is a table, we make sure all empty cells have placeholders
+ in them. */
+ if (GTK_IS_TABLE (widget))
+ {
+ gb_table_update_placeholders (widget, -1, -1);
+ }
+
+ return widget;
+}
+
+
+/* Adds a widget to a parent, when loading or pasting from the clipboard.
+ Returns TRUE on success. */
+gboolean
+gb_widget_add_child (GtkWidget * parent,
+ GbWidgetSetArgData * data,
+ GtkWidget * child)
+{
+ GbWidget *gbwidget;
+
+ MSG2 ("Adding %s to %s", gtk_widget_get_name (child),
+ parent ? gtk_widget_get_name (parent) : "NULL");
+
+ g_return_val_if_fail (parent != NULL, FALSE);
+
+ /* If we are pasting, the top widget replaces the parent rather than being
+ added to it. */
+ if (data->xml_buffer && data->replacing_widget)
+ {
+ return gb_widget_replace_child (parent, data->replacing_widget, child);
+ }
+
+ gbwidget = gb_widget_lookup (parent);
+ g_return_val_if_fail (gbwidget != NULL, FALSE);
+
+ if (gbwidget->gb_widget_add_child)
+ {
+ gbwidget->gb_widget_add_child (parent, child, data);
+ }
+ else if (GTK_IS_BIN (parent))
+ {
+ if (GTK_BIN (parent)->child)
+ gtk_container_remove (GTK_CONTAINER (parent), GTK_BIN (parent)->child);
+ gtk_container_add (GTK_CONTAINER (parent), child);
+ }
+ else if (GTK_IS_CONTAINER (parent))
+ {
+ gtk_container_add (GTK_CONTAINER (parent), child);
+ }
+
+ return TRUE;
+}
+
+
+/*************************************************************************
+ * Functions for saving project files
+ *************************************************************************/
+
+void
+gb_widget_save (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ GbWidget *gbwidget, *parent_gbwidget;
+ GladeWidgetData *widget_data;
+ gchar *child_name, *class_id, *id, *class_to_save;
+ gboolean is_toplevel;
+
+ class_id = class_to_save = gb_widget_get_class_id (widget);
+ child_name = gb_widget_get_child_name (widget);
+ is_toplevel = glade_util_is_component (widget);
+
+ /* Bonobo Controls are save with a class of 'BonoboWidget'. */
+#ifdef USE_GNOME
+ if (gtk_object_get_data (GTK_OBJECT (widget), Moniker))
+ class_to_save = "BonoboWidget";
+#endif
+
+ /* SPECIAL CODE: CList/CTree title buttons don't save the child name. */
+ if (child_name && !strcmp (child_name, GladeChildCListTitle))
+ {
+ child_name = NULL;
+ }
+
+ /* SPECIAL CODE: Don't save a placeholder if its parent is a table, since we
+ don't really want placeholders in the XML when the interface is finished,
+ but it is quite possible that some table cells will be left blank. */
+ if (GB_IS_PLACEHOLDER (widget))
+ {
+ if (!GTK_IS_TABLE (widget->parent))
+ {
+ save_newline (data);
+
+ if (!is_toplevel)
+ save_child_start_tag (data, child_name);
+
+ save_placeholder (data);
+
+ if (!is_toplevel)
+ save_end_tag (data, "child");
+ }
+ return;
+ }
+
+ /* Write out widget data and any child widgets */
+ widget_data = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+
+ /* If this isn't a gbwidget, skip it, but save any child gbwidgets. */
+ if (!widget_data)
+ {
+ /* Recursively save children. */
+ gb_widget_children_foreach (widget, (GtkCallback) gb_widget_save, data);
+ return;
+ }
+
+ data->action = GB_SAVING;
+ data->widget_data = widget_data;
+ data->widget = widget;
+
+ save_newline (data);
+ if (!is_toplevel)
+ save_child_start_tag (data, child_name);
+
+ id = (char*) gtk_widget_get_name (widget);
+ save_widget_start_tag (data, class_to_save, id);
+
+ get_standard_properties (widget, data);
+
+ /* Call gbwidgets save function for any extra properties */
+ gbwidget = gb_widget_lookup_class (class_id);
+ g_return_if_fail (gbwidget != NULL);
+
+ if (gbwidget->gb_widget_get_properties)
+ (gbwidget->gb_widget_get_properties) (widget, data);
+
+ glade_atk_save_properties (widget, data);
+
+ save_signals (widget, data);
+ save_accelerators (widget, data);
+
+ /* Recursively save children. */
+ gb_widget_children_foreach (widget, (GtkCallback) gb_widget_save, data);
+
+ save_end_tag (data, "widget");
+
+ /* Call parent widget's function to save child packing properties. */
+ if (widget->parent)
+ {
+ parent_gbwidget = gb_widget_lookup (widget->parent);
+ /* parent_gbwidget may be NULL, e.g. for GnomeDockItems. */
+ if (parent_gbwidget
+ && parent_gbwidget->gb_widget_get_child_properties)
+ (parent_gbwidget->gb_widget_get_child_properties) (widget->parent,
+ widget, data);
+#ifdef USE_GNOME
+ else if (BONOBO_IS_DOCK_ITEM (widget))
+ {
+ gb_bonobo_dock_item_save_packing_properties (widget->parent, widget,
+ data);
+ }
+#endif
+ }
+
+ if (!is_toplevel)
+ save_end_tag (data, "child");
+}
+
+
+/* This outputs all the standard widget properties, for showing or saving.
+ Note that when saving we try not to save default values. */
+static void
+get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ gboolean can_default, has_default, can_focus, has_focus, visible, sensitive;
+ GladeWidgetData *wdata = data->widget_data;
+ gchar *name, *class_id;
+ GbWidgetAction action = data->action;
+ gchar border_width_property_buf[128];
+ gboolean border_width_visible = FALSE;
+
+ /* The class and name (id) are saved in gb_widget_save, so don't save them
+ here. */
+ name = (char*) gtk_widget_get_name (widget);
+ class_id = gb_widget_get_class_id (widget);
+ if (action != GB_SAVING)
+ {
+ gb_widget_output_string (data, GbName, name);
+ gb_widget_output_string (data, GbClass, class_id);
+ }
+
+ /* If widget is a container, save the border width */
+ sprintf (border_width_property_buf, "%s::border_width", class_id);
+ if (glade_util_uses_border_width (widget))
+ {
+ gint border_width;
+ border_width_visible = TRUE;
+ border_width = GTK_CONTAINER (widget)->border_width;
+ if (action != GB_SAVING || border_width > 0)
+ {
+ gb_widget_output_int (data, border_width_property_buf, border_width);
+ }
+ }
+ if (action == GB_SHOWING)
+ {
+ property_set_visible (border_width_property_buf, border_width_visible);
+ }
+
+ get_position_properties (widget, data);
+ get_lang_specific_properties (widget, data);
+
+ visible = wdata->flags & GLADE_VISIBLE;
+ if (action != GB_SAVING || visible)
+ gb_widget_output_bool (data, GbVisible, visible);
+ sensitive = wdata->flags & GLADE_SENSITIVE;
+ if (action != GB_SAVING || !sensitive)
+ gb_widget_output_bool (data, GbSensitive, sensitive);
+
+ /* Only widgets with windows can have tooltips at present. Though buttons
+ seem to be a special case, as they are NO_WINDOW widgets but have
+ InputOnly windows, so tooltip still work. In GTK+ 2 menuitems are like
+ buttons. */
+ if (!GTK_WIDGET_NO_WINDOW (widget) || GTK_IS_BUTTON (widget)
+ || GTK_IS_MENU_ITEM (widget) || GTK_IS_TOOL_BUTTON (widget)
+ || GTK_IS_EVENT_BOX (widget))
+ {
+ if (action != GB_SAVING || wdata->tooltip)
+ gb_widget_output_translatable_string (data, GbTooltip, wdata->tooltip);
+ if (action == GB_SHOWING)
+ property_set_sensitive (GbTooltip, TRUE);
+ }
+ else if (action == GB_SHOWING)
+ {
+ /* N/A stands for 'Not Applicable'. It is used when a standard widget
+ property does not apply to the current widget. e.g. widgets without
+ windows can't use the Events property. This appears in the property
+ editor and so should be a short abbreviation. */
+ gb_widget_output_string (data, GbTooltip, _("N/A"));
+ property_set_sensitive (GbTooltip, FALSE);
+ }
+
+ can_default = GTK_WIDGET_CAN_DEFAULT (widget);
+ if (action != GB_SAVING || can_default)
+ gb_widget_output_bool (data, GbCanDefault, can_default);
+ has_default = wdata ? wdata->flags & GLADE_GRAB_DEFAULT : 0;
+ if (action != GB_SAVING || has_default)
+ gb_widget_output_bool (data, GbHasDefault, has_default);
+
+ can_focus = GTK_WIDGET_CAN_FOCUS (widget);
+ if (action != GB_SAVING || can_focus)
+ gb_widget_output_bool (data, GbCanFocus, can_focus);
+ has_focus = wdata ? wdata->flags & GLADE_GRAB_FOCUS : 0;
+ if (action != GB_SAVING || has_focus)
+ gb_widget_output_bool (data, GbHasFocus, has_focus);
+
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ GdkExtensionMode ext_mode = gtk_widget_get_extension_events (widget);
+ gint i;
+
+ if (action == GB_SAVING)
+ {
+ if (wdata && wdata->events)
+ {
+ gchar buffer[1024];
+ gboolean written_first = FALSE;
+
+ buffer[0] = '\0';
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ if (wdata->events & GbEventMaskValues[i])
+ {
+ if (written_first)
+ strcat (buffer, " | ");
+ strcat (buffer, GbEventMaskSymbols[i]);
+ written_first = TRUE;
+ }
+ }
+
+ gb_widget_output_string (data, GbEvents, buffer);
+ }
+ }
+ else
+ {
+ gb_widget_output_string (data, GbEvents,
+ property_events_value_to_string (wdata->events));
+ }
+
+ /* Don't save default extension mode ('None') */
+ if (action != GB_SAVING || ext_mode != GDK_EXTENSION_EVENTS_NONE)
+ {
+ for (i = 0; GbExtensionModeChoices[i]; i++)
+ {
+ if (GbExtensionModeValues[i] == ext_mode)
+ gb_widget_output_choice (data, GbExtEvents, i,
+ GbExtensionModeSymbols[i]);
+ }
+ }
+ if (action == GB_SHOWING)
+ {
+ property_set_sensitive (GbEvents, TRUE);
+ property_set_sensitive (GbExtEvents, TRUE);
+ }
+ }
+ else if (action == GB_SHOWING)
+ {
+ gb_widget_output_dialog (data, GbEvents, _("N/A"), NULL);
+ property_set_sensitive (GbEvents, FALSE);
+ gb_widget_output_choice (data, GbExtEvents, 0, GbExtensionModeSymbols[0]);
+ property_set_sensitive (GbExtEvents, FALSE);
+ }
+
+ if (action == GB_SHOWING)
+ {
+#ifdef GLADE_STYLE_SUPPORT
+ gb_widget_show_style (widget);
+#endif
+ show_accelerators (widget, data);
+ show_signals (widget, data);
+
+ glade_atk_get_properties (widget, data);
+ }
+ else
+ {
+#ifdef GLADE_STYLE_SUPPORT
+ save_style (widget, data);
+#endif
+
+ /* These need to be saved in gb_widget_save(), since they must be after
+ all the widget properties. */
+#if 0
+ save_signals (widget, data);
+ save_accelerators (widget, data);
+#endif
+ }
+}
+
+
+/* This is used when saving or displaying properties. */
+static void
+get_lang_specific_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{ guint i;
+
+ GladeWidgetData *wdata = data->widget_data;
+ GbWidgetAction action = data->action;
+
+ /* Note that when saving we only save the property if it is not the
+ default value. Otherwise we get lots of unnecessary XML output. */
+
+ /* C options. */
+ if (action != GB_SAVING || wdata->source_file)
+ gb_widget_output_filename (data, GbCSourceFile, wdata->source_file);
+ if (action != GB_SAVING || wdata->public_field == 0)
+ gb_widget_output_bool (data, GbCPublic, wdata->public_field);
+ if (data->action == GB_SHOWING)
+ {
+ /* We only want the source file set for toplevel widgets. */
+ if (glade_util_is_component (widget))
+ property_set_sensitive (GbCSourceFile, TRUE);
+ else
+ property_set_sensitive (GbCSourceFile, FALSE);
+ }
+
+ /* C++ options. */
+ data->agent = "glademm";
+ if (action != GB_SAVING || wdata->cxx_separate_class == 1)
+ gb_widget_output_bool (data, GbCxxSeparateClass, wdata->cxx_separate_class);
+ if (action == GB_SHOWING)
+ property_set_sensitive (GbCxxSeparateFile, wdata->cxx_separate_class);
+ if (action != GB_SAVING || wdata->cxx_separate_file == 1)
+ gb_widget_output_bool (data, GbCxxSeparateFile, wdata->cxx_separate_file);
+ if (action != GB_SAVING || wdata->cxx_visibility != 0)
+ for (i = 0; GbCxxVisibilityChoices[i]; i++)
+ {
+ if (GbCxxVisibilityValues[i] == wdata->cxx_visibility)
+ gb_widget_output_choice (data, GbCxxVisibility, i,
+ GbCxxVisibilitySymbols[i]);
+ }
+ data->agent = NULL;
+}
+
+
+/* This is used when loading or applying properties. */
+static void
+set_lang_specific_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gchar *filename;
+ gboolean public_field;
+ gboolean cxx_separate_file, cxx_separate_class;
+ gchar *cxx_visibility;
+
+ /* C options. */
+ filename = gb_widget_input_filename (data, GbCSourceFile);
+ if (data->apply)
+ {
+ g_free (wdata->source_file);
+ wdata->source_file = g_strdup (filename);
+ }
+ public_field = gb_widget_input_bool (data, GbCPublic);
+ if (data->apply)
+ wdata->public_field = public_field ? 1 : 0;
+
+ /* C++ options. */
+ data->agent = "glademm";
+ cxx_separate_class = gb_widget_input_bool (data, GbCxxSeparateClass);
+ if (data->apply)
+ {
+ wdata->cxx_separate_class = cxx_separate_class ? 1 : 0;
+ if (!wdata->cxx_separate_class)
+ wdata->cxx_separate_file = 0;
+
+ if (property_get_widget () == widget)
+ {
+ property_set_sensitive (GbCxxSeparateFile, wdata->cxx_separate_class);
+ property_set_auto_apply (FALSE);
+ property_set_bool (GbCxxSeparateFile, FALSE);
+ property_set_auto_apply (TRUE);
+ }
+ }
+
+ cxx_separate_file = gb_widget_input_bool (data, GbCxxSeparateFile);
+ if (data->apply)
+ wdata->cxx_separate_file = cxx_separate_file ? 1 : 0;
+
+ cxx_visibility = gb_widget_input_choice (data, GbCxxVisibility);
+ if (data->apply)
+ {
+ guint i;
+ for (i = 0; GbCxxVisibilityChoices[i]; i++)
+ {
+ if (!strcmp (cxx_visibility, GbCxxVisibilityChoices[i])
+ || !strcmp (cxx_visibility, GbCxxVisibilitySymbols[i]))
+ {
+ wdata->cxx_visibility = GbCxxVisibilityValues[i];
+ break;
+ }
+ }
+ }
+ data->agent = NULL;
+}
+
+
+static void
+get_position_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gboolean wh_applicable = TRUE;
+ gboolean show_wh_buttons = TRUE;
+
+#if 0
+ g_print ("In get_pos: %s WS:%s HS:%s ",
+ gtk_widget_get_name (widget),
+ wdata->flags & GLADE_WIDTH_SET ? "1" : "0",
+ wdata->flags & GLADE_HEIGHT_SET ? "1" : "0");
+#endif
+
+ /* Don't bother if widget's area hasn't been allocated yet, unless it is a
+ window. */
+ /* Note: When using the widget tree to view widget properties the widget's
+ area may not have been allocated but we mustn't just return here. */
+#if 0
+ if (data->action == GB_SHOWING && (wdata->flags & GLADE_SIZE_NOT_ALLOCATED)
+ && !GTK_IS_WINDOW (widget))
+ return;
+#endif
+
+ if (GTK_IS_MENU (widget))
+ {
+ if (data->action == GB_SHOWING)
+ {
+ gb_widget_output_int (data, GbWidth, widget->requisition.width);
+ gb_widget_output_int (data, GbHeight, widget->requisition.height);
+ }
+ wh_applicable = FALSE;
+ }
+ else if (GTK_IS_WINDOW (widget))
+ {
+ /* Toplevel window widgets */
+ if (data->action == GB_SHOWING)
+ {
+ gb_widget_output_int (data, GbWidth, wdata->width);
+ gb_widget_output_int (data, GbHeight, wdata->height);
+ }
+ else
+ {
+ if (wdata->flags & GLADE_WIDTH_SET)
+ gb_widget_output_int (data, GbWidth, wdata->width);
+ if (wdata->flags & GLADE_HEIGHT_SET)
+ gb_widget_output_int (data, GbHeight, wdata->height);
+ }
+ }
+ else if (widget->parent && (GTK_IS_FIXED (widget->parent)
+ || GTK_IS_LAYOUT (widget->parent)))
+ {
+ /* Widgets in fixed or layout containers. Note that for widgets in a
+ layout the allocation is relative to the window origin and changes as
+ the layout is scrolled, so don't output that as the x & y coords. */
+ gb_widget_output_int (data, GbWidth, wdata->width);
+ gb_widget_output_int (data, GbHeight, wdata->height);
+ show_wh_buttons = FALSE;
+ }
+ else
+ {
+ /* Widgets in standard containers */
+ if (data->action == GB_SHOWING)
+ {
+ /* If the width or height has been set explicitly we show the size
+ set, else we show the current requisition. We always remember
+ what we have shown in wdata->width & height so we know if the
+ user changes it. */
+ if (!(wdata->flags & GLADE_WIDTH_SET))
+ wdata->width = widget->requisition.width;
+ gb_widget_output_int (data, GbWidth, wdata->width);
+
+ if (!(wdata->flags & GLADE_HEIGHT_SET))
+ wdata->height = widget->requisition.height;
+ gb_widget_output_int (data, GbHeight, wdata->height);
+
+ }
+ else
+ {
+ /* Only save if user has set it explicitly. */
+ if (wdata->flags & GLADE_WIDTH_SET)
+ gb_widget_output_int (data, GbWidth, wdata->width);
+ if (wdata->flags & GLADE_HEIGHT_SET)
+ gb_widget_output_int (data, GbHeight, wdata->height);
+ }
+ }
+
+ /* Show the buttons for setting the size & positions explicitly, if
+ applicable, and set the values sensitive if they are currently set. */
+ if (data->action == GB_SHOWING)
+ {
+ if (wh_applicable)
+ {
+ gboolean wsensitive = (wdata->flags & GLADE_WIDTH_SET) ? TRUE : FALSE;
+ gboolean hsensitive = (wdata->flags & GLADE_HEIGHT_SET) ? TRUE : FALSE;
+
+ property_set_sensitive_full (GbWidth, TRUE, wsensitive,
+ show_wh_buttons);
+ property_set_sensitive_full (GbHeight, TRUE, hsensitive,
+ show_wh_buttons);
+ }
+ else
+ {
+ property_set_sensitive_full (GbWidth, FALSE, FALSE, FALSE);
+ property_set_sensitive_full (GbHeight, FALSE, FALSE, FALSE);
+ }
+ }
+
+#if 0
+ g_print ("\n");
+#endif
+}
+
+
+static void
+save_accelerators (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GList *item;
+ GladeAccelerator *accel;
+
+ if (data->widget_data == NULL)
+ return;
+
+ item = data->widget_data->accelerators;
+ while (item)
+ {
+ accel = (GladeAccelerator *) item->data;
+
+ save_accelerator (data, accel->modifiers, accel->key, accel->signal);
+
+ item = item->next;
+ }
+}
+
+
+static void
+save_signals (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GList *item;
+ GladeSignal *signal;
+
+ if (data->widget_data == NULL)
+ return;
+
+ item = data->widget_data->signals;
+ while (item)
+ {
+ signal = (GladeSignal *) item->data;
+
+ save_signal (data, signal->name, signal->handler, signal->after,
+ signal->object, signal->last_modification_time);
+
+ item = item->next;
+ }
+}
+
+
+
+/*************************************************************************
+ * Functions for replacing widgets in the user interface
+ *************************************************************************/
+
+/*
+ * Replace a child with a new child. Used to replace placeholders with
+ * a widget when adding widgets, and also to replace widgets with
+ * placeholders when deleting. Returns TRUE on success.
+ * NOTE: gbwidgets do not currently have their own function for this,
+ * but we'll probably add it at some point.
+ */
+gboolean
+gb_widget_replace_child (GtkWidget * widget,
+ GtkWidget * current_child,
+ GtkWidget * new_child)
+{
+ gchar *child_name, *new_child_name;
+
+ /* Copy the child name to the new widget if necessary. */
+ child_name = gb_widget_get_child_name (current_child);
+ new_child_name = gb_widget_get_child_name (new_child);
+
+ /* We never copy these child names to the new child widget.
+ The "vscrollbar" and "hscrollbar" child names come from libglade-convert,
+ but we don't use them and we need to get rid of them. */
+ if (child_name && (!strcmp (child_name, "vscrollbar")
+ || !strcmp (child_name, "hscrollbar")))
+ {
+ child_name = NULL;
+ }
+
+ /* Copy the old child name across. */
+ gb_widget_set_child_name (new_child, child_name);
+
+#ifdef USE_GNOME
+ if (BONOBO_IS_DOCK_ITEM (widget))
+ {
+ gboolean is_floating;
+ gint x, y;
+
+ /* GnomeDockItem widgets which are floating automatically disappear when
+ the child is removed, so we remember the position and try to show it
+ again in the same place after adding the new widget. */
+ is_floating = BONOBO_DOCK_ITEM (widget)->is_floating ? TRUE : FALSE;
+ if (is_floating)
+ bonobo_dock_item_get_floating_position (BONOBO_DOCK_ITEM (widget),
+ &x, &y);
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_widget_hide (new_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+ gtk_widget_show (new_child);
+
+ if (is_floating)
+ bonobo_dock_item_detach (BONOBO_DOCK_ITEM (widget), x, y);
+ }
+ else if (GTK_IS_FRAME (widget))
+#else
+ if (GTK_IS_FRAME (widget))
+#endif
+ {
+ /* If this is the frame's label widget, we replace that. */
+ if (gtk_frame_get_label_widget (GTK_FRAME (widget)) == current_child)
+ {
+ gtk_frame_set_label_widget (GTK_FRAME (widget), new_child);
+ }
+ else
+ {
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+ }
+ }
+ else if (GTK_IS_TOOL_ITEM (widget))
+ {
+ /* For a GtkToolItem, if the current child is a placeholder and the
+ GtkToolItem is not a GbWidget or the new child is a GtkToolItem,
+ we replace the GtkToolItem instead. Otherwise we replace the
+ placeholder as usual. */
+ if (GB_IS_PLACEHOLDER (current_child)
+ && (!GB_IS_GB_WIDGET (widget) || GTK_IS_TOOL_ITEM (new_child)))
+ {
+ return gb_widget_replace_child (widget->parent, widget, new_child);
+ }
+ else
+ {
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+ }
+ }
+ else if (GTK_IS_EXPANDER (widget))
+ {
+ /* If this is the expander's label widget, we replace that. */
+ if (gtk_expander_get_label_widget (GTK_EXPANDER (widget)) == current_child)
+ {
+ gtk_expander_set_label_widget (GTK_EXPANDER (widget), new_child);
+ }
+ else
+ {
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+ }
+ }
+ else if (GTK_IS_BIN (widget))
+ {
+ /* For a bin, we just delete the existing child and add the new one. */
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+ }
+ else if (GTK_IS_BOX (widget))
+ {
+ /* For a box, we find out the position of the current child, delete it,
+ add the new one, and move it into position with reorder_child().
+ If the existing child is a placeholder and the new one is a menubar
+ or toolbar, we set the packing so it doesn't expand, as that is
+ probably what the user wants. */
+ gboolean expand, fill;
+ guint padding;
+ GtkPackType pack_type;
+ gint pos = glade_util_get_box_pos (GTK_BOX (widget), current_child);
+ g_return_val_if_fail (pos != -1, FALSE);
+ gtk_box_query_child_packing (GTK_BOX (widget), current_child,
+ &expand, &fill, &padding, &pack_type);
+
+ /* If we are replacing a placeholder (i.e. we are adding a new widget),
+ we try to set the expand & fill options to reasonable defaults. */
+ if (GB_IS_PLACEHOLDER (current_child))
+ {
+ if (GTK_IS_LABEL (new_child)
+ || GTK_IS_BUTTON (new_child)
+ || GTK_IS_OPTION_MENU (new_child)
+ || GTK_IS_PROGRESS (new_child)
+ || GTK_IS_PROGRESS_BAR (new_child)
+ || GTK_IS_MENU_BAR (new_child)
+ || GTK_IS_TOOLBAR (new_child)
+ || GTK_IS_STATUSBAR (new_child))
+ {
+ expand = FALSE;
+ fill = FALSE;
+ }
+
+ /* In a vbox, entry & combo widgets should not expand/fill either. */
+ if (GTK_IS_VBOX (widget))
+ {
+ if (GTK_IS_ENTRY (new_child)
+ || GTK_IS_COMBO (new_child)
+ || GTK_IS_SPIN_BUTTON (new_child)
+#ifdef USE_GNOME
+ || GNOME_IS_DATE_EDIT (new_child)
+ || GNOME_IS_FILE_ENTRY (new_child)
+ || GNOME_IS_PIXMAP_ENTRY (new_child)
+#endif
+ )
+ {
+ expand = FALSE;
+ fill = FALSE;
+ }
+ }
+ }
+
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+
+ gtk_box_set_child_packing (GTK_BOX (widget), new_child, expand, fill,
+ padding, pack_type);
+ gtk_box_reorder_child (GTK_BOX (widget), new_child, pos);
+
+ }
+ else if (GTK_IS_TOOLBAR (widget))
+ {
+ gint pos;
+
+ pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (current_child));
+ g_return_val_if_fail (pos != -1, FALSE);
+
+ /* FIXME: GTK+/GNOME 2 bug workaround - something keeps a ref to the
+ initial buttons added to a GnomeApp, which causes when they eventually
+ get destroyed later and we try to remove them from the tree. So we
+ remove them from the tree here. */
+ tree_remove_widget (current_child);
+
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+
+ /* If the new child is a GtkToolItem, we can simply add it at the old
+ position. */
+ if (GTK_IS_TOOL_ITEM (new_child))
+ {
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (new_child), pos);
+ }
+ /* If the new child is a placeholder, we need to insert a
+ GtkToolItem above it (but not a GbWidget). */
+ else if (GB_IS_PLACEHOLDER (new_child))
+ {
+ GtkWidget *toolitem = (GtkWidget*) gtk_tool_item_new ();
+ gtk_widget_show (toolitem);
+ gtk_container_add (GTK_CONTAINER (toolitem), new_child);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (toolitem), pos);
+ }
+ /* If the new child is not a GtkToolItem, we need to insert a
+ GtkToolItem above it, but use a GbWidget so its properties can be
+ set as required. */
+ else
+ {
+ GtkWidget *toolitem = gb_widget_new ("GtkToolItem", NULL);
+ gtk_widget_show (toolitem);
+ gtk_container_add (GTK_CONTAINER (toolitem), new_child);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (toolitem), pos);
+ tree_add_widget (toolitem);
+ }
+ }
+ else if (GTK_IS_LIST (widget))
+ {
+ /* For a list, we find out the position of the current child, delete it,
+ and add the new one at the same position. */
+ gint pos = gtk_list_child_position (GTK_LIST (widget), current_child);
+ GList glist =
+ {NULL, NULL, NULL};
+ glist.data = current_child;
+ gtk_list_remove_items (GTK_LIST (widget), &glist);
+ glist.data = new_child;
+ gtk_list_insert_items (GTK_LIST (widget), &glist, pos);
+
+ }
+ else if (GTK_IS_NOTEBOOK (widget))
+ {
+ /* For a notebook, we find out the position of the current child, delete
+ it, and add the new one at the same position. If the current_child is
+ a notebook tab, just replace it. */
+ GtkWidget *page, *tab_label;
+ gint pos;
+
+ pos = find_notebook_page (GTK_NOTEBOOK (widget), current_child,
+ &page, &tab_label);
+ g_return_val_if_fail (pos != -1, FALSE);
+
+ if (page == current_child)
+ {
+ gtk_widget_ref (tab_label);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (widget), pos);
+ gtk_notebook_insert_page (GTK_NOTEBOOK (widget),
+ new_child, tab_label, pos);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), pos);
+ gtk_widget_unref (tab_label);
+ }
+ else
+ {
+ gtk_widget_ref (page);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (widget), pos);
+ gtk_notebook_insert_page (GTK_NOTEBOOK (widget),
+ page, new_child, pos);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), pos);
+ gtk_widget_unref (page);
+ }
+
+ }
+ else if (GTK_IS_PANED (widget))
+ {
+ /* For paned, we find out the position of the current child, delete it,
+ and add the new one at the same position. */
+ gint pos = (GTK_PANED (widget)->child1 == current_child) ? 1 : 2;
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ if (pos == 1)
+ gtk_paned_add1 (GTK_PANED (widget), new_child);
+ else
+ gtk_paned_add2 (GTK_PANED (widget), new_child);
+
+ }
+ else if (GTK_IS_TABLE (widget))
+ {
+ /* For a table, we find out the position & size of the current child,
+ delete it, and add the new one in the same place. */
+ gint left, right, top, bottom;
+ GtkTableChild *tchild;
+ GtkAttachOptions xoptions, yoptions;
+
+ tchild = glade_util_find_table_child (GTK_TABLE (widget), current_child);
+ g_return_val_if_fail (tchild != NULL, FALSE);
+
+ left = tchild->left_attach;
+ right = tchild->right_attach;
+ top = tchild->top_attach;
+ bottom = tchild->bottom_attach;
+
+ xoptions = 0;
+ if (tchild->xexpand)
+ xoptions |= GTK_EXPAND;
+ if (tchild->xshrink)
+ xoptions |= GTK_SHRINK;
+ if (tchild->xfill)
+ xoptions |= GTK_FILL;
+
+ yoptions = 0;
+ if (tchild->yexpand)
+ yoptions |= GTK_EXPAND;
+ if (tchild->yshrink)
+ yoptions |= GTK_SHRINK;
+ if (tchild->yfill)
+ yoptions |= GTK_FILL;
+
+ /* If we are replacing a placeholder (i.e. we are adding a new widget),
+ we try to set the expand & fill options to reasonable defaults. */
+ if (GB_IS_PLACEHOLDER (current_child))
+ {
+ if (GTK_IS_LABEL (new_child)
+ || GTK_IS_BUTTON (new_child)
+ || GTK_IS_OPTION_MENU (new_child)
+ || GTK_IS_PROGRESS (new_child)
+ || GTK_IS_PROGRESS_BAR (new_child)
+ || GTK_IS_MENU_BAR (new_child)
+ || GTK_IS_TOOLBAR (new_child)
+ || GTK_IS_STATUSBAR (new_child))
+ {
+ xoptions = GTK_FILL;
+ yoptions = 0;
+ }
+ else if (GTK_IS_ENTRY (new_child)
+ || GTK_IS_COMBO (new_child)
+ || GTK_IS_SPIN_BUTTON (new_child)
+#ifdef USE_GNOME
+ || GNOME_IS_DATE_EDIT (new_child)
+ || GNOME_IS_FILE_ENTRY (new_child)
+ || GNOME_IS_PIXMAP_ENTRY (new_child)
+#endif
+ )
+ {
+ xoptions = GTK_EXPAND | GTK_FILL;
+ yoptions = 0;
+ }
+ }
+
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_table_attach (GTK_TABLE (widget), new_child,
+ left, right, top, bottom, xoptions, yoptions, 0, 0);
+
+ /* Note that if we have just added a placeholder, but there is already
+ a widget at the same position in the table, the placeholder will be
+ destroyed immediately. Thus don't rely on the new widget still being
+ alive after calling gb_widget_replace_child(). */
+ gb_table_update_placeholders (widget, -1, -1);
+ }
+#if GLADE_SUPPORTS_GTK_TREE
+ else if (GTK_IS_TREE (widget))
+ {
+ /* For a tree, we find out the position of the current child, delete it,
+ and add the new one at the same position. */
+ gint pos = gtk_tree_child_position (GTK_TREE (widget), current_child);
+ GList glist =
+ {NULL, NULL, NULL};
+ glist.data = current_child;
+ gtk_tree_remove_items (GTK_TREE (widget), &glist);
+ gtk_tree_insert (GTK_TREE (widget), new_child, pos);
+
+ }
+#endif
+ else if (GTK_IS_CLIST (widget))
+ {
+ /* For a clist, we check if the widget is a column title and if it is
+ we replace it. */
+ gint pos;
+ GtkCList *clist;
+
+ clist = GTK_CLIST(widget);
+
+ for (pos = 0; pos < clist->columns; pos++)
+ {
+ if (clist->column[pos].button == current_child)
+ {
+ gtk_clist_set_column_widget(clist, pos, new_child);
+ }
+ }
+ }
+ else if (GTK_IS_FIXED (widget) || GTK_IS_LAYOUT (widget))
+ {
+ GladeWidgetData *wdata;
+ gint x, y, w, h;
+
+ /* For a fixed, we find the position and size of the existing child,
+ remove it, and add the new one in the same place. */
+ wdata = gtk_object_get_data (GTK_OBJECT (current_child),
+ GB_WIDGET_DATA_KEY);
+ g_return_val_if_fail (wdata != NULL, FALSE);
+
+ gtk_container_child_get (GTK_CONTAINER (widget), current_child,
+ "x", &x,
+ "y", &y,
+ NULL);
+ w = wdata->width;
+ h = wdata->height;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (new_child), GB_WIDGET_DATA_KEY);
+ g_return_val_if_fail (wdata != NULL, FALSE);
+ wdata->flags |= GLADE_WIDTH_SET | GLADE_HEIGHT_SET;
+ wdata->width = w;
+ wdata->height = h;
+
+ /* Reset the widget's uposition, just in case it gets added to a standard
+ container. I don't think we need this for GTK+ 2. */
+ /*gtk_widget_set_uposition (current_child, -1, -1);*/
+
+ /* FIXME: GTK+ 1.2.3 bug workaround. We need to ref the widget to stop
+ gtk_layout_remove() from issuing a warning. */
+ gtk_widget_ref (current_child);
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_widget_unref (current_child);
+
+ if (GTK_IS_FIXED (widget))
+ {
+ gtk_fixed_put (GTK_FIXED (widget), new_child, x, y);
+ /*gtk_widget_set_uposition (new_child, x, y);*/
+ }
+ else
+ {
+ gtk_layout_put (GTK_LAYOUT (widget), new_child, x, y);
+ }
+ gb_widget_set_usize (new_child, w, h);
+ }
+
+#ifdef USE_GNOME
+ else if (BONOBO_IS_DOCK (widget))
+ {
+ /* For a GnomeDock, we call bonobo_dock_set_client_area (). It removes
+ the existing child automatically. */
+ bonobo_dock_set_client_area (BONOBO_DOCK (widget), new_child);
+ }
+
+#endif
+
+ else if (GTK_IS_CONTAINER (widget))
+ {
+ /* General code for container - has to remove all children and add back
+ NOTE: this may not work for specialised containers.
+ NOTE: need to ref widgets? */
+ g_warning (_("replacing child of container - not implemented yet\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*************************************************************************
+ * Functions for showing/hiding tooltips of the widgets
+ *************************************************************************/
+
+gboolean
+gb_widget_get_show_tooltips ()
+{
+ return GTK_TOOLTIPS (gb_widget_tooltips)->enabled;
+}
+
+
+void
+gb_widget_set_show_tooltips (gboolean show)
+{
+ if (show)
+ gtk_tooltips_enable (gb_widget_tooltips);
+ else
+ gtk_tooltips_disable (gb_widget_tooltips);
+}
+
+
+void
+gb_widget_reset_tooltips ()
+{
+ gtk_object_destroy (GTK_OBJECT (gb_widget_tooltips));
+ gb_widget_tooltips = gtk_tooltips_new ();
+}
+
+
+
+/*************************************************************************
+ * Misc. Functions
+ *************************************************************************/
+
+
+/* This is a GTK bug workaround for combo widgets. They should manage the
+ size of their GtkEntry, but they don't at present, so we have to set its
+ size explicitly (and also in the source code output).
+ I think this has been fixed. It seems to be OK in GTK+ 1.2.3. */
+void
+gb_widget_set_usize (GtkWidget *widget,
+ gint w,
+ gint h)
+{
+#if 0
+ if (GTK_IS_COMBO (widget))
+ gtk_widget_set_usize (GTK_COMBO (widget)->entry,
+ w - 16 < 0 ? -1 : w - 16, h);
+#endif
+ gtk_widget_set_usize (widget, w, h);
+}
+
+
+static gint
+find_notebook_page (GtkNotebook * notebook, GtkWidget * current_child,
+ GtkWidget **page, GtkWidget **tab_label)
+{
+ gint nchildren, i;
+ GtkWidget *tmp_page, *tmp_tab_label;
+
+ nchildren = g_list_length (notebook->children);
+ for (i = 0; i < nchildren; i++)
+ {
+ tmp_page = gtk_notebook_get_nth_page (notebook, i);
+ tmp_tab_label = gtk_notebook_get_tab_label (notebook, tmp_page);
+
+ if (tmp_page == current_child || tmp_tab_label == current_child)
+ {
+ *page = tmp_page;
+ *tab_label = tmp_tab_label;
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static void
+dummy_detach (GtkWidget *attach_widget,
+ GtkMenu *menu)
+{
+ ;
+}
+
+/*
+ * FIXME: MAJOR HACK.
+ *
+ * GtkOptionMenu places the currently selected item inside its button, and
+ * removes it from the menu. So we have to hack around that here so that the
+ * menu items are all output correctly, in the XML and the source code.
+ *
+ * We remove the menu from the original option menu and add it to a temporary
+ * one with the same name.
+ */
+static void
+option_menu_foreach (GtkOptionMenu *option,
+ GtkCallback callback,
+ gpointer data)
+{
+ GtkWidget *menu = option->menu;
+ GtkWidget *temp;
+ int history;
+
+ if (!menu)
+ return;
+
+ temp = gtk_option_menu_new ();
+ gtk_widget_set_name (temp, gtk_widget_get_name (GTK_WIDGET (option)));
+ gtk_object_ref (GTK_OBJECT (temp));
+ gtk_object_sink (GTK_OBJECT (temp));
+
+ history = gtk_option_menu_get_history (option);
+
+ gtk_object_ref (GTK_OBJECT (menu));
+
+ gtk_option_menu_set_menu (option, gtk_menu_new ());
+ gtk_menu_attach_to_widget (GTK_MENU (menu), temp, dummy_detach);
+ (*callback) (menu, data);
+ gtk_menu_detach (GTK_MENU (menu));
+ gtk_option_menu_set_menu (option, menu);
+
+ gtk_object_unref (GTK_OBJECT (menu));
+
+ gtk_option_menu_set_history (option, history);
+
+ gtk_object_unref (GTK_OBJECT (temp));
+}
+
+static void
+combo_foreach (GtkCombo *combo,
+ GtkCallback callback,
+ gpointer data)
+{
+ (*callback) (combo->entry, data);
+ (*callback) (combo->list, data);
+ (*callback) (combo->button, data);
+}
+
+
+/* This calls the given callback for each child of a widget. It gets round
+ some of the quirks of the different versions of GTK, and descends menus
+ as well. */
+void
+gb_widget_children_foreach (GtkWidget *widget,
+ GtkCallback callback,
+ gpointer data)
+{
+ /* SPECIAL CODE: for table, so we output in the reverse order. */
+ if (GTK_IS_TABLE (widget))
+ table_foreach (GTK_TABLE (widget), callback, data);
+ else if (GTK_IS_COMBO (widget))
+ combo_foreach (GTK_COMBO (widget), callback, data);
+ else if (GTK_IS_BOX (widget))
+ box_foreach (GTK_BOX (widget), callback, data);
+ else if (GTK_IS_OPTION_MENU (widget))
+ option_menu_foreach (GTK_OPTION_MENU (widget), callback, data);
+ else if (GTK_IS_CONTAINER (widget))
+ gtk_container_forall (GTK_CONTAINER (widget), callback, data);
+
+ /* SPECIAL CODE: for menu items, descend to child menus. */
+ if (GTK_IS_MENU_ITEM (widget) && GTK_MENU_ITEM (widget)->submenu)
+ (*callback) (GTK_MENU_ITEM (widget)->submenu, data);
+}
+
+
+/* This function is used to iterate through the table children in reverse.
+ It is needed so we output the XML file in the same order each time. */
+static void
+table_foreach (GtkTable * table,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GList *children;
+ GtkTableChild *child;
+
+ children = g_list_last (table->children);
+ while (children)
+ {
+ child = children->data;
+ children = children->prev;
+
+ (*callback) (child->widget, callback_data);
+ }
+}
+
+
+static void
+box_foreach (GtkBox *box,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GList *children;
+ GtkBoxChild *child;
+
+ children = box->children;
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ (* callback) (child->widget, callback_data);
+ }
+}
+
+/*************************************************************************
+ * Common popup menu callbacks
+ *************************************************************************/
+
+static void
+gb_widget_add_alignment (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *alignment, *parent;
+
+ parent = widget->parent;
+ alignment = gb_widget_new ("GtkAlignment", parent);
+
+ gtk_widget_ref (widget);
+ if (!gb_widget_replace_child (parent, widget, alignment))
+ {
+ glade_util_show_message_box (_("Couldn't insert GtkAlignment widget."),
+ parent);
+ gtk_widget_destroy (alignment);
+ gtk_widget_unref (widget);
+ return;
+ }
+ if (GTK_BIN (alignment)->child)
+ gtk_container_remove (GTK_CONTAINER (alignment),
+ GTK_BIN (alignment)->child);
+ gtk_container_add (GTK_CONTAINER (alignment), widget);
+ gtk_widget_unref (widget);
+ tree_insert_widget_parent (alignment, widget);
+}
+
+
+static void
+gb_widget_remove_alignment (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *alignment, *parent;
+
+ alignment = widget->parent;
+ g_return_if_fail (GTK_IS_ALIGNMENT (alignment));
+ parent = alignment->parent;
+
+ gtk_widget_ref (widget);
+ gtk_widget_ref (alignment);
+
+ /* Remove the alignment and all children from the tree. */
+ tree_remove_widget (alignment);
+
+ gtk_container_remove (GTK_CONTAINER (alignment), widget);
+
+ if (gb_widget_replace_child (parent, alignment, widget))
+ {
+ /* Now add the widget and its children back to the tree. */
+ tree_add_widget (widget);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't remove GtkAlignment widget."),
+ parent);
+ /* Try to put it back as it was. */
+ gtk_container_add (GTK_CONTAINER (alignment), widget);
+ tree_add_widget (alignment);
+ }
+
+ gtk_widget_unref (alignment);
+ gtk_widget_unref (widget);
+}
+
+
+static void
+gb_widget_add_event_box (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *event_box, *parent;
+
+ parent = widget->parent;
+ event_box = gb_widget_new ("GtkEventBox", parent);
+
+ gtk_widget_ref (widget);
+ if (!gb_widget_replace_child (parent, widget, event_box))
+ {
+ glade_util_show_message_box (_("Couldn't insert GtkEventBox widget."),
+ parent);
+ gtk_widget_destroy (event_box);
+ gtk_widget_unref (widget);
+ return;
+ }
+ if (GTK_BIN (event_box)->child)
+ gtk_container_remove (GTK_CONTAINER (event_box),
+ GTK_BIN (event_box)->child);
+ gtk_container_add (GTK_CONTAINER (event_box), widget);
+ gtk_widget_unref (widget);
+ tree_insert_widget_parent (event_box, widget);
+}
+
+static void
+gb_widget_remove_event_box (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *event_box, *parent;
+
+ event_box = widget->parent;
+ g_return_if_fail (GTK_IS_EVENT_BOX (event_box));
+ parent = event_box->parent;
+
+ gtk_widget_ref (widget);
+ gtk_widget_ref (event_box);
+
+ /* Remove the event box and all children from the tree. */
+ tree_remove_widget (event_box);
+
+ gtk_container_remove (GTK_CONTAINER (event_box), widget);
+
+ if (gb_widget_replace_child (parent, event_box, widget))
+ {
+ /* Now add the widget and its children back to the tree. */
+ tree_add_widget (widget);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't remove GtkEventBox widget."),
+ parent);
+ /* Try to put it back as it was. */
+ gtk_container_add (GTK_CONTAINER (event_box), widget);
+ tree_add_widget (event_box);
+ }
+ gtk_widget_unref (event_box);
+ gtk_widget_unref (widget);
+}
+
+
+static void
+gb_widget_redisplay_window (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ g_return_if_fail (GTK_IS_WINDOW (widget));
+
+ /* See also editor_on_key_press_event() in editor.c. */
+ glade_util_close_window (widget);
+ gtk_window_reshow_with_initial_size (GTK_WINDOW (widget));
+}
+
+
+static void
+gb_widget_add_scrolled_window (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *scrolledwin, *parent;
+
+ parent = widget->parent;
+ scrolledwin = gb_widget_new ("GtkScrolledWindow", parent);
+
+ gtk_widget_ref (widget);
+ if (!gb_widget_replace_child (parent, widget, scrolledwin))
+ {
+ glade_util_show_message_box (_("Couldn't insert GtkScrolledWindow widget."), parent);
+ gtk_widget_destroy (scrolledwin);
+ gtk_widget_unref (widget);
+ return;
+ }
+ if (GTK_BIN (scrolledwin)->child)
+ gtk_container_remove (GTK_CONTAINER (scrolledwin),
+ GTK_BIN (scrolledwin)->child);
+ gtk_container_add (GTK_CONTAINER (scrolledwin), widget);
+ gtk_widget_unref (widget);
+ tree_insert_widget_parent (scrolledwin, widget);
+}
+
+
+static void
+gb_widget_remove_scrolled_window (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *scrolledwin, *parent;
+
+ scrolledwin = widget->parent;
+ g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolledwin));
+ parent = scrolledwin->parent;
+
+ gtk_widget_ref (widget);
+ gtk_widget_ref (scrolledwin);
+
+ /* Remove the alignment and all children from the tree. */
+ tree_remove_widget (scrolledwin);
+
+ gtk_container_remove (GTK_CONTAINER (scrolledwin), widget);
+
+ if (gb_widget_replace_child (parent, scrolledwin, widget))
+ {
+ /* Now add the widget and its children back to the tree. */
+ tree_add_widget (widget);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't remove GtkScrolledWindow widget."), parent);
+ /* Try to put it back as it was. */
+ gtk_container_add (GTK_CONTAINER (scrolledwin), widget);
+ tree_add_widget (scrolledwin);
+ }
+
+ gtk_widget_unref (scrolledwin);
+ gtk_widget_unref (widget);
+}
+
+
+/*************************************************************************
+ * Common functions used by gbwidgets.
+ *************************************************************************/
+
+/* This gets the child label for buttons or menuitems or subclasses.
+ This is for showing or saving. */
+void
+gb_widget_output_child_label (GtkWidget * widget, GbWidgetGetArgData * data,
+ const gchar * Label)
+{
+ GtkWidget *child;
+ gchar *label_text;
+
+ child = GTK_BIN (widget)->child;
+
+ /* Note that we don't want to save the child label if it is a GbWidget,
+ since it will be saved as a separate widget. */
+ if (child && GTK_IS_LABEL (child) && !GB_IS_GB_WIDGET (child))
+ {
+ label_text = glade_util_get_label_text (child);
+ gb_widget_output_translatable_text (data, Label, label_text);
+ g_free (label_text);
+
+ if (data->action == GB_SHOWING)
+ property_set_sensitive (Label, TRUE);
+
+ /* All our menuitems use underlined accelerators. */
+ if (data->action == GB_SAVING && GTK_IS_MENU_ITEM (widget))
+ gb_widget_output_bool (data, "use_underline", TRUE);
+ }
+ else
+ {
+ if (data->action == GB_SHOWING)
+ {
+ gb_widget_output_translatable_text (data, Label, "");
+ property_set_sensitive (Label, FALSE);
+ }
+ }
+}
+
+
+/* This sets the child label for buttons/items/menuitems or subclasses.
+ This is for applying or loading. */
+void
+gb_widget_input_child_label (GtkWidget * widget, GbWidgetSetArgData * data,
+ const gchar * Label)
+{
+ GtkWidget *child, *label;
+ gchar *label_text;
+
+ child = GTK_BIN (widget)->child;
+
+ label_text = gb_widget_input_text (data, Label);
+ if (data->apply)
+ {
+ if (child && GTK_IS_LABEL (child))
+ {
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (child), label_text);
+ }
+ else
+ {
+ if (child != NULL)
+ gtk_container_remove (GTK_CONTAINER (widget), child);
+ if (GTK_IS_MENU_ITEM (widget))
+ {
+ label = gtk_accel_label_new ("");
+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label),
+ widget);
+ }
+ else
+ {
+ label = gtk_label_new ("");
+ }
+ gtk_container_add (GTK_CONTAINER (widget), label);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label), label_text);
+ gtk_widget_show (label);
+
+ /* Simple child labels are given different alignments according to
+ the parent. GtkButton and GtkToggleButton are centred. All the
+ others are aligned left. See the GTK _new_with_label() fns. */
+ if (data->action == GB_LOADING)
+ {
+ if (GTK_IS_CHECK_BUTTON (widget)
+ || GTK_IS_ITEM (widget))
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ }
+ }
+ }
+ /* This isn't very nice. When a text property is got from the property
+ editor (i.e. when action is GB_APPLYING) it needs to be freed after. */
+ if (data->action == GB_APPLYING)
+ g_free (label_text);
+}
+
+
+void
+gb_widget_create_child_label_popup_menu (GtkWidget *widget,
+ GbWidgetCreateMenuData *data)
+{
+ GtkWidget *menuitem;
+
+ if (GTK_IS_LABEL (GTK_BIN (widget)->child))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Remove Label"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_widget_remove_label), widget);
+ }
+}
+
+
+void
+gb_widget_remove_label (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *child;
+
+ g_return_if_fail (GTK_IS_BIN (widget));
+
+ child = GTK_BIN (widget)->child;
+ if (child && GTK_IS_LABEL (child))
+ editor_delete_widget (child);
+}
+
+
+/*************************************************************************
+ * Adjustment convenience functions - handles all 6 values.
+ *************************************************************************/
+void
+gb_widget_output_adjustment (GbWidgetGetArgData * data,
+ const gchar * Values[],
+ GtkAdjustment * adjustment,
+ gchar *saved_property_name)
+{
+ /* Adjustments are now saved as a single property with all 6 values in a
+ string, e.g. '0 0 100 1 10 10'. */
+ if (data->action == GB_SAVING)
+ {
+ gchar buffer[256];
+
+ sprintf (buffer, "%.12g %.12g %.12g %.12g %.12g %.12g",
+ adjustment->value,
+ adjustment->lower,
+ adjustment->upper,
+ adjustment->step_increment,
+ adjustment->page_increment,
+ adjustment->page_size);
+ save_string (data, saved_property_name, buffer);
+ }
+ else
+ {
+ if (Values[0])
+ gb_widget_output_float (data, Values[0], adjustment->value);
+ if (Values[1])
+ gb_widget_output_float (data, Values[1], adjustment->lower);
+ if (Values[2])
+ gb_widget_output_float (data, Values[2], adjustment->upper);
+ if (Values[3])
+ gb_widget_output_float (data, Values[3], adjustment->step_increment);
+ if (Values[4])
+ gb_widget_output_float (data, Values[4], adjustment->page_increment);
+ if (Values[5])
+ gb_widget_output_float (data, Values[5], adjustment->page_size);
+ }
+}
+
+
+gboolean
+gb_widget_input_adjustment (GbWidgetSetArgData * data,
+ const gchar * Values[],
+ GtkAdjustment * adjustment,
+ gchar *saved_property_name)
+{
+ gfloat value, lower, upper, step_inc, page_inc, page_size, tmp;
+
+ /* Adjustments are now saved as a single property with all 6 values in a
+ string, e.g. '0 0 100 1 10 10'. */
+ if (data->action == GB_LOADING)
+ {
+ gchar *value = gb_widget_input_string (data, saved_property_name);
+ if (data->apply)
+ {
+ gchar *ptr = value;
+
+ adjustment->value = g_strtod (ptr, &ptr);
+ adjustment->lower = g_strtod (ptr, &ptr);
+ adjustment->upper = g_strtod (ptr, &ptr);
+ adjustment->step_increment = g_strtod (ptr, &ptr);
+ adjustment->page_increment = g_strtod (ptr, &ptr);
+ adjustment->page_size = g_strtod (ptr, &ptr);
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ value = adjustment->value;
+ lower = adjustment->lower;
+ upper = adjustment->upper;
+ step_inc = adjustment->step_increment;
+ page_inc = adjustment->page_increment;
+ page_size = adjustment->page_size;
+
+ if (Values[0])
+ {
+ tmp = gb_widget_input_float (data, Values[0]);
+ if (data->apply)
+ value = tmp;
+ }
+
+ if (Values[1])
+ {
+ tmp = gb_widget_input_float (data, Values[1]);
+ if (data->apply)
+ lower = tmp;
+ }
+
+ if (Values[2])
+ {
+ tmp = gb_widget_input_float (data, Values[2]);
+ if (data->apply)
+ upper = tmp;
+ }
+
+ if (Values[3])
+ {
+ tmp = gb_widget_input_float (data, Values[3]);
+ if (data->apply)
+ step_inc = tmp;
+ }
+
+ if (Values[4])
+ {
+ tmp = gb_widget_input_float (data, Values[4]);
+ if (data->apply)
+ page_inc = tmp;
+ }
+
+ if (Values[5])
+ {
+ tmp = gb_widget_input_float (data, Values[5]);
+ if (data->apply)
+ page_size = tmp;
+ }
+
+ /* Only return TRUE if one or more of the properties have changed. */
+ if (adjustment->value != value
+ || adjustment->lower != lower
+ || adjustment->upper != upper
+ || adjustment->step_increment != step_inc
+ || adjustment->page_increment != page_inc
+ || adjustment->page_size != page_size)
+ {
+ adjustment->value = value;
+ adjustment->lower = lower;
+ adjustment->upper = upper;
+ adjustment->step_increment = step_inc;
+ adjustment->page_increment = page_inc;
+ adjustment->page_size = page_size;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*************************************************************************
+ * Functions to input/output properties.
+ *************************************************************************/
+
+/* Inputting Properties - Loading or Applying. */
+
+gchar*
+gb_widget_input_string (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_string (data, property);
+ else
+ return property_get_string (property, data->widget,
+ data->property_to_apply, &data->apply);
+}
+
+
+/* NOTE: You must free the returned string if data->action == GB_APPLYING */
+gchar*
+gb_widget_input_text (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_text (data, property);
+ else
+ return property_get_text (property, data->widget,
+ data->property_to_apply, &data->apply);
+}
+
+
+gint
+gb_widget_input_int (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_int (data, property);
+ else
+ return property_get_int (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gint
+gb_widget_input_optional_int (GbWidgetSetArgData *data,
+ const gchar *property,
+ gboolean *is_set)
+{
+ gint value;
+
+ if (data->action == GB_LOADING)
+ {
+ value = load_int (data, property);
+ if (is_set)
+ *is_set = data->apply;
+ return value;
+ }
+ else
+ return property_get_optional_int (property, data->property_to_apply,
+ &data->apply, is_set);
+}
+
+
+gfloat
+gb_widget_input_float (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_float (data, property);
+ else
+ return property_get_float (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gboolean
+gb_widget_input_bool (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_bool (data, property);
+ else
+ return property_get_bool (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gchar*
+gb_widget_input_choice (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_choice (data, property);
+ else
+ return property_get_choice (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gchar*
+gb_widget_input_combo (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_combo (data, property);
+ else
+ return property_get_combo (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+GdkColor*
+gb_widget_input_color (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_color (data, property);
+ else
+ return property_get_color (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+GdkPixmap*
+gb_widget_input_bgpixmap (GbWidgetSetArgData *data,
+ const gchar *property,
+ gchar **filename)
+{
+ if (data->action == GB_LOADING)
+ return load_bgpixmap (data, property, filename);
+ else
+ return property_get_bgpixmap (property, data->property_to_apply,
+ &data->apply, filename);
+}
+
+
+gpointer
+gb_widget_input_dialog (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_dialog (data, property);
+ else
+ return property_get_dialog (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gchar*
+gb_widget_input_filename (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_filename (data, property);
+ else
+ return property_get_filename (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gchar*
+gb_widget_input_pixmap_filename (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_pixmap_filename (data, property);
+ else
+ return property_get_filename (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+GdkFont*
+gb_widget_input_font (GbWidgetSetArgData *data,
+ const gchar *property,
+ gchar **xlfd_fontname)
+{
+ if (data->action == GB_LOADING)
+ return load_font (data, property, xlfd_fontname);
+ else
+ return property_get_font (property, data->property_to_apply,
+ &data->apply, xlfd_fontname);
+}
+
+
+gchar*
+gb_widget_input_stock_item (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_string (data, property);
+ else
+ return property_get_stock_item (property, data->property_to_apply,
+ &data->apply);
+}
+
+
+gchar*
+gb_widget_input_icon (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_icon (data, property);
+ else
+ return property_get_icon (property, data->property_to_apply,
+ &data->apply);
+}
+
+gchar*
+gb_widget_input_named_icon (GbWidgetSetArgData *data,
+ const gchar *property)
+{
+ if (data->action == GB_LOADING)
+ return load_string (data, property);
+ else
+ return property_get_named_icon (property, data->property_to_apply,
+ &data->apply);
+}
+
+gint
+gb_widget_input_enum (GbWidgetSetArgData *data,
+ GType enum_type,
+ const char **labels,
+ int *values,
+ const gchar *property)
+{
+ gint retval = 0;
+ int i;
+ char *s;
+
+ if (data->action == GB_LOADING)
+ {
+ s = load_string (data, property);
+ if (data->apply && s)
+ retval = glade_enum_from_string (enum_type, s);
+ }
+ else
+ {
+ s = property_get_choice (property, data->property_to_apply,
+ &data->apply);
+ if (data->apply && s)
+ {
+ for (i = 0; labels[i]; i++)
+ {
+ if (!strcmp (labels[i], s))
+ {
+ retval = values[i];
+ break;
+ }
+ }
+ }
+ }
+ return retval;
+}
+
+/* Outputting Properties - Saving or Showing. */
+void
+gb_widget_output_string (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_string (data, property, value);
+ else
+ property_set_string (property, value);
+}
+
+
+void
+gb_widget_output_translatable_string (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_translatable_string (data, property, value);
+ else
+ property_set_translatable_string (property, value, data->widget);
+}
+
+
+void
+gb_widget_output_text (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_text (data, property, value);
+ else
+ property_set_text (property, value);
+}
+
+
+void
+gb_widget_output_translatable_text (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_translatable_text (data, property, value);
+ else
+ property_set_translatable_text (property, value, data->widget);
+}
+
+
+void
+gb_widget_output_translatable_text_in_lines (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_translatable_text_in_lines (data, property, value);
+ else
+ property_set_translatable_text (property, value, data->widget);
+}
+
+
+void
+gb_widget_output_int (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value)
+{
+#if 0
+ if (property == GbX)
+ g_print ("X: %i ", value);
+ else if (property == GbY)
+ g_print ("Y: %i ", value);
+ else if (property == GbWidth)
+ g_print ("W: %i ", value);
+ else if (property == GbHeight)
+ g_print ("H: %i ", value);
+#endif
+
+ if (data->action == GB_SAVING)
+ save_int (data, property, value);
+ else
+ property_set_int (property, value);
+}
+
+
+void
+gb_widget_output_optional_int (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value,
+ gboolean is_set)
+{
+ if (data->action == GB_SAVING)
+ {
+ if (is_set)
+ save_int (data, property, value);
+ }
+ else
+ property_set_optional_int (property, value, is_set);
+}
+
+
+void
+gb_widget_output_float (GbWidgetGetArgData *data,
+ const gchar *property,
+ gfloat value)
+{
+ if (data->action == GB_SAVING)
+ save_float (data, property, value);
+ else
+ property_set_float (property, value);
+}
+
+
+void
+gb_widget_output_bool (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value)
+{
+ if (data->action == GB_SAVING)
+ save_bool (data, property, value);
+ else
+ property_set_bool (property, value);
+}
+
+
+void
+gb_widget_output_choice (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value,
+ const gchar *symbol)
+{
+ if (data->action == GB_SAVING)
+ save_choice (data, property, symbol);
+ else
+ property_set_choice (property, value);
+}
+
+
+void
+gb_widget_output_combo (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_combo (data, property, value);
+ else
+ property_set_combo (property, value);
+}
+
+
+void
+gb_widget_output_color (GbWidgetGetArgData *data,
+ const gchar *property,
+ GdkColor *value)
+{
+ if (data->action == GB_SAVING)
+ save_color (data, property, value);
+ else
+ property_set_color (property, value);
+}
+
+
+void
+gb_widget_output_bgpixmap (GbWidgetGetArgData *data,
+ const gchar *property,
+ GdkPixmap *value,
+ const gchar *filename)
+{
+ if (data->action == GB_SAVING)
+ save_bgpixmap (data, property, filename);
+ else
+ property_set_bgpixmap (property, value, filename);
+}
+
+
+void
+gb_widget_output_dialog (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *string,
+ gconstpointer value)
+{
+ if (data->action == GB_SAVING)
+ save_dialog (data, property, value);
+ else
+ property_set_dialog (property, string, value);
+}
+
+
+/* FIXME: I think this is broken. It should save it relative to the XML file.*/
+void
+gb_widget_output_filename (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_filename (data, property, value);
+ else
+ property_set_filename (property, value);
+}
+
+
+void
+gb_widget_output_pixmap_filename (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_pixmap_filename (data, property, value);
+ else
+ property_set_filename (property, value);
+}
+
+
+void
+gb_widget_output_font (GbWidgetGetArgData *data,
+ const gchar *property,
+ GdkFont *value,
+ const gchar *xlfd_fontname)
+{
+ if (data->action == GB_SAVING)
+ save_font (data, property, xlfd_fontname);
+ else
+ property_set_font (property, value, xlfd_fontname);
+}
+
+
+void
+gb_widget_output_stock_item (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_string (data, property, value);
+ else
+ property_set_stock_item (property, value);
+}
+
+
+void
+gb_widget_output_icon (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_icon (data, property, value);
+ else
+ property_set_icon (property, value);
+}
+
+void
+gb_widget_output_named_icon (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value)
+{
+ if (data->action == GB_SAVING)
+ save_string (data, property, value);
+ else
+ property_set_named_icon (property, value);
+}
+
+void
+gb_widget_output_enum (GbWidgetGetArgData *data,
+ GType enum_type,
+ int *values,
+ int n_values,
+ const gchar *property,
+ gint value)
+{
+ const char *s;
+ int i;
+
+ if (data->action == GB_SAVING)
+ {
+ s = glade_string_from_enum (enum_type, value);
+ save_string (data, property, s);
+ }
+ else
+ {
+ for (i = 0; i < n_values; i++)
+ if (values[i] == value)
+ break;
+
+ property_set_choice (property, i < n_values ? values[i] : 0);
+ }
+}
diff --git a/tools/glade/glade/gbwidget.h b/tools/glade/glade/gbwidget.h
new file mode 100644
index 00000000..6ded9bcb
--- /dev/null
+++ b/tools/glade/glade/gbwidget.h
@@ -0,0 +1,626 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_GBWIDGET_H
+#define GLADE_GBWIDGET_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <gtk/gtktoolbar.h>
+
+#include "glade.h"
+#include "styles.h"
+#include "glade_widget_data.h"
+#include "glade-parser.h"
+#include "gbsource.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GB_WIDGET_DATA_KEY "GB_WIDGET_DATA"
+#define GB_IS_GB_WIDGET(w) \
+ (gtk_object_get_data(GTK_OBJECT(w), GB_WIDGET_DATA_KEY) != NULL)
+
+/* This key has a non-null value if a widget is a placeholder. */
+#define GB_PLACEHOLDER_KEY "GB_PLACEHOLDER"
+/* Macro to see if a widget is a placeholder. */
+#define GB_IS_PLACEHOLDER(w) \
+ (gtk_object_get_data(GTK_OBJECT(w), GB_PLACEHOLDER_KEY) != NULL)
+
+/* This key has a non-null value if a widget is a custom widget. */
+#define GLADE_CUSTOM_KEY "GLADE_CUSTOM"
+/* Macro to see if a widget is a custom widget. */
+#define GLADE_IS_CUSTOM_WIDGET(w) \
+ (gtk_object_get_data(GTK_OBJECT(w), GLADE_CUSTOM_KEY) != NULL)
+
+/* This is used to save a pointer to the GladeWidgetInfo inside a widget while
+ loading, so we can resolve ATK relations afterwards. */
+extern const gchar *GladeWidgetInfoKey;
+
+extern const gchar *GladeMenuItemStockIDKey;
+extern const gchar *GladeMenuItemIconKey;
+extern const gchar *GladeMenuItemStockIndexKey;
+
+/* This is the key we use to store the stock icon name or full pathname.
+ It is used for GtkImage (hence in the menu editor), and also for the
+ icons in buttons. */
+extern const gchar *GladeIconKey;
+
+
+/*************************************************************************
+ * Data structures passed to the GbWidget functions
+ *************************************************************************/
+
+typedef struct _GbWidgetNewData GbWidgetNewData;
+typedef struct _GbWidgetCreateFromData GbWidgetCreateFromData;
+typedef struct _GbWidgetCreateArgData GbWidgetCreateArgData;
+typedef struct _GbWidgetCreateChildArgData GbWidgetCreateChildArgData;
+typedef struct _GbWidgetGetArgData GbWidgetGetArgData;
+typedef struct _GbWidgetSetArgData GbWidgetSetArgData;
+typedef struct _GbWidgetCreateMenuData GbWidgetCreateMenuData;
+typedef struct _GbWidgetDestroyData GbWidgetDestroyData;
+
+typedef void (*GbWidgetNewCallback) (GtkWidget *widget,
+ GbWidgetNewData *data);
+
+/* The gb_widget_set_properties() function is used both when loading in
+ properties from an XML file and when applying properties within Glade.
+ Similarly, gb_widget_get_properties() is used when showing properties and
+ when saving, and gb_widget_new() is used when loading and when creating
+ a new widget within Glade. The GbWidgetAction field can be used by the
+ function to determine which of the actions is actually happening, so
+ special-case code can be used if appropriate. For example, when saving
+ we don't want to save properties if they are the default value. */
+typedef enum
+{
+ GB_CREATING,
+ GB_LOADING,
+ GB_APPLYING,
+ GB_SHOWING,
+ GB_SAVING
+} GbWidgetAction;
+
+
+/* GbWidgetNewData - used when new widgets are created.
+ name is the name of the new widget.
+ callback is the function to be called when the widget has been created.
+ It is used after a dialog has been shown to let the user configure a
+ widget (e.g. setting the number of rows in a new vbox).
+ parent is the parent widget that the new widget will be added to.
+ current_child is the widget which will be replaced by the new one or NULL.
+ x, y, width & height specify the position and size of the new widget,
+ when adding to a fixed container.
+ */
+struct _GbWidgetNewData
+{
+ GladeProject *project;
+ GbWidgetAction action; /* GB_CREATING or GB_LOADING. */
+ gchar *name;
+ GbWidgetNewCallback callback;
+ GtkWidget *parent;
+ GtkWidget *current_child;
+ gint x, y;
+ GladeWidgetData *widget_data;
+
+ /* This is only used when loading. */
+ GbWidgetSetArgData *loading_data;
+};
+
+struct _GbWidgetCreateFromData
+{
+ GladeProject *project;
+
+};
+
+struct _GbWidgetCreateArgData
+{
+ GladeProject *project;
+
+};
+
+struct _GbWidgetCreateChildArgData
+{
+ GladeProject *project;
+
+};
+
+struct _GbWidgetGetArgData
+{
+ GladeProject *project;
+ GbWidgetAction action; /* GB_SHOWING or GB_SAVING. */
+
+ GtkWidget *widget; /* The widget being processed. Note
+ that this is also passed in as an
+ argument, but having it in the
+ struct as well helps with
+ translatable properties. */
+ GladeWidgetData *widget_data; /* The GladeWidgetData of the widget
+ currently being processed. */
+ gchar *agent; /* This is set to the agent parameter
+ when outputting properties for C++
+ etc., e.g. "glademm". */
+
+ /* These are only used when saving (to a file or the clipboard). */
+ gboolean copying_to_clipboard; /* TRUE if we are copying the widgets
+ to the clipboard. */
+ GString *buffer; /* A buffer in which the XML is
+ initially saved, before outputting
+ to the file (or copying to the
+ clipboard). */
+ gboolean save_translatable_strings; /* TRUE if we are saving a file of
+ translatable strings. */
+ GString *translatable_strings; /* A buffer in which declarations of
+ translatable strings are saved, to
+ be output in a file which is added
+ to an application's POTFILES.in
+ if it is using libglade. */
+ gint indent; /* The current indentation level, only
+ used to make the XML look nicer. */
+ GladeError *error; /* If an error occurs when saving the
+ XML this will be non-NULL. */
+};
+
+
+/* Each widget has two types of properties, standard properties which are all
+ the properties shown on the 'Widget' and 'Basic' pages in the property
+ editor, and child properties, shown on the 'Place' page, which relate to
+ how the widget is placed within its parent. In the code to load the widgets,
+ i.e. all the calls to gb_widget_input_bool() etc., the standard properties
+ are used by default. If you need to get at the child properties, set the
+ loading_type field of GbWidgetSetArgData to GB_CHILD_PROPERTIES, get the
+ properties you need, then reset it to GB_STANDARD_PROPERTIES. */
+typedef enum
+{
+ GB_STANDARD_PROPERTIES,
+ GB_CHILD_PROPERTIES
+} GbPropertyType;
+
+
+struct _GbWidgetSetArgData {
+ GladeProject *project;
+ GbWidgetAction action; /* GB_APPLYING or GB_LOADING. */
+ GtkWidget *widget; /* The widget being processed. Note
+ that this is also passed in as an
+ argument, but having it in the
+ struct as well helps with
+ translatable properties. */
+ GladeWidgetData *widget_data;
+ GtkWidget *property_to_apply;
+ gboolean apply;
+
+ /* These are only used when loading. If we are loading from a file, filename
+ is used. If we are pasting from the clipboard, xml_buffer,
+ replacing_widget and discard_names are used. */
+ gchar *filename;
+
+ gchar *xml_buffer;
+ GtkWidget *replacing_widget;
+ gboolean discard_names;
+
+ GladeStatusCode status;
+
+ GladeInterface *interface;
+
+ /* This is the GladeChildInfo & GladeWidgetInfo of the widget currently
+ being created. */
+ GladeChildInfo *child_info;
+ GladeWidgetInfo *widget_info;
+
+ /* As we load widgets, we add them all to this hash, so that the ATK code
+ can find the targets of relations in a second pass. The key is the
+ widget name, and the value is the widget. */
+ GHashTable *all_widgets;
+
+ /* This tells the load_XXX() functions to use the normal or packing
+ properties. */
+ GbPropertyType loading_type;
+
+ /* This is set to the agent we want to match when loading properties,
+ e.g. "glademm" for the C++ properties. */
+ gchar *agent;
+};
+
+
+struct _GbWidgetCreateMenuData
+{
+ GladeProject *project;
+ GtkWidget *menu;
+ GtkWidget *child;
+};
+
+
+struct _GbWidgetDestroyData
+{
+ GladeProject *project;
+
+};
+
+
+/*************************************************************************
+ * The GbWidget struct which contains info on each widget class.
+ *************************************************************************/
+
+/* These are used in the properties_page_number of the GbWidget struct to
+ specify whether the GbWidget's properties page has been created or if it
+ doesn't need one (i.e. it has no properties of its own). */
+#define GB_PROPERTIES_NOT_CREATED -1
+#define GB_PROPERTIES_NOT_NEEDED -2
+
+/* The GbWidget struct, which consists of pointers to the functions
+ implemented by each GbWidget. The properties_page_number is the page in
+ the widget properties notebook corresponding to the GbWidget.
+ The typedef to GbWidget is in glade.h */
+struct _GbWidget
+{
+ gchar **pixmap_struct;
+ gchar *class_id;
+ GdkPixmap *gdkpixmap;
+ GdkBitmap *mask;
+ const gchar *tooltip;
+ gint properties_page_number; /* Used internally */
+ gint child_properties_page_number; /* Used internally */
+
+ /* We need a pixbuf rather than GdkPixmap for the tree. This is only
+ created when needed for now. */
+ GdkPixbuf *pixbuf;
+
+ /* Creates a new widget of the particular class, or possibly shows a dialog
+ for the user to set options before creating the widget (but it must not
+ do this when loading an XML file, i.e. when the action is GB_LOADING). */
+ GtkWidget* (* gb_widget_new) (GbWidgetNewData *data);
+
+ /* This is used when we need to turn a normal widget into a GbWidget,
+ usually because it was created automatically as part of a dialog.
+ It should add any special signal handlers or data that is needed for
+ the widget to be used within Glade. For example, it may need to connect
+ to certain signals so that it can update the property page or redraw
+ the widget. */
+ void (* gb_widget_create_from_widget) (GtkWidget *widget,
+ GbWidgetCreateFromData *data);
+
+ void (* gb_widget_create_properties) (GtkWidget *widget,
+ GbWidgetCreateArgData *data);
+ void (* gb_widget_get_properties) (GtkWidget *widget,
+ GbWidgetGetArgData *data);
+ void (* gb_widget_set_properties) (GtkWidget *widget,
+ GbWidgetSetArgData *data);
+
+ /* Adds a widget as a child, used when loading the XML. Normal containers
+ are handled within Glade, but if you need to call special functions to
+ add the child, do it here. A similar replace_child function may be added
+ in future. */
+ void (* gb_widget_add_child) (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetSetArgData *data);
+ /* Returns a special child of the widget, given it's child name,
+ e.g. "Dialog:action_area". */
+ GtkWidget* (* gb_widget_get_child) (GtkWidget *widget,
+ const gchar *child_name);
+ /* Creates the properties that apply to the children of the widget's class.*/
+ void (* gb_widget_create_child_properties) (GtkWidget *widget,
+ GbWidgetCreateChildArgData *data);
+
+ /* Shows or saves the child properties of a child of the widget. */
+ void (* gb_widget_get_child_properties) (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetGetArgData *data);
+
+ /* Applies or loads the child properties of a child of the widget. */
+ void (* gb_widget_set_child_properties) (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetSetArgData *data);
+
+ /* Here the widget can add widget-specific commands to the popup menu. */
+ void (* gb_widget_create_popup_menu) (GtkWidget *widget,
+ GbWidgetCreateMenuData *data);
+
+ /* Outputs the C source code to create the widget and set its properties.
+ This function needs to call gb_widget_write_standard_source () to output
+ the code to set standard widget properties and add the widget to the
+ parent. */
+ void (* gb_widget_write_source) (GtkWidget *widget,
+ GbWidgetWriteSourceData *data);
+
+ /* Outputs the code to add a child to the widget. If the GbWidget doesn't
+ supply this function, the default gtk_container_add() function will be
+ used. parent_name is the C identifier of the parent, e.g. "vbox1". */
+ void (* gb_widget_write_add_child_source) (GtkWidget *parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData *data);
+
+ /* Called when the widget is destroyed, to free any allocated memory etc. */
+ void (* gb_widget_destroy) (GtkWidget *widget,
+ GbWidgetDestroyData *data);
+};
+
+
+/*************************************************************************
+ * Public Functions
+ *************************************************************************/
+
+/* Call this first, to initialize all GtkWidget & GbWidget types */
+
+void gb_widgets_init();
+
+/* This registers a GbWidget, so it can be looked up by class name. */
+void gb_widget_register_gbwidget (const gchar *class_id,
+ GbWidget *gbwidget);
+/* Thes return the GbWidget struct corresponding to the given class name or
+ widget. */
+GbWidget * gb_widget_lookup_class (const gchar *class_id);
+GbWidget * gb_widget_lookup (GtkWidget *widget);
+
+/* This returns the class id corresponding to the given widget.
+ This should be used instead of gtk_type_name so custom widgets work. */
+gchar* gb_widget_get_class_id (GtkWidget *widget);
+
+/* This initializes the GbWidget struct, setting all function pointers to NULL.
+ */
+void gb_widget_init_struct (GbWidget *gbwidget);
+
+GtkWidget* gb_widget_new (const gchar *class_id,
+ GtkWidget *parent);
+GtkWidget* gb_widget_new_full (const gchar *class_id,
+ gboolean create_default_name,
+ GtkWidget *parent,
+ GtkWidget *current_child,
+ gint x,
+ gint y,
+ GbWidgetNewCallback callback,
+ GbWidgetAction action,
+ GbWidgetSetArgData *loading_data);
+void gb_widget_create_from (GtkWidget *widget,
+ const gchar *name);
+void gb_widget_create_from_full (GtkWidget *widget,
+ const gchar *name,
+ GladeWidgetData *wdata);
+gboolean gb_widget_can_finish_new (GbWidgetNewData *data);
+void gb_widget_initialize (GtkWidget *widget,
+ GbWidgetNewData *data);
+void gb_widget_free_new_data (GbWidgetNewData *data);
+
+void gb_widget_set_usize (GtkWidget *widget,
+ gint w,
+ gint h);
+gint gb_widget_create_properties (GtkWidget *widget);
+
+gint gb_widget_create_child_properties (GtkWidget *widget);
+
+void gb_widget_show_properties (GtkWidget *widget);
+void gb_widget_show_position_properties
+ (GtkWidget *widget);
+#ifdef GLADE_STYLE_SUPPORT
+void gb_widget_show_style (GtkWidget *widget);
+#endif
+
+void gb_widget_apply_properties (GtkWidget *widget,
+ GtkWidget *property);
+
+void gb_widget_show_popup_menu (GtkWidget *widget,
+ GdkEventButton *event);
+GtkWidget* gb_widget_load (GtkWidget *widget,
+ GbWidgetSetArgData *data,
+ GtkWidget *parent);
+void gb_widget_load_style (GbWidgetSetArgData *data);
+void gb_widget_load_project (GbWidgetSetArgData *data);
+gboolean gb_widget_add_child (GtkWidget *parent,
+ GbWidgetSetArgData *data,
+ GtkWidget *child);
+
+void gb_widget_save (GtkWidget *widget,
+ GbWidgetGetArgData *data);
+#ifdef GLADE_STYLE_SUPPORT
+void gb_widget_save_style (GbStyle *gbstyle,
+ GbWidgetGetArgData *data,
+ gboolean save_all);
+#endif
+
+gboolean gb_widget_replace_child (GtkWidget *widget,
+ GtkWidget *current_child,
+ GtkWidget *new_child);
+
+/*
+ * Getting and setting the child name of a widget.
+ */
+
+/* Returns the child name of the widget. */
+gchar* gb_widget_get_child_name (GtkWidget *widget);
+
+/* Sets the child name of the widget. The child_name string is duplicated. */
+void gb_widget_set_child_name (GtkWidget *widget,
+ const gchar *child_name);
+
+
+/* Inputting Properties - Loading or Applying.
+ Note: The only time you have to free the returned value is when calling
+ gb_widget_input_text() and data->action == GB_APPLYING (because we get the
+ value from the text widget and it has to be freed), and when calling
+ gb_widget_input_pixmap_filename() with data->action == GB_LOADING. */
+gchar* gb_widget_input_string (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_text (GbWidgetSetArgData *data,
+ const gchar *property);
+gint gb_widget_input_int (GbWidgetSetArgData *data,
+ const gchar *property);
+gint gb_widget_input_optional_int(GbWidgetSetArgData *data,
+ const gchar *property,
+ gboolean *is_set);
+gfloat gb_widget_input_float (GbWidgetSetArgData *data,
+ const gchar *property);
+gboolean gb_widget_input_bool (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_choice (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_combo (GbWidgetSetArgData *data,
+ const gchar *property);
+GdkColor* gb_widget_input_color (GbWidgetSetArgData *data,
+ const gchar *property);
+GdkPixmap* gb_widget_input_bgpixmap (GbWidgetSetArgData *data,
+ const gchar *property,
+ gchar **filename);
+gpointer gb_widget_input_dialog (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_filename (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_pixmap_filename (GbWidgetSetArgData *data,
+ const gchar *property);
+GdkFont* gb_widget_input_font (GbWidgetSetArgData *data,
+ const gchar *property,
+ gchar **xlfd_fontname);
+gchar* gb_widget_input_stock_item (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_icon (GbWidgetSetArgData *data,
+ const gchar *property);
+gchar* gb_widget_input_named_icon (GbWidgetSetArgData *data,
+ const gchar *property);
+
+/* load only */
+gint gb_widget_input_enum (GbWidgetSetArgData *data,
+ GType enum_type,
+ const char **labels,
+ int *values,
+ const gchar *property);
+
+/* Outputting Properties - Saving or Showing.
+ When saving, the translatable string and text properties may also be output
+ in a separate file, as a number of translatable strings understood by
+ xgettext, i.e. using "N_()". This may be useful when using libglade, as
+ you could include this file in your POTFILES.in so the interface can easily
+ be translated into other languages. */
+void gb_widget_output_string (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_translatable_string (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_text (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_translatable_text (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_translatable_text_in_lines (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_int (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value);
+void gb_widget_output_optional_int (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value,
+ gboolean is_set);
+void gb_widget_output_float (GbWidgetGetArgData *data,
+ const gchar *property,
+ gfloat value);
+void gb_widget_output_bool (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value);
+void gb_widget_output_choice (GbWidgetGetArgData *data,
+ const gchar *property,
+ gint value,
+ const gchar *symbol);
+void gb_widget_output_combo (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_color (GbWidgetGetArgData *data,
+ const gchar *property,
+ GdkColor *value);
+void gb_widget_output_bgpixmap (GbWidgetGetArgData *data,
+ const gchar *property,
+ GdkPixmap *value,
+ const gchar *filename);
+void gb_widget_output_dialog (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *string,
+ gconstpointer value);
+void gb_widget_output_filename (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_pixmap_filename (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_font (GbWidgetGetArgData *data,
+ const gchar *property,
+ GdkFont *value,
+ const gchar *xlfd_fontname);
+void gb_widget_output_stock_item (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_icon (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+void gb_widget_output_named_icon (GbWidgetGetArgData *data,
+ const gchar *property,
+ const gchar *value);
+
+void gb_widget_output_enum (GbWidgetGetArgData *data,
+ GType enum_type,
+ int *values,
+ int n_values,
+ const gchar *property,
+ gint value);
+
+
+
+/* Tooltips functions. */
+gboolean gb_widget_get_show_tooltips (void);
+void gb_widget_set_show_tooltips (gboolean show);
+void gb_widget_reset_tooltips (void);
+
+/* Convenience functions for handling all 6 properties of adjustments. */
+void gb_widget_output_adjustment (GbWidgetGetArgData *data,
+ const gchar *Values[],
+ GtkAdjustment *adjustment,
+ gchar *saved_property_name);
+gboolean gb_widget_input_adjustment (GbWidgetSetArgData *data,
+ const gchar *Values[],
+ GtkAdjustment *adjustment,
+ gchar *saved_property_name);
+
+
+/* Common functions for gbwidgets that have a child label - button/menuitem
+ etc. */
+void gb_widget_remove_label (GtkWidget *menuitem,
+ GtkWidget *widget);
+
+void gb_widget_output_child_label(GtkWidget *widget,
+ GbWidgetGetArgData *data,
+ const gchar *Label);
+void gb_widget_input_child_label (GtkWidget *widget,
+ GbWidgetSetArgData *data,
+ const gchar *Label);
+void gb_widget_create_child_label_popup_menu
+ (GtkWidget *widget,
+ GbWidgetCreateMenuData *data);
+
+/* This calls the given function for all children of the widget that Glade is
+ interested in. It is used for saving the entire tree etc. */
+void gb_widget_children_foreach (GtkWidget *widget,
+ GtkCallback callback,
+ gpointer data);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_GBWIDGET_H */
diff --git a/tools/glade/glade/gbwidgets/Makefile.am b/tools/glade/glade/gbwidgets/Makefile.am
new file mode 100644
index 00000000..862d853a
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/Makefile.am
@@ -0,0 +1,93 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libgbwidgets.a
+
+# maybe this should be $(GLADE_GTK_CFLAGS) ?
+INCLUDES = $(GLADE_GTK_CFLAGS) \
+ $(GLADE_DEPRECATION_CFLAGS)
+
+libgbwidgets_a_SOURCES = \
+ gbaboutdialog.c \
+ gbaccellabel.c \
+ gbalignment.c \
+ gbarrow.c \
+ gbaspectframe.c \
+ gbbutton.c \
+ gbcalendar.c \
+ gbcellview.c \
+ gbcheckbutton.c \
+ gbcheckmenuitem.c \
+ gbclist.c \
+ gbcolorbutton.c \
+ gbcolorselection.c \
+ gbcolorselectiondialog.c \
+ gbcombo.c \
+ gbcombobox.c \
+ gbcomboboxentry.c \
+ gbctree.c \
+ gbcustom.c \
+ gbcurve.c \
+ gbdialog.c \
+ gbdrawingarea.c \
+ gbentry.c \
+ gbeventbox.c \
+ gbexpander.c \
+ gbfilechooserbutton.c \
+ gbfilechooserwidget.c \
+ gbfilechooserdialog.c \
+ gbfileselection.c \
+ gbfixed.c \
+ gbfontbutton.c \
+ gbfontselection.c \
+ gbfontselectiondialog.c \
+ gbframe.c \
+ gbgammacurve.c \
+ gbhandlebox.c \
+ gbhbox.c \
+ gbhbuttonbox.c \
+ gbhpaned.c \
+ gbhruler.c \
+ gbhscale.c \
+ gbhscrollbar.c \
+ gbhseparator.c \
+ gbiconview.c \
+ gbimage.c \
+ gbimagemenuitem.c \
+ gbinputdialog.c \
+ gblabel.c \
+ gblayout.c \
+ gblist.c \
+ gblistitem.c \
+ gbmenu.c \
+ gbmenubar.c \
+ gbmenuitem.c \
+ gbmenutoolbutton.c \
+ gbnotebook.c \
+ gboptionmenu.c \
+ gbpreview.c \
+ gbprogressbar.c \
+ gbradiobutton.c \
+ gbradiomenuitem.c \
+ gbradiotoolbutton.c \
+ gbscrolledwindow.c \
+ gbseparatormenuitem.c \
+ gbseparatortoolitem.c \
+ gbspinbutton.c \
+ gbstatusbar.c \
+ gbtable.c \
+ gbtextview.c \
+ gbtogglebutton.c \
+ gbtoggletoolbutton.c \
+ gbtoolbar.c \
+ gbtoolbutton.c \
+ gbtoolitem.c \
+ gbtreeview.c \
+ gbvbox.c \
+ gbvbuttonbox.c \
+ gbviewport.c \
+ gbvpaned.c \
+ gbvruler.c \
+ gbvscale.c \
+ gbvscrollbar.c \
+ gbvseparator.c \
+ gbwindow.c
diff --git a/tools/glade/glade/gbwidgets/gbaboutdialog.c b/tools/glade/glade/gbwidgets/gbaboutdialog.c
new file mode 100644
index 00000000..dd454986
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbaboutdialog.c
@@ -0,0 +1,602 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/aboutdialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Name = "GtkAboutDialog::name";
+static gchar *Copyright = "GtkAboutDialog::copyright";
+static gchar *Comments = "GtkAboutDialog::comments";
+static gchar *License = "GtkAboutDialog::license";
+static gchar *WrapLicense = "GtkAboutDialog::wrap_license";
+static gchar *Website = "GtkAboutDialog::website";
+static gchar *WebsiteLabel = "GtkAboutDialog::website_label";
+
+static gchar *Authors = "GtkAboutDialog::authors";
+static gchar *Documenters = "GtkAboutDialog::documenters";
+static gchar *Artists = "GtkAboutDialog::artists";
+static gchar *TranslatorCredits = "GtkAboutDialog::translator_credits";
+
+static gchar *Logo = "GtkAboutDialog::logo";
+
+
+static gchar *DestroyWithParent = "GtkAboutDialog|GtkWindow::destroy_with_parent";
+
+#define GLADE_TRANSLATORS_STRING "translator-credits"
+
+/* This is the old string we used for GnomeAbout, but translators don't like
+ it as the '_' character gets confused with an underlined accelerator key. */
+#define GLADE_TRANSLATORS_STRING2 "translator_credits"
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkAboutDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_about_dialog_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ gchar *project_name;
+
+ new_widget = gtk_about_dialog_new ();
+
+ project_name = glade_project_get_name (data->project);
+ if (!project_name)
+ project_name = _("Application Name");
+ gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (new_widget), project_name);
+
+ gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (new_widget), "1.0");
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ /* Set the default comment string for the translator credits. */
+ glade_util_set_translation_properties (new_widget, TranslatorCredits,
+ TRUE, "TRANSLATORS: Replace this string with your names, one name per line.", FALSE);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_about_dialog_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_filename (Logo, _("Logo:"), _("The pixmap to use as the logo"));
+
+ property_add_string (Name, _("Program Name:"), _("The name of the application"));
+ property_add_text (Comments, _("Comments:"), _("Additional information, such as a description of the application"), 3);
+ property_add_text (Copyright, _("Copyright:"), _("The copyright notice"), 2);
+
+ property_add_string (Website, _("Website URL:"), _("The URL of the application's website"));
+ property_add_string (WebsiteLabel, _("Website Label:"), _("The label to display for the link to the website"));
+
+ property_add_text (License, _("License:"), _("The license details of the application"), 3);
+ property_add_bool (WrapLicense, _("Wrap License:"), _("If the license text should be wrapped"));
+
+ property_add_text (Authors, _("Authors:"), _("The authors of the package, one on each line"), 2);
+ property_add_text (Documenters, _("Documenters:"), _("The documenters of the package, one on each line"), 2);
+ property_add_text (Artists, _("Artists:"), _("The people who have created the artwork for the package, one on each line"), 2);
+ property_add_text (TranslatorCredits, _("Translators:"), _("The translators of the package. This should normally be left empty so that translators can add their names in the po files"), 2);
+
+ /* We onlt need the common DestroyWithParent window property. The others
+ shouldn't really need to be changed on a simple About dialog. */
+ gb_window_create_standard_properties (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ NULL, DestroyWithParent, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_about_dialog_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ const gchar *name, *copyright, *comments, *license, *website, *website_label;
+ const char *translator_credits, *translator_credits_output;
+ gboolean wrap_license;
+
+ gb_window_get_standard_properties (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ NULL, DestroyWithParent, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+
+ name = gtk_about_dialog_get_name (GTK_ABOUT_DIALOG (widget));
+ gb_widget_output_translatable_string (data, Name, name);
+
+ copyright = gtk_about_dialog_get_copyright (GTK_ABOUT_DIALOG (widget));
+ gb_widget_output_translatable_text (data, Copyright, copyright);
+
+ comments = gtk_about_dialog_get_comments (GTK_ABOUT_DIALOG (widget));
+ gb_widget_output_translatable_text (data, Comments, comments);
+
+ license = gtk_about_dialog_get_license (GTK_ABOUT_DIALOG (widget));
+ gb_widget_output_translatable_text (data, License, license);
+
+ wrap_license = gtk_about_dialog_get_wrap_license (GTK_ABOUT_DIALOG (widget));
+ gb_widget_output_bool (data, WrapLicense, wrap_license);
+
+ /* We store the Website & WebsiteURL in the object datalist, since the
+ widget does odd things when we set them. */
+ website = g_object_get_data (G_OBJECT (widget), Website);
+ gb_widget_output_string (data, Website, website);
+
+ website_label = g_object_get_data (G_OBJECT (widget), WebsiteLabel);
+ gb_widget_output_translatable_string (data, WebsiteLabel, website_label);
+
+ gb_widget_output_text (data, Authors,
+ gtk_object_get_data (GTK_OBJECT (widget), Authors));
+ gb_widget_output_text (data, Documenters,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ Documenters));
+ gb_widget_output_text (data, Artists,
+ gtk_object_get_data (GTK_OBJECT (widget), Artists));
+
+ /* If we are saving, and translator_credits isn't set but is translatable,
+ we save the string "translator-credits". Translators can then
+ replace this with their own names in the po files. */
+ translator_credits = gtk_about_dialog_get_translator_credits (GTK_ABOUT_DIALOG (widget));
+ translator_credits_output = translator_credits;
+ if (data->action == GB_SAVING
+ && (!translator_credits || *translator_credits == '\0'))
+ {
+ gchar *comments_text;
+ gboolean translatable, context;
+
+ glade_util_get_translation_properties (widget, TranslatorCredits,
+ &translatable,
+ &comments_text, &context);
+ if (translatable)
+ translator_credits_output = GLADE_TRANSLATORS_STRING;
+ }
+ gb_widget_output_translatable_text (data, TranslatorCredits,
+ translator_credits_output);
+
+ gb_widget_output_pixmap_filename (data, Logo,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ Logo));
+}
+
+
+static gchar**
+strv_from_property (GbWidgetSetArgData *data, GtkWidget *widget, const char *key)
+{
+ gchar **retval = NULL;
+ char *str;
+
+ str = gb_widget_input_text (data, key);
+ if (data->apply)
+ {
+ gtk_object_set_data_full (GTK_OBJECT (widget), key, g_strdup (str),
+ str ? g_free : NULL);
+ retval = g_strsplit (str, "\n", 0);
+ }
+ if (data->action == GB_APPLYING)
+ g_free (str);
+
+ return retval;
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_about_dialog_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar **authors, **documenters, **artists;
+ gchar *name, *copyright, *comments, *license, *website, *website_label;
+ gchar *translators, *filename, *old_filename;
+ GdkPixbuf *logo = NULL;
+ GObject *object;
+ gboolean wrap_license;
+
+ object = G_OBJECT (widget);
+
+ gb_window_set_standard_properties (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ NULL, DestroyWithParent, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+
+ name = gb_widget_input_string (data, Name);
+ if (data->apply)
+ gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (widget), name);
+
+ copyright = gb_widget_input_text (data, Copyright);
+ if (data->apply)
+ gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (widget), copyright);
+ if (data->action == GB_APPLYING)
+ g_free (copyright);
+
+ comments = gb_widget_input_text (data, Comments);
+ if (data->apply)
+ gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (widget), comments);
+ if (data->action == GB_APPLYING)
+ g_free (comments);
+
+ license = gb_widget_input_text (data, License);
+ if (data->apply)
+ gtk_about_dialog_set_license (GTK_ABOUT_DIALOG (widget), license);
+ if (data->action == GB_APPLYING)
+ g_free (license);
+
+ wrap_license = gb_widget_input_bool (data, WrapLicense);
+ if (data->apply)
+ gtk_about_dialog_set_wrap_license (GTK_ABOUT_DIALOG (widget), wrap_license);
+
+
+ website = gb_widget_input_string (data, Website);
+ if (data->apply)
+ g_object_set_data_full (G_OBJECT (widget), Website, g_strdup (website),
+ website ? g_free : NULL);
+
+ website_label = gb_widget_input_string (data, WebsiteLabel);
+ if (data->apply)
+ g_object_set_data_full (G_OBJECT (widget), WebsiteLabel,
+ g_strdup (website_label),
+ website_label ? g_free : NULL);
+
+ authors = strv_from_property (data, widget, Authors);
+ if (data->apply)
+ gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (widget),
+ (const gchar**) authors);
+ g_strfreev (authors);
+
+ documenters = strv_from_property (data, widget, Documenters);
+ if (data->apply)
+ gtk_about_dialog_set_documenters (GTK_ABOUT_DIALOG (widget),
+ (const gchar**) documenters);
+ g_strfreev (documenters);
+
+ artists = strv_from_property (data, widget, Artists);
+ if (data->apply)
+ gtk_about_dialog_set_artists (GTK_ABOUT_DIALOG (widget),
+ (const gchar**) artists);
+ g_strfreev (artists);
+
+ translators = gb_widget_input_text (data, TranslatorCredits);
+ if (data->apply)
+ {
+ if (!strcmp (translators, GLADE_TRANSLATORS_STRING)
+ || !strcmp (translators, GLADE_TRANSLATORS_STRING2))
+ g_object_set (object, "translator-credits", "", NULL);
+ else
+ g_object_set (object, "translator-credits", translators, NULL);
+ }
+ if (data->action == GB_APPLYING)
+ g_free (translators);
+
+ filename = gb_widget_input_pixmap_filename (data, Logo);
+ if (data->apply)
+ {
+ if (filename && filename[0] == '\0')
+ filename = NULL;
+
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), Logo);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), Logo,
+ g_strdup (filename), filename ? g_free : NULL);
+ glade_project_add_pixmap (data->project, filename);
+ logo = filename ? gdk_pixbuf_new_from_file (filename, NULL) : NULL;
+ g_object_set (object, "logo", logo, NULL);
+ if (logo)
+ g_object_unref (logo);
+ }
+ if (data->action == GB_LOADING)
+ g_free (filename);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkAboutDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_about_dialog_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+static gboolean
+output_creators_array (GtkWidget *widget, GbWidgetWriteSourceData *data,
+ gchar *array_name, gchar *property_name)
+{
+ gchar *string, **strv;
+ gint i;
+
+ string = gtk_object_get_data (GTK_OBJECT (widget), property_name);
+ if (!string || *string == '\0')
+ return FALSE;
+
+ source_add_decl (data, " const gchar *%s[] = {\n", array_name);
+
+ strv = g_strsplit (string, "\n", 0);
+ for (i = 0; strv[i]; i++)
+ {
+ if (strv[i][0])
+ source_add_decl (data, " %s,\n",
+ source_make_string (strv[i], FALSE));
+ }
+
+ source_add_decl (data, " NULL\n };\n");
+ g_strfreev (strv);
+
+ return TRUE;
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_about_dialog_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean translatable, context, wrap_license;
+ gchar *comments;
+ const gchar *name, *copyright, *about_comments, *license;
+ const gchar *website, *website_label, *translators;
+ gchar *logo_filename;
+ char *pixbuf_name;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_about_dialog_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_window_write_standard_source (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ NULL, DestroyWithParent, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+
+ /* We set the version using the standard "VERSION" macro. */
+ source_add (data,
+ " gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (%s), VERSION);\n", data->wname);
+
+ name = gtk_about_dialog_get_name (GTK_ABOUT_DIALOG (widget));
+ if (name && *name)
+ {
+ glade_util_get_translation_properties (widget, Name, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname,
+ source_make_string_full (name,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ copyright = gtk_about_dialog_get_copyright (GTK_ABOUT_DIALOG (widget));
+ if (copyright && *copyright)
+ {
+ glade_util_get_translation_properties (widget, Copyright, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname,
+ source_make_string_full (copyright,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ about_comments = gtk_about_dialog_get_comments (GTK_ABOUT_DIALOG (widget));
+ if (about_comments && *about_comments)
+ {
+ glade_util_get_translation_properties (widget, Comments, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname,
+ source_make_string_full (about_comments,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ license = gtk_about_dialog_get_license (GTK_ABOUT_DIALOG (widget));
+ if (license && *license)
+ {
+ glade_util_get_translation_properties (widget, License, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_about_dialog_set_license (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname,
+ source_make_string_full (license,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ wrap_license = gtk_about_dialog_get_wrap_license (GTK_ABOUT_DIALOG (widget));
+ if (wrap_license)
+ {
+ source_add (data,
+ " gtk_about_dialog_set_wrap_license (GTK_ABOUT_DIALOG (%s), TRUE);\n",
+ data->wname);
+ }
+
+
+ website = g_object_get_data (G_OBJECT (widget), Website);
+ if (website && *website)
+ {
+ source_add (data,
+ " gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname,
+ source_make_string (website, FALSE));
+ }
+
+ website_label = g_object_get_data (G_OBJECT (widget), WebsiteLabel);
+ if (website_label && *website_label)
+ {
+ glade_util_get_translation_properties (widget, WebsiteLabel,
+ &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_about_dialog_set_website_label (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname,
+ source_make_string_full (website_label,
+ data->use_gettext && translatable,
+ context));
+ }
+
+
+ if (output_creators_array (widget, data, "authors", Authors))
+ source_add (data,
+ " gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (%s), authors);\n", data->wname);
+
+ if (output_creators_array (widget, data, "documenters", Documenters))
+ source_add (data,
+ " gtk_about_dialog_set_documenters (GTK_ABOUT_DIALOG (%s), documenters);\n", data->wname);
+
+ if (output_creators_array (widget, data, "artists", Artists))
+ source_add (data,
+ " gtk_about_dialog_set_artists (GTK_ABOUT_DIALOG (%s), artists);\n", data->wname);
+
+
+ /* If translators is set, then we use that specific string.
+ If it is not set, then if gettext support is enabled we output code
+ to call gettext to translate the special "translator_credits" string,
+ and use that if it is translated. */
+ translators = gtk_about_dialog_get_translator_credits (GTK_ABOUT_DIALOG (widget));
+ glade_util_get_translation_properties (widget, TranslatorCredits,
+ &translatable, &comments, &context);
+ if (translators && translators[0])
+ {
+ source_add_translator_comments_to_buffer (data, GLADE_DECLARATIONS, translatable, comments);
+ source_add_decl (data, " gchar *translators = %s;\n",
+ source_make_string (translators, FALSE));
+
+ source_add (data,
+ " gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (%s), translators);\n", data->wname);
+ }
+ else if (data->use_gettext && translatable)
+ {
+ if (!comments || comments[0] == '\0')
+ comments = "TRANSLATORS: Replace this string with your names, one name per line.";
+
+ source_add_translator_comments_to_buffer (data, GLADE_DECLARATIONS,
+ translatable, comments);
+ source_add_decl (data,
+ " gchar *translators = _(\"%s\");\n",
+ GLADE_TRANSLATORS_STRING);
+
+ source_add (data,
+ " gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (%s), translators);\n", data->wname);
+ }
+
+
+ logo_filename = gtk_object_get_data (GTK_OBJECT (widget), Logo);
+ if (logo_filename && logo_filename[0])
+ {
+ pixbuf_name = g_strdup_printf ("%s_logo_pixbuf", data->wname);
+
+ source_add_decl (data, " GdkPixbuf *%s;\n", pixbuf_name);
+ source_create_pixbuf (data, pixbuf_name, logo_filename);
+
+ source_add (data,
+ " gtk_about_dialog_set_logo (GTK_ABOUT_DIALOG (%s), %s);\n",
+ data->wname, pixbuf_name);
+
+ g_free (pixbuf_name);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_about_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_about_dialog_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = aboutdialog_xpm;
+ gbwidget.tooltip = _("About Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_about_dialog_new;
+ gbwidget.gb_widget_create_properties = gb_about_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_about_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_about_dialog_set_properties;
+ gbwidget.gb_widget_write_source = gb_about_dialog_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_about_dialog_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbaccellabel.c b/tools/glade/glade/gbwidgets/gbaccellabel.c
new file mode 100644
index 00000000..56519fd9
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbaccellabel.c
@@ -0,0 +1,214 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <math.h>
+
+#include <gtk/gtkaccellabel.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/accellabel.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "AccelLabel|GtkLabel::label";
+static gchar *UseUnderline = "AccelLabel|GtkLabel::use_underline";
+static gchar *UseMarkup = "AccelLabel|GtkLabel::use_markup";
+static gchar *Justify = "AccelLabel|GtkLabel::justify";
+static gchar *Wrap = "AccelLabel|GtkLabel::wrap";
+static gchar *XAlign = "AccelLabel|GtkMisc::xalign";
+static gchar *YAlign = "AccelLabel|GtkMisc::yalign";
+static gchar *XPad = "AccelLabel|GtkMisc::xpad";
+static gchar *YPad = "AccelLabel|GtkMisc::ypad";
+static gchar *Selectable = "AccelLabel|GtkLabel::selectable";
+
+static gchar *Ellipsize = "AccelLabel|GtkLabel::ellipsize";
+static gchar *WidthChars = "AccelLabel|GtkLabel::width_chars";
+static gchar *SingleLineMode = "AccelLabel|GtkLabel::single_line_mode";
+static gchar *Angle = "AccelLabel|GtkLabel::angle";
+
+static gchar *FocusTarget = "AccelLabel|GtkLabel::mnemonic_widget";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkAccelLabel, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_accel_label_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_accel_label_new (data->name);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_accel_label_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_label_create_standard_properties (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_accel_label_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_label_get_standard_properties (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_accel_label_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_label_set_standard_properties (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkAccelLabel, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_accel_label_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_accel_label_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ const gchar *label_text = gtk_label_get_label (GTK_LABEL (widget));
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gtk_accel_label_new (%s);\n", data->wname,
+ source_make_string_full (label_text,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (gtk_label_get_use_underline (GTK_LABEL (widget)))
+ source_add (data,
+ " gtk_label_set_use_underline (GTK_LABEL (%s), TRUE);\n",
+ data->wname);
+
+ gb_label_write_standard_source (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_accel_label_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_accel_label_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = accellabel_xpm;
+ gbwidget.tooltip = _("Label with Accelerator");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_accel_label_new;
+ gbwidget.gb_widget_create_properties = gb_accel_label_create_properties;
+ gbwidget.gb_widget_get_properties = gb_accel_label_get_properties;
+ gbwidget.gb_widget_set_properties = gb_accel_label_set_properties;
+ gbwidget.gb_widget_write_source = gb_accel_label_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_accel_label_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbalignment.c b/tools/glade/glade/gbwidgets/gbalignment.c
new file mode 100644
index 00000000..78a7fe2a
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbalignment.c
@@ -0,0 +1,268 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkalignment.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/alignment.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *XAlign = "GtkAlignment::xalign";
+static gchar *YAlign = "GtkAlignment::yalign";
+static gchar *XScale = "GtkAlignment::xscale";
+static gchar *YScale = "GtkAlignment::yscale";
+
+static gchar *TopPadding = "GtkAlignment::top_padding";
+static gchar *BottomPadding = "GtkAlignment::bottom_padding";
+static gchar *LeftPadding = "GtkAlignment::left_padding";
+static gchar *RightPadding = "GtkAlignment::right_padding";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkAlignment, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_alignment_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
+ if (data->action != GB_LOADING)
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_alignment_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_float_range (XAlign, _("X Align:"),
+ _("The horizontal alignment of the child widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (YAlign, _("Y Align:"),
+ _("The vertical alignment of the child widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (XScale, _("X Scale:"),
+ _("The horizontal scale of the child widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (YScale, _("Y Scale:"),
+ _("The vertical scale of the child widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+
+ property_add_int_range (TopPadding,
+ _("Top Padding:"),
+ _("Space to put above the child widget"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (BottomPadding,
+ _("Bottom Padding:"),
+ _("Space to put below the child widget"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (LeftPadding,
+ _("Left Padding:"),
+ _("Space to put to the left of the child widget"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (RightPadding,
+ _("Right Padding:"),
+ _("Space to put to the right of the child widget"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_alignment_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ guint padding_top, padding_bottom, padding_left, padding_right;
+
+ gb_widget_output_float (data, XAlign, GTK_ALIGNMENT (widget)->xalign);
+ gb_widget_output_float (data, YAlign, GTK_ALIGNMENT (widget)->yalign);
+ gb_widget_output_float (data, XScale, GTK_ALIGNMENT (widget)->xscale);
+ gb_widget_output_float (data, YScale, GTK_ALIGNMENT (widget)->yscale);
+
+ gtk_alignment_get_padding (GTK_ALIGNMENT (widget),
+ &padding_top, &padding_bottom,
+ &padding_left, &padding_right);
+
+ gb_widget_output_int (data, TopPadding, padding_top);
+ gb_widget_output_int (data, BottomPadding, padding_bottom);
+ gb_widget_output_int (data, LeftPadding, padding_left);
+ gb_widget_output_int (data, RightPadding, padding_right);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_alignment_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat xalign, yalign, xscale, yscale;
+ guint padding_top, padding_bottom, padding_left, padding_right;
+ gboolean set_alignment = FALSE, set_padding = FALSE;
+
+ xalign = gb_widget_input_float (data, XAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ xalign = GTK_ALIGNMENT (widget)->xalign;
+
+ yalign = gb_widget_input_float (data, YAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ yalign = GTK_ALIGNMENT (widget)->yalign;
+
+ xscale = gb_widget_input_float (data, XScale);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ xscale = GTK_ALIGNMENT (widget)->xscale;
+
+ yscale = gb_widget_input_float (data, YScale);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ yscale = GTK_ALIGNMENT (widget)->yscale;
+
+ if (set_alignment)
+ gtk_alignment_set (GTK_ALIGNMENT (widget), xalign, yalign, xscale, yscale);
+
+ gtk_alignment_get_padding (GTK_ALIGNMENT (widget),
+ &padding_top, &padding_bottom,
+ &padding_left, &padding_right);
+
+ padding_top = gb_widget_input_int (data, TopPadding);
+ if (data->apply)
+ set_padding = TRUE;
+
+ padding_bottom = gb_widget_input_int (data, BottomPadding);
+ if (data->apply)
+ set_padding = TRUE;
+
+ padding_left = gb_widget_input_int (data, LeftPadding);
+ if (data->apply)
+ set_padding = TRUE;
+
+ padding_right = gb_widget_input_int (data, RightPadding);
+ if (data->apply)
+ set_padding = TRUE;
+
+ if (set_padding)
+ gtk_alignment_set_padding (GTK_ALIGNMENT (widget),
+ padding_top, padding_bottom,
+ padding_left, padding_right);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkAlignment, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_alignment_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+static void
+gb_alignment_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ guint padding_top, padding_bottom, padding_left, padding_right;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_alignment_new (%g, %g, %g, %g);\n",
+ data->wname,
+ GTK_ALIGNMENT (widget)->xalign, GTK_ALIGNMENT (widget)->yalign,
+ GTK_ALIGNMENT (widget)->xscale, GTK_ALIGNMENT (widget)->yscale);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ gtk_alignment_get_padding (GTK_ALIGNMENT (widget),
+ &padding_top, &padding_bottom,
+ &padding_left, &padding_right);
+
+ if (padding_top != 0 || padding_bottom != 0
+ || padding_left != 0 || padding_right != 0)
+ {
+ source_add (data,
+ " gtk_alignment_set_padding (GTK_ALIGNMENT (%s), %i, %i, %i, %i);\n",
+ data->wname,
+ padding_top, padding_bottom, padding_left, padding_right);
+
+ }
+}
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_alignment_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_alignment_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = alignment_xpm;
+ gbwidget.tooltip = _("Alignment");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_alignment_new;
+ gbwidget.gb_widget_create_properties = gb_alignment_create_properties;
+ gbwidget.gb_widget_get_properties = gb_alignment_get_properties;
+ gbwidget.gb_widget_set_properties = gb_alignment_set_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_alignment_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_alignment_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbarrow.c b/tools/glade/glade/gbwidgets/gbarrow.c
new file mode 100644
index 00000000..b539bedc
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbarrow.c
@@ -0,0 +1,312 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkarrow.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/arrow.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Direction = "GtkArrow::arrow_type";
+static gchar *Shadow = "GtkArrow::shadow_type";
+static gchar *XAlign = "Arrow|GtkMisc::xalign";
+static gchar *YAlign = "Arrow|GtkMisc::yalign";
+static gchar *XPad = "Arrow|GtkMisc::xpad";
+static gchar *YPad = "Arrow|GtkMisc::ypad";
+
+static const gchar *GbDirectionChoices[] =
+{"Up", "Down", "Left", "Right", NULL};
+static const gint GbDirectionValues[] =
+{
+ GTK_ARROW_UP,
+ GTK_ARROW_DOWN,
+ GTK_ARROW_LEFT,
+ GTK_ARROW_RIGHT
+};
+static const gchar *GbDirectionSymbols[] =
+{
+ "GTK_ARROW_UP",
+ "GTK_ARROW_DOWN",
+ "GTK_ARROW_LEFT",
+ "GTK_ARROW_RIGHT"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkArrow, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_arrow_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_arrow_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Direction, _("Direction:"), _("The direction of the arrow"),
+ GbDirectionChoices);
+ property_add_choice (Shadow, _("Shadow:"), _("The shadow type of the arrow"),
+ GladeShadowChoices);
+ property_add_float_range (XAlign, _("X Align:"),
+ _("The horizontal alignment of the arrow"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (YAlign, _("Y Align:"),
+ _("The vertical alignment of the arrow"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_int_range (XPad, _("X Pad:"), _("The horizontal padding"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (YPad, _("Y Pad:"), _("The vertical padding"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_arrow_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ for (i = 0; i < sizeof (GbDirectionValues) / sizeof (GbDirectionValues[0]);
+ i++)
+ {
+ if (GbDirectionValues[i] == GTK_ARROW (widget)->arrow_type)
+ gb_widget_output_choice (data, Direction, i, GbDirectionSymbols[i]);
+ }
+
+ for (i = 0; i < GladeShadowChoicesSize; i++)
+ {
+ if (GladeShadowValues[i] == GTK_ARROW (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GladeShadowSymbols[i]);
+ }
+ gb_widget_output_float (data, XAlign, GTK_MISC (widget)->xalign);
+ gb_widget_output_float (data, YAlign, GTK_MISC (widget)->yalign);
+ gb_widget_output_int (data, XPad, GTK_MISC (widget)->xpad);
+ gb_widget_output_int (data, YPad, GTK_MISC (widget)->ypad);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_arrow_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *direction, *shadow;
+ gboolean set_arrow = FALSE, set_alignment = FALSE, set_padding = FALSE;
+ gfloat xalign, yalign;
+ gint xpad, ypad, i;
+ GtkArrowType arrow_type = GTK_ARROW_UP;
+ GtkShadowType shadow_type = GTK_SHADOW_NONE;
+
+ direction = gb_widget_input_choice (data, Direction);
+ if (data->apply)
+ {
+ for (i = 0;
+ i < sizeof (GbDirectionValues) / sizeof (GbDirectionValues[0]);
+ i++)
+ {
+ if (!strcmp (direction, GbDirectionChoices[i])
+ || !strcmp (direction, GbDirectionSymbols[i]))
+ {
+ arrow_type = GbDirectionValues[i];
+ set_arrow = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ arrow_type = GTK_ARROW (widget)->arrow_type;
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < GladeShadowChoicesSize; i++)
+ {
+ if (!strcmp (shadow, GladeShadowChoices[i])
+ || !strcmp (shadow, GladeShadowSymbols[i]))
+ {
+ shadow_type = GladeShadowValues[i];
+ set_arrow = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ shadow_type = GTK_ARROW (widget)->shadow_type;
+
+ if (set_arrow)
+ gtk_arrow_set (GTK_ARROW (widget), arrow_type, shadow_type);
+
+ xalign = gb_widget_input_float (data, XAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ xalign = GTK_MISC (widget)->xalign;
+
+ yalign = gb_widget_input_float (data, YAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ yalign = GTK_MISC (widget)->yalign;
+
+ if (set_alignment)
+ gtk_misc_set_alignment (GTK_MISC (widget), xalign, yalign);
+
+ xpad = gb_widget_input_int (data, XPad);
+ if (data->apply)
+ set_padding = TRUE;
+ else
+ xpad = GTK_MISC (widget)->xpad;
+
+ ypad = gb_widget_input_int (data, YPad);
+ if (data->apply)
+ set_padding = TRUE;
+ else
+ ypad = GTK_MISC (widget)->ypad;
+
+ if (set_padding)
+ gtk_misc_set_padding (GTK_MISC (widget), xpad, ypad);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkArrow, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_arrow_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_arrow_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gfloat xalign, yalign;
+ gint xpad, ypad, arrow_type = 0, shadow_type = 0, i;
+
+ for (i = 0; i < sizeof (GbDirectionValues) / sizeof (GbDirectionValues[0]);
+ i++)
+ if (GbDirectionValues[i] == GTK_ARROW (widget)->arrow_type)
+ {
+ arrow_type = i;
+ break;
+ }
+ for (i = 0; i < GladeShadowChoicesSize; i++)
+ if (GladeShadowValues[i] == GTK_ARROW (widget)->shadow_type)
+ {
+ shadow_type = i;
+ break;
+ }
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_arrow_new (%s, %s);\n", data->wname,
+ GbDirectionSymbols[arrow_type], GladeShadowSymbols[shadow_type]);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ xalign = GTK_MISC (widget)->xalign;
+ yalign = GTK_MISC (widget)->yalign;
+ if (xalign != 0.5 || yalign != 0.5)
+ {
+ source_add (data, " gtk_misc_set_alignment (GTK_MISC (%s), %g, %g);\n",
+ data->wname, xalign, yalign);
+ }
+ xpad = GTK_MISC (widget)->xpad;
+ ypad = GTK_MISC (widget)->ypad;
+ if (xpad || ypad)
+ {
+ source_add (data, " gtk_misc_set_padding (GTK_MISC (%s), %d, %d);\n",
+ data->wname, xpad, ypad);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_arrow_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_arrow_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = arrow_xpm;
+ gbwidget.tooltip = _("Arrow");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_arrow_create_properties;
+ gbwidget.gb_widget_get_properties = gb_arrow_get_properties;
+ gbwidget.gb_widget_set_properties = gb_arrow_set_properties;
+/*
+ gbwidget.gb_widget_new = gb_arrow_new;
+ gbwidget.gb_widget_create_popup_menu = gb_arrow_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_arrow_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbaspectframe.c b/tools/glade/glade/gbwidgets/gbaspectframe.c
new file mode 100644
index 00000000..b0c3e181
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbaspectframe.c
@@ -0,0 +1,335 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "../gb.h"
+#include <math.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkaspectframe.h>
+#include <gtk/gtklabel.h>
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/aspectframe.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *LabelXAlign = "AspectFrame|GtkFrame::label_xalign";
+static gchar *LabelYAlign = "AspectFrame|GtkFrame::label_yalign";
+static gchar *Shadow = "AspectFrame|GtkFrame::shadow_type";
+static gchar *XAlign = "GtkAspectFrame::xalign";
+static gchar *YAlign = "GtkAspectFrame::yalign";
+static gchar *Ratio = "GtkAspectFrame::ratio";
+static gchar *Obey = "GtkAspectFrame::obey_child";
+
+/* We don't show this any more, as the label is a child widget now, but we
+ load this for compatability with old XML files. */
+static gchar *Label = "AspectFrame|GtkFrame::label";
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkAspectFrame, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_aspect_frame_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, TRUE);
+
+ if (data->action != GB_LOADING)
+ {
+ GtkWidget *label, *alignment;
+ gchar *label_markup;
+
+ /* For HIG compliance, we create a frame with no shadow, with a label
+ of "<b>widget-name</b>", and with an alignment to add 12 pixels
+ padding on the left. */
+ gtk_frame_set_shadow_type (GTK_FRAME (new_widget), GTK_SHADOW_NONE);
+
+ label = gb_widget_new ("GtkLabel", NULL);
+ label_markup = g_strdup_printf ("<b>%s</b>", data->name);
+ gtk_label_set_markup (GTK_LABEL (label), label_markup);
+ g_free (label_markup);
+ gtk_object_set_data (GTK_OBJECT (label), "GtkLabel::use_markup",
+ GINT_TO_POINTER (TRUE));
+
+ gtk_frame_set_label_widget (GTK_FRAME (new_widget), label);
+
+ alignment = gb_widget_new ("GtkAlignment", NULL);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+
+ gtk_container_add (GTK_CONTAINER (new_widget), alignment);
+ }
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_aspect_frame_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ property_add_float_range (LabelXAlign, _("Label X Align:"),
+ _("The horizontal alignment of the frame's label widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (LabelYAlign, _("Label Y Align:"),
+ _("The vertical alignment of the frame's label widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_choice (Shadow, _("Shadow:"), _("The type of shadow of the frame"),
+ GbShadowChoices);
+ property_add_float_range (XAlign, _("X Align:"),
+ _("The horizontal alignment of the frame's child"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (YAlign, _("Y Align:"),
+ _("The horizontal alignment of the frame's child"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float (Ratio, _("Ratio:"),
+ _("The aspect ratio of the frame's child"));
+ property_add_bool (Obey, _("Obey Child:"),
+ _("If the aspect ratio should be determined by the child"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_aspect_frame_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ gb_widget_output_float (data, LabelXAlign, GTK_FRAME (widget)->label_xalign);
+ gb_widget_output_float (data, LabelYAlign, GTK_FRAME (widget)->label_yalign);
+
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == GTK_FRAME (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GbShadowSymbols[i]);
+ }
+
+ gb_widget_output_float (data, XAlign, GTK_ASPECT_FRAME (widget)->xalign);
+ gb_widget_output_float (data, YAlign, GTK_ASPECT_FRAME (widget)->yalign);
+ gb_widget_output_float (data, Ratio, GTK_ASPECT_FRAME (widget)->ratio);
+ gb_widget_output_bool (data, Obey, GTK_ASPECT_FRAME (widget)->obey_child);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_aspect_frame_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat label_xalign, label_yalign;
+ gboolean apply_xalign, apply_yalign;
+ gfloat xalign, yalign, ratio;
+ gchar *shadow;
+ gboolean obey_child, set_aspect_frame = FALSE;
+ gint i;
+
+ /* We load the 'label' property, but create a child GbWidget. */
+ if (data->action == GB_LOADING)
+ {
+ gchar *label = gb_widget_input_string (data, Label);
+ if (data->apply && label && *label)
+ {
+ GtkWidget *label_widget = gb_widget_new ("GtkLabel", NULL);
+ gtk_label_set_text (GTK_LABEL (label_widget), label);
+ gtk_frame_set_label_widget (GTK_FRAME (widget), label_widget);
+ }
+ }
+
+ label_xalign = gb_widget_input_float (data, LabelXAlign);
+ apply_xalign = data->apply;
+ if (!apply_xalign)
+ label_xalign = GTK_FRAME (widget)->label_xalign;
+
+ label_yalign = gb_widget_input_float (data, LabelYAlign);
+ apply_yalign = data->apply;
+ if (!apply_yalign)
+ label_yalign = GTK_FRAME (widget)->label_yalign;
+
+ if (apply_xalign || apply_yalign)
+ gtk_frame_set_label_align (GTK_FRAME (widget), label_xalign, label_yalign);
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GbShadowValues[i]);
+ break;
+ }
+ }
+ }
+
+ xalign = gb_widget_input_float (data, XAlign);
+ if (data->apply)
+ set_aspect_frame = TRUE;
+ else
+ xalign = GTK_ASPECT_FRAME (widget)->xalign;
+
+ yalign = gb_widget_input_float (data, YAlign);
+ if (data->apply)
+ set_aspect_frame = TRUE;
+ else
+ yalign = GTK_ASPECT_FRAME (widget)->yalign;
+
+ ratio = gb_widget_input_float (data, Ratio);
+ if (data->apply)
+ set_aspect_frame = TRUE;
+ else
+ ratio = GTK_ASPECT_FRAME (widget)->ratio;
+
+ obey_child = gb_widget_input_bool (data, Obey);
+ if (data->apply)
+ set_aspect_frame = TRUE;
+ else
+ obey_child = GTK_ASPECT_FRAME (widget)->obey_child;
+
+ if (set_aspect_frame)
+ gtk_aspect_frame_set (GTK_ASPECT_FRAME (widget), xalign, yalign,
+ ratio, obey_child);
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_aspect_frame_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gfloat xalign, yalign;
+ gint shadow = 0, i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_aspect_frame_new (NULL, %g, %g, %g, %s);\n",
+ data->wname,
+ GTK_ASPECT_FRAME (widget)->xalign,
+ GTK_ASPECT_FRAME (widget)->yalign,
+ GTK_ASPECT_FRAME (widget)->ratio,
+ GTK_ASPECT_FRAME (widget)->obey_child ? "TRUE" : "FALSE");
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ xalign = GTK_FRAME (widget)->label_xalign;
+ yalign = GTK_FRAME (widget)->label_yalign;
+ if (xalign >= GLADE_EPSILON || fabs (yalign - 0.5) >= GLADE_EPSILON)
+ {
+ source_add (data,
+ " gtk_frame_set_label_align (GTK_FRAME (%s), %g, 0.5);\n",
+ data->wname, xalign);
+ }
+
+ if (GTK_FRAME (widget)->shadow_type != GTK_SHADOW_ETCHED_IN)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ if (GbShadowValues[i] == GTK_FRAME (widget)->shadow_type)
+ {
+ shadow = i;
+ break;
+ }
+ source_add (data, " gtk_frame_set_shadow_type (GTK_FRAME (%s), %s);\n",
+ data->wname, GbShadowSymbols[shadow]);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_aspect_frame_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_aspect_frame_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = aspectframe_xpm;
+ gbwidget.tooltip = _("Aspect Frame");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_aspect_frame_new;
+ gbwidget.gb_widget_create_properties = gb_aspect_frame_create_properties;
+ gbwidget.gb_widget_get_properties = gb_aspect_frame_get_properties;
+ gbwidget.gb_widget_set_properties = gb_aspect_frame_set_properties;
+ gbwidget.gb_widget_write_source = gb_aspect_frame_write_source;
+
+ /* We just use the GtkFrame functions for these. */
+ gbwidget.gb_widget_create_popup_menu = gb_frame_create_popup_menu;
+ gbwidget.gb_widget_add_child = gb_frame_add_child;
+ gbwidget.gb_widget_get_child_properties = gb_frame_get_child_properties;
+ gbwidget.gb_widget_write_add_child_source = gb_frame_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbbutton.c b/tools/glade/glade/gbwidgets/gbbutton.c
new file mode 100644
index 00000000..1738b51b
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbbutton.c
@@ -0,0 +1,1612 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkbbox.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkstock.h>
+
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/button.xpm"
+
+/*
+ * GtkButton widget - unfortunately this has been 'overloaded' a bit to cope
+ * with extra properties available in toolbar buttons and Gnome buttons.
+ * Standard toolbar buttons can have an icon as well as a label.
+ * Gnome buttons can be a stock button (which has a label and icon), or can
+ * have a stock pixmap as well as a label if they are in a toolbar or in a
+ * GnomeDialog/MessageBox.
+ */
+
+typedef enum {
+ GLADE_BUTTON_NORMAL,
+ GLADE_BUTTON_DIALOG,
+ GLADE_BUTTON_GNOME_DIALOG
+} GladeButtonType;
+
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "GtkButton::stock_button";
+static gchar *Label = "GtkButton::label";
+static gchar *Icon = "GtkButton::icon";
+static gchar *FocusOnClick = "GtkButton::focus_on_click";
+
+/* This is only used for normal/stock buttons, not special toolbar buttons,
+ as the toolbar has its own relief setting. */
+static gchar *Relief = "GtkButton::relief";
+
+/* This is used for dialog buttons. It is a string, either one of the standard
+ GTK+ response strings, or a user-defined integer. */
+static gchar *ResponseID = "GtkButton::response_id";
+
+/* This is used for dialog buttons, to set if it is a secondary button.
+ Buttons with ResponseID set to "GTK_RESPONSE_HELP" are always secondary. */
+/* FIXME: We don't worry about this for now. We may support it later. */
+/*static gchar *Secondary = "GtkButton::secondary";*/
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_button_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_button_new_with_label (data->name);
+ else
+ {
+ new_widget = gtk_button_new ();
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder());
+ }
+ return new_widget;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ GList *response_list = NULL;
+ gint i;
+
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_choice (Relief, _("Button Relief:"),
+ _("The relief style of the button"),
+ GladeReliefChoices);
+
+ for (i = 0; i < GladeStockResponsesSize; i++)
+ response_list = g_list_append (response_list, GladeStockResponses[i].name);
+ property_add_combo (ResponseID, _("Response ID:"),
+ _("The response code returned when the button is pressed. "
+ "Select one of the standard responses or enter a positive integer value"),
+ response_list);
+ g_list_free (response_list);
+
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+/* Returns the type of the button - NORMAL, DIALOG or GNOME_DIALOG. */
+GladeButtonType
+gb_button_get_button_type (GtkWidget *widget)
+{
+ gchar *child_name;
+
+ if (widget->parent)
+ {
+ child_name = gb_widget_get_child_name (widget->parent);
+ if (child_name && !strcmp (child_name, GladeChildDialogActionArea))
+ {
+ GtkWidget *toplevel = glade_util_get_toplevel (widget);
+
+ if (GTK_IS_DIALOG (toplevel))
+ return GLADE_BUTTON_DIALOG;
+ else
+ return GLADE_BUTTON_GNOME_DIALOG;
+ }
+ }
+
+ return GLADE_BUTTON_NORMAL;
+}
+
+
+/*
+ * NORMAL BUTTONS. GtkButton/GtkToggleButton/GtkCheckButton/GtkRadioButton.
+ */
+
+/* This tries to find the child label & icon of the button. If the button
+ contains other widgets it returns FALSE, i.e. if the user has added other
+ widgets instead. */
+static gboolean
+gb_button_normal_find_child_widgets (GtkWidget *widget,
+ GtkWidget **label,
+ GtkWidget **icon)
+{
+ GtkWidget *child, *alignment_child;
+
+ *label = *icon = NULL;
+
+ /* Check it has a child. If it doesn't output a warning. */
+ child = GTK_BIN (widget)->child;
+ g_return_val_if_fail (child != NULL, FALSE);
+
+ /* Check if it has just a GtkLabel child. */
+ if (GTK_IS_LABEL (child))
+ {
+ /* If it is a GbWidget we don't handle its properties here. */
+ if (GB_IS_GB_WIDGET (child))
+ return FALSE;
+
+ *label = child;
+ return TRUE;
+ }
+
+ /* Check if it has just a GtkImage child. */
+ if (GTK_IS_IMAGE (child))
+ {
+ *icon = child;
+ return TRUE;
+ }
+
+ /* If it contains an icon and a label it must be a GtkAlignment with a
+ GtkHBox in it. */
+ if (!GTK_IS_ALIGNMENT (child))
+ return FALSE;
+
+ /* Now check for a hbox with a GtkImage and GtkLabel children. */
+ alignment_child = GTK_BIN (child)->child;
+ if (alignment_child && GTK_IS_HBOX (alignment_child)
+ && g_list_length (GTK_BOX (alignment_child)->children) == 2)
+ {
+ GList *children;
+ GtkBoxChild *child1, *child2;
+
+ children = GTK_BOX (alignment_child)->children;
+ child1 = children->data;
+ child2 = children->next->data;
+
+ if (GTK_IS_IMAGE (child1->widget) && GTK_IS_LABEL (child2->widget))
+ {
+ *icon = child1->widget;
+ *label = child2->widget;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static void
+gb_button_normal_get_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gchar *stock_id, *label_text;
+ gboolean label_sensitive = TRUE;
+ gboolean icon_sensitive = TRUE;
+ GtkWidget *label, *icon;
+
+ /* We only allow the GTK_ICON_SIZE_BUTTON size for stock items & icons. */
+ if (data->action == GB_SHOWING)
+ {
+ property_set_stock_item_icon_size (stock_id_p, GTK_ICON_SIZE_BUTTON);
+ property_set_icon_size (icon_p, GTK_ICON_SIZE_BUTTON);
+ }
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget), GladeButtonStockIDKey);
+ /* In the XML the stock item name is actually saved as the label property,
+ and the use_stock property specifies that it is a stock item.
+ Also, use_underline needs to be set. */
+ if (data->action == GB_SAVING)
+ {
+ if (stock_id)
+ {
+ gb_widget_output_stock_item (data, "label", stock_id);
+ gb_widget_output_bool (data, "use_stock", TRUE);
+ }
+ }
+ else
+ {
+ gb_widget_output_stock_item (data, stock_id_p, stock_id);
+ }
+
+
+ if (stock_id)
+ {
+ label_sensitive = FALSE;
+ icon_sensitive = FALSE;
+ }
+ else
+ {
+ if (gb_button_normal_find_child_widgets (widget, &label, &icon))
+ {
+ gchar *icon_name = NULL;
+
+ if (label)
+ label_text = (gchar*) gtk_label_get_label (GTK_LABEL (label));
+ else
+ label_text = "";
+
+ /* This is a bit of a hack. The label has the real translation
+ properties, but we copy them to the button so everything works. */
+ if (label) {
+ glade_util_copy_translation_properties (label, "GtkLabel::label",
+ widget, label_p);
+ }
+
+ /* When saving we only output the label if the icon isn't set,
+ since if it is we will be saving as separate child widgets. */
+ if (data->action != GB_SAVING || !icon)
+ gb_widget_output_translatable_text (data, label_p, label_text);
+
+ /* We always save use_underline as TRUE, though we don't load it. */
+ if (data->action == GB_SAVING && !icon)
+ gb_widget_output_bool (data, "use_underline", TRUE);
+
+ if (icon)
+ icon_name = gtk_object_get_data (GTK_OBJECT (icon), GladeIconKey);
+
+ /* We never output the icon when saving, as it will be saved as a
+ child widget. */
+ if (data->action != GB_SAVING)
+ gb_widget_output_icon (data, icon_p, icon_name);
+ }
+ else
+ {
+ label_sensitive = FALSE;
+ icon_sensitive = FALSE;
+ }
+ }
+
+ if (data->action == GB_SHOWING)
+ {
+ if (!label_sensitive)
+ gb_widget_output_translatable_text (data, label_p, "");
+ property_set_sensitive (label_p, label_sensitive);
+
+ if (!icon_sensitive)
+ gb_widget_output_pixmap_filename (data, icon_p, "");
+ property_set_sensitive (icon_p, icon_sensitive);
+ }
+}
+
+
+static void
+gb_button_normal_set_stock_id (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gboolean is_stock_item = FALSE;
+ const gchar *label_text = "";
+
+ if (stock_id && stock_id[0])
+ is_stock_item = TRUE;
+
+ if (is_stock_item)
+ {
+ gtk_button_set_use_stock (GTK_BUTTON (widget), TRUE);
+ gtk_button_set_label (GTK_BUTTON (widget), stock_id);
+ gtk_object_set_data_full (GTK_OBJECT (widget), GladeButtonStockIDKey,
+ g_strdup (stock_id), g_free);
+ }
+ else
+ {
+ /* Change the button back to a normal button with a simple label. */
+ gtk_button_set_use_stock (GTK_BUTTON (widget), FALSE);
+ label_text = gtk_widget_get_name (widget);
+ gtk_button_set_label (GTK_BUTTON (widget), label_text);
+ gtk_object_set_data (GTK_OBJECT (widget), GladeButtonStockIDKey, NULL);
+ }
+
+ /* If the widget's properties are displayed, we update the sensitivity of
+ the label and icon, according to whether a stock item is selected. */
+ if (data->action == GB_APPLYING && property_get_widget () == widget)
+ {
+ property_set_sensitive (label_p, !is_stock_item);
+ property_set_sensitive (icon_p, !is_stock_item);
+
+ /* Turn off auto-apply, and set the label. */
+ property_set_auto_apply (FALSE);
+ property_set_text (label_p, label_text);
+ property_set_filename (icon_p, "");
+ property_set_auto_apply (TRUE);
+ }
+}
+
+
+static void
+gb_button_normal_recreate_children (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *label, gchar *icon_name)
+{
+ GtkWidget *parent = widget;
+
+ /* Remove any existing children. */
+ if (GTK_BIN (widget)->child)
+ gtk_container_remove (GTK_CONTAINER (widget), GTK_BIN (widget)->child);
+
+ /* If both label and icon are needed, we put them in a hbox, otherwise we
+ just add the label or icon to the button. */
+ if (label && icon_name)
+ {
+ GtkWidget *alignment = gb_widget_new ("GtkAlignment", widget);
+ gtk_widget_show (alignment);
+ gtk_container_add (GTK_CONTAINER (widget), alignment);
+ gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.5, 0.5, 0.0, 0.0);
+ if (GTK_BIN (alignment)->child)
+ gtk_container_remove (GTK_CONTAINER (alignment),
+ GTK_BIN (alignment)->child);
+
+ /* We use gb_widget_new_full() and GB_LOADING since we don't want the
+ dialog to be shown asking for the number of columns. */
+ parent = gb_widget_new_full ("GtkHBox", TRUE, alignment, NULL, 0, 0,
+ NULL, GB_LOADING, NULL);
+ gtk_widget_show (parent);
+ gtk_box_set_spacing (GTK_BOX (parent), 2);
+ gtk_container_add (GTK_CONTAINER (alignment), parent);
+ }
+
+ if (icon_name)
+ {
+ GtkWidget *icon_widget;
+
+ icon_widget = gb_widget_new ("GtkImage", parent);
+
+ gtk_object_set_data_full (GTK_OBJECT (icon_widget), GladeIconKey,
+ g_strdup (icon_name),
+ icon_name ? g_free : NULL);
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ gtk_image_set_from_stock (GTK_IMAGE (icon_widget), icon_name,
+ GTK_ICON_SIZE_BUTTON);
+ }
+ else
+ {
+ gtk_image_set_from_file (GTK_IMAGE (icon_widget), icon_name);
+ glade_project_add_pixmap (data->project, icon_name);
+ }
+ gtk_widget_show (icon_widget);
+
+ /* We pack them in the hbox just like GtkButton does. */
+ if (GTK_IS_BOX (parent))
+ gtk_box_pack_start (GTK_BOX (parent), icon_widget, FALSE, FALSE, 0);
+ else
+ gtk_container_add (GTK_CONTAINER (parent), icon_widget);
+ }
+
+ if (label)
+ {
+ GtkWidget *label_widget;
+
+ /* If we only have a label, we use a simple label widget, otherwise we
+ use a GbWidget. */
+ if (icon_name)
+ {
+ label_widget = gb_widget_new ("GtkLabel", parent);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label_widget), label);
+ }
+ else
+ {
+ label_widget = gtk_label_new_with_mnemonic (label);
+ }
+
+ gtk_widget_show (label_widget);
+
+ if (GTK_IS_BOX (parent))
+ gtk_box_pack_start (GTK_BOX (parent), label_widget, FALSE, FALSE, 0);
+ else
+ gtk_container_add (GTK_CONTAINER (parent), label_widget);
+ }
+}
+
+
+void
+gb_button_normal_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gchar *stock_id = NULL, *label, *icon_name = NULL;
+ gboolean apply_stock_id = FALSE, apply_label, apply_icon;
+ gboolean free_label = FALSE, free_icon_name = FALSE;
+ GtkWidget *label_widget, *icon_widget;
+
+ label = gb_widget_input_text (data, label_p);
+ apply_label = data->apply;
+ if (data->action == GB_APPLYING)
+ free_label = TRUE;
+
+ /* When loading, if "use_stock" is TRUE, then the label is the stock item. */
+ if (data->action == GB_LOADING)
+ {
+ gboolean is_stock_item = gb_widget_input_bool (data, "use_stock");
+ if (is_stock_item)
+ {
+ stock_id = label;
+ apply_stock_id = apply_label;
+ }
+ }
+ else
+ {
+ stock_id = gb_widget_input_stock_item (data, stock_id_p);
+ apply_stock_id = data->apply;
+ }
+
+ if (apply_stock_id)
+ {
+ gb_button_normal_set_stock_id (widget, data, stock_id, label_p, icon_p);
+ goto out;
+ }
+
+ icon_name = gb_widget_input_icon (data, icon_p);
+ apply_icon = data->apply;
+
+ gb_button_normal_find_child_widgets (widget, &label_widget,
+ &icon_widget);
+
+ /* This is a bit of a hack. The label has the real translation
+ properties, so we have to copy them back there. */
+ if (apply_label && label_widget)
+ glade_util_copy_translation_properties (widget, label_p,
+ label_widget, "GtkLabel::label");
+
+ /* If neither icon nor label is set, we don't touch the button as it may
+ have other child widgets. */
+ if (!apply_label && !apply_icon)
+ return;
+
+ if (!apply_label)
+ {
+ if (label_widget)
+ {
+ label = g_strdup (gtk_label_get_label (GTK_LABEL (label_widget)));
+ free_label = TRUE;
+ }
+ else
+ label = NULL;
+ }
+
+ if (!apply_icon)
+ {
+ if (icon_widget)
+ {
+ icon_name = gtk_object_get_data (GTK_OBJECT (icon_widget),
+ GladeIconKey);
+ if (icon_name && *icon_name)
+ {
+ icon_name = g_strdup (icon_name);
+ free_icon_name = TRUE;
+ }
+ else
+ icon_name = NULL;
+ }
+ else
+ icon_name = NULL;
+ }
+
+ if (icon_name && !*icon_name)
+ icon_name = NULL;
+
+ /* If we have an empty label and an icon, we set the label to NULL so it is
+ removed. */
+ if (label && !*label && icon_name)
+ {
+ if (free_label)
+ g_free (label);
+ label = NULL;
+ }
+
+ /* Check if we need to rearrange the child widgets, i.e. if we have a label
+ but no label widget or we don't have a label but we do have a label
+ widget. And the same for the icon. */
+ if ((apply_label && ((label && !label_widget) || (!label && label_widget)))
+ || (apply_icon && ((icon_name && !icon_widget) || (!icon_name && icon_widget))))
+ {
+ gb_button_normal_recreate_children (widget, data, label, icon_name);
+
+ gb_button_normal_find_child_widgets (widget, &label_widget,
+ &icon_widget);
+ if (label_widget)
+ glade_util_copy_translation_properties (widget, label_p,
+ label_widget, "GtkLabel::label");
+
+ goto out;
+ }
+
+ /* Just update the current label & icon widgets. */
+ if (apply_label)
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label_widget),
+ label ? label : "");
+
+ if (apply_icon && icon_widget && icon_name)
+ {
+ gchar *old_icon_name;
+
+ /* Remove the old icon_name stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ old_icon_name = gtk_object_get_data (GTK_OBJECT (icon_widget),
+ GladeIconKey);
+ glade_project_remove_pixmap (data->project, old_icon_name);
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ gtk_image_set_from_stock (GTK_IMAGE (icon_widget), icon_name,
+ GTK_ICON_SIZE_BUTTON);
+ }
+ else
+ {
+ gtk_image_set_from_file (GTK_IMAGE (icon_widget), icon_name);
+ glade_project_add_pixmap (data->project, icon_name);
+ }
+
+ gtk_object_set_data_full (GTK_OBJECT (icon_widget), GladeIconKey,
+ g_strdup (icon_name),
+ icon_name ? g_free : NULL);
+ }
+
+ out:
+
+ if (free_label)
+ g_free (label);
+ if (free_icon_name)
+ g_free (icon_name);
+}
+
+
+static void
+gb_button_normal_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data,
+ const gchar *label_p)
+{
+ GtkWidget *label_widget, *icon_widget;
+ gchar *group_string = "", *group_string2 = "", *type, *stock_id;
+ GType widget_type;
+
+ widget_type = G_OBJECT_TYPE (widget);
+ if (widget_type == GTK_TYPE_BUTTON)
+ type = "button";
+ else if (widget_type == GTK_TYPE_TOGGLE_BUTTON)
+ type = "toggle_button";
+ else if (widget_type == GTK_TYPE_CHECK_BUTTON)
+ type = "check_button";
+ else
+ {
+ type = "radio_button";
+ group_string = "NULL, ";
+ group_string2 = "NULL";
+ }
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget), GladeButtonStockIDKey);
+ if (stock_id)
+ {
+ if (G_OBJECT_TYPE (widget) == GTK_TYPE_BUTTON)
+ {
+ source_add (data,
+ " %s = gtk_button_new_from_stock (%s);\n",
+ data->wname, source_make_string (stock_id, FALSE));
+ }
+ else
+ {
+ source_add (data,
+ " %s = gtk_%s_new_with_mnemonic (%s%s);\n"
+ " gtk_button_set_use_stock (GTK_BUTTON (%s), TRUE);\n",
+ data->wname, type, group_string,
+ source_make_string (stock_id, FALSE), data->wname);
+ }
+ }
+ else
+ {
+ gb_button_normal_find_child_widgets (widget, &label_widget,
+ &icon_widget);
+
+ if (label_widget && !icon_widget)
+ {
+ gchar *label_text, *comments;
+ gboolean translatable, context;
+
+ label_text = glade_util_get_label_text (label_widget);
+ glade_util_get_translation_properties (label_widget,
+ "GtkLabel::label",
+ &translatable, &comments,
+ &context);
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data, " %s = gtk_%s_new_with_mnemonic (%s%s);\n",
+ data->wname, type, group_string,
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ g_free (label_text);
+ }
+ else
+ {
+ source_add (data, " %s = gtk_%s_new (%s);\n", data->wname, type,
+ group_string2);
+ }
+ }
+}
+
+
+void
+gb_button_find_radio_group (GtkWidget *widget, GladeFindGroupData *find_data)
+{
+ if (find_data->found_widget)
+ return;
+
+ if (GTK_IS_RADIO_BUTTON (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ if (gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget)) == find_data->group)
+ {
+ find_data->found_widget = widget;
+ return;
+ }
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ gb_widget_children_foreach (widget,
+ (GtkCallback) gb_button_find_radio_group,
+ find_data);
+}
+
+
+/*
+ * GNOME DIALOG BUTTONS. GtkButton only.
+ */
+
+/* This tries to find the child label & icon of the button. If the button
+ contains other widgets it returns FALSE, i.e. if the user has added other
+ widgets instead. */
+static gboolean
+gb_button_gnome_find_child_widgets (GtkWidget *widget,
+ GtkWidget **label,
+ GtkWidget **icon)
+{
+ GtkWidget *child;
+
+ *label = *icon = NULL;
+
+ /* Check it has a child. If it doesn't output a warning. */
+ child = GTK_BIN (widget)->child;
+ g_return_val_if_fail (child != NULL, FALSE);
+
+ /* Check if it has just a GtkLabel child. */
+ if (GTK_IS_LABEL (child))
+ {
+ *label = child;
+ return TRUE;
+ }
+
+ /* Check if it has just a GtkImage child. */
+ if (GTK_IS_IMAGE (child))
+ {
+ *icon = child;
+ return TRUE;
+ }
+
+ /* If it contains an icon and a label it must be a GtkAlignment with a
+ GtkHBox in it. FIXME: GnomeDialog doesn't use a GtkAlignment at present,
+ but we check for it just in case. */
+ if (GTK_IS_ALIGNMENT (child))
+ child = GTK_BIN (child)->child;
+
+ /* GNOME uses a hbox inside a hbox, so check for that. */
+ if (child && GTK_IS_HBOX (child)
+ && g_list_length (GTK_BOX (child)->children) == 1)
+ {
+ GtkBoxChild *hbox_child;
+ hbox_child = GTK_BOX (child)->children->data;
+ child = hbox_child->widget;
+ }
+
+ /* FIXME: Gnome may not show the icon and/or label according to config
+ settings. That may break Glade. */
+
+ /* Now check for a hbox with a GtkImage and GtkLabel children. */
+ if (child && GTK_IS_HBOX (child)
+ && g_list_length (GTK_BOX (child)->children) <= 2)
+ {
+ GList *children;
+ GtkBoxChild *child1, *child2;
+
+ children = GTK_BOX (child)->children;
+ child1 = children->data;
+ child2 = children->next ? children->next->data : NULL;
+
+ if (child1 && child2)
+ {
+ if (GTK_IS_LABEL (child1->widget) && GTK_IS_IMAGE (child2->widget))
+ {
+ *label = child1->widget;
+ *icon = child2->widget;
+ return TRUE;
+ }
+ }
+ else if (GTK_IS_LABEL (child1->widget))
+ {
+ *label = child1->widget;
+ return TRUE;
+ }
+ else if (GTK_IS_IMAGE (child1->widget))
+ {
+ *icon = child1->widget;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static void
+gb_button_gnome_get_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gchar *stock_id, *label_text;
+ gboolean label_sensitive = TRUE;
+ gboolean icon_sensitive = TRUE;
+ GtkWidget *label, *icon;
+
+ /* We only allow the GTK_ICON_SIZE_BUTTON size for stock items & icons. */
+ if (data->action == GB_SHOWING)
+ {
+ property_set_stock_item_icon_size (stock_id_p, GTK_ICON_SIZE_BUTTON);
+ property_set_icon_size (icon_p, GTK_ICON_SIZE_BUTTON);
+ }
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget), GladeButtonStockIDKey);
+ /* In the XML the stock item name is actually saved as the label property,
+ and the use_stock property specifies that it is a stock item.
+ Also, use_underline needs to be set. */
+ if (data->action == GB_SAVING)
+ {
+ if (stock_id)
+ {
+ gb_widget_output_stock_item (data, "label", stock_id);
+ gb_widget_output_bool (data, "use_stock", TRUE);
+ }
+ }
+ else
+ {
+ gb_widget_output_stock_item (data, stock_id_p, stock_id);
+ }
+
+
+ if (stock_id)
+ {
+ label_sensitive = FALSE;
+ icon_sensitive = FALSE;
+ }
+ else
+ {
+ if (gb_button_gnome_find_child_widgets (widget, &label, &icon))
+ {
+ gchar *icon_name = NULL;
+
+ if (label)
+ label_text = (gchar*) gtk_label_get_label (GTK_LABEL (label));
+ else
+ label_text = "";
+
+ gb_widget_output_translatable_text (data, label_p, label_text);
+
+ /* We always save use_underline as TRUE, though we don't load it. */
+ if (data->action == GB_SAVING && !icon)
+ gb_widget_output_bool (data, "use_underline", TRUE);
+
+ if (icon)
+ icon_name = gtk_object_get_data (GTK_OBJECT (icon), GladeIconKey);
+
+ /* We never output the icon when saving, as it will be saved as a
+ child widget. */
+ gb_widget_output_icon (data, icon_p, icon_name);
+ }
+ else
+ {
+ label_sensitive = FALSE;
+ icon_sensitive = FALSE;
+ }
+ }
+
+ if (data->action == GB_SHOWING)
+ {
+ if (!label_sensitive)
+ gb_widget_output_translatable_text (data, label_p, "");
+ property_set_sensitive (label_p, label_sensitive);
+
+ if (!icon_sensitive)
+ gb_widget_output_pixmap_filename (data, icon_p, "");
+ property_set_sensitive (icon_p, icon_sensitive);
+ }
+}
+
+
+static void
+gb_button_gnome_set_stock_id (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gboolean is_stock_item = FALSE;
+ const gchar *label_text = "";
+
+ if (stock_id && stock_id[0])
+ is_stock_item = TRUE;
+
+ if (is_stock_item)
+ {
+ gtk_button_set_use_stock (GTK_BUTTON (widget), TRUE);
+ gtk_button_set_label (GTK_BUTTON (widget), stock_id);
+ gtk_object_set_data_full (GTK_OBJECT (widget), GladeButtonStockIDKey,
+ g_strdup (stock_id), g_free);
+ }
+ else
+ {
+ /* Change the button back to a gnome button with a simple label. */
+ gtk_button_set_use_stock (GTK_BUTTON (widget), FALSE);
+ label_text = gtk_widget_get_name (widget);
+ gtk_button_set_label (GTK_BUTTON (widget), label_text);
+ gtk_object_set_data (GTK_OBJECT (widget), GladeButtonStockIDKey, NULL);
+ }
+
+ /* If the widget's properties are displayed, we update the sensitivity of
+ the label and icon, according to whether a stock item is selected. */
+ if (data->action == GB_APPLYING && property_get_widget () == widget)
+ {
+ property_set_sensitive (label_p, !is_stock_item);
+ property_set_sensitive (icon_p, !is_stock_item);
+
+ /* Turn off auto-apply, and set the label. */
+ property_set_auto_apply (FALSE);
+ property_set_text (label_p, label_text);
+ property_set_filename (icon_p, "");
+ property_set_auto_apply (TRUE);
+ }
+}
+
+
+static void
+gb_button_gnome_recreate_children (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *label, gchar *icon_name)
+{
+ GtkWidget *parent = widget;
+
+ /* Remove any existing children. */
+ if (GTK_BIN (widget)->child)
+ gtk_container_remove (GTK_CONTAINER (widget), GTK_BIN (widget)->child);
+
+ /* If both label and icon are needed, we put them in a hbox, otherwise we
+ just add the label or icon to the button. */
+ if (label && icon_name)
+ {
+ GtkWidget *hbox;
+
+ /* It uses a hbox in a hbox to keep the contents in the center, rather
+ than an alignment like GTK+ does. */
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox);
+ gtk_container_add (GTK_CONTAINER (widget), hbox);
+
+ parent = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (parent);
+ gtk_box_pack_start (GTK_BOX (hbox), parent, TRUE, FALSE, 2);
+ }
+
+ if (label)
+ {
+ GtkWidget *label_widget;
+
+ label_widget = gtk_label_new_with_mnemonic (label);
+ gtk_widget_show (label_widget);
+
+ if (GTK_IS_BOX (parent))
+ gtk_box_pack_end (GTK_BOX (parent), label_widget, FALSE, FALSE, 2);
+ else
+ gtk_container_add (GTK_CONTAINER (parent), label_widget);
+ }
+
+ if (icon_name)
+ {
+ GtkWidget *icon_widget;
+
+ icon_widget = gtk_image_new ();
+
+ gtk_object_set_data_full (GTK_OBJECT (icon_widget), GladeIconKey,
+ g_strdup (icon_name),
+ icon_name ? g_free : NULL);
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ gtk_image_set_from_stock (GTK_IMAGE (icon_widget), icon_name,
+ GTK_ICON_SIZE_BUTTON);
+ }
+ else
+ {
+ gtk_image_set_from_file (GTK_IMAGE (icon_widget), icon_name);
+ glade_project_add_pixmap (data->project, icon_name);
+ }
+ gtk_widget_show (icon_widget);
+
+ if (GTK_IS_BOX (parent))
+ gtk_box_pack_start (GTK_BOX (parent), icon_widget, FALSE, FALSE, 0);
+ else
+ gtk_container_add (GTK_CONTAINER (parent), icon_widget);
+ }
+}
+
+
+void
+gb_button_gnome_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gchar *stock_id = NULL, *label, *icon_name = NULL;
+ gboolean apply_stock_id = FALSE, apply_label, apply_icon;
+ gboolean free_label = FALSE, free_icon_name = FALSE;
+ GtkWidget *label_widget, *icon_widget;
+
+ label = gb_widget_input_text (data, label_p);
+ apply_label = data->apply;
+ if (data->action == GB_APPLYING)
+ free_label = TRUE;
+
+ /* When loading, if "use_stock" is TRUE, then the label is the stock item. */
+ if (data->action == GB_LOADING)
+ {
+ gboolean is_stock_item = gb_widget_input_bool (data, "use_stock");
+ if (is_stock_item)
+ {
+ stock_id = label;
+ apply_stock_id = apply_label;
+ }
+ }
+ else
+ {
+ stock_id = gb_widget_input_stock_item (data, stock_id_p);
+ apply_stock_id = data->apply;
+ }
+
+ if (apply_stock_id)
+ {
+ gb_button_gnome_set_stock_id (widget, data, stock_id, label_p, icon_p);
+ goto out;
+ }
+
+ icon_name = gb_widget_input_icon (data, icon_p);
+ apply_icon = data->apply;
+
+ /* If neither icon nor label is set, we don't touch the button as it may
+ have other child widgets. */
+ if (!apply_label && !apply_icon)
+ return;
+
+ gb_button_gnome_find_child_widgets (widget, &label_widget,
+ &icon_widget);
+
+ if (!apply_label)
+ {
+ if (label_widget)
+ {
+ label = g_strdup (gtk_label_get_label (GTK_LABEL (label_widget)));
+ free_label = TRUE;
+ }
+ else
+ label = NULL;
+ }
+
+ if (!apply_icon)
+ {
+ if (icon_widget)
+ {
+ icon_name = gtk_object_get_data (GTK_OBJECT (icon_widget),
+ GladeIconKey);
+ if (icon_name && *icon_name)
+ {
+ icon_name = g_strdup (icon_name);
+ free_icon_name = TRUE;
+ }
+ else
+ icon_name = NULL;
+ }
+ else
+ icon_name = NULL;
+ }
+
+ if (icon_name && !*icon_name)
+ icon_name = NULL;
+
+ /* If we have an empty label and an icon, we set the label to NULL so it is
+ removed. */
+ if (label && !*label && icon_name)
+ {
+ if (free_label)
+ g_free (label);
+ label = NULL;
+ }
+
+ /* Check if we need to rearrange the child widgets, i.e. if we have a label
+ but no label widget or we don't have a label but we do have a label
+ widget. And the same for the icon. */
+ if ((apply_label && ((label && !label_widget) || (!label && label_widget)))
+ || (apply_icon && ((icon_name && !icon_widget) || (!icon_name && icon_widget))))
+ {
+ gb_button_gnome_recreate_children (widget, data, label, icon_name);
+
+ goto out;
+ }
+
+ /* Just update the current label & icon widgets. */
+ if (apply_label)
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label_widget),
+ label ? label : "");
+
+ if (apply_icon && icon_widget && icon_name)
+ {
+ gchar *old_icon_name;
+
+ /* Remove the old icon_name stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ old_icon_name = gtk_object_get_data (GTK_OBJECT (icon_widget),
+ GladeIconKey);
+ glade_project_remove_pixmap (data->project, old_icon_name);
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ gtk_image_set_from_stock (GTK_IMAGE (icon_widget), icon_name,
+ GTK_ICON_SIZE_BUTTON);
+ }
+ else
+ {
+ gtk_image_set_from_file (GTK_IMAGE (icon_widget), icon_name);
+ glade_project_add_pixmap (data->project, icon_name);
+ }
+
+ gtk_object_set_data_full (GTK_OBJECT (icon_widget), GladeIconKey,
+ g_strdup (icon_name),
+ icon_name ? g_free : NULL);
+ }
+
+ out:
+
+ if (free_label)
+ g_free (label);
+ if (free_icon_name)
+ g_free (icon_name);
+}
+
+
+static void
+gb_button_gnome_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data,
+ const gchar *label_p)
+{
+ gchar *stock_id;
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, label_p, &translatable,
+ &comments, &context);
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget), GladeButtonStockIDKey);
+ if (stock_id)
+ {
+ source_add (data,
+ " gnome_dialog_append_button (GNOME_DIALOG (%s), %s);\n",
+ data->component_name,
+ source_make_string (stock_id, FALSE));
+ }
+ else
+ {
+ GtkWidget *label, *icon;
+ gchar *label_text = NULL;
+
+ gb_button_gnome_find_child_widgets (widget, &label, &icon);
+
+ if (label)
+ label_text = glade_util_get_label_text (label);
+
+ if (icon)
+ {
+ gchar *icon_id;
+
+ icon_id = gtk_object_get_data (GTK_OBJECT (icon), GladeIconKey);
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gnome_dialog_append_button_with_pixmap (GNOME_DIALOG (%s),\n"
+ " %s, ",
+ data->component_name,
+ label_text ? source_make_string_full (label_text, data->use_gettext && translatable, context) : "");
+
+ source_add (data,
+ "%s);\n",
+ source_make_string (icon_id, FALSE));
+ }
+ else
+ {
+ source_add (data,
+ " gnome_dialog_append_button (GNOME_DIALOG (%s), %s);\n",
+ data->component_name,
+ label_text ? source_make_string (label_text, FALSE) : "");
+ }
+
+ g_free (label_text);
+ }
+
+ /* We want to get a pointer to the widget so we can output the standard
+ source, in case handlers have been added to the buttons.
+ We can just get the last widget in the GnomeDialog's list of buttons.
+ Note that we have to make sure that the button isn't added to its
+ parent widget again elsewhere. */
+ source_add (data, " %s = GTK_WIDGET (g_list_last (GNOME_DIALOG (%s)->buttons)->data);\n",
+ data->wname, data->component_name);
+
+ /* We set this to FALSE, so the code to add it to its parent is skipped. */
+ data->create_widget = FALSE;
+}
+
+
+
+
+
+
+/*
+ * GbButton functions.
+ */
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+void
+gb_button_get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *relief_p,
+ gchar *focus_on_click_p)
+{
+ GladeButtonType button_type;
+ gboolean relief_visible = TRUE, icon_file_selection = TRUE;
+ gint i;
+
+ button_type = gb_button_get_button_type (widget);
+
+ switch (button_type)
+ {
+ case GLADE_BUTTON_NORMAL:
+ gb_button_normal_get_properties (widget, data, stock_id_p, label_p,
+ icon_p);
+ break;
+ case GLADE_BUTTON_DIALOG:
+ gb_button_normal_get_properties (widget, data, stock_id_p, label_p,
+ icon_p);
+ break;
+ case GLADE_BUTTON_GNOME_DIALOG:
+ gb_button_gnome_get_properties (widget, data, stock_id_p, label_p,
+ icon_p);
+ /* Gnome dialog buttons can only have stock icons. */
+ icon_file_selection = FALSE;
+ break;
+ }
+
+ /* Handle the Relief property here, as it is simple. */
+ if (data->action == GB_SHOWING)
+ {
+ property_set_visible (relief_p, relief_visible);
+ property_set_icon_filesel (icon_p, icon_file_selection);
+ }
+
+ if (relief_visible)
+ {
+ for (i = 0; i < GladeReliefChoicesSize; i++)
+ {
+ if (GladeReliefValues[i] == GTK_BUTTON (widget)->relief)
+ gb_widget_output_choice (data, relief_p, i, GladeReliefSymbols[i]);
+ }
+ }
+
+ if (focus_on_click_p)
+ gb_widget_output_bool (data, focus_on_click_p,
+ gtk_button_get_focus_on_click (GTK_BUTTON (widget)));
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_button_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GladeButtonType button_type;
+ gboolean response_id_visible = FALSE;
+
+ gb_button_get_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ /* Handle the response id for dialog buttons here. */
+ button_type = gb_button_get_button_type (widget);
+ if (button_type == GLADE_BUTTON_DIALOG)
+ {
+ gint response_id;
+
+ response_id_visible = TRUE;
+
+ response_id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), GladeDialogResponseIDKey));
+ /* We save as an int, but show as a string. */
+ if (data->action == GB_SHOWING)
+ {
+ property_set_combo (ResponseID,
+ gb_dialog_response_id_to_string (response_id));
+ }
+ else
+ {
+ save_int (data, ResponseID, response_id);
+ }
+ }
+
+ if (data->action == GB_SHOWING)
+ property_set_visible (ResponseID, response_id_visible);
+}
+
+
+void
+gb_button_set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *relief_p,
+ gchar *focus_on_click_p)
+{
+ GladeButtonType button_type;
+ gchar *relief;
+ gint i;
+
+ button_type = gb_button_get_button_type (widget);
+
+ switch (button_type)
+ {
+ case GLADE_BUTTON_NORMAL:
+ gb_button_normal_set_properties (widget, data, stock_id_p, label_p,
+ icon_p);
+ break;
+ case GLADE_BUTTON_DIALOG:
+ gb_button_normal_set_properties (widget, data, stock_id_p, label_p,
+ icon_p);
+ break;
+ case GLADE_BUTTON_GNOME_DIALOG:
+ gb_button_gnome_set_properties (widget, data, stock_id_p, label_p,
+ icon_p);
+ break;
+ }
+
+ /* Handle the Relief property here, as it is simple. */
+ relief = gb_widget_input_choice (data, relief_p);
+ if (data->apply)
+ {
+ for (i = 0; i < GladeReliefChoicesSize; i++)
+ {
+ if (!strcmp (relief, GladeReliefChoices[i])
+ || !strcmp (relief, GladeReliefSymbols[i]))
+ {
+ gtk_button_set_relief (GTK_BUTTON (widget),
+ GladeReliefValues[i]);
+ break;
+ }
+ }
+ }
+
+ if (focus_on_click_p)
+ {
+ gboolean focus_on_click;
+
+ focus_on_click = gb_widget_input_bool (data, focus_on_click_p);
+ if (data->apply)
+ gtk_button_set_focus_on_click (GTK_BUTTON (widget), focus_on_click);
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GladeButtonType button_type;
+ gchar *old_stock_id, *stock_id;
+ gboolean set_response_id = FALSE;
+
+ /* Remember the old stock id. */
+ old_stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeButtonStockIDKey);
+
+ gb_button_set_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ /* Handle the response id for dialog buttons here. */
+ button_type = gb_button_get_button_type (widget);
+ if (button_type == GLADE_BUTTON_DIALOG)
+ {
+ gint response_id = 0;
+
+ /* See if the stock id has been changed. Note that we only compare the
+ pointers, since the old string will have been freed. If the stock id
+ has been changed and is set, we use the corresponding response id,
+ unless it is also being set. */
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeButtonStockIDKey);
+ if (data->action == GB_APPLYING && stock_id && stock_id != old_stock_id)
+ {
+ int i;
+
+ for (i = 0; i < GladeStockResponsesSize; i++)
+ {
+ if (GladeStockResponses[i].stock_id
+ && !strcmp (GladeStockResponses[i].stock_id, stock_id))
+ {
+ response_id = GladeStockResponses[i].response_id;
+ set_response_id = TRUE;
+ break;
+ }
+ }
+ }
+
+
+ /* We save as an int, but show as a string. */
+ if (data->action == GB_LOADING)
+ {
+ response_id = gb_widget_input_int (data, ResponseID);
+ }
+ else
+ {
+ char *response_name = gb_widget_input_combo (data, ResponseID);
+ if (data->apply)
+ response_id = gb_dialog_response_id_from_string (response_name);
+ }
+
+ if (data->apply || set_response_id)
+ {
+ gboolean secondary = FALSE;
+
+ gtk_object_set_data (GTK_OBJECT (widget), GladeDialogResponseIDKey,
+ GINT_TO_POINTER (response_id));
+
+ if (response_id == GTK_RESPONSE_HELP)
+ secondary = TRUE;
+ gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (widget->parent),
+ widget, secondary);
+ }
+
+ /* If we are setting the response id as a result of a change of stock
+ id, then we set the field in the property editor now. */
+ if (property_get_widget () == widget && set_response_id)
+ {
+ char *old_response_id, *new_response_id;
+
+ old_response_id = property_get_combo (ResponseID, NULL, NULL);
+ new_response_id = gb_dialog_response_id_to_string (response_id);
+
+ if (strcmp (new_response_id, old_response_id))
+ {
+ property_set_auto_apply (FALSE);
+ property_set_combo (ResponseID, new_response_id);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ }
+}
+
+
+static void
+gb_button_remove_contents (GtkWidget * menuitem,
+ GtkWidget * widget)
+{
+ GtkWidget *child;
+
+ g_return_if_fail (GTK_IS_BIN (widget));
+
+ child = GTK_BIN (widget)->child;
+ if (child && !GB_IS_PLACEHOLDER (child))
+ editor_delete_widget (child);
+
+ /* Reset the stock_id key. */
+ gtk_object_set_data (GTK_OBJECT (widget), GladeButtonStockIDKey, NULL);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkButton, with signals pointing to
+ * other functions in this file.
+ */
+void
+gb_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *child;
+
+ /* If the button's child isn't a placeholder, add a command to remove the
+ button's contents. */
+ child = GTK_BIN (widget)->child;
+ if (child && !GB_IS_PLACEHOLDER (child))
+ {
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_label (_("Remove Button Contents"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_button_remove_contents), widget);
+ }
+}
+
+
+void
+gb_button_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data,
+ const gchar *label_p)
+{
+ GladeButtonType button_type;
+ gboolean set_relief = TRUE;
+ gint i;
+
+ if (data->create_widget)
+ {
+ button_type = gb_button_get_button_type (widget);
+
+ switch (button_type)
+ {
+ case GLADE_BUTTON_NORMAL:
+ gb_button_normal_write_source (widget, data, label_p);
+ break;
+ case GLADE_BUTTON_DIALOG:
+ gb_button_normal_write_source (widget, data, label_p);
+ break;
+ case GLADE_BUTTON_GNOME_DIALOG:
+ gb_button_gnome_write_source (widget, data, label_p);
+ break;
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (set_relief && GTK_BUTTON (widget)->relief != GTK_RELIEF_NORMAL)
+ {
+ for (i = 0; i < GladeReliefChoicesSize; i++)
+ {
+ if (GladeReliefValues[i] == GTK_BUTTON (widget)->relief)
+ source_add (data,
+ " gtk_button_set_relief (GTK_BUTTON (%s), %s);\n",
+ data->wname, GladeReliefSymbols[i]);
+ }
+ }
+
+ if (!gtk_button_get_focus_on_click (GTK_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_button_set_focus_on_click (GTK_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gb_button_write_standard_source (widget, data, Label);
+}
+
+
+/* Note that Check/Radio/Toggle buttons use this function as well. */
+void
+gb_button_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ gchar *filename;
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), GladeIconKey);
+ glade_project_remove_pixmap (data->project, filename);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_button_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = button_xpm;
+ gbwidget.tooltip = _("Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_button_new;
+ gbwidget.gb_widget_create_properties = gb_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_button_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_button_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_button_write_source;
+ gbwidget.gb_widget_destroy = gb_button_destroy;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcalendar.c b/tools/glade/glade/gbwidgets/gbcalendar.c
new file mode 100644
index 00000000..46763bb5
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcalendar.c
@@ -0,0 +1,280 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * calendar gbWidget Copyright (c) 1999 Jay Johnston
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkcalendar.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/calendar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *ShowHeading = "GtkCalendar::show_heading";
+static gchar *ShowDayNames = "GtkCalendar::show_day_names";
+static gchar *NoMonthChange = "GtkCalendar::no_month_change";
+static gchar *ShowWeekNumbers = "GtkCalendar::show_week_numbers";
+static gchar *WeekStartMonday = "GtkCalendar::week_start_monday";
+
+/* When saving, we save all 5 boolean flags in this property. */
+static gchar *DisplayOptions = "GtkCalendar::display_options";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCalendar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_calendar_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget = NULL;
+
+ new_widget = gtk_calendar_new();
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+
+static void
+gb_calendar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (ShowHeading, _("Heading:"),
+ _("If the month and year should be shown at the top"));
+ property_add_bool (ShowDayNames, _("Day Names:"),
+ _("If the day names should be shown"));
+ property_add_bool (NoMonthChange, _("Fixed Month:"),
+ _("If the month and year shouldn't be changeable"));
+ property_add_bool (ShowWeekNumbers, _("Week Numbers:"),
+ _("If the number of the week should be shown"));
+ property_add_bool (WeekStartMonday, _("Monday First:"),
+ _("If the week should start on Monday"));
+}
+
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+
+static void
+gb_calendar_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkCalendarDisplayOptions options;
+
+ options = GTK_CALENDAR (widget)->display_flags;
+
+ /* We save all 5 boolean toggles as one property. */
+ if (data->action == GB_SAVING) {
+ char *s = glade_util_string_from_flags (GTK_TYPE_CALENDAR_DISPLAY_OPTIONS,
+ options);
+ gb_widget_output_string (data, DisplayOptions, s);
+ g_free (s);
+ } else {
+ gb_widget_output_bool (data, ShowHeading,
+ options & GTK_CALENDAR_SHOW_HEADING);
+ gb_widget_output_bool (data, ShowDayNames,
+ options & GTK_CALENDAR_SHOW_DAY_NAMES);
+ gb_widget_output_bool (data, NoMonthChange,
+ options & GTK_CALENDAR_NO_MONTH_CHANGE);
+ gb_widget_output_bool (data, ShowWeekNumbers,
+ options & GTK_CALENDAR_SHOW_WEEK_NUMBERS);
+ gb_widget_output_bool (data, WeekStartMonday,
+ options & GTK_CALENDAR_WEEK_START_MONDAY);
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+
+static void
+gb_calendar_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GtkCalendarDisplayOptions options;
+ gboolean value;
+
+ options = GTK_CALENDAR (widget)->display_flags;
+
+ /* We load all 5 boolean toggles as one property. */
+ if (data->action == GB_LOADING) {
+ char *s = gb_widget_input_string (data, DisplayOptions);
+ if (data->apply)
+ options = glade_util_flags_from_string (GTK_TYPE_CALENDAR_DISPLAY_OPTIONS, s);
+ } else {
+ value = gb_widget_input_bool (data, ShowHeading)
+ ? GTK_CALENDAR_SHOW_HEADING : 0;
+ if (data->apply)
+ options = (options & ~GTK_CALENDAR_SHOW_HEADING) | value;
+
+ value = gb_widget_input_bool (data, ShowDayNames)
+ ? GTK_CALENDAR_SHOW_DAY_NAMES : 0;
+ if (data->apply)
+ options = (options & ~GTK_CALENDAR_SHOW_DAY_NAMES) | value;
+
+ value = gb_widget_input_bool (data, NoMonthChange)
+ ? GTK_CALENDAR_NO_MONTH_CHANGE : 0;
+ if (data->apply)
+ options = (options & ~GTK_CALENDAR_NO_MONTH_CHANGE) | value;
+
+ value = gb_widget_input_bool (data, ShowWeekNumbers)
+ ? GTK_CALENDAR_SHOW_WEEK_NUMBERS : 0;
+ if (data->apply)
+ options = (options & ~GTK_CALENDAR_SHOW_WEEK_NUMBERS) | value;
+
+ value = gb_widget_input_bool (data, WeekStartMonday)
+ ? GTK_CALENDAR_WEEK_START_MONDAY : 0;
+ if (data->apply)
+ options = (options & ~GTK_CALENDAR_WEEK_START_MONDAY) | value;
+ }
+
+ if (options != GTK_CALENDAR (widget)->display_flags)
+ gtk_calendar_display_options (GTK_CALENDAR (widget), options);
+}
+
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCalendar, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_calendar_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+ {
+
+ }
+*/
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+
+static void
+gb_calendar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkCalendarDisplayOptions options = 0;
+ const gchar *prefix = "\n ";
+ const gchar *prefix2 = "\n | ";
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_calendar_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ source_add (data, " gtk_calendar_display_options (GTK_CALENDAR (%s),",
+ data->wname);
+
+ options = GTK_CALENDAR (widget)->display_flags;
+ if (options)
+ {
+ if (options & GTK_CALENDAR_SHOW_HEADING)
+ {
+ source_add (data, "%sGTK_CALENDAR_SHOW_HEADING", prefix);
+ prefix = prefix2;
+ }
+
+ if (options & GTK_CALENDAR_SHOW_DAY_NAMES)
+ {
+ source_add (data, "%sGTK_CALENDAR_SHOW_DAY_NAMES", prefix);
+ prefix = prefix2;
+ }
+
+ if (options & GTK_CALENDAR_NO_MONTH_CHANGE)
+ {
+ source_add (data, "%sGTK_CALENDAR_NO_MONTH_CHANGE", prefix);
+ prefix = prefix2;
+ }
+
+ if (options & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
+ {
+ source_add (data, "%sGTK_CALENDAR_SHOW_WEEK_NUMBERS", prefix);
+ prefix = prefix2;
+ }
+
+ if (options & GTK_CALENDAR_WEEK_START_MONDAY)
+ {
+ source_add (data, "%sGTK_CALENDAR_WEEK_START_MONDAY", prefix);
+ }
+ source_add (data, ");\n");
+ }
+ else
+ source_add (data, " 0);\n");
+}
+
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_calendar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_calendar_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = calendar_xpm;
+ gbwidget.tooltip = _("Calendar");
+
+ /* Fill in any functions that this GbWidget has */
+
+ gbwidget.gb_widget_new = gb_calendar_new;
+ gbwidget.gb_widget_create_properties = gb_calendar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_calendar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_calendar_set_properties;
+ /* gbwidget.gb_widget_create_popup_menu = gb_calendar_create_popup_menu; */
+ gbwidget.gb_widget_write_source = gb_calendar_write_source;
+
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbcellview.c b/tools/glade/glade/gbwidgets/gbcellview.c
new file mode 100644
index 00000000..6f4a09f3
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcellview.c
@@ -0,0 +1,206 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/cellview.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *BackgroundColor = "GtkCellView::background";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCellView, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_cell_view_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_cell_view_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_color (BackgroundColor, _("Back. Color:"),
+ _("The background color"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_cell_view_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gboolean background_set;
+ GdkColor *background_color;
+
+ g_object_get (G_OBJECT (widget),
+ "background_set", &background_set,
+ "background_gdk", &background_color,
+ NULL);
+
+ /* If the background color isn't currently set, set it to black just to
+ make sure we don't get a random color. */
+ if (!background_set) {
+ background_color->red = 0;
+ background_color->green = 0;
+ background_color->blue = 0;
+ }
+
+ if (data->action == GB_SHOWING || background_set)
+ gb_widget_output_color (data, BackgroundColor, background_color);
+
+ gdk_color_free (background_color);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_cell_view_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GdkColor *color;
+
+ color = gb_widget_input_color (data, BackgroundColor);
+ if (data->apply)
+ {
+ gtk_cell_view_set_background_color (GTK_CELL_VIEW (widget), color);
+ gtk_widget_queue_draw (widget);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCellView, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_cell_view_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_cell_view_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean background_set;
+ GdkColor *background_color;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_cell_view_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ g_object_get (G_OBJECT (widget),
+ "background_set", &background_set,
+ "background_gdk", &background_color,
+ NULL);
+
+ if (background_set)
+ {
+ source_add_decl (data,
+ " GdkColor %s_bg_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ background_color->red, background_color->green,
+ background_color->blue);
+
+ source_add (data,
+ " gtk_cell_view_set_background_color (GTK_CELL_VIEW (%s), &%s_bg_color);\n",
+ data->wname, data->wname);
+ }
+
+ gdk_color_free (background_color);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_cell_view_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_cell_view_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = cellview_xpm;
+ gbwidget.tooltip = _("Cell View");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_cell_view_create_properties;
+ gbwidget.gb_widget_get_properties = gb_cell_view_get_properties;
+ gbwidget.gb_widget_set_properties = gb_cell_view_set_properties;
+ gbwidget.gb_widget_write_source = gb_cell_view_write_source;
+/*
+ gbwidget.gb_widget_new = gb_cell_view_new;
+ gbwidget.gb_widget_create_popup_menu = gb_cell_view_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbcheckbutton.c b/tools/glade/glade/gbwidgets/gbcheckbutton.c
new file mode 100644
index 00000000..05a30134
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcheckbutton.c
@@ -0,0 +1,223 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtklabel.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/checkbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "CheckButton|GtkButton::stock_button";
+static gchar *Label = "CheckButton|GtkButton::label";
+static gchar *Icon = "CheckButton|GtkButton::icon";
+static gchar *FocusOnClick = "CheckButton|GtkButton::focus_on_click";
+
+/* This is only used for normal/stock buttons, not special toolbar buttons,
+ as the toolbar has its own relief setting. */
+static gchar *Relief = "CheckButton|GtkButton::relief";
+
+static gchar *State = "CheckButton|GtkToggleButton::active";
+static gchar *Inconsistent = "CheckButton|GtkToggleButton::inconsistent";
+static gchar *Indicator = "CheckButton|GtkToggleButton::draw_indicator";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCheckButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_check_button_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_check_button_new_with_label (data->name);
+ else
+ {
+ new_widget = gtk_check_button_new ();
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder());
+ }
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_check_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_choice (Relief, _("Button Relief:"),
+ _("The relief style of the button"),
+ GladeReliefChoices);
+
+ property_add_bool (State, _("Initially On:"),
+ _("If the check button is initially on"));
+ property_add_bool (Inconsistent, _("Inconsistent:"),
+ _("If the button is shown in an inconsistent state"));
+ property_add_bool (Indicator, _("Indicator:"),
+ _("If the indicator is always drawn"));
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_check_button_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_button_get_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ gb_widget_output_bool (data, State, data->widget_data->flags & GLADE_ACTIVE);
+ gb_widget_output_bool (data, Inconsistent,
+ GTK_TOGGLE_BUTTON (widget)->inconsistent);
+ gb_widget_output_bool (data, Indicator,
+ GTK_TOGGLE_BUTTON (widget)->draw_indicator);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_check_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean state, indicator, inconsistent;
+
+ gb_button_set_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ state = gb_widget_input_bool (data, State);
+ if (data->apply)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), state);
+ if (state)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+
+ inconsistent = gb_widget_input_bool (data, Inconsistent);
+ if (data->apply)
+ gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (widget),
+ inconsistent);
+
+ indicator = gb_widget_input_bool (data, Indicator);
+ if (data->apply)
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (widget), indicator);
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_check_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gb_button_write_standard_source (widget, data, Label);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (GTK_TOGGLE_BUTTON (widget)->inconsistent)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!GTK_TOGGLE_BUTTON (widget)->draw_indicator)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_check_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_check_button_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = checkbutton_xpm;
+ gbwidget.tooltip = _("Check Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_check_button_new;
+ gbwidget.gb_widget_create_properties = gb_check_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_check_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_check_button_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_button_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_check_button_write_source;
+ gbwidget.gb_widget_destroy = gb_button_destroy;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcheckmenuitem.c b/tools/glade/glade/gbwidgets/gbcheckmenuitem.c
new file mode 100644
index 00000000..c58c0937
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcheckmenuitem.c
@@ -0,0 +1,214 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkcheckmenuitem.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenu.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/checkmenuitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "CheckMenuItem|GtkItem::label";
+static gchar *State = "GtkCheckMenuItem::active";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCheckMenuItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_check_menu_item_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_check_menu_item_new_with_label (data->name);
+ else
+ new_widget = gtk_check_menu_item_new ();
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_check_menu_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_bool (State, _("Initially On:"),
+ _("If the check menu item is initially on"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_check_menu_item_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_child_label (widget, data, Label);
+
+ gb_widget_output_bool (data, State, data->widget_data->flags & GLADE_ACTIVE);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_check_menu_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean state;
+
+ gb_widget_input_child_label (widget, data, Label);
+
+ state = gb_widget_input_bool (data, State);
+ if (data->apply)
+ {
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), state);
+ if (state)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCheckMenuItem, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_check_menu_item_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data)
+{
+ /* Add command to remove child label. */
+#if 0
+ gb_widget_create_child_label_popup_menu (widget, data);
+#endif
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_check_menu_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData *
+ data)
+{
+ GtkWidget *child = GTK_BIN (widget)->child;
+ gchar *label_text;
+ gboolean translatable, context;
+ gchar *comments;
+
+#ifdef USE_GNOME
+ if (data->project->gnome_support)
+ {
+ glade_gnome_write_menu_item_source (GTK_MENU_ITEM (widget), data);
+ return;
+ }
+#endif
+
+ if (child && GTK_IS_LABEL (child) && !GB_IS_GB_WIDGET (child))
+ {
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ label_text = glade_util_get_label_text (child);
+ source_add (data,
+ " %s = gtk_check_menu_item_new_with_mnemonic (%s);\n",
+ data->wname,
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ g_free (label_text);
+ }
+ else
+ {
+ source_add (data, " %s = gtk_check_menu_item_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_check_menu_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_check_menu_item_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = checkmenuitem_xpm;
+ gbwidget.tooltip = _("Check Menu Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_check_menu_item_new;
+ gbwidget.gb_widget_create_properties = gb_check_menu_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_check_menu_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_check_menu_item_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_check_menu_item_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_check_menu_item_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbclist.c b/tools/glade/glade/gbwidgets/gbclist.c
new file mode 100644
index 00000000..d52ef9bc
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbclist.c
@@ -0,0 +1,610 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gtk/gtkclist.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/clist.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Mode = "GtkCList::selection_mode";
+static gchar *Titles = "GtkCList::show_titles";
+static gchar *Shadow = "GtkCList::shadow_type";
+
+/* This is only used for loading & saving - it isn't displayed in the property
+ editor. */
+static gchar *Cols = "GtkCList::n_columns";
+static gchar *ColumnWidths = "GtkCList::column_widths";
+
+static const gchar *GbModeChoices[] =
+{"Single", "Browse", "Multiple", NULL};
+static const gint GbModeValues[] =
+{
+ GTK_SELECTION_SINGLE,
+ GTK_SELECTION_BROWSE,
+ GTK_SELECTION_MULTIPLE
+};
+static const gchar *GbModeSymbols[] =
+{
+ "GTK_SELECTION_SINGLE",
+ "GTK_SELECTION_BROWSE",
+ "GTK_SELECTION_MULTIPLE"
+};
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+
+static void show_clist_dialog (GbWidgetNewData * data);
+static void on_clist_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_clist_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+static GtkWidget *new_label (GtkWidget * parent);
+static GtkWidget *new_unnamed_label (GtkWidget * parent);
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCList, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_clist_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ gint cols = 0, i;
+
+ if (data->action == GB_LOADING)
+ {
+ cols = load_int (data->loading_data, Cols);
+ if (cols == 0)
+ cols = 1;
+ new_widget = gtk_clist_new (cols);
+
+ /* GtkCList has problems if the title buttons aren't created. */
+ for (i = 0; i < cols; i++)
+ {
+ gtk_clist_set_column_widget (GTK_CLIST (new_widget), i,
+ new_unnamed_label (new_widget));
+ gtk_clist_set_column_width (GTK_CLIST (new_widget), i, 80);
+ editor_add_mouse_signals_to_existing (GTK_CLIST (new_widget)->column[i].button);
+ }
+
+ return new_widget;
+ }
+ else
+ {
+ show_clist_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_clist_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New columned list"), data->parent,
+ GTK_SIGNAL_FUNC (on_clist_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_clist_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of columns:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "cols",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_clist_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *dialog, *label;
+ gint cols, i;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (dialog), "cols");
+ g_return_if_fail (spinbutton != NULL);
+ cols = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_clist_new (cols);
+ gtk_clist_column_titles_show (GTK_CLIST (new_widget));
+ for (i = 0; i < cols; i++)
+ {
+ label = new_label (new_widget);
+ gtk_clist_set_column_widget (GTK_CLIST (new_widget), i,
+ label);
+ gtk_clist_set_column_width (GTK_CLIST (new_widget), i, 80);
+ }
+
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (dialog);
+}
+
+
+static void
+on_clist_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+GtkWidget *
+new_label (GtkWidget * parent)
+{
+ GtkWidget *label;
+
+ label = gb_widget_new ("GtkLabel", parent);
+ g_return_val_if_fail (label != NULL, NULL);
+ gb_widget_set_child_name (label, GladeChildCListTitle);
+ return label;
+}
+
+
+GtkWidget *
+new_unnamed_label (GtkWidget * parent)
+{
+ GtkWidget *label;
+
+ label = gb_widget_new_full ("GtkLabel", FALSE, parent, NULL, 0, 0, NULL,
+ GB_CREATING, NULL);
+ g_return_val_if_fail (label != NULL, NULL);
+ gb_widget_set_child_name (label, GladeChildCListTitle);
+ return label;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_clist_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Mode, _("Select Mode:"),
+ _("The selection mode of the columned list"),
+ GbModeChoices);
+ property_add_bool (Titles, _("Show Titles:"),
+ _("If the column titles are shown"));
+ property_add_choice (Shadow, _("Shadow:"),
+ _("The type of shadow of the columned list's border"),
+ GbShadowChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_clist_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gchar buffer[1024];
+ gchar *pos;
+ gboolean buffer_overrun = FALSE;
+ gint i;
+
+ if (data->action == GB_SAVING)
+ {
+ gb_widget_output_int (data, Cols, GTK_CLIST (widget)->columns);
+
+ pos = buffer;
+ for (i = 0; i < GTK_CLIST (widget)->columns; i++)
+ {
+ if (i == 0)
+ sprintf (pos, "%i", GTK_CLIST (widget)->column[i].width);
+ else
+ sprintf (pos, ",%i", GTK_CLIST (widget)->column[i].width);
+ pos += strlen (pos);
+
+ /* Extra check to make sure we don't overrun the buffer. */
+ if (pos - buffer > 1000)
+ {
+ g_warning ("Buffer overflow");
+ buffer_overrun = TRUE;
+ break;
+ }
+ }
+ if (!buffer_overrun)
+ gb_widget_output_string (data, ColumnWidths, buffer);
+ }
+
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == GTK_CLIST (widget)->selection_mode)
+ gb_widget_output_choice (data, Mode, i, GbModeSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Titles, GTK_CLIST_SHOW_TITLES (widget));
+
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == GTK_CLIST (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GbShadowSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_clist_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *widths, *pos, *mode;
+ gchar *shadow;
+ gboolean titles;
+ gint col, w, i;
+
+ if (data->action == GB_LOADING)
+ {
+ widths = gb_widget_input_string (data, ColumnWidths);
+ if (data->apply)
+ {
+ pos = widths;
+ for (col = 0; col < GTK_CLIST (widget)->columns; col++)
+ {
+ w = atoi (pos);
+ gtk_clist_set_column_width (GTK_CLIST (widget), col, w);
+ pos = strchr (pos, ',');
+ if (!pos)
+ break;
+ pos++;
+ }
+ }
+ }
+
+ mode = gb_widget_input_choice (data, Mode);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (!strcmp (mode, GbModeChoices[i])
+ || !strcmp (mode, GbModeSymbols[i]))
+ {
+ gtk_clist_set_selection_mode (GTK_CLIST (widget), GbModeValues[i]);
+ break;
+ }
+ }
+ }
+
+ titles = gb_widget_input_bool (data, Titles);
+ if (data->apply)
+ {
+ if (titles)
+ gtk_clist_column_titles_show (GTK_CLIST (widget));
+ else
+ gtk_clist_column_titles_hide (GTK_CLIST (widget));
+ }
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ gtk_clist_set_shadow_type (GTK_CLIST (widget),
+ GbShadowValues[i]);
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCList, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_clist_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+void
+gb_clist_add_child (GtkWidget *widget, GtkWidget *child, GbWidgetSetArgData *data)
+{
+ /* We store the last column title read in 'last_child' */
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ "last_child"));
+
+ if (col >= GTK_CLIST (widget)->columns) {
+ g_warning ("Too many column title widgets for GtkCList - skipping");
+ return;
+ }
+
+ gtk_clist_set_column_widget (GTK_CLIST (widget), col, child);
+ gtk_object_set_data (GTK_OBJECT (widget), "last_child",
+ GINT_TO_POINTER (col + 1));
+
+ /* We need to add signals to the clist button, just in case the
+ title widget has no window and so doesn't get signals itself.
+ Since Clist always creates 1 button initially, the signals would
+ be added to this button in gb_widget_new, so we could skip it,
+ but it doesn't hurt. */
+ editor_add_mouse_signals_to_existing (GTK_CLIST (widget)->column[col].button);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_clist_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint col, i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_clist_new (%i);\n", data->wname,
+ GTK_CLIST (widget)->columns);
+ }
+
+ /* We reset the last_child index, so as the title widgets are written out
+ they will start at column 0. */
+ gtk_object_set_data (GTK_OBJECT (widget), "last_child",
+ GINT_TO_POINTER (-1));
+
+ gb_widget_write_standard_source (widget, data);
+
+ for (col = 0; col < GTK_CLIST (widget)->columns; col++)
+ {
+ source_add (data,
+ " gtk_clist_set_column_width (GTK_CLIST (%s), %i, %i);\n",
+ data->wname, col, GTK_CLIST (widget)->column[col].width);
+ }
+
+ if (GTK_CLIST (widget)->selection_mode != GTK_SELECTION_SINGLE)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == GTK_CLIST (widget)->selection_mode)
+ source_add (data,
+ " gtk_clist_set_selection_mode (GTK_CLIST (%s), %s);\n",
+ data->wname, GbModeSymbols[i]);
+ }
+ }
+
+ if (GTK_CLIST_SHOW_TITLES (widget))
+ source_add (data, " gtk_clist_column_titles_show (GTK_CLIST (%s));\n",
+ data->wname);
+ else
+ source_add (data, " gtk_clist_column_titles_hide (GTK_CLIST (%s));\n",
+ data->wname);
+
+ if (GTK_CLIST (widget)->shadow_type != GTK_SHADOW_IN)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (GbShadowValues[i] == GTK_CLIST (widget)->shadow_type)
+ source_add (data,
+ " gtk_clist_set_shadow_type (GTK_CLIST (%s), %s);\n",
+ data->wname, GbShadowSymbols[i]);
+ }
+ }
+}
+
+
+/* Outputs source to add a child widget to a CList. */
+static void
+gb_clist_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *child_name;
+
+ child_name = gb_widget_get_child_name (child);
+
+ /* See if this is a title widget. */
+ if (child_name && (!strcmp (child_name, GladeChildCListTitle)))
+ {
+ /* We store the last column title written in 'last_child' */
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "last_child"));
+ source_add (data,
+ " gtk_clist_set_column_widget (GTK_CLIST (%s), %i, %s);\n",
+ parent_name, col + 1, data->wname);
+
+ gtk_object_set_data (GTK_OBJECT (parent), "last_child",
+ GINT_TO_POINTER (col + 1));
+ }
+ else
+ {
+ g_warning ("Unknown CList child widgetL %s", data->wname);
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+
+/* This just redraws the entire widget when it is scrolled, to make sure that
+ it isn't messed up due to our selection handles. */
+static void
+gb_scroll_adjustment_changed (GtkAdjustment *adjustment,
+ GtkWidget *widget)
+{
+ /* We check that this is a widget in the interface being created rather
+ than part of Glade's interface. */
+ if (GB_IS_GB_WIDGET (widget))
+ gtk_widget_queue_clear (widget);
+}
+
+
+gboolean
+gb_set_scroll_adjustments_hook (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GtkObject *object, *hadjustment, *vadjustment;
+ GtkObject *old_hadjustment, *old_vadjustment;
+
+ object = g_value_get_object (param_values);
+
+ hadjustment = g_value_get_object (param_values + 1);
+ vadjustment = g_value_get_object (param_values + 2);
+
+ old_hadjustment = gtk_object_get_data (object, "scrollhadjustment");
+ if (hadjustment != old_hadjustment)
+ {
+ gtk_object_set_data (object, "scrollhadjustment", hadjustment);
+
+ if (hadjustment)
+ gtk_signal_connect (hadjustment, "value_changed",
+ (GtkSignalFunc) gb_scroll_adjustment_changed,
+ object);
+ }
+
+ old_vadjustment = gtk_object_get_data (object, "scrollvadjustment");
+ if (vadjustment != old_vadjustment)
+ {
+ gtk_object_set_data (object, "scrollvadjustment", vadjustment);
+
+ if (vadjustment)
+ gtk_signal_connect (vadjustment, "value_changed",
+ (GtkSignalFunc) gb_scroll_adjustment_changed,
+ object);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_clist_init ()
+{
+ GtkWidgetClass *klass;
+
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_clist_get_type ();
+
+ /* Add a signal emission hook so we can connect signal handlers to the
+ scrollbar adjustments to redraw the clist when necessary. This will also
+ work for subclasses of GtkCList. */
+ klass = gtk_type_class (gtk_clist_get_type ());
+ g_signal_add_emission_hook (klass->set_scroll_adjustments_signal, 0,
+ gb_set_scroll_adjustments_hook, NULL, NULL);
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = clist_xpm;
+ gbwidget.tooltip = _("Columned List");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_clist_new;
+ gbwidget.gb_widget_add_child = gb_clist_add_child;
+ gbwidget.gb_widget_create_properties = gb_clist_create_properties;
+ gbwidget.gb_widget_get_properties = gb_clist_get_properties;
+ gbwidget.gb_widget_set_properties = gb_clist_set_properties;
+ gbwidget.gb_widget_write_source = gb_clist_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_clist_write_add_child_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_clist_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcolorbutton.c b/tools/glade/glade/gbwidgets/gbcolorbutton.c
new file mode 100644
index 00000000..95f86b6b
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcolorbutton.c
@@ -0,0 +1,225 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/colorbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *UseAlpha = "GtkColorButton::use_alpha";
+static gchar *Title = "GtkColorButton::title";
+static gchar *FocusOnClick = "GtkColorButton|GtkButton::focus_on_click";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkColorButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_color_button_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_color_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (UseAlpha, _("Use Alpha:"),
+ _("If the alpha channel should be used"));
+
+ property_add_string (Title, _("Title:"),
+ _("The title of the color selection dialog"));
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_color_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ const gchar *title;
+
+ gb_widget_output_bool (data, UseAlpha,
+ gtk_color_button_get_use_alpha (GTK_COLOR_BUTTON (widget)));
+
+ /* Only save if the title is different to the default. */
+ title = gtk_color_button_get_title (GTK_COLOR_BUTTON (widget));
+ if (data->action == GB_SHOWING
+ || (title && strcmp (title, dgettext (GLADE_GTK_GETTEXT_PACKAGE,
+ "Pick a Color"))))
+ gb_widget_output_translatable_string (data, Title, title);
+
+ gb_widget_output_bool (data, FocusOnClick,
+ gtk_button_get_focus_on_click (GTK_BUTTON (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_color_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean use_alpha, focus_on_click;
+ gchar *title;
+
+ use_alpha = gb_widget_input_bool (data, UseAlpha);
+ if (data->apply)
+ gtk_color_button_set_use_alpha (GTK_COLOR_BUTTON (widget), use_alpha);
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ gtk_color_button_set_title (GTK_COLOR_BUTTON (widget),
+ title && title[0]
+ ? title : dgettext (GLADE_GTK_GETTEXT_PACKAGE,
+ "Pick a Color"));
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_button_set_focus_on_click (GTK_BUTTON (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkColorButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_color_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_color_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *title;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_color_button_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ title = gtk_color_button_get_title (GTK_COLOR_BUTTON (widget));
+ if (title && title[0]
+ && strcmp (title, dgettext (GLADE_GTK_GETTEXT_PACKAGE, "Pick a Color")))
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gtk_color_button_set_title (GTK_COLOR_BUTTON (%s), %s);\n",
+ data->wname,
+ source_make_string_full (title, data->use_gettext && translatable, context));
+ }
+
+ if (gtk_color_button_get_use_alpha (GTK_COLOR_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_color_button_set_use_alpha (GTK_COLOR_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!gtk_button_get_focus_on_click (GTK_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_button_set_focus_on_click (GTK_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_color_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_color_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = colorbutton_xpm;
+ gbwidget.tooltip = _("Color Chooser Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_color_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_color_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_color_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_color_button_write_source;
+/*
+ gbwidget.gb_widget_new = gb_color_button_new;
+ gbwidget.gb_widget_create_popup_menu = gb_color_button_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbcolorselection.c b/tools/glade/glade/gbwidgets/gbcolorselection.c
new file mode 100644
index 00000000..cd629021
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcolorselection.c
@@ -0,0 +1,186 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkcolorsel.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/colorselection.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HasOpacity = "GtkColorSelection::has_opacity_control";
+static gchar *HasPalette = "GtkColorSelection::has_palette";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkColorSelection, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_color_selection_new(GbWidgetNewData *data)
+{
+ return gtk_color_selection_new ();
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_color_selection_create_properties (GtkWidget * widget, GbWidgetCreateArgData
+ * data)
+{
+ property_add_bool (HasOpacity, _("Opacity Control:"),
+ _("If the opacity control is shown"));
+ property_add_bool (HasPalette, _("Palette:"),
+ _("If the palette is shown"));
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_color_selection_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, HasOpacity,
+ gtk_color_selection_get_has_opacity_control (GTK_COLOR_SELECTION (widget)));
+ gb_widget_output_bool (data, HasPalette,
+ gtk_color_selection_get_has_palette (GTK_COLOR_SELECTION (widget)));
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_color_selection_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean has_opacity, has_palette;
+
+ has_opacity = gb_widget_input_bool (data, HasOpacity);
+ if (data->apply)
+ {
+ gtk_color_selection_set_has_opacity_control (GTK_COLOR_SELECTION (widget), has_opacity);
+ }
+
+ has_palette = gb_widget_input_bool (data, HasPalette);
+ if (data->apply)
+ {
+ gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (widget),
+ has_palette);
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkColorSelection, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_color_selection_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_color_selection_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ gboolean has_opacity_control;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_color_selection_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* Although the default is TRUE for the GtkColorSelection, it is FALSE in
+ the GtkColorSelectionDialog. So we always set it in the source code, since
+ this is used for both. */
+ has_opacity_control = gtk_color_selection_get_has_opacity_control (GTK_COLOR_SELECTION (widget));
+ source_add (data, " gtk_color_selection_set_has_opacity_control (GTK_COLOR_SELECTION (%s), %s);\n",
+ data->wname, has_opacity_control ? "TRUE" : "FALSE");
+
+ if (gtk_color_selection_get_has_palette (GTK_COLOR_SELECTION (widget)))
+ {
+ source_add (data, " gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_color_selection_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_color_selection_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = colorselection_xpm;
+ gbwidget.tooltip = _("Color Selection");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_color_selection_new;
+ gbwidget.gb_widget_create_properties = gb_color_selection_create_properties;
+ gbwidget.gb_widget_get_properties = gb_color_selection_get_properties;
+ gbwidget.gb_widget_set_properties = gb_color_selection_set_properties;
+ gbwidget.gb_widget_write_source = gb_color_selection_write_source;
+ /*
+ gbwidget.gb_widget_create_popup_menu = gb_color_selection_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcolorselectiondialog.c b/tools/glade/glade/gbwidgets/gbcolorselectiondialog.c
new file mode 100644
index 00000000..bf5eacff
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcolorselectiondialog.c
@@ -0,0 +1,331 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkcolorseldialog.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/colorseldialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "ColorSelDialog|GtkWindow::title";
+static gchar *Type = "ColorSelDialog|GtkWindow::type";
+static gchar *Position = "ColorSelDialog|GtkWindow::window_position";
+static gchar *Modal = "ColorSelDialog|GtkWindow::modal";
+static gchar *DefaultWidth = "ColorSel|GtkWindow::default_width";
+static gchar *DefaultHeight = "ColorSel|GtkWindow::default_height";
+static gchar *Shrink = "ColorSelDialog|GtkWindow::allow_shrink";
+static gchar *Grow = "ColorSelDialog|GtkWindow::allow_grow";
+static gchar *AutoShrink = "ColorSelDialog|GtkWindow::auto_shrink";
+static gchar *IconName = "ColorSelDialog|GtkWindow::icon_name";
+static gchar *FocusOnMap = "ColorSelDialog|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "ColorSelDialog|GtkWindow::resizable";
+static gchar *DestroyWithParent = "ColorSelDialog|GtkWindow::destroy_with_parent";
+static gchar *Icon = "ColorSelDialog|GtkWindow::icon";
+
+static gchar *Role = "ColorSelDialog|GtkWindow::role";
+static gchar *TypeHint = "ColorSelDialog|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "ColorSelDialog|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "ColorSelDialog|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "ColorSelDialog|GtkWindow::decorated";
+static gchar *Gravity = "ColorSelDialog|GtkWindow::gravity";
+static gchar *Urgency = "ColorSelDialog|GtkWindow::urgency_hint";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkColorSelectionDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_color_selection_dialog_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_color_selection_dialog_new (_("Select Color"));
+
+ GtkColorSelectionDialog *colorsel = GTK_COLOR_SELECTION_DIALOG (new_widget);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gb_widget_create_from (colorsel->ok_button,
+ data->action == GB_CREATING ? "ok_button" : NULL);
+ gb_widget_set_child_name (colorsel->ok_button, GladeChildOKButton);
+
+ gb_widget_create_from (colorsel->cancel_button,
+ data->action == GB_CREATING ? "cancel_button" : NULL);
+ gb_widget_set_child_name (colorsel->cancel_button, GladeChildCancelButton);
+
+ gb_widget_create_from (colorsel->help_button,
+ data->action == GB_CREATING ? "help_button" : NULL);
+ gb_widget_set_child_name (colorsel->help_button, GladeChildHelpButton);
+
+ gb_widget_create_from (colorsel->colorsel,
+ data->action == GB_CREATING ? "color_selection" : NULL);
+ gb_widget_set_child_name (colorsel->colorsel, GladeChildColorSelection);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_color_selection_dialog_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_color_selection_dialog_get_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ GtkColorSelectionDialog *colorseldlg;
+ GtkColorSelection *colorsel;
+
+ colorseldlg = GTK_COLOR_SELECTION_DIALOG (widget);
+ colorsel = GTK_COLOR_SELECTION (colorseldlg->colorsel);
+
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_color_selection_dialog_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ GtkColorSelectionDialog *colorseldlg;
+ GtkColorSelection *colorsel;
+
+ colorseldlg = GTK_COLOR_SELECTION_DIALOG (widget);
+ colorsel = GTK_COLOR_SELECTION (colorseldlg->colorsel);
+
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkColorSelectionDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_color_selection_dialog_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_color_selection_dialog_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+ const gchar *child_widget_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gtk_color_selection_dialog_new (%s);\n",
+ data->wname,
+ source_make_string_full (GTK_WINDOW (widget)->title,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+
+ /* We output the source code for the buttons here, but we don't want them
+ to be created. We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+
+ child_widget_name = gtk_widget_get_name (GTK_COLOR_SELECTION_DIALOG (widget)->ok_button);
+ child_name = source_create_valid_identifier (child_widget_name);
+ source_add (data, " %s = GTK_COLOR_SELECTION_DIALOG (%s)->ok_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_COLOR_SELECTION_DIALOG (widget)->ok_button,
+ data);
+
+ child_widget_name = gtk_widget_get_name (GTK_COLOR_SELECTION_DIALOG (widget)->cancel_button);
+ child_name = source_create_valid_identifier (child_widget_name);
+ source_add (data, " %s = GTK_COLOR_SELECTION_DIALOG (%s)->cancel_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_COLOR_SELECTION_DIALOG (widget)->cancel_button,
+ data);
+
+ child_widget_name = gtk_widget_get_name (GTK_COLOR_SELECTION_DIALOG (widget)->help_button);
+ child_name = source_create_valid_identifier (child_widget_name);
+ source_add (data, " %s = GTK_COLOR_SELECTION_DIALOG (%s)->help_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_COLOR_SELECTION_DIALOG (widget)->help_button,
+ data);
+
+ child_widget_name = gtk_widget_get_name (GTK_COLOR_SELECTION_DIALOG (widget)->colorsel);
+ child_name = source_create_valid_identifier (child_widget_name);
+ source_add (data, " %s = GTK_COLOR_SELECTION_DIALOG (%s)->colorsel;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_COLOR_SELECTION_DIALOG (widget)->colorsel,
+ data);
+
+ g_free (wname);
+
+ data->write_children = FALSE;
+}
+
+
+
+static GtkWidget *
+gb_color_selection_dialog_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildOKButton))
+ return GTK_COLOR_SELECTION_DIALOG (widget)->ok_button;
+ else if (!strcmp (child_name, GladeChildCancelButton))
+ return GTK_COLOR_SELECTION_DIALOG (widget)->cancel_button;
+ else if (!strcmp (child_name, GladeChildHelpButton))
+ return GTK_COLOR_SELECTION_DIALOG (widget)->help_button;
+ else if (!strcmp (child_name, GladeChildColorSelection))
+ return GTK_COLOR_SELECTION_DIALOG (widget)->colorsel;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_color_selection_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_color_selection_dialog_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = colorseldialog_xpm;
+ gbwidget.tooltip = _("Color Selection Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_color_selection_dialog_new;
+ gbwidget.gb_widget_create_properties = gb_color_selection_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_color_selection_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_color_selection_dialog_set_properties;
+ gbwidget.gb_widget_get_child = gb_color_selection_dialog_get_child;
+ gbwidget.gb_widget_write_source = gb_color_selection_dialog_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_color_selection_dialog_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcombo.c b/tools/glade/glade/gbwidgets/gbcombo.c
new file mode 100644
index 00000000..3ba0536a
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcombo.c
@@ -0,0 +1,439 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkcombo.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtklist.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/combo.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* These 2 are stored in the widget's datalist since otherwise GtkCombo starts
+ to grab the pointer if invalid values are entered which causes problems. */
+static gchar *ValueInList = "GtkCombo::value_in_list";
+static gchar *OKIfEmpty = "GtkCombo::allow_empty";
+
+static gchar *Case = "GtkCombo::case_sensitive";
+static gchar *Arrows = "GtkCombo::enable_arrow_keys";
+static gchar *Always = "GtkCombo::enable_arrows_always";
+static gchar *Items = "GtkCombo::items";
+
+static void add_label (GtkWidget * widget, GString * items);
+
+static gint is_simple_combo (GtkWidget * widget);
+static void is_simple_combo_callback (GtkWidget * widget,
+ gint * num_children);
+static void write_items_source_callback (GtkWidget * item,
+ GbWidgetWriteSourceData * data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCombo, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_combo_new(GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_combo_new ();
+
+ /* There is no way to move up from the popup list window to the combo, so
+ we have to add a pointer here. It is used in glade_util_get_parent ().
+ We don't add a ref to it, in case it messes up the normal widget code. */
+ gtk_object_set_data (GTK_OBJECT (GTK_COMBO (new_widget)->popwin),
+ GladeParentKey, new_widget);
+
+ gb_widget_create_from (GTK_COMBO (new_widget)->entry,
+ data->action == GB_CREATING ? "combo-entry" : NULL);
+ gb_widget_set_child_name (GTK_COMBO (new_widget)->entry, GladeChildComboEntry);
+
+ gb_widget_create_from (GTK_COMBO (new_widget)->list,
+ data->action == GB_CREATING ? "combo-list" : NULL);
+ gb_widget_set_child_name (GTK_COMBO (new_widget)->list, GladeChildComboList);
+
+ /* This defaults to TRUE. */
+ gtk_object_set_data (GTK_OBJECT (new_widget), OKIfEmpty, "TRUE");
+
+ /* FIXME: GTK+ 1.3 temporary hack to workaround problems. */
+ gtk_signal_handler_block (GTK_OBJECT (GTK_COMBO (new_widget)->entry),
+ GTK_COMBO (new_widget)->entry_change_id);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_combo_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (ValueInList, _("Value In List:"),
+ _("If the value must be in the list"));
+ property_add_bool (OKIfEmpty, _("OK If Empty:"),
+ _("If an empty value is acceptable, when 'Value In List' is set"));
+ property_add_bool (Case, _("Case Sensitive:"),
+ _("If the searching is case sensitive"));
+ property_add_bool (Arrows, _("Use Arrows:"),
+ _("If arrows can be used to change the value"));
+ property_add_bool (Always, _("Use Always:"),
+ _("If arrows work even if the value is not in the list"));
+ property_add_text (Items, _("Items:"),
+ _("The items in the combo list, one per line"), 5);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_combo_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, ValueInList,
+ gtk_object_get_data (GTK_OBJECT (widget), ValueInList)
+ != NULL ? TRUE : FALSE);
+ gb_widget_output_bool (data, OKIfEmpty,
+ gtk_object_get_data (GTK_OBJECT (widget), OKIfEmpty)
+ != NULL ? TRUE : FALSE);
+ gb_widget_output_bool (data, Case, GTK_COMBO (widget)->case_sensitive);
+ gb_widget_output_bool (data, Arrows, GTK_COMBO (widget)->use_arrows);
+ gb_widget_output_bool (data, Always, GTK_COMBO (widget)->use_arrows_always);
+
+ if (data->action == GB_SHOWING && is_simple_combo (widget) >= 0)
+ {
+ GString *items;
+
+ items = g_string_new ("");
+ gtk_container_foreach (GTK_CONTAINER (GTK_COMBO (widget)->list),
+ (GtkCallback) add_label, items);
+ gb_widget_output_translatable_text_in_lines (data, Items, items->str);
+ g_string_free (items, TRUE);
+ }
+}
+
+/* Adds combo label text to buffer, or sets first char to -1 if it won't fit.
+ */
+static void
+add_label (GtkWidget * widget, GString *items)
+{
+ const gchar *label_text;
+
+ label_text = gtk_label_get_text (GTK_LABEL (GTK_BIN (widget)->child));
+ g_string_append (items, label_text);
+ g_string_append_c (items, '\n');
+}
+
+
+/* Returns number of items in combo list, or -1 if not a simple combo (not
+ all children are labels). */
+static gint
+is_simple_combo (GtkWidget * widget)
+{
+ gint num_children = 0;
+
+ gtk_container_foreach (GTK_CONTAINER (GTK_COMBO (widget)->list),
+ (GtkCallback) is_simple_combo_callback, &num_children);
+ return num_children;
+}
+
+
+/* Sets flag to FALSE if list item's child widget is not a label. */
+static void
+is_simple_combo_callback (GtkWidget * widget, gint * num_children)
+{
+ /* If we've already found an item which isn't a simple label, just return. */
+ if (*num_children == -1)
+ return;
+
+ /* If the items isn't a simple label, set num_children to -1, else add 1. */
+ if (!GTK_IS_LABEL (GTK_BIN (widget)->child))
+ *num_children = -1;
+ else
+ *num_children += 1;
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_combo_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean value_in_list, ok_if_empty, case_sensitive, arrows, arrows_always;
+ gchar *items;
+
+ value_in_list = gb_widget_input_bool (data, ValueInList);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), ValueInList,
+ value_in_list ? "TRUE" : NULL);
+ }
+
+ ok_if_empty = gb_widget_input_bool (data, OKIfEmpty);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), OKIfEmpty,
+ ok_if_empty ? "TRUE" : NULL);
+ }
+
+ case_sensitive = gb_widget_input_bool (data, Case);
+ if (data->apply)
+ gtk_combo_set_case_sensitive (GTK_COMBO (widget), case_sensitive);
+ arrows = gb_widget_input_bool (data, Arrows);
+ if (data->apply)
+ gtk_combo_set_use_arrows (GTK_COMBO (widget), arrows);
+ arrows_always = gb_widget_input_bool (data, Always);
+ if (data->apply)
+ gtk_combo_set_use_arrows_always (GTK_COMBO (widget), arrows_always);
+
+ if (data->action == GB_APPLYING)
+ {
+ items = gb_widget_input_text (data, Items);
+ if (data->apply)
+ {
+ GtkWidget *list = GTK_COMBO (widget)->list;
+ GtkWidget *listitem;
+ gchar *pos = items;
+ gchar *items_end = &items[strlen (items)];
+
+ gtk_list_clear_items (GTK_LIST (list), 0, -1);
+
+ while (pos < items_end)
+ {
+ gchar *item_end = strchr (pos, '\n');
+ if (item_end == NULL)
+ item_end = items_end;
+ *item_end = '\0';
+
+ listitem = gb_widget_new ("GtkListItem", list);
+ gtk_label_set_text (GTK_LABEL (GTK_BIN (listitem)->child), pos);
+ gtk_widget_show (listitem);
+ gtk_container_add (GTK_CONTAINER (list), listitem);
+
+ if (item_end != items_end)
+ *item_end = '\n';
+
+ pos = item_end + 1;
+ }
+
+ g_free (items);
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCombo, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_combo_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_combo_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+ gboolean value_in_list, ok_if_empty;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_combo_new ();\n", data->wname);
+ }
+
+ /* We store a pointer to the popup window's parent combo, so lookup_widget()
+ will still work when the popup window is passed as the first arg. */
+ source_add (data,
+ " g_object_set_data (G_OBJECT (GTK_COMBO (%s)->popwin),\n"
+ " \"GladeParentKey\", %s);\n",
+ data->wname, data->wname);
+
+ gb_widget_write_standard_source (widget, data);
+
+ value_in_list = gtk_object_get_data (GTK_OBJECT (widget), ValueInList)
+ != NULL ? TRUE : FALSE;
+ if (value_in_list)
+ {
+ ok_if_empty = gtk_object_get_data (GTK_OBJECT (widget), OKIfEmpty)
+ != NULL ? TRUE : FALSE;
+ source_add (data,
+ " gtk_combo_set_value_in_list (GTK_COMBO (%s), %s, %s);\n",
+ data->wname,
+ value_in_list ? "TRUE" : "FALSE",
+ ok_if_empty ? "TRUE" : "FALSE");
+ }
+
+
+ if (GTK_COMBO (widget)->case_sensitive)
+ {
+ source_add (data,
+ " gtk_combo_set_case_sensitive (GTK_COMBO (%s), TRUE);\n",
+ data->wname);
+ }
+ if (!GTK_COMBO (widget)->use_arrows)
+ {
+ source_add (data,
+ " gtk_combo_set_use_arrows (GTK_COMBO (%s), FALSE);\n",
+ data->wname);
+ }
+ if (GTK_COMBO (widget)->use_arrows_always)
+ {
+ source_add (data,
+ " gtk_combo_set_use_arrows_always (GTK_COMBO (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (is_simple_combo (widget) > 0)
+ {
+ gboolean old_use_gettext;
+
+ source_add_decl (data, " GList *%s_items = NULL;\n", data->real_wname);
+
+ glade_util_get_translation_properties (widget, Items, &translatable,
+ &comments, &context);
+
+ /* Temporarily set data->use_gettext to take the translatable flag for
+ this property into account, so our callback can use that. */
+ old_use_gettext = data->use_gettext;
+ data->use_gettext = data->use_gettext && translatable ? TRUE : FALSE;
+ gtk_container_foreach (GTK_CONTAINER (GTK_COMBO (widget)->list),
+ (GtkCallback) write_items_source_callback, data);
+ data->use_gettext = old_use_gettext;
+
+ source_add (data,
+ " gtk_combo_set_popdown_strings (GTK_COMBO (%s), %s_items);\n",
+ data->wname, data->real_wname);
+ source_add (data, " g_list_free (%s_items);\n", data->real_wname);
+ }
+
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_COMBO (<combo-name>)->entry".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (gchar*) gtk_widget_get_name (GTK_COMBO (widget)->entry);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_COMBO (%s)->entry;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_COMBO (widget)->entry, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static void
+write_items_source_callback (GtkWidget * item, GbWidgetWriteSourceData * data)
+{
+ const gchar *label_text;
+ label_text = gtk_label_get_text (GTK_LABEL (GTK_BIN (item)->child));
+ /* The (gpointer) cast is just to keep g++ happy. */
+ source_add (data, " %s_items = g_list_append (%s_items, (gpointer) %s);\n",
+ data->real_wname, data->real_wname,
+ source_make_string (label_text, data->use_gettext));
+}
+
+
+static GtkWidget *
+gb_combo_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildComboEntry))
+ return GTK_COMBO (widget)->entry;
+ else if (!strcmp (child_name, GladeChildComboList))
+ return GTK_COMBO (widget)->list;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_combo_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_combo_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = combo_xpm;
+ gbwidget.tooltip = _("Combo Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_combo_new;
+ gbwidget.gb_widget_create_properties = gb_combo_create_properties;
+ gbwidget.gb_widget_get_properties = gb_combo_get_properties;
+ gbwidget.gb_widget_set_properties = gb_combo_set_properties;
+ gbwidget.gb_widget_get_child = gb_combo_get_child;
+ gbwidget.gb_widget_write_source = gb_combo_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_combo_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcombobox.c b/tools/glade/glade/gbwidgets/gbcombobox.c
new file mode 100644
index 00000000..d290822b
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcombobox.c
@@ -0,0 +1,303 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/combobox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* This isn't a real property, but since we can't set up a proper tree model
+ we just support simple text like we did for GtkCombo. */
+static gchar *Items = "GtkComboBox::items";
+
+static gchar *AddTearoffs = "GtkComboBox::add_tearoffs";
+#if 0
+/* I don't think this is useful for GtkComboBox itself. */
+static gchar *HasFrame = "GtkComboBox::has_frame";
+#endif
+static gchar *FocusOnClick = "GtkComboBox::focus_on_click";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkComboBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_combo_box_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_combo_box_new_text ();
+
+ /* Force the combobox to create the child widgets, so that we can connect
+ to all the "event" signals so the user can select the widget. */
+ gtk_widget_ensure_style (new_widget);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_combo_box_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_text (Items, _("Items:"),
+ _("The items in the combo list, one per line"), 5);
+
+ property_add_bool (AddTearoffs, _("Add Tearoffs:"),
+ _("Whether dropdowns should have a tearoff menu item"));
+ property_add_bool (FocusOnClick, _("Focus On Click:"),
+ _("Whether the combo box grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_combo_box_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar *items;
+ gboolean add_tearoffs, focus_on_click;
+
+ items = gtk_object_get_data (GTK_OBJECT (widget), Items);
+ gb_widget_output_translatable_text_in_lines (data, Items, items);
+
+ g_object_get (G_OBJECT (widget),
+ "add_tearoffs", &add_tearoffs,
+ "focus_on_click", &focus_on_click,
+ NULL);
+
+ gb_widget_output_bool (data, AddTearoffs, add_tearoffs);
+ gb_widget_output_bool (data, FocusOnClick, focus_on_click);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_combo_box_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *items;
+ gboolean add_tearoffs, focus_on_click;
+
+ items = gb_widget_input_text (data, Items);
+ if (data->apply)
+ {
+ GtkTreeModel *model;
+ gchar *pos = items;
+ gchar *items_end = &items[strlen (items)];
+
+ /* Save a copy so it is easy to get out later. */
+ gtk_object_set_data_full (GTK_OBJECT (widget), Items,
+ g_strdup (items), g_free);
+
+ /* Clear the list. */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ /* Now add the items one at a time. */
+ while (pos < items_end)
+ {
+ gchar *item_end = strchr (pos, '\n');
+ if (item_end == NULL)
+ item_end = items_end;
+ *item_end = '\0';
+
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), pos);
+
+ if (item_end != items_end)
+ *item_end = '\n';
+
+ pos = item_end + 1;
+ }
+ }
+ if (data->action == GB_APPLYING)
+ g_free (items);
+
+ add_tearoffs = gb_widget_input_bool (data, AddTearoffs);
+ if (data->apply)
+ gtk_combo_box_set_add_tearoffs (GTK_COMBO_BOX (widget), add_tearoffs);
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkComboBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_combo_box_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_combo_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *items, *pos, *items_end;
+ gboolean translatable, context;
+ gchar *comments;
+ gboolean add_tearoffs, focus_on_click;
+
+ items = pos = gtk_object_get_data (GTK_OBJECT (widget), Items);
+
+ glade_util_get_translation_properties (widget, Items, &translatable,
+ &comments, &context);
+
+ if (data->create_widget)
+ {
+ /* If any items have been entered, we create a simple text combo,
+ otherwise we create a bare combo without a model, so the user can
+ setup the model in their code. */
+ /* NOTE: Creating it without a model causes problems so we always create
+ a model now. Users can still set the model to something else. */
+#if 0
+ if (items && items[0])
+ {
+ source_add (data, " %s = gtk_combo_box_new_text ();\n",
+ data->wname);
+ }
+ else
+ {
+ source_add (data, " %s = gtk_combo_box_new ();\n",
+ data->wname);
+ }
+#endif
+
+ source_add (data, " %s = gtk_combo_box_text_new ();\n",
+ data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (items && items[0])
+ {
+ items_end = &items[strlen (items)];
+
+ while (pos < items_end)
+ {
+ gchar *item_end = strchr (pos, '\n');
+ if (item_end == NULL)
+ item_end = items_end;
+ *item_end = '\0';
+
+ source_add (data, " gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (%s), %s);\n",
+ data->wname,
+ source_make_string (pos,
+ data->use_gettext && translatable));
+
+ if (item_end != items_end)
+ *item_end = '\n';
+
+ pos = item_end + 1;
+ }
+ }
+
+ g_object_get (G_OBJECT (widget),
+ "add_tearoffs", &add_tearoffs,
+ "focus_on_click", &focus_on_click,
+ NULL);
+
+ if (add_tearoffs)
+ {
+ source_add (data,
+ " gtk_combo_box_set_add_tearoffs (GTK_COMBO_BOX (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!focus_on_click)
+ {
+ source_add (data,
+ " gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_combo_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_combo_box_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = combobox_xpm;
+ gbwidget.tooltip = _("Combo Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_combo_box_new;
+ gbwidget.gb_widget_create_properties = gb_combo_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_combo_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_combo_box_set_properties;
+ gbwidget.gb_widget_write_source = gb_combo_box_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_combo_box_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbcomboboxentry.c b/tools/glade/glade/gbwidgets/gbcomboboxentry.c
new file mode 100644
index 00000000..500a5ad5
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcomboboxentry.c
@@ -0,0 +1,316 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/comboboxentry.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* This isn't a real property, but since we can't set up a proper tree model
+ we just support simple text like we did for GtkCombo. */
+static gchar *Items = "GtkComboBoxEntry::items";
+
+static gchar *AddTearoffs = "GtkComboBoxEntry|GtkComboBox::add_tearoffs";
+static gchar *HasFrame = "GtkComboBoxEntry|GtkComboBox::has_frame";
+static gchar *FocusOnClick = "GtkComboBoxEntry|GtkComboBox::focus_on_click";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkComboBoxEntry, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_combo_box_entry_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_combo_box_entry_new_text ();
+
+ /* Force the combobox to create the child widgets, so that we can connect
+ to all the "event" signals so the user can select the widget. */
+ gtk_widget_ensure_style (new_widget);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_combo_box_entry_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_text (Items, _("Items:"),
+ _("The items in the combo list, one per line"), 5);
+
+ property_add_bool (AddTearoffs, _("Add Tearoffs:"),
+ _("Whether dropdowns should have a tearoff menu item"));
+ property_add_bool (HasFrame, _("Has Frame:"),
+ _("Whether the combo box draws a frame around the child"));
+ property_add_bool (FocusOnClick, _("Focus On Click:"),
+ _("Whether the combo box grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_combo_box_entry_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar *items;
+ gboolean add_tearoffs, has_frame, focus_on_click;
+
+ items = gtk_object_get_data (GTK_OBJECT (widget), Items);
+ gb_widget_output_translatable_text_in_lines (data, Items, items);
+
+ g_object_get (G_OBJECT (widget),
+ "add_tearoffs", &add_tearoffs,
+ "has_frame", &has_frame,
+ "focus_on_click", &focus_on_click,
+ NULL);
+
+ gb_widget_output_bool (data, AddTearoffs, add_tearoffs);
+ gb_widget_output_bool (data, HasFrame, has_frame);
+ gb_widget_output_bool (data, FocusOnClick, focus_on_click);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_combo_box_entry_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *items;
+ gboolean add_tearoffs, has_frame, focus_on_click;
+
+ items = gb_widget_input_text (data, Items);
+ if (data->apply)
+ {
+ GtkTreeModel *model;
+ gchar *pos = items;
+ gchar *items_end = &items[strlen (items)];
+
+ /* Save a copy so it is easy to get out later. */
+ gtk_object_set_data_full (GTK_OBJECT (widget), Items,
+ g_strdup (items), g_free);
+
+ /* Clear the list. */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ /* Now add the items one at a time. */
+ while (pos < items_end)
+ {
+ gchar *item_end = strchr (pos, '\n');
+ if (item_end == NULL)
+ item_end = items_end;
+ *item_end = '\0';
+
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), pos);
+
+ if (item_end != items_end)
+ *item_end = '\n';
+
+ pos = item_end + 1;
+ }
+ }
+ if (data->action == GB_APPLYING)
+ g_free (items);
+
+ add_tearoffs = gb_widget_input_bool (data, AddTearoffs);
+ if (data->apply)
+ gtk_combo_box_set_add_tearoffs (GTK_COMBO_BOX (widget), add_tearoffs);
+
+ has_frame = gb_widget_input_bool (data, HasFrame);
+ if (data->apply)
+ g_object_set (widget, "has_frame", has_frame, NULL);
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkComboBoxEntry, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_combo_box_entry_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_combo_box_entry_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *items, *pos, *items_end;
+ gboolean translatable, context;
+ gchar *comments;
+ gboolean add_tearoffs, has_frame, focus_on_click;
+
+ items = pos = gtk_object_get_data (GTK_OBJECT (widget), Items);
+
+ glade_util_get_translation_properties (widget, Items, &translatable,
+ &comments, &context);
+
+ if (data->create_widget)
+ {
+ /* If any items have been entered, we create a simple text combo,
+ otherwise we create a bare combo without a model, so the user can
+ setup the model in their code. */
+ /* NOTE: Creating it without a model causes problems so we always create
+ a model now. Users can still set the model to something else. */
+#if 0
+ if (items && items[0])
+ {
+ source_add (data, " %s = gtk_combo_box_entry_new_text ();\n",
+ data->wname);
+ }
+ else
+ {
+ source_add (data, " %s = gtk_combo_box_entry_new ();\n",
+ data->wname);
+ }
+#endif
+
+ source_add (data, " %s = gtk_combo_box_entry_new_text ();\n",
+ data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (items && items[0])
+ {
+ items_end = &items[strlen (items)];
+
+ while (pos < items_end)
+ {
+ gchar *item_end = strchr (pos, '\n');
+ if (item_end == NULL)
+ item_end = items_end;
+ *item_end = '\0';
+
+ source_add (data, " gtk_combo_box_append_text (GTK_COMBO_BOX (%s), %s);\n",
+ data->wname,
+ source_make_string (pos,
+ data->use_gettext && translatable));
+
+ if (item_end != items_end)
+ *item_end = '\n';
+
+ pos = item_end + 1;
+ }
+ }
+
+ g_object_get (G_OBJECT (widget),
+ "add_tearoffs", &add_tearoffs,
+ "has_frame", &has_frame,
+ "focus_on_click", &focus_on_click,
+ NULL);
+
+ if (add_tearoffs)
+ {
+ source_add (data,
+ " gtk_combo_box_set_add_tearoffs (GTK_COMBO_BOX (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!has_frame)
+ {
+ source_add (data,
+ " g_object_set (%s, \"has_frame\", FALSE, NULL);\n",
+ data->wname);
+ }
+
+ if (!focus_on_click)
+ {
+ source_add (data,
+ " gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_combo_box_entry_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_combo_box_entry_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = comboboxentry_xpm;
+ gbwidget.tooltip = _("Combo Box Entry");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_combo_box_entry_new;
+ gbwidget.gb_widget_create_properties = gb_combo_box_entry_create_properties;
+ gbwidget.gb_widget_get_properties = gb_combo_box_entry_get_properties;
+ gbwidget.gb_widget_set_properties = gb_combo_box_entry_set_properties;
+ gbwidget.gb_widget_write_source = gb_combo_box_entry_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_combo_box_entry_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbctree.c b/tools/glade/glade/gbwidgets/gbctree.c
new file mode 100644
index 00000000..50aafcbc
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbctree.c
@@ -0,0 +1,554 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkctree.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/ctree.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Mode = "CTree|GtkCList::selection_mode";
+static gchar *Titles = "CTree|GtkCList::show_titles";
+static gchar *Shadow = "CTree|GtkCList::shadow_type";
+
+/* This is only used for loading & saving - it isn't displayed in the property
+ editor. */
+static gchar *Cols = "GtkCTree::n_columns";
+static gchar *ColumnWidths = "GtkCTree::column_widths";
+
+static const gchar *GbModeChoices[] =
+{"Single", "Browse", "Multiple", NULL};
+static const gint GbModeValues[] =
+{
+ GTK_SELECTION_SINGLE,
+ GTK_SELECTION_BROWSE,
+ GTK_SELECTION_MULTIPLE
+};
+static const gchar *GbModeSymbols[] =
+{
+ "GTK_SELECTION_SINGLE",
+ "GTK_SELECTION_BROWSE",
+ "GTK_SELECTION_MULTIPLE"
+};
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+
+static void show_ctree_dialog (GbWidgetNewData * data);
+static void on_ctree_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_ctree_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+static GtkWidget *new_label (GtkWidget * parent);
+static GtkWidget *new_unnamed_label (GtkWidget * parent);
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCTree, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_ctree_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ gint cols = 0, i;
+
+ if (data->action == GB_LOADING)
+ {
+ cols = load_int (data->loading_data, Cols);
+
+ /* For backwards compatability with 1.1.1. */
+ if (cols == 0)
+ cols = load_int (data->loading_data, "columns");
+
+ if (cols == 0)
+ cols = 1;
+ /* FIXME: Allow setting of tree column - 2nd arg */
+ new_widget = gtk_ctree_new (cols, 0);
+
+ /* GtkCList has problems if the title buttons aren't created. */
+ for (i = 0; i < cols; i++)
+ {
+ gtk_clist_set_column_widget (GTK_CLIST (new_widget), i,
+ new_unnamed_label (new_widget));
+ gtk_clist_set_column_width (GTK_CLIST (new_widget), i, 80);
+ editor_add_mouse_signals_to_existing (GTK_CLIST (new_widget)->column[i].button);
+ }
+
+ return new_widget;
+ }
+ else
+ {
+ show_ctree_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_ctree_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New columned tree"), data->parent,
+ GTK_SIGNAL_FUNC (on_ctree_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_ctree_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of columns:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "cols",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_ctree_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *dialog, *label;
+ gint cols, i;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (dialog), "cols");
+ g_return_if_fail (spinbutton != NULL);
+ cols = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ /* FIXME: Allow setting of tree column - 2nd arg */
+ new_widget = gtk_ctree_new (cols, 0);
+ gtk_clist_column_titles_show (GTK_CLIST (new_widget));
+ for (i = 0; i < cols; i++)
+ {
+ label = new_label (new_widget);
+ gtk_clist_set_column_widget (GTK_CLIST (new_widget), i,
+ label);
+ gtk_clist_set_column_width (GTK_CLIST (new_widget), i, 80);
+ }
+
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (dialog);
+}
+
+
+static void
+on_ctree_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+GtkWidget *
+new_label (GtkWidget * parent)
+{
+ GtkWidget *label;
+
+ label = gb_widget_new ("GtkLabel", parent);
+ g_return_val_if_fail (label != NULL, NULL);
+ gb_widget_set_child_name (label, GladeChildCListTitle);
+ return label;
+}
+
+
+GtkWidget *
+new_unnamed_label (GtkWidget * parent)
+{
+ GtkWidget *label;
+
+ label = gb_widget_new_full ("GtkLabel", FALSE, parent, NULL, 0, 0, NULL,
+ GB_CREATING, NULL);
+ g_return_val_if_fail (label != NULL, NULL);
+ gb_widget_set_child_name (label, GladeChildCListTitle);
+ return label;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_ctree_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Mode, _("Select Mode:"),
+ _("The selection mode of the columned tree"),
+ GbModeChoices);
+ property_add_bool (Titles, _("Show Titles:"),
+ _("If the column titles are shown"));
+ property_add_choice (Shadow, _("Shadow:"),
+ _("The type of shadow of the columned tree's border"),
+ GbShadowChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_ctree_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar buffer[1024];
+ gchar *pos;
+ gboolean buffer_overrun = FALSE;
+ gint i;
+
+ if (data->action == GB_SAVING)
+ {
+ gb_widget_output_int (data, Cols, GTK_CLIST (widget)->columns);
+
+ pos = buffer;
+ for (i = 0; i < GTK_CLIST (widget)->columns; i++)
+ {
+ if (i == 0)
+ sprintf (pos, "%i", GTK_CLIST (widget)->column[i].width);
+ else
+ sprintf (pos, ",%i", GTK_CLIST (widget)->column[i].width);
+ pos += strlen (pos);
+
+ /* Extra check to make sure we don't overrun the buffer. */
+ if (pos - buffer > 1000)
+ {
+ g_warning ("Buffer overflow");
+ buffer_overrun = TRUE;
+ break;
+ }
+ }
+ if (!buffer_overrun)
+ gb_widget_output_string (data, ColumnWidths, buffer);
+ }
+
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == GTK_CLIST (widget)->selection_mode)
+ gb_widget_output_choice (data, Mode, i, GbModeSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Titles, GTK_CLIST_SHOW_TITLES (widget));
+
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == GTK_CLIST (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GbShadowSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_ctree_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *widths, *pos, *mode;
+ gchar *shadow;
+ gboolean titles;
+ gint col, w, i;
+
+ if (data->action == GB_LOADING)
+ {
+ widths = gb_widget_input_string (data, ColumnWidths);
+ if (data->apply)
+ {
+ pos = widths;
+ for (col = 0; col < GTK_CLIST (widget)->columns; col++)
+ {
+ w = atoi (pos);
+ gtk_clist_set_column_width (GTK_CLIST (widget), col, w);
+ pos = strchr (pos, ',');
+ if (!pos)
+ break;
+ pos++;
+ }
+ }
+ }
+
+ mode = gb_widget_input_choice (data, Mode);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (!strcmp (mode, GbModeChoices[i])
+ || !strcmp (mode, GbModeSymbols[i]))
+ {
+ gtk_clist_set_selection_mode (GTK_CLIST (widget), GbModeValues[i]);
+ break;
+ }
+ }
+ }
+
+ titles = gb_widget_input_bool (data, Titles);
+ if (data->apply)
+ {
+ if (titles)
+ gtk_clist_column_titles_show (GTK_CLIST (widget));
+ else
+ gtk_clist_column_titles_hide (GTK_CLIST (widget));
+ }
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ gtk_clist_set_shadow_type (GTK_CLIST (widget),
+ GbShadowValues[i]);
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCTree, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_ctree_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+void
+gb_ctree_add_child (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ /* We store the last column title read in 'last_child' */
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ "last_child"));
+
+ if (col >= GTK_CLIST (widget)->columns) {
+ g_warning ("Too many column title widgets for GtkCTree - skipping");
+ return;
+ }
+
+ gtk_clist_set_column_widget (GTK_CLIST (widget), col, child);
+ gtk_object_set_data (GTK_OBJECT (widget), "last_child",
+ GINT_TO_POINTER (col + 1));
+
+ /* We need to add signals to the clist button, just in case the
+ title widget has no window and so doesn't get signals itself.
+ Since Clist always creates 1 button initially, the signals would
+ be added to this button in gb_widget_new, so we could skip it,
+ but it doesn't hurt. */
+ editor_add_mouse_signals_to_existing (GTK_CLIST (widget)->column[col].button);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_ctree_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint col, i;
+
+ if (data->create_widget)
+ {
+ /* FIXME: allow changing of 2nd arg - ctree column */
+ source_add (data, " %s = gtk_ctree_new (%i, 0);\n", data->wname,
+ GTK_CLIST (widget)->columns);
+ }
+
+ /* We reset the last_child index, so as the title widgets are written out
+ they will start at column 0. */
+ gtk_object_set_data (GTK_OBJECT (widget), "last_child", GINT_TO_POINTER (-1));
+
+ gb_widget_write_standard_source (widget, data);
+
+ for (col = 0; col < GTK_CLIST (widget)->columns; col++)
+ {
+ source_add (data,
+ " gtk_clist_set_column_width (GTK_CLIST (%s), %i, %i);\n",
+ data->wname, col, GTK_CLIST (widget)->column[col].width);
+ }
+
+ if (GTK_CLIST (widget)->selection_mode != GTK_SELECTION_SINGLE)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == GTK_CLIST (widget)->selection_mode)
+ source_add (data,
+ " gtk_clist_set_selection_mode (GTK_CLIST (%s), %s);\n",
+ data->wname, GbModeSymbols[i]);
+ }
+ }
+
+ if (GTK_CLIST_SHOW_TITLES (widget))
+ source_add (data, " gtk_clist_column_titles_show (GTK_CLIST (%s));\n",
+ data->wname);
+ else
+ source_add (data, " gtk_clist_column_titles_hide (GTK_CLIST (%s));\n",
+ data->wname);
+
+ if (GTK_CLIST (widget)->shadow_type != GTK_SHADOW_IN)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (GbShadowValues[i] == GTK_CLIST (widget)->shadow_type)
+ source_add (data, " gtk_clist_set_shadow_type (GTK_CLIST (%s), %s);\n",
+ data->wname, GbShadowSymbols[i]);
+ }
+ }
+}
+
+
+/* Outputs source to add a child widget to a CTree. */
+static void
+gb_ctree_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *child_name;
+
+ child_name = gb_widget_get_child_name (child);
+
+ /* See if this is a title widget. */
+ if (child_name && (!strcmp (child_name, GladeChildCListTitle)))
+ {
+ /* We store the last column title written in 'last_child' */
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "last_child"));
+ source_add (data,
+ " gtk_clist_set_column_widget (GTK_CLIST (%s), %i, %s);\n",
+ parent_name, col + 1, data->wname);
+
+ gtk_object_set_data (GTK_OBJECT (parent), "last_child",
+ GINT_TO_POINTER (col + 1));
+ }
+ else
+ {
+ g_warning ("Unknown CTree child widgetL %s", data->wname);
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_ctree_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_ctree_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = ctree_xpm;
+ gbwidget.tooltip = _("Columned Tree");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_ctree_new;
+ gbwidget.gb_widget_add_child = gb_ctree_add_child;
+ gbwidget.gb_widget_create_properties = gb_ctree_create_properties;
+ gbwidget.gb_widget_get_properties = gb_ctree_get_properties;
+ gbwidget.gb_widget_set_properties = gb_ctree_set_properties;
+ gbwidget.gb_widget_write_source = gb_ctree_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_ctree_write_add_child_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_ctree_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbcurve.c b/tools/glade/glade/gbwidgets/gbcurve.c
new file mode 100644
index 00000000..7da60729
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcurve.c
@@ -0,0 +1,263 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkcurve.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/curve.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+#if 0
+static gchar *Type = "GtkCurve::curve_type";
+#endif
+static gchar *XMin = "GtkCurve::min_x";
+static gchar *XMax = "GtkCurve::max_x";
+static gchar *YMin = "GtkCurve::min_y";
+static gchar *YMax = "GtkCurve::max_y";
+
+#if 0
+static const gchar *GbTypeChoices[] =
+{"Linear", "Spline", "Free", NULL};
+static const gint GbTypeValues[] =
+{
+ GTK_CURVE_TYPE_LINEAR, /* linear interpolation */
+ GTK_CURVE_TYPE_SPLINE, /* spline interpolation */
+ GTK_CURVE_TYPE_FREE /* free form curve */
+};
+static const gchar *GbTypeSymbols[] =
+{
+ "GTK_CURVE_TYPE_LINEAR",
+ "GTK_CURVE_TYPE_SPLINE",
+ "GTK_CURVE_TYPE_FREE"
+};
+#endif
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkCurve, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_curve_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_curve_new ();
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_curve_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+#if 0
+ property_add_choice (Type, _("Type:"), _("The type of the curve"), GbTypeChoices);
+#endif
+ property_add_float (XMin, _("X Min:"), _("The minimum horizontal value"));
+ property_add_float (XMax, _("X Max:"), _("The maximum horizontal value"));
+ property_add_float (YMin, _("Y Min:"), _("The minimum vertical value"));
+ property_add_float (YMax, _("Y Max:"), _("The maximum vertical value"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_curve_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+#if 0
+ gint i;
+
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]); i++)
+ {
+ if (GbTypeValues[i] == GTK_CURVE (widget)->curve_type)
+ gb_widget_output_choice (data, Type, i, GbTypeSymbols[i]);
+ }
+#endif
+ gb_widget_output_float (data, XMin, GTK_CURVE (widget)->min_x);
+ gb_widget_output_float (data, XMax, GTK_CURVE (widget)->max_x);
+ gb_widget_output_float (data, YMin, GTK_CURVE (widget)->min_y);
+ gb_widget_output_float (data, YMax, GTK_CURVE (widget)->max_y);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_curve_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat min_x, max_x, min_y, max_y;
+ gboolean set_range = FALSE;
+
+#if 0
+ gint i;
+ gchar *type;
+
+ type = gb_widget_input_choice (data, Type);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]); i++)
+ {
+ if (!strcmp (type, GbTypeChoices[i])
+ || !strcmp (type, GbTypeSymbols[i]))
+ {
+ gtk_curve_set_curve_type (GTK_CURVE (widget), GbTypeValues[i]);
+ break;
+ }
+ }
+ }
+#endif
+
+ min_x = gb_widget_input_float (data, XMin);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ min_x = GTK_CURVE (widget)->min_x;
+
+ max_x = gb_widget_input_float (data, XMax);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ max_x = GTK_CURVE (widget)->max_x;
+
+ min_y = gb_widget_input_float (data, YMin);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ min_y = GTK_CURVE (widget)->min_y;
+
+ max_y = gb_widget_input_float (data, YMax);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ max_y = GTK_CURVE (widget)->max_y;
+
+ if (set_range)
+ gtk_curve_set_range (GTK_CURVE (widget), min_x, max_x, min_y, max_y);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkCurve, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_curve_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_curve_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkCurve *curve = GTK_CURVE (widget);
+#if 0
+ gint i;
+#endif
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_curve_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+#if 0
+ if (curve->curve_type != GTK_CURVE_TYPE_SPLINE)
+ {
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]); i++)
+ {
+ if (GbTypeValues[i] == curve->curve_type)
+ source_add (data,
+ " gtk_curve_set_curve_type (GTK_CURVE (%s), %s);\n",
+ data->wname, GbTypeSymbols[i]);
+ }
+ }
+#endif
+
+ source_add (data, " gtk_curve_set_range (GTK_CURVE (%s), %g, %g, %g, %g);\n",
+ data->wname, curve->min_x, curve->max_x,
+ curve->min_y, curve->max_y);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_curve_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_curve_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = curve_xpm;
+ gbwidget.tooltip = _("Curve");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_curve_new;
+ gbwidget.gb_widget_create_properties = gb_curve_create_properties;
+ gbwidget.gb_widget_get_properties = gb_curve_get_properties;
+ gbwidget.gb_widget_set_properties = gb_curve_set_properties;
+ gbwidget.gb_widget_write_source = gb_curve_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_curve_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbcustom.c b/tools/glade/glade/gbwidgets/gbcustom.c
new file mode 100644
index 00000000..c9faff00
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbcustom.c
@@ -0,0 +1,395 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* This custom GbWidget provides a simple way of allowing external widgets
+ to be used within an interface generated by Glade.
+ The 'Create Function' property specifies a function which will be called
+ to create the widget. 'String2', 'String2', 'Int1', 'Int2' are optional
+ arguments which will be passed to the creation function along with the
+ widget name. */
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/custom.xpm"
+
+/* Include the background pixmap to use inside custom widgets. */
+#include "../graphics/custom_bg.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *CreationFunction = "Custom::creation_function";
+static gchar *LastModTime = "Custom::last_modification_time";
+static gchar *String1 = "Custom::string1";
+static gchar *String2 = "Custom::string2";
+static gchar *Int1 = "Custom::int1";
+static gchar *Int2 = "Custom::int2";
+
+static time_t gb_custom_get_last_mod_time (GtkWidget *widget);
+static void gb_custom_set_last_mod_time (GtkWidget *widget,
+ time_t last_mod_time);
+static void gb_custom_on_widget_realize (GtkWidget *widget, gpointer data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class Custom, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_custom_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_drawing_area_new ();
+ gtk_object_set_data (GTK_OBJECT (new_widget), GLADE_CUSTOM_KEY, "True");
+
+ gtk_signal_connect_after (GTK_OBJECT (new_widget), "realize",
+ GTK_SIGNAL_FUNC (gb_custom_on_widget_realize),
+ NULL);
+
+ /* Set the initial last_mod_time. */
+ gb_custom_set_last_mod_time (new_widget, -1);
+
+ return new_widget;
+}
+
+
+/* We save the last modification time in the widget's datalist. */
+static time_t
+gb_custom_get_last_mod_time (GtkWidget *widget)
+{
+ time_t *current;
+
+ current = gtk_object_get_data (GTK_OBJECT (widget), LastModTime);
+ g_return_val_if_fail (current != NULL, 0);
+ return *current;
+}
+
+
+/* This sets the last modification time of the creation function name.
+ Use -1 to get the current time. */
+static void
+gb_custom_set_last_mod_time (GtkWidget *widget, time_t last_mod_time)
+{
+ time_t *current;
+
+ current = gtk_object_get_data (GTK_OBJECT (widget), LastModTime);
+ /* Create the time_t if it doesn't already exist. */
+ if (current == NULL)
+ {
+ current = g_new (time_t, 1);
+ gtk_object_set_data (GTK_OBJECT (widget), LastModTime, current);
+ }
+
+ if (last_mod_time == -1)
+ last_mod_time = time (NULL);
+ if (last_mod_time == (time_t) -1)
+ g_warning ("Can't get current time");
+
+ *current = last_mod_time;
+}
+
+
+static void
+gb_custom_on_widget_realize (GtkWidget *widget, gpointer data)
+{
+ static GdkPixmap *background_pixmap = NULL;
+
+#if 0
+ g_print ("In gb_custom_on_widget_realize widget:%s (%p)\n",
+ gtk_widget_get_name (widget), widget);
+#endif
+
+ /* Create the background pixmap if it hasn't already been created. */
+ if (background_pixmap == NULL)
+ {
+ background_pixmap = gdk_pixmap_create_from_xpm_d (widget->window,
+ NULL, NULL,
+ custom_bg_xpm);
+ if (!background_pixmap)
+ {
+ g_warning ("Couldn't create background pixmap\n");
+ /* FIXME: Use a color instead? */
+ }
+ }
+
+ if (background_pixmap != NULL)
+ gdk_window_set_back_pixmap (widget->window, background_pixmap, FALSE);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_custom_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (CreationFunction, _("Creation Function:"),
+ _("The function which creates the widget"));
+
+ property_add_string (String1, _("String1:"),
+ _("The first string argument to pass to the function"));
+ property_add_string (String2, _("String2:"),
+ _("The second string argument to pass to the function"));
+ property_add_int (Int1, _("Int1:"),
+ _("The first integer argument to pass to the function"));
+ property_add_int (Int2, _("Int2:"),
+ _("The second integer argument to pass to the function"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_custom_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar *string1, *string2;
+
+ gb_widget_output_string (data, CreationFunction, gtk_object_get_data (GTK_OBJECT (widget), CreationFunction));
+
+ string1 = gtk_object_get_data (GTK_OBJECT (widget), String1);
+ string2 = gtk_object_get_data (GTK_OBJECT (widget), String2);
+
+ /* For empty strings output NULL (i.e. don't save in the XML). */
+ if (string1 && *string1 == '\0')
+ string1 = NULL;
+ if (string2 && *string2 == '\0')
+ string2 = NULL;
+
+ gb_widget_output_string (data, String1, string1);
+ gb_widget_output_string (data, String2, string2);
+
+ gb_widget_output_int (data, Int1, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Int1)));
+ gb_widget_output_int (data, Int2, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Int2)));
+
+ /* When saving we also save the last modification time. */
+ if (data->action == GB_SAVING)
+ {
+ time_t last_mod_time;
+
+ last_mod_time = gb_custom_get_last_mod_time (widget);
+ if (last_mod_time != 0)
+ {
+ save_date (data, LastModTime, last_mod_time);
+ }
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_custom_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *creation_function, *string1, *string2;
+ gint int1, int2;
+
+ creation_function = gb_widget_input_string (data, CreationFunction);
+ if (data->apply)
+ {
+ g_free (gtk_object_get_data (GTK_OBJECT (widget), CreationFunction));
+ gtk_object_set_data (GTK_OBJECT (widget), CreationFunction,
+ g_strdup (creation_function));
+
+ /* If we are applying the property, we set the last modification time. */
+ if (data->action == GB_APPLYING)
+ {
+ gb_custom_set_last_mod_time (widget, -1);
+ }
+ }
+
+ string1 = gb_widget_input_string (data, String1);
+ if (data->apply)
+ {
+ g_free (gtk_object_get_data (GTK_OBJECT (widget), String1));
+ gtk_object_set_data (GTK_OBJECT (widget), String1, g_strdup (string1));
+ }
+
+ string2 = gb_widget_input_string (data, String2);
+ if (data->apply)
+ {
+ g_free (gtk_object_get_data (GTK_OBJECT (widget), String2));
+ gtk_object_set_data (GTK_OBJECT (widget), String2, g_strdup (string2));
+ }
+
+ int1 = gb_widget_input_int (data, Int1);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), Int1, GINT_TO_POINTER (int1));
+
+ int2 = gb_widget_input_int (data, Int2);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), Int2, GINT_TO_POINTER (int2));
+
+ /* If we are loading, load the last modification time. */
+ if (data->action == GB_LOADING)
+ {
+ time_t last_mod_time;
+
+ last_mod_time = load_date (data, LastModTime);
+ if (data->apply)
+ {
+ gb_custom_set_last_mod_time (widget, last_mod_time);
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a Custom, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_custom_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_custom_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *creation_func, *string1, *string2;
+ gint int1, int2;
+ time_t last_mod_time;
+
+ creation_func = gtk_object_get_data (GTK_OBJECT (widget), CreationFunction);
+ string1 = gtk_object_get_data (GTK_OBJECT (widget), String1);
+ string2 = gtk_object_get_data (GTK_OBJECT (widget), String2);
+ int1 = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Int1));
+ int2 = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Int2));
+
+ /* If no creation function has been set, we skip the widget. */
+ if (creation_func == NULL)
+ return;
+
+ creation_func = source_create_valid_identifier (creation_func);
+
+ /* Output "" if the strings are NULL, for consistency. */
+ if (string1 == NULL)
+ string1 = "";
+ if (string2 == NULL)
+ string2 = "";
+
+ if (string1)
+ string1 = g_strdup (source_make_string (string1, FALSE));
+ if (string2)
+ string2 = g_strdup (source_make_string (string2, FALSE));
+ /* Example output:
+ custom1 = create_custom1 ("custom1", "string1", "string2", 5, 10);
+ */
+ source_add (data, " %s = %s (%s, %s, %s, %i, %i);\n",
+ data->wname, creation_func,
+ source_make_string (data->real_wname, FALSE),
+ string1 ? string1 : "NULL", string2 ? string2 : "NULL",
+ int1, int2);
+ gb_widget_write_standard_source (widget, data);
+
+ /* Add declaration of creation function and empty function, just
+ like a signal handler. We need a last_modification_time property. */
+ last_mod_time = gb_custom_get_last_mod_time (widget);
+ if (data->creating_callback_files
+ || (last_mod_time > data->last_write_time))
+ {
+ source_add_to_buffer (data, GLADE_CALLBACK_DECLARATIONS,
+ "\nGtkWidget*\n"
+ "%s (gchar *widget_name, gchar *string1, gchar *string2,\n"
+ " gint int1, gint int2);\n",
+ creation_func);
+
+ source_add_to_buffer (data, GLADE_CALLBACK_SOURCE,
+ "\nGtkWidget*\n"
+ "%s (gchar *widget_name, gchar *string1, gchar *string2,\n"
+ " gint int1, gint int2)\n"
+ "{\n\n}\n\n",
+ creation_func);
+ }
+
+ g_free (creation_func);
+ g_free (string1);
+ g_free (string2);
+}
+
+
+static void
+gb_custom_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ /* We need to free the LastModTime. */
+ g_free (gtk_object_get_data (GTK_OBJECT (widget), LastModTime));
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_custom_init ()
+{
+ /* Initialise the GTK type. We don't need this. */
+ /* gtk_custom_get_type(); */
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = custom_xpm;
+ gbwidget.tooltip = _("Custom Widget");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_custom_new;
+ gbwidget.gb_widget_create_properties = gb_custom_create_properties;
+ gbwidget.gb_widget_get_properties = gb_custom_get_properties;
+ gbwidget.gb_widget_set_properties = gb_custom_set_properties;
+ gbwidget.gb_widget_write_source = gb_custom_write_source;
+ gbwidget.gb_widget_destroy = gb_custom_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_custom_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbdialog.c b/tools/glade/glade/gbwidgets/gbdialog.c
new file mode 100644
index 00000000..3d372804
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbdialog.c
@@ -0,0 +1,621 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtkbbox.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkstock.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/dialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "Dialog|GtkWindow::title";
+static gchar *Type = "Dialog|GtkWindow::type";
+static gchar *Position = "Dialog|GtkWindow::window_position";
+static gchar *Modal = "Dialog|GtkWindow::modal";
+static gchar *DefaultWidth = "Dialog|GtkWindow::default_width";
+static gchar *DefaultHeight = "Dialog|GtkWindow::default_height";
+static gchar *Shrink = "Dialog|GtkWindow::allow_shrink";
+static gchar *Grow = "Dialog|GtkWindow::allow_grow";
+static gchar *AutoShrink = "Dialog|GtkWindow::auto_shrink";
+static gchar *IconName = "Dialog|GtkWindow::icon_name";
+static gchar *FocusOnMap = "Dialog|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "Dialog|GtkWindow::resizable";
+static gchar *DestroyWithParent = "Dialog|GtkWindow::destroy_with_parent";
+static gchar *Icon = "Dialog|GtkWindow::icon";
+
+static gchar *Role = "Dialog|GtkWindow::role";
+static gchar *TypeHint = "Dialog|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "Dialog|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "Dialog|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "Dialog|GtkWindow::decorated";
+static gchar *Gravity = "Dialog|GtkWindow::gravity";
+
+static gchar *HasSeparator = "GtkDialog::has_separator";
+
+static gchar *Urgency = "Dialog|GtkWindow::urgency_hint";
+
+static void show_dialog_creation_dialog (GbWidgetNewData * data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+
+/* Action is GB_LOADING or GB_CREATING. */
+static GtkWidget*
+create_dialog (const gchar *title, GbWidgetAction action)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (new_widget), title);
+ gtk_window_set_policy (GTK_WINDOW (new_widget), TRUE, TRUE, FALSE);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ /* We need to size the placeholders or the dialog is very small. */
+ if (action == GB_CREATING)
+ {
+ GtkWidget *placeholder = editor_new_placeholder ();
+ gtk_widget_set_usize (placeholder, 300, 200);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (new_widget)->vbox), placeholder,
+ TRUE, TRUE, 0);
+ }
+
+ gb_widget_create_from (GTK_DIALOG (new_widget)->vbox,
+ action == GB_CREATING ? "dialog-vbox" : NULL);
+ gb_widget_set_child_name (GTK_DIALOG (new_widget)->vbox, GladeChildDialogVBox);
+
+ gb_widget_create_from (GTK_DIALOG (new_widget)->action_area,
+ action == GB_CREATING ? "dialog-action_area" : NULL);
+ gb_widget_set_child_name (GTK_DIALOG (new_widget)->action_area,
+ GladeChildDialogActionArea);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+/*
+ * Creates a new GtkWidget of class GtkDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_dialog_new (GbWidgetNewData * data)
+{
+ if (data->action == GB_LOADING)
+ {
+ return create_dialog (data->name, GB_LOADING);
+ }
+ else
+ {
+ show_dialog_creation_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+add_button (GtkDialog *dialog,
+ const gchar *stock_id,
+ gint response_id,
+ const gchar *name)
+{
+ GtkWidget *button;
+
+ button = gtk_dialog_add_button (dialog, stock_id, -1);
+ gb_widget_create_from (button, name);
+ gtk_object_set_data (GTK_OBJECT (button), GladeButtonStockIDKey,
+ (gpointer) stock_id);
+ gtk_object_set_data (GTK_OBJECT (button), GladeDialogResponseIDKey,
+ GINT_TO_POINTER (response_id));
+ if (response_id == GTK_RESPONSE_HELP)
+ gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (button->parent),
+ button, TRUE);
+}
+
+
+static void
+on_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *window, *button;
+ GtkWidget *cancel_ok, *just_ok, *cancel_apply_ok, *just_close;
+ GtkWidget *standard_layout, *num_buttons, *show_help_button;
+ GtkDialog *dialog;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (!gb_widget_can_finish_new (data))
+ {
+ gtk_widget_destroy (window);
+ return;
+ }
+
+ new_widget = create_dialog (data->name, GB_CREATING);
+ dialog = GTK_DIALOG (new_widget);
+
+ /* Get pointers to all the widgets in the creation dialog we need. */
+ standard_layout = gtk_object_get_data (GTK_OBJECT (window), "standard_layout");
+ cancel_ok = gtk_object_get_data (GTK_OBJECT (window), "cancel_ok");
+ just_ok = gtk_object_get_data (GTK_OBJECT (window), "just_ok");
+ cancel_apply_ok = gtk_object_get_data (GTK_OBJECT (window), "cancel_apply_ok");
+ just_close = gtk_object_get_data (GTK_OBJECT (window), "just_close");
+ num_buttons = gtk_object_get_data (GTK_OBJECT (window), "num_buttons");
+ show_help_button = gtk_object_get_data (GTK_OBJECT (window), "show_help_button");
+
+ if (GTK_TOGGLE_BUTTON (show_help_button)->active)
+ {
+ add_button (dialog, GTK_STOCK_HELP, GTK_RESPONSE_HELP, "helpbutton");
+ }
+
+ if (GTK_TOGGLE_BUTTON (standard_layout)->active)
+ {
+ if (GTK_TOGGLE_BUTTON (cancel_ok)->active)
+ {
+ add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ "cancelbutton");
+ add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK,
+ "okbutton");
+ }
+ else if (GTK_TOGGLE_BUTTON (just_ok)->active)
+ {
+ add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK,
+ "okbutton");
+ }
+ else if (GTK_TOGGLE_BUTTON (cancel_apply_ok)->active)
+ {
+ add_button (dialog, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
+ "applybutton");
+ add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ "cancelbutton");
+ add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK,
+ "okbutton");
+ }
+ else if (GTK_TOGGLE_BUTTON (just_close)->active)
+ {
+ add_button (dialog, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+ "closebutton");
+ }
+ }
+ else
+ {
+ gint buttons, i;
+
+ buttons = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (num_buttons));
+ /* We set the response_ids to 1,2,3 etc. */
+ for (i = 1; i <= buttons; i++)
+ {
+ button = gb_widget_new ("GtkButton", NULL);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_dialog_add_action_widget (GTK_DIALOG (new_widget), button, i);
+ }
+ }
+
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+static void on_standard_layout_toggled (GtkWidget *radiobutton,
+ GtkWidget *dialog)
+{
+ GtkWidget *cancel_ok, *just_ok, *cancel_apply_ok, *just_close;
+ GtkWidget *num_buttons;
+ gboolean sens;
+
+ cancel_ok = gtk_object_get_data (GTK_OBJECT (dialog), "cancel_ok");
+ just_ok = gtk_object_get_data (GTK_OBJECT (dialog), "just_ok");
+ cancel_apply_ok = gtk_object_get_data (GTK_OBJECT (dialog), "cancel_apply_ok");
+ just_close = gtk_object_get_data (GTK_OBJECT (dialog), "just_close");
+
+ num_buttons = gtk_object_get_data (GTK_OBJECT (dialog), "num_buttons");
+
+ sens = (GTK_TOGGLE_BUTTON (radiobutton)->active) ? TRUE : FALSE;
+
+ gtk_widget_set_sensitive (cancel_ok, sens);
+ gtk_widget_set_sensitive (just_ok, sens);
+ gtk_widget_set_sensitive (cancel_apply_ok, sens);
+ gtk_widget_set_sensitive (just_close, sens);
+
+ gtk_widget_set_sensitive (num_buttons, !sens);
+}
+
+
+static void
+show_dialog_creation_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox1;
+ GtkWidget *table1;
+ GtkWidget *cancel_ok;
+ GSList *layout_group_group = NULL;
+ GtkWidget *just_ok;
+ GtkWidget *cancel_apply_ok;
+ GtkWidget *just_close;
+ GtkWidget *standard_layout;
+ GSList *main_group_group = NULL;
+ GtkWidget *show_help_button;
+ GtkWidget *number_of_buttons;
+ GtkObject *num_buttons_adj;
+ GtkWidget *num_buttons;
+
+ dialog = glade_util_create_dialog (_("New dialog"), data->parent,
+ GTK_SIGNAL_FUNC (on_dialog_ok),
+ data, &vbox1);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_dialog_destroy), data);
+
+ table1 = gtk_table_new (7, 2, FALSE);
+ gtk_widget_show (table1);
+ gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (table1), 8);
+ gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
+
+ cancel_ok = gtk_radio_button_new_with_mnemonic (NULL, _("Cancel, OK"));
+ gtk_object_set_data (GTK_OBJECT (dialog), "cancel_ok", cancel_ok);
+ gtk_widget_show (cancel_ok);
+ gtk_table_attach (GTK_TABLE (table1), cancel_ok, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (cancel_ok), layout_group_group);
+ layout_group_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (cancel_ok));
+
+ just_ok = gtk_radio_button_new_with_mnemonic (NULL, _("OK"));
+ gtk_object_set_data (GTK_OBJECT (dialog), "just_ok", just_ok);
+ gtk_widget_show (just_ok);
+ gtk_table_attach (GTK_TABLE (table1), just_ok, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (just_ok), layout_group_group);
+ layout_group_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (just_ok));
+
+ cancel_apply_ok = gtk_radio_button_new_with_mnemonic (NULL, _("Cancel, Apply, OK"));
+ gtk_object_set_data (GTK_OBJECT (dialog), "cancel_apply_ok", cancel_apply_ok);
+ gtk_widget_show (cancel_apply_ok);
+ gtk_table_attach (GTK_TABLE (table1), cancel_apply_ok, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (cancel_apply_ok), layout_group_group);
+ layout_group_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (cancel_apply_ok));
+
+ just_close = gtk_radio_button_new_with_mnemonic (NULL, _("Close"));
+ gtk_object_set_data (GTK_OBJECT (dialog), "just_close", just_close);
+ gtk_widget_show (just_close);
+ gtk_table_attach (GTK_TABLE (table1), just_close, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (just_close), layout_group_group);
+ layout_group_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (just_close));
+
+ standard_layout = gtk_radio_button_new_with_mnemonic (NULL, _("_Standard Button Layout:"));
+ gtk_object_set_data (GTK_OBJECT (dialog), "standard_layout", standard_layout);
+ gtk_widget_show (standard_layout);
+ gtk_table_attach (GTK_TABLE (table1), standard_layout, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (standard_layout), main_group_group);
+ main_group_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (standard_layout));
+
+ number_of_buttons = gtk_radio_button_new_with_mnemonic (NULL, _("_Number of Buttons:"));
+ gtk_widget_show (number_of_buttons);
+ gtk_table_attach (GTK_TABLE (table1), number_of_buttons, 0, 1, 5, 6,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (number_of_buttons), main_group_group);
+ main_group_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (number_of_buttons));
+
+ num_buttons_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
+ num_buttons = gtk_spin_button_new (GTK_ADJUSTMENT (num_buttons_adj), 1, 0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (num_buttons), TRUE);
+ gtk_object_set_data (GTK_OBJECT (dialog), "num_buttons", num_buttons);
+ gtk_widget_show (num_buttons);
+ gtk_table_attach (GTK_TABLE (table1), num_buttons, 1, 2, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 4);
+
+ show_help_button = gtk_check_button_new_with_mnemonic (_("Show Help Button"));
+ gtk_object_set_data (GTK_OBJECT (dialog), "show_help_button", show_help_button);
+ gtk_widget_show (show_help_button);
+ gtk_table_attach (GTK_TABLE (table1), show_help_button, 0, 2, 6, 7,
+ (GtkAttachOptions) (0),
+ (GtkAttachOptions) (0), 0, 6);
+
+ gtk_widget_set_sensitive (num_buttons, FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (standard_layout), "toggled",
+ GTK_SIGNAL_FUNC (on_standard_layout_toggled), dialog);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_dialog_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ property_add_bool (HasSeparator, _("Has Separator:"),
+ _("If the dialog has a horizontal separator above the buttons"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_dialog_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ gb_widget_output_bool (data, HasSeparator,
+ gtk_dialog_get_has_separator (GTK_DIALOG (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_dialog_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean has_separator;
+
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ has_separator = gb_widget_input_bool (data, HasSeparator);
+ if (data->apply)
+ {
+ gtk_dialog_set_has_separator (GTK_DIALOG (widget), has_separator);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_dialog_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_dialog_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_dialog_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_window_write_standard_source (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (!gtk_dialog_get_has_separator (GTK_DIALOG (widget)))
+ {
+ source_add (data, " gtk_dialog_set_has_separator (GTK_DIALOG (%s), FALSE);\n",
+ data->wname);
+ }
+
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_DIALOG (<dialog-name>)->vbox".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (gchar*) gtk_widget_get_name (GTK_DIALOG (widget)->vbox);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = gtk_dialog_get_content_area (GTK_DIALOG (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_DIALOG (widget)->vbox, data);
+
+ /* action_area is a child of vbox so I had to add a kludge to stop it
+ being written as a normal child - we need to do it here so that we
+ don't output code to create it. */
+ child_name = (gchar*) gtk_widget_get_name (GTK_DIALOG (widget)->action_area);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = gtk_dialog_get_action_area (GTK_DIALOG (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_DIALOG (widget)->action_area, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+
+static GtkWidget *
+gb_dialog_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildDialogVBox))
+ return GTK_DIALOG (widget)->vbox;
+ else if (!strcmp (child_name, GladeChildDialogActionArea))
+ return GTK_DIALOG (widget)->action_area;
+ else
+ return NULL;
+}
+
+
+/* Converts a response id to a string, either a standard GTK+ response string
+ such as "GTK_RESPONSE_OK" or an integer e.g. "1". Note that for integers
+ it uses a static buffer. */
+char*
+gb_dialog_response_id_to_string (gint response_id)
+{
+ gint i;
+
+ if (response_id >= 0)
+ {
+ static char buffer[16];
+
+ sprintf (buffer, "%i", response_id);
+ return buffer;
+ }
+
+ for (i = 0; i < GladeStockResponsesSize; i++)
+ {
+ if (GladeStockResponses[i].response_id == response_id)
+ return GladeStockResponses[i].name;
+ }
+
+ return "0";
+}
+
+
+gint
+gb_dialog_response_id_from_string (const gchar *response_id)
+{
+ gint i;
+
+ if (!response_id || !*response_id)
+ return 0;
+
+ for (i = 0; i < GladeStockResponsesSize; i++)
+ {
+ if (!strcmp (GladeStockResponses[i].name, response_id))
+ return GladeStockResponses[i].response_id;
+ }
+
+ return atoi (response_id);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_dialog_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = dialog_xpm;
+ gbwidget.tooltip = _("Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_dialog_new;
+ gbwidget.gb_widget_create_properties = gb_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_dialog_set_properties;
+ gbwidget.gb_widget_get_child = gb_dialog_get_child;
+ gbwidget.gb_widget_write_source = gb_dialog_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_dialog_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbdrawingarea.c b/tools/glade/glade/gbwidgets/gbdrawingarea.c
new file mode 100644
index 00000000..3b93d69d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbdrawingarea.c
@@ -0,0 +1,159 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkdrawingarea.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/drawingarea.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkDrawingArea, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_drawing_area_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+ static void
+ gb_drawing_area_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+ static void
+ gb_drawing_area_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+ static void
+ gb_drawing_area_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkDrawingArea, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_drawing_area_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_drawing_area_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_drawing_area_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_drawing_area_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_drawing_area_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = drawingarea_xpm;
+ gbwidget.tooltip = _("Drawing Area");
+
+ /* Fill in any functions that this GbWidget has */
+/*
+ gbwidget.gb_widget_new = gb_drawing_area_new;
+ gbwidget.gb_widget_create_properties = gb_drawing_area_create_properties;
+ gbwidget.gb_widget_get_properties = gb_drawing_area_get_properties;
+ gbwidget.gb_widget_set_properties = gb_drawing_area_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_drawing_area_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_drawing_area_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbentry.c b/tools/glade/glade/gbwidgets/gbentry.c
new file mode 100644
index 00000000..528face1
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbentry.c
@@ -0,0 +1,331 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtktogglebutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/entry.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Editable = "Entry|GtkEditable::editable";
+static gchar *Visible = "GtkEntry::visibility";
+static gchar *MaxLength = "GtkEntry::max_length";
+static gchar *Text = "GtkEntry::text";
+
+static gchar *HasFrame = "GtkEntry::has_frame";
+static gchar *InvisibleChar = "GtkEntry::invisible_char";
+static gchar *ActivatesDefault = "GtkEntry::activates_default";
+static gchar *WidthChars = "GtkEntry::width_chars";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkEntry, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_entry_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+static void
+on_toggle_width_chars (GtkWidget * widget, gpointer value)
+{
+ GtkWidget *property_widget;
+ gboolean value_set;
+ gint width = -1;
+
+ property_widget = property_get_widget ();
+ if (property_widget == NULL)
+ return;
+
+ value_set = GTK_TOGGLE_BUTTON (widget)->active ? TRUE : FALSE;
+ gtk_widget_set_sensitive (GTK_WIDGET (value), value_set);
+ if (value_set)
+ {
+ width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (property_widget), WidthChars));
+ }
+
+ gtk_entry_set_width_chars (GTK_ENTRY (property_widget), width);
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_entry_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Editable, _("Editable:"), _("If the text can be edited"));
+ property_add_bool (Visible, _("Text Visible:"),
+ _("If the text entered by the user will be shown. When turned off, the text typed in is displayed as asterix characters, which is useful for entering passwords"));
+ property_add_int_range (MaxLength, _("Max Length:"),
+ _("The maximum length of the text"),
+ 0, 10000, 1, 10, 1);
+ property_add_string (Text, _("Text:"), _("The text to display"));
+
+ property_add_bool (HasFrame, _("Has Frame:"), _("If the entry has a frame around it"));
+ property_add_string (InvisibleChar, _("Invisible Char:"), _("The character to use if the text should not visible, e.g. when entering passwords"));
+ property_add_bool (ActivatesDefault, _("Activates Default:"), _("If the default widget in the window is activated when Enter is pressed"));
+ property_add_optional_int_range (WidthChars, _("Width In Chars:"), _("The number of characters to leave space for in the entry"),
+ 0, 10000, 1, 10, 1,
+ on_toggle_width_chars);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_entry_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gchar buf[8];
+ gint len, width;
+ const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (widget));
+ gb_widget_output_bool (data, Editable, GTK_ENTRY (widget)->editable);
+ gb_widget_output_bool (data, Visible, GTK_ENTRY (widget)->visible);
+ gb_widget_output_int (data, MaxLength, GTK_ENTRY (widget)->text_max_length);
+ gb_widget_output_translatable_string (data, Text, entry_text);
+
+ gb_widget_output_bool (data, HasFrame,
+ gtk_entry_get_has_frame (GTK_ENTRY (widget)));
+ len = g_unichar_to_utf8 (gtk_entry_get_invisible_char (GTK_ENTRY (widget)),
+ buf);
+ buf[len] = '\0';
+ gb_widget_output_string (data, InvisibleChar, buf);
+ gb_widget_output_bool (data, ActivatesDefault,
+ gtk_entry_get_activates_default (GTK_ENTRY (widget)));
+
+ width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ WidthChars));
+ gb_widget_output_optional_int (data, WidthChars, width,
+ gtk_entry_get_width_chars (GTK_ENTRY (widget)) != -1);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_entry_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean editable, visible, has_frame, activates_default, is_set;
+ gint max_length, width_chars;
+ gchar *text, *invisible_char;
+
+ editable = gb_widget_input_bool (data, Editable);
+ if (data->apply)
+ gtk_editable_set_editable (GTK_EDITABLE (widget), editable);
+
+ visible = gb_widget_input_bool (data, Visible);
+ if (data->apply)
+ gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+
+ max_length = gb_widget_input_int (data, MaxLength);
+ if (data->apply)
+ gtk_entry_set_max_length (GTK_ENTRY (widget), max_length);
+
+ text = gb_widget_input_string (data, Text);
+ if (data->apply)
+ gtk_entry_set_text (GTK_ENTRY (widget), text);
+
+ has_frame = gb_widget_input_bool (data, HasFrame);
+ if (data->apply)
+ gtk_entry_set_has_frame (GTK_ENTRY (widget), has_frame);
+
+ invisible_char = gb_widget_input_string (data, InvisibleChar);
+ if (data->apply)
+ {
+ gunichar c = g_utf8_get_char_validated (invisible_char, -1);
+ if (c > 0)
+ gtk_entry_set_invisible_char (GTK_ENTRY (widget), c);
+ }
+
+ activates_default = gb_widget_input_bool (data, ActivatesDefault);
+ if (data->apply)
+ gtk_entry_set_activates_default (GTK_ENTRY (widget), activates_default);
+
+ width_chars = gb_widget_input_optional_int (data, WidthChars, &is_set);
+ if (data->apply)
+ {
+ if (is_set)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), WidthChars,
+ GINT_TO_POINTER (width_chars));
+ gtk_entry_set_width_chars (GTK_ENTRY (widget), width_chars);
+ }
+ else
+ {
+ gtk_entry_set_width_chars (GTK_ENTRY (widget), -1);
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkEntry, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_entry_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_entry_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ guint16 max_len = GTK_ENTRY (widget)->text_max_length;
+ const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (widget));
+ gunichar c;
+ gint width_chars;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_entry_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (max_len)
+ {
+ source_add (data, " gtk_entry_set_max_length (GTK_ENTRY (%s), %d);\n",
+ data->wname, max_len);
+ }
+ if (!GTK_ENTRY (widget)->editable)
+ {
+ source_add (data, " gtk_editable_set_editable (GTK_EDITABLE (%s), FALSE);\n",
+ data->wname);
+ }
+ if (!GTK_ENTRY (widget)->visible)
+ {
+ source_add (data, " gtk_entry_set_visibility (GTK_ENTRY (%s), FALSE);\n",
+ data->wname);
+ }
+ if (entry_text && strlen (entry_text) > 0)
+ {
+ glade_util_get_translation_properties (widget, Text, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " gtk_entry_set_text (GTK_ENTRY (%s), %s);\n",
+ data->wname,
+ source_make_string_full (entry_text, data->use_gettext && translatable, context));
+ }
+
+ if (!gtk_entry_get_has_frame (GTK_ENTRY (widget)))
+ {
+ source_add (data, " gtk_entry_set_has_frame (GTK_ENTRY (%s), FALSE);\n",
+ data->wname);
+ }
+
+ c = gtk_entry_get_invisible_char (GTK_ENTRY (widget));
+ if (c != '*')
+ {
+ /* We just output the integer Unicode character code. I think that is
+ OK. */
+ source_add (data,
+ " gtk_entry_set_invisible_char (GTK_ENTRY (%s), %i);\n",
+ data->wname, c);
+ }
+
+ if (gtk_entry_get_activates_default (GTK_ENTRY (widget)))
+ {
+ source_add (data,
+ " gtk_entry_set_activates_default (GTK_ENTRY (%s), TRUE);\n",
+ data->wname);
+ }
+
+ width_chars = gtk_entry_get_width_chars (GTK_ENTRY (widget));
+ if (width_chars != -1)
+ {
+ source_add (data,
+ " gtk_entry_set_width_chars (GTK_ENTRY (%s), %i);\n",
+ data->wname, width_chars);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_entry_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_entry_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = entry_xpm;
+ gbwidget.tooltip = _("Text Entry");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_entry_create_properties;
+ gbwidget.gb_widget_get_properties = gb_entry_get_properties;
+ gbwidget.gb_widget_set_properties = gb_entry_set_properties;
+/*
+ gbwidget.gb_widget_new = gb_entry_new;
+ gbwidget.gb_widget_create_popup_menu = gb_entry_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_entry_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbeventbox.c b/tools/glade/glade/gbwidgets/gbeventbox.c
new file mode 100644
index 00000000..b23d1f35
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbeventbox.c
@@ -0,0 +1,180 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkeventbox.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/eventbox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *VisibleWindow = "GtkEventBox::visible_window";
+static gchar *AboveChild = "GtkEventBox::above_child";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkEventBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_event_box_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_event_box_new ();
+ if (data->action != GB_LOADING)
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_event_box_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+{
+ property_add_bool (VisibleWindow, _("Visible Window:"), _("If the event box uses a visible window"));
+ property_add_bool (AboveChild, _("Above Child:"), _("If the event box window is above the child widget's window"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_event_box_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+{
+ gb_widget_output_bool (data, VisibleWindow,
+ gtk_event_box_get_visible_window (GTK_EVENT_BOX (widget)));
+ gb_widget_output_bool (data, AboveChild,
+ gtk_event_box_get_above_child (GTK_EVENT_BOX (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_event_box_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+{
+ gboolean visible_window, above_child;
+
+ visible_window = gb_widget_input_bool (data, VisibleWindow);
+ if (data->apply)
+ gtk_event_box_set_visible_window (GTK_EVENT_BOX (widget), visible_window);
+
+ above_child = gb_widget_input_bool (data, AboveChild);
+ if (data->apply)
+ gtk_event_box_set_above_child (GTK_EVENT_BOX (widget), above_child);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkEventBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_event_box_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_event_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_event_box_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (!gtk_event_box_get_visible_window (GTK_EVENT_BOX (widget)))
+ {
+ source_add (data, " gtk_event_box_set_visible_window (GTK_EVENT_BOX (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_event_box_get_above_child (GTK_EVENT_BOX (widget)))
+ {
+ source_add (data, " gtk_event_box_set_above_child (GTK_EVENT_BOX (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_event_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_event_box_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = eventbox_xpm;
+ gbwidget.tooltip = _("Event Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_event_box_new;
+ gbwidget.gb_widget_create_properties = gb_event_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_event_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_event_box_set_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_event_box_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_event_box_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbexpander.c b/tools/glade/glade/gbwidgets/gbexpander.c
new file mode 100644
index 00000000..ad9e90d5
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbexpander.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Mark McLoughlin <mark@skynet.ie>
+ */
+
+#include "../gb.h"
+#include <gtk/gtkexpander.h>
+
+#include "../graphics/expander.xpm"
+
+#define PROPERTY_EXPANDED "GtkExpander::expanded"
+#define PROPERTY_SPACING "GtkExpander::spacing"
+
+static GbWidget gb_expander;
+
+GtkWidget *
+gb_expander_new (GbWidgetNewData *data)
+{
+ GtkWidget *expander = gtk_expander_new (NULL);
+
+ if (data->action != GB_LOADING)
+ {
+ GtkWidget *label;
+
+ gtk_container_add (GTK_CONTAINER (expander), editor_new_placeholder ());
+ label = gb_widget_new ("GtkLabel", NULL);
+ gtk_expander_set_label_widget (GTK_EXPANDER (expander), label);
+ }
+
+ return expander;
+}
+
+static void
+gb_expander_create_properties (GtkWidget *widget,
+ GbWidgetCreateArgData *data)
+{
+ property_add_bool (PROPERTY_EXPANDED,
+ _("Initially Expanded:"),
+ _("Whether the expander is initially opened to reveal the child widget"));
+ property_add_int_range (PROPERTY_SPACING,
+ _("Spacing:"),
+ _("Space to put between the label and the child"),
+ 0, 1000, 1, 10, 1);
+}
+
+static void
+gb_expander_get_properties (GtkWidget *widget,
+ GbWidgetGetArgData *data)
+{
+ gb_widget_output_bool (data,
+ PROPERTY_EXPANDED,
+ gtk_expander_get_expanded (GTK_EXPANDER (widget)));
+ gb_widget_output_int (data,
+ PROPERTY_SPACING,
+ gtk_expander_get_spacing (GTK_EXPANDER (widget)));
+}
+
+static void
+gb_expander_set_properties (GtkWidget *widget,
+ GbWidgetSetArgData *data)
+{
+ gboolean expanded;
+ int spacing;
+
+ expanded = gb_widget_input_bool (data, PROPERTY_EXPANDED);
+ if (data->apply)
+ gtk_expander_set_expanded (GTK_EXPANDER (widget), expanded);
+
+ spacing = gb_widget_input_int (data, PROPERTY_SPACING);
+ if (data->apply)
+ gtk_expander_set_spacing (GTK_EXPANDER (widget), spacing);
+}
+
+static void
+gb_expander_add_label_widget (GtkWidget *menuitem,
+ GtkExpander *expander)
+{
+ gtk_expander_set_label_widget (expander, editor_new_placeholder ());
+}
+
+void
+gb_expander_create_popup_menu (GtkWidget *widget,
+ GbWidgetCreateMenuData *data)
+{
+ GtkWidget *menuitem;
+
+ if (!gtk_expander_get_label_widget (GTK_EXPANDER (widget)))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Label Widget"));
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (gb_expander_add_label_widget), widget);
+ gtk_widget_show (menuitem);
+ }
+}
+
+void
+gb_expander_add_child (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gboolean is_label_item = FALSE;
+
+ if (data->child_info)
+ {
+ int j;
+
+ for (j = 0; j < data->child_info->n_properties; j++)
+ {
+ if (!strcmp (data->child_info->properties[j].name, "type") &&
+ !strcmp (data->child_info->properties[j].value, "label_item"))
+ {
+ is_label_item = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (is_label_item)
+ gtk_expander_set_label_widget (GTK_EXPANDER (widget), child);
+ else
+ gtk_container_add (GTK_CONTAINER (widget), child);
+}
+
+#if 0
+/* This is in gb_widget_replace_child() now. */
+static void
+gb_expander_replace_child (GtkWidget *widget,
+ GtkWidget *current_child,
+ GtkWidget *new_child)
+{
+ /* If this is the expander's label widget, we replace that. */
+ if (gtk_expander_get_label_widget (GTK_EXPANDER (widget)) == current_child)
+ {
+ gtk_expander_set_label_widget (GTK_EXPANDER (widget), new_child);
+ }
+ else
+ {
+ gtk_container_remove (GTK_CONTAINER (widget), current_child);
+ gtk_container_add (GTK_CONTAINER (widget), new_child);
+ }
+}
+#endif
+
+static void
+gb_expander_write_source (GtkWidget *widget,
+ GbWidgetWriteSourceData *data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_expander_new (NULL);\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (gtk_expander_get_expanded (GTK_EXPANDER (widget)))
+ {
+ source_add (data,
+ " gtk_expander_set_expanded (GTK_EXPANDER (%s), %s);\n",
+ data->wname,
+ gtk_expander_get_expanded (GTK_EXPANDER (widget)) ? "TRUE" : "FALSE");
+ }
+
+ if (gtk_expander_get_spacing (GTK_EXPANDER (widget)) != 0)
+ {
+ source_add (data,
+ " gtk_expander_set_spacing (GTK_EXPANDER (%s), %d);\n",
+ data->wname,
+ gtk_expander_get_spacing (GTK_EXPANDER (widget)));
+ }
+}
+
+void
+gb_expander_get_child_properties (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ if (data->action == GB_SAVING &&
+ gtk_expander_get_label_widget (GTK_EXPANDER (widget)) == child)
+ {
+ save_start_tag (data, "packing");
+ save_string (data, "type", "label_item");
+ save_end_tag (data, "packing");
+ }
+}
+
+void
+gb_expander_write_add_child_source (GtkWidget *parent,
+ const char *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData *data)
+{
+ if (gtk_expander_get_label_widget (GTK_EXPANDER (parent)) == child)
+ {
+ source_add (data,
+ " gtk_expander_set_label_widget (GTK_EXPANDER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else
+ {
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+GbWidget *
+gb_expander_init ()
+{
+ gb_widget_init_struct (&gb_expander);
+
+ gb_expander.pixmap_struct = expander_xpm;
+ gb_expander.tooltip = _("Expander");
+
+ gb_expander.gb_widget_new = gb_expander_new;
+ gb_expander.gb_widget_create_properties = gb_expander_create_properties;
+ gb_expander.gb_widget_get_properties = gb_expander_get_properties;
+ gb_expander.gb_widget_set_properties = gb_expander_set_properties;
+ gb_expander.gb_widget_create_popup_menu = gb_expander_create_popup_menu;
+ gb_expander.gb_widget_write_source = gb_expander_write_source;
+
+ gb_expander.gb_widget_add_child = gb_expander_add_child;
+ gb_expander.gb_widget_get_child_properties = gb_expander_get_child_properties;
+ gb_expander.gb_widget_write_add_child_source = gb_expander_write_add_child_source;
+
+ return &gb_expander;
+}
diff --git a/tools/glade/glade/gbwidgets/gbfilechooserbutton.c b/tools/glade/glade/gbwidgets/gbfilechooserbutton.c
new file mode 100644
index 00000000..f2330b6f
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfilechooserbutton.c
@@ -0,0 +1,309 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/filechooserbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Action = "GtkFileChooserButton::action";
+static gchar *LocalOnly = "GtkFileChooserButton::local_only";
+static gchar *ShowHidden = "GtkFileChooserButton::show_hidden";
+static gchar *Confirm = "GtkFileChooserButton::do_overwrite_confirmation";
+static gchar *Title = "GtkFileChooserButton::title";
+static gchar *WidthChars = "GtkFileChooserButton::width_chars";
+
+
+/* Note that GtkFileChooserButton doesn't support "Save" or "Create Folder". */
+static const gchar *GbActionChoices[] =
+{"Open", "Select Folder", NULL};
+static const gint GbActionValues[] =
+{
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
+};
+static const gchar *GbActionSymbols[] =
+{
+ "GTK_FILE_CHOOSER_ACTION_OPEN",
+ "GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFileChooser, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_file_chooser_button_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_file_chooser_button_new (NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_file_chooser_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (Title, _("Title:"),
+ _("The window title of the file chooser dialog"));
+ property_add_choice (Action, _("Action:"),
+ _("The type of file operation being performed"),
+ GbActionChoices);
+ property_add_bool (LocalOnly, _("Local Only:"),
+ _("Whether the selected files should be limited to local files"));
+ property_add_bool (ShowHidden, _("Show Hidden:"),
+ _("Whether the hidden files and folders should be displayed"));
+ property_add_bool (Confirm, _("Confirm:"),
+ _("Whether a confirmation dialog will be displayed if a file will be overwritten"));
+ property_add_int_range (WidthChars, _("Width in Chars:"),
+ _("The width of the button in characters"),
+ -1, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_file_chooser_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar *title;
+ GtkFileChooserAction action;
+ gboolean local_only, show_hidden, confirm;
+ gint i, width_chars;
+
+ g_object_get (widget,
+ "title", &title,
+ "action", &action,
+ "local_only", &local_only,
+ "show_hidden", &show_hidden,
+ "do_overwrite_confirmation", &confirm,
+ "width_chars", &width_chars,
+ NULL);
+
+ gb_widget_output_translatable_string (data, Title, title);
+ g_free (title);
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]); i++)
+ {
+ if (GbActionValues[i] == action)
+ gb_widget_output_choice (data, Action, i, GbActionSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, LocalOnly, local_only);
+ gb_widget_output_bool (data, ShowHidden, show_hidden);
+ gb_widget_output_bool (data, Confirm, confirm);
+ gb_widget_output_int (data, WidthChars, width_chars);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_file_chooser_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *title, *action;
+ gboolean local_only, show_hidden, confirm;
+ gint i, width_chars;
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ g_object_set (widget, "title", title, NULL);
+
+ action = gb_widget_input_choice (data, Action);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (!strcmp (action, GbActionChoices[i])
+ || !strcmp (action, GbActionSymbols[i]))
+ {
+ g_object_set (widget, "action", GbActionValues[i], NULL);
+ break;
+ }
+ }
+ }
+
+ local_only = gb_widget_input_bool (data, LocalOnly);
+ if (data->apply)
+ g_object_set (widget, "local_only", local_only, NULL);
+
+ show_hidden = gb_widget_input_bool (data, ShowHidden);
+ if (data->apply)
+ g_object_set (widget, "show_hidden", show_hidden, NULL);
+
+ confirm = gb_widget_input_bool (data, Confirm);
+ if (data->apply)
+ g_object_set (widget, "do_overwrite_confirmation", confirm, NULL);
+
+ width_chars = gb_widget_input_int (data, WidthChars);
+ if (data->apply)
+ g_object_set (widget, "width_chars", width_chars, NULL);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFileChooser, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_file_chooser_widget_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_file_chooser_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *title;
+ GtkFileChooserAction action;
+ gboolean local_only, show_hidden, confirm;
+ gint width_chars;
+ const gchar *action_symbol = GbActionSymbols[0];
+ gint i;
+
+ g_object_get (widget,
+ "title", &title,
+ "action", &action,
+ "local_only", &local_only,
+ "show_hidden", &show_hidden,
+ "do_overwrite_confirmation", &confirm,
+ "width_chars", &width_chars,
+ NULL);
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]); i++)
+ {
+ if (GbActionValues[i] == action)
+ action_symbol = GbActionSymbols[i];
+ }
+
+ if (data->create_widget)
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " %s = gtk_file_chooser_button_new (%s, %s);\n",
+ data->wname,
+ source_make_string_full (title, data->use_gettext && translatable, context),
+ action_symbol);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!local_only || show_hidden || width_chars != -1 || confirm)
+ {
+ source_add (data, " g_object_set (%s,\n", data->wname);
+
+ if (!local_only)
+ source_add (data, " \"local-only\", FALSE,\n");
+
+ if (show_hidden)
+ source_add (data, " \"show-hidden\", TRUE,\n");
+
+ if (confirm)
+ source_add (data, " \"confirm\", TRUE,\n");
+
+ if (width_chars != -1)
+ source_add (data, " \"width-chars\", %i,\n",
+ width_chars);
+
+ source_add (data, " NULL);\n");
+ }
+
+ g_free (title);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_file_chooser_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_file_chooser_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = filechooserbutton_xpm;
+ gbwidget.tooltip = _("File Chooser Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_file_chooser_button_new;
+ gbwidget.gb_widget_create_properties = gb_file_chooser_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_file_chooser_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_file_chooser_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_file_chooser_button_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_file_chooser_widget_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbfilechooserdialog.c b/tools/glade/glade/gbwidgets/gbfilechooserdialog.c
new file mode 100644
index 00000000..b80a5402
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfilechooserdialog.c
@@ -0,0 +1,451 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/filechooserdialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "FileChooserDialog|GtkWindow::title";
+static gchar *Type = "FileChooserDialog|GtkWindow::type";
+static gchar *Position = "FileChooserDialog|GtkWindow::window_position";
+static gchar *Modal = "FileChooserDialog|GtkWindow::modal";
+static gchar *DefaultWidth = "FileChooserDialog|GtkWindow::default_width";
+static gchar *DefaultHeight = "FileChooserDialog|GtkWindow::default_height";
+static gchar *Shrink = "FileChooserDialog|GtkWindow::allow_shrink";
+static gchar *Grow = "FileChooserDialog|GtkWindow::allow_grow";
+static gchar *AutoShrink = "FileChooserDialog|GtkWindow::auto_shrink";
+static gchar *IconName = "FileChooserDialog|GtkWindow::icon_name";
+static gchar *FocusOnMap = "FileChooserDialog|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "FileChooserDialog|GtkWindow::resizable";
+static gchar *DestroyWithParent = "FileChooserDialog|GtkWindow::destroy_with_parent";
+static gchar *Icon = "FileChooserDialog|GtkWindow::icon";
+
+static gchar *Role = "FileChooserDialog|GtkWindow::role";
+static gchar *TypeHint = "FileChooserDialog|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "FileChooserDialog|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "FileChooserDialog|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "FileChooserDialog|GtkWindow::decorated";
+static gchar *Gravity = "FileChooserDialog|GtkWindow::gravity";
+
+static gchar *Action = "GtkFileChooserDialog::action";
+static gchar *LocalOnly = "GtkFileChooserDialog::local_only";
+static gchar *SelectMultiple = "GtkFileChooserDialog::select_multiple";
+static gchar *ShowHidden = "GtkFileChooserDialog::show_hidden";
+static gchar *Confirm = "GtkFileChooserDialog::do_overwrite_confirmation";
+static gchar *Urgency = "FileChooserDialog|GtkWindow::urgency_hint";
+
+
+static const gchar *GbActionChoices[] =
+{"Open", "Save", "Select Folder", "Create Folder", NULL};
+static const gint GbActionValues[] =
+{
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+};
+static const gchar *GbActionSymbols[] =
+{
+ "GTK_FILE_CHOOSER_ACTION_OPEN",
+ "GTK_FILE_CHOOSER_ACTION_SAVE",
+ "GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER",
+ "GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFileChooserDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_file_chooser_dialog_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *button;
+
+ new_widget = gtk_file_chooser_dialog_new (NULL, NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ NULL);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+
+ gb_widget_create_from (GTK_DIALOG (new_widget)->vbox,
+ data->action == GB_CREATING ? "dialog-content_area" : NULL);
+ gb_widget_set_child_name (GTK_DIALOG (new_widget)->vbox, GladeChildDialogVBox);
+
+ gb_widget_create_from (GTK_DIALOG (new_widget)->action_area,
+ data->action == GB_CREATING ? "dialog-action_area" : NULL);
+ gb_widget_set_child_name (GTK_DIALOG (new_widget)->action_area,
+ GladeChildDialogActionArea);
+
+
+ if (data->action == GB_CREATING)
+ {
+ GladeWidgetData *wdata;
+
+ button = gtk_dialog_add_button (GTK_DIALOG (new_widget),
+ GTK_STOCK_CANCEL, -1);
+ gb_widget_create_from (button, "button");
+ gtk_object_set_data (GTK_OBJECT (button), GladeButtonStockIDKey,
+ (gpointer) GTK_STOCK_CANCEL);
+ gtk_object_set_data (GTK_OBJECT (button), GladeDialogResponseIDKey,
+ GINT_TO_POINTER (GTK_RESPONSE_CANCEL));
+
+ button = gtk_dialog_add_button (GTK_DIALOG (new_widget),
+ GTK_STOCK_OPEN, -1);
+ gb_widget_create_from (button, "button");
+ gtk_object_set_data (GTK_OBJECT (button), GladeButtonStockIDKey,
+ (gpointer) GTK_STOCK_OPEN);
+ gtk_object_set_data (GTK_OBJECT (button), GladeDialogResponseIDKey,
+ GINT_TO_POINTER (GTK_RESPONSE_OK));
+ /* Set this button as the default. */
+ wdata = g_object_get_data (G_OBJECT (button), GB_WIDGET_DATA_KEY);
+ wdata->flags |= GLADE_GRAB_DEFAULT;
+ }
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_file_chooser_dialog_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Action, _("Action:"),
+ _("The type of file operation being performed"),
+ GbActionChoices);
+ property_add_bool (LocalOnly, _("Local Only:"),
+ _("Whether the selected files should be limited to local files"));
+ property_add_bool (SelectMultiple, _("Select Multiple:"),
+ _("Whether to allow multiple files to be selected"));
+ property_add_bool (ShowHidden, _("Show Hidden:"),
+ _("Whether the hidden files and folders should be displayed"));
+ property_add_bool (Confirm, _("Confirm:"),
+ _("Whether a confirmation dialog will be displayed if a file will be overwritten"));
+
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_file_chooser_dialog_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkFileChooserAction action;
+ gboolean local_only, select_multiple, show_hidden, confirm;
+ gint i;
+
+ g_object_get (widget,
+ "action", &action,
+ "local_only", &local_only,
+ "select_multiple", &select_multiple,
+ "show_hidden", &show_hidden,
+ "do_overwrite_confirmation", &confirm,
+ NULL);
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]); i++)
+ {
+ if (GbActionValues[i] == action)
+ gb_widget_output_choice (data, Action, i, GbActionSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, LocalOnly, local_only);
+ gb_widget_output_bool (data, SelectMultiple, select_multiple);
+ gb_widget_output_bool (data, ShowHidden, show_hidden);
+ gb_widget_output_bool (data, Confirm, confirm);
+
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_file_chooser_dialog_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *action;
+ gboolean local_only, select_multiple, show_hidden, confirm;
+ gint i;
+
+ action = gb_widget_input_choice (data, Action);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (!strcmp (action, GbActionChoices[i])
+ || !strcmp (action, GbActionSymbols[i]))
+ {
+ g_object_set (widget, "action", GbActionValues[i], NULL);
+ break;
+ }
+ }
+ }
+
+ local_only = gb_widget_input_bool (data, LocalOnly);
+ if (data->apply)
+ g_object_set (widget, "local_only", local_only, NULL);
+
+ select_multiple = gb_widget_input_bool (data, SelectMultiple);
+ if (data->apply)
+ g_object_set (widget, "select_multiple", select_multiple, NULL);
+
+ show_hidden = gb_widget_input_bool (data, ShowHidden);
+ if (data->apply)
+ g_object_set (widget, "show_hidden", show_hidden, NULL);
+
+ confirm = gb_widget_input_bool (data, Confirm);
+ if (data->apply)
+ g_object_set (widget, "do_overwrite_confirmation", confirm, NULL);
+
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFileChooserDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_file_chooser_dialog_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_file_chooser_dialog_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkFileChooserAction action;
+ gboolean local_only, select_multiple, show_hidden, confirm;
+ gchar *wname, *child_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ g_object_get (widget,
+ "action", &action,
+ "local_only", &local_only,
+ "select_multiple", &select_multiple,
+ "show_hidden", &show_hidden,
+ "do_overwrite_confirmation", &confirm,
+ NULL);
+
+ if (data->create_widget)
+ {
+ const gchar *action_symbol = GbActionSymbols[0];
+ gint i;
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (GbActionValues[i] == action)
+ action_symbol = GbActionSymbols[i];
+ }
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " %s = gtk_file_chooser_dialog_new (%s, NULL, %s, NULL);\n",
+ data->wname,
+ source_make_string_full (GTK_WINDOW (widget)->title,
+ data->use_gettext && translatable,
+ context),
+ action_symbol);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!local_only || select_multiple || show_hidden || confirm)
+ {
+ source_add (data, " g_object_set (%s,\n", data->wname);
+
+ if (!local_only)
+ source_add (data, " \"local-only\", FALSE,\n");
+
+ if (select_multiple)
+ source_add (data, " \"select-multiple\", TRUE,\n");
+
+ if (show_hidden)
+ source_add (data, " \"show-hidden\", TRUE,\n");
+
+ if (confirm)
+ source_add (data, " \"confirm\", TRUE,\n");
+
+ source_add (data, " NULL);\n");
+ }
+
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_DIALOG (<dialog-name>)->vbox".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (gchar*) gtk_widget_get_name (GTK_DIALOG (widget)->vbox);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = gtk_dialog_get_content_area (GTK_DIALOG (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_DIALOG (widget)->vbox, data);
+
+ /* action_area is a child of vbox so I had to add a kludge to stop it
+ being written as a normal child - we need to do it here so that we
+ don't output code to create it. */
+ child_name = (gchar*) gtk_widget_get_name (GTK_DIALOG (widget)->action_area);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = gtk_dialog_get_action_area (GTK_DIALOG (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_DIALOG (widget)->action_area, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_file_chooser_dialog_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildDialogVBox))
+ return GTK_DIALOG (widget)->vbox;
+ else if (!strcmp (child_name, GladeChildDialogActionArea))
+ return GTK_DIALOG (widget)->action_area;
+ else
+ return NULL;
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_file_chooser_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_file_chooser_dialog_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = filechooserdialog_xpm;
+ gbwidget.tooltip = _("File Chooser Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_file_chooser_dialog_new;
+ gbwidget.gb_widget_create_properties = gb_file_chooser_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_file_chooser_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_file_chooser_dialog_set_properties;
+ gbwidget.gb_widget_get_child = gb_file_chooser_dialog_get_child;
+ gbwidget.gb_widget_write_source = gb_file_chooser_dialog_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_file_chooser_dialog_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbfilechooserwidget.c b/tools/glade/glade/gbwidgets/gbfilechooserwidget.c
new file mode 100644
index 00000000..ea19174d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfilechooserwidget.c
@@ -0,0 +1,274 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/filechooserwidget.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Action = "GtkFileChooserWidget::action";
+static gchar *LocalOnly = "GtkFileChooserWidget::local_only";
+static gchar *SelectMultiple = "GtkFileChooserWidget::select_multiple";
+static gchar *ShowHidden = "GtkFileChooserWidget::show_hidden";
+
+
+static const gchar *GbActionChoices[] =
+{"Open", "Save", "Select Folder", "Create Folder", NULL};
+static const gint GbActionValues[] =
+{
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+};
+static const gchar *GbActionSymbols[] =
+{
+ "GTK_FILE_CHOOSER_ACTION_OPEN",
+ "GTK_FILE_CHOOSER_ACTION_SAVE",
+ "GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER",
+ "GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFileChooser, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_file_chooser_widget_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_file_chooser_widget_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Action, _("Action:"),
+ _("The type of file operation being performed"),
+ GbActionChoices);
+ property_add_bool (LocalOnly, _("Local Only:"),
+ _("Whether the selected files should be limited to local files"));
+ property_add_bool (SelectMultiple, _("Select Multiple:"),
+ _("Whether to allow multiple files to be selected"));
+ property_add_bool (ShowHidden, _("Show Hidden:"),
+ _("Whether the hidden files and folders should be displayed"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_file_chooser_widget_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkFileChooserAction action;
+ gboolean local_only, select_multiple, show_hidden;
+ gint i;
+
+ g_object_get (widget,
+ "action", &action,
+ "local_only", &local_only,
+ "select_multiple", &select_multiple,
+ "show_hidden", &show_hidden,
+ NULL);
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]); i++)
+ {
+ if (GbActionValues[i] == action)
+ gb_widget_output_choice (data, Action, i, GbActionSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, LocalOnly, local_only);
+ gb_widget_output_bool (data, SelectMultiple, select_multiple);
+ gb_widget_output_bool (data, ShowHidden, show_hidden);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_file_chooser_widget_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *action;
+ gboolean local_only, select_multiple, show_hidden;
+ gint i;
+
+ action = gb_widget_input_choice (data, Action);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (!strcmp (action, GbActionChoices[i])
+ || !strcmp (action, GbActionSymbols[i]))
+ {
+ g_object_set (widget, "action", GbActionValues[i], NULL);
+ break;
+ }
+ }
+ }
+
+ local_only = gb_widget_input_bool (data, LocalOnly);
+ if (data->apply)
+ g_object_set (widget, "local_only", local_only, NULL);
+
+ select_multiple = gb_widget_input_bool (data, SelectMultiple);
+ if (data->apply)
+ g_object_set (widget, "select_multiple", select_multiple, NULL);
+
+ show_hidden = gb_widget_input_bool (data, ShowHidden);
+ if (data->apply)
+ g_object_set (widget, "show_hidden", show_hidden, NULL);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFileChooser, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_file_chooser_widget_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_file_chooser_widget_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkFileChooserAction action;
+ gboolean local_only, select_multiple, show_hidden;
+
+ g_object_get (widget,
+ "action", &action,
+ "local_only", &local_only,
+ "select_multiple", &select_multiple,
+ "show_hidden", &show_hidden,
+ NULL);
+
+ if (data->create_widget)
+ {
+ const gchar *action_symbol = GbActionSymbols[0];
+ gint i;
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (GbActionValues[i] == action)
+ action_symbol = GbActionSymbols[i];
+ }
+
+ source_add (data,
+ " %s = gtk_file_chooser_widget_new (%s);\n",
+ data->wname,
+ action_symbol);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!local_only || select_multiple || show_hidden)
+ {
+ source_add (data, " g_object_set (%s,\n", data->wname);
+
+ if (!local_only)
+ source_add (data, " \"local-only\", FALSE,\n");
+
+ if (select_multiple)
+ source_add (data, " \"select-multiple\", TRUE,\n");
+
+ if (show_hidden)
+ source_add (data, " \"show-hidden\", TRUE,\n");
+
+ source_add (data, " NULL);\n");
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_file_chooser_widget_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_file_chooser_widget_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = filechooserwidget_xpm;
+ gbwidget.tooltip = _("File Chooser");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_file_chooser_widget_new;
+ gbwidget.gb_widget_create_properties = gb_file_chooser_widget_create_properties;
+ gbwidget.gb_widget_get_properties = gb_file_chooser_widget_get_properties;
+ gbwidget.gb_widget_set_properties = gb_file_chooser_widget_set_properties;
+ gbwidget.gb_widget_write_source = gb_file_chooser_widget_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_file_chooser_widget_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbfileselection.c b/tools/glade/glade/gbwidgets/gbfileselection.c
new file mode 100644
index 00000000..77e34333
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfileselection.c
@@ -0,0 +1,308 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkfilesel.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/fileseldialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "FileSel|GtkWindow::title";
+static gchar *Type = "FileSel|GtkWindow::type";
+static gchar *Position = "FileSel|GtkWindow::window_position";
+static gchar *Modal = "FileSel|GtkWindow::modal";
+static gchar *DefaultWidth = "FileSel|GtkWindow::default_width";
+static gchar *DefaultHeight = "FileSel|GtkWindow::default_height";
+static gchar *FileOps = "GtkFileSelection::show_fileops";
+static gchar *Shrink = "FileSel|GtkWindow::allow_shrink";
+static gchar *Grow = "FileSel|GtkWindow::allow_grow";
+static gchar *AutoShrink = "FileSel|GtkWindow::auto_shrink";
+static gchar *IconName = "FileSel|GtkWindow::icon_name";
+static gchar *FocusOnMap = "FileSel|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "FileSel|GtkWindow::resizable";
+static gchar *DestroyWithParent = "FileSel|GtkWindow::destroy_with_parent";
+static gchar *Icon = "FileSel|GtkWindow::icon";
+
+static gchar *Role = "FileSel|GtkWindow::role";
+static gchar *TypeHint = "FileSel|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "FileSel|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "FileSel|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "FileSel|GtkWindow::decorated";
+static gchar *Gravity = "FileSel|GtkWindow::gravity";
+static gchar *Urgency = "FileSel|GtkWindow::urgency_hint";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFileSelection, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_file_selection_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_file_selection_new (_("Select File"));
+
+ GtkFileSelection *filesel = GTK_FILE_SELECTION (new_widget);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gb_widget_create_from (filesel->ok_button,
+ data->action == GB_CREATING ? "ok_button" : NULL);
+ gb_widget_set_child_name (filesel->ok_button, GladeChildOKButton);
+
+ gb_widget_create_from (filesel->cancel_button,
+ data->action == GB_CREATING ? "cancel_button" : NULL);
+ gb_widget_set_child_name (filesel->cancel_button, GladeChildCancelButton);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_file_selection_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ property_add_bool (FileOps, _("File Ops.:"),
+ _("If the file operation buttons are shown"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_file_selection_get_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ gb_widget_output_bool (data, FileOps,
+ GTK_FILE_SELECTION (widget)->fileop_c_dir != NULL);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_file_selection_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ gboolean show_fileops;
+
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ show_fileops = gb_widget_input_bool (data, FileOps);
+ if (data->apply)
+ {
+ if (show_fileops)
+ gtk_file_selection_show_fileop_buttons (GTK_FILE_SELECTION (widget));
+ else
+ gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (widget));
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFileSelection, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_file_selection_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_file_selection_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData *data)
+{
+ gchar *wname, *child_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gtk_file_selection_new (%s);\n",
+ data->wname,
+ source_make_string_full (GTK_WINDOW (widget)->title,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (GTK_FILE_SELECTION (widget)->fileop_c_dir == NULL)
+ {
+ source_add (data,
+ " gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (%s));\n",
+ data->wname);
+ }
+
+
+ /* We output the source code for the buttons here, but we don't want them
+ to be created. We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (gchar*) gtk_widget_get_name (GTK_FILE_SELECTION (widget)->ok_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_FILE_SELECTION (%s)->ok_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_FILE_SELECTION (widget)->ok_button, data);
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_FILE_SELECTION (widget)->cancel_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_FILE_SELECTION (%s)->cancel_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_FILE_SELECTION (widget)->cancel_button, data);
+
+ g_free (wname);
+
+ data->write_children = FALSE;
+}
+
+
+
+static GtkWidget *
+gb_file_selection_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildOKButton))
+ return GTK_FILE_SELECTION (widget)->ok_button;
+ else if (!strcmp (child_name, GladeChildCancelButton))
+ return GTK_FILE_SELECTION (widget)->cancel_button;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_file_selection_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_file_selection_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = fileseldialog_xpm;
+ gbwidget.tooltip = _("File Selection Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_file_selection_new;
+ gbwidget.gb_widget_create_properties = gb_file_selection_create_properties;
+ gbwidget.gb_widget_get_properties = gb_file_selection_get_properties;
+ gbwidget.gb_widget_set_properties = gb_file_selection_set_properties;
+ gbwidget.gb_widget_get_child = gb_file_selection_get_child;
+ gbwidget.gb_widget_write_source = gb_file_selection_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_file_selection_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbfixed.c b/tools/glade/glade/gbwidgets/gbfixed.c
new file mode 100644
index 00000000..2fbcf653
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfixed.c
@@ -0,0 +1,246 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkfixed.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/fixed.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* Child properties. */
+const gchar *GladeFixedChildX = "GtkFixed::x";
+const gchar *GladeFixedChildY = "GtkFixed::y";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFixed, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_fixed_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+ static void
+ gb_fixed_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+ static void
+ gb_fixed_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+ static void
+ gb_fixed_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFixed, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_fixed_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_fixed_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_fixed_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+/*
+ * Creates the child packing properties for children of this widget.
+ */
+void
+gb_fixed_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_int_range (GladeFixedChildX, _("X:"),
+ _("The X coordinate of the widget in the GtkFixed"),
+ 0, 10000, 1, 10, 1);
+ property_add_int_range (GladeFixedChildY, _("Y:"),
+ _("The Y coordinate of the widget in the GtkFixed"),
+ 0, 10000, 1, 10, 1);
+}
+
+
+/* Shows or saves the child properties of a child of a GtkFixed. */
+void
+gb_fixed_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ gint x, y;
+
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ gtk_container_child_get (GTK_CONTAINER (widget), child,
+ "x", &x,
+ "y", &y,
+ NULL);
+
+ gb_widget_output_int (data, GladeFixedChildX, x);
+ gb_widget_output_int (data, GladeFixedChildY, y);
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+/* Applies or loads the child properties of a child of a GtkFixed. */
+void
+gb_fixed_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gint x, y;
+
+ x = gb_widget_input_int (data, GladeFixedChildX);
+ if (data->apply)
+ gtk_container_child_set (GTK_CONTAINER (widget), child,
+ "x", x,
+ NULL);
+
+ y = gb_widget_input_int (data, GladeFixedChildY);
+ if (data->apply)
+ gtk_container_child_set (GTK_CONTAINER (widget), child,
+ "y", y,
+ NULL);
+}
+
+
+/* Outputs source to add a child widget to a GtkFixed. */
+static void
+gb_fixed_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gint x, y;
+
+ gtk_container_child_get (GTK_CONTAINER (parent), child,
+ "x", &x,
+ "y", &y,
+ NULL);
+ source_add (data,
+ " gtk_fixed_put (GTK_FIXED (%s), %s, %i, %i);\n",
+ parent_name, data->wname, x, y);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_fixed_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_fixed_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = fixed_xpm;
+ gbwidget.tooltip = _("Fixed Positions");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_write_source = gb_fixed_write_source;
+ gbwidget.gb_widget_create_child_properties = gb_fixed_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_fixed_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_fixed_set_child_properties;
+ gbwidget.gb_widget_write_add_child_source = gb_fixed_write_add_child_source;
+
+/*
+ gbwidget.gb_widget_new = gb_fixed_new;
+ gbwidget.gb_widget_create_properties = gb_fixed_create_properties;
+ gbwidget.gb_widget_get_properties = gb_fixed_get_properties;
+ gbwidget.gb_widget_set_properties = gb_fixed_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_fixed_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbfontbutton.c b/tools/glade/glade/gbwidgets/gbfontbutton.c
new file mode 100644
index 00000000..79619e25
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfontbutton.c
@@ -0,0 +1,282 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/fontbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GtkFontButton::title";
+static gchar *ShowStyle = "GtkFontButton::show_style";
+static gchar *ShowSize = "GtkFontButton::show_size";
+static gchar *UseFont = "GtkFontButton::use_font";
+static gchar *UseFontSize = "GtkFontButton::use_size";
+static gchar *FocusOnClick = "GtkFontButton|GtkButton::focus_on_click";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFontButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_font_button_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_font_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (Title, _("Title:"),
+ _("The title of the font selection dialog"));
+ property_add_bool (ShowStyle, _("Show Style:"),
+ _("If the font style is shown as part of the font information"));
+ property_add_bool (ShowSize, _("Show Size:"),
+ _("If the font size is shown as part of the font information"));
+ property_add_bool (UseFont, _("Use Font:"),
+ _("If the selected font is used when displaying the font information"));
+ property_add_bool (UseFontSize, _("Use Size:"),
+ _("if the selected font size is used when displaying the font information"));
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_font_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gboolean show_style, show_size, use_font, use_size;
+ const gchar *title;
+
+ /* Only save if the title is different to the default. */
+ title = gtk_font_button_get_title (GTK_FONT_BUTTON (widget));
+ if (data->action == GB_SHOWING
+ || (title && strcmp (title, dgettext (GLADE_GTK_GETTEXT_PACKAGE,
+ "Pick a Font"))))
+ gb_widget_output_translatable_string (data, Title, title);
+
+ g_object_get (G_OBJECT (widget),
+ "show_style", &show_style,
+ "show_size", &show_size,
+ "use_font", &use_font,
+ "use_size", &use_size,
+ NULL);
+
+ gb_widget_output_bool (data, ShowStyle, show_style);
+ gb_widget_output_bool (data, ShowSize, show_size);
+ gb_widget_output_bool (data, UseFont, use_font);
+ gb_widget_output_bool (data, UseFontSize, use_size);
+
+ gb_widget_output_bool (data, FocusOnClick,
+ gtk_button_get_focus_on_click (GTK_BUTTON (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_font_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *title;
+ gboolean show_style, show_size, use_font, use_size, focus_on_click;
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ gtk_font_button_set_title (GTK_FONT_BUTTON (widget),
+ title && title[0]
+ ? title : dgettext (GLADE_GTK_GETTEXT_PACKAGE,
+ "Pick a Font"));
+
+ show_style = gb_widget_input_bool (data, ShowStyle);
+ if (data->apply)
+ gtk_font_button_set_show_style (GTK_FONT_BUTTON (widget), show_style);
+
+ show_size = gb_widget_input_bool (data, ShowSize);
+ if (data->apply)
+ gtk_font_button_set_show_size (GTK_FONT_BUTTON (widget), show_size);
+
+ use_font = gb_widget_input_bool (data, UseFont);
+ if (data->apply)
+ gtk_font_button_set_use_font (GTK_FONT_BUTTON (widget), use_font);
+
+ use_size = gb_widget_input_bool (data, UseFontSize);
+ if (data->apply)
+ gtk_font_button_set_use_size (GTK_FONT_BUTTON (widget), use_size);
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_button_set_focus_on_click (GTK_BUTTON (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFontButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_font_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_font_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *title;
+ gboolean show_style, show_size, use_font, use_size;
+
+ if (data->create_widget)
+ source_add (data, " %s = gtk_font_button_new ();\n", data->wname);
+
+ gb_widget_write_standard_source (widget, data);
+
+ title = gtk_font_button_get_title (GTK_FONT_BUTTON (widget));
+ if (title && title[0]
+ && strcmp (title, dgettext (GLADE_GTK_GETTEXT_PACKAGE, "Pick a Font")))
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gtk_font_button_set_title (GTK_FONT_BUTTON (%s), %s);\n",
+ data->wname,
+ source_make_string_full (title, data->use_gettext && translatable, context));
+ }
+
+ g_object_get (G_OBJECT (widget),
+ "show_style", &show_style,
+ "show_size", &show_size,
+ "use_font", &use_font,
+ "use_size", &use_size,
+ NULL);
+
+ if (!show_style)
+ {
+ source_add (data,
+ " gtk_font_button_set_show_style (GTK_FONT_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (!show_size)
+ {
+ source_add (data,
+ " gtk_font_button_set_show_size (GTK_FONT_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (use_font)
+ {
+ source_add (data,
+ " gtk_font_button_set_use_font (GTK_FONT_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (use_size)
+ {
+ source_add (data,
+ " gtk_font_button_set_use_size (GTK_FONT_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!gtk_button_get_focus_on_click (GTK_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_button_set_focus_on_click (GTK_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_font_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_font_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = fontbutton_xpm;
+ gbwidget.tooltip = _("Font Chooser Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_font_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_font_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_font_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_font_button_write_source;
+/*
+ gbwidget.gb_widget_new = gb_font_button_new;
+ gbwidget.gb_widget_create_popup_menu = gb_font_button_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbfontselection.c b/tools/glade/glade/gbwidgets/gbfontselection.c
new file mode 100644
index 00000000..11824004
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfontselection.c
@@ -0,0 +1,184 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkfontsel.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/fontsel.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *PreviewText = "GtkFontSelection::preview_text";
+
+
+/* This is the default preview text, pinched from gtkfontsel.c. */
+#define DEFAULT_PREVIEW_TEXT "abcdefghijk ABCDEFGHIJK"
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFontSelection, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_font_selection_new (GbWidgetNewData *data)
+{
+ return gtk_font_selection_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_font_selection_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (PreviewText, _("Preview Text:"), _("The preview text to display"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_font_selection_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ const gchar *preview_text;
+
+ preview_text = gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (widget));
+ gb_widget_output_translatable_string (data, PreviewText, preview_text);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_font_selection_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *preview_text;
+
+ preview_text = gb_widget_input_string (data, PreviewText);
+ if (data->apply)
+ gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (widget),
+ preview_text);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFontSelection, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_font_selection_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_font_selection_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *preview_text;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_font_selection_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ preview_text = gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (widget));
+ if (strcmp (preview_text, DEFAULT_PREVIEW_TEXT))
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, PreviewText,
+ &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (%s), %s);\n",
+ data->wname,
+ source_make_string_full (preview_text, data->use_gettext && translatable, context));
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_font_selection_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_font_selection_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = fontsel_xpm;
+ gbwidget.tooltip = _("Font Selection");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_font_selection_new;
+ gbwidget.gb_widget_create_properties = gb_font_selection_create_properties;
+ gbwidget.gb_widget_get_properties = gb_font_selection_get_properties;
+ gbwidget.gb_widget_set_properties = gb_font_selection_set_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_font_selection_create_popup_menu;
+*/
+ gbwidget.gb_widget_write_source = gb_font_selection_write_source;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbfontselectiondialog.c b/tools/glade/glade/gbwidgets/gbfontselectiondialog.c
new file mode 100644
index 00000000..7a7d198d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbfontselectiondialog.c
@@ -0,0 +1,317 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkfontsel.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/fontseldialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "FontSelDialog|GtkWindow::title";
+static gchar *Type = "FontSelDialog|GtkWindow::type";
+static gchar *Position = "FontSelDialog|GtkWindow::window_position";
+static gchar *Modal = "FontSelDialog|GtkWindow::modal";
+static gchar *DefaultWidth = "FontSel|GtkWindow::default_width";
+static gchar *DefaultHeight = "FontSel|GtkWindow::default_height";
+static gchar *Shrink = "FontSelDialog|GtkWindow::allow_shrink";
+static gchar *Grow = "FontSelDialog|GtkWindow::allow_grow";
+static gchar *AutoShrink = "FontSelDialog|GtkWindow::auto_shrink";
+static gchar *IconName = "FontSelDialog|GtkWindow::icon_name";
+static gchar *FocusOnMap = "FontSelDialog|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "FontSelDialog|GtkWindow::resizable";
+static gchar *DestroyWithParent = "FontSelDialog|GtkWindow::destroy_with_parent";
+static gchar *Icon = "FontSelDialog|GtkWindow::icon";
+
+static gchar *Role = "FontSelDialog|GtkWindow::role";
+static gchar *TypeHint = "FontSelDialog|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "FontSelDialog|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "FontSelDialog|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "FontSelDialog|GtkWindow::decorated";
+static gchar *Gravity = "FontSelDialog|GtkWindow::gravity";
+static gchar *Urgency = "FontSelDialog|GtkWindow::urgency_hint";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFontSelectionDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_font_selection_dialog_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget = gtk_font_selection_dialog_new (_("Select Font"));
+
+ GtkFontSelectionDialog *fontsel = GTK_FONT_SELECTION_DIALOG (new_widget);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gb_widget_create_from (fontsel->ok_button,
+ data->action == GB_CREATING ? "ok_button" : NULL);
+ gb_widget_set_child_name (fontsel->ok_button, GladeChildOKButton);
+
+ gb_widget_create_from (fontsel->cancel_button,
+ data->action == GB_CREATING ? "cancel_button" : NULL);
+ gb_widget_set_child_name (fontsel->cancel_button, GladeChildCancelButton);
+
+ gb_widget_create_from (fontsel->apply_button,
+ data->action == GB_CREATING ? "apply_button" : NULL);
+ gb_widget_set_child_name (fontsel->apply_button, GladeChildApplyButton);
+
+ gb_widget_create_from (fontsel->fontsel,
+ data->action == GB_CREATING ? "font_selection" : NULL);
+ gb_widget_set_child_name (fontsel->fontsel, GladeChildFontSelection);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_font_selection_dialog_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_font_selection_dialog_get_properties (GtkWidget *widget,
+ GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_font_selection_dialog_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFontSelectionDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_font_selection_dialog_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_font_selection_dialog_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gtk_font_selection_dialog_new (%s);\n",
+ data->wname,
+ source_make_string_full (GTK_WINDOW (widget)->title,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+
+ /* We output the source code for the buttons here, but we don't want them
+ to be created. We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_FONT_SELECTION_DIALOG (widget)->ok_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_FONT_SELECTION_DIALOG (%s)->ok_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_FONT_SELECTION_DIALOG (widget)->ok_button,
+ data);
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_FONT_SELECTION_DIALOG (widget)->cancel_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_FONT_SELECTION_DIALOG (%s)->cancel_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_FONT_SELECTION_DIALOG (widget)->cancel_button,
+ data);
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_FONT_SELECTION_DIALOG (widget)->apply_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_FONT_SELECTION_DIALOG (%s)->apply_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_FONT_SELECTION_DIALOG (widget)->apply_button,
+ data);
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_FONT_SELECTION_DIALOG (widget)->fontsel);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_FONT_SELECTION_DIALOG (%s)->fontsel;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_FONT_SELECTION_DIALOG (widget)->fontsel,
+ data);
+
+ g_free (wname);
+
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_font_selection_dialog_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildOKButton))
+ return GTK_FONT_SELECTION_DIALOG (widget)->ok_button;
+ else if (!strcmp (child_name, GladeChildApplyButton))
+ return GTK_FONT_SELECTION_DIALOG (widget)->apply_button;
+ else if (!strcmp (child_name, GladeChildCancelButton))
+ return GTK_FONT_SELECTION_DIALOG (widget)->cancel_button;
+ else if (!strcmp (child_name, GladeChildFontSelection))
+ return GTK_FONT_SELECTION_DIALOG (widget)->fontsel;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_font_selection_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_font_selection_dialog_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = fontseldialog_xpm;
+ gbwidget.tooltip = _("Font Selection Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_font_selection_dialog_new;
+ gbwidget.gb_widget_create_properties = gb_font_selection_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_font_selection_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_font_selection_dialog_set_properties;
+ gbwidget.gb_widget_get_child = gb_font_selection_dialog_get_child;
+ gbwidget.gb_widget_write_source = gb_font_selection_dialog_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_font_selection_dialog_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbframe.c b/tools/glade/glade/gbwidgets/gbframe.c
new file mode 100644
index 00000000..39f9a55e
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbframe.c
@@ -0,0 +1,375 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "../gb.h"
+#include <math.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenuitem.h>
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/frame.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *LabelXAlign = "GtkFrame::label_xalign";
+static gchar *LabelYAlign = "GtkFrame::label_yalign";
+static gchar *Shadow = "GtkFrame::shadow_type";
+
+/* We don't show this any more, as the label is a child widget now, but we
+ load this for compatability with old XML files. */
+static gchar *Label = "GtkFrame::label";
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkFrame, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_frame_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_frame_new (NULL);
+
+ if (data->action != GB_LOADING)
+ {
+ GtkWidget *label, *alignment;
+ gchar *label_markup;
+
+ /* For HIG compliance, we create a frame with no shadow, with a label
+ of "<b>widget-name</b>", and with an alignment to add 12 pixels
+ padding on the left. */
+ gtk_frame_set_shadow_type (GTK_FRAME (new_widget), GTK_SHADOW_NONE);
+
+ label = gb_widget_new ("GtkLabel", NULL);
+ label_markup = g_strdup_printf ("<b>%s</b>", data->name);
+ gtk_label_set_markup (GTK_LABEL (label), label_markup);
+ g_free (label_markup);
+ gtk_object_set_data (GTK_OBJECT (label), "GtkLabel::use_markup",
+ GINT_TO_POINTER (TRUE));
+
+ gtk_frame_set_label_widget (GTK_FRAME (new_widget), label);
+
+ alignment = gb_widget_new ("GtkAlignment", NULL);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+
+ gtk_container_add (GTK_CONTAINER (new_widget), alignment);
+ }
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_frame_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_float_range (LabelXAlign, _("Label X Align:"),
+ _("The horizontal alignment of the frame's label widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (LabelYAlign, _("Label Y Align:"),
+ _("The vertical alignment of the frame's label widget"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_choice (Shadow, _("Shadow:"), _("The type of shadow of the frame"),
+ GbShadowChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_frame_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ gb_widget_output_float (data, LabelXAlign, GTK_FRAME (widget)->label_xalign);
+ gb_widget_output_float (data, LabelYAlign, GTK_FRAME (widget)->label_yalign);
+
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == GTK_FRAME (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GbShadowSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_frame_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat label_xalign, label_yalign;
+ gboolean apply_xalign, apply_yalign;
+ gchar *shadow;
+ gint i;
+
+ /* We load the 'label' property, but create a child GbWidget. */
+ if (data->action == GB_LOADING)
+ {
+ gchar *label = gb_widget_input_string (data, Label);
+ if (data->apply && label && *label)
+ {
+ GtkWidget *label_widget = gb_widget_new ("GtkLabel", NULL);
+ gtk_label_set_text (GTK_LABEL (label_widget), label);
+ gtk_frame_set_label_widget (GTK_FRAME (widget), label_widget);
+ }
+ }
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GbShadowValues[i]);
+ break;
+ }
+ }
+ }
+
+ label_xalign = gb_widget_input_float (data, LabelXAlign);
+ apply_xalign = data->apply;
+ if (!apply_xalign)
+ label_xalign = GTK_FRAME (widget)->label_xalign;
+
+ label_yalign = gb_widget_input_float (data, LabelYAlign);
+ apply_yalign = data->apply;
+ if (!apply_yalign)
+ label_yalign = GTK_FRAME (widget)->label_yalign;
+
+ if (apply_xalign || apply_yalign)
+ gtk_frame_set_label_align (GTK_FRAME (widget), label_xalign, label_yalign);
+}
+
+
+
+static void
+gb_frame_add_label_widget (GtkWidget * menuitem, GtkFrame * frame)
+{
+ gtk_frame_set_label_widget (frame, editor_new_placeholder ());
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkFrame, with signals pointing to
+ * other functions in this file.
+ */
+void
+gb_frame_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+{
+ GtkWidget *menuitem;
+
+ /* If there is no label widget at present, we add a command to add one. */
+ if (!gtk_frame_get_label_widget (GTK_FRAME (widget)))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Label Widget"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_frame_add_label_widget), widget);
+ }
+}
+
+
+void
+gb_frame_add_child (GtkWidget *widget, GtkWidget *child, GbWidgetSetArgData *data)
+{
+ gboolean is_label_item = FALSE;
+
+ /* See if this is a tab widget. We use a special "type" packing property set
+ to "label_item".*/
+ if (data->child_info)
+ {
+ int j;
+
+ for (j = 0; j < data->child_info->n_properties; j++)
+ {
+ if (!strcmp (data->child_info->properties[j].name, "type")
+ && !strcmp (data->child_info->properties[j].value, "label_item"))
+ {
+ is_label_item = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (is_label_item)
+ gtk_frame_set_label_widget (GTK_FRAME (widget), child);
+ else
+ gtk_container_add (GTK_CONTAINER (widget), child);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_frame_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gfloat xalign, yalign;
+ gint shadow = 0, i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_frame_new (NULL);\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ xalign = GTK_FRAME (widget)->label_xalign;
+ yalign = GTK_FRAME (widget)->label_yalign;
+ if (xalign >= GLADE_EPSILON || fabs (yalign - 0.5) >= GLADE_EPSILON)
+ {
+ source_add (data,
+ " gtk_frame_set_label_align (GTK_FRAME (%s), %g, %g);\n",
+ data->wname, xalign, yalign);
+ }
+
+ if (GTK_FRAME (widget)->shadow_type != GTK_SHADOW_ETCHED_IN)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ if (GbShadowValues[i] == GTK_FRAME (widget)->shadow_type)
+ {
+ shadow = i;
+ break;
+ }
+ source_add (data, " gtk_frame_set_shadow_type (GTK_FRAME (%s), %s);\n",
+ data->wname, GbShadowSymbols[shadow]);
+ }
+}
+
+
+void
+gb_frame_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+
+ /* When saving the label widget, we save a "type" packing property set to
+ "label_item". */
+ if (data->action != GB_SAVING
+ || gtk_frame_get_label_widget (GTK_FRAME (widget)) != child)
+ return;
+
+ save_start_tag (data, "packing");
+ save_string (data, "type", "label_item");
+ save_end_tag (data, "packing");
+}
+
+
+/* Outputs source to add a child widget to a GtkNotebook. */
+void
+gb_frame_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+
+ if (gtk_frame_get_label_widget (GTK_FRAME (parent)) == child)
+ {
+ source_add (data,
+ " gtk_frame_set_label_widget (GTK_FRAME (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else
+ {
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_frame_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_frame_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = frame_xpm;
+ gbwidget.tooltip = _("Frame");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_frame_new;
+ gbwidget.gb_widget_create_properties = gb_frame_create_properties;
+ gbwidget.gb_widget_get_properties = gb_frame_get_properties;
+ gbwidget.gb_widget_set_properties = gb_frame_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_frame_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_frame_write_source;
+
+ gbwidget.gb_widget_add_child = gb_frame_add_child;
+ gbwidget.gb_widget_get_child_properties = gb_frame_get_child_properties;
+ gbwidget.gb_widget_write_add_child_source = gb_frame_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbgammacurve.c b/tools/glade/glade/gbwidgets/gbgammacurve.c
new file mode 100644
index 00000000..ac6a4c25
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbgammacurve.c
@@ -0,0 +1,269 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkcurve.h>
+#include <gtk/gtkgamma.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gammacurve.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+#if 0
+static gchar *Type = "GammaCurve|GtkCurve::curve_type";
+#endif
+static gchar *XMin = "GammaCurve|GtkCurve::min_x";
+static gchar *XMax = "GammaCurve|GtkCurve::max_x";
+static gchar *YMin = "GammaCurve|GtkCurve::min_y";
+static gchar *YMax = "GammaCurve|GtkCurve::max_y";
+
+#if 0
+static const gchar *GbTypeChoices[] =
+{"Linear", "Spline", "Free", NULL};
+static const gint GbTypeValues[] =
+{
+ GTK_CURVE_TYPE_LINEAR, /* linear interpolation */
+ GTK_CURVE_TYPE_SPLINE, /* spline interpolation */
+ GTK_CURVE_TYPE_FREE /* free form curve */
+};
+static const gchar *GbTypeSymbols[] =
+{
+ "GTK_CURVE_TYPE_LINEAR",
+ "GTK_CURVE_TYPE_SPLINE",
+ "GTK_CURVE_TYPE_FREE"
+};
+#endif
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkGammaCurve, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_gamma_curve_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gamma_curve_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+#if 0
+ property_add_choice (Type, _("Initial Type:"), _("The initial type of the curve"),
+ GbTypeChoices);
+#endif
+ property_add_float (XMin, _("X Min:"), _("The minimum horizontal value"));
+ property_add_float (XMax, _("X Max:"), _("The maximum horizontal value"));
+ property_add_float (YMin, _("Y Min:"), _("The minimum vertical value"));
+ property_add_float (YMax, _("Y Max:"), _("The maximum vertical value"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gamma_curve_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GtkCurve *curve = GTK_CURVE (GTK_GAMMA_CURVE (widget)->curve);
+
+#if 0
+ gint i;
+
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]); i++)
+ {
+ if (GbTypeValues[i] == curve->curve_type)
+ gb_widget_output_choice (data, Type, i, GbTypeSymbols[i]);
+ }
+#endif
+ gb_widget_output_float (data, XMin, curve->min_x);
+ gb_widget_output_float (data, XMax, curve->max_x);
+ gb_widget_output_float (data, YMin, curve->min_y);
+ gb_widget_output_float (data, YMax, curve->max_y);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gamma_curve_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GtkCurve *curve = GTK_CURVE (GTK_GAMMA_CURVE (widget)->curve);
+ gfloat min_x, max_x, min_y, max_y;
+ gboolean set_range = FALSE;
+
+#if 0
+ gint i;
+ gchar *type;
+
+ type = gb_widget_input_choice (data, Type);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]); i++)
+ {
+ if (!strcmp (type, GbTypeChoices[i])
+ || !strcmp (type, GbTypeSymbols[i]))
+ {
+ gtk_curve_set_curve_type (curve, GbTypeValues[i]);
+ break;
+ }
+ }
+ }
+#endif
+
+ min_x = gb_widget_input_float (data, XMin);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ min_x = GTK_CURVE (widget)->min_x;
+
+ max_x = gb_widget_input_float (data, XMax);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ max_x = GTK_CURVE (widget)->max_x;
+
+ min_y = gb_widget_input_float (data, YMin);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ min_y = GTK_CURVE (widget)->min_y;
+
+ max_y = gb_widget_input_float (data, YMax);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ max_y = GTK_CURVE (widget)->max_y;
+
+ if (set_range)
+ gtk_curve_set_range (curve, min_x, max_x, min_y, max_y);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkGammaCurve, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_gamma_curve_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gamma_curve_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkCurve *curve = GTK_CURVE (GTK_GAMMA_CURVE (widget)->curve);
+#if 0
+ gint i;
+#endif
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_gamma_curve_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+#if 0
+ if (curve->curve_type != GTK_CURVE_TYPE_SPLINE)
+ {
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]); i++)
+ {
+ if (GbTypeValues[i] == curve->curve_type)
+ source_add (data, " gtk_curve_set_curve_type (GTK_CURVE (GTK_GAMMA_CURVE (%s)->curve), %s);\n",
+ data->wname, GbTypeSymbols[i]);
+ }
+ }
+#endif
+
+ source_add (data, " gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (%s)->curve), %g, %g, %g, %g);\n",
+ data->wname, curve->min_x, curve->max_x,
+ curve->min_y, curve->max_y);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_gamma_curve_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_gamma_curve_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gammacurve_xpm;
+ gbwidget.tooltip = _("Gamma Curve");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_gamma_curve_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gamma_curve_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gamma_curve_set_properties;
+ gbwidget.gb_widget_write_source = gb_gamma_curve_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gamma_curve_new;
+ gbwidget.gb_widget_create_popup_menu = gb_gamma_curve_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhandlebox.c b/tools/glade/glade/gbwidgets/gbhandlebox.c
new file mode 100644
index 00000000..fb9b2e21
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhandlebox.c
@@ -0,0 +1,317 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhandlebox.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/handlebox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Shadow = "GtkHandleBox::shadow_type";
+static gchar *Position = "GtkHandleBox::handle_position";
+static gchar *SnapEdge = "GtkHandleBox::snap_edge";
+
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+static const gchar *GbPositionChoices[] =
+{"Left", "Right", "Top", "Bottom", NULL};
+static const gint GbPositionValues[] =
+{
+ GTK_POS_LEFT,
+ GTK_POS_RIGHT,
+ GTK_POS_TOP,
+ GTK_POS_BOTTOM
+};
+static const gchar *GbPositionSymbols[] =
+{
+ "GTK_POS_LEFT",
+ "GTK_POS_RIGHT",
+ "GTK_POS_TOP",
+ "GTK_POS_BOTTOM"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHandleBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_handle_box_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_handle_box_new ();
+
+ /* We set the snap edge to top, which matches the default handle position,
+ since we don't support the default value of -1. */
+ gtk_handle_box_set_snap_edge (GTK_HANDLE_BOX (new_widget), GTK_POS_TOP);
+
+ if (data->action != GB_LOADING)
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_handle_box_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+{
+ property_add_choice (Shadow, _("Shadow:"),
+ _("The type of shadow around the handle box"),
+ GbShadowChoices);
+
+ property_add_choice (Position, _("Handle Pos:"),
+ _("The position of the handle"),
+ GbPositionChoices);
+ property_add_choice (SnapEdge, _("Snap Edge:"),
+ _("The edge of the handle box which snaps into position"),
+ GbPositionChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_handle_box_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+{
+ gint i;
+
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == GTK_HANDLE_BOX (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GbShadowSymbols[i]);
+ }
+
+ for (i = 0; i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (GbPositionValues[i] == GTK_HANDLE_BOX (widget)->handle_position)
+ gb_widget_output_choice (data, Position, i, GbPositionSymbols[i]);
+ }
+
+ for (i = 0; i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (GbPositionValues[i] == GTK_HANDLE_BOX (widget)->snap_edge)
+ gb_widget_output_choice (data, SnapEdge, i, GbPositionSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_handle_box_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+{
+ gchar *shadow, *position, *snap_edge;
+ gint i;
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]);
+ i++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ gtk_handle_box_set_shadow_type (GTK_HANDLE_BOX (widget),
+ GbShadowValues[i]);
+ break;
+ }
+ }
+ }
+
+ position = gb_widget_input_choice (data, Position);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (!strcmp (position, GbPositionChoices[i])
+ || !strcmp (position, GbPositionSymbols[i]))
+ {
+ gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (widget),
+ GbPositionValues[i]);
+ break;
+ }
+ }
+ }
+
+ snap_edge = gb_widget_input_choice (data, SnapEdge);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (!strcmp (snap_edge, GbPositionChoices[i])
+ || !strcmp (snap_edge, GbPositionSymbols[i]))
+ {
+ gtk_handle_box_set_snap_edge (GTK_HANDLE_BOX (widget),
+ GbPositionValues[i]);
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHandleBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_handle_box_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_handle_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_handle_box_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_HANDLE_BOX (widget)->shadow_type != GTK_SHADOW_OUT)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]);
+ i++)
+ if (GbShadowValues[i] == GTK_HANDLE_BOX (widget)->shadow_type)
+ {
+ source_add (data,
+ " gtk_handle_box_set_shadow_type (GTK_HANDLE_BOX (%s), %s);\n",
+ data->wname, GbShadowSymbols[i]);
+ break;
+ }
+ }
+
+ if (GTK_HANDLE_BOX (widget)->handle_position != GTK_POS_LEFT)
+ {
+ for (i = 0; i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (GbPositionValues[i] == GTK_HANDLE_BOX (widget)->handle_position)
+ source_add (data,
+ " gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (%s), %s);\n",
+ data->wname, GbPositionSymbols[i]);
+ }
+ }
+
+ if (GTK_HANDLE_BOX (widget)->snap_edge != GTK_POS_TOP)
+ {
+ for (i = 0; i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (GbPositionValues[i] == GTK_HANDLE_BOX (widget)->snap_edge)
+ source_add (data,
+ " gtk_handle_box_set_snap_edge (GTK_HANDLE_BOX (%s), %s);\n",
+ data->wname, GbPositionSymbols[i]);
+ }
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_handle_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_handle_box_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = handlebox_xpm;
+ gbwidget.tooltip = _("Handle Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_handle_box_new;
+ gbwidget.gb_widget_create_properties = gb_handle_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_handle_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_handle_box_set_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_handle_box_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_handle_box_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhbox.c b/tools/glade/glade/gbwidgets/gbhbox.c
new file mode 100644
index 00000000..2205824d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhbox.c
@@ -0,0 +1,587 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkbbox.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+#include "../tree.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hbox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* Size is not saved to the XML. */
+static const gchar *Size = "HBox|GtkBox::size";
+static const gchar *Homogeneous = "HBox|GtkBox::homogeneous";
+static const gchar *Spacing = "HBox|GtkBox::spacing";
+
+/* For children of a box */
+static const gchar *GbPadding = "GtkBoxChild::padding";
+static const gchar *GbExpand = "GtkBoxChild::expand";
+static const gchar *GbFill = "GtkBoxChild::fill";
+static const gchar *GbPack = "GtkBoxChild::pack_type";
+
+/* This is only used internally - it isn't save in the XML. */
+static const gchar *GbPosition = "GtkBoxChild::position";
+
+
+static void show_hbox_dialog (GbWidgetNewData * data);
+static void on_hbox_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_hbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+static void gb_box_insert_before (GtkWidget * menuitem, GtkWidget * child);
+static void gb_box_insert_after (GtkWidget * menuitem, GtkWidget * child);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_hbox_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gtk_hbox_new (FALSE, 0);
+ return new_widget;
+ }
+ else
+ {
+ show_hbox_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_hbox_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New horizontal box"), data->parent,
+ GTK_SIGNAL_FUNC (on_hbox_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_hbox_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of columns:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "cols",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_hbox_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *placeholder;
+ gint cols, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "cols");
+ g_return_if_fail (spinbutton != NULL);
+ cols = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_hbox_new (FALSE, 0);
+ for (i = 0; i < cols; i++)
+ {
+ placeholder = editor_new_placeholder ();
+ /*gtk_widget_set_usize(placeholder, 60, 80); */
+ gtk_box_pack_start (GTK_BOX (new_widget), placeholder, TRUE, TRUE, 0);
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_hbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_hbox_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_int_range (Size, _("Size:"), _("The number of widgets in the box"),
+ 0, 1000, 1, 10, 1);
+ property_add_bool (Homogeneous, _("Homogeneous:"),
+ _("If the children should be the same size"));
+ property_add_int_range (Spacing, _("Spacing:"), _("The space between each child"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_hbox_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ if (data->action != GB_SAVING)
+ gb_widget_output_int (data, Size, g_list_length (GTK_BOX (widget)->children));
+ gb_widget_output_bool (data, Homogeneous, GTK_BOX (widget)->homogeneous);
+ gb_widget_output_int (data, Spacing, GTK_BOX (widget)->spacing);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_hbox_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean homogeneous;
+ gint spacing, size;
+
+ if (data->action != GB_LOADING)
+ {
+ size = gb_widget_input_int (data, Size);
+ if (data->apply)
+ gb_box_set_size (widget, size);
+ }
+
+ homogeneous = gb_widget_input_bool (data, Homogeneous);
+ if (data->apply)
+ gtk_box_set_homogeneous (GTK_BOX (widget), homogeneous);
+
+ spacing = gb_widget_input_int (data, Spacing);
+ if (data->apply)
+ gtk_box_set_spacing (GTK_BOX (widget), spacing);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hbox_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_hbox_new (%s, %i);\n", data->wname,
+ GTK_BOX (widget)->homogeneous ? "TRUE" : "FALSE",
+ GTK_BOX (widget)->spacing);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+/*
+ * Functions common to GtkHBox & GtkVBox (and possibly GtkHButtonBox
+ * & GtkVButtonBox).
+ */
+
+
+/* This updates the box size to the given value, adding placeholders or
+ deleting widgets as necessary. */
+void
+gb_box_set_size (GtkWidget * widget, gint size)
+{
+ GtkWidget *new_child;
+ gint current_size = g_list_length (GTK_BOX (widget)->children);
+ gint i;
+
+ if (current_size < size)
+ {
+ /* This avoids any problems with redrawing the selection. */
+ editor_clear_selection (NULL);
+
+ for (i = 0; i < size - current_size; i++)
+ {
+ if (GTK_IS_BUTTON_BOX (widget))
+ {
+ new_child = gb_widget_new ("GtkButton", widget);
+ GTK_WIDGET_SET_FLAGS (new_child, GTK_CAN_DEFAULT);
+ gtk_box_pack_start (GTK_BOX (widget), new_child, TRUE, TRUE, 0);
+ tree_add_widget (new_child);
+ }
+ else
+ {
+ new_child = editor_new_placeholder ();
+ gtk_box_pack_start (GTK_BOX (widget), new_child, TRUE, TRUE, 0);
+ }
+ }
+ }
+ else if (current_size > size)
+ {
+ GList *children, *elem;
+ GtkWidget *child;
+ gchar *error = NULL;
+
+ /* Get a list of children in the order they appear in the box, start at
+ the end and move backwards until we find a widget that can be
+ destroyed. If we can't find any, show a message box. */
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+ elem = g_list_last (children);
+
+ while (elem)
+ {
+ child = elem->data;
+ error = editor_can_delete_widget (child);
+ if (!error)
+ {
+ gtk_container_remove (GTK_CONTAINER (widget), child);
+ current_size--;
+ if (current_size == size)
+ break;
+ }
+ elem = elem->prev;
+ }
+
+ g_list_free (children);
+
+ /* If we show an error dialog it causes weird problems with the
+ spinbutton used to change the size. So we don't do this. */
+#if 0
+ if (current_size > size)
+ {
+ glade_util_show_message_box (error ? error
+ : _("Can't delete any children."),
+ widget);
+ }
+#endif
+ }
+}
+
+
+/*
+ * Creates the child packing properties for children of this widget.
+ */
+void
+gb_box_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_int_range (GbPosition, _("Position:"),
+ _("The widget's position relative to its siblings"),
+ 0, 10000, 1, 10, 1);
+ property_add_int_range (GbPadding, _("Padding:"),
+ _("The widget's padding"),
+ 0, 10000, 1, 10, 1);
+ property_add_bool (GbExpand, _("Expand:"),
+ _("Set True to let the widget expand"));
+ property_add_bool (GbFill, _("Fill:"),
+ _("Set True to let the widget fill its allocated area"));
+ property_add_bool (GbPack, _("Pack Start:"),
+ _("Set True to pack the widget at the start of the box"));
+}
+
+
+void
+gb_box_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ gboolean expand, fill;
+ gint position;
+ guint padding;
+ GtkPackType pack_type;
+
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ if (data->action == GB_SHOWING)
+ {
+ position = glade_util_get_box_pos (GTK_BOX (widget), child);
+ gb_widget_output_int (data, GbPosition, position);
+ }
+
+ gtk_box_query_child_packing (GTK_BOX (widget), child,
+ &expand, &fill, &padding, &pack_type);
+ gb_widget_output_int (data, GbPadding, padding);
+ gb_widget_output_bool (data, GbExpand, expand);
+ gb_widget_output_bool (data, GbFill, fill);
+
+ if (data->action == GB_SAVING)
+ {
+ /* Save pack type as an enum symbol rather than a bool */
+ if (pack_type == GTK_PACK_END)
+ {
+ gb_widget_output_string (data, GbPack, "GTK_PACK_END");
+ }
+ }
+ else
+ {
+ gb_widget_output_bool (data, GbPack, pack_type == GTK_PACK_START);
+ }
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+/* Applies or loads the child properties of a child of a hbox/vbox. */
+void
+gb_box_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gint position, padding;
+ guint old_padding;
+ gboolean expand, fill, pack, set_child_packing = FALSE;
+ gboolean old_expand, old_fill;
+ GtkPackType old_pack_type;
+
+ position = gb_widget_input_int (data, GbPosition);
+ if (data->apply)
+ {
+ gtk_box_reorder_child (GTK_BOX (widget), child, position);
+ }
+
+ gtk_box_query_child_packing (GTK_BOX (widget), child,
+ &old_expand, &old_fill, &old_padding,
+ &old_pack_type);
+
+ padding = gb_widget_input_int (data, GbPadding);
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ padding = old_padding;
+
+ expand = gb_widget_input_bool (data, GbExpand);
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ expand = old_expand;
+
+ fill = gb_widget_input_bool (data, GbFill);
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ fill = old_fill;
+
+ if (data->action == GB_APPLYING)
+ {
+ pack = gb_widget_input_bool (data, GbPack);
+ }
+ else
+ {
+ gchar *pack_symbol = gb_widget_input_string (data, GbPack);
+ pack = pack_symbol && !strcmp (pack_symbol, "GTK_PACK_START");
+ }
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ pack = (old_pack_type == GTK_PACK_START) ? TRUE : FALSE;
+
+ if (set_child_packing)
+ gtk_box_set_child_packing (GTK_BOX (widget), child, expand, fill, padding,
+ pack ? GTK_PACK_START : GTK_PACK_END);
+}
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHBox, with signals pointing to
+ * other functions in this file.
+ */
+void
+gb_box_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+
+ if (data->child == NULL)
+ return;
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Before"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_box_insert_before), data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert After"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_box_insert_after), data->child);
+}
+
+
+static void
+gb_box_insert_before (GtkWidget * menuitem, GtkWidget * child)
+{
+ GtkWidget *box, *newchild;
+ guint pos;
+ gboolean expand, fill;
+ guint padding;
+ GtkPackType pack_type;
+
+ box = child->parent;
+ pos = glade_util_get_box_pos (GTK_BOX (box), child);
+ g_return_if_fail (pos != -1);
+ newchild = editor_new_placeholder ();
+ gtk_box_query_child_packing (GTK_BOX (box), child,
+ &expand, &fill, &padding, &pack_type);
+ if (pack_type == GTK_PACK_START)
+ {
+ gtk_box_pack_start (GTK_BOX (box), newchild, TRUE, TRUE, 0);
+ gtk_box_reorder_child (GTK_BOX (box), newchild, pos);
+ }
+ else
+ {
+ gtk_box_pack_end (GTK_BOX (box), newchild, TRUE, TRUE, 0);
+ gtk_box_reorder_child (GTK_BOX (box), newchild, pos + 1);
+ }
+}
+
+static void
+gb_box_insert_after (GtkWidget * menuitem, GtkWidget * child)
+{
+ GtkWidget *box, *newchild;
+ guint pos;
+ gboolean expand, fill;
+ guint padding;
+ GtkPackType pack_type;
+
+ box = child->parent;
+ pos = glade_util_get_box_pos (GTK_BOX (box), child);
+ g_return_if_fail (pos != -1);
+ newchild = editor_new_placeholder ();
+ gtk_box_query_child_packing (GTK_BOX (box), child,
+ &expand, &fill, &padding, &pack_type);
+ if (pack_type == GTK_PACK_START)
+ {
+ gtk_box_pack_start (GTK_BOX (box), newchild, TRUE, TRUE, 0);
+ gtk_box_reorder_child (GTK_BOX (box), newchild, pos + 1);
+ }
+ else
+ {
+ gtk_box_pack_end (GTK_BOX (box), newchild, TRUE, TRUE, 0);
+ gtk_box_reorder_child (GTK_BOX (box), newchild, pos);
+ }
+}
+
+
+/* Outputs source to add a child widget to a hbox/vbox. */
+void
+gb_box_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gboolean expand, fill;
+ guint padding;
+ GtkPackType pack_type;
+
+ gtk_box_query_child_packing (GTK_BOX (parent), child,
+ &expand, &fill, &padding, &pack_type);
+ if (pack_type == GTK_PACK_START)
+ {
+ source_add (data,
+ " gtk_box_pack_start (GTK_BOX (%s), %s, %s, %s, %i);\n",
+ parent_name, data->wname,
+ expand ? "TRUE" : "FALSE", fill ? "TRUE" : "FALSE", padding);
+ }
+ else
+ {
+ source_add (data,
+ " gtk_box_pack_end (GTK_BOX (%s), %s, %s, %s, %i);\n",
+ parent_name, data->wname,
+ expand ? "TRUE" : "FALSE", fill ? "TRUE" : "FALSE", padding);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hbox_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hbox_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hbox_xpm;
+ gbwidget.tooltip = _("Horizontal Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hbox_new;
+ gbwidget.gb_widget_create_properties = gb_hbox_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hbox_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hbox_set_properties;
+ gbwidget.gb_widget_write_source = gb_hbox_write_source;
+
+ gbwidget.gb_widget_create_child_properties = gb_box_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_box_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_box_set_child_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_box_create_popup_menu;
+ gbwidget.gb_widget_write_add_child_source = gb_box_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhbuttonbox.c b/tools/glade/glade/gbwidgets/gbhbuttonbox.c
new file mode 100644
index 00000000..b64f9383
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhbuttonbox.c
@@ -0,0 +1,428 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#include "../glade_gnome.h"
+#else
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkhbbox.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkspinbutton.h>
+#endif
+
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hbuttonbox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Size = "HBBox|GtkBox::size";
+static gchar *Layout = "HBBox|GtkButtonBox::layout_style";
+static gchar *Spacing = "HBBox|GtkButtonBox::spacing";
+
+static const gchar *GbLayoutChoices[] =
+{"Default", "Spread", "Edge",
+ "Start", "End", NULL};
+static const gint GbLayoutValues[] =
+{
+ GTK_BUTTONBOX_DEFAULT_STYLE,
+ GTK_BUTTONBOX_SPREAD,
+ GTK_BUTTONBOX_EDGE,
+ GTK_BUTTONBOX_START,
+ GTK_BUTTONBOX_END
+};
+static const gchar *GbLayoutSymbols[] =
+{
+ "GTK_BUTTONBOX_DEFAULT_STYLE",
+ "GTK_BUTTONBOX_SPREAD",
+ "GTK_BUTTONBOX_EDGE",
+ "GTK_BUTTONBOX_START",
+ "GTK_BUTTONBOX_END"
+};
+
+
+/* FIXME: Hack - copied from gtkbbox.c. Should use GParam query instead,
+ or use an optional int property instead. */
+#define DEFAULT_CHILD_MIN_WIDTH 85
+#define DEFAULT_CHILD_MIN_HEIGHT 27
+#define DEFAULT_CHILD_IPAD_X 4
+#define DEFAULT_CHILD_IPAD_Y 0
+
+
+static void show_hbbox_dialog (GbWidgetNewData * data);
+static void on_hbbox_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_hbbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHButtonBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_hbutton_box_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gtk_hbutton_box_new ();
+ return new_widget;
+ }
+ else
+ {
+ show_hbbox_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_hbbox_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New horizontal button box"),
+ data->parent,
+ GTK_SIGNAL_FUNC (on_hbbox_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_hbbox_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of columns:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "cols",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_hbbox_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *new_child;
+ gint cols, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "cols");
+ g_return_if_fail (spinbutton != NULL);
+ cols = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_hbutton_box_new ();
+ for (i = 0; i < cols; i++)
+ {
+ new_child = gb_widget_new ("GtkButton", new_widget);
+ GTK_WIDGET_SET_FLAGS (new_child, GTK_CAN_DEFAULT);
+ gtk_container_add (GTK_CONTAINER (new_widget), new_child);
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_hbbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_hbutton_box_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ property_add_int_range (Size, _("Size:"), _("The number of buttons"),
+ 0, 1000, 1, 10, 1);
+ property_add_choice (Layout, _("Layout:"),
+ _("The layout style of the buttons"),
+ GbLayoutChoices);
+ property_add_int_range (Spacing, _("Spacing:"), _("The space between the buttons"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+static gboolean
+gb_hbutton_box_is_dialog_action_area (GtkWidget *widget)
+{
+ char *child_name = gb_widget_get_child_name (widget);
+ if (child_name && !strcmp (child_name, GladeChildDialogActionArea))
+ return TRUE;
+ return FALSE;
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_hbutton_box_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GtkButtonBoxStyle layout;
+ gint i, spacing;
+ gboolean spacing_visible = FALSE;
+
+ if (data->action != GB_SAVING)
+ gb_widget_output_int (data, Size, g_list_length (GTK_BOX (widget)->children));
+
+ layout = gtk_button_box_get_layout (GTK_BUTTON_BOX (widget));
+ for (i = 0; i < sizeof (GbLayoutValues) / sizeof (GbLayoutValues[0]); i++)
+ {
+ if (GbLayoutValues[i] == layout)
+ gb_widget_output_choice (data, Layout, i, GbLayoutSymbols[i]);
+ }
+
+ if (!gb_hbutton_box_is_dialog_action_area (widget))
+ {
+ spacing_visible = TRUE;
+ spacing = gtk_box_get_spacing (GTK_BOX (widget));
+ gb_widget_output_int (data, Spacing, spacing);
+ }
+
+ if (data->action == GB_SHOWING)
+ {
+ property_set_visible (Spacing, spacing_visible);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_hbutton_box_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint size, i, spacing;
+ gchar *layout;
+ gboolean queue_resize = FALSE;
+
+ if (data->action != GB_LOADING)
+ {
+ size = gb_widget_input_int (data, Size);
+ if (data->apply)
+ gb_box_set_size (widget, size);
+ }
+
+ layout = gb_widget_input_choice (data, Layout);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbLayoutValues) / sizeof (GbLayoutValues[0]);
+ i++)
+ {
+ if (!strcmp (layout, GbLayoutChoices[i])
+ || !strcmp (layout, GbLayoutSymbols[i]))
+ {
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (widget), GbLayoutValues
+ [i]);
+ queue_resize = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!gb_hbutton_box_is_dialog_action_area (widget))
+ {
+ spacing = gb_widget_input_int (data, Spacing);
+ if (data->apply)
+ {
+ gtk_box_set_spacing (GTK_BOX (widget), spacing);
+ queue_resize = TRUE;
+ }
+ }
+
+ if (queue_resize)
+ gtk_widget_queue_resize (widget);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHButtonBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_hbutton_box_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hbutton_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkButtonBoxStyle layout_style;
+ gint spacing, i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_hbutton_box_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ layout_style = GTK_BUTTON_BOX (widget)->layout_style;
+ if (layout_style != GTK_BUTTONBOX_DEFAULT_STYLE)
+ {
+ for (i = 0; i < sizeof (GbLayoutValues) / sizeof (GbLayoutValues[0]); i
+ ++)
+ {
+ if (GbLayoutValues[i] == layout_style)
+ source_add (data,
+ " gtk_button_box_set_layout (GTK_BUTTON_BOX (%s), %s);\n",
+ data->wname, GbLayoutSymbols[i]);
+ }
+ }
+
+ if (!gb_hbutton_box_is_dialog_action_area (widget))
+ {
+ spacing = gtk_box_get_spacing (GTK_BOX (widget));
+ if (spacing != 0)
+ {
+ source_add (data,
+ " gtk_box_set_spacing (GTK_BOX (%s), %i);\n",
+ data->wname, spacing);
+ }
+ }
+}
+
+
+/* Outputs source to add a child widget to a hbuttonbox. We need to check if
+ the hbuttonbox is a GtkDialog action area, and if it is we use the special
+ gtk_dialog_add_action_widget() function to add it. */
+void
+gb_hbutton_box_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ if (gb_hbutton_box_is_dialog_action_area (parent)
+ && G_OBJECT_TYPE (child) == GTK_TYPE_BUTTON)
+ {
+ gint response_id;
+ char *response_name, *dialog_name;
+
+ response_id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (child), GladeDialogResponseIDKey));
+ response_name = gb_dialog_response_id_to_string (response_id);
+
+ dialog_name = (char*) gtk_widget_get_name (parent->parent->parent);
+ dialog_name = source_create_valid_identifier (dialog_name);
+
+ source_add (data,
+ " gtk_dialog_add_action_widget (GTK_DIALOG (%s), %s, %s);\n",
+ dialog_name, data->wname, response_name);
+
+ g_free (dialog_name);
+ }
+ else
+ {
+ /* Use the standard gtk_container_add(). */
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hbutton_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hbutton_box_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hbuttonbox_xpm;
+ gbwidget.tooltip = _("Horizontal Button Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hbutton_box_new;
+ gbwidget.gb_widget_create_properties = gb_hbutton_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hbutton_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hbutton_box_set_properties;
+ gbwidget.gb_widget_write_source = gb_hbutton_box_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_hbutton_box_write_add_child_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_hbutton_box_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhpaned.c b/tools/glade/glade/gbwidgets/gbhpaned.c
new file mode 100644
index 00000000..c8438dcf
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhpaned.c
@@ -0,0 +1,332 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhpaned.h>
+#include <gtk/gtktogglebutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hpaned.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Position = "HPaned|GtkPaned::position";
+
+/* For children of a paned */
+static const gchar *Shrink = "GtkPanedChild::shrink";
+static const gchar *Resize = "GtkPanedChild::resize";
+
+static void on_toggle_position (GtkWidget * widget, gpointer value);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHPaned, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_hpaned_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_hpaned_new ();
+ if (data->action != GB_LOADING)
+ {
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ }
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_hpaned_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_optional_int_range (Position, _("Position:"),
+ _("The position of the divider"),
+ 1, 1000, 1, 10, 1,
+ on_toggle_position);
+}
+
+
+static void
+on_toggle_position (GtkWidget * button, gpointer value)
+{
+ GtkWidget *widget;
+ gboolean value_set;
+ gint position;
+
+ widget = property_get_widget ();
+ if (widget == NULL)
+ return;
+
+ value_set = GTK_TOGGLE_BUTTON (button)->active ? TRUE : FALSE;
+ gtk_widget_set_sensitive (GTK_WIDGET (value), value_set);
+
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Position));
+ gtk_paned_set_position (GTK_PANED (widget),
+ value_set ? position : -1);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_hpaned_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint position;
+
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Position));
+ gb_widget_output_optional_int (data, Position, position,
+ GTK_PANED (widget)->position_set);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_hpaned_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint position;
+
+ position = gb_widget_input_int (data, Position);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), Position,
+ GINT_TO_POINTER (position));
+ gtk_paned_set_position (GTK_PANED (widget), position);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHPaned, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_hpaned_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hpaned_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint position;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_hpaned_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_PANED (widget)->position_set)
+ {
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Position));
+ source_add (data, " gtk_paned_set_position (GTK_PANED (%s), %d);\n",
+ data->wname, position);
+ }
+}
+
+
+/*
+ * Creates the child packing properties for children of this widget.
+ */
+void
+gb_paned_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_bool (Shrink, _("Shrink:"),
+ _("Set True to let the widget shrink"));
+ property_add_bool (Resize, _("Resize:"),
+ _("Set True to let the widget resize"));
+}
+
+
+void
+gb_paned_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ gboolean shrink, resize;
+
+ if (child == GTK_PANED (widget)->child1)
+ {
+ shrink = GTK_PANED (widget)->child1_shrink;
+ resize = GTK_PANED (widget)->child1_resize;
+ }
+ else if (child == GTK_PANED (widget)->child2)
+ {
+ shrink = GTK_PANED (widget)->child2_shrink;
+ resize = GTK_PANED (widget)->child2_resize;
+ }
+ else
+ {
+ /* This shouldn't happen. */
+ g_warning ("Couldn't find child of GtkPaned container");
+ return;
+ }
+
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ gb_widget_output_bool (data, Shrink, shrink);
+ gb_widget_output_bool (data, Resize, resize);
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+/* Applies or loads the child properties of a child of a hbox/vbox. */
+void
+gb_paned_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gboolean shrink, resize, is_child1, need_resize = FALSE;
+
+ if (child == GTK_PANED (widget)->child1)
+ is_child1 = TRUE;
+ else if (child == GTK_PANED (widget)->child2)
+ is_child1 = FALSE;
+ else
+ {
+ /* This shouldn't happen. */
+ g_warning ("Couldn't find child of GtkPaned container");
+ return;
+ }
+
+ shrink = gb_widget_input_bool (data, Shrink);
+ if (data->apply)
+ {
+ if (is_child1)
+ GTK_PANED (widget)->child1_shrink = shrink;
+ else
+ GTK_PANED (widget)->child2_shrink = shrink;
+ need_resize = TRUE;
+ }
+
+ resize = gb_widget_input_bool (data, Resize);
+ if (data->apply)
+ {
+ if (is_child1)
+ GTK_PANED (widget)->child1_resize = resize;
+ else
+ GTK_PANED (widget)->child2_resize = resize;
+ need_resize = TRUE;
+ }
+
+ if (need_resize)
+ gtk_widget_queue_resize (widget);
+}
+
+
+void
+gb_paned_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gint child_num;
+ gchar *resize, *shrink;
+
+ if (child == GTK_PANED (parent)->child1) {
+ child_num = 1;
+ resize = GTK_PANED (parent)->child1_resize ? "TRUE" : "FALSE";
+ shrink = GTK_PANED (parent)->child1_shrink ? "TRUE" : "FALSE";
+ } else if (child == GTK_PANED (parent)->child2) {
+ child_num = 2;
+ resize = GTK_PANED (parent)->child2_resize ? "TRUE" : "FALSE";
+ shrink = GTK_PANED (parent)->child2_shrink ? "TRUE" : "FALSE";
+ } else {
+ g_warning ("Paned child not found");
+ return;
+ }
+
+ source_add (data, " gtk_paned_pack%i (GTK_PANED (%s), %s, %s, %s);\n",
+ child_num, parent_name, data->wname, resize, shrink);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hpaned_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hpaned_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hpaned_xpm;
+ gbwidget.tooltip = _("Horizontal Panes");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hpaned_new;
+ gbwidget.gb_widget_create_properties = gb_hpaned_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hpaned_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hpaned_set_properties;
+ gbwidget.gb_widget_create_child_properties = gb_paned_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_paned_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_paned_set_child_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_hpaned_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_hpaned_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_paned_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhruler.c b/tools/glade/glade/gbwidgets/gbhruler.c
new file mode 100644
index 00000000..5a44611b
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhruler.c
@@ -0,0 +1,260 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhruler.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hruler.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Metric = "HRuler|GtkRuler::metric";
+static gchar *Lower = "HRuler|GtkRuler::lower";
+static gchar *Upper = "HRuler|GtkRuler::upper";
+static gchar *Pos = "HRuler|GtkRuler::position";
+static gchar *Max = "HRuler|GtkRuler::max_size";
+
+static const gchar *GbMetricChoices[] =
+{"Pixels", "Inches", "Centimeters", NULL};
+static const gint GbMetricValues[] =
+{
+ GTK_PIXELS,
+ GTK_INCHES,
+ GTK_CENTIMETERS
+};
+static const gchar *GbMetricSymbols[] =
+{
+ "GTK_PIXELS",
+ "GTK_INCHES",
+ "GTK_CENTIMETERS"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHRuler, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_hruler_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_hruler_new ();
+ gtk_ruler_set_range (GTK_RULER (new_widget), 0, 10, 0, 10);
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_hruler_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Metric, _("Metric:"),
+ _("The units of the ruler"),
+ GbMetricChoices);
+ property_add_float (Lower, _("Lower Value:"),
+ _("The low value of the ruler"));
+ property_add_float (Upper, _("Upper Value:"),
+ _("The high value of the ruler"));
+ property_add_float (Pos, _("Position:"),
+ _("The current position on the ruler"));
+ property_add_float (Max, _("Max:"),
+ _("The maximum value of the ruler"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_hruler_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gchar *metric_name;
+ gint i;
+
+ metric_name = GTK_RULER (widget)->metric->metric_name;
+ for (i = 0; i < sizeof (GbMetricValues) / sizeof (GbMetricValues[0]); i++)
+ {
+ if (!strcmp (GbMetricChoices[i], metric_name))
+ gb_widget_output_choice (data, Metric, i, GbMetricSymbols[i]);
+ }
+
+ gb_widget_output_float (data, Lower, GTK_RULER (widget)->lower);
+ gb_widget_output_float (data, Upper, GTK_RULER (widget)->upper);
+ gb_widget_output_float (data, Pos, GTK_RULER (widget)->position);
+ gb_widget_output_float (data, Max, GTK_RULER (widget)->max_size);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_hruler_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *metric;
+ gint i;
+ gfloat lower, upper, pos, max;
+ gboolean set_range = FALSE;
+
+ metric = gb_widget_input_choice (data, Metric);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbMetricValues) / sizeof (GbMetricValues[0]); i
+ ++)
+ {
+ if (!strcmp (metric, GbMetricChoices[i])
+ || !strcmp (metric, GbMetricSymbols[i]))
+ {
+ gtk_ruler_set_metric (GTK_RULER (widget), GbMetricValues[i]);
+ break;
+ }
+ }
+ }
+
+ lower = gb_widget_input_float (data, Lower);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ lower = GTK_RULER (widget)->lower;
+
+ upper = gb_widget_input_float (data, Upper);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ upper = GTK_RULER (widget)->upper;
+
+ pos = gb_widget_input_float (data, Pos);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ pos = GTK_RULER (widget)->position;
+
+ max = gb_widget_input_float (data, Max);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ max = GTK_RULER (widget)->max_size;
+
+ if (set_range)
+ gtk_ruler_set_range (GTK_RULER (widget), lower, upper, pos, max);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHRuler, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_hruler_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hruler_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *metric_name;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_hruler_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ metric_name = GTK_RULER (widget)->metric->metric_name;
+ if (strcmp (metric_name, "Pixels"))
+ {
+ for (i = 0; i < sizeof (GbMetricValues) / sizeof (GbMetricValues[0]); i
+ ++)
+ {
+ if (!strcmp (GbMetricChoices[i], metric_name))
+ source_add (data, " gtk_ruler_set_metric (GTK_RULER (%s), %s);\n",
+ data->wname, GbMetricSymbols[i]);
+ }
+ }
+ source_add (data, " gtk_ruler_set_range (GTK_RULER (%s), %g, %g, %g, %g);\n",
+ data->wname, GTK_RULER (widget)->lower, GTK_RULER (widget)->upper,
+ GTK_RULER (widget)->position, GTK_RULER (widget)->max_size);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hruler_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hruler_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hruler_xpm;
+ gbwidget.tooltip = _("Horizontal Ruler");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hruler_new;
+ gbwidget.gb_widget_create_properties = gb_hruler_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hruler_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hruler_set_properties;
+ gbwidget.gb_widget_write_source = gb_hruler_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_hruler_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhscale.c b/tools/glade/glade/gbwidgets/gbhscale.c
new file mode 100644
index 00000000..d5c6d413
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhscale.c
@@ -0,0 +1,332 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhscale.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hscale.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *DrawValue = "HScale|GtkScale::draw_value";
+static gchar *ValuePos = "HScale|GtkScale::value_pos";
+static gchar *Digits = "HScale|GtkRange::digits";
+static gchar *Policy = "HScale|GtkRange::update_policy";
+static gchar *Inverted = "HScale|GtkRange::inverted";
+
+static const gchar *Values[] =
+{
+ "GtkHScale::value",
+ "GtkHScale::lower",
+ "GtkHScale::upper",
+ "GtkHScale::step",
+ "GtkHScale::page",
+ "GtkHScale::page_size",
+};
+
+static const gchar *GbValuePosChoices[] =
+{"Left", "Right", "Top", "Bottom", NULL};
+static const gint GbValuePosValues[] =
+{
+ GTK_POS_LEFT,
+ GTK_POS_RIGHT,
+ GTK_POS_TOP,
+ GTK_POS_BOTTOM
+};
+static const gchar *GbValuePosSymbols[] =
+{
+ "GTK_POS_LEFT",
+ "GTK_POS_RIGHT",
+ "GTK_POS_TOP",
+ "GTK_POS_BOTTOM"
+};
+
+static const gchar *GbPolicyChoices[] =
+{"Continuous", "Discontinuous", "Delayed",
+ NULL};
+static const gint GbPolicyValues[] =
+{
+ GTK_UPDATE_CONTINUOUS,
+ GTK_UPDATE_DISCONTINUOUS,
+ GTK_UPDATE_DELAYED
+};
+static const gchar *GbPolicySymbols[] =
+{
+ "GTK_UPDATE_CONTINUOUS",
+ "GTK_UPDATE_DISCONTINUOUS",
+ "GTK_UPDATE_DELAYED"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHScale, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_hscale_new (GbWidgetNewData * data)
+{
+ return gtk_hscale_new (NULL);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_hscale_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (DrawValue, _("Show Value:"), _("If the scale's value is shown"));
+ property_add_int_range (Digits, _("Digits:"), _("The number of digits to show"),
+ 0, 13, 1, 10, 1);
+ property_add_choice (ValuePos, _("Value Pos:"),
+ _("The position of the value"),
+ GbValuePosChoices);
+ property_add_choice (Policy, _("Policy:"),
+ _("The update policy of the scale"),
+ GbPolicyChoices);
+ property_add_bool (Inverted, _("Inverted:"), _("If the range values are inverted"));
+ property_add_adjustment (Values, GB_ADJUST_DEFAULT_LABELS);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_hscale_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ gb_widget_output_bool (data, DrawValue, GTK_SCALE (widget)->draw_value);
+
+ for (i = 0; i < sizeof (GbValuePosValues) / sizeof (GbValuePosValues[0]);
+ i++)
+ {
+ if (GbValuePosValues[i] == GTK_SCALE (widget)->value_pos)
+ gb_widget_output_choice (data, ValuePos, i, GbValuePosSymbols[i]);
+ }
+ gb_widget_output_int (data, Digits, GTK_SCALE (widget)->digits);
+
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ gb_widget_output_choice (data, Policy, i, GbPolicySymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Inverted, GTK_RANGE (widget)->inverted);
+
+ gb_widget_output_adjustment (data, Values, GTK_RANGE (widget)->adjustment,
+ "adjustment");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_hscale_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean draw_value, inverted;
+ gint digits, i;
+ gchar *valuepos, *policy;
+ GtkAdjustment *adj;
+
+ draw_value = gb_widget_input_bool (data, DrawValue);
+ if (data->apply)
+ {
+ gtk_scale_set_draw_value (GTK_SCALE (widget), draw_value);
+ /* Shouldn't really need to do this */
+ editor_refresh_widget (widget);
+ }
+
+ valuepos = gb_widget_input_choice (data, ValuePos);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbValuePosValues) / sizeof (GbValuePosValues[0]);
+ i++)
+ {
+ if (!strcmp (valuepos, GbValuePosChoices[i])
+ || !strcmp (valuepos, GbValuePosSymbols[i]))
+ {
+ gtk_scale_set_value_pos (GTK_SCALE (widget), GbValuePosValues[i]);
+ break;
+ }
+ }
+ }
+
+ digits = gb_widget_input_int (data, Digits);
+ if (data->apply)
+ gtk_scale_set_digits (GTK_SCALE (widget), digits);
+
+ policy = gb_widget_input_choice (data, Policy);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (!strcmp (policy, GbPolicyChoices[i])
+ || !strcmp (policy, GbPolicySymbols[i]))
+ {
+ gtk_range_set_update_policy (GTK_RANGE (widget), GbPolicyValues
+ [i]);
+ break;
+ }
+ }
+ }
+
+ inverted = gb_widget_input_bool (data, Inverted);
+ if (data->apply)
+ {
+ gtk_range_set_inverted (GTK_RANGE (widget), inverted);
+ }
+
+ adj = GTK_RANGE (widget)->adjustment;
+ if (gb_widget_input_adjustment (data, Values, adj, "adjustment"))
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHScale, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_hscale_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hscale_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkAdjustment *adj = GTK_RANGE (widget)->adjustment;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (%g, %g, %g, %g, %g, %g)));\n",
+ data->wname, adj->value, adj->lower, adj->upper,
+ adj->step_increment, adj->page_increment, adj->page_size);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!GTK_SCALE (widget)->draw_value)
+ source_add (data, " gtk_scale_set_draw_value (GTK_SCALE (%s), FALSE);\n",
+ data->wname);
+
+ if (GTK_SCALE (widget)->value_pos != GTK_POS_TOP)
+ {
+ for (i = 0; i < sizeof (GbValuePosValues) / sizeof (GbValuePosValues[0]);
+ i++)
+ {
+ if (GbValuePosValues[i] == GTK_SCALE (widget)->value_pos)
+ source_add (data, " gtk_scale_set_value_pos (GTK_SCALE (%s), %s);\n",
+ data->wname, GbValuePosSymbols[i]);
+ }
+ }
+ if (GTK_SCALE (widget)->digits != 1)
+ source_add (data, " gtk_scale_set_digits (GTK_SCALE (%s), %i);\n",
+ data->wname, GTK_SCALE (widget)->digits);
+
+ if (GTK_RANGE (widget)->update_policy != GTK_UPDATE_CONTINUOUS)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ source_add (data,
+ " gtk_range_set_update_policy (GTK_RANGE (%s), %s);\n",
+ data->wname, GbPolicySymbols[i]);
+ }
+ }
+
+ if (GTK_RANGE (widget)->inverted)
+ {
+ source_add (data,
+ " gtk_range_set_inverted (GTK_RANGE (%s), TRUE);\n",
+ data->wname);
+
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hscale_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hscale_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hscale_xpm;
+ gbwidget.tooltip = _("Horizontal Scale");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hscale_new;
+ gbwidget.gb_widget_create_properties = gb_hscale_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hscale_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hscale_set_properties;
+ gbwidget.gb_widget_write_source = gb_hscale_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_hscale_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhscrollbar.c b/tools/glade/glade/gbwidgets/gbhscrollbar.c
new file mode 100644
index 00000000..8ca4d2da
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhscrollbar.c
@@ -0,0 +1,250 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhscrollbar.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hscrollbar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Policy = "HScrollbar|GtkRange::update_policy";
+static gchar *Inverted = "HScrollbar|GtkRange::inverted";
+
+static const gchar *Values[] =
+{
+ "GtkHScrollbar::value",
+ "GtkHScrollbar::lower",
+ "GtkHScrollbar::upper",
+ "GtkHScrollbar::step",
+ "GtkHScrollbar::page",
+ "GtkHScrollbar::page_size",
+};
+
+static const gchar *GbPolicyChoices[] =
+{"Continuous", "Discontinuous", "Delayed",
+ NULL};
+static const gint GbPolicyValues[] =
+{
+ GTK_UPDATE_CONTINUOUS,
+ GTK_UPDATE_DISCONTINUOUS,
+ GTK_UPDATE_DELAYED
+};
+static const gchar *GbPolicySymbols[] =
+{
+ "GTK_UPDATE_CONTINUOUS",
+ "GTK_UPDATE_DISCONTINUOUS",
+ "GTK_UPDATE_DELAYED"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHScrollbar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_hscrollbar_new (GbWidgetNewData * data)
+{
+ return gtk_hscrollbar_new (NULL);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_hscrollbar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Policy, _("Policy:"),
+ _("The update policy of the scrollbar"),
+ GbPolicyChoices);
+ property_add_bool (Inverted, _("Inverted:"), _("If the range values are inverted"));
+ property_add_adjustment (Values, GB_ADJUST_DEFAULT_LABELS);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_hscrollbar_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ gb_widget_output_choice (data, Policy, i, GbPolicySymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Inverted, GTK_RANGE (widget)->inverted);
+
+ gb_widget_output_adjustment (data, Values, GTK_RANGE (widget)->adjustment,
+ "adjustment");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_hscrollbar_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *policy;
+ gint i;
+ gboolean inverted;
+ GtkAdjustment *adj;
+
+ policy = gb_widget_input_choice (data, Policy);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (!strcmp (policy, GbPolicyChoices[i])
+ || !strcmp (policy, GbPolicySymbols[i]))
+ {
+ gtk_range_set_update_policy (GTK_RANGE (widget), GbPolicyValues
+ [i]);
+ break;
+ }
+ }
+ }
+
+ inverted = gb_widget_input_bool (data, Inverted);
+ if (data->apply)
+ {
+ gtk_range_set_inverted (GTK_RANGE (widget), inverted);
+ }
+
+ adj = GTK_RANGE (widget)->adjustment;
+ if (gb_widget_input_adjustment (data, Values, adj, "adjustment"))
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHScrollbar, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_hscrollbar_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hscrollbar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkAdjustment *adj = GTK_RANGE (widget)->adjustment;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = gtk_hscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (%g, %g, %g, %g, %g, %g)));\n",
+ data->wname, adj->value, adj->lower, adj->upper,
+ adj->step_increment, adj->page_increment, adj->page_size);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_RANGE (widget)->update_policy != GTK_UPDATE_CONTINUOUS)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ source_add (data,
+ " gtk_range_set_update_policy (GTK_RANGE (%s), %s);\n",
+ data->wname, GbPolicySymbols[i]);
+ }
+ }
+
+ if (GTK_RANGE (widget)->inverted)
+ {
+ source_add (data,
+ " gtk_range_set_inverted (GTK_RANGE (%s), TRUE);\n",
+ data->wname);
+
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hscrollbar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hscrollbar_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hscrollbar_xpm;
+ gbwidget.tooltip = _("Horizontal Scrollbar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hscrollbar_new;
+ gbwidget.gb_widget_create_properties = gb_hscrollbar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hscrollbar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hscrollbar_set_properties;
+ gbwidget.gb_widget_write_source = gb_hscrollbar_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_hscrollbar_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbhseparator.c b/tools/glade/glade/gbwidgets/gbhseparator.c
new file mode 100644
index 00000000..bcefcf28
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbhseparator.c
@@ -0,0 +1,157 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhseparator.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/hseparator.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkHSeparator, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_hseparator_new(GbWidgetNewData *data)
+{
+ return gtk_hseparator_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+ static void
+ gb_hseparator_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+ static void
+ gb_hseparator_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+ static void
+ gb_hseparator_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkHSeparator, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_hseparator_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_hseparator_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_hseparator_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_hseparator_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_hseparator_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = hseparator_xpm;
+ gbwidget.tooltip = _("Horizonal Separator");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_hseparator_new;
+/*
+ gbwidget.gb_widget_create_properties = gb_hseparator_create_properties;
+ gbwidget.gb_widget_get_properties = gb_hseparator_get_properties;
+ gbwidget.gb_widget_set_properties = gb_hseparator_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_hseparator_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_hseparator_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbiconview.c b/tools/glade/glade/gbwidgets/gbiconview.c
new file mode 100644
index 00000000..1c8f4d56
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbiconview.c
@@ -0,0 +1,322 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/iconview.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *SelectionMode = "GtkIconView::selection_mode";
+static gchar *Orientation = "GtkIconView::orientation";
+static gchar *Reorderable = "GtkIconView::reorderable";
+
+
+static const gchar *GbModeChoices[] =
+{"None", "Single", "Browse", "Multiple", NULL};
+static const gint GbModeValues[] =
+{
+ GTK_SELECTION_NONE,
+ GTK_SELECTION_SINGLE,
+ GTK_SELECTION_BROWSE,
+ GTK_SELECTION_MULTIPLE
+};
+static const gchar *GbModeSymbols[] =
+{
+ "GTK_SELECTION_NONE",
+ "GTK_SELECTION_SINGLE",
+ "GTK_SELECTION_BROWSE",
+ "GTK_SELECTION_MULTIPLE"
+};
+
+
+static const gchar *GbOrientationChoices[] =
+{"Horizontal", "Vertical", NULL};
+static const gint GbOrientationValues[] =
+{
+ GTK_ORIENTATION_HORIZONTAL,
+ GTK_ORIENTATION_VERTICAL
+};
+static const gchar *GbOrientationSymbols[] =
+{
+ "GTK_ORIENTATION_HORIZONTAL",
+ "GTK_ORIENTATION_VERTICAL"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkIconView, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_icon_view_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GbWidget *gbwidget;
+ GdkPixbuf *pixbuf;
+ char buf[256];
+ gint i;
+
+ new_widget = gtk_icon_view_new ();
+
+ /* Set up a dummy model so the user sees something. */
+ store = gtk_list_store_new (2, G_TYPE_STRING, GDK_TYPE_PIXBUF);
+
+ gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (gbwidget->pixbuf == NULL && gbwidget->pixmap_struct)
+ {
+ gbwidget->pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**) gbwidget->pixmap_struct);
+ }
+ pixbuf = gbwidget->pixbuf;
+
+ for (i = 1; i <= 8; i++)
+ {
+ gtk_list_store_append (store, &iter);
+ sprintf (buf, _("Icon %i"), i);
+ gtk_list_store_set (store, &iter, 0, buf, 1, pixbuf, -1);
+ }
+
+ gtk_icon_view_set_model (GTK_ICON_VIEW (new_widget), GTK_TREE_MODEL (store));
+ gtk_icon_view_set_text_column (GTK_ICON_VIEW (new_widget), 0);
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (new_widget), 1);
+
+ g_object_unref (G_OBJECT (store));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_icon_view_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (SelectionMode, _("Select Mode:"),
+ _("The selection mode of the icon view"),
+ GbModeChoices);
+ property_add_choice (Orientation, _("Orientation:"),
+ _("The orientation of the icons"),
+ GbOrientationChoices);
+ property_add_bool (Reorderable, _("Reorderable:"),
+ _("If the view can be reordered using Drag and Drop"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_icon_view_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkSelectionMode mode;
+ GtkOrientation orientation;
+ gboolean reorderable;
+ gint i;
+
+ mode = gtk_icon_view_get_selection_mode (GTK_ICON_VIEW (widget));
+ orientation = gtk_icon_view_get_orientation (GTK_ICON_VIEW (widget));
+
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == mode)
+ gb_widget_output_choice (data, SelectionMode, i, GbModeSymbols[i]);
+ }
+
+ for (i = 0; i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (GbOrientationValues[i] == orientation)
+ gb_widget_output_choice (data, Orientation, i, GbOrientationSymbols[i]);
+ }
+
+ reorderable = gtk_icon_view_get_reorderable (GTK_ICON_VIEW (widget));
+ gb_widget_output_bool (data, Reorderable, reorderable);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_icon_view_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *mode, *orientation;
+ gboolean reorderable;
+ gint i;
+
+ mode = gb_widget_input_choice (data, SelectionMode);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (!strcmp (mode, GbModeChoices[i])
+ || !strcmp (mode, GbModeSymbols[i]))
+ {
+ gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (widget), GbModeValues[i]);
+ break;
+ }
+ }
+ }
+
+ orientation = gb_widget_input_choice (data, Orientation);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (!strcmp (orientation, GbOrientationChoices[i])
+ || !strcmp (orientation, GbOrientationSymbols[i]))
+ {
+ gtk_icon_view_set_orientation (GTK_ICON_VIEW (widget),
+ GbOrientationValues[i]);
+ break;
+ }
+ }
+ }
+
+ reorderable = gb_widget_input_bool (data, Reorderable);
+ if (data->apply)
+ gtk_icon_view_set_reorderable (GTK_ICON_VIEW (widget), reorderable);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkIconView, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_icon_view_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_icon_view_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkSelectionMode mode;
+ GtkOrientation orientation;
+ gboolean reorderable;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_icon_view_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ mode = gtk_icon_view_get_selection_mode (GTK_ICON_VIEW (widget));
+ orientation = gtk_icon_view_get_orientation (GTK_ICON_VIEW (widget));
+
+ if (mode != GTK_SELECTION_SINGLE)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == mode)
+ source_add (data,
+ " gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (%s), %s);\n",
+ data->wname, GbModeSymbols[i]);
+ }
+ }
+
+ if (orientation != GTK_ORIENTATION_VERTICAL)
+ {
+ for (i = 0; i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (GbOrientationValues[i] == orientation)
+ source_add (data,
+ " gtk_icon_view_set_orientation (GTK_ICON_VIEW (%s), %s);\n",
+ data->wname, GbOrientationSymbols[i]);
+ }
+ }
+
+ reorderable = gtk_icon_view_get_reorderable (GTK_ICON_VIEW (widget));
+ if (reorderable)
+ {
+ source_add (data,
+ " gtk_icon_view_set_reorderable (GTK_ICON_VIEW (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_icon_view_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_icon_view_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = iconview_xpm;
+ gbwidget.tooltip = _("Icon View");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_icon_view_new;
+ gbwidget.gb_widget_create_properties = gb_icon_view_create_properties;
+ gbwidget.gb_widget_get_properties = gb_icon_view_get_properties;
+ gbwidget.gb_widget_set_properties = gb_icon_view_set_properties;
+ gbwidget.gb_widget_write_source = gb_icon_view_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_icon_view_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbimage.c b/tools/glade/glade/gbwidgets/gbimage.c
new file mode 100644
index 00000000..4906efbf
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbimage.c
@@ -0,0 +1,662 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <math.h>
+
+#include <gtk/gtkiconfactory.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/image.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* This could be a stock icon or a filename. */
+static gchar *Icon = "GtkImage::icon";
+
+/* This is the stock icon size, and isn't relevant when a filename is used. */
+static gchar *IconSize = "GtkImage::icon_size";
+
+static gchar *XAlign = "Image|GtkMisc::xalign";
+static gchar *YAlign = "Image|GtkMisc::yalign";
+static gchar *XPad = "Image|GtkMisc::xpad";
+static gchar *YPad = "Image|GtkMisc::ypad";
+
+static gchar *IconName = "GtkImage::icon_name";
+static gchar *PixelSize = "GtkImage::pixel_size";
+
+
+static const gchar *GladeIconSizeChoices[] =
+{"Menu", "Small Toolbar", "Large Toolbar", "Button", "Drag & Drop",
+ "Dialog", NULL};
+static const gint GladeIconSizeValues[] =
+{
+ GTK_ICON_SIZE_MENU,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ GTK_ICON_SIZE_LARGE_TOOLBAR,
+ GTK_ICON_SIZE_BUTTON,
+ GTK_ICON_SIZE_DND,
+ GTK_ICON_SIZE_DIALOG
+};
+static const gchar *GladeIconSizeSymbols[] =
+{
+ "GTK_ICON_SIZE_MENU",
+ "GTK_ICON_SIZE_SMALL_TOOLBAR",
+ "GTK_ICON_SIZE_LARGE_TOOLBAR",
+ "GTK_ICON_SIZE_BUTTON",
+ "GTK_ICON_SIZE_DND",
+ "GTK_ICON_SIZE_DIALOG"
+};
+const int GladeIconSizeChoicesSize = sizeof (GladeIconSizeValues) / sizeof (GladeIconSizeValues[0]);
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkImage, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_image_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ new_widget = gtk_image_new_from_pixmap (gbwidget.gdkpixmap, gbwidget.mask);
+ return new_widget;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_image_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GLADE_ICON_SIZE_ANY);
+ property_add_named_icon (IconName, _("Named Icon:"),
+ _("The named icon to use"));
+ property_add_choice (IconSize, _("Icon Size:"),
+ _("The stock icon size"),
+ GladeIconSizeChoices);
+ property_add_int_range (PixelSize, _("Pixel Size:"),
+ _("The size of the named icon in pixels, or -1 to use the Icon Size property"),
+ -1, 1000, 1, 10, 1);
+
+ property_add_float_range (XAlign, _("X Align:"),
+ _("The horizontal alignment"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (YAlign, _("Y Align:"),
+ _("The vertical alignment"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_int_range (XPad, _("X Pad:"), _("The horizontal padding"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (YPad, _("Y Pad:"), _("The vertical padding"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+static void
+check_visible_sizes (const gchar *stock_id, gboolean show_all)
+{
+ GtkIconSet *icon_set;
+ GtkIconSize *sizes;
+ gint n_sizes, i, j;
+ GtkWidget *option_menu, *menu;
+ gboolean item_visible[G_N_ELEMENTS(GladeIconSizeValues)];
+ GList *children;
+
+ for (j = 0; j < GladeIconSizeChoicesSize; j++)
+ item_visible[j] = show_all;
+
+ if (!show_all)
+ {
+ icon_set = gtk_icon_factory_lookup_default (stock_id);
+ if (icon_set)
+ {
+ gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
+ /* Figure out which of our choices should be visible. */
+ for (i = 0; i < n_sizes; i++)
+ {
+ for (j = 0; j < GladeIconSizeChoicesSize; j++)
+ {
+ if (sizes[i] == GladeIconSizeValues[j])
+ item_visible[j] = TRUE;
+ }
+ }
+ g_free (sizes);
+ }
+ }
+
+ /* Show or Hide the items as appropriate. */
+ option_menu = property_get_value_widget (IconSize);
+ g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+ menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (option_menu));
+ g_return_if_fail (GTK_IS_MENU (menu));
+
+ children = GTK_MENU_SHELL (menu)->children;
+ for (j = 0; j < GladeIconSizeChoicesSize; j++)
+ {
+ GtkWidget *item;
+
+ item = children->data;
+
+ if (item_visible[j])
+ gtk_widget_show (item);
+ else
+ gtk_widget_hide (item);
+
+ children = children->next;
+ }
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_image_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gchar *icon = gtk_object_get_data (GTK_OBJECT (widget), GladeIconKey);
+ gchar *icon_name = NULL;
+ gboolean is_stock_icon, is_named_icon = FALSE;
+ gint i, pixel_size;
+ GtkImageType storage_type;
+
+ storage_type = gtk_image_get_storage_type (GTK_IMAGE (widget));
+ pixel_size = gtk_image_get_pixel_size (GTK_IMAGE (widget));
+
+ is_stock_icon = glade_util_check_is_stock_id (icon);
+
+ if (storage_type == GTK_IMAGE_ICON_NAME)
+ {
+ g_object_get (widget,
+ "icon_name", &icon_name,
+ NULL);
+ if (icon_name && *icon_name)
+ is_named_icon = TRUE;
+ }
+
+ if (data->action == GB_SAVING)
+ {
+ /* When saving we want to use "stock" or "pixbuf", depending on whether
+ it is a stock icon or an oridinary pixmap file. */
+ if (is_stock_icon)
+ gb_widget_output_icon (data, "stock", icon);
+ else
+ gb_widget_output_icon (data, "pixbuf", icon);
+ }
+ else
+ {
+ gb_widget_output_icon (data, Icon, icon);
+ }
+
+ if (is_stock_icon || is_named_icon)
+ {
+ if (data->action == GB_SHOWING)
+ {
+ for (i = 0; i < GladeIconSizeChoicesSize; i++)
+ {
+ if (GladeIconSizeValues[i] == GTK_IMAGE (widget)->icon_size)
+ gb_widget_output_choice (data, IconSize, i,
+ GladeIconSizeSymbols[i]);
+ }
+
+ check_visible_sizes (icon, is_named_icon);
+ }
+ else
+ {
+ /* We have to save the size as an integer, which sucks a bit.
+ The integer is the GtkIconSize enum value, not the actual size.*/
+ if (is_stock_icon || pixel_size == -1)
+ gb_widget_output_int (data, IconSize,
+ GTK_IMAGE (widget)->icon_size);
+ }
+ }
+
+ gb_widget_output_named_icon (data, IconName, icon_name);
+
+ /* The icon size only applies to stock icons or named icons.
+ The pixel size only applies to named icons. */
+ if (data->action == GB_SHOWING)
+ {
+ property_set_sensitive (IconSize, is_stock_icon || is_named_icon);
+ property_set_sensitive (PixelSize, is_named_icon);
+ }
+
+ /* We only want to save the pixel size for named icons, and only if it is
+ not -1. */
+ if (data->action == GB_SHOWING
+ || (storage_type == GTK_IMAGE_ICON_NAME && pixel_size != -1))
+ gb_widget_output_int (data, PixelSize, pixel_size);
+
+ gb_widget_output_float (data, XAlign, GTK_MISC (widget)->xalign);
+ gb_widget_output_float (data, YAlign, GTK_MISC (widget)->yalign);
+ gb_widget_output_int (data, XPad, GTK_MISC (widget)->xpad);
+ gb_widget_output_int (data, YPad, GTK_MISC (widget)->ypad);
+}
+
+
+/* Check the icon size is valid for the stock item, and if not pick
+ the first valid size. */
+static GtkIconSize
+check_icon_size (const gchar *stock_id, GtkIconSize icon_size)
+{
+ GtkIconSet *icon_set;
+ GtkIconSize *sizes, retval = GTK_ICON_SIZE_BUTTON;
+ gint n_sizes, i;
+
+ icon_set = gtk_icon_factory_lookup_default (stock_id);
+ if (icon_set)
+ {
+ gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
+
+ for (i = 0; i < n_sizes; i++)
+ {
+ if (sizes[i] == icon_size)
+ return icon_size;
+ }
+
+ retval = sizes[0];
+ g_free (sizes);
+ }
+
+ return retval;
+}
+
+
+static void
+gb_image_clear_pixmap (GtkWidget *widget, GladeProject *project)
+{
+ gchar *old_icon;
+
+ /* Remove the old icon stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ old_icon = gtk_object_get_data (GTK_OBJECT (widget), GladeIconKey);
+ glade_project_remove_pixmap (project, old_icon);
+
+ gtk_object_set_data (GTK_OBJECT (widget), GladeIconKey, NULL);
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_image_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat xalign, yalign;
+ gint xpad, ypad, i, pixel_size;
+ gboolean set_alignment = FALSE, set_padding = FALSE, apply_icon_size;
+ GtkIconSize icon_size = GTK_ICON_SIZE_BUTTON;
+ gchar *icon_size_string, *icon, *icon_name;
+
+ icon_size = GTK_IMAGE (widget)->icon_size;
+
+ if (data->action == GB_APPLYING)
+ {
+ icon_size_string = gb_widget_input_choice (data, IconSize);
+ apply_icon_size = data->apply;
+ if (data->apply)
+ {
+ for (i = 0; i < GladeIconSizeChoicesSize; i++)
+ {
+ if (!strcmp (icon_size_string, GladeIconSizeChoices[i])
+ || !strcmp (icon_size_string, GladeIconSizeSymbols[i]))
+ {
+ icon_size = GladeIconSizeValues[i];
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* We have to save the size as an integer, which sucks a bit.
+ The integer is the GtkIconSize enum value, not the actual size.*/
+ int new_size = gb_widget_input_int (data, IconSize);
+ apply_icon_size = data->apply;
+ if (data->apply)
+ icon_size = new_size;
+ }
+
+ /* When loading we use different names. */
+ if (data->action == GB_LOADING)
+ {
+ icon = gb_widget_input_icon (data, "stock");
+ if (!data->apply)
+ icon = gb_widget_input_icon (data, "pixbuf");
+ }
+ else
+ {
+ icon = gb_widget_input_icon (data, Icon);
+ }
+
+ if (data->apply)
+ {
+ gboolean is_stock_icon = glade_util_check_is_stock_id (icon);
+
+ /* Remove the old icon stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ gb_image_clear_pixmap (widget, data->project);
+
+ gtk_object_set_data_full (GTK_OBJECT (widget), GladeIconKey,
+ g_strdup (icon), icon ? g_free : NULL);
+
+ if (is_stock_icon)
+ {
+ GtkIconSize new_icon_size;
+
+ new_icon_size = check_icon_size (icon, icon_size);
+
+ /* If we are showing this widget's properties, we need to update
+ the sizes option menu. */
+ if (property_get_widget () == widget)
+ {
+ /* We set it sensitive before changing the value, so the child
+ menu item is changed from insensitive to sensitive if needed.
+ Otherwise it may remain insensitive. */
+ property_set_sensitive (IconSize, TRUE);
+ property_set_sensitive (PixelSize, FALSE);
+
+ property_set_auto_apply (FALSE);
+
+ check_visible_sizes (icon, FALSE);
+
+ /* Check the icon size is valid for the stock item, and if not
+ pick the first valid size. */
+ for (i = 0; i < GladeIconSizeChoicesSize; i++)
+ {
+ if (GladeIconSizeValues[i] == new_icon_size)
+ {
+ property_set_choice (IconSize, i);
+ }
+ }
+
+ property_set_named_icon (IconName, NULL);
+
+ property_set_auto_apply (TRUE);
+ }
+
+ gtk_image_set_from_stock (GTK_IMAGE (widget), icon,
+ new_icon_size);
+ }
+ else
+ {
+ /* If an icon filename is set, use that, otherwise use the icon
+ we use for the palette. */
+ if (icon)
+ {
+ gtk_image_set_from_file (GTK_IMAGE (widget), icon);
+ glade_project_add_pixmap (data->project, icon);
+ }
+ else
+ {
+ gtk_image_set_from_pixmap (GTK_IMAGE (widget),
+ gbwidget.gdkpixmap, gbwidget.mask);
+ }
+
+ if (property_get_widget () == widget)
+ {
+ /* The icon size isn't relevant to non-stock icons. */
+ property_set_sensitive (IconSize, FALSE);
+ property_set_sensitive (PixelSize, FALSE);
+
+ property_set_auto_apply (FALSE);
+ property_set_named_icon (IconName, NULL);
+ property_set_auto_apply (TRUE);
+ }
+ }
+
+ /* We've recreated the icon with the new size above, so we don't need
+ to apply the size again. */
+ apply_icon_size = FALSE;
+ }
+
+ /* This is for the named/themed icon. */
+ icon_name = gb_widget_input_named_icon (data, IconName);
+ if (data->apply)
+ {
+ /* Clear any stock icon or icon from a file. */
+ gb_image_clear_pixmap (widget, data->project);
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (widget), icon_name,
+ icon_size);
+
+ if (property_get_widget () == widget)
+ {
+ property_set_sensitive (IconSize, TRUE);
+ property_set_sensitive (PixelSize, TRUE);
+
+ /* Clear the Icon property. */
+ property_set_auto_apply (FALSE);
+ property_set_icon (Icon, NULL);
+ property_set_auto_apply (TRUE);
+ }
+
+ /* We've recreated the icon with the new size above, so we don't need
+ to apply the size again. */
+ apply_icon_size = FALSE;
+ }
+
+ /* When we set the icon size, we reset the pixel size to -1, otherwise it
+ overrides the icon size. */
+ if (apply_icon_size)
+ {
+ gtk_image_set_pixel_size (GTK_IMAGE (widget), -1);
+ g_object_set (widget, "icon_size", icon_size, NULL);
+
+ if (property_get_widget () == widget)
+ {
+ property_set_auto_apply (FALSE);
+ property_set_int (PixelSize, -1);
+ property_set_auto_apply (TRUE);
+ }
+ }
+
+ /* GtkImage doesn't like a pixel size of 0 so we just skip that. */
+ pixel_size = gb_widget_input_int (data, PixelSize);
+ if (data->apply && pixel_size != 0)
+ gtk_image_set_pixel_size (GTK_IMAGE (widget), pixel_size);
+
+ xalign = gb_widget_input_float (data, XAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ xalign = GTK_MISC (widget)->xalign;
+
+ yalign = gb_widget_input_float (data, YAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ yalign = GTK_MISC (widget)->yalign;
+
+ if (set_alignment)
+ gtk_misc_set_alignment (GTK_MISC (widget), xalign, yalign);
+
+ xpad = gb_widget_input_int (data, XPad);
+ if (data->apply)
+ set_padding = TRUE;
+ else
+ xpad = GTK_MISC (widget)->xpad;
+
+ ypad = gb_widget_input_int (data, YPad);
+ if (data->apply)
+ set_padding = TRUE;
+ else
+ ypad = GTK_MISC (widget)->ypad;
+
+ if (set_padding)
+ gtk_misc_set_padding (GTK_MISC (widget), xpad, ypad);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkImage, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_image_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_image_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ /* For GNOME projects menuitem images are handled by the GnomeUIInfo
+ structs, so we don't create source code here. */
+ if (widget->parent && GTK_IS_IMAGE_MENU_ITEM (widget->parent)
+ && glade_project_get_gnome_support (data->project))
+ return;
+
+ if (data->create_widget)
+ {
+ gchar *icon = gtk_object_get_data (GTK_OBJECT (widget), GladeIconKey);
+ const gchar *icon_size = "GTK_ICON_SIZE_BUTTON";
+ GtkImageType storage_type;
+ gint i;
+
+ for (i = 0; i < GladeIconSizeChoicesSize; i++)
+ {
+ if (GladeIconSizeValues[i] == GTK_IMAGE (widget)->icon_size)
+ {
+ icon_size = GladeIconSizeSymbols[i];
+ }
+ }
+
+ storage_type = gtk_image_get_storage_type (GTK_IMAGE (widget));
+
+ if (storage_type == GTK_IMAGE_ICON_NAME)
+ {
+ gint pixel_size = gtk_image_get_pixel_size (GTK_IMAGE (widget));
+ gchar *icon_name;
+
+ g_object_get (widget,
+ "icon_name", &icon_name,
+ NULL);
+
+ source_add (data,
+ " %s = gtk_image_new_from_icon_name (\"%s\", %s);\n",
+ data->wname, icon_name ? icon_name : "gtk-missing-image",
+ icon_size);
+
+ if (pixel_size > 0)
+ {
+ source_add (data,
+ " gtk_image_set_pixel_size (%s, %i);\n",
+ data->wname, pixel_size);
+ }
+ }
+ else if (glade_util_check_is_stock_id (icon))
+ {
+
+ source_add (data,
+ " %s = gtk_image_new_from_stock (\"%s\", %s);\n",
+ data->wname, icon, icon_size);
+ }
+ else
+ {
+ source_create_pixmap (data, data->wname, icon);
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (fabs (GTK_MISC (widget)->xalign - 0.5) > 0.0001
+ || fabs (GTK_MISC (widget)->yalign - 0.5) > 0.0001)
+ source_add (data, " gtk_misc_set_alignment (GTK_MISC (%s), %g, %g);\n",
+ data->wname, GTK_MISC (widget)->xalign, GTK_MISC (widget)->yalign);
+
+ if (GTK_MISC (widget)->xpad != 0 || GTK_MISC (widget)->ypad != 0)
+ source_add (data, " gtk_misc_set_padding (GTK_MISC (%s), %i, %i);\n",
+ data->wname, GTK_MISC (widget)->xpad, GTK_MISC (widget)->ypad);
+}
+
+
+void
+gb_image_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ gb_image_clear_pixmap (widget, data->project);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_image_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_image_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = image_xpm;
+ gbwidget.tooltip = _("Image");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_image_new;
+ gbwidget.gb_widget_create_properties = gb_image_create_properties;
+ gbwidget.gb_widget_get_properties = gb_image_get_properties;
+ gbwidget.gb_widget_set_properties = gb_image_set_properties;
+ gbwidget.gb_widget_write_source = gb_image_write_source;
+ gbwidget.gb_widget_destroy = gb_image_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_image_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbimagemenuitem.c b/tools/glade/glade/gbwidgets/gbimagemenuitem.c
new file mode 100644
index 00000000..0c63872d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbimagemenuitem.c
@@ -0,0 +1,486 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtkaccellabel.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkstock.h>
+
+#include "../gb.h"
+#include "../glade_gnome.h"
+#include "../glade_keys_dialog.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/menuitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "ImageMenuItem|GtkItem::label";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkPixmapMenuItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_image_menu_item_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_image_menu_item_new_with_label (data->name);
+ else
+ new_widget = gtk_image_menu_item_new ();
+ return new_widget;
+}
+
+
+void
+gb_image_menu_item_add_child (GtkWidget * widget, GtkWidget * child, GbWidgetSetArgData *data)
+{
+ if (GTK_IS_MENU (child))
+ {
+ MSG ("Trying to add a menu to a menu item");
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), child);
+ }
+ else if (GTK_IS_IMAGE (child))
+ {
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), child);
+ }
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_image_menu_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+#if 0
+ /* For now we don't support editing the menuitem properties in the property
+ editor. The menu editor has to be used instead. */
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+#endif
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_image_menu_item_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gboolean output_label = TRUE;
+
+ /* We only support saving the properties here. */
+ if (data->action != GB_SAVING)
+ return;
+
+ /* Check if it is a stock menu item, and if so, we just save that. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+#ifdef USE_GNOME
+ gint stock_item_index;
+
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), GladeMenuItemStockIndexKey));
+ /* The 'New' item is special. If it has a child menu, it must be a
+ GNOMEUIINFO_MENU_NEW_SUBTREE. If not, it is a
+ GNOMEUIINFO_MENU_NEW_ITEM, in which case the label is also output. */
+ if (stock_item_index == GladeStockMenuItemNew)
+ {
+ if (GTK_MENU_ITEM (widget)->submenu)
+ {
+ gb_widget_output_string (data, "stock_item",
+ "GNOMEUIINFO_MENU_NEW_SUBTREE");
+ output_label = FALSE;
+ }
+ else
+ {
+ gb_widget_output_string (data, "stock_item",
+ "GNOMEUIINFO_MENU_NEW_ITEM");
+ }
+ }
+ else if (stock_item_index != 0)
+ {
+ gb_widget_output_string (data, "stock_item", GladeStockMenuItemSymbols[stock_item_index]);
+ output_label = FALSE;
+ }
+#endif
+ }
+ else
+ {
+ char *stock_id;
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget), GladeMenuItemStockIDKey);
+ if (stock_id)
+ {
+ gb_widget_output_string (data, "label", stock_id);
+ gb_widget_output_bool (data, "use_stock", TRUE);
+
+ /* The 'New' item isn't special for GTK+ apps. */
+ output_label = FALSE;
+ }
+ }
+
+ if (output_label)
+ gb_widget_output_child_label (widget, data, Label);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_image_menu_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean input_label = TRUE, input_rest = TRUE;
+ GtkAccelGroup *accel_group;
+ guint key;
+ GdkModifierType modifiers;
+
+ /* We only support loading the properties here. */
+ if (data->action != GB_LOADING)
+ return;
+
+ /* Check for a stock menu item. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+#ifdef USE_GNOME
+ gchar *stock_item;
+
+ stock_item = gb_widget_input_string (data, "stock_item");
+ if (stock_item && stock_item[0])
+ {
+ gint stock_item_index;
+
+ /* Special case for the NEW_SUBTREE. */
+ if (!strcmp (stock_item, "GNOMEUIINFO_MENU_NEW_SUBTREE"))
+ {
+ stock_item_index = GladeStockMenuItemNew;
+ }
+ else
+ {
+ stock_item_index = glade_util_string_array_index (GladeStockMenuItemSymbols, GladeStockMenuItemSize, stock_item);
+ }
+
+ if (stock_item_index != -1)
+ {
+ GnomeUIInfo *uiinfo;
+ GtkWidget *pixmap = NULL, *label;
+
+ uiinfo = &GladeStockMenuItemValues[stock_item_index];
+ if (uiinfo->type == GNOME_APP_UI_ITEM_CONFIGURABLE)
+ gnome_app_ui_configure_configurable (uiinfo);
+
+ if (uiinfo->pixmap_type == GNOME_APP_PIXMAP_STOCK)
+ pixmap = gtk_image_new_from_stock (uiinfo->pixmap_info,
+ GTK_ICON_SIZE_MENU);
+
+ if (pixmap)
+ {
+ gtk_widget_show (pixmap);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget),
+ pixmap);
+ }
+
+ label = gtk_accel_label_new ("");
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label),
+ glade_gnome_gettext (uiinfo->label));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label),
+ widget);
+ gtk_container_add (GTK_CONTAINER (widget), label);
+
+ /* Add the configured accelerator key. */
+ if (uiinfo->accelerator_key != 0 && widget->parent
+ && GTK_IS_MENU (widget->parent))
+ {
+ accel_group = GTK_MENU (widget->parent)->accel_group;
+ gtk_widget_add_accelerator (widget, "activate", accel_group,
+ uiinfo->accelerator_key,
+ uiinfo->ac_mods,
+ GTK_ACCEL_VISIBLE);
+ }
+
+ /* Remember the index of the stock item. */
+ gtk_object_set_data (GTK_OBJECT (widget),
+ GladeMenuItemStockIndexKey,
+ GINT_TO_POINTER (stock_item_index));
+
+ /* The 'New' item can have a label. The rest can't. */
+ if (stock_item_index != GladeStockMenuItemNew)
+ input_label = FALSE;
+ input_rest = FALSE;
+ }
+ else
+ {
+#ifdef FIXME
+ load_add_error_message_with_tag (data,
+ GLADE_LINE_PROPERTY,
+ _("Invalid stock menu item"),
+ "stock_item", stock_item);
+#endif
+ }
+ }
+#endif
+ }
+ else
+ {
+ gboolean is_stock_item;
+ gchar *stock_id;
+
+ is_stock_item = gb_widget_input_bool (data, "use_stock");
+ if (is_stock_item)
+ {
+ stock_id = gb_widget_input_string (data, "label");
+ }
+ else
+ {
+ /* This is for backwards compatability with Glade 1.1.0. */
+ stock_id = gb_widget_input_string (data, "stock");
+ if (stock_id && stock_id[0])
+ is_stock_item = TRUE;
+ }
+
+ if (is_stock_item && stock_id && stock_id[0])
+ {
+ GtkStockItem item;
+ GtkWidget *label, *image;
+
+ if (gtk_stock_lookup (stock_id, &item))
+ {
+ label = gtk_type_new (GTK_TYPE_ACCEL_LABEL);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label), item.label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+
+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label),
+ widget);
+ gtk_container_add (GTK_CONTAINER (widget), label);
+
+ /* Add the configured accelerator key. */
+ if (item.keyval && widget->parent
+ && GTK_IS_MENU (widget->parent))
+ {
+ accel_group = GTK_MENU (widget->parent)->accel_group;
+ gtk_widget_add_accelerator (widget, "activate", accel_group,
+ item.keyval,
+ item.modifier,
+ GTK_ACCEL_VISIBLE);
+ }
+
+ image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+ if (image)
+ {
+ gtk_widget_show (image);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget),
+ image);
+ }
+
+
+
+ /* Remember the stock ID. */
+ gtk_object_set_data_full (GTK_OBJECT (widget),
+ GladeMenuItemStockIDKey,
+ g_strdup (stock_id), g_free);
+
+ input_label = FALSE;
+ input_rest = FALSE;
+ }
+ else
+ {
+ g_warning ("Invalid stock menu item: %s", stock_id);
+ }
+ }
+ }
+
+ if (input_label)
+ gb_widget_input_child_label (widget, data, Label);
+
+ if (input_rest)
+ {
+ /* FIXME: should this be somewhere else? */
+ /* If we are loading, install the 'activate' accelerator, if it has one,
+ so that is is visible. */
+ if (data->action == GB_LOADING && widget->parent
+ && GTK_IS_MENU (widget->parent))
+ {
+ int i;
+
+ for (i = 0; i < data->widget_info->n_accels; i++)
+ {
+ if (!strcmp (data->widget_info->accels[i].signal, "activate"))
+ {
+ key = data->widget_info->accels[i].key;
+ modifiers = data->widget_info->accels[i].modifiers;
+ accel_group = GTK_MENU (widget->parent)->accel_group;
+ gtk_widget_add_accelerator (widget, "activate", accel_group,
+ key, modifiers,
+ GTK_ACCEL_VISIBLE);
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkPixmapMenuItem, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_image_menu_item_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data)
+{
+ /* Add command to remove child label. */
+#if 0
+ gb_widget_create_child_label_popup_menu (widget, data);
+#endif
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_image_menu_item_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *stock_id, *label_text;
+ gboolean translatable, context;
+ gchar *comments;
+
+#ifdef USE_GNOME
+ if (data->project->gnome_support)
+ {
+ glade_gnome_write_menu_item_source (GTK_MENU_ITEM (widget), data);
+ return;
+ }
+#endif
+
+ /* See if it is a stock item. */
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeMenuItemStockIDKey);
+ if (stock_id)
+ {
+ data->need_accel_group = TRUE;
+ source_add (data, " %s = gtk_image_menu_item_new_from_stock (\"%s\", accel_group);\n",
+ data->wname, stock_id);
+ }
+ else
+ {
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ label_text = glade_util_get_label_text (GTK_BIN (widget)->child);
+ source_add (data, " %s = gtk_image_menu_item_new_with_mnemonic (%s);\n",
+ data->wname,
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+/* Outputs source to add a child menu to a menu item. */
+static void
+gb_image_menu_item_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ if (GTK_IS_MENU (child))
+ {
+ source_add (data,
+ " gtk_menu_item_set_submenu (GTK_MENU_ITEM (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else if (GTK_IS_IMAGE (child))
+ {
+ source_add (data,
+ " gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else
+ {
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_image_menu_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_image_menu_item_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = menuitem_xpm;
+ gbwidget.tooltip = _("Menu item with a pixmap");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_image_menu_item_new;
+ gbwidget.gb_widget_add_child = gb_image_menu_item_add_child;
+ gbwidget.gb_widget_create_properties = gb_image_menu_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_image_menu_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_image_menu_item_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_image_menu_item_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_image_menu_item_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_image_menu_item_write_add_child_source;
+ /*gbwidget.gb_widget_destroy = gb_image_menu_item_destroy;*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbinputdialog.c b/tools/glade/glade/gbwidgets/gbinputdialog.c
new file mode 100644
index 00000000..4057cd23
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbinputdialog.c
@@ -0,0 +1,273 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkinputdialog.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/inputdialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "InputDialog|GtkWindow::title";
+static gchar *Type = "InputDialog|GtkWindow::type";
+static gchar *Position = "InputDialog|GtkWindow::window_position";
+static gchar *Modal = "InputDialog|GtkWindow::modal";
+static gchar *DefaultWidth = "Input|GtkWindow::default_width";
+static gchar *DefaultHeight = "Input|GtkWindow::default_height";
+static gchar *Shrink = "InputDialog|GtkWindow::allow_shrink";
+static gchar *Grow = "InputDialog|GtkWindow::allow_grow";
+static gchar *AutoShrink = "InputDialog|GtkWindow::auto_shrink";
+static gchar *IconName = "InputDialog|GtkWindow::icon_name";
+static gchar *FocusOnMap = "InputDialog|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "InputDialog|GtkWindow::resizable";
+static gchar *DestroyWithParent = "InputDialog|GtkWindow::destroy_with_parent";
+static gchar *Icon = "InputDialog|GtkWindow::icon";
+
+static gchar *Role = "InputDialog|GtkWindow::role";
+static gchar *TypeHint = "InputDialog|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "InputDialog|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "InputDialog|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "InputDialog|GtkWindow::decorated";
+static gchar *Gravity = "InputDialog|GtkWindow::gravity";
+static gchar *Urgency = "InputDialog|GtkWindow::urgency_hint";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkInputDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_input_dialog_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget = gtk_input_dialog_new ();
+
+ GtkInputDialog *inputdlg = GTK_INPUT_DIALOG (new_widget);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gb_widget_create_from (inputdlg->save_button,
+ data->action == GB_CREATING ? "save_button" : NULL);
+ gb_widget_set_child_name (inputdlg->save_button, GladeChildSaveButton);
+ /* We need to set it sensitive so the user can select it. */
+ gtk_widget_set_sensitive (inputdlg->save_button, TRUE);
+
+ gb_widget_create_from (inputdlg->close_button,
+ data->action == GB_CREATING ? "close_button" : NULL);
+ gb_widget_set_child_name (inputdlg->close_button, GladeChildCloseButton);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_input_dialog_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_input_dialog_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_input_dialog_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkInputDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_input_dialog_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_input_dialog_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_input_dialog_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_window_write_standard_source (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ /* We output the source code for the buttons here, but we don't want them
+ to be created. We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_INPUT_DIALOG (widget)->save_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_INPUT_DIALOG (%s)->save_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_INPUT_DIALOG (widget)->save_button,
+ data);
+
+ child_name = (gchar*) gtk_widget_get_name (GTK_INPUT_DIALOG (widget)->close_button);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GTK_INPUT_DIALOG (%s)->close_button;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_INPUT_DIALOG (widget)->close_button,
+ data);
+
+ g_free (wname);
+
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_input_dialog_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildSaveButton))
+ return GTK_INPUT_DIALOG (widget)->save_button;
+ else if (!strcmp (child_name, GladeChildCloseButton))
+ return GTK_INPUT_DIALOG (widget)->close_button;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_input_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_input_dialog_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = inputdialog_xpm;
+ gbwidget.tooltip = _("Input Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_input_dialog_new;
+ gbwidget.gb_widget_get_child = gb_input_dialog_get_child;
+ gbwidget.gb_widget_create_properties = gb_input_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_input_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_input_dialog_set_properties;
+ gbwidget.gb_widget_write_source = gb_input_dialog_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_input_dialog_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gblabel.c b/tools/glade/glade/gbwidgets/gblabel.c
new file mode 100644
index 00000000..dbfd9879
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gblabel.c
@@ -0,0 +1,885 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <gtk/gtkcombo.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkexpander.h>
+#include <gtk/gtkfilechooserbutton.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtklist.h>
+#include <gtk/gtklistitem.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkeventbox.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/label.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "GtkLabel::label";
+static gchar *UseUnderline = "GtkLabel::use_underline";
+static gchar *UseMarkup = "GtkLabel::use_markup";
+static gchar *Justify = "GtkLabel::justify";
+static gchar *Wrap = "GtkLabel::wrap";
+static gchar *XAlign = "Label|GtkMisc::xalign";
+static gchar *YAlign = "Label|GtkMisc::yalign";
+static gchar *XPad = "Label|GtkMisc::xpad";
+static gchar *YPad = "Label|GtkMisc::ypad";
+static gchar *Selectable = "GtkLabel::selectable";
+
+static gchar *Ellipsize = "GtkLabel::ellipsize";
+static gchar *WidthChars = "GtkLabel::width_chars";
+static gchar *SingleLineMode = "GtkLabel::single_line_mode";
+static gchar *Angle = "GtkLabel::angle";
+
+static gchar *FocusTarget = "GtkLabel::mnemonic_widget";
+
+
+static const gchar *GbJustifyChoices[] =
+{
+ "Left",
+ "Right",
+ "Center",
+ "Fill",
+ NULL
+};
+static const gint GbJustifyValues[] =
+{
+ GTK_JUSTIFY_LEFT,
+ GTK_JUSTIFY_RIGHT,
+ GTK_JUSTIFY_CENTER,
+ GTK_JUSTIFY_FILL
+};
+static const gchar *GbJustifySymbols[] =
+{
+ "GTK_JUSTIFY_LEFT",
+ "GTK_JUSTIFY_RIGHT",
+ "GTK_JUSTIFY_CENTER",
+ "GTK_JUSTIFY_FILL"
+};
+
+static const gchar *GbEllipsizeChoices[] =
+{
+ "None",
+ "Start",
+ "Middle",
+ "End",
+ NULL
+};
+static const gint GbEllipsizeValues[] =
+{
+ PANGO_ELLIPSIZE_NONE,
+ PANGO_ELLIPSIZE_START,
+ PANGO_ELLIPSIZE_MIDDLE,
+ PANGO_ELLIPSIZE_END
+};
+static const gchar *GbEllipsizeSymbols[] =
+{
+ "PANGO_ELLIPSIZE_NONE",
+ "PANGO_ELLIPSIZE_START",
+ "PANGO_ELLIPSIZE_MIDDLE",
+ "PANGO_ELLIPSIZE_END"
+};
+
+
+static void gb_label_get_focus_targets (GtkWidget * widget,
+ GList ** focus_targets);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkLabel, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_label_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_label_new (data->name);
+
+ /* If we are creating a new label in a table or in an event box in a table
+ set it to left-aligned, since that is what is usually wanted. */
+ if (data->action == GB_CREATING && data->parent
+ && (GTK_IS_TABLE (data->parent)
+ || (GTK_IS_EVENT_BOX (data->parent) && data->parent->parent
+ && GTK_IS_TABLE (data->parent->parent))))
+ {
+ gtk_misc_set_alignment (GTK_MISC (new_widget), 0.0, 0.5);
+ }
+
+ return new_widget;
+}
+
+
+
+void
+gb_label_create_standard_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p)
+{
+ GtkWidget *combo;
+
+ property_add_text (label_p, _("Label:"), _("The text to display"), 5);
+ property_add_bool (use_underline_p, _("Use Underline:"),
+ _("If the text includes an underlined access key"));
+ property_add_bool (use_markup_p, _("Use Markup:"),
+ _("If the text includes pango markup"));
+ property_add_choice (justify_p, _("Justify:"),
+ _("The justification of the lines of the label"),
+ GbJustifyChoices);
+ property_add_bool (wrap_p, _("Wrap Text:"),
+ _("If the text is wrapped to fit within the width of the label"));
+ property_add_bool (selectable_p, _("Selectable:"),
+ _("If the label text can be selected with the mouse"));
+ property_add_float_range (xalign_p, _("X Align:"),
+ _("The horizontal alignment of the entire label"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (yalign_p, _("Y Align:"),
+ _("The vertical alignment of the entire label"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_int_range (xpad_p, _("X Pad:"), _("The horizontal padding"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (ypad_p, _("Y Pad:"), _("The vertical padding"),
+ 0, 1000, 1, 10, 1);
+ property_add_combo (focus_target_p, _("Focus Target:"),
+ _("The widget to set the keyboard focus to when the underlined access key is used"),
+ NULL);
+ combo = property_get_value_widget (focus_target_p);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE);
+ /*gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, TRUE);*/
+
+ property_add_choice (ellipsize_p, _("Ellipsize:"),
+ _("How to ellipsize the string"),
+ GbEllipsizeChoices);
+ property_add_int_range (width_chars_p, _("Width in Chars:"),
+ _("The width of the label in characters"),
+ -1, 1000, 1, 10, 1);
+ property_add_bool (single_line_mode_p, _("Single Line Mode:"),
+ _("If the label is only given enough height for a single line"));
+ property_add_float_range (angle_p, _("Angle:"),
+ _("The angle of the label text"),
+ 0, 360, 1, 10, 1, 2);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_label_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_label_create_standard_properties (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+
+/* This tries to find a parent widget of a label that would be used for
+ mnemonic activation, e.g. a button or a menuitem. If it finds one, it
+ returns TRUE. */
+static gboolean
+gb_label_find_mnemonic_widget (GtkWidget *widget)
+{
+ GtkWidget *parent;
+
+ parent = widget->parent;
+
+ while (parent)
+ {
+ if (GTK_IS_EXPANDER (parent))
+ {
+ if (gtk_expander_get_label_widget (GTK_EXPANDER (parent)) == widget)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ if (GTK_WIDGET_GET_CLASS (parent)->activate_signal)
+ {
+ return TRUE;
+ }
+ if (GTK_IS_MENU_ITEM (parent))
+ {
+ return TRUE;
+ }
+
+ parent = parent->parent;
+ }
+
+ return FALSE;
+}
+
+
+void
+gb_label_get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p)
+{
+ const gchar *label_text;
+ PangoEllipsizeMode ellipsize_mode;
+ gint i, width_chars;
+ gboolean single_line_mode;
+ gfloat angle;
+
+ label_text = gtk_label_get_label (GTK_LABEL (widget));
+ gb_widget_output_translatable_text (data, label_p, label_text);
+
+ gb_widget_output_bool (data, use_underline_p,
+ gtk_label_get_use_underline (GTK_LABEL (widget)));
+ gb_widget_output_bool (data, use_markup_p,
+ GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), use_markup_p)));
+
+ for (i = 0; i < sizeof (GbJustifyValues) / sizeof (GbJustifyValues[0]); i++)
+ {
+ if (GbJustifyValues[i] == GTK_LABEL (widget)->jtype)
+ gb_widget_output_choice (data, justify_p, i, GbJustifySymbols[i]);
+ }
+ gb_widget_output_bool (data, wrap_p, GTK_LABEL (widget)->wrap);
+ gb_widget_output_bool (data, selectable_p,
+ gtk_label_get_selectable (GTK_LABEL (widget)));
+ gb_widget_output_float (data, xalign_p, GTK_MISC (widget)->xalign);
+ gb_widget_output_float (data, yalign_p, GTK_MISC (widget)->yalign);
+ gb_widget_output_int (data, xpad_p, GTK_MISC (widget)->xpad);
+ gb_widget_output_int (data, ypad_p, GTK_MISC (widget)->ypad);
+
+ /* Labels not in buttons may have a focus target widget. */
+ if (!gb_label_find_mnemonic_widget (widget))
+ {
+ gchar *accel_target;
+
+ accel_target = gtk_object_get_data (GTK_OBJECT (widget), focus_target_p);
+
+ /* If we're showing we need to display the list of possible focus target
+ widgets. We walk the tree of widgets in this component, and if a
+ widget has CAN_FOCUS set, we add it to the list. */
+ if (data->action == GB_SHOWING)
+ {
+ GList *focus_targets = NULL, *standard_items = NULL;
+ GtkWidget *item, *combo;
+
+ property_set_visible (focus_target_p, TRUE);
+
+ gb_label_get_focus_targets (gtk_widget_get_toplevel (widget),
+ &focus_targets);
+ property_set_combo_strings (focus_target_p, focus_targets);
+ g_list_free (focus_targets);
+
+ combo = property_get_value_widget (focus_target_p);
+
+ item = gtk_list_item_new_with_label (_("Auto"));
+ gtk_widget_show (item);
+ standard_items = g_list_append (standard_items, item);
+
+ item = gtk_list_item_new ();
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_widget_show (item);
+ standard_items = g_list_append (standard_items, item);
+ gtk_combo_set_item_string (GTK_COMBO (combo), GTK_ITEM (item), "");
+
+ gtk_list_prepend_items (GTK_LIST (GTK_COMBO (combo)->list),
+ standard_items);
+
+ if (!accel_target)
+ {
+ accel_target = _("Auto");
+ }
+ gb_widget_output_combo (data, focus_target_p, accel_target);
+ }
+ else
+ {
+ /* When saving, we only save the property if it has been set. */
+ if (accel_target)
+ {
+ /* First check that the widget is still there, and if it isn't
+ just skip it. */
+ if (glade_util_find_widget (gtk_widget_get_toplevel (widget),
+ accel_target))
+ {
+ gb_widget_output_combo (data, focus_target_p, accel_target);
+ }
+ }
+ else
+ {
+ /* If no target has been set, and the label has an underlined
+ key, we try to find a default target and save that. */
+ if (gtk_label_get_use_underline (GTK_LABEL (widget)))
+ {
+ GtkWidget *accel_target;
+
+ accel_target = glade_util_find_default_accelerator_target (widget);
+ if (accel_target)
+ {
+ gb_widget_output_string (data, focus_target_p, gtk_widget_get_name (accel_target));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (data->action == GB_SHOWING)
+ {
+ property_set_visible (focus_target_p, FALSE);
+ }
+ }
+
+ ellipsize_mode = gtk_label_get_ellipsize (GTK_LABEL (widget));
+ for (i = 0; i < sizeof (GbEllipsizeValues) / sizeof (GbEllipsizeValues[0]); i++)
+ {
+ if (GbEllipsizeValues[i] == ellipsize_mode)
+ gb_widget_output_choice (data, ellipsize_p, i, GbEllipsizeSymbols[i]);
+ }
+
+ width_chars = gtk_label_get_width_chars (GTK_LABEL (widget));
+ gb_widget_output_int (data, width_chars_p, width_chars);
+
+ single_line_mode = gtk_label_get_single_line_mode (GTK_LABEL (widget));
+ gb_widget_output_bool (data, single_line_mode_p, single_line_mode);
+
+ angle = gtk_label_get_angle (GTK_LABEL (widget));
+ gb_widget_output_float (data, angle_p, angle);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_label_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_label_get_standard_properties (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+static void
+gb_label_get_focus_targets (GtkWidget * widget,
+ GList ** focus_targets)
+{
+ /* GtkWidget now has a "mnemonic_activate" signal, which some widgets use
+ to set focus to themselves or a child. So it is difficult to know if
+ a widget can be a focus target. We can't just use CAN_FOCUS as before.
+ For now I've just added some specific widgets. */
+ if (GB_IS_GB_WIDGET (widget)
+ && (GTK_WIDGET_CAN_FOCUS (widget)
+ || GTK_IS_COMBO_BOX (widget) || GTK_IS_FILE_CHOOSER_BUTTON (widget)
+ || GLADE_IS_CUSTOM_WIDGET (widget)))
+ {
+ *focus_targets = g_list_insert_sorted (*focus_targets,
+ (gchar*) gtk_widget_get_name (widget),
+ (GCompareFunc) g_utf8_collate);
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ {
+ gtk_container_forall (GTK_CONTAINER (widget),
+ (GtkCallback) gb_label_get_focus_targets,
+ focus_targets);
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+void
+gb_label_set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p)
+{
+ gchar *label, *justify, *accel_target, *ellipsize_mode;
+ const gchar *label_text;
+ gfloat xalign, yalign, angle;
+ gint xpad, ypad, i, width_chars;
+ gboolean wrap, selectable, set_alignment = FALSE, set_padding = FALSE;
+ gboolean use_underline, use_markup, single_line_mode;
+ gboolean set_label = FALSE;
+
+ use_underline = gb_widget_input_bool (data, use_underline_p);
+ if (data->apply)
+ gtk_label_set_use_underline (GTK_LABEL (widget), use_underline);
+
+ use_markup = gb_widget_input_bool (data, use_markup_p);
+ if (data->apply)
+ {
+ set_label = TRUE;
+ gtk_object_set_data (GTK_OBJECT (widget), use_markup_p,
+ GINT_TO_POINTER (use_markup));
+ }
+
+ label = gb_widget_input_text (data, label_p);
+ if (data->apply)
+ {
+ set_label = TRUE;
+ label_text = label;
+ }
+ else
+ {
+ label_text = gtk_label_get_label (GTK_LABEL (widget));
+ }
+
+ if (set_label)
+ {
+ gboolean prev_use_markup;
+
+ use_markup = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ use_markup_p));
+
+ /* We try to parse the markup here, and if it isn't valid, we will
+ turn use_markup off and show it as plain text. */
+ if (use_markup)
+ {
+ GError *error = NULL;
+ gunichar accel_marker = 0;
+ PangoAttrList *attrs = NULL;
+ gunichar accel_char = 0;
+ gchar *text = NULL;
+
+ if (gtk_label_get_use_underline (GTK_LABEL (widget)))
+ accel_marker = '_';
+
+ /* We check it is valid markup. If it isn't we will set "use_markup"
+ to FALSE. Note that we don't need attrs, text, or accel_char but
+ it seems to crash otherwise. */
+ if (!pango_parse_markup (label_text, -1, accel_marker, &attrs, &text,
+ &accel_char, &error))
+ {
+ use_markup = FALSE;
+ g_error_free (error);
+ }
+ else
+ {
+ if (attrs)
+ pango_attr_list_unref (attrs);
+ g_free (text);
+ }
+ }
+
+ /* If we are turning use_markup off, we want to do that before setting
+ the text. If we are turning it on, we want to do it after. */
+ prev_use_markup = gtk_label_get_use_markup (GTK_LABEL (widget));
+ if (!use_markup && prev_use_markup)
+ gtk_label_set_use_markup (GTK_LABEL (widget), use_markup);
+
+ gtk_label_set_label (GTK_LABEL (widget), label_text);
+
+ if (use_markup && !prev_use_markup)
+ gtk_label_set_use_markup (GTK_LABEL (widget), use_markup);
+ }
+
+ if (data->action == GB_APPLYING)
+ g_free (label);
+
+ justify = gb_widget_input_choice (data, justify_p);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbJustifyValues) / sizeof (GbJustifyValues[0]);
+ i++)
+ {
+ if (!strcmp (justify, GbJustifyChoices[i])
+ || !strcmp (justify, GbJustifySymbols[i]))
+ {
+ gtk_label_set_justify (GTK_LABEL (widget), GbJustifyValues[i]);
+ break;
+ }
+ }
+ }
+
+ wrap = gb_widget_input_bool (data, wrap_p);
+ if (data->apply)
+ gtk_label_set_line_wrap (GTK_LABEL (widget), wrap);
+
+ selectable = gb_widget_input_bool (data, selectable_p);
+ if (data->apply)
+ gtk_label_set_selectable (GTK_LABEL (widget), selectable);
+
+ xalign = gb_widget_input_float (data, xalign_p);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ xalign = GTK_MISC (widget)->xalign;
+
+ yalign = gb_widget_input_float (data, yalign_p);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ yalign = GTK_MISC (widget)->yalign;
+
+ if (set_alignment)
+ gtk_misc_set_alignment (GTK_MISC (widget), xalign, yalign);
+
+ xpad = gb_widget_input_int (data, xpad_p);
+ if (data->apply)
+ set_padding = TRUE;
+ else
+ xpad = GTK_MISC (widget)->xpad;
+
+ ypad = gb_widget_input_int (data, ypad_p);
+ if (data->apply)
+ set_padding = TRUE;
+ else
+ ypad = GTK_MISC (widget)->ypad;
+
+ if (set_padding)
+ gtk_misc_set_padding (GTK_MISC (widget), xpad, ypad);
+
+ /* Labels not in buttons may have a focus target widget. */
+ accel_target = gb_widget_input_combo (data, focus_target_p);
+ if (data->apply)
+ {
+ if (!gb_label_find_mnemonic_widget (widget))
+ {
+ if (!strcmp (accel_target, _("Auto")))
+ accel_target = NULL;
+
+ gtk_object_set_data_full (GTK_OBJECT (widget), focus_target_p,
+ g_strdup (accel_target),
+ accel_target ? g_free : NULL);
+ }
+ }
+
+ ellipsize_mode = gb_widget_input_choice (data, ellipsize_p);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbEllipsizeValues) / sizeof (GbEllipsizeValues[0]);
+ i++)
+ {
+ if (!strcmp (ellipsize_mode, GbEllipsizeChoices[i])
+ || !strcmp (ellipsize_mode, GbEllipsizeSymbols[i]))
+ {
+ gtk_label_set_ellipsize (GTK_LABEL (widget),
+ GbEllipsizeValues[i]);
+ break;
+ }
+ }
+ }
+
+ width_chars = gb_widget_input_int (data, width_chars_p);
+ if (data->apply)
+ gtk_label_set_width_chars (GTK_LABEL (widget), width_chars);
+
+ single_line_mode = gb_widget_input_bool (data, single_line_mode_p);
+ if (data->apply)
+ gtk_label_set_single_line_mode (GTK_LABEL (widget), single_line_mode);
+
+ angle = gb_widget_input_float (data, angle_p);
+ if (data->apply)
+ gtk_label_set_angle (GTK_LABEL (widget), angle);
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_label_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_label_set_standard_properties (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkLabel, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_label_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+void
+gb_label_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data,
+ const char *label_p,
+ const char *use_underline_p,
+ const char *use_markup_p,
+ const char *justify_p,
+ const char *wrap_p,
+ const char *selectable_p,
+ const char *xalign_p,
+ const char *yalign_p,
+ const char *xpad_p,
+ const char *ypad_p,
+ const char *focus_target_p,
+ const char *ellipsize_p,
+ const char *width_chars_p,
+ const char *single_line_mode_p,
+ const char *angle_p)
+{
+ GtkWidget *accel_target = NULL;
+ PangoEllipsizeMode ellipsize_mode;
+ gint i, width_chars;
+ gboolean single_line_mode;
+ gfloat angle;
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), use_markup_p))
+ source_add (data, " gtk_label_set_use_markup (GTK_LABEL (%s), TRUE);\n",
+ data->wname);
+
+ /* If there is an underlined accelerator, set up the accel signal.
+ If the label is in a button or something similar, this is now setup
+ automatically by GTK+. If the accelerator is being used to set focus
+ to something like a GtkEntry, we need to set the mnemonic_widget. */
+ if (gtk_label_get_use_underline (GTK_LABEL (widget))
+ && !gb_label_find_mnemonic_widget (widget))
+ {
+ gchar *target_name = gtk_object_get_data (GTK_OBJECT (widget),
+ focus_target_p);
+ if (target_name)
+ accel_target = glade_util_find_widget (gtk_widget_get_toplevel (widget), target_name);
+
+ if (!accel_target)
+ accel_target = glade_util_find_default_accelerator_target (widget);
+
+ if (accel_target)
+ {
+ target_name = (gchar*) gtk_widget_get_name (accel_target);
+ target_name = source_create_valid_identifier (target_name);
+ source_add_to_buffer (data, GLADE_ACCELERATORS,
+ " gtk_label_set_mnemonic_widget (GTK_LABEL (%s), %s);\n",
+ data->wname, target_name);
+ g_free (target_name);
+ }
+ }
+
+ if (GTK_LABEL (widget)->jtype != GTK_JUSTIFY_LEFT)
+ {
+ for (i = 0; i < sizeof (GbJustifyValues) / sizeof (GbJustifyValues[0]);
+ i++)
+ {
+ if (GbJustifyValues[i] == GTK_LABEL (widget)->jtype)
+ source_add (data,
+ " gtk_label_set_justify (GTK_LABEL (%s), %s);\n",
+ data->wname, GbJustifySymbols[i]);
+ }
+ }
+
+ if (GTK_LABEL (widget)->wrap)
+ source_add (data, " gtk_label_set_line_wrap (GTK_LABEL (%s), TRUE);\n",
+ data->wname);
+
+ if (gtk_label_get_selectable (GTK_LABEL (widget)))
+ source_add (data, " gtk_label_set_selectable (GTK_LABEL (%s), TRUE);\n",
+ data->wname);
+
+
+ if (fabs (GTK_MISC (widget)->xalign - 0.5) > 0.0001
+ || fabs (GTK_MISC (widget)->yalign - 0.5) > 0.0001)
+ source_add (data, " gtk_misc_set_alignment (GTK_MISC (%s), %g, %g);\n",
+ data->wname, GTK_MISC (widget)->xalign, GTK_MISC (widget)->yalign);
+
+ if (GTK_MISC (widget)->xpad != 0 || GTK_MISC (widget)->ypad != 0)
+ source_add (data, " gtk_misc_set_padding (GTK_MISC (%s), %i, %i);\n",
+ data->wname, GTK_MISC (widget)->xpad, GTK_MISC (widget)->ypad);
+
+ ellipsize_mode = gtk_label_get_ellipsize (GTK_LABEL (widget));
+ if (ellipsize_mode != PANGO_ELLIPSIZE_NONE)
+ {
+ for (i = 0;
+ i < sizeof (GbEllipsizeValues) / sizeof (GbEllipsizeValues[0]);
+ i++)
+ {
+ if (GbEllipsizeValues[i] == ellipsize_mode)
+ source_add (data,
+ " gtk_label_set_ellipsize (GTK_LABEL (%s), %s);\n",
+ data->wname, GbEllipsizeSymbols[i]);
+ }
+ }
+
+ width_chars = gtk_label_get_width_chars (GTK_LABEL (widget));
+ if (width_chars != -1)
+ {
+ source_add (data,
+ " gtk_label_set_width_chars (GTK_LABEL (%s), %i);\n",
+ data->wname, width_chars);
+ }
+
+ single_line_mode = gtk_label_get_single_line_mode (GTK_LABEL (widget));
+ if (single_line_mode)
+ {
+ source_add (data,
+ " gtk_label_set_single_line_mode (GTK_LABEL (%s), TRUE);\n",
+ data->wname);
+ }
+
+ angle = gtk_label_get_angle (GTK_LABEL (widget));
+ if (angle > GLADE_EPSILON)
+ {
+ source_add (data,
+ " gtk_label_set_angle (GTK_LABEL (%s), %g);\n",
+ data->wname, angle);
+ }
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_label_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ const gchar *label_text = gtk_label_get_label (GTK_LABEL (widget));
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ if (gtk_label_get_use_underline (GTK_LABEL (widget)))
+ source_add (data, " %s = gtk_label_new_with_mnemonic (%s);\n",
+ data->wname,
+ source_make_string_full (label_text,
+ data->use_gettext && translatable,
+ context));
+ else
+ source_add (data, " %s = gtk_label_new (%s);\n",
+ data->wname,
+ source_make_string_full (label_text,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_label_write_standard_source (widget, data,
+ Label, UseUnderline, UseMarkup,
+ Justify, Wrap, Selectable,
+ XAlign, YAlign, XPad, YPad,
+ FocusTarget, Ellipsize, WidthChars,
+ SingleLineMode, Angle);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_label_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_label_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = label_xpm;
+ gbwidget.tooltip = _("Label");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_label_new;
+ gbwidget.gb_widget_create_properties = gb_label_create_properties;
+ gbwidget.gb_widget_get_properties = gb_label_get_properties;
+ gbwidget.gb_widget_set_properties = gb_label_set_properties;
+ gbwidget.gb_widget_write_source = gb_label_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_label_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gblayout.c b/tools/glade/glade/gbwidgets/gblayout.c
new file mode 100644
index 00000000..aa2b4157
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gblayout.c
@@ -0,0 +1,399 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/layout.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *AreaWidth = "GtkLayout::width";
+static gchar *AreaHeight = "GtkLayout::height";
+
+/* Child properties. */
+const gchar *GladeLayoutChildX = "GtkLayout::x";
+const gchar *GladeLayoutChildY = "GtkLayout::y";
+
+
+
+/* The default step increment for new layouts. */
+#define GLADE_DEFAULT_STEP_INCREMENT 10
+
+/* We only use the step increment property since the other are set
+ automatically by the GtkLayout, or aren't relevant. */
+static const gchar *HValues[] = {
+ NULL, NULL, NULL, "GtkLayout::hstep", NULL, NULL,
+};
+
+static const gchar *VValues[] = {
+ NULL, NULL, NULL, "GtkLayout::vstep", NULL, NULL,
+};
+
+static void gb_layout_adjustment_changed (GtkAdjustment *adjustment,
+ GtkWidget *widget);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkLayout, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_layout_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_layout_new (NULL, NULL);
+ gtk_layout_set_size (GTK_LAYOUT (new_widget), 400, 400);
+
+ return new_widget;
+}
+
+
+static void
+gb_layout_adjustment_changed (GtkAdjustment *adjustment,
+ GtkWidget *widget)
+{
+ /* We check that this is a widget in the interface being created rather
+ than part of Glade's interface. */
+ if (GB_IS_GB_WIDGET (widget))
+ gtk_widget_queue_clear (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_layout_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_int_range (AreaWidth, _("Area Width:"),
+ _("The width of the layout area"),
+ 1, 1000, 1, 10, 1);
+ property_add_int_range (AreaHeight, _("Area Height:"),
+ _("The height of the layout area"),
+ 1, 1000, 1, 10, 1);
+
+ property_add_adjustment (HValues, GB_ADJUST_H_LABELS);
+ property_add_adjustment (VValues, GB_ADJUST_V_LABELS);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_layout_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_int (data, AreaWidth, GTK_LAYOUT (widget)->width);
+ gb_widget_output_int (data, AreaHeight, GTK_LAYOUT (widget)->height);
+
+ gb_widget_output_adjustment (data, HValues,
+ GTK_LAYOUT (widget)->hadjustment,
+ "hadjustment");
+ gb_widget_output_adjustment (data, VValues,
+ GTK_LAYOUT (widget)->vadjustment,
+ "vadjustment");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_layout_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint width, height;
+ gboolean set_size = FALSE;
+
+ width = gb_widget_input_int (data, AreaWidth);
+ if (data->apply)
+ set_size = TRUE;
+ else
+ width = GTK_LAYOUT (widget)->width;
+
+ height = gb_widget_input_int (data, AreaHeight);
+ if (data->apply)
+ set_size = TRUE;
+ else
+ height = GTK_LAYOUT (widget)->height;
+
+ if (set_size)
+ gtk_layout_set_size (GTK_LAYOUT (widget), width, height);
+
+ gb_widget_input_adjustment (data, HValues, GTK_LAYOUT (widget)->hadjustment,
+ "hadjustment");
+ gb_widget_input_adjustment (data, VValues, GTK_LAYOUT (widget)->vadjustment,
+ "vadjustment");
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkLayout, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_layout_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+void
+gb_layout_add_child (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gtk_layout_put (GTK_LAYOUT (widget), child, 0, 0);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_layout_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_layout_new (NULL, NULL);\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ source_add (data, " gtk_layout_set_size (GTK_LAYOUT (%s), %i, %i);\n",
+ data->wname,
+ GTK_LAYOUT (widget)->width,
+ GTK_LAYOUT (widget)->height);
+
+ source_add (data,
+ " GTK_ADJUSTMENT (GTK_LAYOUT (%s)->hadjustment)->step_increment = %g;\n",
+ data->wname,
+ GTK_ADJUSTMENT (GTK_LAYOUT (widget)->hadjustment)->step_increment);
+ source_add (data,
+ " GTK_ADJUSTMENT (GTK_LAYOUT (%s)->vadjustment)->step_increment = %g;\n",
+ data->wname,
+ GTK_ADJUSTMENT (GTK_LAYOUT (widget)->vadjustment)->step_increment);
+}
+
+
+/*
+ * Creates the child packing properties for children of this widget.
+ */
+void
+gb_layout_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_int_range (GladeLayoutChildX, _("X:"),
+ _("The X coordinate of the widget in the GtkLayout"),
+ 0, 10000, 1, 10, 1);
+ property_add_int_range (GladeLayoutChildY, _("Y:"),
+ _("The Y coordinate of the widget in the GtkLayout"),
+ 0, 10000, 1, 10, 1);
+}
+
+
+/* Shows or saves the child properties of a child of a layout. */
+void
+gb_layout_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ gint x, y;
+
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ gtk_container_child_get (GTK_CONTAINER (widget), child,
+ "x", &x,
+ "y", &y,
+ NULL);
+
+ gb_widget_output_int (data, GladeLayoutChildX, x);
+ gb_widget_output_int (data, GladeLayoutChildY, y);
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+/* Applies or loads the child properties of a child of a layout. */
+void
+gb_layout_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gint x, y;
+
+ x = gb_widget_input_int (data, GladeLayoutChildX);
+ if (data->apply)
+ gtk_container_child_set (GTK_CONTAINER (widget), child,
+ "x", x,
+ NULL);
+
+ y = gb_widget_input_int (data, GladeLayoutChildY);
+ if (data->apply)
+ gtk_container_child_set (GTK_CONTAINER (widget), child,
+ "y", y,
+ NULL);
+}
+
+
+/* Outputs source to add a child widget to a layout. */
+static void
+gb_layout_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gint x, y;
+
+ gtk_container_child_get (GTK_CONTAINER (parent), child,
+ "x", &x,
+ "y", &y,
+ NULL);
+ source_add (data,
+ " gtk_layout_put (GTK_LAYOUT (%s), %s, %i, %i);\n",
+ parent_name, data->wname, x, y);
+}
+
+
+static gboolean
+gb_layout_emission_hook (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GtkObject *object, *hadjustment, *vadjustment;
+ GtkObject *old_hadjustment, *old_vadjustment;
+
+ object = g_value_get_object (param_values);
+ g_return_val_if_fail (GTK_IS_LAYOUT (object), FALSE);
+
+ hadjustment = g_value_get_object (param_values + 1);
+ vadjustment = g_value_get_object (param_values + 2);
+
+ old_hadjustment = gtk_object_get_data (object, "scrollhadjustment");
+ if (hadjustment != old_hadjustment)
+ {
+ gtk_object_set_data (object, "scrollhadjustment", hadjustment);
+
+ if (hadjustment)
+ {
+ gtk_signal_connect (hadjustment, "value_changed",
+ (GtkSignalFunc) gb_layout_adjustment_changed,
+ object);
+
+ GTK_ADJUSTMENT (hadjustment)->step_increment = GLADE_DEFAULT_STEP_INCREMENT;
+ if (property_get_widget () == GTK_WIDGET (object))
+ {
+ property_set_auto_apply (FALSE);
+ property_set_float (HValues[3], GLADE_DEFAULT_STEP_INCREMENT);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ }
+
+ old_vadjustment = gtk_object_get_data (object, "scrollvadjustment");
+ if (vadjustment != old_vadjustment)
+ {
+ gtk_object_set_data (object, "scrollvadjustment", vadjustment);
+
+ if (vadjustment)
+ {
+ gtk_signal_connect (vadjustment, "value_changed",
+ (GtkSignalFunc) gb_layout_adjustment_changed,
+ object);
+
+ GTK_ADJUSTMENT (vadjustment)->step_increment = GLADE_DEFAULT_STEP_INCREMENT;
+ if (property_get_widget () == GTK_WIDGET (object))
+ {
+ property_set_auto_apply (FALSE);
+ property_set_float (VValues[3], GLADE_DEFAULT_STEP_INCREMENT);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_layout_init ()
+{
+ GtkWidgetClass *klass;
+
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_layout_get_type();
+
+ /* Add a signal emission hook so we can connect signal handlers to the
+ scrollbar adjustments to redraw the layout when necessary. This will also
+ work for subclasses of GtkLayout. */
+ klass = gtk_type_class (gtk_layout_get_type ());
+ g_signal_add_emission_hook (klass->set_scroll_adjustments_signal, 0,
+ gb_layout_emission_hook, NULL, NULL);
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = layout_xpm;
+ gbwidget.tooltip = _("Layout");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_layout_new;
+ gbwidget.gb_widget_create_properties = gb_layout_create_properties;
+ gbwidget.gb_widget_get_properties = gb_layout_get_properties;
+ gbwidget.gb_widget_set_properties = gb_layout_set_properties;
+ gbwidget.gb_widget_write_source = gb_layout_write_source;
+ gbwidget.gb_widget_create_child_properties = gb_layout_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_layout_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_layout_set_child_properties;
+ gbwidget.gb_widget_write_add_child_source = gb_layout_write_add_child_source;
+ gbwidget.gb_widget_add_child = gb_layout_add_child;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_layout_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gblist.c b/tools/glade/glade/gbwidgets/gblist.c
new file mode 100644
index 00000000..e333cd4c
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gblist.c
@@ -0,0 +1,205 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtklist.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/list.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Mode = "GtkList::selection_mode";
+
+static const gchar *GbModeChoices[] =
+{"Single", "Browse", "Multiple", NULL};
+static const gint GbModeValues[] =
+{
+ GTK_SELECTION_SINGLE,
+ GTK_SELECTION_BROWSE,
+ GTK_SELECTION_MULTIPLE
+};
+static const gchar *GbModeSymbols[] =
+{
+ "GTK_SELECTION_SINGLE",
+ "GTK_SELECTION_BROWSE",
+ "GTK_SELECTION_MULTIPLE"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkList, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_list_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_list_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Mode, _("Select Mode:"),
+ _("The selection mode of the list"),
+ GbModeChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_list_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == GTK_LIST (widget)->selection_mode)
+ gb_widget_output_choice (data, Mode, i, GbModeSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_list_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *mode;
+ gint i;
+
+ mode = gb_widget_input_choice (data, Mode);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (!strcmp (mode, GbModeChoices[i])
+ || !strcmp (mode, GbModeSymbols[i]))
+ {
+ gtk_list_set_selection_mode (GTK_LIST (widget), GbModeValues[i]);
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkList, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_list_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_list_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_list_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_LIST (widget)->selection_mode != GTK_SELECTION_SINGLE)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == GTK_LIST (widget)->selection_mode)
+ source_add (data,
+ " gtk_list_set_selection_mode (GTK_LIST (%s), %s);\n",
+ data->wname, GbModeSymbols[i]);
+ }
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_list_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_list_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = list_xpm;
+ gbwidget.tooltip = _("List");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_list_create_properties;
+ gbwidget.gb_widget_get_properties = gb_list_get_properties;
+ gbwidget.gb_widget_set_properties = gb_list_set_properties;
+ gbwidget.gb_widget_write_source = gb_list_write_source;
+/*
+ gbwidget.gb_widget_new = gb_list_new;
+ gbwidget.gb_widget_create_popup_menu = gb_list_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gblistitem.c b/tools/glade/glade/gbwidgets/gblistitem.c
new file mode 100644
index 00000000..70a0cd9f
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gblistitem.c
@@ -0,0 +1,182 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtklistitem.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/listitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "GtkListItem::label";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkListItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_list_item_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_list_item_new_with_label (data->name);
+ else
+ {
+ new_widget = gtk_list_item_new ();
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder());
+ }
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_list_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_list_item_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_child_label (widget, data, Label);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_list_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_widget_input_child_label (widget, data, Label);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkListItem, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_list_item_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data)
+{
+ /* Add command to remove child label. */
+ gb_widget_create_child_label_popup_menu (widget, data);
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_list_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkWidget *child = GTK_BIN (widget)->child;
+ const gchar *label_text;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ if (child && GTK_IS_LABEL (child) && !GB_IS_GB_WIDGET (child))
+ {
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ label_text = gtk_label_get_text (GTK_LABEL (child));
+ source_add (data, " %s = gtk_list_item_new_with_label (%s);\n",
+ data->wname,
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ }
+ else
+ {
+ source_add (data, " %s = gtk_list_item_new ();\n", data->wname);
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_list_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_list_item_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = listitem_xpm;
+ gbwidget.tooltip = _("List Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_list_item_new;
+ gbwidget.gb_widget_create_properties = gb_list_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_list_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_list_item_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_list_item_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_list_item_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbmenu.c b/tools/glade/glade/gbwidgets/gbmenu.c
new file mode 100644
index 00000000..4655228e
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbmenu.c
@@ -0,0 +1,211 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkmenu.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/popupmenu.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkMenu, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_menu_new(GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_menu_new ();
+
+ /* We create an accelerator table/group so that we can install accels
+ easily. */
+ gtk_menu_set_accel_group (GTK_MENU (new_widget), gtk_accel_group_new ());
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+ static void
+ gb_menu_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+ static void
+ gb_menu_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+ static void
+ gb_menu_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkMenu, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_menu_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_menu_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+#ifdef USE_GNOME
+ /* For Gnome projects the menus are created using GnomeUIInfo structs, so
+ we just create the start of the struct here, and output code to fill
+ the menu from the GnomeUIInfo structs. */
+ if (data->project->gnome_support)
+ {
+ GtkWidget *attach_widget;
+
+ glade_gnome_start_menu_source (GTK_MENU_SHELL (widget), data);
+
+ /* We only need to create the toplevel menu. */
+ attach_widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ if (attach_widget == NULL || GTK_IS_OPTION_MENU (attach_widget))
+ {
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_menu_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ data->need_accel_group = TRUE;
+ source_add (data,
+ " gnome_app_fill_menu (GTK_MENU_SHELL (%s), %s_uiinfo,\n"
+ " accel_group, FALSE, 0);\n",
+ data->wname, data->real_wname);
+ }
+
+ return;
+ }
+#endif
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_menu_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+#if 0
+ gchar *accel_group_decl;
+
+ /* I don't think we need this for GTK+ 2.0. */
+ accel_group_decl = g_strdup_printf (" GtkAccelGroup *%s_accels;\n",
+ data->real_wname);
+ source_ensure_decl (data, accel_group_decl);
+ source_add (data,
+ " %s_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (%s));\n",
+ data->wname, data->wname);
+ g_free (accel_group_decl);
+#endif
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_menu_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_menu_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = popupmenu_xpm;
+ gbwidget.tooltip = _("Popup Menu");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_menu_new;
+ gbwidget.gb_widget_write_source = gb_menu_write_source;
+/*
+ gbwidget.gb_widget_create_properties = gb_menu_create_properties;
+ gbwidget.gb_widget_get_properties = gb_menu_get_properties;
+ gbwidget.gb_widget_set_properties = gb_menu_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_menu_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbmenubar.c b/tools/glade/glade/gbwidgets/gbmenubar.c
new file mode 100644
index 00000000..c756094d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbmenubar.c
@@ -0,0 +1,552 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkbutton.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenubar.h>
+#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtkstock.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+#include "../glade_menu_editor.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/menubar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *PackDirection = "GtkMenuBar::pack_direction";
+static gchar *ChildPackDirection = "GtkMenuBar::child_pack_direction";
+
+
+static const gchar *GbPackDirectionChoices[] =
+{
+ "Left to Right",
+ "Right to Left",
+ "Top to Bottom",
+ "Bottom to Top",
+ NULL
+};
+static const gint GbPackDirectionValues[] =
+{
+ GTK_PACK_DIRECTION_LTR,
+ GTK_PACK_DIRECTION_RTL,
+ GTK_PACK_DIRECTION_TTB,
+ GTK_PACK_DIRECTION_BTT
+};
+static const gchar *GbPackDirectionSymbols[] =
+{
+ "GTK_PACK_DIRECTION_LTR",
+ "GTK_PACK_DIRECTION_RTL",
+ "GTK_PACK_DIRECTION_TTB",
+ "GTK_PACK_DIRECTION_BTT"
+};
+
+static void on_menu_bar_size_request (GtkWidget * widget,
+ GtkRequisition *requisition,
+ gpointer data);
+static void gb_menu_bar_on_edit_menu (GtkWidget *button,
+ gpointer data);
+static void gb_menu_bar_on_edit_menu_activate (GtkWidget *menuitem,
+ GtkWidget *menubar);
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+
+static GtkWidget*
+gb_menu_bar_add_menu (GtkWidget *menu, const gchar *label)
+{
+ GtkWidget *menuitem, *child_menu;
+
+ menuitem = gb_widget_new ("GtkMenuItem", NULL);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child),
+ label);
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ child_menu = gb_widget_new ("GtkMenu", NULL);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), child_menu);
+
+ return child_menu;
+}
+
+
+/* This returns the name to use given the widget's label. Spaces are converted
+ to underscores, and '.' and '_' chars are ignore, e.g. '_Open...' -> 'Open'.
+ The returned string should be freed. */
+static char*
+gb_menu_bar_generate_item_name (const gchar *label)
+{
+ char *name, *dest;
+ const char *src;
+
+ /* We never add characters, so name is never longer than label. I think this
+ is OK for UTF-8. */
+ name = g_malloc (strlen (label) + 1);
+ for (src = label, dest = name; *src; src++)
+ {
+ if (*src == ' ')
+ *dest++ = '_';
+ else if (*src == '.')
+ continue;
+ else if (*src == '_')
+ continue;
+ else
+ *dest++ = *src;
+ }
+ *dest = '\0';
+
+ return name;
+}
+
+
+/* This adds an "activate" signal handler to the menuitem. */
+static void
+gb_menu_bar_add_item_handler (GtkWidget *menuitem)
+{
+ GladeWidgetData *wdata;
+ GladeSignal *signal;
+ const char *name;
+
+ wdata = (GladeWidgetData*) gtk_object_get_data (GTK_OBJECT(menuitem),
+ GB_WIDGET_DATA_KEY);
+ if (wdata == NULL)
+ {
+ g_warning ("Widget has no GladeWidgetData attached");
+ return;
+ }
+
+
+ name = gtk_widget_get_name (menuitem);
+
+ signal = g_new (GladeSignal, 1);
+ signal->name = g_strdup ("activate");
+ signal->handler = g_strdup_printf ("on_%s_activate", name);
+ signal->object = NULL;
+ signal->after = FALSE;
+ signal->data = NULL;
+ signal->last_modification_time = time (NULL);
+ wdata->signals = g_list_append (wdata->signals, signal);
+}
+
+static void
+gb_menu_bar_add_stock_item (GtkWidget *menu, const gchar *stock_id)
+{
+ GtkWidget *menuitem;
+ char *label_text, *name;
+
+ menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
+ label_text = glade_util_get_label_text (GTK_BIN (menuitem)->child);
+ name = gb_menu_bar_generate_item_name (label_text);
+ gb_widget_create_from (menuitem, name);
+ g_free (name);
+ g_free (label_text);
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ /* For stock items we also have to store the stock_id. */
+ gtk_object_set_data_full (GTK_OBJECT (menuitem), GladeMenuItemStockIDKey,
+ g_strdup (stock_id), g_free);
+
+ gb_menu_bar_add_item_handler (menuitem);
+}
+
+
+static void
+gb_menu_bar_add_item (GtkWidget *menu, const gchar *label)
+{
+ GtkWidget *menuitem;
+ char *name;
+
+ menuitem = gtk_menu_item_new_with_mnemonic (label);
+ name = gb_menu_bar_generate_item_name (label);
+ gb_widget_create_from (menuitem, name);
+ g_free (name);
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ gb_menu_bar_add_item_handler (menuitem);
+}
+
+
+static void
+gb_menu_bar_add_separator (GtkWidget *menu)
+{
+ GtkWidget *menuitem;
+
+ menuitem = gb_widget_new ("GtkSeparatorMenuItem", NULL);
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+}
+
+
+static void
+gb_menu_bar_setup_initial_menus (GtkWidget *widget)
+{
+ GtkWidget *menu;
+
+ /* FIXME: I'm not sure if we should translate the non-stock labels or not. */
+ menu = gb_menu_bar_add_menu (widget, _("_File"));
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_NEW);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_OPEN);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_SAVE);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_SAVE_AS);
+ gb_menu_bar_add_separator (menu);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_QUIT);
+
+ menu = gb_menu_bar_add_menu (widget, _("_Edit"));
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_CUT);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_COPY);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_PASTE);
+ gb_menu_bar_add_stock_item (menu, GTK_STOCK_DELETE);
+
+ menu = gb_menu_bar_add_menu (widget, _("_View"));
+
+ menu = gb_menu_bar_add_menu (widget, _("_Help"));
+ gb_menu_bar_add_item (menu, _("_About"));
+}
+
+
+/*
+ * Creates a new GtkWidget of class GtkMenuBar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_menu_bar_new(GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_menu_bar_new ();
+
+ gtk_signal_connect_after (GTK_OBJECT (new_widget), "size_request",
+ GTK_SIGNAL_FUNC (on_menu_bar_size_request),
+ NULL);
+
+ if (data->action == GB_CREATING)
+ {
+#ifdef USE_GNOME
+ if (glade_project_get_gnome_support (data->project))
+ glade_gnome_setup_initial_menus (new_widget);
+ else
+ gb_menu_bar_setup_initial_menus (new_widget);
+#else
+ gb_menu_bar_setup_initial_menus (new_widget);
+#endif
+ }
+
+ return new_widget;
+}
+
+
+static void
+on_menu_bar_size_request (GtkWidget * widget,
+ GtkRequisition *requisition,
+ gpointer data)
+{
+ /* Make sure we request a decent size. If we don't do this, when a menubar
+ is created it appears about 3 pixels high which is not very good. */
+ requisition->width = MAX (requisition->width, 32);
+ requisition->height = MAX (requisition->height, 24);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_menu_bar_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+{
+ GtkWidget *property_table, *button;
+ gint property_table_row;
+
+ property_add_choice (PackDirection, _("Pack Direction:"),
+ _("The pack direction of the menubar"),
+ GbPackDirectionChoices);
+ property_add_choice (ChildPackDirection, _("Child Direction:"),
+ _("The child pack direction of the menubar"),
+ GbPackDirectionChoices);
+
+ /* Add a button for editing the menubar. */
+ property_table = property_get_table_position (&property_table_row);
+ button = gtk_button_new_with_label (_("Edit Menus..."));
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (gb_menu_bar_on_edit_menu), NULL);
+ gtk_table_attach (GTK_TABLE (property_table), button, 0, 3,
+ property_table_row, property_table_row + 1,
+ GTK_FILL, GTK_FILL, 10, 10);
+}
+
+
+/* Make window behave like a dialog */
+static void
+dialogize (GtkWidget *menued, GtkWidget *parent_widget)
+{
+ GtkWidget *transient_parent;
+
+ gtk_signal_connect (GTK_OBJECT (menued), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscDestroys));
+ transient_parent = glade_util_get_toplevel (parent_widget);
+ if (GTK_IS_WINDOW (transient_parent))
+ {
+ gtk_window_set_transient_for (GTK_WINDOW (menued),
+ GTK_WINDOW (transient_parent));
+ }
+}
+
+static void
+gb_menu_bar_on_edit_menu (GtkWidget *button,
+ gpointer data)
+{
+ GtkWidget *menubar, *menued;
+
+ menubar = property_get_widget ();
+ g_return_if_fail (GTK_IS_MENU_BAR (menubar));
+
+ menued = glade_menu_editor_new (current_project, GTK_MENU_SHELL (menubar));
+ dialogize (menued, button);
+ gtk_widget_show (GTK_WIDGET (menued));
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_menu_bar_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+{
+ GtkPackDirection pack_direction, child_pack_direction;
+ gint i;
+
+ pack_direction = gtk_menu_bar_get_pack_direction (GTK_MENU_BAR (widget));
+ child_pack_direction = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (widget));
+
+ for (i = 0; i < sizeof (GbPackDirectionValues) / sizeof (GbPackDirectionValues[0]); i++)
+ {
+ if (GbPackDirectionValues[i] == pack_direction)
+ gb_widget_output_choice (data, PackDirection, i, GbPackDirectionSymbols[i]);
+
+ if (GbPackDirectionValues[i] == child_pack_direction)
+ gb_widget_output_choice (data, ChildPackDirection, i, GbPackDirectionSymbols[i]);
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_menu_bar_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+{
+ gchar *pack_direction, *child_pack_direction;
+ gint i;
+
+ pack_direction = gb_widget_input_choice (data, PackDirection);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPackDirectionValues) / sizeof (GbPackDirectionValues[0]); i++)
+ {
+ if (!strcmp (pack_direction, GbPackDirectionChoices[i])
+ || !strcmp (pack_direction, GbPackDirectionSymbols[i]))
+ {
+ gtk_menu_bar_set_pack_direction (GTK_MENU_BAR (widget),
+ GbPackDirectionValues[i]);
+ break;
+ }
+ }
+ }
+
+ child_pack_direction = gb_widget_input_choice (data, ChildPackDirection);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPackDirectionValues) / sizeof (GbPackDirectionValues[0]); i++)
+ {
+ if (!strcmp (child_pack_direction, GbPackDirectionChoices[i])
+ || !strcmp (child_pack_direction, GbPackDirectionSymbols[i]))
+ {
+ gtk_menu_bar_set_child_pack_direction (GTK_MENU_BAR (widget),
+ GbPackDirectionValues[i]);
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkMenuBar, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_menu_bar_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+{
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_label (_("Edit Menus..."));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_menu_bar_on_edit_menu_activate),
+ widget);
+}
+
+
+static void
+gb_menu_bar_on_edit_menu_activate (GtkWidget *menuitem,
+ GtkWidget *menubar)
+{
+ GtkWidget *menued;
+
+ menued = glade_menu_editor_new (current_project, GTK_MENU_SHELL (menubar));
+ dialogize (menued, menubar);
+ gtk_widget_show (GTK_WIDGET (menued));
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_menu_bar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean created_menu = FALSE;
+ GtkPackDirection pack_direction, child_pack_direction;
+ gint i;
+
+ pack_direction = gtk_menu_bar_get_pack_direction (GTK_MENU_BAR (widget));
+ child_pack_direction = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (widget));
+
+#ifdef USE_GNOME
+ /* For Gnome projects the menus are created using GnomeUIInfo structs, so
+ we just create the start of the struct here. In a GnomeApp dock item,
+ the code to add the menu to the GnomeApp is in output in gnomedockitem.c.
+ If the menubar is not in a GnomeApp, we have to output the code to create
+ it here. */
+ if (data->project->gnome_support)
+ {
+ glade_gnome_start_menu_source (GTK_MENU_SHELL (widget), data);
+
+ if (widget->parent && glade_gnome_is_app_dock_item (widget->parent))
+ {
+ /* FIXME: should we set some standard properties? */
+ gb_widget_write_add_child_source (widget, data);
+ return;
+ }
+ else
+ {
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_menu_bar_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ data->need_accel_group = TRUE;
+ source_add (data,
+ " gnome_app_fill_menu (GTK_MENU_SHELL (%s), %s_uiinfo,\n"
+ " accel_group, FALSE, 0);\n",
+ data->wname, data->real_wname);
+ created_menu = TRUE;
+ }
+ }
+#endif
+
+ if (!created_menu)
+ {
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_menu_bar_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+ }
+
+ if (pack_direction != GTK_PACK_DIRECTION_LTR)
+ {
+ for (i = 0; i < sizeof (GbPackDirectionValues) / sizeof (GbPackDirectionValues[0]); i++)
+ {
+ if (GbPackDirectionValues[i] == pack_direction)
+ source_add (data,
+ " gtk_menu_bar_set_pack_direction (GTK_MENU_BAR (%s), %s);\n",
+ data->wname, GbPackDirectionSymbols[i]);
+ }
+ }
+
+ if (child_pack_direction != GTK_PACK_DIRECTION_LTR)
+ {
+ for (i = 0; i < sizeof (GbPackDirectionValues) / sizeof (GbPackDirectionValues[0]); i++)
+ {
+ if (GbPackDirectionValues[i] == child_pack_direction)
+ source_add (data,
+ " gtk_menu_bar_set_child_pack_direction (GTK_MENU_BAR (%s), %s);\n",
+ data->wname, GbPackDirectionSymbols[i]);
+ }
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_menu_bar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_menu_bar_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = menubar_xpm;
+ gbwidget.tooltip = _("Menu Bar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_menu_bar_new;
+ gbwidget.gb_widget_create_properties = gb_menu_bar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_menu_bar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_menu_bar_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_menu_bar_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_menu_bar_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbmenuitem.c b/tools/glade/glade/gbwidgets/gbmenuitem.c
new file mode 100644
index 00000000..eae44ac6
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbmenuitem.c
@@ -0,0 +1,393 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenubar.h>
+#include <gtk/gtkmenuitem.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+#include "../glade_keys_dialog.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/menuitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "MenuItem|GtkItem::label";
+static gchar *Icon = "GtkMenuItem::icon";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkMenuItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_menu_item_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_menu_item_new_with_label (data->name);
+ else
+ new_widget = gtk_menu_item_new ();
+ return new_widget;
+}
+
+void
+gb_menu_item_add_child (GtkWidget * widget, GtkWidget * child, GbWidgetSetArgData *data)
+{
+ if (GTK_IS_MENU (child))
+ {
+ MSG ("Trying to add a menu to a menu item");
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), child);
+ }
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_menu_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+#if 0
+ /* For now we don't support editing the menuitem properties in the property
+ editor. The menu editor has to be used instead. */
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+#endif
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_menu_item_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gboolean output_label = TRUE;
+
+ /* We only support saving the properties here. */
+ if (data->action != GB_SAVING)
+ return;
+
+ /* If we are saving, we check for a stock Gnome menu item, and if so, we
+ just save that. GTK+ stock items are all GtkImageMenuItems, so we don't
+ have to worry about those here. */
+#ifdef USE_GNOME
+ if (glade_project_get_gnome_support (data->project))
+ {
+ gint stock_item_index;
+
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), GladeMenuItemStockIndexKey));
+ /* The 'New' item is special. If it has a child menu, it must be a
+ GNOMEUIINFO_MENU_NEW_SUBTREE. If not, it is a
+ GNOMEUIINFO_MENU_NEW_ITEM, in which case the label is also output. */
+ if (stock_item_index == GladeStockMenuItemNew)
+ {
+ if (GTK_MENU_ITEM (widget)->submenu)
+ {
+ gb_widget_output_string (data, "stock_item",
+ "GNOMEUIINFO_MENU_NEW_SUBTREE");
+ output_label = FALSE;
+ }
+ else
+ {
+ gb_widget_output_string (data, "stock_item",
+ "GNOMEUIINFO_MENU_NEW_ITEM");
+ }
+ }
+ else if (stock_item_index != 0)
+ {
+ gb_widget_output_string (data, "stock_item", GladeStockMenuItemSymbols[stock_item_index]);
+ output_label = FALSE;
+ }
+ }
+#endif
+
+ if (output_label)
+ gb_widget_output_child_label (widget, data, Label);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_menu_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean input_label = TRUE, input_rest = TRUE;
+ GtkAccelGroup *accel_group;
+ guint key;
+ GdkModifierType modifiers;
+
+ /* We only support loading the properties here. */
+ if (data->action != GB_LOADING)
+ return;
+
+#ifdef USE_GNOME
+ /* Check for a stock menu item. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+ GnomeUIInfo *uiinfo;
+ gchar *stock_item;
+ GtkWidget *label;
+ gint stock_item_index;
+
+ stock_item = gb_widget_input_string (data, "stock_item");
+ if (stock_item && stock_item[0])
+ {
+ /* Special case for the NEW_SUBTREE. */
+ if (!strcmp (stock_item, "GNOMEUIINFO_MENU_NEW_SUBTREE"))
+ {
+ stock_item_index = GladeStockMenuItemNew;
+ }
+ else
+ {
+ stock_item_index = glade_util_string_array_index (GladeStockMenuItemSymbols, GladeStockMenuItemSize, stock_item);
+ }
+
+ if (stock_item_index != -1)
+ {
+ uiinfo = &GladeStockMenuItemValues[stock_item_index];
+ if (uiinfo->type == GNOME_APP_UI_ITEM_CONFIGURABLE)
+ gnome_app_ui_configure_configurable (uiinfo);
+
+ /* Note that we don't have to worry about the pixmap, since if
+ it had a pixmap it would be a GtkImageMenuItem. */
+
+ label = gtk_accel_label_new ("");
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label),
+ uiinfo->label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label),
+ widget);
+ gtk_container_add (GTK_CONTAINER (widget), label);
+
+ /* Add the configured accelerator key. */
+ if (uiinfo->accelerator_key != 0 && widget->parent
+ && GTK_IS_MENU (widget->parent))
+ {
+ accel_group = GTK_MENU (widget->parent)->accel_group;
+ gtk_widget_add_accelerator (widget, "activate", accel_group,
+ uiinfo->accelerator_key,
+ uiinfo->ac_mods,
+ GTK_ACCEL_VISIBLE);
+ }
+
+ /* Remember the index of the stock item. */
+ gtk_object_set_data (GTK_OBJECT (widget),
+ GladeMenuItemStockIndexKey,
+ GINT_TO_POINTER (stock_item_index));
+
+ /* The 'New' item can have a label. The rest can't. */
+ if (stock_item_index != GladeStockMenuItemNew)
+ input_label = FALSE;
+ input_rest = FALSE;
+ }
+ else
+ {
+#ifdef FIXME
+ load_add_error_message_with_tag (data,
+ GLADE_LINE_PROPERTY,
+ _("Invalid stock menu item"),
+ "stock_item", stock_item);
+#endif
+ }
+ }
+ }
+#endif
+
+ if (input_label)
+ gb_widget_input_child_label (widget, data, Label);
+
+ if (input_rest)
+ {
+ /* FIXME: should this be somewhere else? */
+ /* If we are loading, install the 'activate' accelerator, if it has one,
+ so that is is visible. */
+ if (data->action == GB_LOADING && widget->parent
+ && GTK_IS_MENU (widget->parent))
+ {
+ int i;
+
+ for (i = 0; i < data->widget_info->n_accels; i++)
+ {
+ if (!strcmp (data->widget_info->accels[i].signal, "activate"))
+ {
+ key = data->widget_info->accels[i].key;
+ modifiers = data->widget_info->accels[i].modifiers;
+ accel_group = GTK_MENU (widget->parent)->accel_group;
+ gtk_widget_add_accelerator (widget, "activate", accel_group,
+ key, modifiers,
+ GTK_ACCEL_VISIBLE);
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkMenuItem, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_menu_item_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data)
+{
+ /* Add command to remove child label. */
+#if 0
+ gb_widget_create_child_label_popup_menu (widget, data);
+#endif
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_menu_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkWidget *child = GTK_BIN (widget)->child;
+ gchar *label_text;
+ gboolean translatable, context;
+ gchar *comments;
+
+#ifdef USE_GNOME
+ if (data->project->gnome_support)
+ {
+ glade_gnome_write_menu_item_source (GTK_MENU_ITEM (widget), data);
+ return;
+ }
+#endif
+
+ if (child && GTK_IS_LABEL (child) && !GB_IS_GB_WIDGET (child))
+ {
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ label_text = glade_util_get_label_text (child);
+ source_add (data, " %s = gtk_menu_item_new_with_mnemonic (%s);\n",
+ data->wname,
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ g_free (label_text);
+ }
+ else
+ {
+ source_add (data, " %s = gtk_menu_item_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+/* Outputs source to add a child menu to a menu item. */
+static void
+gb_menu_item_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ if (GTK_IS_MENU (child))
+ {
+ source_add (data,
+ " gtk_menu_item_set_submenu (GTK_MENU_ITEM (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else
+ {
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+static void
+gb_menu_item_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ /* We need to remove the icon pixmap from the project.
+ Note that it may be a stock icon name, in which case it will be ignored
+ by glade_project_remove_pixmap. */
+ gchar *filename = gtk_object_get_data (GTK_OBJECT (widget), Icon);
+ if (filename)
+ {
+ glade_project_remove_pixmap (data->project, filename);
+ g_free (filename);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_menu_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_menu_item_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = menuitem_xpm;
+ gbwidget.tooltip = _("Menu Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_menu_item_new;
+ gbwidget.gb_widget_add_child = gb_menu_item_add_child;
+ gbwidget.gb_widget_create_properties = gb_menu_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_menu_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_menu_item_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_menu_item_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_menu_item_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_menu_item_write_add_child_source;
+ gbwidget.gb_widget_destroy = gb_menu_item_destroy;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbmenutoolbutton.c b/tools/glade/glade/gbwidgets/gbmenutoolbutton.c
new file mode 100644
index 00000000..c8f82ac3
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbmenutoolbutton.c
@@ -0,0 +1,269 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/menutoolbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "GtkMenuToolButton|GtkToolButton::stock_id";
+static gchar *Label = "GtkMenuToolButton|GtkToolButton::label";
+static gchar *Icon = "GtkMenuToolButton|GtkToolButton::icon";
+static gchar *VisibleHorz = "GtkMenuToolButton|GtkToolItem::visible_horizontal";
+static gchar *VisibleVert = "GtkMenuToolButton|GtkToolItem::visible_vertical";
+static gchar *IsImportant = "GtkMenuToolButton|GtkToolItem::is_important";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkMenuToolButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_menu_tool_button_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *image;
+ GbWidget *pixmap_gbwidget;
+
+ /* Place the pixmap icon in the button initially (even when loading). */
+ pixmap_gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (pixmap_gbwidget)
+ {
+ image = gtk_image_new_from_pixmap (pixmap_gbwidget->gdkpixmap,
+ pixmap_gbwidget->mask);
+ }
+ else
+ {
+ image = gtk_image_new ();
+ g_warning ("Couldn't find GtkPixmap data");
+ }
+ gtk_widget_show (image);
+
+ new_widget = (GtkWidget*) gtk_menu_tool_button_new (image, "");
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_menu_tool_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_bool (VisibleHorz, _("Show Horizontal:"),
+ _("If the item is visible when the toolbar is horizontal"));
+ property_add_bool (VisibleVert, _("Show Vertical:"),
+ _("If the item is visible when the toolbar is vertical"));
+ property_add_bool (IsImportant, _("Is Important:"),
+ _("If the item's text should be shown when the toolbar's mode is GTK_TOOLBAR_BOTH_HORIZ"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_menu_tool_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_tool_button_get_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_menu_tool_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_tool_button_set_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkMenuToolButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_menu_tool_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_menu_tool_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *stock_id, *label, *icon_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey);
+ icon_name = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ label = (gchar*) gtk_tool_button_get_label (GTK_TOOL_BUTTON (widget));
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+
+ if (data->create_widget)
+ {
+ if (stock_id)
+ {
+ /* Stock Button */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_menu_tool_button_new_from_stock (%s);\n",
+ data->wname, source_make_string (stock_id, FALSE));
+ }
+ else if (icon_name)
+ {
+ /* Icon and Label */
+ source_ensure_decl (data, " GtkWidget *tmp_image;\n");
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ source_add (data,
+ " tmp_image = gtk_image_new_from_stock (\"%s\", tmp_toolbar_icon_size);\n",
+ icon_name);
+ }
+ else
+ {
+ source_create_pixmap (data, "tmp_image", icon_name);
+ }
+
+ source_add (data, " gtk_widget_show (tmp_image);\n");
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " %s = (GtkWidget*) gtk_menu_tool_button_new (tmp_image, %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+ }
+ else
+ {
+ /* Just a Label */
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " %s = (GtkWidget*) gtk_menu_tool_button_new (NULL, %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleVert) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)))
+ {
+ source_add (data,
+ " gtk_tool_item_set_is_important (GTK_TOOL_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_menu_tool_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_menu_tool_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = menutoolbutton_xpm;
+ gbwidget.tooltip = _("Toolbar Button with Menu");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_menu_tool_button_new;
+ gbwidget.gb_widget_create_properties = gb_menu_tool_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_menu_tool_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_menu_tool_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_menu_tool_button_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_menu_tool_button_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbnotebook.c b/tools/glade/glade/gbwidgets/gbnotebook.c
new file mode 100644
index 00000000..b4251ab3
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbnotebook.c
@@ -0,0 +1,954 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+#include "../tree.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/notebook.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *ShowTabs = "GtkNotebook::show_tabs";
+static gchar *ShowBorder = "GtkNotebook::show_border";
+static gchar *TabPos = "GtkNotebook::tab_pos";
+static gchar *Scrollable = "GtkNotebook::scrollable";
+static gchar *Popups = "GtkNotebook::enable_popup";
+
+#if 0
+/* These seem to be deprecated. */
+static gchar *TabHBorder = "GtkNotebook::tab_hborder";
+static gchar *TabVBorder = "GtkNotebook::tab_vborder";
+#endif
+
+/* This isn't save in the XML as it is implicit. */
+static gchar *NumPages = "GtkNotebook::num_pages";
+
+/* This isn't save in the XML as it is implicit. */
+static gchar *ChildPosition = "GtkNotebook::position";
+
+static gchar *ChildExpand = "GtkNotebook::tab_expand";
+static gchar *ChildFill = "GtkNotebook::tab_fill";
+static gchar *ChildPack = "GtkNotebook::tab_pack";
+static gchar *ChildMenuLabel = "GtkNotebook::menu_label";
+
+
+static const gchar *GbTabPosChoices[] =
+{"Left", "Right", "Top", "Bottom", NULL};
+static const gint GbTabPosValues[] =
+{
+ GTK_POS_LEFT,
+ GTK_POS_RIGHT,
+ GTK_POS_TOP,
+ GTK_POS_BOTTOM
+};
+static const gchar *GbTabPosSymbols[] =
+{
+ "GTK_POS_LEFT",
+ "GTK_POS_RIGHT",
+ "GTK_POS_TOP",
+ "GTK_POS_BOTTOM"
+};
+
+
+static void show_notebook_dialog (GbWidgetNewData * data);
+static void on_notebook_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_notebook_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+static GtkWidget *gb_notebook_new_tab_label ();
+static void gb_notebook_next_page (GtkWidget * menuitem, GtkNotebook * notebook);
+static void gb_notebook_prev_page (GtkWidget * menuitem, GtkNotebook * notebook);
+static void gb_notebook_update_num_pages (GtkNotebook *notebook);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkNotebook, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_notebook_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gtk_notebook_new ();
+ return new_widget;
+ }
+ else
+ {
+ show_notebook_dialog (data);
+ return NULL;
+ }
+}
+
+
+void
+gb_notebook_add_child (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gboolean is_tab = FALSE;
+
+ /* See if this is a tab widget. We use a special "type" packing property set
+ to "tab".*/
+ if (data->child_info)
+ {
+ int j;
+
+ for (j = 0; j < data->child_info->n_properties; j++)
+ {
+ if (!strcmp (data->child_info->properties[j].name, "type")
+ && !strcmp (data->child_info->properties[j].value, "tab"))
+ {
+ is_tab = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (is_tab)
+ {
+ /* We store the last tab read in 'last_child' */
+ GtkWidget *notebook_page;
+ gint pos = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ "last_child"));
+
+ MSG1 ("Adding notebook tab: %i", pos);
+ /* SPECIAL CODE to replace the notebooks default tab label with the
+ loaded widget. We remove the page and add it with the new tab,
+ just like in gb_widget_replace_child(). */
+
+ notebook_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (widget), pos);
+ if (notebook_page)
+ {
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (widget), notebook_page,
+ child);
+ }
+ else
+ {
+ g_warning ("Notebook tab found for non-existent page");
+ gtk_notebook_append_page (GTK_NOTEBOOK (widget),
+ editor_new_placeholder (), child);
+ }
+ gtk_object_set_data (GTK_OBJECT (widget), "last_child",
+ GINT_TO_POINTER (pos + 1));
+ }
+ else
+ {
+ /* We create a label, in case it does not appear in the XML file,
+ or we are pasting into the notebook. */
+ GtkWidget *label = gb_widget_new_full ("GtkLabel", FALSE, widget,
+ NULL, 0, 0, NULL, GB_CREATING,
+ NULL);
+ g_return_if_fail (label != NULL);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (widget), child, label);
+ }
+}
+
+
+static void
+show_notebook_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New notebook"), data->parent,
+ GTK_SIGNAL_FUNC (on_notebook_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_notebook_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of pages:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "pages",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_notebook_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window;
+ gint pages, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "pages");
+ g_return_if_fail (spinbutton != NULL);
+ pages = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_notebook_new ();
+ for (i = 0; i < pages; i++)
+ {
+ gtk_notebook_append_page (GTK_NOTEBOOK (new_widget),
+ editor_new_placeholder (),
+ gb_notebook_new_tab_label ());
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_notebook_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+GtkWidget *
+gb_notebook_new_tab_label ()
+{
+ GtkWidget *label;
+
+ label = gb_widget_new ("GtkLabel", NULL);
+ g_return_val_if_fail (label != NULL, NULL);
+ return label;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_notebook_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (ShowTabs, _("Show Tabs:"), _("If the notebook tabs are shown"));
+ property_add_bool (ShowBorder, _("Show Border:"),
+ _("If the notebook border is shown, when the tabs are not shown"));
+ property_add_choice (TabPos, _("Tab Pos:"),
+ _("The position of the notebook tabs"),
+ GbTabPosChoices);
+ property_add_bool (Scrollable, _("Scrollable:"),
+ _("If the notebook tabs are scrollable"));
+#if 0
+/* These seem to be deprecated. */
+ property_add_int_range (TabHBorder, _("Tab Horz. Border:"),
+ _("The size of the notebook tabs' horizontal border"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (TabVBorder, _("Tab Vert. Border:"),
+ _("The size of the notebook tabs' vertical border"),
+ 0, 1000, 1, 10, 1);
+#endif
+ property_add_bool (Popups, _("Show Popup:"), _("If the popup menu is enabled"));
+ property_add_int_range (NumPages, _("Number of Pages:"),
+ _("The number of notebook pages"),
+ 1, 100, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_notebook_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint tab_pos, i;
+
+ gb_widget_output_bool (data, ShowTabs, GTK_NOTEBOOK (widget)->show_tabs);
+ gb_widget_output_bool (data, ShowBorder, GTK_NOTEBOOK (widget)->show_border);
+
+ tab_pos = GTK_NOTEBOOK (widget)->tab_pos;
+ for (i = 0; i < sizeof (GbTabPosValues) / sizeof (GbTabPosValues[0]); i++)
+ {
+ if (GbTabPosValues[i] == tab_pos)
+ gb_widget_output_choice (data, TabPos, i, GbTabPosSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Scrollable, GTK_NOTEBOOK (widget)->scrollable);
+
+#if 0
+/* These seem to be deprecated. */
+ gb_widget_output_int (data, TabHBorder, GTK_NOTEBOOK (widget)->tab_hborder);
+ gb_widget_output_int (data, TabVBorder, GTK_NOTEBOOK (widget)->tab_vborder);
+#endif
+
+ gb_widget_output_bool (data, Popups,
+ (GTK_NOTEBOOK (widget)->menu) ? TRUE : FALSE);
+
+ /* Don't save the number of pages. */
+ if (data->action != GB_SAVING)
+ gb_widget_output_int (data, NumPages,
+ g_list_length (GTK_NOTEBOOK (widget)->children));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_notebook_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean show_tabs, show_border, scrollable, popups;
+ gchar *tab_pos;
+ gint i, num_pages;
+ GtkWidget *new_label;
+
+ show_tabs = gb_widget_input_bool (data, ShowTabs);
+ if (data->apply)
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), show_tabs);
+
+ show_border = gb_widget_input_bool (data, ShowBorder);
+ if (data->apply)
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), show_border);
+
+ tab_pos = gb_widget_input_choice (data, TabPos);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbTabPosValues) / sizeof (GbTabPosValues[0]); i
+ ++)
+ {
+ if (!strcmp (tab_pos, GbTabPosChoices[i])
+ || !strcmp (tab_pos, GbTabPosSymbols[i]))
+ {
+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (widget), GbTabPosValues
+ [i]);
+ break;
+ }
+ }
+ }
+
+ scrollable = gb_widget_input_bool (data, Scrollable);
+ if (data->apply)
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (widget), scrollable);
+
+#if 0
+/* These seem to be deprecated. */
+ tab_border = gb_widget_input_int (data, TabHBorder);
+ if (data->apply)
+ gtk_notebook_set_tab_hborder (GTK_NOTEBOOK (widget), tab_border);
+
+ tab_border = gb_widget_input_int (data, TabVBorder);
+ if (data->apply)
+ gtk_notebook_set_tab_vborder (GTK_NOTEBOOK (widget), tab_border);
+#endif
+
+ popups = gb_widget_input_bool (data, Popups);
+ if (data->apply)
+ {
+ if (popups)
+ gtk_notebook_popup_enable (GTK_NOTEBOOK (widget));
+ else
+ gtk_notebook_popup_disable (GTK_NOTEBOOK (widget));
+ }
+
+ /* Don't adjust the size of a notebook if loading a project
+ * as it is handled by other routines. */
+ if (data->action != GB_LOADING)
+ {
+ num_pages = gb_widget_input_int (data, NumPages);
+ if (data->apply)
+ {
+ if (num_pages != g_list_length (GTK_NOTEBOOK (widget)->children))
+ {
+ if (num_pages > g_list_length (GTK_NOTEBOOK (widget)->children))
+ {
+ while (num_pages > g_list_length (GTK_NOTEBOOK (widget)->children))
+ {
+ new_label = gb_notebook_new_tab_label ();
+ gtk_notebook_append_page (GTK_NOTEBOOK (widget),
+ editor_new_placeholder (),
+ new_label);
+ tree_add_widget (new_label);
+ }
+ }
+ else
+ {
+ while (num_pages < g_list_length (GTK_NOTEBOOK (widget)->children))
+ {
+ gtk_notebook_remove_page (GTK_NOTEBOOK (widget),
+ num_pages);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+static void
+gb_notebook_next_page (GtkWidget * menuitem, GtkNotebook * notebook)
+{
+ gtk_notebook_next_page (notebook);
+}
+
+static void
+gb_notebook_prev_page (GtkWidget * menuitem, GtkNotebook * notebook)
+{
+ gtk_notebook_prev_page (notebook);
+}
+
+static void
+gb_notebook_switch_prev (GtkWidget *menuitem, GtkNotebook *notebook)
+{
+ GtkWidget *child;
+ gint current_page;
+
+ current_page = gtk_notebook_get_current_page (notebook);
+ child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), current_page);
+
+ if (child)
+ {
+ gtk_notebook_reorder_child (notebook, child, current_page - 1);
+ }
+}
+
+static void
+gb_notebook_switch_next (GtkWidget *menuitem, GtkNotebook *notebook)
+{
+ GtkWidget *child;
+ gint current_page;
+
+ current_page = gtk_notebook_get_current_page (notebook);
+ child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), current_page);
+
+ if (child)
+ {
+ gtk_notebook_reorder_child (notebook, child, current_page + 1);
+ }
+}
+
+static void
+gb_notebook_insert_next (GtkWidget *menuitem, GtkNotebook *notebook)
+{
+ gint current_page;
+ GtkWidget *new_label;
+
+ current_page = gtk_notebook_get_current_page (notebook);
+
+ new_label = gb_notebook_new_tab_label ();
+ gtk_notebook_insert_page (notebook, editor_new_placeholder (),
+ new_label, current_page + 1);
+ tree_add_widget (new_label);
+ gb_notebook_update_num_pages (notebook);
+}
+
+static void
+gb_notebook_insert_prev (GtkWidget *menuitem, GtkNotebook *notebook)
+{
+ gint current_page;
+ GtkWidget *new_label;
+
+ current_page = gtk_notebook_get_current_page (notebook);
+
+ new_label = gb_notebook_new_tab_label ();
+ gtk_notebook_insert_page (notebook, editor_new_placeholder (),
+ new_label, current_page);
+ tree_add_widget (new_label);
+ gb_notebook_update_num_pages (notebook);
+}
+
+static void
+gb_notebook_delete_page (GtkWidget *menuitem, GtkNotebook *notebook)
+{
+ gtk_notebook_remove_page (notebook,
+ gtk_notebook_get_current_page (notebook));
+ gb_notebook_update_num_pages (notebook);
+}
+
+
+/* This updates the number of pages property, if the notebook's properties are
+ currently shown. */
+static void
+gb_notebook_update_num_pages (GtkNotebook *notebook)
+{
+ if (property_get_widget () == GTK_WIDGET (notebook))
+ {
+ property_set_auto_apply (FALSE);
+ property_set_int (NumPages, g_list_length (notebook->children));
+ property_set_auto_apply (TRUE);
+ }
+}
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkNotebook, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_notebook_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+ gint current_page, num_pages;
+
+ current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (widget));
+ num_pages = g_list_length (GTK_NOTEBOOK (widget)->children);
+
+ menuitem = gtk_menu_item_new_with_label (_("Previous Page"));
+ gtk_widget_show (menuitem);
+ if (current_page == 0)
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_prev_page), GTK_NOTEBOOK (widget));
+
+ menuitem = gtk_menu_item_new_with_label (_("Next Page"));
+ gtk_widget_show (menuitem);
+ if (current_page == num_pages - 1)
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_next_page), GTK_NOTEBOOK (widget));
+
+ menuitem = gtk_menu_item_new_with_label (_("Delete Page"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_delete_page), GTK_NOTEBOOK (widget));
+
+ menuitem = gtk_menu_item_new_with_label (_("Switch Next"));
+ gtk_widget_show (menuitem);
+ if (current_page == num_pages - 1)
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_switch_next), GTK_NOTEBOOK (widget));
+
+ menuitem = gtk_menu_item_new_with_label (_("Switch Previous"));
+ gtk_widget_show (menuitem);
+ if (current_page == 0)
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_switch_prev), GTK_NOTEBOOK (widget));
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Page After"));
+ gtk_widget_show (menuitem);
+ /* if (current_page == num_pages - 1)
+ gtk_widget_set_sensitive (menuitem, FALSE);*/
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_insert_next), GTK_NOTEBOOK (widget));
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Page Before"));
+ gtk_widget_show (menuitem);
+ /*if (current_page == 0)
+ gtk_widget_set_sensitive (menuitem, FALSE);*/
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_notebook_insert_prev), GTK_NOTEBOOK (widget));
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_notebook_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_notebook_new ();\n", data->wname);
+ }
+
+ /* We reset the last_child index, so as the tab widgets are written out
+ they will start at page 0. */
+ gtk_object_set_data (GTK_OBJECT (widget), "last_child",
+ GINT_TO_POINTER (-1));
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!GTK_NOTEBOOK (widget)->show_tabs)
+ source_add (data,
+ " gtk_notebook_set_show_tabs (GTK_NOTEBOOK (%s), FALSE);\n",
+ data->wname);
+ if (!GTK_NOTEBOOK (widget)->show_border)
+ source_add (data,
+ " gtk_notebook_set_show_border (GTK_NOTEBOOK (%s), FALSE);\n",
+ data->wname);
+ if (GTK_NOTEBOOK (widget)->tab_pos != GTK_POS_TOP)
+ {
+ for (i = 0; i < sizeof (GbTabPosValues) / sizeof (GbTabPosValues[0]); i
+ ++)
+ {
+ if (GbTabPosValues[i] == GTK_NOTEBOOK (widget)->tab_pos)
+ source_add (data,
+ " gtk_notebook_set_tab_pos (GTK_NOTEBOOK (%s), %s);\n",
+ data->wname, GbTabPosSymbols[i]);
+ }
+ }
+ if (GTK_NOTEBOOK (widget)->scrollable)
+ source_add (data,
+ " gtk_notebook_set_scrollable (GTK_NOTEBOOK (%s), TRUE);\n",
+ data->wname);
+
+#if 0
+/* These seem to be deprecated. */
+ if (GTK_NOTEBOOK (widget)->tab_hborder != 2)
+ source_add (data,
+ " gtk_notebook_set_tab_hborder (GTK_NOTEBOOK (%s), %i);\n",
+ data->wname, GTK_NOTEBOOK (widget)->tab_hborder);
+ if (GTK_NOTEBOOK (widget)->tab_vborder != 2)
+ source_add (data,
+ " gtk_notebook_set_tab_vborder (GTK_NOTEBOOK (%s), %i);\n",
+ data->wname, GTK_NOTEBOOK (widget)->tab_vborder);
+#endif
+
+ if (GTK_NOTEBOOK (widget)->menu)
+ source_add (data,
+ " gtk_notebook_popup_enable (GTK_NOTEBOOK (%s));\n",
+ data->wname);
+}
+
+
+/*
+ * Creates the child packing properties for children of this widget.
+ */
+void
+gb_notebook_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_int_range (ChildPosition, _("Position:"),
+ _("The page's position in the list of pages"),
+ 0, 10000, 1, 10, 1);
+ property_add_bool (ChildExpand, _("Expand:"),
+ _("Set True to let the tab expand"));
+ property_add_bool (ChildFill, _("Fill:"),
+ _("Set True to let the tab fill its allocated area"));
+ property_add_bool (ChildPack, _("Pack Start:"),
+ _("Set True to pack the tab at the start of the notebook"));
+ property_add_string (ChildMenuLabel, _("Menu Label:"),
+ _("The text to display in the popup menu"));
+}
+
+
+static gboolean
+gb_notebook_get_child_info (GtkNotebook *notebook, GtkWidget *child,
+ GtkWidget **notebook_child,
+ GtkWidget **notebook_tab,
+ gint *position, gboolean *expand, gboolean *fill,
+ GtkPackType *pack_type)
+{
+ gint nchildren, page;
+
+ nchildren = g_list_length (notebook->children);
+
+ for (page = 0; page < nchildren; page++)
+ {
+ *notebook_child = gtk_notebook_get_nth_page (notebook, page);
+ *notebook_tab = gtk_notebook_get_tab_label (notebook, *notebook_child);
+
+ if (*notebook_child == child || *notebook_tab == child)
+ {
+ gtk_notebook_query_tab_label_packing (notebook, *notebook_child,
+ expand, fill, pack_type);
+ *position = page;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+void
+gb_notebook_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ GtkWidget *notebook_child, *notebook_tab;
+ gboolean expand, fill;
+ gint position;
+ GtkPackType pack_type;
+ const gchar *menu_label;
+
+ /* If we can't find the child, output a warning and return. */
+ if (!gb_notebook_get_child_info (GTK_NOTEBOOK (widget), child,
+ &notebook_child, &notebook_tab,
+ &position, &expand, &fill, &pack_type))
+ {
+ g_warning ("Notebook child not found");
+ return;
+ }
+
+ /* If we are saving, we save the packing properties with the main child
+ widget, and not with the tab label. But we show the packing properties
+ for the tab label as well, as that is easier for the user.
+ For the tab label we save the special "type" packing property. */
+ if (data->action == GB_SAVING && child == notebook_tab)
+ {
+ save_start_tag (data, "packing");
+ gb_widget_output_string (data, "type", "tab");
+ save_end_tag (data, "packing");
+ return;
+ }
+
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ if (data->action == GB_SHOWING)
+ gb_widget_output_int (data, ChildPosition, position);
+
+ gb_widget_output_bool (data, ChildExpand, expand);
+ gb_widget_output_bool (data, ChildFill, fill);
+
+ if (data->action == GB_SAVING)
+ {
+ /* Save pack type as an enum symbol rather than a bool */
+ if (pack_type == GTK_PACK_END)
+ {
+ gb_widget_output_string (data, ChildPack, "GTK_PACK_END");
+ }
+ }
+ else
+ {
+ gb_widget_output_bool (data, ChildPack, pack_type == GTK_PACK_START);
+ }
+
+ menu_label = gtk_notebook_get_menu_label_text (GTK_NOTEBOOK (widget),
+ notebook_child);
+ gb_widget_output_translatable_string (data, ChildMenuLabel, menu_label);
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+/* Applies or loads the child properties of a child of a hbox/vbox. */
+void
+gb_notebook_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ GtkWidget *notebook_child, *notebook_tab;
+ gint position, old_position;
+ gboolean expand, fill, pack, set_child_packing = FALSE;
+ gboolean old_expand, old_fill;
+ GtkPackType old_pack_type;
+ char *menu_label;
+
+ /* If we can't find the child, output a warning and return. */
+ if (!gb_notebook_get_child_info (GTK_NOTEBOOK (widget), child,
+ &notebook_child, &notebook_tab,
+ &old_position, &old_expand, &old_fill,
+ &old_pack_type))
+ {
+ g_warning ("Notebook child not found");
+ return;
+ }
+
+ /* If we are loading, don't set the packing properties for the tab. */
+ if (data->action == GB_LOADING && child == notebook_tab)
+ return;
+
+ position = gb_widget_input_int (data, ChildPosition);
+ if (data->apply)
+ {
+ gtk_notebook_reorder_child (GTK_NOTEBOOK (widget), notebook_child,
+ position);
+ }
+
+ expand = gb_widget_input_bool (data, ChildExpand);
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ expand = old_expand;
+
+ fill = gb_widget_input_bool (data, ChildFill);
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ fill = old_fill;
+
+ if (data->action == GB_APPLYING)
+ {
+ pack = gb_widget_input_bool (data, ChildPack);
+ }
+ else
+ {
+ gchar *pack_symbol = gb_widget_input_string (data, ChildPack);
+ pack = pack_symbol && !strcmp (pack_symbol, "GTK_PACK_START");
+ }
+ if (data->apply)
+ set_child_packing = TRUE;
+ else
+ pack = (old_pack_type == GTK_PACK_START) ? TRUE : FALSE;
+
+ if (set_child_packing)
+ gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (widget), notebook_child,
+ expand, fill,
+ pack ? GTK_PACK_START : GTK_PACK_END);
+
+ menu_label = gb_widget_input_string (data, ChildMenuLabel);
+ if (data->apply)
+ {
+ gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (widget), notebook_child,
+ menu_label);
+ }
+}
+
+/* Outputs source to add a child widget to a GtkNotebook. */
+static void
+gb_notebook_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ GtkWidget *notebook_child, *notebook_tab;
+ gboolean expand, fill;
+ gint position;
+ GtkPackType pack_type;
+
+ if (!gb_notebook_get_child_info (GTK_NOTEBOOK (parent), child,
+ &notebook_child, &notebook_tab,
+ &position, &expand, &fill, &pack_type))
+ {
+ g_warning ("Notebook child not found");
+ return;
+ }
+
+ /* See if this is a notebook tab widget. */
+ if (child == notebook_tab)
+ {
+ /* We store the last tab written in 'last_child' */
+ gint col = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "last_child"));
+ /* We use the special function to add the tab to the notebook. */
+ source_add (data,
+ " gtk_notebook_set_tab_label (GTK_NOTEBOOK (%s), gtk_notebook_get_nth_page (GTK_NOTEBOOK (%s), %i), %s);\n",
+ parent_name, parent_name, col + 1, data->wname);
+
+ gtk_object_set_data (GTK_OBJECT (parent), "last_child",
+ GINT_TO_POINTER (col + 1));
+ }
+ else
+ {
+ const gchar *menu_label;
+
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+
+ /* Set the packing properties, if different to the defaults. */
+ if (expand || !fill || pack_type != GTK_PACK_START)
+ {
+ source_add (data,
+ " gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (%s), %s,\n"
+ " %s, %s, %s);\n",
+ parent_name, data->wname,
+ expand ? "TRUE" : "FALSE",
+ fill ? "TRUE" : "FALSE",
+ pack_type == GTK_PACK_START ? "GTK_PACK_START" : "GTK_PACK_END");
+ }
+
+ menu_label = gtk_notebook_get_menu_label_text (GTK_NOTEBOOK (parent),
+ notebook_child);
+ if (menu_label && *menu_label)
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (notebook_child,
+ ChildMenuLabel, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (%s), %s, %s);\n",
+ parent_name, data->wname,
+ source_make_string_full (menu_label, data->use_gettext && translatable, context));
+ }
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_notebook_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_notebook_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = notebook_xpm;
+ gbwidget.tooltip = _("Notebook");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_notebook_new;
+ gbwidget.gb_widget_add_child = gb_notebook_add_child;
+
+ gbwidget.gb_widget_create_properties = gb_notebook_create_properties;
+ gbwidget.gb_widget_get_properties = gb_notebook_get_properties;
+ gbwidget.gb_widget_set_properties = gb_notebook_set_properties;
+ gbwidget.gb_widget_write_source = gb_notebook_write_source;
+ gbwidget.gb_widget_create_child_properties = gb_notebook_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_notebook_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_notebook_set_child_properties;
+ gbwidget.gb_widget_write_add_child_source = gb_notebook_write_add_child_source;
+ gbwidget.gb_widget_create_popup_menu = gb_notebook_create_popup_menu;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gboptionmenu.c b/tools/glade/glade/gbwidgets/gboptionmenu.c
new file mode 100644
index 00000000..be5a695f
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gboptionmenu.c
@@ -0,0 +1,285 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkoptionmenu.h>
+#include "../gb.h"
+#include "../glade_menu_editor.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/optionmenu.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static const char *History = "GtkOptionMenu::history";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkOptionMenu, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_option_menu_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ new_widget = gtk_option_menu_new ();
+ return new_widget;
+}
+
+/* Make window behave like a dialog */
+static void
+dialogize (GtkWidget *menued, GtkWidget *parent_widget)
+{
+ GtkWidget *transient_parent;
+
+ gtk_signal_connect (GTK_OBJECT (menued), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscDestroys));
+ transient_parent = glade_util_get_toplevel (parent_widget);
+ if (GTK_IS_WINDOW (transient_parent))
+ {
+ gtk_window_set_transient_for (GTK_WINDOW (menued),
+ GTK_WINDOW (transient_parent));
+ }
+}
+
+static void
+set_menu (GladeMenuEditor *menued, GtkOptionMenu *option)
+{
+ int history;
+
+ g_return_if_fail (GLADE_IS_MENU_EDITOR (menued));
+ g_return_if_fail (GTK_IS_OPTION_MENU (option));
+
+ history = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (option), History));
+ gtk_option_menu_set_menu (option, GTK_WIDGET (menued->menu));
+ gtk_option_menu_set_history (option, history);
+}
+
+static void
+gb_menu_bar_on_edit_menu (GtkWidget *button,
+ gpointer data)
+{
+ GtkWidget *option, *menued, *menu;
+
+ option = property_get_widget ();
+ g_return_if_fail (GTK_IS_OPTION_MENU (option));
+
+ /*
+ * we need to remove the menu from the option menu otherwise there
+ * will be a separator where the selected menu is
+ */
+ g_object_set_data (G_OBJECT (option),
+ History,
+ GINT_TO_POINTER (gtk_option_menu_get_history (GTK_OPTION_MENU (option))));
+ menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (option));
+ if (!menu)
+ menu = gb_widget_new ("GtkMenu", option);
+ g_object_ref (menu);
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (option), gtk_menu_new ());
+
+ menued = glade_menu_editor_new (current_project, GTK_MENU_SHELL (menu));
+ g_signal_connect (menued, "destroy", G_CALLBACK (set_menu), option);
+
+ /* I think this was hidden as it doesn't call set_menu() to reset the
+ history. */
+ gtk_widget_hide (GLADE_MENU_EDITOR (menued)->apply_button);
+
+ dialogize (menued, button);
+ gtk_widget_show (GTK_WIDGET (menued));
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (option), menu);
+ g_object_unref (menu);
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_option_menu_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ GtkWidget *property_table, *button;
+ gint property_table_row;
+
+ /* Add a button for editing the menubar. */
+ property_table = property_get_table_position (&property_table_row);
+ button = gtk_button_new_with_label (_("Edit Menus..."));
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (gb_menu_bar_on_edit_menu), NULL);
+ gtk_table_attach (GTK_TABLE (property_table), button, 0, 3,
+ property_table_row, property_table_row + 1,
+ GTK_FILL, GTK_FILL, 10, 10);
+
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_option_menu_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ if (data->action == GB_SAVING)
+ gb_widget_output_int (data, History,
+ gtk_option_menu_get_history (GTK_OPTION_MENU (widget)));
+}
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_option_menu_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ int history;
+
+ if (data->action == GB_LOADING)
+ {
+ history = gb_widget_input_int (data, History);
+ if (data->apply)
+ gtk_option_menu_set_history (GTK_OPTION_MENU (widget), history);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkOptionMenu, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_option_menu_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_option_menu_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint history;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_option_menu_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ history = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
+ if (history > 0)
+ source_add (data,
+ " gtk_option_menu_set_history (GTK_OPTION_MENU (%s), %i);\n",
+ data->wname, history);
+}
+
+
+static void
+gb_option_menu_add_child (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ if (GTK_IS_MENU (child))
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), child);
+ else
+ g_warning (_("Cannot add a %s to a GtkOptionMenu."),
+ g_type_name (G_OBJECT_TYPE (child)));
+}
+
+
+/* Outputs source to add a child widget to a hbox/vbox. */
+void
+gb_option_menu_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ /* We don't output anything here. The code to add the menu to the option
+ menu must be output after all the menuitems are added, so we have some
+ special code in gb_widget_write_source() to do that. */
+#if 0
+ source_add (data,
+ " gtk_option_menu_set_menu (GTK_OPTION_MENU (%s), %s);\n",
+ parent_name, data->wname);
+#endif
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_option_menu_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_option_menu_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = optionmenu_xpm;
+ gbwidget.tooltip = _("Option Menu");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_option_menu_new;
+ gbwidget.gb_widget_create_properties = gb_option_menu_create_properties;
+ gbwidget.gb_widget_get_properties = gb_option_menu_get_properties;
+ gbwidget.gb_widget_set_properties = gb_option_menu_set_properties;
+ gbwidget.gb_widget_add_child = gb_option_menu_add_child;
+ gbwidget.gb_widget_write_source = gb_option_menu_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_option_menu_write_add_child_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_option_menu_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbpreview.c b/tools/glade/glade/gbwidgets/gbpreview.c
new file mode 100644
index 00000000..1879a2f9
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbpreview.c
@@ -0,0 +1,175 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkpreview.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/preview.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Type = "GtkPreview::type";
+static gchar *Expand = "GtkPreview::expand";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkPreview, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_preview_new (GbWidgetNewData * data)
+{
+ GtkWidget *preview;
+ preview = gtk_preview_new (GTK_PREVIEW_COLOR);
+ return preview;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_preview_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Type, _("Color:"),
+ _("If the preview is color or grayscale"));
+ property_add_bool (Expand, _("Expand:"),
+ _("If the preview expands to fill its allocated area"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_preview_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, Type, GTK_PREVIEW (widget)->type == GTK_PREVIEW_COLOR);
+ gb_widget_output_bool (data, Expand, GTK_PREVIEW (widget)->expand);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_preview_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean type, expand;
+
+ type = gb_widget_input_bool (data, Type);
+ /* We shouldn't really set the preview type after initialisation, but it
+ should be OK as we never use the preview */
+ if (data->apply)
+ GTK_PREVIEW (widget)->type = type ? GTK_PREVIEW_COLOR
+ : GTK_PREVIEW_GRAYSCALE;
+ expand = gb_widget_input_bool (data, Expand);
+ if (data->apply)
+ gtk_preview_set_expand (GTK_PREVIEW (widget), expand);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkPreview, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_preview_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_preview_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_preview_new (%s);\n", data->wname,
+ GTK_PREVIEW (widget)->type == GTK_PREVIEW_COLOR
+ ? "GTK_PREVIEW_COLOR" : "GTK_PREVIEW_GRAYSCALE");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_PREVIEW (widget)->expand)
+ source_add (data, " gtk_preview_set_expand (GTK_PREVIEW (%s), TRUE);\n",
+ data->wname);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_preview_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_preview_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = preview_xpm;
+ gbwidget.tooltip = _("Preview");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_preview_new;
+ gbwidget.gb_widget_create_properties = gb_preview_create_properties;
+ gbwidget.gb_widget_get_properties = gb_preview_get_properties;
+ gbwidget.gb_widget_set_properties = gb_preview_set_properties;
+ gbwidget.gb_widget_write_source = gb_preview_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_preview_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbprogressbar.c b/tools/glade/glade/gbwidgets/gbprogressbar.c
new file mode 100644
index 00000000..e346bccc
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbprogressbar.c
@@ -0,0 +1,433 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * Update 3/17/99 - Jay Johnston:
+ * - added property adjustments
+ * - style
+ * - orientation
+ * - activity mode
+ * - show text
+ * - added sample animation (most of that code was taken from the Gtk v1.2
+ * tutorial by Tony Gale <gale@gtk.org> and Ian Main <imain@gtk.org> )
+ * - added dynamic popup menus which change depending on whether the animation
+ * is active or not
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <math.h>
+#include <gtk/gtkprogressbar.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/progressbar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Orientation = "GtkProgressBar::orientation";
+static gchar *Fraction = "GtkProgressBar::fraction";
+static gchar *PulseStep = "GtkProgressBar::pulse_step";
+static gchar *Text = "GtkProgressBar::text";
+static gchar *Ellipsize = "GtkProgressBar::ellipsize";
+
+#if 0
+static gchar *ShowText = "ProgressBar|GtkProgress::show_text";
+static gchar *ActivityMode = "ProgressBar|GtkProgress::activity_mode";
+static gchar *XAlign = "GtkProgressBar::text_xalign";
+static gchar *YAlign = "GtkProgressBar::text_yalign";
+
+static gchar *Value = "ProgressBar|GtkProgress::value";
+static gchar *MinValue = "ProgressBar|GtkProgress::lower";
+static gchar *MaxValue = "ProgressBar|GtkProgress::upper";
+static gchar *Style = "GtkProgressBar::bar_style";
+#endif
+
+
+static const gchar *GbOrientationChoices[] =
+{"Left to Right", "Right to Left", "Bottom to Top", "Top to Bottom", NULL};
+
+static const gint GbOrientationValues[] =
+{
+ GTK_PROGRESS_LEFT_TO_RIGHT,
+ GTK_PROGRESS_RIGHT_TO_LEFT,
+ GTK_PROGRESS_BOTTOM_TO_TOP,
+ GTK_PROGRESS_TOP_TO_BOTTOM
+};
+static const gchar *GbOrientationSymbols[] =
+{
+ "GTK_PROGRESS_LEFT_TO_RIGHT",
+ "GTK_PROGRESS_RIGHT_TO_LEFT",
+ "GTK_PROGRESS_BOTTOM_TO_TOP",
+ "GTK_PROGRESS_TOP_TO_BOTTOM"
+};
+
+static const gchar *GbEllipsizeChoices[] =
+{
+ "None",
+ "Start",
+ "Middle",
+ "End",
+ NULL
+};
+static const gint GbEllipsizeValues[] =
+{
+ PANGO_ELLIPSIZE_NONE,
+ PANGO_ELLIPSIZE_START,
+ PANGO_ELLIPSIZE_MIDDLE,
+ PANGO_ELLIPSIZE_END
+};
+static const gchar *GbEllipsizeSymbols[] =
+{
+ "PANGO_ELLIPSIZE_NONE",
+ "PANGO_ELLIPSIZE_START",
+ "PANGO_ELLIPSIZE_MIDDLE",
+ "PANGO_ELLIPSIZE_END"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkProgressBar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_progress_bar_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_progress_bar_new ();
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+
+static void
+gb_progress_bar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Orientation, _("Orientation:"),
+ _("The orientation of the progress bar's contents"),
+ GbOrientationChoices);
+ property_add_float_range (Fraction, _("Fraction:"),
+ _("The fraction of work that has been completed"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (PulseStep, _("Pulse Step:"),
+ _("The fraction of the progress bar length to move the bouncing block when pulsed"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_string (Text, _("Text:"),
+ _("The text to display over the progress bar"));
+
+ property_add_choice (Ellipsize, _("Ellipsize:"),
+ _("How to ellipsize the string"),
+ GbEllipsizeChoices);
+
+#if 0
+ /* ShowText is implicit now, if the Text property is set to anything. */
+ property_add_bool (ShowText, _("Show Text:"),
+ _("If the text should be shown in the progress bar"));
+
+ /* ActivityMode is deprecated and implicit now. The app just calls
+ gtk_progress_bar_pulse() and it automatically goes into activity mode. */
+ property_add_bool (ActivityMode, _("Activity Mode:"),
+ _("If the progress bar should act like the front of Kit's car"));
+
+ /* The GtkProgress interface is deprecated now, and GtkProgressBar doesn't
+ have functions to set these, so I suppose we shouldn't support them. */
+ property_add_float_range (XAlign, _("X Align:"),
+ _("The horizontal alignment of the text"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+ property_add_float_range (YAlign, _("Y Align:"),
+ _("The vertical alignment of the text"),
+ 0, 1, 0.01, 0.1, 0.01, 2);
+#endif
+}
+
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+
+static void
+gb_progress_bar_get_properties(GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ PangoEllipsizeMode ellipsize_mode;
+ gint i;
+
+ for (i = 0; i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (GbOrientationValues[i] == GTK_PROGRESS_BAR (widget)->orientation)
+ gb_widget_output_choice (data, Orientation, i, GbOrientationSymbols[i]);
+ }
+
+ gb_widget_output_float (data, Fraction, gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget)));
+ gb_widget_output_float (data, PulseStep, gtk_progress_bar_get_pulse_step (GTK_PROGRESS_BAR (widget)));
+ gb_widget_output_translatable_string (data, Text, gtk_progress_bar_get_text (GTK_PROGRESS_BAR (widget)));
+
+ ellipsize_mode = gtk_progress_bar_get_ellipsize (GTK_PROGRESS_BAR (widget));
+ for (i = 0; i < sizeof (GbEllipsizeValues) / sizeof (GbEllipsizeValues[0]); i++)
+ {
+ if (GbEllipsizeValues[i] == ellipsize_mode)
+ gb_widget_output_choice (data, Ellipsize, i, GbEllipsizeSymbols[i]);
+ }
+
+#if 0
+ gb_widget_output_bool (data, ShowText, GTK_PROGRESS (widget)->show_text);
+ gb_widget_output_bool (data, ActivityMode, GTK_PROGRESS (widget)->activity_mode);
+
+ gb_widget_output_float (data, XAlign, GTK_PROGRESS (widget)->x_align);
+ gb_widget_output_float (data, YAlign, GTK_PROGRESS (widget)->y_align);
+#endif
+}
+
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+
+static void
+gb_progress_bar_set_properties(GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat fraction, pulse_step;
+#if 0
+ gfloat activityMode, xalign, yalign;
+ gboolean set_alignment = FALSE;
+ gboolean showText;
+#endif
+ gchar *orientation, *text, *ellipsize_mode;
+ gint i;
+
+ orientation = gb_widget_input_choice (data, Orientation);
+ if (data->apply)
+ {
+ for (i = 0;
+ i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]);
+ i++)
+ {
+ if (!strcmp (orientation, GbOrientationChoices[i])
+ || !strcmp (orientation, GbOrientationSymbols[i]))
+ {
+ gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (widget),
+ GbOrientationValues[i]);
+ break;
+ }
+ }
+ }
+
+ fraction = gb_widget_input_float (data, Fraction);
+ if (data->apply)
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget), fraction);
+
+ pulse_step = gb_widget_input_float (data, PulseStep);
+ if (data->apply)
+ gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (widget), pulse_step);
+
+ text = gb_widget_input_string (data, Text);
+ if (data->apply)
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget), text);
+
+ ellipsize_mode = gb_widget_input_choice (data, Ellipsize);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbEllipsizeValues) / sizeof (GbEllipsizeValues[0]);
+ i++)
+ {
+ if (!strcmp (ellipsize_mode, GbEllipsizeChoices[i])
+ || !strcmp (ellipsize_mode, GbEllipsizeSymbols[i]))
+ {
+ gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (widget),
+ GbEllipsizeValues[i]);
+ break;
+ }
+ }
+ }
+
+#if 0
+ showText = gb_widget_input_bool (data, ShowText);
+ if (data->apply)
+ gtk_progress_set_show_text (GTK_PROGRESS (widget), showText);
+
+ activityMode = gb_widget_input_bool (data, ActivityMode);
+ if (data->apply)
+ gtk_progress_set_activity_mode (GTK_PROGRESS (widget), activityMode);
+
+ xalign = gb_widget_input_float (data, XAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ xalign = GTK_PROGRESS (widget)->x_align;
+
+ yalign = gb_widget_input_float (data, YAlign);
+ if (data->apply)
+ set_alignment = TRUE;
+ else
+ yalign = GTK_PROGRESS (widget)->y_align;
+
+ if (set_alignment)
+ gtk_progress_set_text_alignment (GTK_PROGRESS (widget), xalign, yalign);
+#endif
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_progress_bar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gfloat fraction, pulse_step;
+ const char *text;
+ PangoEllipsizeMode ellipsize_mode;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_progress_bar_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_PROGRESS_BAR (widget)->orientation != GTK_PROGRESS_LEFT_TO_RIGHT)
+ {
+ for (i = 0; i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (GbOrientationValues[i] == GTK_PROGRESS_BAR (widget)->orientation)
+ source_add (data,
+ " gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (%s), %s);\n",
+ data->wname, GbOrientationSymbols[i]);
+ }
+ }
+
+ fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget));
+ if (fraction >= GLADE_EPSILON)
+ source_add (data,
+ " gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (%s), %g);\n",
+ data->wname, fraction);
+
+ pulse_step = gtk_progress_bar_get_pulse_step (GTK_PROGRESS_BAR (widget));
+ if (fabs (pulse_step - 0.1) >= GLADE_EPSILON)
+ source_add (data,
+ " gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (%s), %g);\n",
+ data->wname, pulse_step);
+
+ text = gtk_progress_bar_get_text (GTK_PROGRESS_BAR (widget));
+ if (text && *text)
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Text,
+ &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gtk_progress_bar_set_text (GTK_PROGRESS_BAR (%s), %s);\n",
+ data->wname,
+ source_make_string_full (text, data->use_gettext && translatable, context));
+ }
+
+ ellipsize_mode = gtk_progress_bar_get_ellipsize (GTK_PROGRESS_BAR (widget));
+ if (ellipsize_mode != PANGO_ELLIPSIZE_NONE)
+ {
+ for (i = 0;
+ i < sizeof (GbEllipsizeValues) / sizeof (GbEllipsizeValues[0]);
+ i++)
+ {
+ if (GbEllipsizeValues[i] == ellipsize_mode)
+ source_add (data,
+ " gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (%s), %s);\n",
+ data->wname, GbEllipsizeSymbols[i]);
+ }
+ }
+
+#if 0
+ if (GTK_PROGRESS (widget)->show_text)
+ {
+ source_add( data,
+ " gtk_progress_set_show_text (GTK_PROGRESS (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (GTK_PROGRESS (widget)->activity_mode)
+ {
+ source_add( data,
+ " gtk_progress_set_activity_mode (GTK_PROGRESS (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (GTK_PROGRESS (widget)->x_align != 0.5
+ || GTK_PROGRESS (widget)->y_align != 0.5)
+ {
+ source_add( data,
+ " gtk_progress_set_text_alignment (GTK_PROGRESS (%s), %g, %g);\n",
+ data->wname,
+ GTK_PROGRESS (widget)->x_align,
+ GTK_PROGRESS (widget)->y_align);
+ }
+#endif
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_progress_bar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_progress_bar_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = progressbar_xpm;
+ gbwidget.tooltip = _("Progress Bar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_progress_bar_new;
+
+ gbwidget.gb_widget_create_properties = gb_progress_bar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_progress_bar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_progress_bar_set_properties;
+ /*gbwidget.gb_widget_create_popup_menu = gb_progress_bar_create_popup_menu;*/
+ gbwidget.gb_widget_write_source = gb_progress_bar_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbradiobutton.c b/tools/glade/glade/gbwidgets/gbradiobutton.c
new file mode 100644
index 00000000..458e3fd6
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbradiobutton.c
@@ -0,0 +1,477 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkradiobutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/radiobutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "RadioButton|GtkButton::stock_button";
+static gchar *Label = "RadioButton|GtkButton::label";
+static gchar *Icon = "RadioButton|GtkButton::icon";
+static gchar *FocusOnClick = "RadioButton|GtkButton::focus_on_click";
+
+/* This is only used for normal/stock buttons, not special toolbar buttons,
+ as the toolbar has its own relief setting. */
+static gchar *Relief = "RadioButton|GtkButton::relief";
+
+static gchar *State = "RadioButton|GtkToggleButton::active";
+static gchar *Inconsistent = "RadioButton|GtkToggleButton::inconsistent";
+static gchar *Group = "GtkRadioButton::group";
+static gchar *Indicator = "RadioButton|GtkToggleButton::draw_indicator";
+
+typedef struct _GladeFindGroupsData GladeFindGroupsData;
+struct _GladeFindGroupsData {
+ GList *groups_found;
+ GList *group_names;
+};
+
+
+typedef struct _GladeFindGroupWidgetData GladeFindGroupWidgetData;
+struct _GladeFindGroupWidgetData {
+ gchar *name;
+ GtkWidget *found_widget;
+};
+
+
+static void get_radio_button_groups (GtkWidget * widget,
+ GladeFindGroupsData *find_data);
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+static void
+find_parents_group (GtkWidget * widget, GSList ** group)
+{
+ /* If a group has already been found, return. */
+ if (*group)
+ return;
+
+ if (GTK_IS_RADIO_BUTTON (widget))
+ *group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+}
+
+
+/*
+ * Creates a new GtkWidget of class GtkRadioButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_radio_button_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ GSList *group_list = NULL;
+
+ /* When creating a radiobutton we try to place it in the same group as other
+ radio buttons with the same parent. */
+ if (data->parent && data->action == GB_CREATING)
+ gb_widget_children_foreach (data->parent, (GtkCallback) find_parents_group,
+ &group_list);
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_radio_button_new_with_label (group_list, data->name);
+ else
+ {
+ new_widget = gtk_radio_button_new (group_list);
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder());
+ }
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_radio_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ GtkWidget *combo;
+
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_choice (Relief, _("Button Relief:"),
+ _("The relief style of the button"),
+ GladeReliefChoices);
+
+ property_add_bool (State, _("Initially On:"),
+ _("If the radio button is initially on"));
+ property_add_bool (Inconsistent, _("Inconsistent:"),
+ _("If the button is shown in an inconsistent state"));
+ property_add_bool (Indicator, _("Indicator:"),
+ _("If the indicator is always drawn"));
+ property_add_combo (Group, _("Group:"),
+ _("The radio button group (the default is all radio buttons with the same parent)"),
+ NULL);
+ combo = property_get_value_widget (Group);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE);
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_radio_button_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GtkWidget *component;
+ GladeFindGroupData find_data;
+
+ component = glade_util_get_toplevel (widget);
+
+ gb_button_get_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ gb_widget_output_bool (data, State, data->widget_data->flags & GLADE_ACTIVE);
+
+ gb_widget_output_bool (data, Inconsistent,
+ GTK_TOGGLE_BUTTON (widget)->inconsistent);
+
+ gb_widget_output_bool (data, Indicator,
+ GTK_TOGGLE_BUTTON (widget)->draw_indicator);
+
+ /* If we're showing we need to display the list of groups to choose from.
+ We walk the tree of widgets in this component, and if a widget is
+ a radio button, we see if it has a group and if it is already in the
+ list and if not we add it. */
+ if (data->action == GB_SHOWING)
+ {
+ GladeFindGroupsData find_groups_data;
+
+ find_groups_data.groups_found = NULL;
+ find_groups_data.group_names = NULL;
+ get_radio_button_groups (component, &find_groups_data);
+
+ find_groups_data.group_names = g_list_prepend (find_groups_data.group_names,
+ _("New Group"));
+ property_set_combo_strings (Group, find_groups_data.group_names);
+
+ g_list_free (find_groups_data.groups_found);
+ g_list_free (find_groups_data.group_names);
+
+ /*property_set_visible (Indicator, !is_toolbar_button);*/
+ }
+
+ find_data.group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ find_data.found_widget = NULL;
+ gb_button_find_radio_group (component, &find_data);
+
+ if (find_data.found_widget)
+ {
+ /* If we are saving, we don't output the group if this widget is the
+ first widget in the group. */
+ if (data->action == GB_SHOWING || find_data.found_widget != widget)
+ {
+ const char *name;
+ name = gtk_widget_get_name (find_data.found_widget);
+ gb_widget_output_combo (data, Group, name);
+ }
+ }
+ else
+ {
+ g_warning ("Radiobutton has no group");
+ gb_widget_output_combo (data, Group, "");
+ }
+}
+
+
+/* Note that this must walk the widget tree in exactly the same way that we
+ save the widgets, so we know which widget in the group will be the first
+ output. */
+static void
+get_radio_button_groups (GtkWidget * widget, GladeFindGroupsData *find_data)
+{
+ if (GTK_IS_RADIO_BUTTON (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ GSList *group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+
+ /* See if we've already found a widget in this group. */
+ if (!g_list_find (find_data->groups_found, group))
+ {
+ const char *name = gtk_widget_get_name (GTK_WIDGET (widget));
+
+ /* Remember that we've already seen this group. */
+ find_data->groups_found = g_list_prepend (find_data->groups_found,
+ group);
+
+ /* Add the widget's name to the list. */
+ find_data->group_names = g_list_insert_sorted (find_data->group_names, (char*)name, (GCompareFunc) g_utf8_collate);
+ }
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ gb_widget_children_foreach (widget, (GtkCallback) get_radio_button_groups,
+ find_data);
+}
+
+
+/* This tries to ensure that one and only one radio button in the given
+ group is selected. It's used because GtkRadioButton doesn't handle this
+ when groups are changed. */
+void
+gb_radio_button_update_radio_group (GSList * group)
+{
+ GtkRadioButton *button;
+ GSList *slist;
+ gboolean found_selected = FALSE;
+
+ if (group == NULL)
+ return;
+
+ for (slist = group; slist; slist = slist->next)
+ {
+ button = GTK_RADIO_BUTTON (slist->data);
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ {
+ if (found_selected)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+ else
+ found_selected = TRUE;
+ }
+ }
+ /* If none are currently selected, select the first. */
+ if (!found_selected)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (group->data), TRUE);
+}
+
+
+/* This recursively steps though a complete component's hierarchy to find
+ a radio button with a particular group name set. When found the radio
+ button's group list is returned in find_group_data->group. */
+static void
+find_group_widget (GtkWidget *widget, GladeFindGroupWidgetData *find_data)
+{
+ if (find_data->found_widget)
+ return;
+
+ if (GTK_IS_RADIO_BUTTON (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ if (!strcmp (gtk_widget_get_name (widget), find_data->name))
+ {
+#if 0
+ g_print ("Found widget: %s\n", find_data->name);
+#endif
+ find_data->found_widget = widget;
+ return;
+ }
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ gb_widget_children_foreach (widget, (GtkCallback) find_group_widget,
+ find_data);
+}
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_radio_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean state, indicator, inconsistent;
+ gchar *group_name;
+
+ gb_button_set_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ state = gb_widget_input_bool (data, State);
+ if (data->apply)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), state);
+ if (state)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+
+ inconsistent = gb_widget_input_bool (data, Inconsistent);
+ if (data->apply)
+ gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (widget),
+ inconsistent);
+
+ indicator = gb_widget_input_bool (data, Indicator);
+ if (data->apply)
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (widget), indicator);
+
+ /* Find any widgets in given group and set this widgets group.
+ If group is NULL try to find radiobuttons with same parent and use
+ their group. If these don't succeed, set group to NULL. */
+ group_name = gb_widget_input_combo (data, Group);
+ if (data->apply)
+ {
+ GSList *old_group, *new_group = NULL;
+
+ old_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+
+ if (group_name && (group_name[0] == '\0'
+ || !strcmp (group_name, _("New Group"))))
+ group_name = NULL;
+
+ if (group_name)
+ {
+ GladeFindGroupWidgetData find_data;
+ GtkWidget *component;
+
+ component = glade_util_get_toplevel (widget);
+
+ find_data.name = group_name;
+ find_data.found_widget = NULL;
+ find_group_widget (component, &find_data);
+
+ if (find_data.found_widget)
+ new_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (find_data.found_widget));
+ else if (data->action == GB_LOADING)
+ g_warning ("Invalid radio group: %s\n (Note that forward references are not allowed in Glade files)", group_name);
+ }
+
+#if 0
+ g_print ("New Group: %p Old Group: %p\n", new_group, old_group);
+#endif
+
+ if (new_group != old_group)
+ {
+#if 0
+ g_print ("##### setting radio group: %s\n",
+ group_name ? group_name : "NULL");
+#endif
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (widget), new_group);
+ }
+ }
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_radio_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GladeFindGroupData find_data;
+ GtkWidget *group_widget;
+ gchar buffer[256], *group_name;
+
+ find_data.group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ find_data.found_widget = NULL;
+ gb_button_find_radio_group (glade_util_get_toplevel (widget), &find_data);
+
+ group_widget = find_data.found_widget;
+ if (!group_widget)
+ {
+ g_warning ("Radiobutton has no group");
+ group_widget = widget;
+ }
+
+ gb_button_write_standard_source (widget, data, Label);
+
+ /* Make sure the temporary group list variable is declared. */
+ group_name = (char*) gtk_widget_get_name (group_widget);
+ group_name = source_create_valid_identifier (group_name);
+ sprintf (buffer, " GSList *%s_group = NULL;\n", group_name);
+ source_ensure_decl (data, buffer);
+
+ source_add (data,
+ " gtk_radio_button_set_group (GTK_RADIO_BUTTON (%s), %s_group);\n",
+ data->wname, group_name);
+ source_add (data,
+ " %s_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (%s));\n",
+ group_name, data->wname);
+ g_free (group_name);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (GTK_TOGGLE_BUTTON (widget)->inconsistent)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!GTK_TOGGLE_BUTTON (widget)->draw_indicator)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_radio_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_radio_button_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = radiobutton_xpm;
+ gbwidget.tooltip = _("Radio Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_radio_button_new;
+ gbwidget.gb_widget_create_properties = gb_radio_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_radio_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_radio_button_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_button_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_radio_button_write_source;
+ gbwidget.gb_widget_destroy = gb_button_destroy;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbradiomenuitem.c b/tools/glade/glade/gbwidgets/gbradiomenuitem.c
new file mode 100644
index 00000000..7a9b4348
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbradiomenuitem.c
@@ -0,0 +1,399 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkradiomenuitem.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/radiomenuitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Label = "RadioMenuItem|GtkItem::label";
+static gchar *State = "RadioMenuItem|GtkCheckMenuItem::active";
+static gchar *Group = "GtkRadioMenuItem::group";
+
+
+typedef struct _GladeFindGroupWidgetData GladeFindGroupWidgetData;
+struct _GladeFindGroupWidgetData {
+ gchar *name;
+ GtkWidget *found_widget;
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+static void
+find_parents_group (GtkWidget * widget, GSList ** group)
+{
+ /* If a group has already been found, return. */
+ if (*group)
+ return;
+
+ if (GTK_IS_RADIO_MENU_ITEM (widget))
+ {
+ *group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
+ }
+}
+
+
+/*
+ * Creates a new GtkWidget of class GtkRadioMenuItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_radio_menu_item_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ GSList *group_list = NULL;
+
+ /* When creating a radiomenuitem we try to place it in the same group as
+ other radiomenuitems with the same parent. */
+ if (data->parent && data->action == GB_CREATING)
+ gtk_container_foreach (GTK_CONTAINER (data->parent),
+ (GtkCallback) find_parents_group, &group_list);
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_radio_menu_item_new_with_label (group_list, data->name);
+ else
+ new_widget = gtk_radio_menu_item_new (group_list);
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_radio_menu_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData
+ * data)
+{
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_bool (State, _("Initially On:"),
+ _("If the radio menu item is initially on"));
+ property_add_combo (Group, _("Group:"),
+ _("The radio menu item group (the default is all radio menu items with the same parent)"),
+ NULL);
+ /* The Group property is only used for loading and saving at present. */
+ property_set_visible (Group, FALSE);
+}
+
+
+
+void
+gb_radio_menu_item_find_radio_group (GtkWidget *widget,
+ GladeFindGroupData *find_data)
+{
+ if (find_data->found_widget)
+ return;
+
+ if (GTK_IS_RADIO_MENU_ITEM (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ if (gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget)) == find_data->group)
+ {
+ find_data->found_widget = widget;
+ return;
+ }
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ gb_widget_children_foreach (widget,
+ (GtkCallback) gb_radio_menu_item_find_radio_group,
+ find_data);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_radio_menu_item_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_child_label (widget, data, Label);
+
+ gb_widget_output_bool (data, State, data->widget_data->flags & GLADE_ACTIVE);
+
+ /* We only output the group when saving, for now. */
+ if (data->action == GB_SAVING)
+ {
+ GladeFindGroupData find_data;
+ GtkWidget *component;
+
+ component = glade_util_get_toplevel (widget);
+
+ find_data.group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
+ find_data.found_widget = NULL;
+ gb_radio_menu_item_find_radio_group (component, &find_data);
+
+ if (find_data.found_widget)
+ {
+ /* We don't output the group if this widget is the first widget in
+ the group. */
+ if (find_data.found_widget != widget)
+ {
+ const char *name;
+ name = gtk_widget_get_name (find_data.found_widget);
+ gb_widget_output_combo (data, Group, name);
+ }
+ }
+ }
+}
+
+
+/* This recursively steps though a complete component's hierarchy to find
+ a radio button with a particular group name set. When found the radio
+ button's group list is returned in find_group_data->group. */
+static void
+find_group_widget (GtkWidget *widget, GladeFindGroupWidgetData *find_data)
+{
+ if (find_data->found_widget)
+ return;
+
+ if (GTK_IS_RADIO_MENU_ITEM (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ if (!strcmp (gtk_widget_get_name (widget), find_data->name))
+ {
+#if 0
+ g_print ("Found widget: %s\n", find_data->name);
+#endif
+ find_data->found_widget = widget;
+ return;
+ }
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ gb_widget_children_foreach (widget, (GtkCallback) find_group_widget,
+ find_data);
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_radio_menu_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean state;
+
+ gb_widget_input_child_label (widget, data, Label);
+
+ state = gb_widget_input_bool (data, State);
+ if (data->apply)
+ {
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), state);
+ if (state)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+
+ /* We only set the group when loading, for now. */
+ if (data->action == GB_LOADING)
+ {
+ gchar *group_name;
+
+ /* Find any widgets in given group and set this widgets group.
+ If group is NULL try to find radiomenuitems with same parent and use
+ their group. If these don't succeed, set group to NULL. */
+ group_name = gb_widget_input_combo (data, Group);
+ if (data->apply)
+ {
+ GSList *old_group, *new_group = NULL;
+
+ old_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
+
+ if (group_name && group_name[0] == '\0')
+ group_name = NULL;
+
+ if (group_name)
+ {
+ GladeFindGroupWidgetData find_data;
+ GtkWidget *component;
+
+ component = glade_util_get_toplevel (widget);
+
+ find_data.name = group_name;
+ find_data.found_widget = NULL;
+ find_group_widget (component, &find_data);
+
+ if (find_data.found_widget)
+ new_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (find_data.found_widget));
+ else if (data->action == GB_LOADING)
+ g_warning ("Invalid radio group: %s\n (Note that forward references are not allowed in Glade files)", group_name);
+ }
+
+ if (new_group != old_group)
+ {
+#if 0
+ g_print ("##### setting radio group: %s\n",
+ group_name ? group_name : "NULL");
+#endif
+ gtk_radio_menu_item_set_group (GTK_RADIO_MENU_ITEM (widget),
+ new_group);
+ }
+ }
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkRadioMenuItem, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_radio_menu_item_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData
+ * data)
+{
+ /* Add command to remove child label. */
+#if 0
+ gb_widget_create_child_label_popup_menu (widget, data);
+#endif
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_radio_menu_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData *
+ data)
+{
+ GladeFindGroupData find_data;
+ GtkWidget *group_widget;
+ GtkWidget *child = GTK_BIN (widget)->child;
+ gchar buffer[256], *group_name, *label_text;
+ gboolean translatable, context;
+ gchar *comments;
+
+#ifdef USE_GNOME
+ if (data->project->gnome_support)
+ {
+ glade_gnome_write_menu_item_source (GTK_MENU_ITEM (widget), data);
+ return;
+ }
+#endif
+
+ find_data.group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
+ find_data.found_widget = NULL;
+ gb_radio_menu_item_find_radio_group (glade_util_get_toplevel (widget),
+ &find_data);
+
+ group_widget = find_data.found_widget;
+ if (!group_widget)
+ {
+ g_warning ("Radiobutton has no group");
+ group_widget = widget;
+ }
+
+ if (data->create_widget)
+ {
+ /* Make sure the temporary group list variable is declared. */
+ group_name = (char*) gtk_widget_get_name (group_widget);
+ group_name = source_create_valid_identifier (group_name);
+ sprintf (buffer, " GSList *%s_group = NULL;\n", group_name);
+ source_ensure_decl (data, buffer);
+
+ if (child && GTK_IS_LABEL (child) && !GB_IS_GB_WIDGET (child))
+ {
+ label_text = glade_util_get_label_text (child);
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " %s = gtk_radio_menu_item_new_with_mnemonic (%s_group, %s);\n",
+ data->wname, group_name,
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ g_free (label_text);
+ }
+ else
+ {
+ source_add (data, " %s = gtk_radio_menu_item_new (%s_group);\n",
+ data->wname, group_name);
+ }
+ source_add (data,
+ " %s_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (%s));\n",
+ group_name, data->wname);
+ g_free (group_name);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_radio_menu_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_radio_menu_item_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = radiomenuitem_xpm;
+ gbwidget.tooltip = _("Radio Menu Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_radio_menu_item_new;
+ gbwidget.gb_widget_create_properties = gb_radio_menu_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_radio_menu_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_radio_menu_item_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_radio_menu_item_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_radio_menu_item_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbradiotoolbutton.c b/tools/glade/glade/gbwidgets/gbradiotoolbutton.c
new file mode 100644
index 00000000..95faf681
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbradiotoolbutton.c
@@ -0,0 +1,545 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/radiotoolbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "GtkRadioToolButton|GtkToolButton::stock_id";
+static gchar *Label = "GtkRadioToolButton|GtkToolButton::label";
+static gchar *Icon = "GtkRadioToolButton|GtkToolButton::icon";
+static gchar *VisibleHorz = "GtkRadioToolButton|GtkToolItem::visible_horizontal";
+static gchar *VisibleVert = "GtkRadioToolButton|GtkToolItem::visible_vertical";
+static gchar *IsImportant = "GtkRadioToolButton|GtkToolItem::is_important";
+
+static gchar *Group = "GtkRadioToolButton::group";
+static gchar *Active = "GtkRadioToolButton|GtkToggleToolButton::active";
+
+
+typedef struct _GladeFindGroupsData GladeFindGroupsData;
+struct _GladeFindGroupsData {
+ GList *groups_found;
+ GList *group_names;
+};
+
+
+typedef struct _GladeFindGroupWidgetData GladeFindGroupWidgetData;
+struct _GladeFindGroupWidgetData {
+ gchar *name;
+ GtkWidget *found_widget;
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+static void
+find_parents_group (GtkWidget * widget, GSList ** group)
+{
+ /* If a group has already been found, return. */
+ if (*group)
+ return;
+
+ if (GTK_IS_RADIO_TOOL_BUTTON (widget))
+ *group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (widget));
+}
+
+
+/*
+ * Creates a new GtkWidget of class GtkRadioToolButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_radio_tool_button_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *image;
+ GbWidget *pixmap_gbwidget;
+ GSList *group_list = NULL;
+
+ /* When creating a radiotoolbutton we try to place it in the same group
+ as other radiotoolbuttons in the same toolbar. */
+ if (data->action == GB_CREATING)
+ {
+ GtkWidget *parent = data->parent;
+ while (parent && !GTK_IS_TOOLBAR (parent))
+ parent = parent->parent;
+ if (parent)
+ gb_widget_children_foreach (parent,
+ (GtkCallback) find_parents_group,
+ &group_list);
+ }
+
+ /* Place the pixmap icon in the button initially (even when loading). */
+ pixmap_gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (pixmap_gbwidget)
+ {
+ image = gtk_image_new_from_pixmap (pixmap_gbwidget->gdkpixmap,
+ pixmap_gbwidget->mask);
+ }
+ else
+ {
+ image = gtk_image_new ();
+ g_warning ("Couldn't find GtkPixmap data");
+ }
+ gtk_widget_show (image);
+
+ new_widget = (GtkWidget*) gtk_radio_tool_button_new (group_list);
+
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (new_widget), "");
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (new_widget), image);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_radio_tool_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ GtkWidget *combo;
+
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+ property_add_combo (Group, _("Group:"),
+ _("The radio tool button group (the default is all radio tool buttons in the toolbar)"),
+ NULL);
+ combo = property_get_value_widget (Group);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE);
+
+ property_add_bool (Active, _("Initially On:"),
+ _("If the radio button is initially on"));
+
+ property_add_bool (VisibleHorz, _("Show Horizontal:"),
+ _("If the item is visible when the toolbar is horizontal"));
+ property_add_bool (VisibleVert, _("Show Vertical:"),
+ _("If the item is visible when the toolbar is vertical"));
+ property_add_bool (IsImportant, _("Is Important:"),
+ _("If the item's text should be shown when the toolbar's mode is GTK_TOOLBAR_BOTH_HORIZ"));
+}
+
+
+/* Note that this must walk the widget tree in exactly the same way that we
+ save the widgets, so we know which widget in the group will be the first
+ output. */
+static void
+get_radio_button_groups (GtkWidget * widget, GladeFindGroupsData *find_data)
+{
+ if (GTK_IS_RADIO_TOOL_BUTTON (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ GSList *group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (widget));
+
+ /* See if we've already found a widget in this group. */
+ if (!g_list_find (find_data->groups_found, group))
+ {
+ const char *name = gtk_widget_get_name (GTK_WIDGET (widget));
+
+ /* Remember that we've already seen this group. */
+ find_data->groups_found = g_list_prepend (find_data->groups_found,
+ group);
+
+ /* Add the widget's name to the list. */
+ find_data->group_names = g_list_insert_sorted (find_data->group_names, (char*)name, (GCompareFunc) g_utf8_collate);
+ }
+ }
+}
+
+
+static void
+find_radio_group (GtkWidget *widget, GladeFindGroupData *find_data)
+{
+ if (find_data->found_widget)
+ return;
+
+ if (GTK_IS_RADIO_TOOL_BUTTON (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ if (gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (widget)) == find_data->group)
+ {
+ find_data->found_widget = widget;
+ }
+ }
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_radio_tool_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GladeFindGroupData find_data;
+
+ gb_tool_button_get_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+
+ gb_widget_output_bool (data, Active,
+ data->widget_data->flags & GLADE_ACTIVE);
+
+ /* If we're showing we need to display the list of groups to choose from.
+ We walk the tree of widgets in this component, and if a widget is
+ a radio button, we see if it has a group and if it is already in the
+ list and if not we add it. */
+ if (data->action == GB_SHOWING)
+ {
+ GladeFindGroupsData find_groups_data;
+
+ find_groups_data.groups_found = NULL;
+ find_groups_data.group_names = NULL;
+ gb_widget_children_foreach (widget->parent,
+ (GtkCallback) get_radio_button_groups,
+ &find_groups_data);
+
+ find_groups_data.group_names = g_list_prepend (find_groups_data.group_names,
+ _("New Group"));
+ property_set_combo_strings (Group, find_groups_data.group_names);
+
+ g_list_free (find_groups_data.groups_found);
+ g_list_free (find_groups_data.group_names);
+ }
+
+ find_data.group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (widget));
+ find_data.found_widget = NULL;
+ gb_widget_children_foreach (widget->parent,
+ (GtkCallback) find_radio_group,
+ &find_data);
+
+ if (find_data.found_widget)
+ {
+ /* If we are saving, we don't output the group if this widget is the
+ first widget in the group. */
+ if (data->action == GB_SHOWING || find_data.found_widget != widget)
+ {
+ const char *name;
+ name = gtk_widget_get_name (find_data.found_widget);
+ gb_widget_output_combo (data, Group, name);
+ }
+ }
+ else
+ {
+ g_warning ("Radiotoolbutton has no group");
+ gb_widget_output_combo (data, Group, "");
+ }
+}
+
+
+
+static void
+find_group_widget (GtkWidget *widget, GladeFindGroupWidgetData *find_data)
+{
+ if (find_data->found_widget)
+ return;
+
+ if (GTK_IS_RADIO_TOOL_BUTTON (widget) && GB_IS_GB_WIDGET (widget))
+ {
+ if (!strcmp (gtk_widget_get_name (widget), find_data->name))
+ {
+#if 0
+ g_print ("Found widget: %s\n", find_data->name);
+#endif
+ find_data->found_widget = widget;
+ }
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_radio_tool_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean active;
+ gchar *group_name;
+
+ gb_tool_button_set_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+
+ active = gb_widget_input_bool (data, Active);
+ if (data->apply)
+ {
+ gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (widget),
+ active);
+ if (active)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+
+ /* Find any widgets in given group and set this widgets group.
+ If group is NULL try to find radiobuttons with same parent and use
+ their group. If these don't succeed, set group to NULL. */
+ group_name = gb_widget_input_combo (data, Group);
+ if (data->apply)
+ {
+ GSList *old_group, *new_group = NULL;
+
+ old_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (widget));
+
+ if (group_name && (group_name[0] == '\0'
+ || !strcmp (group_name, _("New Group"))))
+ group_name = NULL;
+
+ if (group_name)
+ {
+ GladeFindGroupWidgetData find_data;
+
+ find_data.name = group_name;
+ find_data.found_widget = NULL;
+ gb_widget_children_foreach (widget->parent,
+ (GtkCallback) find_group_widget,
+ &find_data);
+
+ if (find_data.found_widget)
+ new_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (find_data.found_widget));
+ else if (data->action == GB_LOADING)
+ g_warning ("Invalid radio group: %s\n (Note that forward references are not allowed in Glade files)", group_name);
+ }
+
+#if 0
+ g_print ("New Group: %p Old Group: %p\n", new_group, old_group);
+#endif
+
+ if (new_group != old_group)
+ {
+#if 0
+ g_print ("##### setting radio group: %s\n",
+ group_name ? group_name : "NULL");
+#endif
+ gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (widget),
+ new_group);
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkRadioToolButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_radio_tool_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_radio_tool_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GladeFindGroupData find_data;
+ GtkWidget *group_widget;
+ gchar *stock_id, *label, *icon_name;
+ gchar buffer[256], *group_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey);
+ icon_name = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ label = (gchar*) gtk_tool_button_get_label (GTK_TOOL_BUTTON (widget));
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+
+ find_data.group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (widget));
+ find_data.found_widget = NULL;
+ gb_widget_children_foreach (widget->parent,
+ (GtkCallback) find_radio_group,
+ &find_data);
+
+ group_widget = find_data.found_widget;
+ if (!group_widget)
+ {
+ g_warning ("Radiotoolbutton has no group");
+ group_widget = widget;
+ }
+ group_name = (char*) gtk_widget_get_name (group_widget);
+ group_name = source_create_valid_identifier (group_name);
+ sprintf (buffer, " GSList *%s_group = NULL;\n", group_name);
+ source_ensure_decl (data, buffer);
+
+ if (data->create_widget)
+ {
+ if (stock_id)
+ {
+ /* Stock Button */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_radio_tool_button_new_from_stock (NULL, %s);\n",
+ data->wname, source_make_string (stock_id, FALSE));
+ }
+ else if (icon_name)
+ {
+ /* Icon and Label */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_radio_tool_button_new (NULL);\n",
+ data->wname);
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_tool_button_set_label (GTK_TOOL_BUTTON (%s), %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+
+ source_ensure_decl (data, " GtkWidget *tmp_image;\n");
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ source_add (data,
+ " tmp_image = gtk_image_new_from_stock (\"%s\", tmp_toolbar_icon_size);\n",
+ icon_name);
+ }
+ else
+ {
+ source_create_pixmap (data, "tmp_image", icon_name);
+ }
+
+ source_add (data, " gtk_widget_show (tmp_image);\n");
+
+ source_add (data,
+ " gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (%s), tmp_image);\n",
+ data->wname);
+ }
+ else
+ {
+ /* Just a Label */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_radio_tool_button_new (NULL);\n",
+ data->wname);
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_tool_button_set_label (GTK_TOOL_BUTTON (%s), %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ source_add (data,
+ " gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (%s), %s_group);\n",
+ data->wname, group_name);
+ source_add (data,
+ " %s_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (%s));\n",
+ group_name, data->wname);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleVert) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)))
+ {
+ source_add (data,
+ " gtk_tool_item_set_is_important (GTK_TOOL_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+
+ g_free (group_name);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_radio_tool_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_radio_tool_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = radiotoolbutton_xpm;
+ gbwidget.tooltip = _("Toolbar Radio Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_radio_tool_button_new;
+ gbwidget.gb_widget_create_properties = gb_radio_tool_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_radio_tool_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_radio_tool_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_radio_tool_button_write_source;
+ gbwidget.gb_widget_destroy = gb_tool_button_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_radio_tool_button_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbscrolledwindow.c b/tools/glade/glade/gbwidgets/gbscrolledwindow.c
new file mode 100644
index 00000000..566a5120
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbscrolledwindow.c
@@ -0,0 +1,366 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkscrolledwindow.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/scrolledwindow.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HPolicy = "GtkScrolledWindow::hscrollbar_policy";
+static gchar *VPolicy = "GtkScrolledWindow::vscrollbar_policy";
+
+static gchar *WindowPlacement = "GtkScrolledWindow::window_placement";
+static gchar *ShadowType = "GtkScrolledWindow::shadow_type";
+
+/* I don't think there's any point in adding these. */
+/*
+ static gchar *HValues[] = {
+ "GtkScrolledWindow::hvalue",
+ "GtkScrolledWindow::hlower",
+ "GtkScrolledWindow::hupper",
+ "GtkScrolledWindow::hstep",
+ "GtkScrolledWindow::hpage",
+ "GtkScrolledWindow::hpage_size",
+ };
+
+ static gchar *VValues[] = {
+ "GtkScrolledWindow::vvalue",
+ "GtkScrolledWindow::vlower",
+ "GtkScrolledWindow::vupper",
+ "GtkScrolledWindow::vstep",
+ "GtkScrolledWindow::vpage",
+ "GtkScrolledWindow::vpage_size",
+ };
+ */
+
+
+static const gchar *GbPolicyChoices[] =
+{
+ "Always",
+ "Automatic",
+ "Never",
+ NULL
+};
+static const gint GbPolicyValues[] =
+{
+ GTK_POLICY_ALWAYS,
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_NEVER
+};
+static const gchar *GbPolicySymbols[] =
+{
+ "GTK_POLICY_ALWAYS",
+ "GTK_POLICY_AUTOMATIC",
+ "GTK_POLICY_NEVER"
+};
+
+/* These aren't really useful so we'll remove them. They should be in the
+ scrollbar internal children anyway. */
+/*
+static const gchar *GbUpdatePolicyChoices[] =
+{"Continuous", "Discontinuous",
+ "Delayed", NULL};
+static const gint GbUpdatePolicyValues[] =
+{
+ GTK_UPDATE_CONTINUOUS,
+ GTK_UPDATE_DISCONTINUOUS,
+ GTK_UPDATE_DELAYED
+};
+static const gchar *GbUpdatePolicySymbols[] =
+{
+ "GTK_UPDATE_CONTINUOUS",
+ "GTK_UPDATE_DISCONTINUOUS",
+ "GTK_UPDATE_DELAYED"
+};
+*/
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkScrolledWindow, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_scrolled_window_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_scrolled_window_new (NULL, NULL);
+ if (data->action != GB_LOADING)
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_scrolled_window_create_properties (GtkWidget * widget, GbWidgetCreateArgData
+ * data)
+{
+ property_add_choice (HPolicy, _("H Policy:"),
+ _("When the horizontal scrollbar will be shown"),
+ GbPolicyChoices);
+ property_add_choice (VPolicy, _("V Policy:"),
+ _("When the vertical scrollbar will be shown"),
+ GbPolicyChoices);
+ property_add_choice (WindowPlacement, _("Window Pos:"),
+ _("Where the child window is located with respect to the scrollbars"),
+ GladeCornerChoices);
+ property_add_choice (ShadowType, _("Shadow Type:"),
+ _("The update policy of the vertical scrollbar"),
+ GladeShadowChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_scrolled_window_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_SCROLLED_WINDOW (widget)->hscrollbar_policy)
+ gb_widget_output_choice (data, HPolicy, i, GbPolicySymbols[i]);
+ }
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_SCROLLED_WINDOW (widget)->vscrollbar_policy)
+ gb_widget_output_choice (data, VPolicy, i, GbPolicySymbols[i]);
+ }
+
+ for (i = 0; i < GladeShadowChoicesSize; i++)
+ {
+ if (GladeShadowValues[i] == GTK_SCROLLED_WINDOW (widget)->shadow_type)
+ gb_widget_output_choice (data, ShadowType, i, GladeShadowSymbols[i]);
+ }
+
+ for (i = 0; i < GladeCornerChoicesSize; i++)
+ {
+ if (GladeCornerValues[i] == GTK_SCROLLED_WINDOW (widget)->window_placement)
+ gb_widget_output_choice (data, WindowPlacement, i,
+ GladeCornerSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_scrolled_window_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint i;
+ gchar *hpolicy, *vpolicy;
+ gboolean set_policy = FALSE;
+ GtkPolicyType hpolicy_value = GTK_POLICY_AUTOMATIC;
+ GtkPolicyType vpolicy_value = GTK_POLICY_AUTOMATIC;
+ gchar *shadow, *placement;
+
+ hpolicy = gb_widget_input_choice (data, HPolicy);
+ if (data->apply)
+ {
+ set_policy = TRUE;
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]);
+ i++)
+ {
+ if (!strcmp (hpolicy, GbPolicyChoices[i])
+ || !strcmp (hpolicy, GbPolicySymbols[i]))
+ hpolicy_value = GbPolicyValues[i];
+ }
+ }
+ else
+ hpolicy_value = GTK_SCROLLED_WINDOW (widget)->hscrollbar_policy;
+
+ vpolicy = gb_widget_input_choice (data, VPolicy);
+ if (data->apply)
+ {
+ set_policy = TRUE;
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]);
+ i++)
+ {
+ if (!strcmp (vpolicy, GbPolicyChoices[i])
+ || !strcmp (vpolicy, GbPolicySymbols[i]))
+ vpolicy_value = GbPolicyValues[i];
+ }
+ }
+ else
+ vpolicy_value = GTK_SCROLLED_WINDOW (widget)->vscrollbar_policy;
+
+ if (set_policy)
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget),
+ hpolicy_value, vpolicy_value);
+
+ shadow = gb_widget_input_choice (data, ShadowType);
+ if (data->apply)
+ {
+ for (i = 0; i < GladeShadowChoicesSize; i++)
+ {
+ if (!strcmp (shadow, GladeShadowChoices[i])
+ || !strcmp (shadow, GladeShadowSymbols[i]))
+ {
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget), GladeShadowValues[i]);
+ break;
+ }
+ }
+ }
+
+ placement = gb_widget_input_choice (data, WindowPlacement);
+ if (data->apply)
+ {
+ for (i = 0; i < GladeCornerChoicesSize; i++)
+ {
+ if (!strcmp (placement, GladeCornerChoices[i])
+ || !strcmp (placement, GladeCornerSymbols[i]))
+ {
+ gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (widget),
+ GladeCornerValues[i]);
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkScrolledWindow, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_scrolled_window_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_scrolled_window_write_source (GtkWidget * widget, GbWidgetWriteSourceData *
+ data)
+{
+ const gchar *hpolicy = GbPolicySymbols[0], *vpolicy = GbPolicySymbols[0];
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_scrolled_window_new (NULL, NULL);\n",
+ data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_SCROLLED_WINDOW (widget)->hscrollbar_policy != GTK_POLICY_ALWAYS
+ || GTK_SCROLLED_WINDOW (widget)->vscrollbar_policy != GTK_POLICY_ALWAYS)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues)
+ / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_SCROLLED_WINDOW (widget)->hscrollbar_policy)
+ hpolicy = GbPolicySymbols[i];
+ if (GbPolicyValues[i] == GTK_SCROLLED_WINDOW (widget)->vscrollbar_policy)
+ vpolicy = GbPolicySymbols[i];
+ }
+ source_add (data, " gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (%s), %s, %s);\n",
+ data->wname, hpolicy, vpolicy);
+ }
+
+ if (GTK_SCROLLED_WINDOW (widget)->shadow_type != GTK_SHADOW_NONE)
+ {
+ for (i = 0; i < GladeShadowChoicesSize; i++)
+ {
+ if (GladeShadowValues[i] == GTK_SCROLLED_WINDOW (widget)->shadow_type)
+ source_add (data, " gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (%s), %s);\n",
+ data->wname, GladeShadowSymbols[i]);
+ }
+ }
+
+ if (GTK_SCROLLED_WINDOW (widget)->window_placement != GTK_CORNER_TOP_LEFT)
+ {
+ for (i = 0; i < GladeCornerChoicesSize; i++)
+ {
+ if (GladeCornerValues[i] == GTK_SCROLLED_WINDOW (widget)->window_placement)
+ source_add (data, " gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (%s), %s);\n",
+ data->wname, GladeCornerSymbols[i]);
+ }
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_scrolled_window_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_scrolled_window_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = scrolledwindow_xpm;
+ gbwidget.tooltip = _("Scrolled Window");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_scrolled_window_new;
+ gbwidget.gb_widget_create_properties = gb_scrolled_window_create_properties;
+ gbwidget.gb_widget_get_properties = gb_scrolled_window_get_properties;
+ gbwidget.gb_widget_set_properties = gb_scrolled_window_set_properties;
+ gbwidget.gb_widget_write_source = gb_scrolled_window_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_scrolled_window_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbseparatormenuitem.c b/tools/glade/glade/gbwidgets/gbseparatormenuitem.c
new file mode 100644
index 00000000..be4c1fbf
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbseparatormenuitem.c
@@ -0,0 +1,166 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkseparatormenuitem.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/menuitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkSeparatorMenuItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_separator_menu_item_new(GbWidgetNewData *data)
+{
+ return gtk_separator_menu_item_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+ static void
+ gb_separator_menu_item_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+ static void
+ gb_separator_menu_item_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+ static void
+ gb_separator_menu_item_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkSeparatorMenuItem, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_separator_menu_item_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_separator_menu_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+#ifdef USE_GNOME
+ if (data->project->gnome_support)
+ {
+ glade_gnome_write_menu_item_source (GTK_MENU_ITEM (widget), data);
+ return;
+ }
+#endif
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_separator_menu_item_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_separator_menu_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_separator_menu_item_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = menuitem_xpm;
+ gbwidget.tooltip = _("Separator for Menus");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_separator_menu_item_new;
+/*
+ gbwidget.gb_widget_create_properties = gb_separator_menu_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_separator_menu_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_separator_menu_item_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_separator_menu_item_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_separator_menu_item_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbseparatortoolitem.c b/tools/glade/glade/gbwidgets/gbseparatortoolitem.c
new file mode 100644
index 00000000..038eea37
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbseparatortoolitem.c
@@ -0,0 +1,218 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/separatortoolitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Draw = "GtkSeparatorToolItem::draw";
+static gchar *VisibleHorz = "GtkSeparatorToolItem|GtkToolItem::visible_horizontal";
+static gchar *VisibleVert = "GtkSeparatorToolItem|GtkToolItem::visible_vertical";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkSeparatorToolItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_separator_tool_item_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_separator_tool_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Draw, _("Draw:"),
+ _("If the separator is drawn, or just blank"));
+ property_add_bool (VisibleHorz, _("Show Horizontal:"),
+ _("If the item is visible when the toolbar is horizontal"));
+ property_add_bool (VisibleVert, _("Show Vertical:"),
+ _("If the item is visible when the toolbar is vertical"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_separator_tool_item_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, Draw,
+ gtk_separator_tool_item_get_draw (GTK_SEPARATOR_TOOL_ITEM (widget)));
+
+ gb_widget_output_bool (data, VisibleHorz,
+ gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz)
+ != NULL ? FALSE : TRUE);
+
+ gb_widget_output_bool (data, VisibleVert,
+ gtk_object_get_data (GTK_OBJECT (widget), VisibleVert)
+ != NULL ? FALSE : TRUE);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_separator_tool_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean draw, visible_horz, visible_vert;
+
+ draw = gb_widget_input_bool (data, Draw);
+ if (data->apply)
+ {
+ gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (widget),
+ draw);
+ }
+
+ visible_horz = gb_widget_input_bool (data, VisibleHorz);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), VisibleHorz,
+ visible_horz ? NULL : "FALSE");
+ }
+
+ visible_vert = gb_widget_input_bool (data, VisibleVert);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), VisibleVert,
+ visible_vert ? NULL : "FALSE");
+ }
+
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkSeparatorToolItem, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_separator_tool_item_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_separator_tool_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = (GtkWidget*) gtk_separator_tool_item_new ();\n",
+ data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!gtk_separator_tool_item_get_draw (GTK_SEPARATOR_TOOL_ITEM (widget)))
+ {
+ source_add (data,
+ " gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleVert) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_separator_tool_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_separator_tool_item_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = separatortoolitem_xpm;
+ gbwidget.tooltip = _("Toolbar Separator Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_separator_tool_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_separator_tool_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_separator_tool_item_set_properties;
+ gbwidget.gb_widget_write_source = gb_separator_tool_item_write_source;
+/*
+ gbwidget.gb_widget_new = gb_separator_tool_item_new;
+ gbwidget.gb_widget_create_popup_menu = gb_separator_tool_item_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbspinbutton.c b/tools/glade/glade/gbwidgets/gbspinbutton.c
new file mode 100644
index 00000000..38c986fc
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbspinbutton.c
@@ -0,0 +1,297 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/spinbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *ClimbRate = "GtkSpinButton::climb_rate";
+static gchar *Digits = "GtkSpinButton::digits";
+static gchar *Numeric = "GtkSpinButton::numeric";
+static gchar *Policy = "GtkSpinButton::update_policy";
+static gchar *Snap = "GtkSpinButton::snap_to_ticks";
+static gchar *Wrap = "GtkSpinButton::wrap";
+
+
+static const gchar *Values[] =
+{
+ "GtkSpinButton::value",
+ "GtkSpinButton::lower",
+ "GtkSpinButton::upper",
+ "GtkSpinButton::step",
+ "GtkSpinButton::page",
+ "GtkSpinButton::page_size",
+};
+
+static const gchar *GbPolicyChoices[] =
+{"Always", "If Valid", NULL};
+static const gint GbPolicyValues[] =
+{
+ GTK_UPDATE_ALWAYS,
+ GTK_UPDATE_IF_VALID
+};
+static const gchar *GbPolicySymbols[] =
+{
+ "GTK_UPDATE_ALWAYS",
+ "GTK_UPDATE_IF_VALID"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkSpinButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_spin_button_new (GbWidgetNewData * data)
+{
+ GtkObject *adjustment = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
+ return gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_spin_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ property_add_float (ClimbRate, _("Climb Rate:"),
+ _("The climb rate of the spinbutton, used in conjunction with the Page Increment"));
+ property_add_int_range (Digits, _("Digits:"),
+ _("The number of decimal digits to show"),
+ 0, 5, 1, 1, 0);
+ property_add_bool (Numeric, _("Numeric:"),
+ _("If only numeric entry is allowed"));
+ property_add_choice (Policy, _("Update Policy:"),
+ _("When value_changed signals are emitted"),
+ GbPolicyChoices);
+ property_add_bool (Snap, _("Snap:"),
+ _("If the value is snapped to multiples of the step increment"));
+ property_add_bool (Wrap, _("Wrap:"),
+ _("If the value is wrapped at the limits"));
+ property_add_adjustment (Values, GB_ADJUST_DEFAULT_LABELS);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_spin_button_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i, update_policy;
+ gb_widget_output_float (data, ClimbRate, GTK_SPIN_BUTTON (widget)->climb_rate);
+ gb_widget_output_int (data, Digits, GTK_SPIN_BUTTON (widget)->digits);
+ gb_widget_output_bool (data, Numeric, GTK_SPIN_BUTTON (widget)->numeric);
+
+ /* This is a slight kludge since the spin_button's update policy is
+ a set of flags rather than integer values */
+ update_policy = GTK_SPIN_BUTTON (widget)->update_policy
+ & (GTK_UPDATE_ALWAYS | GTK_UPDATE_IF_VALID);
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == update_policy)
+ gb_widget_output_choice (data, Policy, i, GbPolicySymbols[i]);
+ }
+ /* In GTK 1.1 snap_to_ticks is given its own variable. */
+ gb_widget_output_bool (data, Snap, GTK_SPIN_BUTTON (widget)->snap_to_ticks);
+
+ gb_widget_output_bool (data, Wrap, GTK_SPIN_BUTTON (widget)->wrap);
+ gb_widget_output_adjustment (data, Values,
+ GTK_SPIN_BUTTON (widget)->adjustment,
+ "adjustment");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_spin_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gfloat climb_rate;
+ gint digits, policy_value = GTK_UPDATE_ALWAYS, i;
+ gchar *policy;
+ gboolean numeric, snap, wrap;
+ GtkAdjustment *adj;
+
+ climb_rate = gb_widget_input_float (data, ClimbRate);
+ /* No set function for this */
+ if (data->apply)
+ GTK_SPIN_BUTTON (widget)->climb_rate = climb_rate;
+
+ digits = gb_widget_input_int (data, Digits);
+ if (data->apply)
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (widget), digits);
+
+ numeric = gb_widget_input_bool (data, Numeric);
+ if (data->apply)
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), numeric);
+
+ snap = gb_widget_input_bool (data, Snap);
+ if (data->apply)
+ gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (widget), snap);
+
+ policy = gb_widget_input_choice (data, Policy);
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (!strcmp (policy, GbPolicyChoices[i])
+ || !strcmp (policy, GbPolicySymbols[i]))
+ {
+ policy_value = GbPolicyValues[i];
+ break;
+ }
+ }
+ if (data->apply)
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (widget), policy_value);
+
+ wrap = gb_widget_input_bool (data, Wrap);
+ if (data->apply)
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), wrap);
+
+ adj = GTK_SPIN_BUTTON (widget)->adjustment;
+ if (gb_widget_input_adjustment (data, Values, adj, "adjustment"))
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkSpinButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_spin_button_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_spin_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint update_policy;
+ GtkAdjustment *adj = GTK_SPIN_BUTTON (widget)->adjustment;
+
+ if (data->create_widget)
+ {
+ source_add_decl (data, " GObject *%s_adj;\n", data->real_wname);
+ source_add (data,
+ " %s_adj = G_OBJECT(gtk_adjustment_new (%.12g, %.12g, %.12g, %.12g, %.12g, %.12g));\n",
+ data->real_wname, adj->value, adj->lower, adj->upper,
+ adj->step_increment, adj->page_increment, adj->page_size);
+ source_add (data,
+ " %s = gtk_spin_button_new (GTK_ADJUSTMENT (%s_adj), %.12g, %d);\n",
+ data->wname, data->real_wname,
+ GTK_SPIN_BUTTON (widget)->climb_rate,
+ GTK_SPIN_BUTTON (widget)->digits);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_SPIN_BUTTON (widget)->numeric)
+ {
+ source_add (data,
+ " gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ update_policy = GTK_SPIN_BUTTON (widget)->update_policy;
+ if (update_policy != GTK_UPDATE_ALWAYS)
+ {
+ source_add (data,
+ " gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (%s), GTK_UPDATE_IF_VALID);\n",
+ data->wname);
+ }
+
+ if (GTK_SPIN_BUTTON (widget)->snap_to_ticks)
+ source_add (data,
+ " gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (%s), TRUE);\n",
+ data->wname);
+
+ if (GTK_SPIN_BUTTON (widget)->wrap)
+ source_add (data,
+ " gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (%s), TRUE);\n",
+ data->wname);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_spin_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_spin_button_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = spinbutton_xpm;
+ gbwidget.tooltip = _("Spin Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_spin_button_new;
+ gbwidget.gb_widget_create_properties = gb_spin_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_spin_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_spin_button_set_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_spin_button_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_spin_button_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbstatusbar.c b/tools/glade/glade/gbwidgets/gbstatusbar.c
new file mode 100644
index 00000000..611c4c7e
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbstatusbar.c
@@ -0,0 +1,169 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkstatusbar.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/statusbar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *ResizeGrip = "GtkStatusbar::has_resize_grip";
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkStatusbar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+ GtkWidget*
+ gb_statusbar_new(GbWidgetNewData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_statusbar_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+{
+ property_add_bool (ResizeGrip, _("Resize Grip:"), _("If the status bar has a resize grip to resize the window"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_statusbar_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+{
+ gb_widget_output_bool (data, ResizeGrip,
+ GTK_STATUSBAR (widget)->has_resize_grip);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_statusbar_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+{
+ gboolean resize_grip;
+
+ resize_grip = gb_widget_input_bool (data, ResizeGrip);
+ if (data->apply)
+ {
+ gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (widget), resize_grip);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkStatusbar, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_statusbar_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_statusbar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_statusbar_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (!GTK_STATUSBAR (widget)->has_resize_grip)
+ {
+ source_add (data,
+ " gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_statusbar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_statusbar_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = statusbar_xpm;
+ gbwidget.tooltip = _("Status Bar");
+
+ /* Fill in any functions that this GbWidget has */
+/*
+ gbwidget.gb_widget_new = gb_statusbar_new;
+ gbwidget.gb_widget_create_popup_menu = gb_statusbar_create_popup_menu;
+ */
+ gbwidget.gb_widget_create_properties = gb_statusbar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_statusbar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_statusbar_set_properties;
+ gbwidget.gb_widget_write_source = gb_statusbar_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbtable.c b/tools/glade/glade/gbwidgets/gbtable.c
new file mode 100644
index 00000000..b5c11afe
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtable.c
@@ -0,0 +1,1223 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtktable.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/table.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static const gchar *Rows = "GtkTable::n_rows";
+static const gchar *Columns = "GtkTable::n_columns";
+static const gchar *Homogeneous = "GtkTable::homogeneous";
+static const gchar *RowSpacing = "GtkTable::row_spacing";
+static const gchar *ColSpacing = "GtkTable::column_spacing";
+
+/* For children of a table */
+static const gchar *GbCellX = "GtkTableChild::cell_x";
+static const gchar *GbCellY = "GtkTableChild::cell_y";
+static const gchar *GbColSpan = "GtkTableChild::col_span";
+static const gchar *GbRowSpan = "GtkTableChild::row_span";
+static const gchar *GbXPad = "GtkTableChild::x_padding";
+static const gchar *GbYPad = "GtkTableChild::y_padding";
+static const gchar *GbXExpand = "GtkTableChild::xexpand";
+static const gchar *GbYExpand = "GtkTableChild::yexpand";
+static const gchar *GbXShrink = "GtkTableChild::xshrink";
+static const gchar *GbYShrink = "GtkTableChild::yshrink";
+static const gchar *GbXFill = "GtkTableChild::xfill";
+static const gchar *GbYFill = "GtkTableChild::yfill";
+
+/* The Expand, Shrink and Fill get merged into one property when saved. */
+static const gchar *GbXOptions = "GtkTableChild::x_options";
+static const gchar *GbYOptions = "GtkTableChild::y_options";
+
+/* These are used to return what is in a table cell */
+#define GB_CELL_EMPTY 1
+#define GB_CELL_WIDGET 2
+#define GB_CELL_PLACEHOLDER 3
+
+static void show_table_dialog (GbWidgetNewData * data);
+static void on_table_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_table_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+static void update_table_size (GtkWidget * table, gint rows, gint cols);
+
+static void gb_table_insert_row_before (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_table_insert_row_after (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_table_insert_column_before (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_table_insert_column_after (GtkWidget * menuitem,
+ GtkWidget * widget);
+static void gb_table_insert_row_or_col (GtkWidget * table, gint row, gint col);
+static void gb_table_delete_row (GtkWidget * menuitem, GtkWidget * widget);
+static void gb_table_delete_column (GtkWidget * menuitem, GtkWidget * widget);
+
+static gint gb_table_is_cell_occupied (GtkWidget * table, gint row, gint col);
+static void gb_table_remove_placeholders (GtkWidget * table,
+ gint row, gint col);
+static void gb_table_split_placeholder (GtkWidget * table,
+ GtkWidget * placeholder,
+ gint left, gint right,
+ gint top, gint bottom,
+ gint skip_row, gint skip_col);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkTable, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_table_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+ gint rows, cols;
+
+ if (data->action == GB_LOADING)
+ {
+ rows = load_int (data->loading_data, Rows);
+ cols = load_int (data->loading_data, Columns);
+ new_widget = gtk_table_new (rows, cols, FALSE);
+ return new_widget;
+ }
+ else
+ {
+ show_table_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_table_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *table, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New table"), data->parent,
+ GTK_SIGNAL_FUNC (on_table_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_table_dialog_destroy), data);
+
+ /* Rows label & entry */
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_widget_show (table);
+
+ label = gtk_label_new (_("Number of rows:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL,
+ 0, 0);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "rows",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 4, 4);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ /* Columns label & entry */
+ label = gtk_label_new (_("Number of columns:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL,
+ 0, 0);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "cols",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 4, 4);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_table_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window;
+ gint rows, cols, row, col;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "rows");
+ g_return_if_fail (spinbutton != NULL);
+ rows = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "cols");
+ g_return_if_fail (spinbutton != NULL);
+ cols = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_table_new (rows, cols, FALSE);
+ for (row = 0; row < rows; row++)
+ {
+ for (col = 0; col < cols; col++)
+ {
+ gtk_table_attach (GTK_TABLE (new_widget),
+ editor_new_placeholder (),
+ col, col + 1, row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+ 0, 0);
+ }
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_table_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_table_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_int_range (Rows, _("Rows:"),
+ _("The number of rows in the table"),
+ 1, 1000, 1, 10, 1);
+ property_add_int_range (Columns, _("Columns:"),
+ _("The number of columns in the table"),
+ 1, 1000, 1, 10, 1);
+ property_add_bool (Homogeneous, _("Homogeneous:"),
+ _("If the children should all be the same size"));
+ property_add_int_range (RowSpacing, _("Row Spacing:"),
+ _("The space between each row"),
+ 0, 1000, 1, 10, 1);
+ property_add_int_range (ColSpacing, _("Col Spacing:"),
+ _("The space between each column"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_table_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_int (data, Rows, GTK_TABLE (widget)->nrows);
+ gb_widget_output_int (data, Columns, GTK_TABLE (widget)->ncols);
+ gb_widget_output_bool (data, Homogeneous, GTK_TABLE (widget)->homogeneous);
+ gb_widget_output_int (data, RowSpacing, GTK_TABLE (widget)->row_spacing);
+ gb_widget_output_int (data, ColSpacing, GTK_TABLE (widget)->column_spacing);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_table_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean homogeneous, update_size = FALSE;
+ gint rows, cols, row_spacing, column_spacing;
+
+ rows = gb_widget_input_int (data, Rows);
+ if (data->apply)
+ update_size = TRUE;
+ else
+ rows = GTK_TABLE (widget)->nrows;
+
+ cols = gb_widget_input_int (data, Columns);
+ if (data->apply)
+ update_size = TRUE;
+ else
+ cols = GTK_TABLE (widget)->ncols;
+
+ if (update_size)
+ update_table_size (widget, rows, cols);
+
+ homogeneous = gb_widget_input_bool (data, Homogeneous);
+ if (data->apply)
+ gtk_table_set_homogeneous (GTK_TABLE (widget), homogeneous);
+
+ row_spacing = gb_widget_input_int (data, RowSpacing);
+ if (data->apply)
+ gtk_table_set_row_spacings (GTK_TABLE (widget), row_spacing);
+
+ column_spacing = gb_widget_input_int (data, ColSpacing);
+ if (data->apply)
+ gtk_table_set_col_spacings (GTK_TABLE (widget), column_spacing);
+}
+
+
+/* This changes the size of the table to the given dimensions. Placeholders
+ are added in empty cells, and widgets are destroyed if they fall outside
+ the new dimensions.
+ NOTE: this changes the table data structures, which we would prefer not to
+ do, but there is no alternative. */
+static void
+update_table_size (GtkWidget * table, gint rows, gint cols)
+{
+ GList *children;
+ GtkTableChild *child;
+
+ g_return_if_fail (rows > 0);
+ g_return_if_fail (cols > 0);
+
+ if (GTK_TABLE (table)->nrows == rows && GTK_TABLE (table)->ncols == cols)
+ return;
+
+ children = GTK_TABLE (table)->children;
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ /* Remove the widget if it doesn't fit into the new dimensions,
+ or crop it if it extends past the edges. */
+ if (child->left_attach >= cols || child->top_attach >= rows)
+ {
+ gtk_container_remove (GTK_CONTAINER (table), child->widget);
+ }
+ else
+ {
+ if (child->right_attach > cols)
+ child->right_attach = cols;
+ if (child->bottom_attach > rows)
+ child->bottom_attach = rows;
+ }
+ }
+
+ /* This is in ../gbwidget.c. It will expand the dimensions if necessary. */
+ gb_table_update_placeholders (table, rows, cols);
+
+ /* This bit is especially naughty. It makes sure the table shrinks,
+ so we don't get extra spacings on the end. */
+ GTK_TABLE (table)->nrows = rows;
+ GTK_TABLE (table)->ncols = cols;
+
+ /* We clear the selection since it isn't displayed properly. */
+ editor_clear_selection (NULL);
+}
+
+
+/*
+ * Creates the child packing properties for children of this widget.
+ */
+static void
+gb_table_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_int_range (GbCellX, _("Cell X:"),
+ _("The left edge of the widget in the table"),
+ 0, 10000, 1, 10, 1);
+ property_add_int_range (GbCellY, _("Cell Y:"),
+ _("The top edge of the widget in the table"),
+ 0, 10000, 1, 10, 1);
+
+ property_add_int_range (GbColSpan, _("Col Span:"),
+ _("The number of columns spanned by the widget in the table"),
+ 1, 10000, 1, 10, 1);
+ property_add_int_range (GbRowSpan, _("Row Span:"),
+ _("The number of rows spanned by the widget in the table"),
+ 1, 10000, 1, 10, 1);
+ property_add_int_range (GbXPad, _("H Padding:"),
+ _("The horizontal padding"),
+ 0, 10000, 1, 10, 1);
+ property_add_int_range (GbYPad, _("V Padding:"),
+ _("The vertical padding"),
+ 0, 10000, 1, 10, 1);
+ property_add_bool (GbXExpand, _("X Expand:"),
+ _("Set True to let the widget expand horizontally"));
+ property_add_bool (GbYExpand, _("Y Expand:"),
+ _("Set True to let the widget expand vertically"));
+ property_add_bool (GbXShrink, _("X Shrink:"),
+ _("Set True to let the widget shrink horizontally"));
+ property_add_bool (GbYShrink, _("Y Shrink:"),
+ _("Set True to let the widget shrink vertically"));
+ property_add_bool (GbXFill, _("X Fill:"),
+ _("Set True to let the widget fill its horizontal allocated area"));
+ property_add_bool (GbYFill, _("Y Fill:"),
+ _("Set True to let the widget fill its vertical allocated area"));
+}
+
+
+static void
+gb_table_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ GtkTableChild *table_child;
+
+ table_child = glade_util_find_table_child (GTK_TABLE (widget), child);
+ g_return_if_fail (table_child != NULL);
+
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ if (data->action == GB_SAVING)
+ {
+ /* We use left/right/top/bottom_attach here as they are used in GTK */
+ gb_widget_output_int (data, "GtkWidget::left_attach",
+ table_child->left_attach);
+ gb_widget_output_int (data, "GtkWidget::right_attach",
+ table_child->right_attach);
+ gb_widget_output_int (data, "GtkWidget::top_attach",
+ table_child->top_attach);
+ gb_widget_output_int (data, "GtkWidget::bottom_attach",
+ table_child->bottom_attach);
+ }
+ else
+ {
+ gb_widget_output_int (data, GbCellX, table_child->left_attach);
+ gb_widget_output_int (data, GbCellY, table_child->top_attach);
+ gb_widget_output_int (data, GbColSpan,
+ table_child->right_attach
+ - table_child->left_attach);
+ gb_widget_output_int (data, GbRowSpan,
+ table_child->bottom_attach
+ - table_child->top_attach);
+ }
+
+ /* Default X & Y padding is 0. */
+ if (data->action != GB_SAVING || table_child->xpadding)
+ gb_widget_output_int (data, GbXPad, table_child->xpadding);
+ if (data->action != GB_SAVING || table_child->ypadding)
+ gb_widget_output_int (data, GbYPad, table_child->ypadding);
+
+ if (data->action == GB_SAVING)
+ {
+ char buffer[32];
+
+ /* Default packing is GTK_EXPAND | GTK_FILL. */
+ if (!table_child->xexpand || !table_child->xfill || table_child->xshrink)
+ {
+ buffer[0] = '\0';
+ if (table_child->xexpand)
+ strcat (buffer, "expand");
+ if (table_child->xshrink)
+ {
+ if (buffer[0])
+ strcat (buffer, "|");
+ strcat (buffer, "shrink");
+ }
+ if (table_child->xfill)
+ {
+ if (buffer[0])
+ strcat (buffer, "|");
+ strcat (buffer, "fill");
+ }
+ gb_widget_output_string (data, GbXOptions, buffer);
+ }
+
+ if (!table_child->yexpand || !table_child->yfill || table_child->yshrink)
+ {
+ buffer[0] = '\0';
+ if (table_child->yexpand)
+ strcat (buffer, "expand");
+ if (table_child->yshrink)
+ {
+ if (buffer[0])
+ strcat (buffer, "|");
+ strcat (buffer, "shrink");
+ }
+ if (table_child->yfill)
+ {
+ if (buffer[0])
+ strcat (buffer, "|");
+ strcat (buffer, "fill");
+ }
+ gb_widget_output_string (data, GbYOptions, buffer);
+ }
+ }
+ else
+ {
+ gb_widget_output_bool (data, GbXExpand, table_child->xexpand);
+ gb_widget_output_bool (data, GbYExpand, table_child->yexpand);
+ gb_widget_output_bool (data, GbXShrink, table_child->xshrink);
+ gb_widget_output_bool (data, GbYShrink, table_child->yshrink);
+ gb_widget_output_bool (data, GbXFill, table_child->xfill);
+ gb_widget_output_bool (data, GbYFill, table_child->yfill);
+ }
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+static void
+gb_table_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ GtkTableChild *tchild;
+ gint xpad, ypad, left_attach, right_attach, top_attach, bottom_attach;
+ gint xexpand, yexpand, xshrink, yshrink, xfill, yfill;
+
+ tchild = glade_util_find_table_child (GTK_TABLE (widget), child);
+ g_return_if_fail (tchild != NULL);
+
+ xpad = gb_widget_input_int (data, GbXPad);
+ if (!data->apply)
+ xpad = tchild->xpadding;
+
+ ypad = gb_widget_input_int (data, GbYPad);
+ if (!data->apply)
+ ypad = tchild->ypadding;
+
+ if (data->action == GB_APPLYING)
+ {
+ xexpand = (gb_widget_input_bool (data, GbXExpand)) ? GTK_EXPAND : 0;
+ if (!data->apply)
+ xexpand = tchild->xexpand ? GTK_EXPAND : 0;
+
+ yexpand = (gb_widget_input_bool (data, GbYExpand)) ? GTK_EXPAND : 0;
+ if (!data->apply)
+ yexpand = tchild->yexpand ? GTK_EXPAND : 0;
+
+ xshrink = (gb_widget_input_bool (data, GbXShrink)) ? GTK_SHRINK : 0;
+ if (!data->apply)
+ xshrink = tchild->xshrink ? GTK_SHRINK : 0;
+
+ yshrink = (gb_widget_input_bool (data, GbYShrink)) ? GTK_SHRINK : 0;
+ if (!data->apply)
+ yshrink = tchild->yshrink ? GTK_SHRINK : 0;
+
+ xfill = (gb_widget_input_bool (data, GbXFill)) ? GTK_FILL : 0;
+ if (!data->apply)
+ xfill = tchild->xfill ? GTK_FILL : 0;
+
+ yfill = (gb_widget_input_bool (data, GbYFill)) ? GTK_FILL : 0;
+ if (!data->apply)
+ yfill = tchild->yfill ? GTK_FILL : 0;
+ }
+ else
+ {
+ char *xoptions, *yoptions;
+
+ xoptions = gb_widget_input_string (data, GbXOptions);
+ if (data->apply)
+ {
+ xexpand = (strstr (xoptions, "expand")) ? GTK_EXPAND : 0;
+ xfill = (strstr (xoptions, "fill")) ? GTK_FILL : 0;
+ xshrink = (strstr (xoptions, "shrink")) ? GTK_SHRINK : 0;
+ }
+ else
+ {
+ xexpand = GTK_EXPAND;
+ xfill = GTK_FILL;
+ xshrink = 0;
+ }
+
+ yoptions = gb_widget_input_string (data, GbYOptions);
+ if (data->apply)
+ {
+ yexpand = (strstr (yoptions, "expand")) ? GTK_EXPAND : 0;
+ yfill = (strstr (yoptions, "fill")) ? GTK_FILL : 0;
+ yshrink = (strstr (yoptions, "shrink")) ? GTK_SHRINK : 0;
+ }
+ else
+ {
+ yexpand = GTK_EXPAND;
+ yfill = GTK_FILL;
+ yshrink = 0;
+ }
+ }
+
+ if (data->action == GB_APPLYING)
+ {
+ left_attach = gb_widget_input_int (data, GbCellX);
+ if (!data->apply)
+ left_attach = tchild->left_attach;
+
+ top_attach = gb_widget_input_int (data, GbCellY);
+ if (!data->apply)
+ top_attach = tchild->top_attach;
+
+ right_attach = gb_widget_input_int (data, GbColSpan) + left_attach;
+ if (!data->apply)
+ right_attach = left_attach + (tchild->right_attach
+ - tchild->left_attach);
+
+ bottom_attach = gb_widget_input_int (data, GbRowSpan) + top_attach;
+ if (!data->apply)
+ bottom_attach = top_attach + (tchild->bottom_attach
+ - tchild->top_attach);
+ }
+ else
+ {
+ left_attach = gb_widget_input_int (data, "GtkWidget::left_attach");
+ if (!data->apply)
+ left_attach = tchild->left_attach;
+
+ top_attach = gb_widget_input_int (data, "GtkWidget::top_attach");
+ if (!data->apply)
+ top_attach = tchild->top_attach;
+
+ right_attach = gb_widget_input_int (data, "GtkWidget::right_attach");
+ if (!data->apply)
+ right_attach = tchild->right_attach;
+
+ bottom_attach = gb_widget_input_int (data, "GtkWidget::bottom_attach");
+ if (!data->apply)
+ bottom_attach = tchild->bottom_attach;
+ }
+
+ if (right_attach <= left_attach)
+ right_attach = left_attach + 1;
+ if (bottom_attach <= top_attach)
+ bottom_attach = top_attach + 1;
+
+ if (xpad != tchild->xpadding || ypad != tchild->ypadding
+ || (xexpand && !tchild->xexpand) || (!xexpand && tchild->xexpand)
+ || (yexpand && !tchild->yexpand) || (!yexpand && tchild->yexpand)
+ || (xshrink && !tchild->xshrink) || (!xshrink && tchild->xshrink)
+ || (yshrink && !tchild->yshrink) || (!yshrink && tchild->yshrink)
+ || (xfill && !tchild->xfill) || (!xfill && tchild->xfill)
+ || (yfill && !tchild->yfill) || (!yfill && tchild->yfill)
+ || left_attach != tchild->left_attach
+ || right_attach != tchild->right_attach
+ || top_attach != tchild->top_attach
+ || bottom_attach != tchild->bottom_attach)
+ {
+ gtk_widget_ref (child);
+ gtk_container_remove (GTK_CONTAINER (widget), child);
+ gtk_table_attach (GTK_TABLE (widget), child,
+ left_attach, right_attach, top_attach, bottom_attach,
+ xexpand | xshrink | xfill, yexpand | yshrink | yfill,
+ xpad, ypad);
+ gtk_widget_unref (child);
+ if (data->action == GB_APPLYING)
+ gb_table_update_placeholders (widget, -1, -1);
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkTable, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_table_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+
+ /* It is possible that the mouse button was clicked outside a child
+ (e.g. beneath all the children), in which case we return. We could
+ still support adding rows/cols. */
+ if (data->child == NULL)
+ return;
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Row Before"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_table_insert_row_before),
+ data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Row After"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_table_insert_row_after),
+ data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Column Before"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_table_insert_column_before),
+ data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Column After"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_table_insert_column_after),
+ data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Delete Row"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_table_delete_row), data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Delete Column"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_table_delete_column), data->child);
+}
+
+
+static void
+gb_table_insert_row_before (GtkWidget * menuitem, GtkWidget * widget)
+{
+ GtkWidget *table;
+ GtkTableChild *tchild;
+
+ table = widget->parent;
+ g_return_if_fail (GTK_IS_TABLE (table));
+ tchild = glade_util_find_table_child (GTK_TABLE (table), widget);
+ g_return_if_fail (tchild != NULL);
+ gb_table_insert_row_or_col (table, tchild->top_attach, -1);
+}
+
+
+static void
+gb_table_insert_row_after (GtkWidget * menuitem, GtkWidget * widget)
+{
+ GtkWidget *table;
+ GtkTableChild *tchild;
+
+ table = widget->parent;
+ g_return_if_fail (GTK_IS_TABLE (table));
+ tchild = glade_util_find_table_child (GTK_TABLE (table), widget);
+ g_return_if_fail (tchild != NULL);
+ gb_table_insert_row_or_col (table, tchild->bottom_attach, -1);
+}
+
+
+static void
+gb_table_insert_column_before (GtkWidget * menuitem, GtkWidget * widget)
+{
+ GtkWidget *table;
+ GtkTableChild *tchild;
+
+ table = widget->parent;
+ g_return_if_fail (GTK_IS_TABLE (table));
+ tchild = glade_util_find_table_child (GTK_TABLE (table), widget);
+ g_return_if_fail (tchild != NULL);
+ gb_table_insert_row_or_col (table, -1, tchild->left_attach);
+}
+
+
+static void
+gb_table_insert_column_after (GtkWidget * menuitem, GtkWidget * widget)
+{
+ GtkWidget *table;
+ GtkTableChild *tchild;
+
+ table = widget->parent;
+ g_return_if_fail (GTK_IS_TABLE (table));
+ tchild = glade_util_find_table_child (GTK_TABLE (table), widget);
+ g_return_if_fail (tchild != NULL);
+ gb_table_insert_row_or_col (table, -1, tchild->right_attach);
+}
+
+
+/* This inserts a row or column into the table at the given position.
+ Use -1 for the other unused argument. */
+static void
+gb_table_insert_row_or_col (GtkWidget * table, gint row, gint col)
+{
+ GtkTableChild *tchild;
+ GList *child;
+ GtkWidget *widget, *tmp_label;
+ gint rows, cols;
+
+ /* This relies on knowing the internals of GtkTable, so it is fast.
+ First it adds a simple label at the bottom right of the new table size,
+ to ensure that the table grows. Then it removes the label, and moves
+ all the widgets down/right as appropriate, and adds any necessary
+ placeholders. */
+ tmp_label = gtk_label_new ("");
+ rows = GTK_TABLE (table)->nrows + (row != -1 ? 1 : 0);
+ cols = GTK_TABLE (table)->ncols + (col != -1 ? 1 : 0);
+ gtk_table_attach_defaults (GTK_TABLE (table), tmp_label,
+ cols - 1, cols, rows - 1, rows);
+
+ child = GTK_TABLE (table)->children;
+ while (child)
+ {
+ tchild = child->data;
+ child = child->next;
+ widget = tchild->widget;
+
+ if ((row != -1 && tchild->top_attach >= row)
+ || (col != -1 && tchild->left_attach >= col))
+ {
+ /* If we're inserting a row, we move the widget down.
+ If we're inserting a col, we move the widget right. */
+ if (row != -1)
+ {
+ tchild->top_attach++;
+ tchild->bottom_attach++;
+ }
+ else
+ {
+ tchild->left_attach++;
+ tchild->right_attach++;
+ }
+ }
+ }
+
+ /* Now remove the temporary label. */
+ gtk_container_remove (GTK_CONTAINER (table), tmp_label);
+
+ /* This fills any empty cells with placeholders. */
+ gb_table_update_placeholders (table, -1, -1);
+
+ /* If the tables properties are currently shown, update rows/cols. */
+ if (property_get_widget () == table)
+ {
+ property_set_auto_apply (FALSE);
+ if (row != -1)
+ property_set_int (Rows, GTK_TABLE (table)->nrows);
+ else
+ property_set_int (Columns, GTK_TABLE (table)->ncols);
+ property_set_auto_apply (TRUE);
+ }
+}
+
+
+static void
+gb_table_delete_row (GtkWidget * menuitem, GtkWidget * widget)
+{
+ GtkWidget *table;
+ GtkTableChild *tchild;
+ GList *children;
+ guint16 nrows, ncols, row;
+
+ table = widget->parent;
+ nrows = GTK_TABLE (table)->nrows - 1;
+ if (nrows == 0)
+ return;
+ ncols = GTK_TABLE (table)->ncols;
+ tchild = glade_util_find_table_child (GTK_TABLE (table), widget);
+ g_return_if_fail (tchild != NULL);
+ row = tchild->top_attach;
+
+ children = GTK_TABLE (table)->children;
+ while (children)
+ {
+ tchild = children->data;
+ children = children->next;
+ if (tchild->top_attach == row && tchild->bottom_attach == row + 1)
+ {
+ gtk_container_remove (GTK_CONTAINER (table), tchild->widget);
+ }
+ else if (tchild->top_attach <= row && tchild->bottom_attach > row)
+ {
+ tchild->bottom_attach -= 1;
+ }
+ else if (tchild->top_attach > row)
+ {
+ tchild->top_attach -= 1;
+ tchild->bottom_attach -= 1;
+ }
+ }
+ update_table_size (table, nrows, ncols);
+
+ if (property_get_widget () == table)
+ {
+ property_set_auto_apply (FALSE);
+ property_set_int (Rows, nrows);
+ property_set_auto_apply (TRUE);
+ }
+}
+
+
+static void
+gb_table_delete_column (GtkWidget * menuitem, GtkWidget * widget)
+{
+ GtkWidget *table;
+ GtkTableChild *tchild;
+ GList *children;
+ guint16 nrows, ncols, col;
+
+ table = widget->parent;
+ nrows = GTK_TABLE (table)->nrows;
+ ncols = GTK_TABLE (table)->ncols - 1;
+ if (ncols == 0)
+ return;
+ tchild = glade_util_find_table_child (GTK_TABLE (table), widget);
+ g_return_if_fail (tchild != NULL);
+ col = tchild->left_attach;
+
+ children = GTK_TABLE (table)->children;
+ while (children)
+ {
+ tchild = children->data;
+ children = children->next;
+ if (tchild->left_attach == col && tchild->right_attach == col + 1)
+ {
+ gtk_container_remove (GTK_CONTAINER (table), tchild->widget);
+ }
+ else if (tchild->left_attach <= col && tchild->right_attach > col)
+ {
+ tchild->right_attach -= 1;
+ }
+ else if (tchild->left_attach > col)
+ {
+ tchild->left_attach -= 1;
+ tchild->right_attach -= 1;
+ }
+ }
+ update_table_size (table, nrows, ncols);
+
+ if (property_get_widget () == table)
+ {
+ property_set_auto_apply (FALSE);
+ property_set_int (Columns, ncols);
+ property_set_auto_apply (TRUE);
+ }
+}
+
+
+/* This ensures that placeholders are placed in every unoccupied cell.
+ If rows and cols are not -1, then they are the new dimensions of the table.
+ FIXME: This is very inefficient.
+ */
+void
+gb_table_update_placeholders (GtkWidget * table, gint rows, gint cols)
+{
+ gint row, col, cell_contents;
+ guchar *rows_occupied, *cols_occupied;
+ GList *children;
+ GtkTableChild *child;
+
+ if (rows == -1)
+ rows = GTK_TABLE (table)->nrows;
+ if (cols == -1)
+ cols = GTK_TABLE (table)->ncols;
+
+ /* These hold flags to indicate which rows/cols have widgets in them. */
+ rows_occupied = g_new0 (guchar, rows);
+ cols_occupied = g_new0 (guchar, cols);
+
+ for (row = 0; row < rows; row++)
+ {
+ for (col = 0; col < cols; col++)
+ {
+ /* Find out what is in the cell */
+ cell_contents = gb_table_is_cell_occupied (table, row, col);
+ if (cell_contents == GB_CELL_WIDGET)
+ {
+ /* If cell is occupied, delete any placeholders there. If a
+ placeholder occupies the cell but spans multiple rows/cols
+ split it into single cells but without a placeholder in this
+ cell */
+ gb_table_remove_placeholders (table, row, col);
+ rows_occupied[row] = 1;
+ cols_occupied[col] = 1;
+ }
+ else if (cell_contents == GB_CELL_EMPTY)
+ {
+ /* If the cell is empty, put a placeholder in it */
+ gtk_table_attach (GTK_TABLE (table),
+ editor_new_placeholder (),
+ col, col + 1, row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+ 0, 0);
+ }
+ }
+ }
+
+ /* Now make sure that if a row/col is occupied, any placeholders in that
+ row/col do not expand, and vice versa. */
+ children = GTK_TABLE (table)->children;
+ while (children)
+ {
+ child = children->data;
+ if (GB_IS_PLACEHOLDER (child->widget))
+ {
+ gboolean xexpand = TRUE, yexpand = TRUE;
+ gint row, col;
+
+ /* Check if any widgets are in the same rows as the placeholder. */
+ for (row = child->top_attach; row < child->bottom_attach; row++)
+ {
+ if (rows_occupied[row])
+ yexpand = FALSE;
+ }
+ child->yexpand = yexpand;
+
+ /* Check if any widgets are in the same cols as the placeholder. */
+ for (col = child->left_attach; col < child->right_attach; col++)
+ {
+ if (cols_occupied[col])
+ xexpand = FALSE;
+ }
+ child->xexpand = xexpand;
+
+ child->xfill = TRUE;
+ child->yfill = TRUE;
+ }
+ children = children->next;
+ }
+
+ g_free (rows_occupied);
+ g_free (cols_occupied);
+
+ gtk_widget_queue_resize (table);
+}
+
+
+/* Finds out if cell is occupied by a real widget. If not, returns whether
+ the cell is empty or whether a placeholder is in it */
+static gint
+gb_table_is_cell_occupied (GtkWidget * table, gint row, gint col)
+{
+ GList *children;
+ GtkTableChild *child;
+ gint return_val = GB_CELL_EMPTY;
+
+ children = GTK_TABLE (table)->children;
+ while (children)
+ {
+ child = children->data;
+ if (child->top_attach <= row && child->bottom_attach > row
+ && child->left_attach <= col && child->right_attach > col)
+ {
+ if (GB_IS_PLACEHOLDER (child->widget))
+ return_val = GB_CELL_PLACEHOLDER;
+ else
+ return GB_CELL_WIDGET;
+ }
+ children = children->next;
+ }
+ return return_val;
+}
+
+
+static void
+gb_table_remove_placeholders (GtkWidget * table, gint row, gint col)
+{
+ GList *children, *next;
+ GtkTableChild *child;
+ gint left, right, top, bottom;
+
+ children = GTK_TABLE (table)->children;
+ while (children)
+ {
+ next = children->next;
+ child = children->data;
+ left = child->left_attach;
+ right = child->right_attach;
+ top = child->top_attach;
+ bottom = child->bottom_attach;
+
+ if (top <= row && bottom > row && left <= col && right > col)
+ {
+ /* If the widget is a placeholder remove it */
+ if (GB_IS_PLACEHOLDER (child->widget))
+ {
+ if (bottom - top > 1 || right - left > 1)
+ {
+ gb_table_split_placeholder (table, child->widget,
+ left, right, top, bottom,
+ row, col);
+ }
+ else
+ {
+ gtk_container_remove (GTK_CONTAINER (table), child->widget);
+ }
+ }
+ }
+ children = next;
+ }
+}
+
+
+static void
+gb_table_split_placeholder (GtkWidget * table, GtkWidget * placeholder,
+ gint left, gint right, gint top, gint bottom,
+ gint skip_row, gint skip_col)
+{
+ gint row, col;
+
+ gtk_container_remove (GTK_CONTAINER (table), placeholder);
+ for (row = top; row < bottom; row++)
+ {
+ for (col = left; col < right; col++)
+ {
+ if (!(row == skip_row && col == skip_col))
+ {
+ gtk_table_attach (GTK_TABLE (table),
+ editor_new_placeholder (),
+ col, col + 1, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ }
+ }
+ }
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_table_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_table_new (%i, %i, %s);\n", data->wname,
+ GTK_TABLE (widget)->nrows, GTK_TABLE (widget)->ncols,
+ GTK_TABLE (widget)->homogeneous ? "TRUE" : "FALSE");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_TABLE (widget)->row_spacing != 0)
+ {
+ source_add (data, " gtk_table_set_row_spacings (GTK_TABLE (%s), %i);\n",
+ data->wname, GTK_TABLE (widget)->row_spacing);
+ }
+ if (GTK_TABLE (widget)->column_spacing != 0)
+ {
+ source_add (data, " gtk_table_set_col_spacings (GTK_TABLE (%s), %i);\n",
+ data->wname, GTK_TABLE (widget)->column_spacing);
+ }
+}
+
+
+/* Outputs source to add a child widget to a table. */
+static void
+gb_table_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gchar xoptions[48], yoptions[48];
+ GtkTableChild *tchild = glade_util_find_table_child (GTK_TABLE (parent),
+ child);
+ g_return_if_fail (tchild != NULL);
+
+ xoptions[0] = yoptions[0] = '\0';
+ if (tchild->xexpand)
+ strcpy (xoptions, "GTK_EXPAND");
+ if (tchild->xshrink)
+ {
+ if (xoptions[0] != '\0')
+ strcat (xoptions, " | ");
+ strcat (xoptions, "GTK_SHRINK");
+ }
+ if (tchild->xfill)
+ {
+ if (xoptions[0] != '\0')
+ strcat (xoptions, " | ");
+ strcat (xoptions, "GTK_FILL");
+ }
+ if (xoptions[0] == '\0')
+ strcpy (xoptions, "0");
+
+ if (tchild->yexpand)
+ strcpy (yoptions, "GTK_EXPAND");
+ if (tchild->yshrink)
+ {
+ if (yoptions[0] != '\0')
+ strcat (yoptions, " | ");
+ strcat (yoptions, "GTK_SHRINK");
+ }
+ if (tchild->yfill)
+ {
+ if (yoptions[0] != '\0')
+ strcat (yoptions, " | ");
+ strcat (yoptions, "GTK_FILL");
+ }
+ if (yoptions[0] == '\0')
+ strcpy (yoptions, "0");
+
+ source_add (data,
+ " gtk_table_attach (GTK_TABLE (%s), %s, %i, %i, %i, %i,\n"
+ " (GtkAttachOptions) (%s),\n"
+ " (GtkAttachOptions) (%s), %i, %i);\n",
+ parent_name, data->wname,
+ tchild->left_attach, tchild->right_attach,
+ tchild->top_attach, tchild->bottom_attach,
+ xoptions, yoptions, tchild->xpadding, tchild->ypadding);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_table_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_table_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = table_xpm;
+ gbwidget.tooltip = _("Table");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_table_new;
+ gbwidget.gb_widget_create_properties = gb_table_create_properties;
+ gbwidget.gb_widget_get_properties = gb_table_get_properties;
+ gbwidget.gb_widget_set_properties = gb_table_set_properties;
+ gbwidget.gb_widget_create_child_properties = gb_table_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_table_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_table_set_child_properties;
+ gbwidget.gb_widget_write_source = gb_table_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_table_write_add_child_source;
+ gbwidget.gb_widget_create_popup_menu = gb_table_create_popup_menu;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbtextview.c b/tools/glade/glade/gbwidgets/gbtextview.c
new file mode 100644
index 00000000..31cbe830
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtextview.c
@@ -0,0 +1,479 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/text.xpm"
+
+static gchar *Editable = "GtkTextView::editable";
+static gchar *Text = "GtkTextView::text";
+static gchar *Justification = "GtkTextView::justification";
+static gchar *WrapMode = "GtkTextView::wrap_mode";
+static gchar *CursorVisible = "GtkTextView::cursor_visible";
+static gchar *PixelsAboveLines = "GtkTextView::pixels_above_lines";
+static gchar *PixelsBelowLines = "GtkTextView::pixels_below_lines";
+static gchar *PixelsInsideWrap = "GtkTextView::pixels_inside_wrap";
+static gchar *LeftMargin = "GtkTextView::left_margin";
+static gchar *RightMargin = "GtkTextView::right_margin";
+static gchar *Indent = "GtkTextView::indent";
+
+static gchar *Overwrite = "GtkTextView::overwrite";
+static gchar *AcceptsTab = "GtkTextView::accepts_tab";
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static const char *GbJustifyChoices[] = {
+ N_("Left"),
+ N_("Right"),
+ N_("Center"),
+ N_("Fill"),
+ NULL
+};
+
+static gint GbJustifyValues[] = {
+ GTK_JUSTIFY_LEFT,
+ GTK_JUSTIFY_RIGHT,
+ GTK_JUSTIFY_CENTER,
+ GTK_JUSTIFY_FILL
+};
+static const gchar *GbJustifySymbols[] =
+{
+ "GTK_JUSTIFY_LEFT",
+ "GTK_JUSTIFY_RIGHT",
+ "GTK_JUSTIFY_CENTER",
+ "GTK_JUSTIFY_FILL"
+};
+
+static const char *GbWrapChoices[] = {
+ N_("None"),
+ N_("Character"),
+ N_("Word"),
+ NULL
+};
+
+static gint GbWrapValues[] = {
+ GTK_WRAP_NONE,
+ GTK_WRAP_CHAR,
+ GTK_WRAP_WORD
+};
+static const char *GbWrapSymbols[] = {
+ "GTK_WRAP_NONE",
+ "GTK_WRAP_CHAR",
+ "GTK_WRAP_WORD"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkTextView, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_text_view_new (GbWidgetNewData *data)
+{
+ return gtk_text_view_new ();
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_text_view_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Editable, _("Editable:"),
+ _("If the text can be edited"));
+ property_add_bool (CursorVisible, _("Cursor Visible:"),
+ _("If the cursor is visible"));
+ property_add_bool (Overwrite, _("Overwrite:"),
+ _("If entered text overwrites the existing text"));
+ property_add_bool (AcceptsTab, _("Accepts Tab:"),
+ _("If tab characters can be entered"));
+
+ property_add_text (Text, _("Text:"), _("The text to display"), 5);
+
+ property_add_choice (Justification, _("Justification:"),
+ _("The justification of the text"),
+ GbJustifyChoices);
+ property_add_choice (WrapMode, _("Wrapping:"),
+ _("The wrapping of the text"),
+ GbWrapChoices);
+
+ property_add_int_range (PixelsAboveLines, _("Space Above:"),
+ _("Pixels of blank space above paragraphs"),
+ 0, G_MAXINT, 1, 2, 10);
+ property_add_int_range (PixelsBelowLines, _("Space Below:"),
+ _("Pixels of blank space below paragraphs"),
+ 0, G_MAXINT, 1, 2, 10);
+ property_add_int_range (PixelsInsideWrap, _("Space Inside:"),
+ _("Pixels of blank space between wrapped lines in a paragraph"),
+ 0, G_MAXINT, 1, 2, 10);
+
+ property_add_int_range (LeftMargin, _("Left Margin:"),
+ _("Width of the left margin in pixels"),
+ 0, G_MAXINT, 1, 2, 10);
+ property_add_int_range (RightMargin, _("Right Margin:"),
+ _("Width of the right margin in pixels"),
+ 0, G_MAXINT, 1, 2, 10);
+ property_add_int_range (Indent, _("Indent:"),
+ _("Amount of pixels to indent paragraphs"),
+ 0, G_MAXINT, 1, 2, 10);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_text_view_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkTextBuffer *buffy;
+ GtkTextIter start, end;
+ gboolean editable, cursor_visible, overwrite, accepts_tab;
+ gint wrap_mode, justification;
+ gint pixels_above, pixels_below, pixels_inside;
+ gint left_margin, right_margin, indent;
+ char *text;
+
+ g_object_get (widget,
+ "editable", &editable,
+ "overwrite", &overwrite,
+ "accepts_tab", &accepts_tab,
+ "justification", &justification,
+ "wrap-mode", &wrap_mode,
+ "cursor-visible", &cursor_visible,
+ "pixels-above-lines", &pixels_above,
+ "pixels-below-lines", &pixels_below,
+ "pixels-inside-wrap", &pixels_inside,
+ "left-margin", &left_margin,
+ "right-margin", &right_margin,
+ "indent", &indent,
+ NULL);
+
+
+ gb_widget_output_bool (data, Editable, editable);
+ gb_widget_output_bool (data, Overwrite, overwrite);
+ gb_widget_output_bool (data, AcceptsTab, accepts_tab);
+ gb_widget_output_enum (data, GTK_TYPE_JUSTIFICATION,
+ GbJustifyValues,
+ G_N_ELEMENTS (GbJustifyValues),
+ Justification, justification);
+ gb_widget_output_enum (data, GTK_TYPE_WRAP_MODE,
+ GbWrapValues,
+ G_N_ELEMENTS (GbWrapValues),
+ WrapMode, wrap_mode);
+ gb_widget_output_bool (data, CursorVisible, cursor_visible);
+ gb_widget_output_int (data, PixelsAboveLines, pixels_above);
+ gb_widget_output_int (data, PixelsBelowLines, pixels_below);
+ gb_widget_output_int (data, PixelsInsideWrap, pixels_inside);
+ gb_widget_output_int (data, LeftMargin, left_margin);
+ gb_widget_output_int (data, RightMargin, right_margin);
+ gb_widget_output_int (data, Indent, indent);
+
+ buffy = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ gtk_text_buffer_get_bounds (buffy, &start, &end);
+ text = gtk_text_iter_get_text (&start, &end);
+ gb_widget_output_translatable_text (data, Text, text);
+ g_free (text);
+}
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_text_view_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ int i;
+ char *s;
+
+ i = gb_widget_input_bool (data, Editable);
+ if (data->apply)
+ g_object_set (widget, "editable", i, NULL);
+
+ i = gb_widget_input_bool (data, Overwrite);
+ if (data->apply)
+ g_object_set (widget, "overwrite", i, NULL);
+
+ i = gb_widget_input_bool (data, AcceptsTab);
+ if (data->apply)
+ g_object_set (widget, "accepts_tab", i, NULL);
+
+ s = gb_widget_input_text (data, Text);
+ if (data->apply) {
+ GtkTextBuffer *buffy;
+ buffy = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ gtk_text_buffer_set_text (buffy, s, strlen (s));
+ }
+ if (data->action == GB_APPLYING)
+ g_free (s);
+
+
+ i = gb_widget_input_enum (data, GTK_TYPE_JUSTIFICATION,
+ GbJustifyChoices, GbJustifyValues,
+ Justification);
+ if (data->apply)
+ g_object_set (widget, "justification", i, NULL);
+
+ i = gb_widget_input_enum (data, GTK_TYPE_WRAP_MODE,
+ GbWrapChoices, GbWrapValues,
+ WrapMode);
+ if (data->apply)
+ g_object_set (widget, "wrap-mode", i, NULL);
+
+ i = gb_widget_input_bool (data, CursorVisible);
+ if (data->apply)
+ g_object_set (widget, "cursor-visible", i, NULL);
+
+ i = gb_widget_input_int (data, PixelsAboveLines);
+ if (data->apply)
+ g_object_set (widget, "pixels-above-lines", i, NULL);
+
+ i = gb_widget_input_int (data, PixelsBelowLines);
+ if (data->apply)
+ g_object_set (widget, "pixels-below-lines", i, NULL);
+
+ i = gb_widget_input_int (data, PixelsInsideWrap);
+ if (data->apply)
+ g_object_set (widget, "pixels-inside-wrap", i, NULL);
+
+ i = gb_widget_input_int (data, LeftMargin);
+ if (data->apply)
+ g_object_set (widget, "left-margin", i, NULL);
+
+ i = gb_widget_input_int (data, RightMargin);
+ if (data->apply)
+ g_object_set (widget, "right-margin", i, NULL);
+
+ i = gb_widget_input_int (data, Indent);
+ if (data->apply)
+ g_object_set (widget, "indent", i, NULL);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkTextView, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_text_view_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_text_view_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkTextBuffer *buffy;
+ GtkTextIter start, end;
+ gboolean editable, cursor_visible, overwrite, accepts_tab;
+ gint wrap_mode, justification;
+ gint pixels_above, pixels_below, pixels_inside;
+ gint left_margin, right_margin, indent, i;
+ char *text;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_text_view_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ g_object_get (widget,
+ "editable", &editable,
+ "overwrite", &overwrite,
+ "accepts_tab", &accepts_tab,
+ "justification", &justification,
+ "wrap-mode", &wrap_mode,
+ "cursor-visible", &cursor_visible,
+ "pixels-above-lines", &pixels_above,
+ "pixels-below-lines", &pixels_below,
+ "pixels-inside-wrap", &pixels_inside,
+ "left-margin", &left_margin,
+ "right-margin", &right_margin,
+ "indent", &indent,
+ NULL);
+
+ if (!editable)
+ source_add (data,
+ " gtk_text_view_set_editable (GTK_TEXT_VIEW (%s), FALSE);\n",
+ data->wname);
+
+ if (overwrite)
+ source_add (data,
+ " gtk_text_view_set_overwrite (GTK_TEXT_VIEW (%s), TRUE);\n",
+ data->wname);
+
+ if (!accepts_tab)
+ source_add (data,
+ " gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (%s), FALSE);\n",
+ data->wname);
+
+ if (justification != GTK_JUSTIFY_LEFT)
+ {
+ for (i = 0; i < sizeof (GbJustifyValues) / sizeof (GbJustifyValues[0]);
+ i++)
+ {
+ if (GbJustifyValues[i] == justification)
+ source_add (data,
+ " gtk_text_view_set_justification (GTK_TEXT_VIEW (%s), %s);\n",
+ data->wname, GbJustifySymbols[i]);
+ }
+ }
+
+ if (wrap_mode != GTK_WRAP_NONE)
+ {
+ for (i = 0; i < sizeof (GbWrapValues) / sizeof (GbWrapValues[0]); i++)
+ {
+ if (GbWrapValues[i] == wrap_mode)
+ source_add (data,
+ " gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (%s), %s);\n",
+ data->wname, GbWrapSymbols[i]);
+ }
+ }
+
+ if (!cursor_visible)
+ source_add (data,
+ " gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (%s), FALSE);\n",
+ data->wname);
+
+ if (pixels_above != 0)
+ source_add (data,
+ " gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (%s), %i);\n",
+ data->wname, pixels_above);
+
+ if (pixels_below != 0)
+ source_add (data,
+ " gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (%s), %i);\n",
+ data->wname, pixels_below);
+
+ if (pixels_inside != 0)
+ source_add (data,
+ " gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (%s), %i);\n",
+ data->wname, pixels_inside);
+
+ if (left_margin != 0)
+ source_add (data,
+ " gtk_text_view_set_left_margin (GTK_TEXT_VIEW (%s), %i);\n",
+ data->wname, left_margin);
+
+ if (right_margin != 0)
+ source_add (data,
+ " gtk_text_view_set_right_margin (GTK_TEXT_VIEW (%s), %i);\n",
+ data->wname, right_margin);
+
+ if (indent != 0)
+ source_add (data,
+ " gtk_text_view_set_indent (GTK_TEXT_VIEW (%s), %i);\n",
+ data->wname, indent);
+
+
+ buffy = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ gtk_text_buffer_get_bounds (buffy, &start, &end);
+ text = gtk_text_iter_get_text (&start, &end);
+ if (text && *text)
+ {
+ glade_util_get_translation_properties (widget, Text, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (%s)), %s, -1);\n",
+ data->wname,
+ source_make_string_full (text,
+ data->use_gettext && translatable,
+ context));
+ }
+ g_free (text);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_text_view_init ()
+{
+ GtkWidgetClass *klass;
+
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_text_view_get_type();
+
+ /* Add a signal emission hook so we can connect signal handlers to the
+ scrollbar adjustments to redraw the clist when necessary. This will also
+ work for subclasses of GtkCList. */
+ klass = gtk_type_class (gtk_text_view_get_type ());
+ g_signal_add_emission_hook (klass->set_scroll_adjustments_signal, 0,
+ gb_set_scroll_adjustments_hook, NULL, NULL);
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = text_xpm;
+ gbwidget.tooltip = _("Text View");
+
+ /* Fill in any functions that this GbWidget has */
+/*
+ gbwidget.gb_widget_new = gb_text_view_new;
+*/
+ gbwidget.gb_widget_create_properties = gb_text_view_create_properties;
+ gbwidget.gb_widget_get_properties = gb_text_view_get_properties;
+ gbwidget.gb_widget_set_properties = gb_text_view_set_properties;
+ gbwidget.gb_widget_write_source = gb_text_view_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_text_view_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbtogglebutton.c b/tools/glade/glade/gbwidgets/gbtogglebutton.c
new file mode 100644
index 00000000..8007b985
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtogglebutton.c
@@ -0,0 +1,211 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtktogglebutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/togglebutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "ToggleButton|GtkButton::stock_button";
+static gchar *Label = "ToggleButton|GtkButton::label";
+static gchar *Icon = "ToggleButton|GtkButton::icon";
+static gchar *FocusOnClick = "ToggleButton|GtkButton::focus_on_click";
+
+/* This is only used for normal/stock buttons, not special toolbar buttons,
+ as the toolbar has its own relief setting. */
+static gchar *Relief = "ToggleButton|GtkButton::relief";
+
+static gchar *State = "GtkToggleButton::active";
+static gchar *Inconsistent = "GtkToggleButton::inconsistent";
+
+
+/* draw_indicator is not really useful for toggle buttons. I think its only
+ for radio/check buttons. */
+/*static gchar *Indicator = "GtkToggleButton::draw_indicator"; */
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkToggleButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_toggle_button_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_CREATING)
+ new_widget = gtk_toggle_button_new_with_label (data->name);
+ else
+ {
+ new_widget = gtk_toggle_button_new ();
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder());
+ }
+ return new_widget;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_toggle_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData
+ * data)
+{
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_BUTTON);
+ property_add_choice (Relief, _("Button Relief:"),
+ _("The relief style of the button"),
+ GladeReliefChoices);
+
+ property_add_bool (State, _("Initially On:"),
+ _("If the toggle button is initially on"));
+ property_add_bool (Inconsistent, _("Inconsistent:"),
+ _("If the button is shown in an inconsistent state"));
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_toggle_button_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_button_get_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ gb_widget_output_bool (data, State, data->widget_data->flags & GLADE_ACTIVE);
+
+ gb_widget_output_bool (data, Inconsistent,
+ GTK_TOGGLE_BUTTON (widget)->inconsistent);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_toggle_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean state, inconsistent;
+
+ gb_button_set_standard_properties (widget, data, StockButton, Label, Icon,
+ Relief, FocusOnClick);
+
+ state = gb_widget_input_bool (data, State);
+ if (data->apply)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), state);
+ if (state)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+
+ inconsistent = gb_widget_input_bool (data, Inconsistent);
+ if (data->apply)
+ gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (widget),
+ inconsistent);
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_toggle_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gb_button_write_standard_source (widget, data, Label);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (GTK_TOGGLE_BUTTON (widget)->inconsistent)
+ {
+ source_add (data,
+ " gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_toggle_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_toggle_button_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = togglebutton_xpm;
+ gbwidget.tooltip = _("Toggle Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_toggle_button_new;
+ gbwidget.gb_widget_create_properties = gb_toggle_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_toggle_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_toggle_button_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_button_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_toggle_button_write_source;
+ gbwidget.gb_widget_destroy = gb_button_destroy;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbtoggletoolbutton.c b/tools/glade/glade/gbwidgets/gbtoggletoolbutton.c
new file mode 100644
index 00000000..65036fdf
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtoggletoolbutton.c
@@ -0,0 +1,312 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/toggletoolbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *StockButton = "GtkToggleToolButton|GtkToolButton::stock_id";
+static gchar *Label = "GtkToggleToolButton|GtkToolButton::label";
+static gchar *Icon = "GtkToggleToolButton|GtkToolButton::icon";
+static gchar *VisibleHorz = "GtkToggleToolButton|GtkToolItem::visible_horizontal";
+static gchar *VisibleVert = "GtkToggleToolButton|GtkToolItem::visible_vertical";
+static gchar *IsImportant = "GtkToggleToolButton|GtkToolItem::is_important";
+
+static gchar *Active = "GtkToggleToolButton::active";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkToggleToolButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_toggle_tool_button_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *image;
+ GbWidget *pixmap_gbwidget;
+
+ /* Place the pixmap icon in the button initially (even when loading). */
+ pixmap_gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (pixmap_gbwidget)
+ {
+ image = gtk_image_new_from_pixmap (pixmap_gbwidget->gdkpixmap,
+ pixmap_gbwidget->mask);
+ }
+ else
+ {
+ image = gtk_image_new ();
+ g_warning ("Couldn't find GtkPixmap data");
+ }
+ gtk_widget_show (image);
+
+ new_widget = (GtkWidget*) gtk_toggle_tool_button_new ();
+
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (new_widget), "");
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (new_widget), image);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_toggle_tool_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_bool (Active, _("Initially On:"),
+ _("If the toggle button is initially on"));
+ property_add_bool (VisibleHorz, _("Show Horizontal:"),
+ _("If the item is visible when the toolbar is horizontal"));
+ property_add_bool (VisibleVert, _("Show Vertical:"),
+ _("If the item is visible when the toolbar is vertical"));
+ property_add_bool (IsImportant, _("Is Important:"),
+ _("If the item's text should be shown when the toolbar's mode is GTK_TOOLBAR_BOTH_HORIZ"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_toggle_tool_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_tool_button_get_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+
+ gb_widget_output_bool (data, Active,
+ data->widget_data->flags & GLADE_ACTIVE);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_toggle_tool_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean active;
+
+ gb_tool_button_set_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+
+ active = gb_widget_input_bool (data, Active);
+ if (data->apply)
+ {
+ gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (widget),
+ active);
+ if (active)
+ data->widget_data->flags |= GLADE_ACTIVE;
+ else
+ data->widget_data->flags &= ~GLADE_ACTIVE;
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkToggleToolButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_toggle_tool_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_toggle_tool_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *stock_id, *label, *icon_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey);
+ icon_name = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ label = (gchar*) gtk_tool_button_get_label (GTK_TOOL_BUTTON (widget));
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+
+ if (data->create_widget)
+ {
+ if (stock_id)
+ {
+ /* Stock Button */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_toggle_tool_button_new_from_stock (%s);\n",
+ data->wname, source_make_string (stock_id, FALSE));
+ }
+ else if (icon_name)
+ {
+ /* Icon and Label */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_toggle_tool_button_new ();\n",
+ data->wname);
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_tool_button_set_label (GTK_TOOL_BUTTON (%s), %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+
+ source_ensure_decl (data, " GtkWidget *tmp_image;\n");
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ source_add (data,
+ " tmp_image = gtk_image_new_from_stock (\"%s\", tmp_toolbar_icon_size);\n",
+ icon_name);
+ }
+ else
+ {
+ source_create_pixmap (data, "tmp_image", icon_name);
+ }
+
+ source_add (data, " gtk_widget_show (tmp_image);\n");
+
+ source_add (data,
+ " gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (%s), tmp_image);\n",
+ data->wname);
+ }
+ else
+ {
+ /* Just a Label */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_toggle_tool_button_new ();\n",
+ data->wname);
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " gtk_tool_button_set_label (GTK_TOOL_BUTTON (%s), %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (data->widget_data->flags & GLADE_ACTIVE)
+ {
+ source_add (data,
+ " gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleVert) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)))
+ {
+ source_add (data,
+ " gtk_tool_item_set_is_important (GTK_TOOL_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_toggle_tool_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_toggle_tool_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = toggletoolbutton_xpm;
+ gbwidget.tooltip = _("Toolbar Toggle Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_toggle_tool_button_new;
+ gbwidget.gb_widget_create_properties = gb_toggle_tool_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_toggle_tool_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_toggle_tool_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_toggle_tool_button_write_source;
+ gbwidget.gb_widget_destroy = gb_tool_button_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_toggle_tool_button_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbtoolbar.c b/tools/glade/glade/gbwidgets/gbtoolbar.c
new file mode 100644
index 00000000..96b40260
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtoolbar.c
@@ -0,0 +1,696 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+/* This is just for testing, to make sure we don't use deprecated calls. */
+#if 0
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+#include <gtk/gtkenums.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtktoolitem.h>
+#define GTK_DISABLE_DEPRECATED
+#include <gtk/gtktoolbar.h>
+#undef GTK_DISABLE_DEPRECATED
+#endif
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#include "../glade_gnome.h"
+#else
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtktoolbar.h>
+#include <gtk/gtktoolbutton.h>
+#include <gtk/gtkvbox.h>
+#endif
+
+#include "../gb.h"
+#include "../tree.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/toolbar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static const gchar *Size = "GtkToolbar::size";
+static const gchar *Orientation = "GtkToolbar::orientation";
+static const gchar *Style = "GtkToolbar::toolbar_style";
+static const gchar *Tooltips = "GtkToolbar::tooltips";
+static const gchar *ShowArrow = "GtkToolbar::show_arrow";
+
+/* For children of a toolbar */
+static const gchar *Expand = "GtkToolbarChild::expand";
+static const gchar *Homogeneous = "GtkToolbarChild::homogeneous";
+
+
+static const gchar *GbOrientationChoices[] =
+{"Horizontal", "Vertical", NULL};
+static const gint GbOrientationValues[] =
+{
+ GTK_ORIENTATION_HORIZONTAL,
+ GTK_ORIENTATION_VERTICAL
+};
+static const gchar *GbOrientationSymbols[] =
+{
+ "GTK_ORIENTATION_HORIZONTAL",
+ "GTK_ORIENTATION_VERTICAL"
+};
+
+static const gchar *GbStyleChoices[] =
+{"Icons", "Text", "Both", "Both Horizontal", NULL};
+static const gint GbStyleValues[] =
+{
+ GTK_TOOLBAR_ICONS,
+ GTK_TOOLBAR_TEXT,
+ GTK_TOOLBAR_BOTH,
+ GTK_TOOLBAR_BOTH_HORIZ
+};
+static const gchar *GbStyleSymbols[] =
+{
+ "GTK_TOOLBAR_ICONS",
+ "GTK_TOOLBAR_TEXT",
+ "GTK_TOOLBAR_BOTH",
+ "GTK_TOOLBAR_BOTH_HORIZ"
+};
+
+
+static void show_toolbar_dialog (GbWidgetNewData * data);
+static void on_toolbar_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_toolbar_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+static void update_toolbar_size (GtkWidget * widget, gint size);
+
+static void gb_toolbar_insert_before (GtkWidget * menuitem,
+ GtkWidget * child);
+static void gb_toolbar_insert_after (GtkWidget * menuitem,
+ GtkWidget * child);
+static void gb_toolbar_insert (GtkWidget * child,
+ gint offset);
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkToolbar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_toolbar_new(GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gtk_toolbar_new ();
+ return new_widget;
+ }
+ else
+ {
+ show_toolbar_dialog (data);
+ return NULL;
+ }
+}
+
+
+void
+gb_toolbar_add_child (GtkWidget *widget, GtkWidget *child, GbWidgetSetArgData *data)
+{
+ /* If the child is a placeholder, we need to insert a GtkToolItem. */
+ if (GB_IS_PLACEHOLDER (child))
+ {
+ GtkWidget *toolitem = (GtkWidget*) gtk_tool_item_new ();
+ gtk_widget_show (toolitem);
+ gtk_container_add (GTK_CONTAINER (toolitem), child);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (toolitem), -1);
+ }
+ /* GtkToolItems can just be added as they are. */
+ else if (GTK_IS_TOOL_ITEM (child))
+ {
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (child), -1);
+ }
+ /* Any other widgets are from the old GTK+ 2.2 files, and we need to insert
+ a GtkToolItem. */
+ else
+ {
+ GtkWidget *toolitem = gb_widget_new_full ("GtkToolItem", FALSE,
+ NULL, NULL, 0, 0, NULL,
+ GB_LOADING, data);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (toolitem), -1);
+ tree_add_widget (toolitem);
+
+ gtk_container_add (GTK_CONTAINER (toolitem), child);
+ }
+}
+
+
+static void
+show_toolbar_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New toolbar"), data->parent,
+ GTK_SIGNAL_FUNC (on_toolbar_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_toolbar_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of items:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "items",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_toolbar_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *toolitem, *placeholder;
+ gint items, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "items");
+ g_return_if_fail (spinbutton != NULL);
+ items = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_toolbar_new ();
+ for (i = 0; i < items; i++)
+ {
+ toolitem = (GtkWidget*) gtk_tool_item_new ();
+ gtk_widget_show (toolitem);
+ gtk_toolbar_insert (GTK_TOOLBAR (new_widget),
+ GTK_TOOL_ITEM (toolitem), -1);
+
+ placeholder = editor_new_placeholder ();
+ gtk_container_add (GTK_CONTAINER (toolitem), placeholder);
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_toolbar_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_toolbar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_int_range (Size, _("Size:"),
+ _("The number of items in the toolbar"),
+ 0, 1000, 1, 10, 1);
+ property_add_choice (Orientation, _("Orientation:"),
+ _("The toolbar orientation"),
+ GbOrientationChoices);
+ property_add_choice (Style, _("Style:"),
+ _("The toolbar style"),
+ GbStyleChoices);
+ property_add_bool (Tooltips, _("Tooltips:"), _("If tooltips are enabled"));
+ property_add_bool (ShowArrow, _("Show Arrow:"), _("If an arrow should be shown to popup a menu if the toolbar doesn't fit"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_toolbar_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ if (data->action != GB_SAVING)
+ gb_widget_output_int (data, Size,
+ gtk_toolbar_get_n_items (GTK_TOOLBAR (widget)));
+
+ for (i = 0; i < sizeof (GbOrientationValues)
+ / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (GbOrientationValues[i] == GTK_TOOLBAR (widget)->orientation)
+ gb_widget_output_choice (data, Orientation, i, GbOrientationSymbols[i]);
+ }
+
+ for (i = 0; i < sizeof (GbStyleValues) / sizeof (GbStyleValues[0]); i++)
+ {
+ if (GbStyleValues[i] == GTK_TOOLBAR (widget)->style)
+ gb_widget_output_choice (data, Style, i, GbStyleSymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Tooltips,
+ GTK_TOOLTIPS (GTK_TOOLBAR (widget)->tooltips)->enabled);
+
+ gb_widget_output_bool (data, ShowArrow,
+ gtk_toolbar_get_show_arrow (GTK_TOOLBAR (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_toolbar_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *orientation, *style;
+ gint i, size;
+ gboolean tooltips, show_arrow;
+
+ size = gb_widget_input_int (data, Size);
+ if (data->apply)
+ update_toolbar_size (widget, size);
+
+ orientation = gb_widget_input_choice (data, Orientation);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbOrientationValues)
+ / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (!strcmp (orientation, GbOrientationChoices[i])
+ || !strcmp (orientation, GbOrientationSymbols[i]))
+ {
+ gtk_toolbar_set_orientation (GTK_TOOLBAR (widget),
+ GbOrientationValues[i]);
+ break;
+ }
+ }
+ }
+
+ style = gb_widget_input_choice (data, Style);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbStyleValues) / sizeof (GbStyleValues[0]); i++
+ )
+ {
+ if (!strcmp (style, GbStyleChoices[i])
+ || !strcmp (style, GbStyleSymbols[i]))
+ {
+ /* This avoids any problems with redrawing the selection. */
+ if (data->action == GB_APPLYING)
+ editor_clear_selection (NULL);
+ gtk_toolbar_set_style (GTK_TOOLBAR (widget), GbStyleValues[i]);
+ /*editor_refresh_widget (widget);*/
+ break;
+ }
+ }
+ }
+
+ tooltips = gb_widget_input_bool (data, Tooltips);
+ if (data->apply)
+ gtk_toolbar_set_tooltips (GTK_TOOLBAR (widget), tooltips);
+
+ show_arrow = gb_widget_input_bool (data, ShowArrow);
+ if (data->apply)
+ gtk_toolbar_set_show_arrow (GTK_TOOLBAR (widget), show_arrow);
+}
+
+
+/* This updates the toolbar size to the given value, adding buttons or
+ deleting items as necessary. */
+static void
+update_toolbar_size (GtkWidget * widget, gint size)
+{
+ gint current_size;
+
+ current_size = gtk_toolbar_get_n_items (GTK_TOOLBAR (widget));
+
+ if (current_size < size)
+ {
+ /* FIXME: This avoids any problems with redrawing the selection. */
+ editor_clear_selection (NULL);
+
+ while (current_size < size)
+ {
+ GtkWidget *toolitem, *placeholder;
+
+ toolitem = (GtkWidget*) gtk_tool_item_new ();
+ gtk_widget_show (toolitem);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (toolitem), -1);
+
+ placeholder = editor_new_placeholder ();
+ gtk_container_add (GTK_CONTAINER (toolitem), placeholder);
+
+ current_size++;
+ }
+ }
+ else if (current_size > size)
+ {
+ while (current_size > size)
+ {
+ GtkToolItem *item;
+
+ item = gtk_toolbar_get_nth_item (GTK_TOOLBAR (widget), size);
+ gtk_container_remove (GTK_CONTAINER (widget), GTK_WIDGET (item));
+ current_size--;
+ }
+ }
+}
+
+
+static void
+gb_toolbar_create_child_properties (GtkWidget * widget,
+ GbWidgetCreateChildArgData * data)
+{
+ property_add_bool (Expand, _("Expand:"),
+ _("Set True to let the widget expand"));
+ property_add_bool (Homogeneous, _("Homogeneous:"),
+ _("If the item should be the same size as other homogeneous items"));
+}
+
+
+static void
+gb_toolbar_get_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetGetArgData *data)
+{
+ if (data->action == GB_SAVING)
+ save_start_tag (data, "packing");
+
+ gb_widget_output_bool (data, Expand,
+ gtk_tool_item_get_expand (GTK_TOOL_ITEM (child)));
+ gb_widget_output_bool (data, Homogeneous,
+ gtk_tool_item_get_homogeneous (GTK_TOOL_ITEM (child)));
+
+ if (data->action == GB_SAVING)
+ save_end_tag (data, "packing");
+}
+
+
+/* Migrate old 2.0 XML files. We insert a separator tool item. */
+static void
+gb_toolbar_set_new_group (GtkWidget *widget, GtkWidget *child)
+{
+ gint pos;
+ GtkWidget *separator;
+
+ pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (widget),
+ GTK_TOOL_ITEM (child));
+
+ /* We use gb_widget_new_full() passing FALSE for create_default_name,
+ since we are loading and we don't want to create any names while loading
+ or they may clash. */
+ separator = gb_widget_new_full ("GtkSeparatorToolItem", FALSE,
+ widget, NULL, 0, 0, NULL,
+ GB_LOADING, NULL);
+
+ gtk_toolbar_insert (GTK_TOOLBAR (widget), GTK_TOOL_ITEM (separator), pos);
+}
+
+
+static void
+gb_toolbar_set_child_properties (GtkWidget *widget, GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gboolean new_group, expand, homogeneous;
+
+ /* Migrate old 2.0 XML files. */
+ if (data->action == GB_LOADING)
+ {
+ new_group = gb_widget_input_bool (data, "new_group");
+ if (data->apply && new_group)
+ gb_toolbar_set_new_group (widget, child);
+ }
+
+ expand = gb_widget_input_bool (data, Expand);
+ if (data->apply)
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (child), expand);
+
+ homogeneous = gb_widget_input_bool (data, Homogeneous);
+ if (data->apply)
+ gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), homogeneous);
+}
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkToolbar, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_toolbar_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+{
+ GtkWidget *menuitem;
+
+ if (data->child == NULL)
+ return;
+
+ /* Commands for inserting new items. */
+ menuitem = gtk_menu_item_new_with_label (_("Insert Item Before"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_toolbar_insert_before),
+ data->child);
+
+ menuitem = gtk_menu_item_new_with_label (_("Insert Item After"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_toolbar_insert_after),
+ data->child);
+}
+
+
+static void
+gb_toolbar_insert_before (GtkWidget * menuitem, GtkWidget * child)
+{
+ gb_toolbar_insert (child, -1);
+}
+
+
+static void
+gb_toolbar_insert_after (GtkWidget * menuitem, GtkWidget * child)
+{
+ gb_toolbar_insert (child, 1);
+}
+
+
+static void
+gb_toolbar_insert (GtkWidget * child, gint offset)
+{
+ GtkWidget *toolbar = child->parent, *toolitem, *placeholder;
+ gint pos;
+
+ pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar),
+ GTK_TOOL_ITEM (child));
+
+ if (offset > 0)
+ pos++;
+
+ toolitem = (GtkWidget*) gtk_tool_item_new ();
+ gtk_widget_show (toolitem);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), (GtkToolItem*) toolitem, pos);
+
+ placeholder = editor_new_placeholder ();
+ gtk_container_add (GTK_CONTAINER (toolitem), placeholder);
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_toolbar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *orientation = GbOrientationSymbols[0];
+ const gchar *style = GbStyleSymbols[0];
+ gint i;
+
+ for (i = 0;
+ i < sizeof (GbOrientationValues) / sizeof (GbOrientationValues[0]); i++)
+ {
+ if (GbOrientationValues[i] == GTK_TOOLBAR (widget)->orientation)
+ orientation = GbOrientationSymbols[i];
+ }
+
+ for (i = 0; i < sizeof (GbStyleValues) / sizeof (GbStyleValues[0]); i++)
+ {
+ if (GbStyleValues[i] == GTK_TOOLBAR (widget)->style)
+ style = GbStyleSymbols[i];
+ }
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_toolbar_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* We have to set the style explicitly for now, as the default style depends
+ on the user's theme settings. Ideally GTK+ should have a
+ GTK_TOOLBAR_DEFAULT style. */
+ source_add (data,
+ " gtk_toolbar_set_style (GTK_TOOLBAR (%s), %s);\n",
+ data->wname, style);
+
+ if (GTK_TOOLBAR (widget)->orientation != GTK_ORIENTATION_HORIZONTAL)
+ source_add (data,
+ " gtk_toolbar_set_orientation (GTK_TOOLBAR (%s), %s);\n",
+ data->wname, orientation);
+
+ if (!GTK_TOOLTIPS (GTK_TOOLBAR (widget)->tooltips)->enabled)
+ source_add (data,
+ " gtk_toolbar_set_tooltips (GTK_TOOLBAR (%s), FALSE);\n",
+ data->wname);
+
+ if (!gtk_toolbar_get_show_arrow (GTK_TOOLBAR (widget)))
+ source_add (data,
+ " gtk_toolbar_set_show_arrow (GTK_TOOLBAR (%s), FALSE);\n",
+ data->wname);
+
+ /* We set up a tmp_toolbar_icon_size variable that we can use when creating
+ the tool items. */
+ source_ensure_decl (data, " GtkIconSize tmp_toolbar_icon_size;\n");
+ source_add (data,
+ " tmp_toolbar_icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (%s));\n",
+ data->wname);
+}
+
+
+static void
+gb_toolbar_write_add_child_source (GtkWidget *parent,
+ const char *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData *data)
+{
+ gboolean homogeneous, output_homogeneous = FALSE;
+
+ if (gtk_tool_item_get_expand (GTK_TOOL_ITEM (child)))
+ {
+ source_add (data,
+ " gtk_tool_item_set_expand (GTK_TOOL_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+
+ /* Homogeneous defaults to FALSE for GtkToolItem, but TRUE for
+ GtkToolButton and descendants. */
+ homogeneous = gtk_tool_item_get_homogeneous (GTK_TOOL_ITEM (child));
+ if (GTK_IS_TOOL_BUTTON (child))
+ {
+ if (!homogeneous)
+ output_homogeneous = TRUE;
+ }
+ else
+ {
+ if (homogeneous)
+ output_homogeneous = TRUE;
+ }
+
+ if (output_homogeneous)
+ {
+ source_add (data,
+ " gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (%s), %s);\n",
+ data->wname,
+ homogeneous ? "TRUE" : "FALSE");
+ }
+
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_toolbar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_toolbar_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = toolbar_xpm;
+ gbwidget.tooltip = _("Toolbar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_toolbar_new;
+ gbwidget.gb_widget_add_child = gb_toolbar_add_child;
+ gbwidget.gb_widget_create_properties = gb_toolbar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_toolbar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_toolbar_set_properties;
+ gbwidget.gb_widget_create_child_properties = gb_toolbar_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_toolbar_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_toolbar_set_child_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_toolbar_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_toolbar_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_toolbar_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbtoolbutton.c b/tools/glade/glade/gbwidgets/gbtoolbutton.c
new file mode 100644
index 00000000..471865ed
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtoolbutton.c
@@ -0,0 +1,602 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/toolbutton.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/*
+ * Our internal representation is slightly different to the saved XML,
+ * since it is awkward to support all the GtkToolButton properties.
+ * We only support stock buttons, or simple labels and icons. We don't
+ * support arbitrary label and icon widgets, partly because the Glade DTD
+ * can't handle them at present.
+ *
+ * If a stock_id is set within Glade, both the label and icon are set
+ * and these properties are made insensitive in the property editor.
+ *
+ * If no stock_id is set within Glade, the user can enter a label and use
+ * a stock icon or an icon from a file. Note that if a stock icon is used it
+ * will be saved as the "stock_id" property and the label will then override
+ * the stock label. So when loading if we find a "stock_id" property we check
+ * if a "label" property is present. If it isn't, we set Glade's "stock_id"
+ * property. If it is, we set Glade's "icon" property to the stock value
+ * instead. Phew.
+ */
+static gchar *StockButton = "GtkToolButton::stock_id";
+static gchar *Label = "GtkToolButton::label";
+static gchar *Icon = "GtkToolButton::icon";
+static gchar *VisibleHorz = "GtkToolButton|GtkToolItem::visible_horizontal";
+static gchar *VisibleVert = "GtkToolButton|GtkToolItem::visible_vertical";
+static gchar *IsImportant = "GtkToolButton|GtkToolItem::is_important";
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkToolButton, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_tool_button_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *image;
+ GbWidget *pixmap_gbwidget;
+
+ /* Place the pixmap icon in the button initially (even when loading). */
+ pixmap_gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (pixmap_gbwidget)
+ {
+ image = gtk_image_new_from_pixmap (pixmap_gbwidget->gdkpixmap,
+ pixmap_gbwidget->mask);
+ }
+ else
+ {
+ image = gtk_image_new ();
+ g_warning ("Couldn't find GtkPixmap data");
+ }
+ gtk_widget_show (image);
+
+ new_widget = (GtkWidget*) gtk_tool_button_new (image, "");
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_tool_button_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_stock_item (StockButton, _("Stock Button:"),
+ _("The stock button to use"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_text (Label, _("Label:"), _("The text to display"), 2);
+ property_add_icon (Icon, _("Icon:"),
+ _("The icon to display"),
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ property_add_bool (VisibleHorz, _("Show Horizontal:"),
+ _("If the item is visible when the toolbar is horizontal"));
+ property_add_bool (VisibleVert, _("Show Vertical:"),
+ _("If the item is visible when the toolbar is vertical"));
+ property_add_bool (IsImportant, _("Is Important:"),
+ _("If the item's text should be shown when the toolbar's mode is GTK_TOOLBAR_BOTH_HORIZ"));
+}
+
+
+void
+gb_tool_button_get_standard_properties (GtkWidget *widget,
+ GbWidgetGetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *visible_horz_p,
+ gchar *visible_vert_p,
+ gchar *is_important_p)
+{
+ gchar *stock_id, *label, *icon_name;
+ gboolean label_sensitive = TRUE;
+ gboolean icon_sensitive = TRUE;
+
+ /* We use the icon size from the parent toolbar. */
+ if (data->action == GB_SHOWING)
+ {
+ GtkIconSize icon_size;
+
+ icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (widget->parent));
+ property_set_stock_item_icon_size (stock_id_p, icon_size);
+ property_set_icon_size (icon_p, icon_size);
+ }
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey);
+ gb_widget_output_stock_item (data, stock_id_p, stock_id);
+ if (stock_id)
+ {
+ label_sensitive = FALSE;
+ icon_sensitive = FALSE;
+ }
+ else
+ {
+ label = (gchar*) gtk_tool_button_get_label (GTK_TOOL_BUTTON (widget));
+ gb_widget_output_translatable_text (data, label_p, label);
+
+ /* We always save use_underline as TRUE, though we don't load it. */
+ if (data->action == GB_SAVING)
+ gb_widget_output_bool (data, "use_underline", TRUE);
+
+ icon_name = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ /* When saving, we save stock icons as "stock_id". */
+ if (data->action == GB_SAVING
+ && glade_util_check_is_stock_id (icon_name))
+ gb_widget_output_icon (data, "stock_id", icon_name);
+ else
+ gb_widget_output_icon (data, icon_p, icon_name);
+ }
+
+ if (data->action == GB_SHOWING)
+ {
+ if (!label_sensitive)
+ gb_widget_output_translatable_text (data, label_p, "");
+ property_set_sensitive (label_p, label_sensitive);
+
+ if (!icon_sensitive)
+ gb_widget_output_pixmap_filename (data, icon_p, "");
+ property_set_sensitive (icon_p, icon_sensitive);
+ }
+
+ gb_widget_output_bool (data, visible_horz_p,
+ gtk_object_get_data (GTK_OBJECT (widget), visible_horz_p)
+ != NULL ? FALSE : TRUE);
+
+ gb_widget_output_bool (data, visible_vert_p,
+ gtk_object_get_data (GTK_OBJECT (widget), visible_vert_p)
+ != NULL ? FALSE : TRUE);
+
+ gb_widget_output_bool (data, is_important_p,
+ gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)));
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_tool_button_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_tool_button_get_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+}
+
+
+
+static void
+gb_tool_button_set_icon (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *icon_name)
+{
+ GtkWidget *image;
+ gchar *old_icon_name;
+
+ if (icon_name && !*icon_name)
+ icon_name = NULL;
+
+ /* Remove the old icon_name stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ old_icon_name = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ glade_project_remove_pixmap (data->project, old_icon_name);
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ GtkIconSize icon_size;
+
+ icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (widget->parent));
+ image = gtk_image_new_from_stock (icon_name, icon_size);
+ }
+ else if (icon_name)
+ {
+ image = gtk_image_new_from_file (icon_name);
+ glade_project_add_pixmap (data->project, icon_name);
+ }
+ else
+ {
+ GbWidget *pixmap_gbwidget;
+
+ pixmap_gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (pixmap_gbwidget)
+ {
+ image = gtk_image_new_from_pixmap (pixmap_gbwidget->gdkpixmap,
+ pixmap_gbwidget->mask);
+ }
+ else
+ {
+ image = gtk_image_new ();
+ g_warning ("Couldn't find GtkPixmap data");
+ }
+ }
+
+ gtk_widget_show (image);
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (widget), image);
+
+ gtk_object_set_data_full (GTK_OBJECT (widget), GladeToolButtonIconKey,
+ g_strdup (icon_name),
+ icon_name ? g_free : NULL);
+}
+
+
+static void
+gb_tool_button_set_stock_id (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id,
+ gboolean apply_label,
+ gchar *label_p,
+ gchar *icon_p)
+{
+ gboolean is_stock_item;
+
+ is_stock_item = glade_util_check_is_stock_id (stock_id);
+
+ if (is_stock_item)
+ {
+ gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (widget), stock_id);
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (widget), NULL);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (widget), NULL);
+
+ /* If we are loading, and label is set, then this is a stock icon
+ rather than a stock button (at least within Glade). */
+ if (data->action == GB_LOADING && apply_label)
+ {
+ gtk_object_set_data_full (GTK_OBJECT (widget),
+ GladeToolButtonIconKey,
+ g_strdup (stock_id), g_free);
+ }
+ else
+ {
+ gtk_object_set_data_full (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey,
+ g_strdup (stock_id), g_free);
+ gtk_object_set_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey, NULL);
+ }
+ }
+ else
+ {
+ /* It isn't a stock ID, so assume "None" has been selected and make
+ it a normal toolbar button. */
+ GtkWidget *image;
+ GbWidget *pixmap_gbwidget;
+
+ pixmap_gbwidget = gb_widget_lookup_class ("GtkImage");
+ if (pixmap_gbwidget)
+ {
+ image = gtk_image_new_from_pixmap (pixmap_gbwidget->gdkpixmap,
+ pixmap_gbwidget->mask);
+ }
+ else
+ {
+ image = gtk_image_new ();
+ g_warning ("Couldn't find GtkPixmap data");
+ }
+ gtk_widget_show (image);
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (widget), image);
+
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (widget), "");
+
+ gtk_object_set_data (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey, NULL);
+ gtk_object_set_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey, NULL);
+ }
+
+ /* If the widget's properties are displayed, we update the sensitivity of
+ the label and icon, according to whether a stock item is selected. */
+ if (data->action == GB_APPLYING && property_get_widget () == widget)
+ {
+ property_set_sensitive (label_p, !is_stock_item);
+ property_set_sensitive (icon_p, !is_stock_item);
+
+ /* Turn off auto-apply, and set the label. */
+ property_set_auto_apply (FALSE);
+ property_set_text (label_p, "");
+ property_set_filename (icon_p, "");
+ property_set_auto_apply (TRUE);
+ }
+}
+
+
+void
+gb_tool_button_set_standard_properties (GtkWidget *widget,
+ GbWidgetSetArgData * data,
+ gchar *stock_id_p,
+ gchar *label_p,
+ gchar *icon_p,
+ gchar *visible_horz_p,
+ gchar *visible_vert_p,
+ gchar *is_important_p)
+{
+ gchar *label, *stock_id, *icon_name;
+ gboolean apply_label;
+ gboolean visible_horz, visible_vert, is_important;
+
+ label = gb_widget_input_text (data, label_p);
+ apply_label = data->apply;
+
+ stock_id = gb_widget_input_stock_item (data, stock_id_p);
+ if (data->apply)
+ {
+ gb_tool_button_set_stock_id (widget, data, stock_id, apply_label,
+ label_p, icon_p);
+ }
+ else if (data->action == GB_LOADING)
+ {
+ /* Migrate old 2.0 XML files. */
+ gboolean use_stock = gb_widget_input_bool (data, "use_stock");
+ if (data->apply && use_stock && apply_label)
+ {
+ gb_tool_button_set_stock_id (widget, data, label, FALSE,
+ label_p, icon_p);
+ apply_label = FALSE;
+ }
+ }
+
+ icon_name = gb_widget_input_icon (data, icon_p);
+ if (data->apply)
+ {
+ gb_tool_button_set_icon (widget, data, icon_name);
+ }
+ else if (data->action == GB_LOADING)
+ {
+ /* Migrate old 2.0 XML files. */
+ icon_name = gb_widget_input_icon (data, "stock_pixmap");
+ if (data->apply)
+ {
+ gb_tool_button_set_icon (widget, data, icon_name);
+ }
+ else
+ {
+ icon_name = gb_widget_input_icon (data, "icon");
+ if (data->apply)
+ {
+ gb_tool_button_set_icon (widget, data, icon_name);
+ }
+ }
+ }
+
+ if (apply_label)
+ {
+ gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (widget), TRUE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (widget), label);
+ }
+
+ if (data->action == GB_APPLYING)
+ g_free (label);
+
+
+ visible_horz = gb_widget_input_bool (data, visible_horz_p);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), visible_horz_p,
+ visible_horz ? NULL : "FALSE");
+ }
+
+ visible_vert = gb_widget_input_bool (data, visible_vert_p);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), visible_vert_p,
+ visible_vert ? NULL : "FALSE");
+ }
+
+ is_important = gb_widget_input_bool (data, is_important_p);
+ if (data->apply)
+ {
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), is_important);
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_tool_button_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_tool_button_set_standard_properties (widget, data,
+ StockButton, Label, Icon,
+ VisibleHorz, VisibleVert,
+ IsImportant);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkToolButton, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_tool_button_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_tool_button_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *stock_id, *label, *icon_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonStockIDKey);
+ icon_name = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ label = (gchar*) gtk_tool_button_get_label (GTK_TOOL_BUTTON (widget));
+
+ glade_util_get_translation_properties (widget, Label, &translatable,
+ &comments, &context);
+
+ if (data->create_widget)
+ {
+ if (stock_id)
+ {
+ /* Stock Button */
+ source_add (data,
+ " %s = (GtkWidget*) gtk_tool_button_new_from_stock (%s);\n",
+ data->wname, source_make_string (stock_id, FALSE));
+ }
+ else if (icon_name)
+ {
+ /* Icon and Label */
+ source_ensure_decl (data, " GtkWidget *tmp_image;\n");
+
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ source_add (data,
+ " tmp_image = gtk_image_new_from_stock (\"%s\", tmp_toolbar_icon_size);\n",
+ icon_name);
+ }
+ else
+ {
+ source_create_pixmap (data, "tmp_image", icon_name);
+ }
+
+ source_add (data, " gtk_widget_show (tmp_image);\n");
+
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " %s = (GtkWidget*) gtk_tool_button_new (tmp_image, %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+ }
+ else
+ {
+ /* Just a Label */
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " %s = (GtkWidget*) gtk_tool_button_new (NULL, %s);\n",
+ data->wname,
+ label ? source_make_string_full (label, data->use_gettext && translatable, context) : "NULL");
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleVert) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)))
+ {
+ source_add (data,
+ " gtk_tool_item_set_is_important (GTK_TOOL_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+/* Note that Radio/Toggle tool buttons use this function as well. */
+void
+gb_tool_button_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ gchar *filename;
+
+ /* This can be a stock id or a filename. But glade_project_remove_pixmap()
+ will just ignore it if it isn't a project pixmap file. */
+ filename = gtk_object_get_data (GTK_OBJECT (widget),
+ GladeToolButtonIconKey);
+ glade_project_remove_pixmap (data->project, filename);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_tool_button_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_tool_button_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = toolbutton_xpm;
+ gbwidget.tooltip = _("Toolbar Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_tool_button_new;
+ gbwidget.gb_widget_create_properties = gb_tool_button_create_properties;
+ gbwidget.gb_widget_get_properties = gb_tool_button_get_properties;
+ gbwidget.gb_widget_set_properties = gb_tool_button_set_properties;
+ gbwidget.gb_widget_write_source = gb_tool_button_write_source;
+ gbwidget.gb_widget_destroy = gb_tool_button_destroy;
+
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_tool_button_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbtoolitem.c b/tools/glade/glade/gbwidgets/gbtoolitem.c
new file mode 100644
index 00000000..974a733f
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtoolitem.c
@@ -0,0 +1,215 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/toolitem.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *VisibleHorz = "GtkToolItem::visible_horizontal";
+static gchar *VisibleVert = "GtkToolItem::visible_vertical";
+static gchar *IsImportant = "GtkToolItem::is_important";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkToolItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_tool_item_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_tool_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (VisibleHorz, _("Show Horizontal:"),
+ _("If the item is visible when the toolbar is horizontal"));
+ property_add_bool (VisibleVert, _("Show Vertical:"),
+ _("If the item is visible when the toolbar is vertical"));
+ property_add_bool (IsImportant, _("Is Important:"),
+ _("If the item's text should be shown when the toolbar's mode is GTK_TOOLBAR_BOTH_HORIZ"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_tool_item_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, VisibleHorz,
+ gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz)
+ != NULL ? FALSE : TRUE);
+
+ gb_widget_output_bool (data, VisibleVert,
+ gtk_object_get_data (GTK_OBJECT (widget), VisibleVert)
+ != NULL ? FALSE : TRUE);
+
+ gb_widget_output_bool (data, IsImportant,
+ gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_tool_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean visible_horz, visible_vert, is_important;
+
+ visible_horz = gb_widget_input_bool (data, VisibleHorz);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), VisibleHorz,
+ visible_horz ? NULL : "FALSE");
+ }
+
+ visible_vert = gb_widget_input_bool (data, VisibleVert);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), VisibleVert,
+ visible_vert ? NULL : "FALSE");
+ }
+
+ is_important = gb_widget_input_bool (data, IsImportant);
+ if (data->apply)
+ {
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), is_important);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkToolItem, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_tool_item_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_tool_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = (GtkWidget*) gtk_tool_item_new ();\n",
+ data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleHorz) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), VisibleVert) != NULL)
+ {
+ source_add (data,
+ " gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (widget)))
+ {
+ source_add (data,
+ " gtk_tool_item_set_is_important (GTK_TOOL_ITEM (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_tool_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_tool_item_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = toolitem_xpm;
+ gbwidget.tooltip = _("Toolbar Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_tool_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_tool_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_tool_item_set_properties;
+ gbwidget.gb_widget_write_source = gb_tool_item_write_source;
+/*
+ gbwidget.gb_widget_new = gb_tool_item_new;
+ gbwidget.gb_widget_create_popup_menu = gb_tool_item_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbtreeview.c b/tools/glade/glade/gbwidgets/gbtreeview.c
new file mode 100644
index 00000000..3baebab0
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbtreeview.c
@@ -0,0 +1,331 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/ctree.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HeadersVisible = "GtkTreeView::headers_visible";
+static gchar *RulesHint = "GtkTreeView::rules_hint";
+static gchar *Reorderable = "GtkTreeView::reorderable";
+static gchar *EnableSearch = "GtkTreeView::enable_search";
+
+static gchar *FixedHeightMode = "GtkTreeView::fixed_height_mode";
+static gchar *HoverSelection = "GtkTreeView::hover_selection";
+static gchar *HoverExpand = "GtkTreeView::hover_expand";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkTreeView, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_tree_view_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *rend;
+ char buf[256];
+ gint i;
+
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ new_widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+
+ /* We set the columns to a fixed size, since the "fixed_height_mode"
+ property requires that. */
+ rend = gtk_cell_renderer_text_new ();
+ col = gtk_tree_view_column_new_with_attributes (_("Column 1"), rend,
+ "text", 0,
+ NULL);
+ gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (col, 100);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (new_widget), col);
+
+ rend = gtk_cell_renderer_text_new ();
+ col = gtk_tree_view_column_new_with_attributes (_("Column 2"), rend,
+ "text", 1,
+ NULL);
+ gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (col, 100);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (new_widget), col);
+
+ rend = gtk_cell_renderer_text_new ();
+ col = gtk_tree_view_column_new_with_attributes (_("Column 3"), rend,
+ "text", 2,
+ NULL);
+ gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (col, 100);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (new_widget), col);
+
+ for (i = 1; i <= 8; i++)
+ {
+ gtk_list_store_append (store, &iter);
+ sprintf (buf, _("Row %i"), i);
+ gtk_list_store_set (store, &iter, 0, buf, 1, "...", 2, "...", -1);
+ }
+
+ g_object_unref (G_OBJECT (store));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_tree_view_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (HeadersVisible, _("Headers Visible:"),
+ _("If the column header buttons are shown"));
+ property_add_bool (RulesHint, _("Rules Hint:"),
+ _("If a hint is set so the theme engine should draw rows in alternating colors"));
+ property_add_bool (Reorderable, _("Reorderable:"),
+ _("If the view is reorderable"));
+ property_add_bool (EnableSearch, _("Enable Search:"),
+ _("If the user can search through columns interactively"));
+
+ property_add_bool (FixedHeightMode, _("Fixed Height Mode:"),
+ _("Sets all rows to the same height to improve performance"));
+ property_add_bool (HoverSelection, _("Hover Selection:"),
+ _("Whether the selection should follow the pointer"));
+ property_add_bool (HoverExpand, _("Hover Expand:"),
+ _("Whether rows should be expanded or collapsed when the pointer moves over them"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_tree_view_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gboolean headers_visible, rules_hint, reorderable, enable_search;
+ gboolean fixed_height_mode, hover_selection, hover_expand;
+
+ g_object_get (G_OBJECT (widget),
+ "headers_visible", &headers_visible,
+ "rules_hint", &rules_hint,
+ "reorderable", &reorderable,
+ "enable_search", &enable_search,
+ "fixed_height_mode", &fixed_height_mode,
+ "hover_selection", &hover_selection,
+ "hover_expand", &hover_expand,
+ NULL);
+
+ gb_widget_output_bool (data, HeadersVisible, headers_visible);
+ gb_widget_output_bool (data, RulesHint, rules_hint);
+ gb_widget_output_bool (data, Reorderable, reorderable);
+ gb_widget_output_bool (data, EnableSearch, enable_search);
+ gb_widget_output_bool (data, FixedHeightMode, fixed_height_mode);
+ gb_widget_output_bool (data, HoverSelection, hover_selection);
+ gb_widget_output_bool (data, HoverExpand, hover_expand);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_tree_view_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean headers_visible, rules_hint, reorderable, enable_search;
+ gboolean fixed_height_mode, hover_selection, hover_expand;
+
+ headers_visible = gb_widget_input_bool (data, HeadersVisible);
+ if (data->apply)
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), headers_visible);
+
+ rules_hint = gb_widget_input_bool (data, RulesHint);
+ if (data->apply)
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (widget), rules_hint);
+
+ reorderable = gb_widget_input_bool (data, Reorderable);
+ if (data->apply)
+ gtk_tree_view_set_reorderable (GTK_TREE_VIEW (widget), reorderable);
+
+ enable_search = gb_widget_input_bool (data, EnableSearch);
+ if (data->apply)
+ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (widget), enable_search);
+
+ fixed_height_mode = gb_widget_input_bool (data, FixedHeightMode);
+ if (data->apply)
+ gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (widget), fixed_height_mode);
+
+ hover_selection = gb_widget_input_bool (data, HoverSelection);
+ if (data->apply)
+ gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (widget), hover_selection);
+
+ hover_expand = gb_widget_input_bool (data, HoverExpand);
+ if (data->apply)
+ gtk_tree_view_set_hover_expand (GTK_TREE_VIEW (widget), hover_expand);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkTreeView, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_tree_view_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_tree_view_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean headers_visible, rules_hint, reorderable, enable_search;
+ gboolean fixed_height_mode, hover_selection, hover_expand;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_tree_view_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ g_object_get (G_OBJECT (widget),
+ "headers_visible", &headers_visible,
+ "rules_hint", &rules_hint,
+ "reorderable", &reorderable,
+ "enable_search", &enable_search,
+ "fixed_height_mode", &fixed_height_mode,
+ "hover_selection", &hover_selection,
+ "hover_expand", &hover_expand,
+ NULL);
+
+ if (!headers_visible)
+ {
+ source_add (data,
+ " gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (rules_hint)
+ {
+ source_add (data,
+ " gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (reorderable)
+ {
+ source_add (data,
+ " gtk_tree_view_set_reorderable (GTK_TREE_VIEW (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!enable_search)
+ {
+ source_add (data,
+ " gtk_tree_view_set_enable_search (GTK_TREE_VIEW (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (fixed_height_mode)
+ {
+ source_add (data,
+ " gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (hover_selection)
+ {
+ source_add (data,
+ " gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (hover_expand)
+ {
+ source_add (data,
+ " gtk_tree_view_set_hover_expand (GTK_TREE_VIEW (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_tree_view_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_tree_view_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = ctree_xpm;
+ gbwidget.tooltip = _("List or Tree View");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_tree_view_new;
+ gbwidget.gb_widget_create_properties = gb_tree_view_create_properties;
+ gbwidget.gb_widget_get_properties = gb_tree_view_get_properties;
+ gbwidget.gb_widget_set_properties = gb_tree_view_set_properties;
+ gbwidget.gb_widget_write_source = gb_tree_view_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_tree_view_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gbwidgets/gbvbox.c b/tools/glade/glade/gbwidgets/gbvbox.c
new file mode 100644
index 00000000..fcdc580d
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvbox.c
@@ -0,0 +1,261 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkvbox.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vbox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Size = "VBox|GtkBox::size";
+static gchar *Homogeneous = "VBox|GtkBox::homogeneous";
+static gchar *Spacing = "VBox|GtkBox::spacing";
+
+static void show_vbox_dialog (GbWidgetNewData * data);
+static void on_vbox_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_vbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_vbox_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gtk_vbox_new (FALSE, 0);
+ return new_widget;
+ }
+ else
+ {
+ show_vbox_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_vbox_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New vertical box"), data->parent,
+ GTK_SIGNAL_FUNC (on_vbox_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_vbox_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of rows:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "rows",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_vbox_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *placeholder;
+ gint rows, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "rows");
+ g_return_if_fail (spinbutton != NULL);
+ rows = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_vbox_new (FALSE, 0);
+ for (i = 0; i < rows; i++)
+ {
+ placeholder = editor_new_placeholder ();
+ /*gtk_widget_set_usize(placeholder, 80, 60); */
+ gtk_box_pack_start (GTK_BOX (new_widget), placeholder, TRUE, TRUE, 0);
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_vbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_vbox_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_int_range (Size, _("Size:"), _("The number of widgets in the box"),
+ 0, 1000, 1, 10, 1);
+ property_add_bool (Homogeneous, _("Homogeneous:"),
+ _("If the children should be the same size"));
+ property_add_int_range (Spacing, _("Spacing:"), _("The space between each child"),
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_vbox_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ if (data->action != GB_SAVING)
+ gb_widget_output_int (data, Size, g_list_length (GTK_BOX (widget)->children));
+ gb_widget_output_bool (data, Homogeneous, GTK_BOX (widget)->homogeneous);
+ gb_widget_output_int (data, Spacing, GTK_BOX (widget)->spacing);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_vbox_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean homogeneous;
+ gint spacing, size;
+
+ if (data->action != GB_LOADING)
+ {
+ size = gb_widget_input_int (data, Size);
+ if (data->apply)
+ gb_box_set_size (widget, size);
+ }
+
+ homogeneous = gb_widget_input_bool (data, Homogeneous);
+ if (data->apply)
+ gtk_box_set_homogeneous (GTK_BOX (widget), homogeneous);
+
+ spacing = gb_widget_input_int (data, Spacing);
+ if (data->apply)
+ gtk_box_set_spacing (GTK_BOX (widget), spacing);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vbox_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_vbox_new (%s, %i);\n", data->wname,
+ GTK_BOX (widget)->homogeneous ? "TRUE" : "FALSE",
+ GTK_BOX (widget)->spacing);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vbox_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vbox_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vbox_xpm;
+ gbwidget.tooltip = _("Vertical Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vbox_new;
+ gbwidget.gb_widget_create_properties = gb_vbox_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vbox_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vbox_set_properties;
+ gbwidget.gb_widget_write_source = gb_vbox_write_source;
+
+ gbwidget.gb_widget_create_child_properties = gb_box_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_box_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_box_set_child_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_box_create_popup_menu;
+ gbwidget.gb_widget_write_add_child_source = gb_box_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbvbuttonbox.c b/tools/glade/glade/gbwidgets/gbvbuttonbox.c
new file mode 100644
index 00000000..2d581c76
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvbuttonbox.c
@@ -0,0 +1,357 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkvbbox.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkspinbutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vbuttonbox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Size = "VBBox|GtkBox::size";
+static gchar *Layout = "VBBox|GtkButtonBox::layout_style";
+static gchar *Spacing = "VBBox|GtkButtonBox::spacing";
+
+static const gchar *GbLayoutChoices[] =
+{"Default", "Spread", "Edge",
+ "Start", "End", NULL};
+static const gint GbLayoutValues[] =
+{
+ GTK_BUTTONBOX_DEFAULT_STYLE,
+ GTK_BUTTONBOX_SPREAD,
+ GTK_BUTTONBOX_EDGE,
+ GTK_BUTTONBOX_START,
+ GTK_BUTTONBOX_END
+};
+static const gchar *GbLayoutSymbols[] =
+{
+ "GTK_BUTTONBOX_DEFAULT_STYLE",
+ "GTK_BUTTONBOX_SPREAD",
+ "GTK_BUTTONBOX_EDGE",
+ "GTK_BUTTONBOX_START",
+ "GTK_BUTTONBOX_END"
+};
+
+
+/* FIXME: Hack - copied from gtkbbox.c. Should use GParam query instead,
+ or use an optional int property instead. */
+#define DEFAULT_CHILD_MIN_WIDTH 85
+#define DEFAULT_CHILD_MIN_HEIGHT 27
+#define DEFAULT_CHILD_IPAD_X 4
+#define DEFAULT_CHILD_IPAD_Y 0
+
+
+static void show_vbbox_dialog (GbWidgetNewData * data);
+static void on_vbbox_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_vbbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVButtonBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_vbutton_box_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gtk_vbutton_box_new ();
+ return new_widget;
+ }
+ else
+ {
+ show_vbbox_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_vbbox_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New vertical button box"),
+ data->parent,
+ GTK_SIGNAL_FUNC (on_vbbox_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_vbbox_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of rows:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "rows",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_vbbox_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *new_child;
+ gint rows, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "rows");
+ g_return_if_fail (spinbutton != NULL);
+ rows = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gtk_vbutton_box_new ();
+ for (i = 0; i < rows; i++)
+ {
+ new_child = gb_widget_new ("GtkButton", new_widget);
+ GTK_WIDGET_SET_FLAGS (new_child, GTK_CAN_DEFAULT);
+ gtk_container_add (GTK_CONTAINER (new_widget), new_child);
+ }
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_vbbox_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_vbutton_box_create_properties (GtkWidget * widget, GbWidgetCreateArgData *
+ data)
+{
+ property_add_int_range (Size, "Size:", "The number of buttons",
+ 0, 1000, 1, 10, 1);
+ property_add_choice (Layout, "Layout:",
+ "The layout style of the buttons",
+ GbLayoutChoices);
+ property_add_int_range (Spacing, "Spacing:", "The space between the buttons",
+ 0, 1000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_vbutton_box_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ GtkButtonBoxStyle layout;
+ gint i, spacing;
+
+ if (data->action != GB_SAVING)
+ gb_widget_output_int (data, Size, g_list_length (GTK_BOX (widget)->children));
+
+ layout = gtk_button_box_get_layout (GTK_BUTTON_BOX (widget));
+ for (i = 0; i < sizeof (GbLayoutValues) / sizeof (GbLayoutValues[0]); i++)
+ {
+ if (GbLayoutValues[i] == layout)
+ gb_widget_output_choice (data, Layout, i, GbLayoutSymbols[i]);
+ }
+
+ spacing = gtk_box_get_spacing (GTK_BOX (widget));
+ gb_widget_output_int (data, Spacing, spacing);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_vbutton_box_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint size, i, spacing;
+ gchar *layout;
+ gboolean queue_resize = FALSE;
+
+ if (data->action != GB_LOADING)
+ {
+ size = gb_widget_input_int (data, Size);
+ if (data->apply)
+ gb_box_set_size (widget, size);
+ }
+
+ layout = gb_widget_input_choice (data, Layout);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbLayoutValues) / sizeof (GbLayoutValues[0]); i
+ ++)
+ {
+ if (!strcmp (layout, GbLayoutChoices[i])
+ || !strcmp (layout, GbLayoutSymbols[i]))
+ {
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (widget), GbLayoutValues
+ [i]);
+ queue_resize = TRUE;
+ break;
+ }
+ }
+ }
+
+ spacing = gb_widget_input_int (data, Spacing);
+ if (data->apply)
+ {
+ gtk_box_set_spacing (GTK_BOX (widget), spacing);
+ queue_resize = TRUE;
+ }
+
+ if (queue_resize)
+ gtk_widget_queue_resize (widget);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkVButtonBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_vbutton_box_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vbutton_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkButtonBoxStyle layout_style;
+ gint spacing, i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_vbutton_box_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ layout_style = GTK_BUTTON_BOX (widget)->layout_style;
+ if (layout_style != GTK_BUTTONBOX_DEFAULT_STYLE)
+ {
+ for (i = 0; i < sizeof (GbLayoutValues) / sizeof (GbLayoutValues[0]); i
+ ++)
+ {
+ if (GbLayoutValues[i] == layout_style)
+ source_add (data,
+ " gtk_button_box_set_layout (GTK_BUTTON_BOX (%s), %s);\n",
+ data->wname, GbLayoutSymbols[i]);
+ }
+ }
+
+ spacing = gtk_box_get_spacing (GTK_BOX (widget));
+ if (spacing != 0)
+ {
+ source_add (data,
+ " gtk_box_set_spacing (GTK_BOX (%s), %i);\n",
+ data->wname, spacing);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vbutton_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vbutton_box_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vbuttonbox_xpm;
+ gbwidget.tooltip = _("Vertical Button Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vbutton_box_new;
+ gbwidget.gb_widget_create_properties = gb_vbutton_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vbutton_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vbutton_box_set_properties;
+ gbwidget.gb_widget_write_source = gb_vbutton_box_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_vbutton_box_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbviewport.c b/tools/glade/glade/gbwidgets/gbviewport.c
new file mode 100644
index 00000000..8fc8777e
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbviewport.c
@@ -0,0 +1,253 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkviewport.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/viewport.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Shadow = "GtkViewport::shadow_type";
+
+/* I don't think there's any point in adding these. */
+/*
+ static gchar *HValues[] = {
+ "GtkViewport::hvalue",
+ "GtkViewport::hlower",
+ "GtkViewport::hupper",
+ "GtkViewport::hstep",
+ "GtkViewport::hpage",
+ "GtkViewport::hpage_size",
+ };
+
+ static gchar *VValues[] = {
+ "GtkViewport::vvalue",
+ "GtkViewport::vlower",
+ "GtkViewport::vupper",
+ "GtkViewport::vstep",
+ "GtkViewport::vpage",
+ "GtkViewport::vpage_size",
+ };
+ */
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkViewport, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_viewport_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_viewport_new (NULL, NULL);
+ if (data->action != GB_LOADING)
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_viewport_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Shadow, _("Shadow:"), _("The type of shadow of the viewport"),
+ GbShadowChoices);
+ /*
+ property_add_adjustment(HValues, GB_ADJUST_H_LABELS);
+ property_add_adjustment(VValues, GB_ADJUST_V_LABELS);
+ */
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_viewport_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == GTK_VIEWPORT (widget)->shadow_type)
+ gb_widget_output_choice (data, Shadow, i, GbShadowSymbols[i]);
+ }
+
+ /*
+ gb_widget_output_adjustment(data, HValues, GTK_VIEWPORT(widget)->hadjustment);
+ gb_widget_output_adjustment(data, VValues, GTK_VIEWPORT(widget)->vadjustment);
+ */
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_viewport_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint i;
+ gchar *shadow;
+
+ shadow = gb_widget_input_choice (data, Shadow);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget), GbShadowValues
+ [i]);
+ break;
+ }
+ }
+ }
+
+ /*
+ if (gb_widget_input_adjustment(data, HValues,
+ GTK_VIEWPORT(widget)->hadjustment))
+ gtk_signal_emit_by_name (GTK_OBJECT (GTK_VIEWPORT(widget)->hadjustment),
+ "value_changed");
+ if (gb_widget_input_adjustment(data, VValues,
+ GTK_VIEWPORT(widget)->vadjustment))
+ gtk_signal_emit_by_name (GTK_OBJECT (GTK_VIEWPORT(widget)->vadjustment),
+ "value_changed");
+ */
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkViewport, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_viewport_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_viewport_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_viewport_new (NULL, NULL);\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_VIEWPORT (widget)->shadow_type != GTK_SHADOW_IN)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i
+ ++)
+ {
+ if (GbShadowValues[i] == GTK_VIEWPORT (widget)->shadow_type)
+ source_add (data,
+ " gtk_viewport_set_shadow_type (GTK_VIEWPORT (%s), %s);\n",
+ data->wname, GbShadowSymbols[i]);
+ }
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_viewport_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_viewport_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = viewport_xpm;
+ gbwidget.tooltip = _("Viewport");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_viewport_new;
+ gbwidget.gb_widget_create_properties = gb_viewport_create_properties;
+ gbwidget.gb_widget_get_properties = gb_viewport_get_properties;
+ gbwidget.gb_widget_set_properties = gb_viewport_set_properties;
+ gbwidget.gb_widget_write_source = gb_viewport_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_viewport_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbvpaned.c b/tools/glade/glade/gbwidgets/gbvpaned.c
new file mode 100644
index 00000000..47a4d1b7
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvpaned.c
@@ -0,0 +1,209 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkvpaned.h>
+#include <gtk/gtktogglebutton.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vpaned.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Position = "VPaned|GtkPaned::position";
+
+static void on_toggle_position (GtkWidget * widget, gpointer value);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVPaned, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_vpaned_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_vpaned_new ();
+ if (data->action != GB_LOADING)
+ {
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ gtk_container_add (GTK_CONTAINER (new_widget), editor_new_placeholder ());
+ }
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_vpaned_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_optional_int_range (Position, _("Position:"),
+ _("The position of the divider"),
+ 1, 1000, 1, 10, 1,
+ on_toggle_position);
+}
+
+
+static void
+on_toggle_position (GtkWidget * button, gpointer value)
+{
+ GtkWidget *widget;
+ gboolean value_set;
+ gint position;
+
+ widget = property_get_widget ();
+ if (widget == NULL)
+ return;
+
+ value_set = GTK_TOGGLE_BUTTON (button)->active ? TRUE : FALSE;
+ gtk_widget_set_sensitive (GTK_WIDGET (value), value_set);
+
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Position));
+ gtk_paned_set_position (GTK_PANED (widget),
+ value_set ? position : -1);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_vpaned_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint position;
+
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Position));
+ gb_widget_output_optional_int (data, Position, position,
+ GTK_PANED (widget)->position_set);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_vpaned_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gint position;
+
+ position = gb_widget_input_int (data, Position);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), Position,
+ GINT_TO_POINTER (position));
+ gtk_paned_set_position (GTK_PANED (widget), position);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkVPaned, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_vpaned_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vpaned_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint position;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_vpaned_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_PANED (widget)->position_set)
+ {
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Position));
+ source_add (data, " gtk_paned_set_position (GTK_PANED (%s), %d);\n",
+ data->wname, position);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vpaned_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vpaned_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vpaned_xpm;
+ gbwidget.tooltip = _("Vertical Panes");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vpaned_new;
+ gbwidget.gb_widget_create_properties = gb_vpaned_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vpaned_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vpaned_set_properties;
+ gbwidget.gb_widget_create_child_properties = gb_paned_create_child_properties;
+ gbwidget.gb_widget_get_child_properties = gb_paned_get_child_properties;
+ gbwidget.gb_widget_set_child_properties = gb_paned_set_child_properties;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_vpaned_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_vpaned_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_paned_write_add_child_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbvruler.c b/tools/glade/glade/gbwidgets/gbvruler.c
new file mode 100644
index 00000000..f482df36
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvruler.c
@@ -0,0 +1,260 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkvruler.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vruler.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Metric = "VRuler|GtkRuler::metric";
+static gchar *Lower = "VRuler|GtkRuler::lower";
+static gchar *Upper = "VRuler|GtkRuler::upper";
+static gchar *Pos = "VRuler|GtkRuler::position";
+static gchar *Max = "VRuler|GtkRuler::max_size";
+
+static const gchar *GbMetricChoices[] =
+{"Pixels", "Inches", "Centimeters", NULL};
+static const gint GbMetricValues[] =
+{
+ GTK_PIXELS,
+ GTK_INCHES,
+ GTK_CENTIMETERS
+};
+static const gchar *GbMetricSymbols[] =
+{
+ "GTK_PIXELS",
+ "GTK_INCHES",
+ "GTK_CENTIMETERS"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVRuler, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_vruler_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget = gtk_vruler_new ();
+ gtk_ruler_set_range (GTK_RULER (new_widget), 0, 10, 0, 10);
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_vruler_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Metric, _("Metric:"),
+ _("The units of the ruler"),
+ GbMetricChoices);
+ property_add_float (Lower, _("Lower Value:"),
+ _("The low value of the ruler"));
+ property_add_float (Upper, _("Upper Value:"),
+ _("The low value of the ruler"));
+ property_add_float (Pos, _("Position:"),
+ _("The current position on the ruler"));
+ property_add_float (Max, _("Max:"),
+ _("The maximum value of the ruler"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_vruler_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gchar *metric_name;
+ gint i;
+
+ metric_name = GTK_RULER (widget)->metric->metric_name;
+ for (i = 0; i < sizeof (GbMetricValues) / sizeof (GbMetricValues[0]); i++)
+ {
+ if (!strcmp (GbMetricChoices[i], metric_name))
+ gb_widget_output_choice (data, Metric, i, GbMetricSymbols[i]);
+ }
+
+ gb_widget_output_float (data, Lower, GTK_RULER (widget)->lower);
+ gb_widget_output_float (data, Upper, GTK_RULER (widget)->upper);
+ gb_widget_output_float (data, Pos, GTK_RULER (widget)->position);
+ gb_widget_output_float (data, Max, GTK_RULER (widget)->max_size);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_vruler_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *metric;
+ gint i;
+ gfloat lower, upper, pos, max;
+ gboolean set_range = FALSE;
+
+ metric = gb_widget_input_choice (data, Metric);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbMetricValues) / sizeof (GbMetricValues[0]); i
+ ++)
+ {
+ if (!strcmp (metric, GbMetricChoices[i])
+ || !strcmp (metric, GbMetricSymbols[i]))
+ {
+ gtk_ruler_set_metric (GTK_RULER (widget), GbMetricValues[i]);
+ break;
+ }
+ }
+ }
+
+ lower = gb_widget_input_float (data, Lower);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ lower = GTK_RULER (widget)->lower;
+
+ upper = gb_widget_input_float (data, Upper);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ upper = GTK_RULER (widget)->upper;
+
+ pos = gb_widget_input_float (data, Pos);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ pos = GTK_RULER (widget)->position;
+
+ max = gb_widget_input_float (data, Max);
+ if (data->apply)
+ set_range = TRUE;
+ else
+ max = GTK_RULER (widget)->max_size;
+
+ if (set_range)
+ gtk_ruler_set_range (GTK_RULER (widget), lower, upper, pos, max);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkVRuler, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_vruler_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vruler_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *metric_name;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_vruler_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ metric_name = GTK_RULER (widget)->metric->metric_name;
+ if (strcmp (metric_name, "Pixels"))
+ {
+ for (i = 0; i < sizeof (GbMetricValues) / sizeof (GbMetricValues[0]); i
+ ++)
+ {
+ if (!strcmp (GbMetricChoices[i], metric_name))
+ source_add (data, " gtk_ruler_set_metric (GTK_RULER (%s), %s);\n",
+ data->wname, GbMetricSymbols[i]);
+ }
+ }
+ source_add (data, " gtk_ruler_set_range (GTK_RULER (%s), %g, %g, %g, %g);\n",
+ data->wname, GTK_RULER (widget)->lower, GTK_RULER (widget)->upper,
+ GTK_RULER (widget)->position, GTK_RULER (widget)->max_size);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vruler_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vruler_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vruler_xpm;
+ gbwidget.tooltip = _("Vertical Ruler");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vruler_new;
+ gbwidget.gb_widget_create_properties = gb_vruler_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vruler_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vruler_set_properties;
+ gbwidget.gb_widget_write_source = gb_vruler_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_vruler_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbvscale.c b/tools/glade/glade/gbwidgets/gbvscale.c
new file mode 100644
index 00000000..0f8166c6
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvscale.c
@@ -0,0 +1,332 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkvscale.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vscale.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *DrawValue = "VScale|GtkScale::draw_value";
+static gchar *ValuePos = "VScale|GtkScale::value_pos";
+static gchar *Digits = "VScale|GtkRange::digits";
+static gchar *Policy = "VScale|GtkRange::update_policy";
+static gchar *Inverted = "VScale|GtkRange::inverted";
+
+static const gchar *Values[] =
+{
+ "GtkVScale::value",
+ "GtkVScale::lower",
+ "GtkVScale::upper",
+ "GtkVScale::step",
+ "GtkVScale::page",
+ "GtkVScale::page_size",
+};
+
+static const gchar *GbValuePosChoices[] =
+{"Left", "Right", "Top", "Bottom", NULL};
+static const gint GbValuePosValues[] =
+{
+ GTK_POS_LEFT,
+ GTK_POS_RIGHT,
+ GTK_POS_TOP,
+ GTK_POS_BOTTOM
+};
+static const gchar *GbValuePosSymbols[] =
+{
+ "GTK_POS_LEFT",
+ "GTK_POS_RIGHT",
+ "GTK_POS_TOP",
+ "GTK_POS_BOTTOM"
+};
+
+static const gchar *GbPolicyChoices[] =
+{"Continuous", "Discontinuous", "Delayed",
+ NULL};
+static const gint GbPolicyValues[] =
+{
+ GTK_UPDATE_CONTINUOUS,
+ GTK_UPDATE_DISCONTINUOUS,
+ GTK_UPDATE_DELAYED
+};
+static const gchar *GbPolicySymbols[] =
+{
+ "GTK_UPDATE_CONTINUOUS",
+ "GTK_UPDATE_DISCONTINUOUS",
+ "GTK_UPDATE_DELAYED"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVScale, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_vscale_new (GbWidgetNewData * data)
+{
+ return gtk_vscale_new (NULL);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_vscale_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (DrawValue, _("Show Value:"), _("If the scale's value is shown"));
+ property_add_int_range (Digits, _("Digits:"), _("The number of digits to show"),
+ 0, 13, 1, 10, 1);
+ property_add_choice (ValuePos, _("Value Pos:"),
+ _("The position of the value"),
+ GbValuePosChoices);
+ property_add_choice (Policy, _("Policy:"),
+ _("The update policy of the scale"),
+ GbPolicyChoices);
+ property_add_bool (Inverted, _("Inverted:"), _("If the range values are inverted"));
+ property_add_adjustment (Values, GB_ADJUST_DEFAULT_LABELS);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_vscale_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ gb_widget_output_bool (data, DrawValue, GTK_SCALE (widget)->draw_value);
+
+ for (i = 0; i < sizeof (GbValuePosValues) / sizeof (GbValuePosValues[0]);
+ i++)
+ {
+ if (GbValuePosValues[i] == GTK_SCALE (widget)->value_pos)
+ gb_widget_output_choice (data, ValuePos, i, GbValuePosSymbols[i]);
+ }
+ gb_widget_output_int (data, Digits, GTK_SCALE (widget)->digits);
+
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ gb_widget_output_choice (data, Policy, i, GbPolicySymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Inverted, GTK_RANGE (widget)->inverted);
+
+ gb_widget_output_adjustment (data, Values, GTK_RANGE (widget)->adjustment,
+ "adjustment");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_vscale_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean draw_value, inverted;
+ gint digits, i;
+ gchar *valuepos, *policy;
+ GtkAdjustment *adj;
+
+ draw_value = gb_widget_input_bool (data, DrawValue);
+ if (data->apply)
+ {
+ gtk_scale_set_draw_value (GTK_SCALE (widget), draw_value);
+ /* Shouldn't really need to do this */
+ editor_refresh_widget (widget);
+ }
+
+ valuepos = gb_widget_input_choice (data, ValuePos);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbValuePosValues) / sizeof (GbValuePosValues[0]);
+ i++)
+ {
+ if (!strcmp (valuepos, GbValuePosChoices[i])
+ || !strcmp (valuepos, GbValuePosSymbols[i]))
+ {
+ gtk_scale_set_value_pos (GTK_SCALE (widget), GbValuePosValues[i]);
+ break;
+ }
+ }
+ }
+
+ digits = gb_widget_input_int (data, Digits);
+ if (data->apply)
+ gtk_scale_set_digits (GTK_SCALE (widget), digits);
+
+ policy = gb_widget_input_choice (data, Policy);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]);
+ i++)
+ {
+ if (!strcmp (policy, GbPolicyChoices[i])
+ || !strcmp (policy, GbPolicySymbols[i]))
+ {
+ gtk_range_set_update_policy (GTK_RANGE (widget),
+ GbPolicyValues[i]);
+ break;
+ }
+ }
+ }
+
+ inverted = gb_widget_input_bool (data, Inverted);
+ if (data->apply)
+ {
+ gtk_range_set_inverted (GTK_RANGE (widget), inverted);
+ }
+
+ adj = GTK_RANGE (widget)->adjustment;
+ if (gb_widget_input_adjustment (data, Values, adj, "adjustment"))
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkVScale, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_vscale_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vscale_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkAdjustment *adj = GTK_RANGE (widget)->adjustment;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = gtk_vscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (%g, %g, %g, %g, %g, %g)));\n",
+ data->wname, adj->value, adj->lower, adj->upper,
+ adj->step_increment, adj->page_increment, adj->page_size);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!GTK_SCALE (widget)->draw_value)
+ source_add (data, " gtk_scale_set_draw_value (GTK_SCALE (%s), FALSE);\n",
+ data->wname);
+
+ if (GTK_SCALE (widget)->value_pos != GTK_POS_TOP)
+ {
+ for (i = 0; i < sizeof (GbValuePosValues) / sizeof (GbValuePosValues[0]);
+ i++)
+ {
+ if (GbValuePosValues[i] == GTK_SCALE (widget)->value_pos)
+ source_add (data, " gtk_scale_set_value_pos (GTK_SCALE (%s), %s);\n",
+ data->wname, GbValuePosSymbols[i]);
+ }
+ }
+ if (GTK_SCALE (widget)->digits != 1)
+ source_add (data, " gtk_scale_set_digits (GTK_SCALE (%s), %i);\n",
+ data->wname, GTK_SCALE (widget)->digits);
+
+ if (GTK_RANGE (widget)->update_policy != GTK_UPDATE_CONTINUOUS)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ source_add (data, " gtk_range_set_update_policy (GTK_RANGE (%s), %s);\n",
+ data->wname, GbPolicySymbols[i]);
+ }
+ }
+
+ if (GTK_RANGE (widget)->inverted)
+ {
+ source_add (data,
+ " gtk_range_set_inverted (GTK_RANGE (%s), TRUE);\n",
+ data->wname);
+
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vscale_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vscale_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vscale_xpm;
+ gbwidget.tooltip = _("Vertical Scale");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vscale_new;
+ gbwidget.gb_widget_create_properties = gb_vscale_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vscale_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vscale_set_properties;
+ gbwidget.gb_widget_write_source = gb_vscale_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_vscale_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbvscrollbar.c b/tools/glade/glade/gbwidgets/gbvscrollbar.c
new file mode 100644
index 00000000..de852f67
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvscrollbar.c
@@ -0,0 +1,249 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkvscrollbar.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vscrollbar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Policy = "VScrollbar|GtkRange::update_policy";
+static gchar *Inverted = "VScrollbar|GtkRange::inverted";
+
+static const gchar *Values[] =
+{
+ "GtkVScrollbar::value",
+ "GtkVScrollbar::lower",
+ "GtkVScrollbar::upper",
+ "GtkVScrollbar::step",
+ "GtkVScrollbar::page",
+ "GtkVScrollbar::page_size",
+};
+
+static const gchar *GbPolicyChoices[] =
+{"Continuous", "Discontinuous", "Delayed",
+ NULL};
+static const gint GbPolicyValues[] =
+{
+ GTK_UPDATE_CONTINUOUS,
+ GTK_UPDATE_DISCONTINUOUS,
+ GTK_UPDATE_DELAYED
+};
+static const gchar *GbPolicySymbols[] =
+{
+ "GTK_UPDATE_CONTINUOUS",
+ "GTK_UPDATE_DISCONTINUOUS",
+ "GTK_UPDATE_DELAYED"
+};
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVScrollbar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_vscrollbar_new (GbWidgetNewData * data)
+{
+ return gtk_vscrollbar_new (NULL);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_vscrollbar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (Policy, _("Policy:"),
+ _("The update policy of the scrollbar"),
+ GbPolicyChoices);
+ property_add_bool (Inverted, _("Inverted:"), _("If the range values are inverted"));
+ property_add_adjustment (Values, GB_ADJUST_DEFAULT_LABELS);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_vscrollbar_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gint i;
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ gb_widget_output_choice (data, Policy, i, GbPolicySymbols[i]);
+ }
+
+ gb_widget_output_bool (data, Inverted, GTK_RANGE (widget)->inverted);
+
+ gb_widget_output_adjustment (data, Values, GTK_RANGE (widget)->adjustment,
+ "adjustment");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_vscrollbar_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *policy;
+ gint i;
+ gboolean inverted;
+ GtkAdjustment *adj;
+
+ policy = gb_widget_input_choice (data, Policy);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (!strcmp (policy, GbPolicyChoices[i])
+ || !strcmp (policy, GbPolicySymbols[i]))
+ {
+ gtk_range_set_update_policy (GTK_RANGE (widget), GbPolicyValues
+ [i]);
+ break;
+ }
+ }
+ }
+
+ inverted = gb_widget_input_bool (data, Inverted);
+ if (data->apply)
+ {
+ gtk_range_set_inverted (GTK_RANGE (widget), inverted);
+ }
+
+ adj = GTK_RANGE (widget)->adjustment;
+ if (gb_widget_input_adjustment (data, Values, adj, "adjustment"))
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkVScrollbar, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_vscrollbar_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vscrollbar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkAdjustment *adj = GTK_RANGE (widget)->adjustment;
+ gint i;
+
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (%g, %g, %g, %g, %g, %g)));\n",
+ data->wname, adj->value, adj->lower, adj->upper,
+ adj->step_increment, adj->page_increment, adj->page_size);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (GTK_RANGE (widget)->update_policy != GTK_UPDATE_CONTINUOUS)
+ {
+ for (i = 0; i < sizeof (GbPolicyValues) / sizeof (GbPolicyValues[0]); i
+ ++)
+ {
+ if (GbPolicyValues[i] == GTK_RANGE (widget)->update_policy)
+ source_add (data, " gtk_range_set_update_policy (GTK_RANGE (%s), %s);\n",
+ data->wname, GbPolicySymbols[i]);
+ }
+ }
+
+ if (GTK_RANGE (widget)->inverted)
+ {
+ source_add (data,
+ " gtk_range_set_inverted (GTK_RANGE (%s), TRUE);\n",
+ data->wname);
+
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vscrollbar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vscrollbar_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vscrollbar_xpm;
+ gbwidget.tooltip = _("Vertical Scrollbar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vscrollbar_new;
+ gbwidget.gb_widget_create_properties = gb_vscrollbar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vscrollbar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vscrollbar_set_properties;
+ gbwidget.gb_widget_write_source = gb_vscrollbar_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_vscrollbar_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbvseparator.c b/tools/glade/glade/gbwidgets/gbvseparator.c
new file mode 100644
index 00000000..ab068c48
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbvseparator.c
@@ -0,0 +1,157 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkvseparator.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/vseparator.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkVSeparator, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget*
+gb_vseparator_new(GbWidgetNewData *data)
+{
+ return gtk_vseparator_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+ static void
+ gb_vseparator_create_properties(GtkWidget *widget, GbWidgetCreateArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+ static void
+ gb_vseparator_get_properties(GtkWidget *widget, GbWidgetGetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+ static void
+ gb_vseparator_set_properties(GtkWidget *widget, GbWidgetSetArgData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkVSeparator, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_vseparator_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_vseparator_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gtk_vseparator_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_vseparator_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_vseparator_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = vseparator_xpm;
+ gbwidget.tooltip = _("Vertical Separator");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_vseparator_new;
+/*
+ gbwidget.gb_widget_create_properties = gb_vseparator_create_properties;
+ gbwidget.gb_widget_get_properties = gb_vseparator_get_properties;
+ gbwidget.gb_widget_set_properties = gb_vseparator_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_vseparator_create_popup_menu;
+ */
+ gbwidget.gb_widget_write_source = gb_vseparator_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gbwidgets/gbwindow.c b/tools/glade/glade/gbwidgets/gbwindow.c
new file mode 100644
index 00000000..616825a1
--- /dev/null
+++ b/tools/glade/glade/gbwidgets/gbwindow.c
@@ -0,0 +1,1246 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkwindow.h>
+#include "../gb.h"
+
+/* This file includes some common routines for standard window properties
+ such as title, type, position, default width & height, shrink, grow,
+ auto_shrink & icon. Other widgets can call these functions just
+ by supplying the property names. Note that for most properties we use the
+ widget's own property names as keys when storing values in the objects
+ datalist, but for default width & height we use the windows own names since
+ we need to access the values in the on_toggle_default_xx() callbacks. */
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/window.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GtkWindow::title";
+static gchar *Type = "GtkWindow::type";
+static gchar *Position = "GtkWindow::window_position";
+static gchar *Modal = "GtkWindow::modal";
+static gchar *DefaultWidth = "GtkWindow::default_width";
+static gchar *DefaultHeight = "GtkWindow::default_height";
+static gchar *IconName = "GtkWindow::icon_name";
+static gchar *FocusOnMap = "GtkWindow::focus_on_map";
+static gchar *Resizable = "GtkWindow::resizable";
+static gchar *DestroyWithParent = "GtkWindow::destroy_with_parent";
+static gchar *Icon = "GtkWindow::icon";
+
+static gchar *Role = "GtkWindow::role";
+static gchar *TypeHint = "GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GtkWindow::decorated";
+static gchar *Gravity = "GtkWindow::gravity";
+static gchar *Urgency = "GtkWindow::urgency_hint";
+
+/* These are deprecated. We don't show them any more. */
+static gchar *Shrink = "GtkWindow::allow_shrink";
+static gchar *Grow = "GtkWindow::allow_grow";
+
+
+/* The key to hold the icon filename. */
+static gchar *GladeWindowIconKey = "GladeWindowIconKey";
+
+static const gchar *GbTypeChoices[] =
+{"Top Level", "Popup", NULL};
+static const gint GbTypeValues[] =
+{
+ GTK_WINDOW_TOPLEVEL,
+ GTK_WINDOW_POPUP
+};
+static const gchar *GbTypeSymbols[] =
+{
+ "GTK_WINDOW_TOPLEVEL",
+ "GTK_WINDOW_POPUP"
+};
+
+/* If you change these arrays be sure to make sure
+ GLADE_TYPE_HINT_DIALOG_INDEX is up to date in gb.h. */
+static const gchar *GbTypeHintChoices[] =
+{"Normal", "Dialog", "Menu", "Toolbar", "Splash Screen", "Utility",
+ "Dock", "Desktop", NULL};
+static const gint GbTypeHintValues[] =
+{
+ GDK_WINDOW_TYPE_HINT_NORMAL,
+ GDK_WINDOW_TYPE_HINT_DIALOG,
+ GDK_WINDOW_TYPE_HINT_MENU,
+ GDK_WINDOW_TYPE_HINT_TOOLBAR,
+ GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
+ GDK_WINDOW_TYPE_HINT_UTILITY,
+ GDK_WINDOW_TYPE_HINT_DOCK,
+ GDK_WINDOW_TYPE_HINT_DESKTOP
+};
+static const gchar *GbTypeHintSymbols[] =
+{
+ "GDK_WINDOW_TYPE_HINT_NORMAL",
+ "GDK_WINDOW_TYPE_HINT_DIALOG",
+ "GDK_WINDOW_TYPE_HINT_MENU",
+ "GDK_WINDOW_TYPE_HINT_TOOLBAR",
+ "GDK_WINDOW_TYPE_HINT_SPLASHSCREEN",
+ "GDK_WINDOW_TYPE_HINT_UTILITY",
+ "GDK_WINDOW_TYPE_HINT_DOCK",
+ "GDK_WINDOW_TYPE_HINT_DESKTOP"
+};
+
+static const gchar *GbPositionChoices[] =
+{"None", "Center", "Mouse", "Center Always", "Center on Parent", NULL};
+static const gint GbPositionValues[] =
+{
+ GTK_WIN_POS_NONE,
+ GTK_WIN_POS_CENTER,
+ GTK_WIN_POS_MOUSE,
+ GTK_WIN_POS_CENTER_ALWAYS,
+ GTK_WIN_POS_CENTER_ON_PARENT
+};
+static const gchar *GbPositionSymbols[] =
+{
+ "GTK_WIN_POS_NONE",
+ "GTK_WIN_POS_CENTER",
+ "GTK_WIN_POS_MOUSE",
+ "GTK_WIN_POS_CENTER_ALWAYS",
+ "GTK_WIN_POS_CENTER_ON_PARENT"
+};
+
+static const gchar *GbGravityChoices[] =
+{"North West", "North", "North East", "West", "Center", "East",
+ "South West", "South", "South East", "Static", NULL};
+static const gint GbGravityValues[] =
+{
+ GDK_GRAVITY_NORTH_WEST,
+ GDK_GRAVITY_NORTH,
+ GDK_GRAVITY_NORTH_EAST,
+ GDK_GRAVITY_WEST,
+ GDK_GRAVITY_CENTER,
+ GDK_GRAVITY_EAST,
+ GDK_GRAVITY_SOUTH_WEST,
+ GDK_GRAVITY_SOUTH,
+ GDK_GRAVITY_SOUTH_EAST,
+ GDK_GRAVITY_STATIC
+};
+static const gchar *GbGravitySymbols[] =
+{
+ "GDK_GRAVITY_NORTH_WEST",
+ "GDK_GRAVITY_NORTH",
+ "GDK_GRAVITY_NORTH_EAST",
+ "GDK_GRAVITY_WEST",
+ "GDK_GRAVITY_CENTER",
+ "GDK_GRAVITY_EAST",
+ "GDK_GRAVITY_SOUTH_WEST",
+ "GDK_GRAVITY_SOUTH",
+ "GDK_GRAVITY_SOUTH_EAST",
+ "GDK_GRAVITY_STATIC"
+};
+
+
+static void on_toggle_default_width (GtkWidget * widget, gpointer value);
+static void on_toggle_default_height (GtkWidget * widget, gpointer value);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GtkWindow, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+GtkWidget *
+gb_window_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *placeholder;
+
+ new_widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (new_widget), data->name);
+ gtk_window_set_policy (GTK_WINDOW (new_widget), FALSE, TRUE, FALSE);
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ /* We need to size the placeholder or the window is very small. */
+ if (data->action != GB_LOADING)
+ {
+ placeholder = editor_new_placeholder ();
+ gtk_widget_set_usize (placeholder, 400, 300);
+ gtk_container_add (GTK_CONTAINER (new_widget), placeholder);
+ }
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_window_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, NULL,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+void
+gb_window_create_standard_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p)
+{
+ if (title_p)
+ property_add_string (title_p, _("Title:"), _("The title of the window"));
+
+ if (type_p)
+ property_add_choice (type_p, _("Type:"), _("The type of the window"),
+ GbTypeChoices);
+
+ if (type_hint_p)
+ property_add_choice (type_hint_p, _("Type Hint:"),
+ _("Tells the window manager how to treat the window"),
+ GbTypeHintChoices);
+
+ if (position_p)
+ property_add_choice (position_p, _("Position:"),
+ _("The initial position of the window"),
+ GbPositionChoices);
+
+ if (modal_p)
+ property_add_bool (modal_p, _("Modal:"), _("If the window is modal"));
+
+ if (default_width_p && default_height_p)
+ {
+ property_add_optional_int_range (default_width_p,
+ _("Default Width:"),
+ _("The default width of the window"),
+ 0, 10000, 1, 10, 1,
+ on_toggle_default_width);
+ property_add_optional_int_range (default_height_p,
+ _("Default Height:"),
+ _("The default height of the window"),
+ 0, 10000, 1, 10, 1,
+ on_toggle_default_height);
+ }
+
+ if (resizable_p)
+ property_add_bool (resizable_p, _("Resizable:"),
+ _("If the window can be resized"));
+
+#if 0
+ /* These are deprecated. */
+ if (shrink_p && grow_p)
+ {
+ property_add_bool (shrink_p, _("Shrink:"),
+ _("If the window can be shrunk"));
+ property_add_bool (grow_p, _("Grow:"),
+ _("If the window can be enlarged"));
+ }
+#endif
+
+ if (destroy_with_parent_p)
+ property_add_bool (destroy_with_parent_p, _("Auto-Destroy:"),
+ _("If the window is destroyed when its transient parent is destroyed"));
+
+ if (icon_p)
+ property_add_filename (icon_p, _("Icon:"),
+ _("The icon for this window"));
+
+ if (icon_name_p)
+ property_add_named_icon (icon_name_p, _("Named Icon:"),
+ _("The named icon to use"));
+
+ if (role_p)
+ property_add_string (role_p, _("Role:"), _("A unique identifier for the window to be used when restoring a session"));
+
+ if (decorated_p)
+ property_add_bool (decorated_p, _("Decorated:"),
+ _("If the window should be decorated by the window manager"));
+
+ if (skip_taskbar_p)
+ property_add_bool (skip_taskbar_p, _("Skip Taskbar:"),
+ _("If the window should not appear in the task bar"));
+
+ if (skip_pager_p)
+ property_add_bool (skip_pager_p, _("Skip Pager:"),
+ _("If the window should not appear in the pager"));
+
+ if (gravity_p)
+ property_add_choice (gravity_p, _("Gravity:"),
+ _("The reference point to use when the window coordinates are set"),
+ GbGravityChoices);
+
+ if (focus_on_map_p)
+ property_add_bool (focus_on_map_p, _("Focus On Map:"), _("If the window should receive the input focus when it is mapped"));
+
+ if (urgency_p)
+ property_add_bool (urgency_p, _("Urgency Hint:"), _("If the window should be brought to the user's attention"));
+}
+
+
+static void
+on_toggle_default_width (GtkWidget * widget, gpointer value)
+{
+ GtkWidget *property_widget;
+ gboolean value_set;
+ gint width, height;
+
+ property_widget = property_get_widget ();
+ if (property_widget == NULL)
+ return;
+
+ value_set = GTK_TOGGLE_BUTTON (widget)->active ? TRUE : FALSE;
+ gtk_widget_set_sensitive (GTK_WIDGET (value), value_set);
+
+ if (value_set)
+ {
+ width = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (value));
+ gtk_object_set_data (GTK_OBJECT (property_widget), DefaultWidth,
+ GINT_TO_POINTER (width));
+ }
+ else
+ {
+ width = -1;
+ gtk_object_set_data (GTK_OBJECT (property_widget), DefaultWidth,
+ NULL);
+ }
+
+ height = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (property_widget),
+ DefaultHeight));
+ gtk_window_set_default_size (GTK_WINDOW (property_widget),
+ width, height != 0 ? height : -1);
+}
+
+
+static void
+on_toggle_default_height (GtkWidget * widget, gpointer value)
+{
+ GtkWidget *property_widget;
+ gboolean value_set;
+ gint width, height;
+
+ property_widget = property_get_widget ();
+ if (property_widget == NULL)
+ return;
+
+ value_set = GTK_TOGGLE_BUTTON (widget)->active ? TRUE : FALSE;
+ gtk_widget_set_sensitive (GTK_WIDGET (value), value_set);
+
+ if (value_set)
+ {
+ height = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (value));
+ gtk_object_set_data (GTK_OBJECT (property_widget), DefaultHeight,
+ GINT_TO_POINTER (height));
+ }
+ else
+ {
+ height = -1;
+ gtk_object_set_data (GTK_OBJECT (property_widget), DefaultHeight,
+ NULL);
+ }
+
+ width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (property_widget),
+ DefaultWidth));
+ gtk_window_set_default_size (GTK_WINDOW (property_widget),
+ width != 0 ? width : -1, height);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_window_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, NULL,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+void
+gb_window_get_standard_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p)
+{
+ gint type, position, default_width, default_height, type_hint, gravity;
+
+ if (title_p)
+ gb_widget_output_translatable_string (data, title_p,
+ GTK_WINDOW (widget)->title);
+
+ /* The type is stored in the object datalist as we can't change it after the
+ window is realized. It will default to 0, which is OK. */
+ if (type_p)
+ {
+ type = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ type_p));
+ gb_widget_output_choice (data, type_p, type, GbTypeSymbols[type]);
+ }
+
+ /* The position is stored in the object datalist so that it doesn't affect
+ the displaying of the window within Glade. It will default to 0, i.e.
+ GTK_WIN_POS_NONE, which is OK. */
+ if (position_p)
+ {
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ position_p));
+ gb_widget_output_choice (data, position_p, position,
+ GbPositionSymbols[position]);
+ }
+
+ if (modal_p)
+ {
+ gb_widget_output_bool (data, modal_p,
+ gtk_object_get_data (GTK_OBJECT (widget), modal_p)
+ != NULL ? TRUE : FALSE);
+ }
+
+ if (default_width_p && default_height_p)
+ {
+ default_width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ DefaultWidth));
+ gb_widget_output_optional_int (data, default_width_p, default_width,
+ default_width != 0 ? TRUE : FALSE);
+
+ default_height = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ DefaultHeight));
+ gb_widget_output_optional_int (data, default_height_p, default_height,
+ default_height != 0 ? TRUE : FALSE);
+ }
+
+#if 0
+ /* These are deprecated. */
+ if (grow_p && shrink_p)
+ {
+ gb_widget_output_bool (data, grow_p,
+ GTK_WINDOW (widget)->allow_grow);
+ gb_widget_output_bool (data, shrink_p,
+ GTK_WINDOW (widget)->allow_shrink);
+ }
+#endif
+
+ if (resizable_p)
+ gb_widget_output_bool (data, resizable_p,
+ gtk_window_get_resizable (GTK_WINDOW (widget)));
+
+ if (destroy_with_parent_p)
+ gb_widget_output_bool (data, destroy_with_parent_p,
+ gtk_window_get_destroy_with_parent (GTK_WINDOW (widget)));
+
+ if (icon_p)
+ gb_widget_output_pixmap_filename (data, icon_p,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ GladeWindowIconKey));
+
+ if (icon_name_p)
+ gb_widget_output_named_icon (data, icon_name_p,
+ gtk_window_get_icon_name (GTK_WINDOW (widget)));
+
+ if (role_p)
+ gb_widget_output_string (data, role_p,
+ gtk_window_get_role (GTK_WINDOW (widget)));
+
+ /* We can't set the decorated property as that may make it awkward to
+ edit. The default (i.e. NULL value) is TRUE. */
+ if (decorated_p)
+ gb_widget_output_bool (data, decorated_p,
+ gtk_object_get_data (GTK_OBJECT (widget), decorated_p)
+ == NULL ? TRUE : FALSE);
+
+ /* The default (i.e. NULL value) is FALSE. */
+ if (skip_taskbar_p)
+ gb_widget_output_bool (data, skip_taskbar_p,
+ gtk_object_get_data (GTK_OBJECT (widget), skip_taskbar_p)
+ != NULL ? TRUE : FALSE);
+
+ /* The default (i.e. NULL value) is FALSE. */
+ if (skip_pager_p)
+ gb_widget_output_bool (data, skip_pager_p,
+ gtk_object_get_data (GTK_OBJECT (widget), skip_pager_p)
+ != NULL ? TRUE : FALSE);
+
+ /* We can't set the type hint within Glade as it may make the window
+ awkward to edit. It defaults to 0 which is GDK_WINDOW_TYPE_HINT_NORMAL
+ which is OK. */
+ if (type_hint_p)
+ {
+ type_hint = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ type_hint_p));
+ gb_widget_output_choice (data, type_hint_p, type_hint,
+ GbTypeHintSymbols[type_hint]);
+ }
+
+ /* I'm not sure if we should set the gravity or not.
+ It defaults to 0, which is GDK_GRAVITY_NORTH_WEST which is OK. */
+ if (gravity_p)
+ {
+ gravity = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ gravity_p));
+ gb_widget_output_choice (data, gravity_p, gravity,
+ GbGravitySymbols[gravity]);
+ }
+
+ if (focus_on_map_p)
+ {
+ gb_widget_output_bool (data, focus_on_map_p,
+ gtk_object_get_data (GTK_OBJECT (widget), focus_on_map_p) == NULL ? TRUE : FALSE);
+ }
+
+ if (urgency_p)
+ {
+ gb_widget_output_bool (data, urgency_p,
+ gtk_object_get_data (GTK_OBJECT (widget), urgency_p) != NULL ? TRUE : FALSE);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_window_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, NULL,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+static void
+gb_window_clear_pixmap (GtkWidget *widget, GladeProject *project)
+{
+ gchar *old_icon;
+
+ /* Remove the old icon stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ old_icon = gtk_object_get_data (GTK_OBJECT (widget), GladeWindowIconKey);
+ glade_project_remove_pixmap (project, old_icon);
+
+ gtk_object_set_data (GTK_OBJECT (widget), GladeWindowIconKey, NULL);
+}
+
+
+void
+gb_window_set_standard_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p)
+{
+ gchar *title, *type, *position, *role;
+ gint default_width, default_height, i;
+ gboolean modal, apply_default_width, apply_default_height;
+ gboolean resizable, destroy_with_parent;
+ gboolean decorated, skip_taskbar, skip_pager;
+ gchar *type_hint, *gravity;
+
+ if (title_p)
+ {
+ title = gb_widget_input_string (data, title_p);
+ if (data->apply)
+ gtk_window_set_title (GTK_WINDOW (widget), title);
+ }
+
+ if (type_p)
+ {
+ type = gb_widget_input_choice (data, type_p);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbTypeValues) / sizeof (GbTypeValues[0]);
+ i++)
+ {
+ if (!strcmp (type, GbTypeChoices[i])
+ || !strcmp (type, GbTypeSymbols[i]))
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), type_p,
+ GINT_TO_POINTER (i));
+ break;
+ }
+ }
+ }
+ }
+
+ if (position_p)
+ {
+ position = gb_widget_input_choice (data, position_p);
+ if (data->apply)
+ {
+ for (i = 0;
+ i < sizeof (GbPositionValues) / sizeof (GbPositionValues[0]);
+ i++)
+ {
+ if (!strcmp (position, GbPositionChoices[i])
+ || !strcmp (position, GbPositionSymbols[i]))
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), position_p,
+ GINT_TO_POINTER (i));
+ break;
+ }
+ }
+ }
+ }
+
+ if (modal_p)
+ {
+ modal = gb_widget_input_bool (data, modal_p);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), modal_p,
+ modal ? "TRUE" : NULL);
+ }
+ }
+
+ if (default_width_p && default_height_p)
+ {
+ default_width = gb_widget_input_int (data, default_width_p);
+ apply_default_width = data->apply;
+ if (apply_default_width)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), DefaultWidth,
+ GINT_TO_POINTER (default_width));
+ }
+
+ default_height = gb_widget_input_int (data, default_height_p);
+ apply_default_height = data->apply;
+ if (apply_default_height)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), DefaultHeight,
+ GINT_TO_POINTER (default_height));
+ }
+
+ if (apply_default_width || apply_default_height)
+ {
+ if (!apply_default_width)
+ default_width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ DefaultWidth));
+ if (!apply_default_height)
+ default_height = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ DefaultHeight));
+ gtk_window_set_default_size (GTK_WINDOW (widget),
+ default_width ? default_width : -1,
+ default_height ? default_height : -1);
+ }
+ }
+
+#if 0
+ /* These are deprecated. */
+ if (shrink_p && grow_p)
+ {
+ shrink = gb_widget_input_bool (data, shrink_p);
+ if (data->apply)
+ set_policy = TRUE;
+ else
+ shrink = GTK_WINDOW (widget)->allow_shrink;
+
+ grow = gb_widget_input_bool (data, grow_p);
+ if (data->apply)
+ set_policy = TRUE;
+ else
+ grow = GTK_WINDOW (widget)->allow_grow;
+
+ if (set_policy)
+ gtk_window_set_policy (GTK_WINDOW (widget), shrink, grow, FALSE);
+ }
+#endif
+
+ if (resizable_p)
+ {
+ resizable = gb_widget_input_bool (data, resizable_p);
+ if (data->apply)
+ gtk_window_set_resizable (GTK_WINDOW (widget), resizable);
+ }
+
+ if (destroy_with_parent_p)
+ {
+ destroy_with_parent = gb_widget_input_bool (data, destroy_with_parent_p);
+ if (data->apply)
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (widget),
+ destroy_with_parent);
+ }
+
+ if (icon_p)
+ {
+ char *filename = gb_widget_input_pixmap_filename (data, icon_p);
+ if (data->apply)
+ {
+ if (filename && filename[0] == '\0')
+ filename = NULL;
+
+ /* Remove the old icon stored in the widget data, and remove the
+ pixmap from the project, if necessary. */
+ gb_window_clear_pixmap (widget, data->project);
+
+ gtk_object_set_data_full (GTK_OBJECT (widget), GladeWindowIconKey,
+ g_strdup (filename),
+ filename ? g_free : NULL);
+
+ glade_project_add_pixmap (data->project, filename);
+
+ if (filename)
+ {
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+ gtk_window_set_icon (GTK_WINDOW (widget), pixbuf);
+ if (pixbuf)
+ gdk_pixbuf_unref (pixbuf);
+ }
+
+ if (property_get_widget () == widget && icon_name_p)
+ {
+ /* Clear the IconName property. */
+ property_set_auto_apply (FALSE);
+ property_set_named_icon (icon_name_p, NULL);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ if (data->action == GB_LOADING)
+ g_free (filename);
+ }
+
+ if (icon_name_p)
+ {
+ gchar *icon_name = gb_widget_input_named_icon (data, icon_name_p);
+
+ if (data->apply)
+ {
+ /* Clear any stock icon or icon from a file. */
+ gb_window_clear_pixmap (widget, data->project);
+
+ gtk_window_set_icon (GTK_WINDOW (widget), NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (widget), icon_name);
+
+ if (property_get_widget () == widget && icon_p)
+ {
+ /* Clear the Icon property. */
+ property_set_auto_apply (FALSE);
+ property_set_filename (icon_p, NULL);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ }
+
+ if (role_p)
+ {
+ role = gb_widget_input_string (data, role_p);
+ if (data->apply)
+ gtk_window_set_role (GTK_WINDOW (widget), role);
+ }
+
+ if (decorated_p)
+ {
+ decorated = gb_widget_input_bool (data, decorated_p);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), decorated_p,
+ decorated ? NULL : "FALSE");
+ }
+
+ if (skip_taskbar_p)
+ {
+ skip_taskbar = gb_widget_input_bool (data, skip_taskbar_p);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), skip_taskbar_p,
+ skip_taskbar ? "TRUE" : NULL);
+ }
+
+ if (skip_pager_p)
+ {
+ skip_pager = gb_widget_input_bool (data, skip_pager_p);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), skip_pager_p,
+ skip_pager ? "TRUE" : NULL);
+ }
+
+ if (type_hint_p)
+ {
+ type_hint = gb_widget_input_choice (data, type_hint_p);
+ if (data->apply)
+ {
+ for (i = 0;
+ i < sizeof (GbTypeHintValues) / sizeof (GbTypeHintValues[0]);
+ i++)
+ {
+ if (!strcmp (type_hint, GbTypeHintChoices[i])
+ || !strcmp (type_hint, GbTypeHintSymbols[i]))
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), type_hint_p,
+ GINT_TO_POINTER (i));
+ break;
+ }
+ }
+ }
+ }
+
+ if (gravity_p)
+ {
+ gravity = gb_widget_input_choice (data, gravity_p);
+ if (data->apply)
+ {
+ for (i = 0;
+ i < sizeof (GbGravityValues) / sizeof (GbGravityValues[0]);
+ i++)
+ {
+ if (!strcmp (gravity, GbGravityChoices[i])
+ || !strcmp (gravity, GbGravitySymbols[i]))
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), gravity_p,
+ GINT_TO_POINTER (i));
+ break;
+ }
+ }
+ }
+ }
+
+ if (focus_on_map_p)
+ {
+ gboolean focus_on_map = gb_widget_input_bool (data, focus_on_map_p);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), focus_on_map_p,
+ focus_on_map ? NULL : "FALSE");
+ }
+ }
+
+ if (urgency_p)
+ {
+ gboolean urgency = gb_widget_input_bool (data, urgency_p);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), urgency_p,
+ urgency ? "TRUE" : NULL);
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GtkWindow, with signals pointing to
+ * other functions in this file.
+ */
+/*
+ static void
+ gb_window_create_popup_menu(GtkWidget *widget, GbWidgetCreateMenuData *data)
+ {
+
+ }
+ */
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_window_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gint type;
+
+ if (data->create_widget)
+ {
+ type = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Type));
+ source_add (data, " %s = gtk_window_new (%s);\n", data->wname,
+ GbTypeSymbols[type]);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The type is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, NULL,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+void
+gb_window_write_standard_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data,
+ gchar *title_p,
+ gchar *type_p,
+ gchar *position_p,
+ gchar *modal_p,
+ gchar *default_width_p,
+ gchar *default_height_p,
+ gchar *shrink_p,
+ gchar *grow_p,
+ gchar *auto_shrink_p,
+ gchar *icon_name_p,
+ gchar *focus_on_map_p,
+ gchar *resizable_p,
+ gchar *destroy_with_parent_p,
+ gchar *icon_p,
+ gchar *role_p,
+ gchar *type_hint_p,
+ gchar *skip_taskbar_p,
+ gchar *skip_pager_p,
+ gchar *decorated_p,
+ gchar *gravity_p,
+ gchar *urgency_p)
+{
+ gint type, position, default_width, default_height, type_hint, gravity;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (title_p)
+ {
+ if (GTK_WINDOW (widget)->title
+ && strlen (GTK_WINDOW (widget)->title) > 0)
+ {
+ glade_util_get_translation_properties (widget, title_p,
+ &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " gtk_window_set_title (GTK_WINDOW (%s), %s);\n",
+ data->wname,
+ source_make_string_full (GTK_WINDOW (widget)->title,
+ data->use_gettext && translatable,
+ context));
+ }
+ }
+
+ if (type_p)
+ {
+ type = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ type_p));
+ if (type != GTK_WINDOW_TOPLEVEL)
+ {
+ /* Note: there is no gtk_window_set_type () */
+ source_add (data, " GTK_WINDOW (%s)->type = %s;\n",
+ data->wname, GbTypeSymbols[type]);
+ }
+ }
+
+ if (position_p)
+ {
+ position = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ position_p));
+ if (GbPositionValues[position] != GTK_WIN_POS_NONE)
+ {
+ source_add (data,
+ " gtk_window_set_position (GTK_WINDOW (%s), %s);\n",
+ data->wname, GbPositionSymbols[position]);
+ }
+ }
+
+ if (modal_p)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), modal_p))
+ {
+ source_add (data,
+ " gtk_window_set_modal (GTK_WINDOW (%s), TRUE);\n",
+ data->wname);
+ }
+ }
+
+ if (default_width_p && default_height_p)
+ {
+ default_width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ DefaultWidth));
+ default_height = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ DefaultHeight));
+ if (default_width || default_height )
+ {
+ source_add (data,
+ " gtk_window_set_default_size (GTK_WINDOW (%s), %i, %i);\n",
+ data->wname,
+ default_width ? default_width : -1,
+ default_height ? default_height : -1);
+ }
+ }
+
+#if 0
+ if (shrink_p && grow_p)
+ {
+ if (GTK_WINDOW (widget)->allow_grow != TRUE
+ || GTK_WINDOW (widget)->allow_shrink != FALSE)
+ source_add (data,
+ " gtk_window_set_policy (GTK_WINDOW (%s), %s, %s, %s);\n",
+ data->wname,
+ GTK_WINDOW (widget)->allow_shrink ? "TRUE" : "FALSE",
+ GTK_WINDOW (widget)->allow_grow ? "TRUE" : "FALSE",
+ "FALSE");
+ }
+#endif
+
+ if (resizable_p)
+ {
+ if (!gtk_window_get_resizable (GTK_WINDOW (widget)))
+ source_add (data,
+ " gtk_window_set_resizable (GTK_WINDOW (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (destroy_with_parent_p)
+ {
+ if (gtk_window_get_destroy_with_parent (GTK_WINDOW (widget)))
+ source_add (data,
+ " gtk_window_set_destroy_with_parent (GTK_WINDOW (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (icon_p)
+ {
+ gchar *filename = gtk_object_get_data (GTK_OBJECT (widget), GladeWindowIconKey);
+ if (filename && *filename)
+ {
+ char *pixbuf_name = g_strdup_printf ("%s_icon_pixbuf", data->wname);
+
+ source_add_decl (data, " GdkPixbuf *%s;\n", pixbuf_name);
+ source_create_pixbuf (data, pixbuf_name, filename);
+ source_add (data,
+ " if (%s)\n"
+ " {\n"
+ " gtk_window_set_icon (GTK_WINDOW (%s), %s);\n"
+ " gdk_pixbuf_unref (%s);\n"
+ " }\n",
+ pixbuf_name,
+ data->wname, pixbuf_name,
+ pixbuf_name);
+
+ g_free (pixbuf_name);
+ }
+ }
+
+ if (icon_p)
+ {
+ const gchar *icon_name = gtk_window_get_icon_name (GTK_WINDOW (widget));
+ if (icon_name && *icon_name)
+ {
+ source_add (data,
+ " gtk_window_set_icon_name (GTK_WINDOW (%s), \"%s\");\n",
+ data->wname, icon_name);
+ }
+ }
+
+ if (role_p)
+ {
+ const gchar *role = gtk_window_get_role (GTK_WINDOW (widget));
+
+ /* The role isn't translated. */
+ if (role && *role)
+ source_add (data, " gtk_window_set_role (GTK_WINDOW (%s), %s);\n",
+ data->wname,
+ source_make_string (role, FALSE));
+ }
+
+ if (decorated_p)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), decorated_p) != NULL)
+ {
+ source_add (data, " gtk_window_set_decorated (GTK_WINDOW (%s), FALSE);\n",
+ data->wname);
+ }
+ }
+
+ if (skip_taskbar_p)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), skip_taskbar_p) != NULL)
+ {
+ source_add (data, " gtk_window_set_skip_taskbar_hint (GTK_WINDOW (%s), TRUE);\n",
+ data->wname);
+ }
+ }
+
+ if (skip_pager_p)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), skip_pager_p) != NULL)
+ {
+ source_add (data, " gtk_window_set_skip_pager_hint (GTK_WINDOW (%s), TRUE);\n",
+ data->wname);
+ }
+ }
+
+ if (type_hint_p)
+ {
+ type_hint = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ type_hint_p));
+ if (GbTypeHintValues[type_hint] != GDK_WINDOW_TYPE_HINT_NORMAL)
+ {
+ source_add (data, " gtk_window_set_type_hint (GTK_WINDOW (%s), %s);\n",
+ data->wname, GbTypeHintSymbols[type_hint]);
+ }
+
+ }
+
+ if (gravity_p)
+ {
+ gravity = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ gravity_p));
+ if (GbGravityValues[gravity] != GDK_GRAVITY_NORTH_WEST)
+ {
+ source_add (data, " gtk_window_set_gravity (GTK_WINDOW (%s), %s);\n",
+ data->wname, GbGravitySymbols[gravity]);
+ }
+ }
+
+ if (focus_on_map_p)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), focus_on_map_p))
+ {
+ source_add (data,
+ " gtk_window_set_focus_on_map (GTK_WINDOW (%s), FALSE);\n",
+ data->wname);
+ }
+ }
+
+ if (urgency_p)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), urgency_p))
+ {
+ source_add (data,
+ " gtk_window_set_urgency_hint (GTK_WINDOW (%s), TRUE);\n",
+ data->wname);
+ }
+ }
+}
+
+
+void
+gb_window_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ gb_window_clear_pixmap (widget, data->project);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_window_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gtk_window_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = window_xpm;
+ gbwidget.tooltip = _("Window");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_window_new;
+ gbwidget.gb_widget_create_properties = gb_window_create_properties;
+ gbwidget.gb_widget_get_properties = gb_window_get_properties;
+ gbwidget.gb_widget_set_properties = gb_window_set_properties;
+ gbwidget.gb_widget_write_source = gb_window_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_window_create_popup_menu;
+ */
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/glade-parser.c b/tools/glade/glade/glade-parser.c
new file mode 100644
index 00000000..cb6dee60
--- /dev/null
+++ b/tools/glade/glade/glade-parser.c
@@ -0,0 +1,1415 @@
+/* -*- Mode: C; c-basic-offset: 4 -*- */
+/*
+ * Glade - a GTK+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * glade-parser.c: functions for parsing glade-2.0 files
+ * Copyright (C) 1998-2002 James Henstridge <james@daa.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file comes from libglade. Though I've had to make a few minor changes
+ * to use it in Glade. Try to keep the versions in sync as much as possible.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* GLADE: We don't want the strings translated in Glade. */
+/*#ifdef ENABLE_NLS*/
+#if 0
+# include <libintl.h>
+#else
+# define textdomain(String) (String)
+# define dgettext(Domain, String) (String)
+#endif
+
+#include <libxml/parser.h>
+
+#include "glade-parser.h"
+
+typedef enum {
+ PARSER_START,
+ PARSER_GLADE_INTERFACE,
+ PARSER_REQUIRES,
+ PARSER_WIDGET,
+ PARSER_WIDGET_PROPERTY,
+ PARSER_WIDGET_ATK,
+ PARSER_WIDGET_ATK_PROPERTY,
+ PARSER_WIDGET_ATK_ACTION,
+ PARSER_WIDGET_ATK_RELATION,
+ PARSER_WIDGET_AFTER_ATK,
+ PARSER_WIDGET_SIGNAL,
+ PARSER_WIDGET_AFTER_SIGNAL,
+ PARSER_WIDGET_ACCEL,
+ PARSER_WIDGET_AFTER_ACCEL,
+ PARSER_WIDGET_CHILD,
+ PARSER_WIDGET_CHILD_AFTER_WIDGET,
+ PARSER_WIDGET_CHILD_PACKING,
+ PARSER_WIDGET_CHILD_PACKING_PROPERTY,
+ PARSER_WIDGET_CHILD_AFTER_PACKING,
+ PARSER_WIDGET_CHILD_PLACEHOLDER,
+ PARSER_WIDGET_CHILD_AFTER_PLACEHOLDER,
+ PARSER_FINISH,
+ PARSER_UNKNOWN
+} ParserState;
+
+typedef struct _GladeParseState GladeParseState;
+struct _GladeParseState {
+ ParserState state;
+
+ const gchar *domain;
+
+ guint unknown_depth; /* handle recursive unrecognised tags */
+ ParserState prev_state; /* the last `known' state we were in */
+
+ guint widget_depth;
+ GString *content;
+
+ GladeInterface *interface;
+ GladeWidgetInfo *widget;
+
+ enum {PROP_NONE, PROP_WIDGET, PROP_ATK, PROP_CHILD } prop_type;
+ gchar *prop_name;
+ gchar *prop_agent;
+ gboolean translate_prop;
+ gchar *prop_translator_comments;
+ gboolean prop_context_prefix;
+ GArray *props;
+
+ GArray *signals;
+ GArray *atk_actions;
+ GArray *relations;
+ GArray *accels;
+};
+
+static gchar *
+alloc_string(GladeInterface *interface, const gchar *string)
+{
+ gchar *s;
+
+ s = g_hash_table_lookup(interface->strings, string);
+ if (!s) {
+ s = g_strdup(string);
+ g_hash_table_insert(interface->strings, s, s);
+ }
+ return s;
+}
+
+static GladeWidgetInfo *
+create_widget_info(GladeInterface *interface, const xmlChar **attrs)
+{
+ GladeWidgetInfo *info = g_new0(GladeWidgetInfo, 1);
+ int i;
+
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "class"))
+ info->class = alloc_string(interface, attrs[i+1]);
+ else if (!strcmp(attrs[i], "id"))
+ info->name = alloc_string(interface, attrs[i+1]);
+ else
+ g_warning("unknown attribute `%s' for <widget>.", attrs[i]);
+ }
+ if (info->class == NULL || info->name == NULL)
+ g_warning("<widget> element missing required attributes!");
+ if (info->name)
+ g_hash_table_insert(interface->names, info->name, info);
+ return info;
+}
+
+static inline void
+flush_properties(GladeParseState *state)
+{
+ if (state->props == NULL)
+ return;
+ switch (state->prop_type) {
+ case PROP_NONE:
+ break;
+ case PROP_WIDGET:
+ if (state->widget->properties)
+ g_warning("we already read all the props for this key. Leaking");
+ state->widget->properties = (GladeProperty *)state->props->data;
+ state->widget->n_properties = state->props->len;
+ g_array_free(state->props, FALSE);
+ break;
+ case PROP_ATK:
+ if (state->widget->atk_props)
+ g_warning("we already read all the ATK props for this key. Leaking");
+ state->widget->atk_props = (GladeProperty *)state->props->data;
+ state->widget->n_atk_props = state->props->len;
+ g_array_free(state->props, FALSE);
+ break;
+ case PROP_CHILD:
+ if (state->widget->n_children == 0) {
+ g_warning("no children, but have child properties!");
+ g_array_free(state->props, TRUE);
+ } else {
+ GladeChildInfo *info = &state->widget->children[
+ state->widget->n_children-1];
+ if (info->properties)
+ g_warning("we already read all the child props for this key. Leaking");
+ info->properties = (GladeProperty *)state->props->data;
+ info->n_properties = state->props->len;
+ g_array_free(state->props, FALSE);
+ }
+ break;
+ }
+ state->prop_type = PROP_NONE;
+ state->prop_name = NULL;
+ state->prop_agent = NULL;
+ state->prop_translator_comments = NULL;
+ state->prop_context_prefix = FALSE;
+ state->props = NULL;
+}
+
+static inline void
+flush_signals(GladeParseState *state)
+{
+ if (state->signals) {
+ state->widget->signals = (GladeSignalInfo *)state->signals->data;
+ state->widget->n_signals = state->signals->len;
+ g_array_free(state->signals, FALSE);
+ }
+ state->signals = NULL;
+}
+
+static inline void
+flush_actions(GladeParseState *state)
+{
+ if (state->atk_actions) {
+ state->widget->atk_actions = (GladeAtkActionInfo *)state->atk_actions->data;
+ state->widget->n_atk_actions = state->atk_actions->len;
+ g_array_free(state->atk_actions, FALSE);
+ }
+ state->atk_actions = NULL;
+}
+
+static inline void
+flush_relations(GladeParseState *state)
+{
+ if (state->relations) {
+ state->widget->relations = (GladeAtkRelationInfo *)state->relations->data;
+ state->widget->n_relations = state->relations->len;
+ g_array_free(state->relations, FALSE);
+ }
+ state->relations = NULL;
+}
+
+static inline void
+flush_accels(GladeParseState *state)
+{
+ if (state->accels) {
+ state->widget->accels = (GladeAccelInfo *)state->accels->data;
+ state->widget->n_accels = state->accels->len;
+ g_array_free(state->accels, FALSE);
+ }
+ state->accels = NULL;
+}
+
+static inline void
+handle_atk_action(GladeParseState *state, const xmlChar **attrs)
+{
+ gint i;
+ GladeAtkActionInfo info = { 0 };
+
+ flush_properties(state);
+
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "action_name"))
+ info.action_name = alloc_string(state->interface, attrs[i+1]);
+ else if (!strcmp(attrs[i], "description"))
+ info.description = alloc_string(state->interface, attrs[i+1]);
+ else
+ g_warning("unknown attribute `%s' for <action>.", attrs[i]);
+ }
+ if (info.action_name == NULL) {
+ g_warning("required <atkaction> attribute 'action_name' missing!!!");
+ return;
+ }
+ if (!state->atk_actions)
+ state->atk_actions = g_array_new(FALSE, FALSE,
+ sizeof(GladeAtkActionInfo));
+ g_array_append_val(state->atk_actions, info);
+}
+
+static inline void
+handle_atk_relation(GladeParseState *state, const xmlChar **attrs)
+{
+ gint i;
+ GladeAtkRelationInfo info = { 0 };
+
+ flush_properties(state);
+
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "target"))
+ info.target = alloc_string(state->interface, attrs[i+1]);
+ else if (!strcmp(attrs[i], "type"))
+ info.type = alloc_string(state->interface, attrs[i+1]);
+ else
+ g_warning("unknown attribute `%s' for <signal>.", attrs[i]);
+ }
+ if (info.target == NULL || info.type == NULL) {
+ g_warning("required <atkrelation> attributes ('target' and/or 'type') missing!!!");
+ return;
+ }
+ if (!state->relations)
+ state->relations = g_array_new(FALSE, FALSE,
+ sizeof(GladeAtkRelationInfo));
+ g_array_append_val(state->relations, info);
+}
+
+static inline void
+handle_signal(GladeParseState *state, const xmlChar **attrs)
+{
+ GladeSignalInfo info = { 0 };
+ gint i;
+
+ flush_properties(state);
+
+ info.after = FALSE;
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "name"))
+ info.name = alloc_string(state->interface, attrs[i+1]);
+ else if (!strcmp(attrs[i], "handler"))
+ info.handler = alloc_string(state->interface, attrs[i+1]);
+ else if (!strcmp(attrs[i], "after"))
+ info.after = attrs[i+1][0] == 'y';
+ else if (!strcmp(attrs[i], "object"))
+ info.object = alloc_string(state->interface, attrs[i+1]);
+ else if (!strcmp(attrs[i], "last_modification_time"))
+ info.last_modification_time = alloc_string(state->interface, attrs[i+1]);
+ else
+ g_warning("unknown attribute `%s' for <signal>.", attrs[i]);
+ }
+ if (info.name == NULL || info.handler == NULL) {
+ g_warning("required <signal> attributes missing!!!");
+ return;
+ }
+ if (!state->signals)
+ state->signals = g_array_new(FALSE, FALSE,
+ sizeof(GladeSignalInfo));
+ g_array_append_val(state->signals, info);
+}
+
+static inline void
+handle_accel(GladeParseState *state, const xmlChar **attrs)
+{
+ GladeAccelInfo info = { 0 };
+ gint i;
+
+ flush_properties(state);
+ flush_signals(state);
+ flush_actions(state);
+ flush_relations(state);
+
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "key"))
+ info.key = gdk_keyval_from_name(attrs[i+1]);
+ else if (!strcmp(attrs[i], "modifiers")) {
+ const xmlChar *pos = attrs[i+1];
+
+ info.modifiers = 0;
+ while (pos[0])
+ if (!strncmp(pos, "GDK_", 4)) {
+ pos += 4;
+ if (!strncmp(pos, "SHIFT_MASK", 10)) {
+ info.modifiers |= GDK_SHIFT_MASK;
+ pos += 10;
+ } else if (!strncmp(pos, "LOCK_MASK", 9)) {
+ info.modifiers |= GDK_LOCK_MASK;
+ pos += 9;
+ } else if (!strncmp(pos, "CONTROL_MASK", 12)) {
+ info.modifiers |= GDK_CONTROL_MASK;
+ pos += 12;
+ } else if (!strncmp(pos, "MOD", 3) &&
+ !strncmp(pos+4, "_MASK", 5)) {
+ switch (pos[3]) {
+ case '1':
+ info.modifiers |= GDK_MOD1_MASK; break;
+ case '2':
+ info.modifiers |= GDK_MOD2_MASK; break;
+ case '3':
+ info.modifiers |= GDK_MOD3_MASK; break;
+ case '4':
+ info.modifiers |= GDK_MOD4_MASK; break;
+ case '5':
+ info.modifiers |= GDK_MOD5_MASK; break;
+ }
+ pos += 9;
+ } else if (!strncmp(pos, "BUTTON", 6) &&
+ !strncmp(pos+7, "_MASK", 5)) {
+ switch (pos[6]) {
+ case '1':
+ info.modifiers |= GDK_BUTTON1_MASK; break;
+ case '2':
+ info.modifiers |= GDK_BUTTON2_MASK; break;
+ case '3':
+ info.modifiers |= GDK_BUTTON3_MASK; break;
+ case '4':
+ info.modifiers |= GDK_BUTTON4_MASK; break;
+ case '5':
+ info.modifiers |= GDK_BUTTON5_MASK; break;
+ }
+ pos += 12;
+ } else if (!strncmp(pos, "RELEASE_MASK", 12)) {
+ info.modifiers |= GDK_RELEASE_MASK;
+ pos += 12;
+ } else
+ pos++;
+ } else
+ pos++;
+ } else if (!strcmp(attrs[i], "signal"))
+ info.signal = alloc_string(state->interface, attrs[i+1]);
+ else
+ g_warning("unknown attribute `%s' for <accelerator>.", attrs[i]);
+ }
+ if (info.key == 0 || info.signal == NULL) {
+ g_warning("required <accelerator> attributes missing!!!");
+ return;
+ }
+ if (!state->accels)
+ state->accels = g_array_new(FALSE, FALSE,
+ sizeof(GladeAccelInfo));
+ g_array_append_val(state->accels, info);
+}
+
+static inline void
+handle_child(GladeParseState *state, const xmlChar **attrs)
+{
+ GladeChildInfo *info;
+ gint i;
+
+ /* make sure all of these are flushed */
+ flush_properties(state);
+ flush_signals(state);
+ flush_actions(state);
+ flush_relations(state);
+ flush_accels(state);
+
+ state->widget->n_children++;
+ state->widget->children = g_renew(GladeChildInfo, state->widget->children,
+ state->widget->n_children);
+ info = &state->widget->children[state->widget->n_children-1];
+ info->internal_child = NULL;
+ info->properties = NULL;
+ info->n_properties = 0;
+ info->child = NULL;
+
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "internal-child"))
+ info->internal_child = alloc_string(state->interface, attrs[i+1]);
+ else
+ g_warning("unknown attribute `%s' for <child>.", attrs[i]);
+ }
+}
+
+static void
+glade_parser_start_document(GladeParseState *state)
+{
+ state->state = PARSER_START;
+
+ state->unknown_depth = 0;
+ state->prev_state = PARSER_UNKNOWN;
+
+ state->widget_depth = 0;
+ state->content = g_string_sized_new(128);
+
+ state->interface = g_new0(GladeInterface, 1);
+ state->interface->names = g_hash_table_new(g_str_hash, g_str_equal);
+ state->interface->strings = g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ (GDestroyNotify)g_free,
+ NULL);
+ state->widget = NULL;
+
+ state->prop_type = PROP_NONE;
+ state->prop_name = NULL;
+ state->prop_agent = NULL;
+ state->translate_prop = FALSE;
+ state->prop_translator_comments = NULL;
+ state->prop_context_prefix = FALSE;
+ state->props = NULL;
+
+ state->signals = NULL;
+ state->accels = NULL;
+}
+
+static void
+glade_parser_end_document(GladeParseState *state)
+{
+ g_string_free(state->content, TRUE);
+
+ if (state->unknown_depth != 0)
+ g_warning("unknown_depth != 0 (%d)", state->unknown_depth);
+ if (state->widget_depth != 0)
+ g_warning("widget_depth != 0 (%d)", state->widget_depth);
+}
+
+static void
+glade_parser_start_element(GladeParseState *state,
+ const xmlChar *name, const xmlChar **attrs)
+{
+ int i;
+
+ switch (state->state) {
+ case PARSER_START:
+ if (!strcmp(name, "glade-interface")) {
+ state->state = PARSER_GLADE_INTERFACE;
+#if 0
+ /* check for correct XML namespace */
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "xmlns") &&
+ !strcmp(attrs[i+1], "...")) {
+ g_warning("bad XML namespace `%s'.", attrs[i+1]);
+ } else
+ g_warning("unknown attribute `%s' for <glade-interface>",
+ attrs[i]);
+ }
+#endif
+ } else {
+ g_warning("Expected <glade-interface>. Got <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_GLADE_INTERFACE:
+ if (!strcmp(name, "requires")) {
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "lib")) {
+ GladeInterface *iface = state->interface;
+
+ /* add to the list of requirements for this module */
+ iface->n_requires++;
+ iface->requires = g_renew(gchar *, iface->requires,
+ iface->n_requires);
+ iface->requires[iface->n_requires-1] =
+ alloc_string(iface, attrs[i+1]);
+ } else
+ g_warning("unknown attribute `%s' for <requires>.",
+ attrs[i]);
+ }
+ state->state = PARSER_REQUIRES;
+ } else if (!strcmp(name, "widget")) {
+ GladeInterface *iface = state->interface;
+
+ iface->n_toplevels++;
+ iface->toplevels = g_renew(GladeWidgetInfo *, iface->toplevels,
+ iface->n_toplevels);
+ state->widget = create_widget_info(iface, attrs);
+ iface->toplevels[iface->n_toplevels-1] = state->widget;
+
+ state->widget_depth++;
+ state->prop_type = PROP_NONE;
+ state->prop_name = NULL;
+ state->prop_agent = NULL;
+ state->prop_translator_comments = NULL;
+ state->prop_context_prefix = FALSE;
+ state->props = NULL;
+ state->signals = NULL;
+ state->accels = NULL;
+
+ state->state = PARSER_WIDGET;
+ } else {
+ g_warning("Unexpected element <%s> inside <glade-interface>.",
+ name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_REQUIRES:
+ g_warning("<requires> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET:
+ if (!strcmp(name, "property")) {
+ if (state->prop_type != PROP_NONE &&
+ state->prop_type != PROP_WIDGET)
+ g_warning("non widget properties defined here (oh no!)");
+ state->prop_type = PROP_WIDGET;
+ state->translate_prop = FALSE;
+ state->prop_context_prefix = FALSE;
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "name"))
+ state->prop_name = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "translatable"))
+ state->translate_prop = !strcmp(attrs[i+1], "yes");
+ else if (!strcmp(attrs[i], "agent"))
+ state->prop_agent = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "comments"))
+ state->prop_translator_comments = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "context"))
+ state->prop_context_prefix = !strcmp(attrs[i+1], "yes");
+ else
+ g_warning("unknown attribute `%s' for <property>.",
+ attrs[i]);
+ }
+ state->state = PARSER_WIDGET_PROPERTY;
+ } else if (!strcmp(name, "accessibility")) {
+ flush_properties(state);
+
+ if (attrs != NULL && attrs[0] != NULL)
+ g_warning("<accessibility> element should have no attributes");
+ state->state = PARSER_WIDGET_ATK;
+ } else if (!strcmp(name, "signal")) {
+ handle_signal(state, attrs);
+ state->state = PARSER_WIDGET_SIGNAL;
+ } else if (!strcmp(name, "accelerator")) {
+ handle_accel(state, attrs);
+ state->state = PARSER_WIDGET_ACCEL;
+ } else if (!strcmp(name, "child")) {
+ handle_child(state, attrs);
+ state->state = PARSER_WIDGET_CHILD;
+ } else {
+ g_warning("Unexpected element <%s> inside <widget>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_PROPERTY:
+ g_warning("<property> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_ATK:
+ if (!strcmp(name, "atkproperty")) {
+ if (state->prop_type != PROP_NONE &&
+ state->prop_type != PROP_ATK)
+ g_warning("non atk properties defined here (oh no!)");
+ state->prop_type = PROP_ATK;
+ state->translate_prop = FALSE;
+ state->prop_context_prefix = FALSE;
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "name"))
+ state->prop_name = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "translatable"))
+ state->translate_prop = !strcmp(attrs[i+1], "yes");
+ else if (!strcmp(attrs[i], "comments"))
+ state->prop_translator_comments = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "context"))
+ state->prop_context_prefix = !strcmp(attrs[i+1], "yes");
+ else
+ g_warning("unknown attribute `%s' for <atkproperty>.",
+ attrs[i]);
+ }
+ state->state = PARSER_WIDGET_ATK_PROPERTY;
+ } else if (!strcmp(name, "atkaction")) {
+ handle_atk_action(state, attrs);
+ state->state = PARSER_WIDGET_ATK_ACTION;
+ } else if (!strcmp(name, "atkrelation")) {
+ handle_atk_relation(state, attrs);
+ state->state = PARSER_WIDGET_ATK_RELATION;
+ } else {
+ g_warning("Unexpected element <%s> inside <accessibility>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_ATK_PROPERTY:
+ if (!strcmp(name, "accessibility")) {
+ state->state = PARSER_WIDGET_ATK;
+ } else {
+ g_warning("Unexpected element <%s> inside <atkproperty>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_ATK_ACTION:
+ g_warning("<atkaction> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_ATK_RELATION:
+ g_warning("<atkrelation> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_AFTER_ATK:
+ if (!strcmp(name, "signal")) {
+ handle_signal(state, attrs);
+ state->state = PARSER_WIDGET_SIGNAL;
+ } else if (!strcmp(name, "accelerator")) {
+ handle_accel(state, attrs);
+ state->state = PARSER_WIDGET_ACCEL;
+ } else if (!strcmp(name, "child")) {
+ handle_child(state, attrs);
+ state->state = PARSER_WIDGET_CHILD;
+ } else {
+ g_warning("Unexpected element <%s> inside <widget>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_SIGNAL:
+ g_warning("<signal> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_AFTER_SIGNAL:
+ if (!strcmp(name, "accelerator")) {
+ handle_accel(state, attrs);
+ state->state = PARSER_WIDGET_ACCEL;
+ } else if (!strcmp(name, "child")) {
+ handle_child(state, attrs);
+ state->state = PARSER_WIDGET_CHILD;
+ } else {
+ g_warning("Unexpected element <%s> inside <widget>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_ACCEL:
+ g_warning("<accelerator> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_AFTER_ACCEL:
+ if (!strcmp(name, "child")) {
+ handle_child(state, attrs);
+ state->state = PARSER_WIDGET_CHILD;
+ } else {
+ g_warning("Unexpected element <%s> inside <widget>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_CHILD:
+ if (!strcmp(name, "widget")) {
+ GladeWidgetInfo *parent = state->widget;
+ GladeChildInfo *info = &parent->children[parent->n_children-1];
+
+ if (info->child)
+ g_warning("widget pointer already set!! not good");
+
+ state->widget = create_widget_info(state->interface, attrs);
+ info->child = state->widget;
+ info->child->parent = parent;
+
+ state->widget_depth++;
+ state->prop_type = PROP_NONE;
+ state->prop_name = NULL;
+ state->prop_agent = NULL;
+ state->prop_translator_comments = NULL;
+ state->prop_context_prefix = FALSE;
+ state->props = NULL;
+ state->signals = NULL;
+ state->accels = NULL;
+
+ state->state = PARSER_WIDGET;
+ } else if (!strcmp(name, "placeholder")) {
+ /* this isn't a real child, so knock off the last ChildInfo */
+ /* GLADE: We need to know about placeholders so we leave the
+ ChildInfo there. If the 'child' field of the GladeWidgetInfo
+ struct is NULL it is a placeholder. */
+ /*state->widget->n_children--;*/
+ state->state = PARSER_WIDGET_CHILD_PLACEHOLDER;
+ } else {
+ g_warning("Unexpected element <%s> inside <child>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_CHILD_AFTER_WIDGET:
+ if (!strcmp(name, "packing")) {
+ state->state = PARSER_WIDGET_CHILD_PACKING;
+ } else {
+ g_warning("Unexpected element <%s> inside <child>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_CHILD_PACKING:
+ if (!strcmp(name, "property")) {
+ if (state->prop_type != PROP_NONE &&
+ state->prop_type != PROP_CHILD)
+ g_warning("non child properties defined here (oh no!)");
+ state->prop_type = PROP_CHILD;
+ state->translate_prop = FALSE;
+ for (i = 0; attrs && attrs[i] != NULL; i += 2) {
+ if (!strcmp(attrs[i], "name"))
+ state->prop_name = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "translatable"))
+ state->translate_prop = !strcmp(attrs[i+1], "yes");
+ else if (!strcmp(attrs[i], "agent"))
+ state->prop_agent = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "comments"))
+ state->prop_translator_comments = alloc_string(state->interface,
+ attrs[i+1]);
+ else if (!strcmp(attrs[i], "context"))
+ state->prop_context_prefix = !strcmp(attrs[i+1], "yes");
+ else
+ g_warning("unknown attribute `%s' for <property>.",
+ attrs[i]);
+ }
+ state->state = PARSER_WIDGET_CHILD_PACKING_PROPERTY;
+ } else {
+ g_warning("Unexpected element <%s> inside <child>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ }
+ break;
+ case PARSER_WIDGET_CHILD_PACKING_PROPERTY:
+ g_warning("<property> element should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_CHILD_AFTER_PACKING:
+ g_warning("<child> should have no elements after <packing>. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_CHILD_PLACEHOLDER:
+ g_warning("<placeholder> should be empty. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_WIDGET_CHILD_AFTER_PLACEHOLDER:
+ /* this is a placeholder <child> element -- ignore extra elements */
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_FINISH:
+ g_warning("There should be no elements here. Found <%s>.", name);
+ state->prev_state = state->state;
+ state->state = PARSER_UNKNOWN;
+ state->unknown_depth++;
+ break;
+ case PARSER_UNKNOWN:
+ state->unknown_depth++;
+ break;
+ }
+ /* truncate the content string ... */
+ g_string_truncate(state->content, 0);
+}
+
+static void
+glade_parser_end_element(GladeParseState *state, const xmlChar *name)
+{
+ GladeProperty prop;
+ switch (state->state) {
+ case PARSER_START:
+ g_warning("should not be closing any elements in this state");
+ break;
+ case PARSER_GLADE_INTERFACE:
+ if (strcmp(name, "glade-interface") != 0)
+ g_warning("should find </glade-interface> here. Found </%s>",
+ name);
+ state->state = PARSER_FINISH;
+ break;
+ case PARSER_REQUIRES:
+ if (strcmp(name, "requires") != 0)
+ g_warning("should find </requires> here. Found </%s>", name);
+ state->state = PARSER_GLADE_INTERFACE;
+ break;
+ case PARSER_WIDGET:
+ case PARSER_WIDGET_AFTER_ATK:
+ case PARSER_WIDGET_AFTER_SIGNAL:
+ case PARSER_WIDGET_AFTER_ACCEL:
+ if (strcmp(name, "widget") != 0)
+ g_warning("should find </widget> here. Found </%s>", name);
+ flush_properties(state);
+ flush_signals(state);
+ flush_actions(state);
+ flush_relations(state);
+ flush_accels(state);
+ state->widget = state->widget->parent;
+ state->widget_depth--;
+
+ if (state->widget_depth == 0)
+ state->state = PARSER_GLADE_INTERFACE;
+ else
+ state->state = PARSER_WIDGET_CHILD_AFTER_WIDGET;
+ break;
+ case PARSER_WIDGET_PROPERTY:
+ if (strcmp(name, "property") != 0)
+ g_warning("should find </property> here. Found </%s>", name);
+ if (!state->props)
+ state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty));
+ prop.name = state->prop_name;
+ prop.agent = state->prop_agent;
+ prop.translator_comments = state->prop_translator_comments;
+ prop.translatable = state->translate_prop;
+ prop.context_prefix = state->prop_context_prefix;
+ if (state->translate_prop && state->content->str[0] != '\0') {
+ prop.value = alloc_string(state->interface,
+ dgettext(state->domain, state->content->str));
+ } else {
+ prop.value = alloc_string(state->interface, state->content->str);
+ }
+ g_array_append_val(state->props, prop);
+ state->prop_name = NULL;
+ state->prop_agent = NULL;
+ state->prop_translator_comments = NULL;
+ state->state = PARSER_WIDGET;
+ break;
+ case PARSER_WIDGET_ATK:
+ if (strcmp(name, "accessibility") != 0)
+ g_warning("should find </accessibility> here. Found </%s>", name);
+ flush_properties(state); /* flush the ATK properties */
+ state->state = PARSER_WIDGET_AFTER_ATK;
+ break;
+ case PARSER_WIDGET_ATK_PROPERTY:
+ if (strcmp(name, "atkproperty") != 0)
+ g_warning("should find </atkproperty> here. Found </%s>", name);
+ if (!state->props)
+ state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty));
+ prop.name = state->prop_name;
+ prop.translator_comments = state->prop_translator_comments;
+ prop.translatable = state->translate_prop;
+ prop.context_prefix = state->prop_context_prefix;
+ if (state->translate_prop && state->content->str[0] != '\0') {
+ prop.value = alloc_string(state->interface,
+ dgettext(state->domain, state->content->str));
+ } else {
+ prop.value = alloc_string(state->interface, state->content->str);
+ }
+ g_array_append_val(state->props, prop);
+ state->prop_name = NULL;
+ state->prop_translator_comments = NULL;
+ state->state = PARSER_WIDGET_ATK;
+ break;
+ case PARSER_WIDGET_ATK_ACTION:
+ if (strcmp(name, "atkaction") != 0)
+ g_warning("should find </atkaction> here. Found </%s>", name);
+ state->prop_name = NULL;
+ state->state = PARSER_WIDGET_ATK;
+ break;
+ case PARSER_WIDGET_ATK_RELATION:
+ if (strcmp(name, "atkrelation") != 0)
+ g_warning("should find </atkrelation> here. Found </%s>", name);
+ state->prop_name = NULL;
+ state->state = PARSER_WIDGET_ATK;
+ break;
+ case PARSER_WIDGET_SIGNAL:
+ if (strcmp(name, "signal") != 0)
+ g_warning("should find </signal> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_AFTER_ATK;
+ break;
+ case PARSER_WIDGET_ACCEL:
+ if (strcmp(name, "accelerator") != 0)
+ g_warning("should find </accelerator> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_AFTER_SIGNAL;
+ break;
+ case PARSER_WIDGET_CHILD:
+ if (strcmp(name, "child") != 0)
+ g_warning("should find </child> here. Found </%s>", name);
+ /* if we are ending the element in this state, then there
+ * hasn't been a <widget> element inside this <child>
+ * element. (If there was, then we would be in
+ * PARSER_WIDGET_CHILD_AFTER_WIDGET state. */
+ g_warning("no <widget> element found inside <child>. Discarding");
+ g_free(state->widget->children[
+ state->widget->n_children-1].properties);
+ state->widget->n_children--;
+ state->state = PARSER_WIDGET_AFTER_ACCEL;
+ break;
+ case PARSER_WIDGET_CHILD_AFTER_WIDGET:
+ if (strcmp(name, "child") != 0)
+ g_warning("should find </child> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_AFTER_ACCEL;
+ break;
+ case PARSER_WIDGET_CHILD_PACKING:
+ if (strcmp(name, "packing") != 0)
+ g_warning("should find </packing> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_CHILD_AFTER_PACKING;
+ flush_properties(state); /* flush the properties. */
+ break;
+ case PARSER_WIDGET_CHILD_PACKING_PROPERTY:
+ if (strcmp(name, "property") != 0)
+ g_warning("should find </property> here. Found </%s>", name);
+ if (!state->props)
+ state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty));
+ prop.name = state->prop_name;
+ prop.agent = state->prop_agent;
+ prop.translator_comments = state->prop_translator_comments;
+ prop.translatable = state->translate_prop;
+ prop.context_prefix = state->prop_context_prefix;
+ if (state->translate_prop && state->content->str[0] != '\0') {
+ prop.value = alloc_string(state->interface,
+ dgettext(state->domain, state->content->str));
+ } else {
+ prop.value = alloc_string(state->interface, state->content->str);
+ }
+ g_array_append_val(state->props, prop);
+ state->prop_name = NULL;
+ state->prop_agent = NULL;
+ state->prop_translator_comments = NULL;
+ state->state = PARSER_WIDGET_CHILD_PACKING;
+ break;
+ case PARSER_WIDGET_CHILD_AFTER_PACKING:
+ if (strcmp(name, "child") != 0)
+ g_warning("should find </child> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_AFTER_ACCEL;
+ break;
+ case PARSER_WIDGET_CHILD_PLACEHOLDER:
+ if (strcmp(name, "placeholder") != 0)
+ g_warning("should find </placeholder> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_CHILD_AFTER_PLACEHOLDER;
+ break;
+ case PARSER_WIDGET_CHILD_AFTER_PLACEHOLDER:
+ if (strcmp(name, "child") != 0)
+ g_warning("should find </child> here. Found </%s>", name);
+ state->state = PARSER_WIDGET_AFTER_ACCEL;
+ break;
+ case PARSER_FINISH:
+ g_warning("should not be closing any elements in this state");
+ break;
+ case PARSER_UNKNOWN:
+ state->unknown_depth--;
+ if (state->unknown_depth == 0)
+ state->state = state->prev_state;
+ break;
+ }
+}
+
+static void
+glade_parser_characters(GladeParseState *state, const xmlChar *chars, int len)
+{
+ switch (state->state) {
+ case PARSER_WIDGET_PROPERTY:
+ case PARSER_WIDGET_ATK_PROPERTY:
+ case PARSER_WIDGET_CHILD_PACKING_PROPERTY:
+ g_string_append_len(state->content, chars, len);
+ break;
+ default:
+ /* don't care about content in any other states */
+ break;
+ }
+}
+
+static xmlEntityPtr
+glade_parser_get_entity(GladeParseState *state, const xmlChar *name)
+{
+ return xmlGetPredefinedEntity(name);
+}
+
+static void
+glade_parser_warning(GladeParseState *state, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_WARNING, msg, args);
+ va_end(args);
+}
+
+static void
+glade_parser_error(GladeParseState *state, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_CRITICAL, msg, args);
+ va_end(args);
+}
+
+static void
+glade_parser_fatal_error(GladeParseState *state, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_ERROR, msg, args);
+ va_end(args);
+}
+
+static xmlSAXHandler glade_parser = {
+ 0, /* internalSubset */
+ 0, /* isStandalone */
+ 0, /* hasInternalSubset */
+ 0, /* hasExternalSubset */
+ 0, /* resolveEntity */
+ (getEntitySAXFunc)glade_parser_get_entity, /* getEntity */
+ 0, /* entityDecl */
+ 0, /* notationDecl */
+ 0, /* attributeDecl */
+ 0, /* elementDecl */
+ 0, /* unparsedEntityDecl */
+ 0, /* setDocumentLocator */
+ (startDocumentSAXFunc)glade_parser_start_document, /* startDocument */
+ (endDocumentSAXFunc)glade_parser_end_document, /* endDocument */
+ (startElementSAXFunc)glade_parser_start_element, /* startElement */
+ (endElementSAXFunc)glade_parser_end_element, /* endElement */
+ 0, /* reference */
+ (charactersSAXFunc)glade_parser_characters, /* characters */
+ 0, /* ignorableWhitespace */
+ 0, /* processingInstruction */
+ (commentSAXFunc)0, /* comment */
+ (warningSAXFunc)glade_parser_warning, /* warning */
+ (errorSAXFunc)glade_parser_error, /* error */
+ (fatalErrorSAXFunc)glade_parser_fatal_error, /* fatalError */
+};
+
+static void
+widget_info_free(GladeWidgetInfo *info)
+{
+ gint i;
+
+ /* GLADE: info can be NULL for placeholders. */
+ /*g_return_if_fail(info != NULL);*/
+ if (!info)
+ return;
+
+ g_free(info->properties);
+ g_free(info->atk_props);
+ g_free(info->signals);
+ g_free(info->accels);
+
+ for (i = 0; i < info->n_children; i++) {
+ g_free(info->children[i].properties);
+ widget_info_free(info->children[i].child);
+ }
+ g_free(info->children);
+ g_free(info);
+}
+
+/**
+ * glade_interface_destroy
+ * @interface: the GladeInterface structure.
+ *
+ * Frees a GladeInterface structure.
+ */
+void
+glade_interface_destroy(GladeInterface *interface)
+{
+ gint i;
+
+ g_return_if_fail(interface != NULL);
+
+ /* free requirements */
+ g_free(interface->requires);
+
+ for (i = 0; i < interface->n_toplevels; i++)
+ widget_info_free(interface->toplevels[i]);
+ g_free(interface->toplevels);
+
+ g_hash_table_destroy(interface->names);
+
+ /* free the strings hash table. The destroy notify will take care
+ * of the strings. */
+ g_hash_table_destroy(interface->strings);
+
+ g_free(interface);
+}
+
+/**
+ * glade_parser_parse_file
+ * @file: the filename of the glade XML file.
+ * @domain: the translation domain for the XML file.
+ *
+ * This function parses a Glade XML interface file to a GladeInterface
+ * object (which is libglade's internal representation of the
+ * interface data).
+ *
+ * Generally, user code won't need to call this function. Instead, it
+ * should go through the GladeXML interfaces.
+ *
+ * Returns: the GladeInterface structure for the XML file.
+ */
+GladeInterface *
+glade_parser_parse_file(const gchar *file, const gchar *domain)
+{
+ int old_substitute_entities;
+ int result;
+ GladeParseState state = { 0 };
+
+ state.interface = NULL;
+ if (domain)
+ state.domain = domain;
+ else
+ state.domain = textdomain(NULL);
+
+ old_substitute_entities = xmlSubstituteEntitiesDefault(1);
+ result = xmlSAXUserParseFile(&glade_parser, &state, file);
+ xmlSubstituteEntitiesDefault(old_substitute_entities);
+
+ if (result < 0) {
+ g_warning("document not well formed!");
+ if (state.interface)
+ glade_interface_destroy (state.interface);
+ return NULL;
+ }
+ if (state.state != PARSER_FINISH) {
+ g_warning("did not finish in PARSER_FINISH state!");
+ if (state.interface)
+ glade_interface_destroy(state.interface);
+ return NULL;
+ }
+ return state.interface;
+}
+
+/**
+ * glade_parser_parse_buffer
+ * @buffer: a buffer in memory containing XML data.
+ * @len: the length of @buffer.
+ * @domain: the translation domain for the XML file.
+ *
+ * This function is similar to glade_parser_parse_file, except that it
+ * parses XML data from a buffer in memory. This could be used to
+ * embed an interface into the executable, for instance.
+ *
+ * Generally, user code won't need to call this function. Instead, it
+ * should go through the GladeXML interfaces.
+ *
+ * Returns: the GladeInterface structure for the XML buffer.
+ */
+GladeInterface *
+glade_parser_parse_buffer(const gchar *buffer, gint len, const gchar *domain)
+{
+ int old_substitute_entities;
+ int result;
+ GladeParseState state = { 0 };
+
+ state.interface = NULL;
+ if (domain)
+ state.domain = domain;
+ else
+ state.domain = textdomain(NULL);
+
+ old_substitute_entities = xmlSubstituteEntitiesDefault(1);
+ result = xmlSAXUserParseMemory(&glade_parser, &state, buffer, len);
+ xmlSubstituteEntitiesDefault(old_substitute_entities);
+
+ if (result < 0) {
+ g_warning("document not well formed!");
+ if (state.interface)
+ glade_interface_destroy (state.interface);
+ return NULL;
+ }
+ if (state.state != PARSER_FINISH) {
+ g_warning("did not finish in PARSER_FINISH state!");
+ if (state.interface)
+ glade_interface_destroy(state.interface);
+ return NULL;
+ }
+ return state.interface;
+}
+
+static void
+dump_widget(xmlNode *parent, GladeWidgetInfo *info, gint indent)
+{
+ xmlNode *widget = xmlNewNode(NULL, "widget");
+ gint i, j;
+
+ xmlSetProp(widget, "class", info->class);
+ xmlSetProp(widget, "id", info->name);
+ xmlAddChild(parent, widget);
+ xmlNodeAddContent(widget, "\n");
+
+ for (i = 0; i < info->n_properties; i++) {
+ xmlNode *node;
+
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(widget, " ");
+ node = xmlNewNode(NULL, "property");
+ xmlSetProp(node, "name", info->properties[i].name);
+ xmlNodeSetContent(node, info->properties[i].value);
+ xmlAddChild(widget, node);
+ xmlNodeAddContent(widget, "\n");
+ }
+
+ if (info->n_atk_props != 0) {
+ xmlNode *atk;
+
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(widget, " ");
+ atk = xmlNewNode(NULL, "accessibility");
+ xmlAddChild(widget, atk);
+ xmlNodeAddContent(widget, "\n");
+ xmlNodeAddContent(atk, "\n");
+
+ for (i = 0; i < info->n_atk_props; i++) {
+ xmlNode *node;
+
+ for (j = 0; j < indent + 2; j++)
+ xmlNodeAddContent(atk, " ");
+ node = xmlNewNode(NULL, "property");
+ xmlSetProp(node, "name", info->atk_props[i].name);
+ xmlNodeSetContent(node, info->atk_props[i].value);
+ xmlAddChild(atk, node);
+ xmlNodeAddContent(atk, "\n");
+ }
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(atk, " ");
+ }
+
+ for (i = 0; i < info->n_signals; i++) {
+ xmlNode *node;
+
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(widget, " ");
+
+ node = xmlNewNode(NULL, "signal");
+ xmlSetProp(node, "name", info->signals[i].name);
+ xmlSetProp(node, "handler", info->signals[i].handler);
+ if (info->signals[i].after)
+ xmlSetProp(node, "after", "yes");
+ if (info->signals[i].object)
+ xmlSetProp(node, "object", info->signals[i].object);
+ xmlAddChild(widget, node);
+ xmlNodeAddContent(widget, "\n");
+ }
+
+ for (i = 0; i < info->n_accels; i++) {
+ xmlNode *node;
+
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(widget, " ");
+
+ node = xmlNewNode(NULL, "accelerator");
+ xmlSetProp(node, "key", gdk_keyval_name(info->accels[i].key));
+ xmlSetProp(node, "modifier", "something"/*info->accels[i].modifiers*/);
+ xmlSetProp(node, "signal", info->accels[i].signal);
+ xmlAddChild(widget, node);
+ xmlNodeAddContent(widget, "\n");
+ }
+
+ for (i = 0; i < info->n_children; i++) {
+ xmlNode *child;
+ GladeChildInfo *childinfo = &info->children[i];
+ gint k;
+
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(widget, " ");
+
+ child = xmlNewNode(NULL, "child");
+ if (childinfo->internal_child)
+ xmlSetProp(child, "internal-child", childinfo->internal_child);
+ xmlAddChild(widget, child);
+ xmlNodeAddContent(widget, "\n");
+ xmlNodeAddContent(child, "\n");
+
+ for (k = 0; k < childinfo->n_properties; k++) {
+ xmlNode *node;
+
+ for (j = 0; j < indent + 2; j++)
+ xmlNodeAddContent(child, " ");
+ node = xmlNewNode(NULL, "property");
+ xmlSetProp(node, "name", childinfo->properties[i].name);
+ xmlNodeSetContent(node, childinfo->properties[i].value);
+ xmlAddChild(child, node);
+ xmlNodeAddContent(child, "\n");
+ }
+
+ for (j = 0; j < indent + 2; j++)
+ xmlNodeAddContent(child, " ");
+ dump_widget(child, childinfo->child, indent + 2);
+ xmlNodeAddContent(child, "\n");
+
+ for (j = 0; j < indent + 1; j++)
+ xmlNodeAddContent(child, " ");
+ }
+
+ for (j = 0; j < indent; j++)
+ xmlNodeAddContent(widget, " ");
+}
+
+/**
+ * glade_interface_dump
+ * @interface: the GladeInterface
+ * @filename: the filename to write the interface data to.
+ *
+ * This function dumps the contents of a GladeInterface into a file as
+ * XML. It is intended mainly as a debugging tool.
+ */
+void
+glade_interface_dump(GladeInterface *interface, const gchar *filename)
+{
+ xmlDoc *doc;
+ xmlNode *root;
+ gint i;
+
+ doc = xmlNewDoc("1.0");
+ doc->standalone = FALSE;
+ xmlCreateIntSubset(doc, "glade-interface",
+ NULL, "glade-2.0.dtd");
+ root = xmlNewNode(NULL, "glade-interface");
+ xmlDocSetRootElement(doc, root);
+
+ xmlNodeAddContent(root, "\n");
+
+ for (i = 0; i < interface->n_requires; i++) {
+ xmlNode *node = xmlNewNode(NULL, "requires");
+
+ xmlSetProp(node, "lib", interface->requires[i]);
+
+ xmlNodeAddContent(root, " ");
+ xmlAddChild(root, node);
+ xmlNodeAddContent(root, "\n");
+ }
+
+ for (i = 0; i < interface->n_toplevels; i++) {
+ xmlNodeAddContent(root, " ");
+ dump_widget(root, interface->toplevels[i], 1);
+ xmlNodeAddContent(root, "\n");
+ }
+
+ /* output */
+
+ xmlSaveFileEnc(filename, doc, "UTF-8");
+ xmlFreeDoc(doc);
+}
+
+#if 0
+int
+main(int argc, char **argv) {
+ gtk_init(&argc, &argv);
+ if (argc > 1) {
+ GladeInterface *interface = glade_parser_parse_file(argv[1]);
+ g_message("output: %p", interface);
+ if (interface) {
+ glade_interface_dump(interface, "/dev/stdout");
+ glade_interface_destroy(interface);
+ }
+ } else
+ g_message("need filename");
+ return 0;
+}
+#endif
diff --git a/tools/glade/glade/glade-parser.h b/tools/glade/glade/glade-parser.h
new file mode 100644
index 00000000..71c04b07
--- /dev/null
+++ b/tools/glade/glade/glade-parser.h
@@ -0,0 +1,140 @@
+/* -*- Mode: C; c-basic-offset: 4 -*- */
+/*
+ * Glade - a GTK+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * glade-parser.h: functions for parsing glade-2.0 files
+ * Copyright (C) 1998-2002 James Henstridge <james@daa.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file comes from libglade. Though I've had to make a few minor changes
+ * to use it in Glade. Try to keep the versions in sync as much as possible.
+ */
+
+#ifndef GLADE_PARSER_H
+#define GLADE_PARSER_H
+
+#include <glib.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GladeProperty GladeProperty;
+struct _GladeProperty {
+ gchar *name;
+ gchar *agent;
+ gchar *value;
+
+ gchar *translator_comments;
+ gboolean translatable;
+ gboolean context_prefix;
+};
+
+typedef struct _GladeSignalInfo GladeSignalInfo;
+struct _GladeSignalInfo {
+ gchar *name;
+ gchar *handler;
+ gchar *object; /* NULL if this isn't a connect_object signal */
+ guint after : 1;
+ gchar *last_modification_time;
+};
+
+typedef struct _GladeAtkActionInfo GladeAtkActionInfo;
+struct _GladeAtkActionInfo {
+ gchar *action_name;
+ gchar *description;
+};
+
+typedef struct _GladeAtkRelationInfo GladeAtkRelationInfo;
+struct _GladeAtkRelationInfo {
+ gchar *target;
+ gchar *type;
+};
+
+typedef struct _GladeAccelInfo GladeAccelInfo;
+struct _GladeAccelInfo {
+ guint key;
+ GdkModifierType modifiers;
+ gchar *signal;
+};
+
+typedef struct _GladeWidgetInfo GladeWidgetInfo;
+typedef struct _GladeChildInfo GladeChildInfo;
+
+struct _GladeWidgetInfo {
+ GladeWidgetInfo *parent;
+
+ gchar *class;
+ gchar *name;
+
+ GladeProperty *properties;
+ guint n_properties;
+
+ GladeProperty *atk_props;
+ guint n_atk_props;
+
+ GladeSignalInfo *signals;
+ guint n_signals;
+
+ GladeAtkActionInfo *atk_actions;
+ guint n_atk_actions;
+
+ GladeAtkRelationInfo *relations;
+ guint n_relations;
+
+ GladeAccelInfo *accels;
+ guint n_accels;
+
+ GladeChildInfo *children;
+ guint n_children;
+};
+
+struct _GladeChildInfo {
+ GladeProperty *properties;
+ guint n_properties;
+
+ GladeWidgetInfo *child;
+ gchar *internal_child;
+};
+
+typedef struct _GladeInterface GladeInterface;
+struct _GladeInterface {
+ gchar **requires;
+ guint n_requires;
+
+ GladeWidgetInfo **toplevels;
+ guint n_toplevels;
+
+ GHashTable *names;
+
+ GHashTable *strings;
+};
+
+/* the actual functions ... */
+GladeInterface *glade_parser_parse_file (const gchar *file,
+ const gchar *domain);
+GladeInterface *glade_parser_parse_buffer (const gchar *buffer, gint len,
+ const gchar *domain);
+void glade_interface_destroy (GladeInterface *interface);
+
+void glade_interface_dump (GladeInterface *interface,
+ const gchar *filename);
+
+G_END_DECLS
+
+#endif
diff --git a/tools/glade/glade/glade.c b/tools/glade/glade/glade.c
new file mode 100644
index 00000000..9556561e
--- /dev/null
+++ b/tools/glade/glade/glade.c
@@ -0,0 +1,482 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <libxml/parser.h>
+
+#include "gladeconfig.h"
+#include "glade.h"
+#include "glade_clipboard.h"
+#include "glade_project.h"
+#include "glade_project_window.h"
+#include "gbwidget.h"
+#include "editor.h"
+#include "load.h"
+#include "property.h"
+#include "palette.h"
+#include "tree.h"
+#include "utils.h"
+
+/* This is the global clipboard. */
+GtkWidget *glade_clipboard;
+
+void
+glade_app_init (void)
+{
+ /* Initialize debugging flags from the GLADE_DEBUG environment variable. */
+ glade_debug_init ();
+
+ palette_init ();
+ gb_widgets_init ();
+ editor_init ();
+ tree_init ();
+ glade_clipboard = glade_clipboard_new ();
+
+ property_init ();
+}
+
+
+static void
+write_window_geometry (FILE *fp, gchar *window_name, GtkWindow *window)
+{
+ gint x, y, width, height;
+
+ gtk_window_get_size (window, &width, &height);
+ gtk_window_get_position (window, &x, &y);
+ fprintf (fp,
+ "<window id=\"%s\" visible=\"%d\" x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/>\n",
+ window_name, GTK_WIDGET_VISIBLE (window), x, y, width, height);
+}
+
+
+static gchar*
+get_settings_filename (void)
+{
+ const gchar *home_dir;
+
+ home_dir = g_get_home_dir ();
+ if (!home_dir)
+ {
+#ifdef _WIN32
+ home_dir = "C:\\";
+#else
+ /* Just use the root directory. Though it probably won't be writable. */
+ home_dir = G_DIR_SEPARATOR_S;
+#endif
+ }
+
+ return g_strdup_printf ("%s%s.glade2", home_dir, G_DIR_SEPARATOR_S);
+}
+
+
+static gboolean
+get_window_setting (xmlNodePtr child, gchar *property, gint *retval)
+{
+ xmlChar *tmp;
+ gint num_items;
+
+ tmp = xmlGetProp (child, property);
+ if (!tmp)
+ return FALSE;
+
+ num_items = sscanf (tmp, "%d", retval);
+ xmlFree (tmp);
+
+ return (num_items == 1) ? TRUE : FALSE;
+}
+
+
+void
+restore_window_geometry (xmlNodePtr child, GtkWindow *window,
+ gboolean *show_window)
+{
+ int visible, x, y, width, height;
+ gboolean has_visibility, has_x, has_y, has_width, has_height;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ has_visibility = get_window_setting (child, "visible", &visible);
+ has_x = get_window_setting (child, "x", &x);
+ has_y = get_window_setting (child, "y", &y);
+ has_width = get_window_setting (child, "width", &width);
+ has_height = get_window_setting (child, "height", &height);
+
+ if (has_visibility && show_window)
+ *show_window = visible;
+
+ if (has_x && has_y)
+ gtk_window_move (GTK_WINDOW (window), x, y);
+
+ if (has_width && has_height)
+ gtk_window_resize (GTK_WINDOW (window), width, height);
+}
+
+
+void
+glade_load_settings (gpointer project_window,
+ GtkWidget *palette,
+ gboolean *show_palette,
+ GtkWidget *property_editor,
+ gboolean *show_property_editor,
+ GtkWidget *widget_tree,
+ gboolean *show_widget_tree,
+ GtkWidget *clipboard,
+ gboolean *show_clipboard)
+{
+ gchar *filename;
+ xmlDocPtr doc;
+ xmlNodePtr child;
+
+ g_return_if_fail (project_window != NULL);
+ g_return_if_fail (GTK_IS_WINDOW (palette));
+ g_return_if_fail (GTK_IS_WINDOW (property_editor));
+ g_return_if_fail (GTK_IS_WINDOW (widget_tree));
+ g_return_if_fail (GTK_IS_WINDOW (clipboard));
+
+ filename = get_settings_filename ();
+ doc = xmlParseFile (filename);
+ g_free (filename);
+
+ if (!doc)
+ return;
+
+ child = xmlDocGetRootElement (doc);
+
+ for (child = child->children; child; child = child->next)
+ {
+ xmlChar *id;
+
+ if (!xmlStrEqual (child->name, "window"))
+ continue;
+
+ id = xmlGetProp (child, "id");
+ if (id)
+ {
+ if (xmlStrEqual ("MainWindow", id))
+ restore_window_geometry (child, GTK_WINDOW (((GladeProjectWindow*)project_window)->window), NULL);
+ else if (xmlStrEqual ("Palette", id))
+ restore_window_geometry (child, GTK_WINDOW (palette),
+ show_palette);
+ else if (xmlStrEqual ("PropertyEditor", id))
+ restore_window_geometry (child, GTK_WINDOW (property_editor),
+ show_property_editor);
+ else if (xmlStrEqual ("WidgetTree", id))
+ restore_window_geometry (child, GTK_WINDOW (widget_tree),
+ show_widget_tree);
+ else if (xmlStrEqual ("Clipboard", id))
+ restore_window_geometry (child, GTK_WINDOW (clipboard),
+ show_clipboard);
+
+ xmlFree (id);
+ }
+ }
+
+ xmlFreeDoc (doc);
+}
+
+
+void
+glade_save_settings (gpointer project_window,
+ GtkWidget *palette,
+ GtkWidget *property_editor,
+ GtkWidget *widget_tree,
+ GtkWidget *clipboard)
+{
+ gchar *filename;
+ FILE *fp;
+
+ g_return_if_fail (project_window != NULL);
+ g_return_if_fail (GTK_IS_WINDOW (palette));
+ g_return_if_fail (GTK_IS_WINDOW (property_editor));
+ g_return_if_fail (GTK_IS_WINDOW (widget_tree));
+ g_return_if_fail (GTK_IS_WINDOW (clipboard));
+
+ filename = get_settings_filename ();
+ fp = fopen (filename, "w");
+ if (!fp)
+ {
+ g_free (filename);
+ return;
+ }
+
+ fprintf (fp, "<glade-settings>\n");
+ write_window_geometry (fp, "MainWindow", GTK_WINDOW (((GladeProjectWindow*)project_window)->window));
+ write_window_geometry (fp, "Palette", GTK_WINDOW (palette));
+ write_window_geometry (fp, "PropertyEditor", GTK_WINDOW (property_editor));
+ write_window_geometry (fp, "WidgetTree", GTK_WINDOW (widget_tree));
+ write_window_geometry (fp, "Clipboard", GTK_WINDOW (clipboard));
+ fprintf (fp, "</glade-settings>\n");
+ fclose (fp);
+ g_free (filename);
+}
+
+
+/* Simple user interface functions. */
+void
+glade_show_project_window (void)
+{
+
+}
+
+
+void
+glade_hide_project_window (void)
+{
+
+}
+
+
+void
+glade_show_palette (void)
+{
+ palette_show (NULL, NULL);
+}
+
+
+void
+glade_hide_palette (void)
+{
+ palette_hide (NULL, NULL);
+}
+
+
+void
+glade_show_property_editor (void)
+{
+ property_show (NULL, NULL);
+}
+
+
+void
+glade_hide_property_editor (void)
+{
+ property_hide (NULL, NULL);
+}
+
+
+void
+glade_show_widget_tree (void)
+{
+ tree_show (NULL, NULL);
+}
+
+
+void
+glade_hide_widget_tree (void)
+{
+ tree_hide (NULL, NULL);
+}
+
+
+void
+glade_show_clipboard (void)
+{
+ gtk_widget_show (glade_clipboard);
+ gdk_window_show (GTK_WIDGET (glade_clipboard)->window);
+ gdk_window_raise (GTK_WIDGET (glade_clipboard)->window);
+}
+
+
+void
+glade_hide_clipboard (void)
+{
+ glade_util_close_window (glade_clipboard);
+}
+
+
+void
+glade_show_widget_tooltips (gboolean show)
+{
+ gb_widget_set_show_tooltips (show);
+}
+
+
+void
+glade_show_grid (gboolean show)
+{
+ editor_set_show_grid (show);
+}
+
+
+void
+glade_snap_to_grid (gboolean snap)
+{
+ editor_set_snap_to_grid (snap);
+}
+
+
+#if 0
+/* Changed editor_show_grid_settings_dialog and
+ editor_show_grid_settings_dialog to take a widget parameter, to use for
+ selecting a transient parent.
+ These functions don't know about any widgets. Since they're unused,
+ they're commented out. I guess it would be even better to remove them
+ outright. */
+void
+glade_show_grid_settings (void)
+{
+ editor_show_grid_settings_dialog ();
+}
+
+
+void
+glade_show_snap_settings (void)
+{
+ editor_show_snap_settings_dialog ();
+}
+#endif
+
+
+GtkAccelGroup*
+glade_get_global_accel_group (void)
+{
+ /* This is our global accelerator group that should be added to every
+ window, so our main accelerator keys work in every window. */
+ static GtkAccelGroup *accel_group = NULL;
+
+ if (accel_group == NULL)
+ accel_group = gtk_accel_group_new ();
+
+ return accel_group;
+}
+
+
+gchar*
+glade_get_error_message (GladeStatusCode status)
+{
+ switch (status)
+ {
+ case GLADE_STATUS_OK:
+ return _("OK");
+ case GLADE_STATUS_ERROR:
+ return _("Error");
+
+ case GLADE_STATUS_SYSTEM_ERROR:
+ return _("System Error");
+
+ /* File related errors. */
+ case GLADE_STATUS_FILE_OPEN_ERROR:
+ return _("Error opening file");
+ case GLADE_STATUS_FILE_READ_ERROR:
+ return _("Error reading file");
+ case GLADE_STATUS_FILE_WRITE_ERROR:
+ return _("Error writing file");
+
+ case GLADE_STATUS_INVALID_DIRECTORY:
+ return _("Invalid directory");
+
+ /* XML Parsing errors. */
+ case GLADE_STATUS_INVALID_VALUE:
+ return _("Invalid value");
+ case GLADE_STATUS_INVALID_ENTITY:
+ return _("Invalid XML entity");
+ case GLADE_STATUS_START_TAG_EXPECTED:
+ return _("Start tag expected");
+ case GLADE_STATUS_END_TAG_EXPECTED:
+ return _("End tag expected");
+ case GLADE_STATUS_DATA_EXPECTED:
+ return _("Character data expected");
+ case GLADE_STATUS_CLASS_ID_MISSING:
+ return _("Class id missing");
+ case GLADE_STATUS_CLASS_UNKNOWN:
+ return _("Class unknown");
+ case GLADE_STATUS_INVALID_COMPONENT:
+ return _("Invalid component");
+ case GLADE_STATUS_EOF:
+ return _("Unexpected end of file");
+
+ default:
+ return _("Unknown error code");
+ }
+}
+
+
+/*************************************************************************
+ * GladeError - an ADT to represent an error which occurred in Glade.
+ * Currently it is only used for writing source, but it may be
+ * extended for all errors, since GladeStatus doesn't really
+ * provide enough detail to show the user useful messages.
+ *************************************************************************/
+
+GladeError*
+glade_error_new (void)
+{
+ GladeError *error;
+
+ error = g_new (GladeError, 1);
+ error->status = GLADE_STATUS_OK;
+ error->system_errno = 0;
+ error->message = NULL;
+
+ return error;
+}
+
+
+/* Creates a GladeError with the given Glade status code and the printf-like
+ message and arguments. */
+GladeError*
+glade_error_new_general (GladeStatusCode status,
+ gchar *message,
+ ...)
+{
+ GladeError *error;
+ va_list args;
+
+ error = glade_error_new ();
+ error->status = status;
+
+ va_start (args, message);
+ error->message = g_strdup_vprintf (message, args);
+ va_end (args);
+
+ return error;
+}
+
+
+/* Creates a GladeError using the system errno and the printf-like
+ message and arguments. This must be called immediately after the error
+ is detected, so that errno is still valid and can be copied into the
+ GladeError. */
+GladeError*
+glade_error_new_system (gchar *message,
+ ...)
+{
+ GladeError *error;
+ va_list args;
+
+ error = glade_error_new ();
+ error->status = GLADE_STATUS_SYSTEM_ERROR;
+ error->system_errno = errno;
+
+ va_start (args, message);
+ error->message = g_strdup_vprintf (message, args);
+ va_end (args);
+
+ return error;
+}
+
+
+/* Frees the GladeError and its contents. */
+void
+glade_error_free (GladeError *error)
+{
+ g_free (error->message);
+ g_free (error);
+}
diff --git a/tools/glade/glade/glade.h b/tools/glade/glade/glade.h
new file mode 100644
index 00000000..0b6d42fb
--- /dev/null
+++ b/tools/glade/glade/glade.h
@@ -0,0 +1,180 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_H
+#define GLADE_H
+
+#include <gtk/gtkwidget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This is the main header file for the Glade library. */
+
+/* Error codes returned by Glade functions. */
+typedef enum
+{
+ GLADE_STATUS_OK = 0,
+
+ /* General error, when nothing else is suitable. */
+ GLADE_STATUS_ERROR = 1,
+
+ /* System error. In a GladeError, system_errno will hold the error code. */
+ GLADE_STATUS_SYSTEM_ERROR = 2,
+
+ /* File related errors. */
+ GLADE_STATUS_FILE_OPEN_ERROR = 11,
+ GLADE_STATUS_FILE_READ_ERROR = 12,
+ GLADE_STATUS_FILE_WRITE_ERROR = 13,
+
+ GLADE_STATUS_INVALID_DIRECTORY = 15,
+
+ /* XML Parsing errors. */
+ GLADE_STATUS_INVALID_VALUE = 20,
+ GLADE_STATUS_INVALID_ENTITY = 21,
+ GLADE_STATUS_START_TAG_EXPECTED = 22,
+ GLADE_STATUS_END_TAG_EXPECTED = 23,
+ GLADE_STATUS_DATA_EXPECTED = 24,
+ GLADE_STATUS_CLASS_ID_MISSING = 25,
+ GLADE_STATUS_CLASS_UNKNOWN = 26,
+ GLADE_STATUS_INVALID_COMPONENT = 27,
+ GLADE_STATUS_EOF = 28
+} GladeStatusCode;
+
+
+/* This is the global clipboard. */
+extern GtkWidget *glade_clipboard;
+
+typedef struct _GladeWidgetInitData GladeWidgetInitData;
+typedef struct _GladePaletteSectionData GladePaletteSectionData;
+
+typedef struct _GladeProject GladeProject;
+typedef struct _GbWidget GbWidget;
+
+struct _GladeWidgetInitData
+{
+ gchar *name;
+ GbWidget* (*init_func)();
+};
+
+struct _GladePaletteSectionData
+{
+ gchar *section;
+ GladeWidgetInitData *widgets;
+};
+
+
+void glade_app_init (void);
+
+void glade_load_settings (gpointer project_window,
+ GtkWidget *palette,
+ gboolean *show_palette,
+ GtkWidget *property_editor,
+ gboolean *show_property_editor,
+ GtkWidget *widget_tree,
+ gboolean *show_widget_tree,
+ GtkWidget *clipboard,
+ gboolean *show_clipboard);
+void glade_save_settings (gpointer project_window,
+ GtkWidget *palette,
+ GtkWidget *property_editor,
+ GtkWidget *widget_tree,
+ GtkWidget *clipboard);
+/*
+GladeProject* glade_project_new (void);
+GladeProject* glade_project_open (gchar *filename);
+GladeStatusCode glade_project_save (GladeProject *project);
+GladeStatusCode glade_project_set_interface_filename (GladeProject *project);
+GladeStatusCode glade_project_set_graphics_directory (GladeProject *project);
+*/
+
+void glade_show_project_window (void);
+void glade_hide_project_window (void);
+
+void glade_show_palette (void);
+void glade_hide_palette (void);
+
+void glade_show_property_editor (void);
+void glade_hide_property_editor (void);
+
+void glade_show_widget_tree (void);
+void glade_hide_widget_tree (void);
+
+void glade_show_clipboard (void);
+void glade_hide_clipboard (void);
+
+void glade_show_widget_tooltips (gboolean show);
+
+void glade_show_grid (gboolean show);
+void glade_snap_to_grid (gboolean snap);
+#if 0
+/* Changed editor_show_grid_settings_dialog and
+ editor_show_grid_settings_dialog to take a widget parameter, to use for
+ selecting a transient parent.
+ These functions don't know about any widgets. Since they're unused,
+ they're commented out. I guess it would be even better to remove them
+ outright. */
+void glade_show_grid_settings (void);
+void glade_show_snap_settings (void);
+#endif
+
+gchar* glade_get_error_message (GladeStatusCode status);
+
+GtkAccelGroup* glade_get_global_accel_group (void);
+
+
+/*************************************************************************
+ * GladeError - an ADT to represent an error which occurred in Glade.
+ * Currently it is only used for writing source, but it may be
+ * extended for all errors, since GladeStatus doesn't really
+ * provide enough detail to show the user useful messages.
+ *************************************************************************/
+
+typedef struct _GladeError GladeError;
+
+struct _GladeError
+{
+ GladeStatusCode status;
+ gint system_errno;
+ gchar *message;
+};
+
+/* Creates a new GladeError with no error set. */
+GladeError* glade_error_new (void);
+
+/* Creates a GladeError with the given Glade status code and the printf-like
+ message and arguments. */
+GladeError* glade_error_new_general (GladeStatusCode status,
+ gchar *message,
+ ...);
+
+/* Creates a GladeError using the system errno and the printf-like
+ message and arguments. This must be called immediately after the error
+ is detected, so that errno is still valid and can be copied into the
+ GladeError. */
+GladeError* glade_error_new_system (gchar *message,
+ ...);
+
+/* Frees the GladeError and its contents. */
+void glade_error_free (GladeError *error);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_H */
diff --git a/tools/glade/glade/glade_atk.c b/tools/glade/glade/glade_atk.c
new file mode 100644
index 00000000..3a2330cb
--- /dev/null
+++ b/tools/glade/glade/glade_atk.c
@@ -0,0 +1,1662 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-2002 Damon Chaplin
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file contains most of the ATK-related code in Glade.
+ * It handles the properties, actions and relations in the property editor.
+ */
+
+#include <config.h>
+#include <gladeconfig.h>
+
+#include <string.h>
+
+#include <atk/atk.h>
+#include <gtk/gtkcellrenderertoggle.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkliststore.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkvbox.h>
+
+#include "property.h"
+#include "save.h"
+#include "source.h"
+#include "utils.h"
+#include "glade_atk.h"
+
+#include "graphics/glade-atk.xpm"
+
+const gchar *GladeATKName = "AtkObject::accessible_name";
+const gchar *GladeATKDescription = "AtkObject::accessible_description";
+/* There is a problem with this as AtkObject says it is a string property
+ but it really is an AtkObject. I've taken it out for now. */
+#if 0
+const gchar *GladeATKTableCaption = "AtkObject::accessible_table_caption";
+#endif
+
+/* These are keys we use to store data in the property value widget - the
+ entry in the property editor that shows relations. */
+const gchar *GladeATKPropertyName = "GladeATKPropertyName";
+const gchar *GladeATKRelationType = "GladeATKRelationType";
+const gchar *GladeATKRelationsDialog = "GladeATKRelationsDialog";
+
+/* These are keys we use to store data in the relations dialog. */
+const gchar *GladeATKValueWidget = "GladeATKValueWidget";
+const gchar *GladeATKRelationsListStore = "GladeATKRelationsListStore";
+const gchar *GladeATKRelationsWidgets = "GladeATKRelationsWidgets";
+
+
+/* These are the GtkTables used in the property editor to contain the action
+ properties and the relation properties. */
+static GtkWidget *actions_table = NULL;
+static GtkWidget *relations_table = NULL;
+
+/* This is a list of the relation property value widgets, i.e. the GtkEntry
+ widgets in the property editor for each relation. */
+static GList *relations_properties = NULL;
+
+/* A hash of action property widgets. The keys are the Glade property names
+ ('AtkAction:<action-name>') and the values are the widgets in the property
+ editor. */
+static GHashTable *action_properties = NULL;
+static gint n_action_properties = 0;
+
+enum
+{
+ COLUMN_SELECTED,
+ COLUMN_WIDGET_NAME
+};
+
+
+/***************************************************************************
+ * Utility functions.
+ ***************************************************************************/
+
+/* Returns the property name to use in the property editor given a relation
+ type name. We need to add a prefix to make sure we don't clash with other
+ types of properties. The returned string must be freed. */
+static gchar *
+glade_atk_get_relation_property_name (const char *name)
+{
+ return g_strdup_printf ("AtkRelation:%s", name);
+}
+
+
+typedef struct _GladePropertyLabel GladePropertyLabel;
+struct _GladePropertyLabel
+{
+ const char *name;
+ const char *label;
+};
+
+
+/* This table lets us translate relation names to show in the property editor.
+ These are the standard relations from from atkrelation.h. */
+GladePropertyLabel relation_names_table[] = {
+ { "controlled-by", N_("Controlled By") },
+ { "controller-for", N_("Controller For") },
+ { "label-for", N_("Label For") },
+ { "labelled-by", N_("Labelled By") },
+ { "member-of", N_("Member Of") },
+ { "node-child-of", N_("Node Child Of") },
+ { "flows-to", N_("Flows To") },
+ { "flows-from", N_("Flows From") },
+ { "subwindow-of", N_("Subwindow Of") },
+ { "embeds", N_("Embeds") },
+ { "embedded-by", N_("Embedded By") },
+ { "popup-for", N_("Popup For") },
+ { "parent-window-of", N_("Parent Window Of") }
+};
+
+/* This returns the translated relation name. We hardcode some strings here so
+ we can translate them. The returned string should not be freed. */
+static const gchar*
+glade_atk_get_relation_name_for_display (const gchar *name)
+{
+ const char *label = name;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (relation_names_table); i++)
+ {
+ if (!strcmp (name, relation_names_table[i].name))
+ label = _(relation_names_table[i].label);
+ }
+
+ return label;
+}
+
+/* This returns the label to use for the given relation name. We hardcode some
+ strings here so we can translate the action names. The returned string
+ should be freed. */
+static gchar*
+glade_atk_get_relation_property_label (const gchar *name)
+{
+ const char *label;
+
+ label = glade_atk_get_relation_name_for_display (name);
+ return g_strdup_printf ("%s:", label);
+}
+
+
+/***************************************************************************
+ * The Relations Dialog.
+ ***************************************************************************/
+
+typedef struct _GladeRelationsApplyData GladeRelationsApplyData;
+struct _GladeRelationsApplyData
+{
+ gint row;
+ GList *widget_pointers;
+
+ GList *targets;
+ GString *buffer;
+};
+
+static gboolean
+relations_dialog_apply_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GladeRelationsApplyData *data = user_data;
+ gboolean selected;
+
+ gtk_tree_model_get (model, iter, COLUMN_SELECTED, &selected, -1);
+
+ if (selected)
+ {
+ GtkWidget *widget = data->widget_pointers->data;
+
+ if (widget)
+ {
+ data->targets = g_list_prepend (data->targets, widget);
+
+ /* We add a weak pointer to the widget, so the element data will be
+ set to NULL if the widget is destroyed. */
+#if 0
+ g_print ("Adding weak pointer Object:%p Pointer:%p\n",
+ widget, &data->targets->data);
+#endif
+ g_object_add_weak_pointer (G_OBJECT (widget),
+ &data->targets->data);
+
+ /* Add a comma if the string isn't empty. */
+ if (data->buffer->len > 0)
+ g_string_append_c (data->buffer, ',');
+ g_string_append (data->buffer, gtk_widget_get_name (widget));
+ }
+ }
+
+ if (data->widget_pointers)
+ data->widget_pointers = data->widget_pointers->next;
+ data->row++;
+ return FALSE;
+}
+
+
+static void
+relations_dialog_apply (GtkWidget *relations_dialog)
+{
+ GtkWidget *widget, *value_widget;
+ GladeWidgetData *wdata;
+ GtkTreeModel *model;
+ AtkRelationType relationship;
+ GList *widget_pointers;
+ GladeRelationsApplyData data;
+
+ widget = property_get_widget ();
+ if (!widget)
+ return;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ value_widget = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKValueWidget);
+ g_return_if_fail (value_widget != NULL);
+
+ model = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsListStore);
+ g_return_if_fail (model != NULL);
+
+ widget_pointers = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsWidgets);
+
+ relationship = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (value_widget), GladeATKRelationType));
+
+ /* Step through the list of widgets in the dialog, adding selected widgets
+ to a list of targets. */
+ data.row = 0;
+ data.widget_pointers = widget_pointers;
+ data.buffer = g_string_sized_new (256);
+ data.targets = NULL;
+ gtk_tree_model_foreach (model, relations_dialog_apply_cb, &data);
+
+ /* Update the field in the property editor. */
+ gtk_entry_set_text (GTK_ENTRY (value_widget), data.buffer->str);
+ g_string_free (data.buffer, TRUE);
+
+ /* Now set the relation in the GladeWidgetData. */
+ glade_widget_data_set_relation (wdata, relationship, data.targets);
+}
+
+
+static void
+relations_dialog_response_cb (GtkWidget *dialog, gint response_id)
+{
+
+ if (response_id == GTK_RESPONSE_APPLY || response_id == GTK_RESPONSE_OK)
+ relations_dialog_apply (dialog);
+
+ if (response_id == GTK_RESPONSE_APPLY)
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_APPLY, FALSE);
+
+ if (response_id != GTK_RESPONSE_APPLY)
+ gtk_widget_hide (dialog);
+}
+
+
+static void
+relations_widget_toggled_cb (GtkWidget *widget, gchar *path_str,
+ GtkWidget *relations_dialog)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean selected;
+
+ model = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsListStore);
+
+ /* Toggle the selected flag. */
+ path = gtk_tree_path_new_from_string (path_str);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+
+ gtk_tree_model_get (model, &iter, COLUMN_SELECTED, &selected, -1);
+ selected = selected ? FALSE : TRUE;
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_SELECTED,
+ selected, -1);
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (relations_dialog),
+ GTK_RESPONSE_APPLY, TRUE);
+}
+
+
+static GtkWidget*
+create_relations_dialog (GtkWidget *value_widget)
+{
+ GtkWindow *property_editor;
+ GtkWidget *relations_dialog, *scrolledwin, *treeview;
+ GtkListStore *list_store;
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *rend;
+ AtkRelationType relationship;
+ const gchar *relation_name, *name;
+ gchar *title;
+
+ property_editor = GTK_WINDOW (gtk_widget_get_toplevel (value_widget));
+
+ relationship = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (value_widget), GladeATKRelationType));
+ relation_name = atk_relation_type_get_name (relationship);
+ name = glade_atk_get_relation_name_for_display (relation_name);
+
+ /* I don't think we should set the transient parent as the dialog could be
+ left open if desired. */
+ title = g_strdup_printf (_("Relationship: %s"), name);
+ relations_dialog = gtk_dialog_new_with_buttons (title,
+ NULL /*property_editor*/,
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ GTK_STOCK_APPLY,
+ GTK_RESPONSE_APPLY,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+ g_free (title);
+ gtk_window_set_default_size (GTK_WINDOW (relations_dialog), 250, 300);
+ /* We say it is a normal window as it may be left open if desired. */
+ gtk_window_set_type_hint (GTK_WINDOW (relations_dialog),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ scrolledwin = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwin);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwin),
+ GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (relations_dialog)->vbox),
+ scrolledwin, TRUE, TRUE, 0);
+
+ list_store = gtk_list_store_new (2, G_TYPE_BOOLEAN, G_TYPE_STRING);
+
+ treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
+ g_object_unref (G_OBJECT (list_store));
+ gtk_widget_show (treeview);
+ gtk_container_add (GTK_CONTAINER (scrolledwin), treeview);
+
+ rend = gtk_cell_renderer_toggle_new ();
+ col = gtk_tree_view_column_new_with_attributes ("", rend,
+ "active", COLUMN_SELECTED,
+ NULL);
+ gtk_tree_view_column_set_resizable (col, FALSE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), col);
+ gtk_signal_connect (GTK_OBJECT (rend), "toggled",
+ GTK_SIGNAL_FUNC (relations_widget_toggled_cb),
+ relations_dialog);
+
+ rend = gtk_cell_renderer_text_new ();
+ col = gtk_tree_view_column_new_with_attributes (_("Widget"), rend,
+ "text", COLUMN_WIDGET_NAME,
+ NULL);
+ gtk_tree_view_column_set_resizable (col, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), col);
+
+ gtk_signal_connect (GTK_OBJECT (relations_dialog), "response",
+ GTK_SIGNAL_FUNC (relations_dialog_response_cb),
+ value_widget);
+ gtk_signal_connect (GTK_OBJECT (relations_dialog), "delete-event",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Save a pointer to the dialog in the value widget and vice versa, and save
+ a pointer to the list store in the dialog. */
+ gtk_object_set_data (GTK_OBJECT (value_widget),
+ GladeATKRelationsDialog, relations_dialog);
+ gtk_object_set_data (GTK_OBJECT (relations_dialog),
+ GladeATKValueWidget, value_widget);
+ gtk_object_set_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsListStore, list_store);
+
+ return relations_dialog;
+}
+
+
+/* This is a recursive function to traverse the widget hierarchy and add all
+ the GbWidgets to the list. */
+void
+scan_widgets (GtkWidget *widget, GList **widget_list)
+{
+ /* First add this widget, if it is a GbWidget. */
+ if (GB_IS_GB_WIDGET (widget))
+ {
+ /* GbWidget names shouldn't be empty, but check just in case. */
+ const gchar *name = gtk_widget_get_name (widget);
+ if (name && *name)
+ *widget_list = g_list_prepend (*widget_list, widget);
+ }
+
+ /* Now add child widgets recursively. */
+ gb_widget_children_foreach (widget, (GtkCallback) scan_widgets,
+ widget_list);
+}
+
+
+gint
+compare_widget_names (GtkWidget *a, GtkWidget *b)
+{
+ const char *namea = gtk_widget_get_name (a);
+ const char *nameb = gtk_widget_get_name (b);
+ return g_utf8_collate (namea, nameb);
+}
+
+
+/* Remove all the weak pointers to the widgets. */
+static void
+clear_relations_dialog_weak_pointers (GList *widget_pointers)
+{
+ GList *elem;
+
+ for (elem = widget_pointers; elem; elem = elem->next)
+ {
+ GtkWidget *widget = elem->data;
+ if (widget)
+ {
+#if 0
+ g_print ("Removing weak pointer Object:%p Pointer:%p\n",
+ widget, &elem->data);
+#endif
+ g_object_remove_weak_pointer (G_OBJECT (widget), &elem->data);
+ }
+ }
+
+ g_list_free (widget_pointers);
+}
+
+
+/* This refreshes the contents of a relations dialog. It clears the list,
+ then adds all widgets in the same component as the widget shown in the
+ property editor, selecting those that are in this relation. */
+/* FIXME: Note that we could share the list of widgets in the component among
+ all the relations dialogs. That would be more efficient, though it should
+ only make a difference when several relations dialogs are left open. */
+static void
+glade_atk_refresh_relations_dialog (GtkWidget *relations_dialog)
+{
+ GtkWidget *widget, *value_widget, *toplevel;
+ GladeWidgetData *wdata;
+ GList *widget_list = NULL, *elem, *targets = NULL;
+ GtkListStore *list_store;
+ GList *widget_pointers;
+ AtkRelationType relationship;
+
+ widget = property_get_widget ();
+ g_return_if_fail (widget != NULL);
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ value_widget = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKValueWidget);
+ g_return_if_fail (value_widget != NULL);
+
+ /* Get a pointer to the list store that we set when creating the dialog. */
+ list_store = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsListStore);
+ g_return_if_fail (list_store != NULL);
+
+ /* Clear the list. */
+ gtk_list_store_clear (list_store);
+
+ /* Remove all the weak pointers to the widgets. */
+ widget_pointers = gtk_object_get_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsWidgets);
+ clear_relations_dialog_weak_pointers (widget_pointers);
+ widget_pointers = NULL;
+
+ /* Traverse the widget hierarchy of the window the widget is in, adding
+ all GbWidgets to a list, and sort it by their names. */
+ toplevel = glade_util_get_toplevel (widget);
+ scan_widgets (toplevel, &widget_list);
+ widget_list = g_list_sort (widget_list, (GCompareFunc) compare_widget_names);
+
+ /* Get the current relations, so we can check them in the list. */
+ relationship = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (value_widget), GladeATKRelationType));
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ GladeRelation *relation = elem->data;
+ if (relation->relationship == relationship)
+ {
+ targets = relation->targets;
+ break;
+ }
+ }
+
+ /* Now add the widgets to the list store. If the widget is already
+ in the relation, check the checkbox. */
+ for (elem = widget_list; elem; elem = elem->next)
+ {
+ GtkWidget *widget_to_add = elem->data;
+ GtkTreeIter iter;
+ gboolean selected = FALSE;
+
+ if (g_list_find (targets, widget_to_add))
+ selected = TRUE;
+
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter,
+ 0, selected,
+ 1, gtk_widget_get_name (widget_to_add),
+ -1);
+
+ widget_pointers = g_list_prepend (widget_pointers, widget_to_add);
+ /* Add a weak pointer, so it gets set to NULL if the widget is
+ destroyed. */
+#if 0
+ g_print ("Adding weak pointer Object:%p Pointer:%p\n",
+ widget_to_add, &widget_pointers->data);
+#endif
+ g_object_add_weak_pointer (G_OBJECT (widget_to_add),
+ &widget_pointers->data);
+ }
+
+ widget_pointers = g_list_reverse (widget_pointers);
+ gtk_object_set_data (GTK_OBJECT (relations_dialog),
+ GladeATKRelationsWidgets, widget_pointers);
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (relations_dialog),
+ GTK_RESPONSE_APPLY, FALSE);
+}
+
+
+/* This is the callback that is called when the little button on the right
+ of each relation property is clicked. value_button is the little button
+ that was clicked. value_widget is the entry to the left of it. */
+static void
+show_relations_dialog (GtkWidget *value_button,
+ gpointer value_widget)
+{
+ GtkWidget *relations_dialog;
+
+ /* Create the dialog if it we don't already have one for this relation. */
+ relations_dialog = gtk_object_get_data (GTK_OBJECT (value_widget),
+ GladeATKRelationsDialog);
+ if (!relations_dialog)
+ relations_dialog = create_relations_dialog (value_widget);
+
+ glade_atk_refresh_relations_dialog (relations_dialog);
+
+ /* Show the dialog, or raise it if it is already shown. */
+ gtk_widget_show (relations_dialog);
+ gdk_window_show (GTK_WIDGET (relations_dialog)->window);
+ gdk_window_raise (GTK_WIDGET (relations_dialog)->window);
+}
+
+
+/* This updates any relations dialogs which are currently visible, when the
+ widget being shown in the property editor changes (maybe to NULL). */
+void
+glade_atk_update_relation_dialogs (void)
+{
+ GList *elem;
+
+ /* Iterate over the list of relations value widgets (the entry fields in
+ the property editor). Get the associated dialog, if it has been created,
+ and check if it is visible. If it is, refresh it. */
+ for (elem = relations_properties; elem; elem = elem->next)
+ {
+ GtkWidget *value_widget = elem->data;
+ GtkWidget *relations_dialog;
+
+ relations_dialog = gtk_object_get_data (GTK_OBJECT (value_widget),
+ GladeATKRelationsDialog);
+ if (relations_dialog && GTK_WIDGET_DRAWABLE (relations_dialog))
+ {
+ glade_atk_refresh_relations_dialog (relations_dialog);
+ }
+ }
+}
+
+
+/***************************************************************************
+ * Creating the initial properties in the property editor.
+ ***************************************************************************/
+
+/* This creates the ATK properties page of the property editor.
+ We add the standard atk properties and relations here. Actions and other
+ relations may get added as needed. */
+void
+glade_atk_create_property_page (GtkNotebook *notebook)
+{
+ GtkWidget *page, *icon, *vbox, *table;
+ GdkPixbuf *pixbuf;
+ /* Don't use AtkRelationType here since new values can be registered
+ dynamically, which can cause problems with optimizing compilers. */
+ int relationship;
+
+ page = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show (page);
+
+ /* We use an icon for the notebook tab, as there isn't much room for text. */
+ pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**) glade_atk_xpm);
+ icon = gtk_image_new_from_pixbuf (pixbuf);
+ gdk_pixbuf_unref (pixbuf);
+ gtk_widget_show (icon);
+
+ gtk_notebook_append_page (notebook, page, icon);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (page), vbox);
+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (GTK_BIN (page)->child),
+ GTK_SHADOW_NONE);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_widget_show (table);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
+
+ property_set_table_position (table, 0);
+
+ property_add_string (GladeATKName, _("Name:"),
+ _("The name of the widget to pass to assistive technologies"));
+ property_add_text (GladeATKDescription, _("Description:"),
+ _("The description of the widget to pass to assistive technologies"), 4);
+#if 0
+ property_add_text (GladeATKTableCaption, _("Table Caption:"),
+ _("The table caption to pass to assistive technologies"), 2);
+#endif
+
+ /* We create separate tables for the actions and relations as we need to be
+ able to add properties to them as they are needed. */
+ actions_table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (actions_table), 1);
+ gtk_widget_show (actions_table);
+ gtk_box_pack_start (GTK_BOX (vbox), actions_table, FALSE, TRUE, 0);
+
+ action_properties = g_hash_table_new (g_str_hash, g_str_equal);
+
+ relations_table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (relations_table), 1);
+ gtk_widget_show (relations_table);
+ gtk_box_pack_start (GTK_BOX (vbox), relations_table, FALSE, TRUE, 0);
+
+ /* We assume that all relation types will have already been registered by
+ now. I hope that is correct. */
+ property_set_table_position (relations_table, 0);
+ for (relationship = 0; ; relationship++)
+ {
+ /* Skip these 2 as they aren't real relations. */
+ if (relationship != ATK_RELATION_NULL
+ && relationship != ATK_RELATION_LAST_DEFINED)
+ {
+ const gchar *name = atk_relation_type_get_name (relationship);
+ char *property_name, *property_label;
+ GtkWidget *value_widget;
+
+ if (!name)
+ break;
+
+ property_name = glade_atk_get_relation_property_name (name);
+ property_label = glade_atk_get_relation_property_label (name);
+
+ property_add_dialog (property_name, property_label,
+ _("Select the widgets with this relationship"),
+ FALSE, show_relations_dialog);
+
+ /* Store the property name and the relation type in the value widget,
+ so we can find them later. */
+ value_widget = property_get_value_widget (property_name);
+ relations_properties = g_list_prepend (relations_properties,
+ value_widget);
+ gtk_object_set_data_full (GTK_OBJECT (value_widget),
+ GladeATKPropertyName, property_name,
+ g_free);
+ gtk_object_set_data (GTK_OBJECT (value_widget),
+ GladeATKRelationType,
+ GINT_TO_POINTER (relationship));
+
+ g_free (property_label);
+ }
+ }
+}
+
+
+/***************************************************************************
+ * Showing properties in the property editor.
+ ***************************************************************************/
+
+static void
+glade_atk_get_atk_properties (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetGetArgData * data)
+{
+ const char *name, *description;
+#if 0
+ const char *table_caption;
+ gboolean show_table_caption = FALSE;
+#endif
+
+ name = atk_object_get_name (atko);
+ gb_widget_output_translatable_string (data, GladeATKName, name);
+
+ description = atk_object_get_description (atko);
+ gb_widget_output_translatable_text (data, GladeATKDescription, description);
+
+#if 0
+ if (GTK_IS_TREE_VIEW (widget))
+ {
+ show_table_caption = TRUE;
+
+ g_object_get (G_OBJECT (atko),
+ "AtkObject::accessible-table-caption", &table_caption,
+ NULL);
+ gb_widget_output_translatable_text (data, GladeATKTableCaption,
+ table_caption);
+ }
+
+ if (data->action == GB_SHOWING)
+ property_set_visible (GladeATKTableCaption, show_table_caption);
+#endif
+}
+
+
+/* Returns the property name to use in the property editor given an action
+ name. We need to add a prefix to make sure we don't clash with other
+ types of properties. The returned string must be freed. */
+static gchar *
+glade_atk_get_action_property_name (const char *name)
+{
+ return g_strdup_printf ("AtkAction:%s", name);
+}
+
+
+static void
+hide_action_properties (const gchar * key, gpointer data, gpointer user_data)
+{
+ property_set_visible (key, FALSE);
+}
+
+
+/* This table lets us translate action names to show in the property editor.
+ These are the only 3 actions I can find at present. */
+GladePropertyLabel action_names_table[] = {
+ { "click", N_("Click") },
+ { "press", N_("Press") },
+ { "release", N_("Release") }
+};
+
+/* This returns the label to use for the given action name. We hardcode some
+ strings here so we can translate the action names. The returned string
+ should be freed. */
+static gchar*
+get_action_property_label (const gchar *name)
+{
+ const char *label = name;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (action_names_table); i++)
+ {
+ if (!strcmp (name, action_names_table[i].name))
+ label = _(action_names_table[i].label);
+ }
+
+ return g_strdup_printf ("%s:", label);
+}
+
+
+static void
+glade_atk_get_actions (GtkWidget * widget,
+ AtkAction * action,
+ GbWidgetGetArgData * data)
+{
+ gint n_actions, i;
+
+ /* Hide all the action properties. We'll show the ones the widget supports
+ after. */
+ g_hash_table_foreach (action_properties, (GHFunc) hide_action_properties,
+ NULL);
+
+ n_actions = atk_action_get_n_actions (action);
+ for (i = 0; i < n_actions; i++)
+ {
+ const char *name, *description;
+ char *property_name, *property_label;
+ GtkWidget *value;
+ gboolean free_property_name;
+
+ name = atk_action_get_name (action, i);
+ description = atk_action_get_description (action, i);
+ property_name = glade_atk_get_action_property_name (name);
+ free_property_name = TRUE;
+
+ /* If we already have a property widget for this action, then show it,
+ else create a new property widget to edit the description. */
+ value = property_get_value_widget (property_name);
+ if (value)
+ {
+ property_set_visible (property_name, TRUE);
+ }
+ else
+ {
+ property_set_table_position (actions_table, n_action_properties);
+ property_label = get_action_property_label (name);
+ property_add_text (property_name, property_label,
+ _("Enter the description of the action to pass to assistive technologies"), 2);
+ g_free (property_label);
+ n_action_properties++;
+
+ /* Add to our hash. */
+ value = property_get_value_widget (property_name);
+ g_hash_table_insert (action_properties, property_name, value);
+ free_property_name = FALSE;
+ }
+
+ /* Now set the current value. */
+ property_set_text (property_name, description);
+
+ if (free_property_name)
+ g_free (property_name);
+ }
+}
+
+
+static void
+glade_atk_get_relations (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetGetArgData * data)
+{
+ GladeWidgetData *wdata;
+ GList *elem;
+ GString *buffer;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ buffer = g_string_sized_new (256);
+
+ /* Clear all the relations properties. */
+ for (elem = relations_properties; elem; elem = elem->next)
+ {
+ GtkWidget *value_widget = elem->data;
+ gtk_entry_set_text (GTK_ENTRY (value_widget), "");
+ }
+
+ /* Step through each of the relations in the GladeWidgetData. */
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ GladeRelation *relation = elem->data;
+ const gchar *relation_name;
+ char *property_name;
+ GtkWidget *value_widget;
+
+ /* Find the property for the relationship. */
+ relation_name = atk_relation_type_get_name (relation->relationship);
+ property_name = glade_atk_get_relation_property_name (relation_name);
+
+ value_widget = property_get_value_widget (property_name);
+ if (value_widget)
+ {
+ GList *target;
+
+ /* Convert the list of target widgets to a comma-separated string. */
+ for (target = relation->targets; target; target = target->next)
+ {
+ GtkWidget *target_widget = target->data;
+
+ /* Remember this is a weak pointer so may be NULL. */
+ if (target_widget)
+ {
+ const char *target_name = gtk_widget_get_name (target_widget);
+ if (target_name && *target_name)
+ {
+ /* Add a comma if the string isn't empty. */
+ if (buffer->len > 0)
+ g_string_append_c (buffer, ',');
+ g_string_append (buffer, target_name);
+ }
+ }
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (value_widget), buffer->str);
+ g_string_truncate (buffer, 0);
+ }
+
+ g_free (property_name);
+ }
+
+ g_string_free (buffer, TRUE);
+}
+
+
+/* This shows the widget's ATK properties in the property editor. */
+void
+glade_atk_get_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ AtkObject *atko;
+
+ atko = gtk_widget_get_accessible (widget);
+
+ glade_atk_get_atk_properties (widget, atko, data);
+
+ if (ATK_IS_ACTION (atko))
+ {
+ glade_atk_get_actions (widget, ATK_ACTION (atko), data);
+ gtk_widget_show (actions_table);
+ }
+ else
+ {
+ gtk_widget_hide (actions_table);
+ }
+
+ glade_atk_get_relations (widget, atko, data);
+}
+
+
+/***************************************************************************
+ * Applying properties from the property editor.
+ ***************************************************************************/
+
+static void
+glade_atk_set_atk_properties (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetSetArgData * data)
+{
+ char *name, *description;
+
+ name = gb_widget_input_string (data, GladeATKName);
+ if (data->apply)
+ {
+ /* Set a flag to indicate the name has been set explicitly. */
+ g_object_set_data (G_OBJECT (atko), GladeATKName, "T");
+ atk_object_set_name (atko, name);
+ }
+
+ description = gb_widget_input_text (data, GladeATKDescription);
+ if (data->apply)
+ {
+ g_object_set_data (G_OBJECT (atko), GladeATKDescription, "T");
+ atk_object_set_description (atko, description);
+ }
+ g_free (description);
+
+#if 0
+ if (GTK_IS_TREE_VIEW (widget))
+ {
+ char *table_caption;
+
+ table_caption = gb_widget_input_text (data, GladeATKTableCaption);
+ if (data->apply)
+ {
+ g_object_set_data (G_OBJECT (atko), GladeATKTableCaption, "T");
+ g_object_set (G_OBJECT (atko),
+ "AtkObject::accessible-table-caption", table_caption,
+ NULL);
+ }
+ g_free (table_caption);
+ }
+#endif
+}
+
+
+static void
+glade_atk_set_actions (GtkWidget * widget,
+ AtkAction * action,
+ GbWidgetSetArgData * data)
+{
+ gint n_actions, i;
+
+ n_actions = atk_action_get_n_actions (action);
+ for (i = 0; i < n_actions; i++)
+ {
+ const char *name;
+ char *property_name, *description;
+
+ name = atk_action_get_name (action, i);
+ property_name = glade_atk_get_action_property_name (name);
+
+ description = gb_widget_input_text (data, property_name);
+ if (data->apply)
+ atk_action_set_description (action, i, description);
+ g_free (description);
+
+ g_free (property_name);
+ }
+}
+
+
+/* This applies the ATK properties from the property editor. */
+void
+glade_atk_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ AtkObject *atko;
+
+ atko = gtk_widget_get_accessible (widget);
+
+ glade_atk_set_atk_properties (widget, atko, data);
+
+ if (ATK_IS_ACTION (atko))
+ glade_atk_set_actions (widget, ATK_ACTION (atko), data);
+
+ /* Note that we don't have to set the relations here, since that is done
+ when the relations dialog is closed. */
+}
+
+
+/***************************************************************************
+ * Saving properties in the XML.
+ ***************************************************************************/
+
+static void
+save_atk_property (GbWidgetGetArgData * data, GString *buffer, gint indent,
+ const gchar * tag_name, const gchar * tag_value)
+{
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (tag_value == NULL)
+ return;
+
+ glade_util_get_translation_properties (data->widget, tag_name, &translatable,
+ &comments, &context);
+
+ save_buffer_add_indent (buffer, indent);
+ g_string_append (buffer, "<atkproperty name=\"");
+ save_buffer_add_string (buffer, tag_name);
+ g_string_append_c (buffer, '"');
+
+ if (translatable)
+ {
+ g_string_append (buffer, " translatable=\"yes\"");
+
+ if (context)
+ g_string_append (buffer, " context=\"yes\"");
+
+ if (comments && *comments)
+ {
+ g_string_append (buffer, " comments=\"");
+ save_buffer_add_string (buffer, comments);
+ g_string_append_c (buffer, '"');
+ }
+ }
+
+ g_string_append_c (buffer, '>');
+
+ save_buffer_add_string (buffer, tag_value);
+ g_string_append (buffer, "</atkproperty>\n");
+
+ if (data->save_translatable_strings)
+ save_add_translatable_string (data, tag_value);
+}
+
+
+static void
+glade_atk_save_atk_properties (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetGetArgData * data,
+ GString * buffer,
+ gint indent)
+{
+ const char *name, *description;
+
+ /* We only save the name, description and caption if they are set explicitly
+ by the user, and are not empty. There may be default settings. */
+ name = atk_object_get_name (atko);
+ if (name && *name && g_object_get_data (G_OBJECT (atko), GladeATKName))
+ save_atk_property (data, buffer, indent, GladeATKName, name);
+
+ description = atk_object_get_description (atko);
+ if (description && *description
+ && g_object_get_data (G_OBJECT (atko), GladeATKDescription))
+ save_atk_property (data, buffer, indent, GladeATKDescription, description);
+
+#if 0
+ if (GTK_IS_TREE_VIEW (widget))
+ {
+ const char *table_caption;
+
+ g_object_get (G_OBJECT (atko),
+ "AtkObject::accessible-table-caption", &table_caption,
+ NULL);
+ if (table_caption && *table_caption
+ && g_object_get_data (G_OBJECT (atko), GladeATKTableCaption))
+ save_atk_property (data, buffer, indent, GladeATKTableCaption,
+ table_caption);
+ }
+#endif
+}
+
+
+static void
+glade_atk_save_actions (GtkWidget * widget,
+ AtkAction * action,
+ GbWidgetGetArgData * data,
+ GString * buffer,
+ gint indent)
+{
+ gint n_actions, i;
+
+ n_actions = atk_action_get_n_actions (action);
+ for (i = 0; i < n_actions; i++)
+ {
+ const char *name, *description;
+
+ name = atk_action_get_name (action, i);
+ description = atk_action_get_description (action, i);
+
+ if (description && *description)
+ {
+ save_buffer_add_indent (buffer, indent);
+ g_string_append (buffer, "<atkaction action_name=\"");
+ save_buffer_add_string (buffer, name);
+ g_string_append (buffer, "\" description=\"");
+ save_buffer_add_string (buffer, description);
+ g_string_append (buffer, "\"/>\n");
+
+ if (data->save_translatable_strings)
+ save_add_translatable_string (data, description);
+ }
+ }
+}
+
+
+static void
+glade_atk_save_relations (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetGetArgData * data,
+ GString * buffer,
+ gint indent)
+{
+ GladeWidgetData *wdata;
+ GList *elem;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ GladeRelation *relation = elem->data;
+ const gchar *relation_name;
+ GList *target;
+
+ relation_name = atk_relation_type_get_name (relation->relationship);
+
+ /* We output a separate <atkrelation> element for each target. */
+ for (target = relation->targets; target; target = target->next)
+ {
+ GtkWidget *widget = target->data;
+ if (widget)
+ {
+ const gchar *target_name = gtk_widget_get_name (widget);
+ if (target_name && *target_name)
+ {
+ save_buffer_add_indent (buffer, indent);
+ g_string_append (buffer, "<atkrelation target=\"");
+ save_buffer_add_string (buffer, target_name);
+ g_string_append (buffer, "\" type=\"");
+ save_buffer_add_string (buffer, relation_name);
+ g_string_append (buffer, "\"/>\n");
+ }
+ }
+ }
+ }
+}
+
+
+/* This saves the ATK properties in the XML file. */
+void
+glade_atk_save_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data)
+{
+ AtkObject *atko;
+ GString *buffer;
+ gint indent;
+
+ atko = gtk_widget_get_accessible (widget);
+
+ /* We output all the ATK properties into a buffer. Then if it isn't empty
+ we output an <accessibility> element with the buffer contents. */
+ buffer = g_string_sized_new (1024);
+ indent = data->indent + 1;
+
+ glade_atk_save_atk_properties (widget, atko, data, buffer, indent);
+
+ if (ATK_IS_ACTION (atko))
+ glade_atk_save_actions (widget, ATK_ACTION (atko), data, buffer, indent);
+
+ glade_atk_save_relations (widget, atko, data, buffer, indent);
+
+ if (buffer->len > 0)
+ {
+ save_start_tag (data, "accessibility");
+ g_string_append (data->buffer, buffer->str);
+ save_end_tag (data, "accessibility");
+ }
+
+ g_string_free (buffer, TRUE);
+}
+
+
+/***************************************************************************
+ * Loading properties from the XML.
+ ***************************************************************************/
+
+static void
+glade_atk_load_atk_properties (GtkWidget * widget,
+ AtkObject * atko,
+ GladeWidgetInfo * info)
+{
+ gint i;
+
+ for (i = 0; i < info->n_atk_props; i++)
+ {
+ GladeProperty *prop = &info->atk_props[i];
+
+ if (!strcmp (prop->name, GladeATKName))
+ {
+ /* Set a flag to indicate the name has been set explicitly. */
+ g_object_set_data (G_OBJECT (atko), GladeATKName, "T");
+ atk_object_set_name (atko, prop->value);
+
+ glade_util_set_translation_properties (widget, GladeATKName,
+ prop->translatable,
+ prop->translator_comments,
+ prop->context_prefix);
+ }
+ else if (!strcmp (prop->name, GladeATKDescription))
+ {
+ g_object_set_data (G_OBJECT (atko), GladeATKDescription, "T");
+ atk_object_set_description (atko, prop->value);
+
+ glade_util_set_translation_properties (widget, GladeATKDescription,
+ prop->translatable,
+ prop->translator_comments,
+ prop->context_prefix);
+ }
+#if 0
+ else if (GTK_IS_TREE_VIEW (widget)
+ && !strcmp (prop->name, GladeATKTableCaption))
+ {
+ g_object_set_data (G_OBJECT (atko), GladeATKTableCaption, "T");
+ g_object_set (G_OBJECT (atko),
+ "AtkObject::accessible-table-caption", prop->value,
+ NULL);
+
+ glade_util_set_translation_properties (widget, GladeATKTableCaption,
+ prop->translatable,
+ prop->translator_comments,
+ prop->context_prefix);
+ }
+#endif
+ }
+}
+
+
+static void
+glade_atk_load_actions (GtkWidget * widget,
+ AtkAction * action,
+ GladeWidgetInfo * info)
+{
+ gint n_actions, i, j;
+
+ n_actions = atk_action_get_n_actions (action);
+
+ for (j = 0; j < info->n_atk_actions; j++)
+ {
+ GladeAtkActionInfo *action_info = &info->atk_actions[j];
+
+ for (i = 0; i < n_actions; i++)
+ {
+ const char *name;
+
+ name = atk_action_get_name (action, i);
+ if (!strcmp (name, action_info->action_name))
+ {
+ atk_action_set_description (action, i, action_info->description);
+ break;
+ }
+ }
+ }
+}
+
+
+static void
+glade_atk_load_relations (GtkWidget * widget,
+ AtkObject * atko,
+ GladeWidgetInfo *info,
+ GHashTable *all_widgets)
+{
+ GladeWidgetData *wdata;
+ gint i;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ for (i = 0; i < info->n_relations; i++)
+ {
+ GladeAtkRelationInfo *relation = &info->relations[i];
+ AtkRelationType relationship = ATK_RELATION_NULL;
+ GtkWidget *target = NULL;
+
+ /* Convert the type string to an integer. */
+ if (relation->type && relation->type[0])
+ {
+ relationship = atk_relation_type_for_name (relation->type);
+ if (relationship == ATK_RELATION_NULL)
+ g_warning ("Couldn't find relation type: %s", relation->type);
+ }
+ else
+ g_warning ("<atkrelation> element has no type");
+
+ /* Try to find the target widget. */
+ if (relation->target && relation->target[0])
+ {
+ target = g_hash_table_lookup (all_widgets, relation->target);
+ if (!target)
+ g_warning ("Couldn't find relation target: %s", relation->target);
+ }
+ else
+ g_warning ("<atkrelation> element has no target");
+
+ /* Add the target to the widget's GladeWidgetData. */
+ if (relationship != ATK_RELATION_NULL && target)
+ {
+ glade_widget_data_add_relation (wdata, relationship, target);
+ }
+ }
+}
+
+
+/* This loads the ATK properties from the XML file. It is called after the
+ entire XML file is loaded and all the widgets are created, so that it
+ can resolve relation targets properly. */
+void
+glade_atk_load_properties (GtkWidget * widget,
+ GladeWidgetInfo * info,
+ GHashTable *all_widgets)
+{
+ AtkObject *atko;
+
+ atko = gtk_widget_get_accessible (widget);
+
+ glade_atk_load_atk_properties (widget, atko, info);
+
+ if (ATK_IS_ACTION (atko))
+ glade_atk_load_actions (widget, ATK_ACTION (atko), info);
+
+ glade_atk_load_relations (widget, atko, info, all_widgets);
+}
+
+
+
+
+
+/***************************************************************************
+ * Generating source code.
+ ***************************************************************************/
+
+static void
+glade_gtk_source_add_v (GString *buffer,
+ const gchar *format,
+ va_list args)
+{
+ gchar *buf;
+
+ buf = g_strdup_vprintf (format, args);
+ g_string_append (buffer, buf);
+ g_free (buf);
+}
+
+
+static void
+glade_atk_source_add (GString *buffer,
+ const gchar *format,
+ ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ glade_gtk_source_add_v (buffer, format, args);
+ va_end (args);
+}
+
+
+void
+glade_atk_source_add_translator_comments (GString *buffer,
+ gboolean translatable,
+ const gchar *comments)
+{
+ /* If the property isn't being translated we don't bother outputting the
+ translator comments. */
+ if (!translatable || !comments || comments[0] == '\0')
+ return;
+
+ /* We simply output it in a C comment.
+ FIXME: If the comments contain an end of comment marker it won't
+ compile. */
+ g_string_append (buffer, " /* ");
+ g_string_append (buffer, comments);
+ g_string_append (buffer, " */\n");
+}
+
+
+static void
+glade_atk_write_atk_properties_source (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetWriteSourceData * data,
+ GString * buffer)
+{
+ const char *name, *description;
+ gboolean translatable, context;
+ gchar *comments;
+
+ /* We only generate code for setting the name, description and caption if
+ they are set explicitly by the user, and are not empty. There may be
+ default settings. */
+ name = atk_object_get_name (atko);
+ if (name && *name && g_object_get_data (G_OBJECT (atko), GladeATKName))
+ {
+ glade_util_get_translation_properties (widget, GladeATKName,
+ &translatable,
+ &comments, &context);
+ glade_atk_source_add_translator_comments (buffer, translatable,
+ comments);
+
+ glade_atk_source_add (buffer,
+ " atk_object_set_name (atko, %s);\n",
+ source_make_string_full (name, data->use_gettext && translatable, context));
+ }
+
+ description = atk_object_get_description (atko);
+ if (description && *description
+ && g_object_get_data (G_OBJECT (atko), GladeATKDescription))
+ {
+ glade_util_get_translation_properties (widget, GladeATKDescription,
+ &translatable,
+ &comments, &context);
+ glade_atk_source_add_translator_comments (buffer, translatable,
+ comments);
+
+ glade_atk_source_add (buffer,
+ " atk_object_set_description (atko, %s);\n",
+ source_make_string_full (description, data->use_gettext && translatable, context));
+ }
+
+#if 0
+ if (GTK_IS_TREE_VIEW (widget))
+ {
+ const char *table_caption;
+
+ g_object_get (G_OBJECT (atko),
+ "AtkObject::accessible-table-caption", &table_caption,
+ NULL);
+ if (table_caption && *table_caption
+ && g_object_get_data (G_OBJECT (atko), GladeATKTableCaption))
+ {
+ glade_util_get_translation_properties (widget, GladeATKTableCaption,
+ &translatable,
+ &comments, &context);
+ glade_atk_source_add_translator_comments (buffer, translatable,
+ comments);
+
+ glade_atk_source_add (buffer,
+ " g_object_set (G_OBJECT (atko), \"AtkObject::accessible-table-caption\", %s,\n"
+ " NULL);\n",
+ source_make_string_full (table_caption, data->use_gettext && translatable, context));
+
+ }
+ }
+#endif
+}
+
+
+static void
+glade_atk_write_actions_source (GtkWidget * widget,
+ AtkAction * action,
+ GbWidgetWriteSourceData * data,
+ GString * buffer)
+{
+ gint n_actions, i;
+
+ n_actions = atk_action_get_n_actions (action);
+ for (i = 0; i < n_actions; i++)
+ {
+ const char *name, *description;
+
+ name = atk_action_get_name (action, i);
+ description = atk_action_get_description (action, i);
+
+ if (description && *description)
+ {
+ /* We use a support function to set the action description. */
+ glade_atk_source_add (buffer,
+ " glade_set_atk_action_description (ATK_ACTION (atko), %s,\n",
+ source_make_string (name, FALSE));
+
+ glade_atk_source_add (buffer,
+ " %s);\n",
+ source_make_string (description,
+ data->use_gettext));
+ }
+ }
+}
+
+
+static void
+glade_atk_write_relations_source (GtkWidget * widget,
+ AtkObject * atko,
+ GbWidgetWriteSourceData * data,
+ GString * buffer)
+{
+ GladeWidgetData *wdata;
+ gint max_targets = 0;
+ GList *elem;
+ gchar *decl;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ if (!wdata->relations)
+ return;
+
+ /* Find out the maximum number of targets in the relations. We'll use one
+ temporary targets array for all of them. */
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ GladeRelation *relation = elem->data;
+ gint n_targets = 0;
+ GList *target;
+
+ for (target = relation->targets; target; target = target->next)
+ {
+ if (target->data)
+ n_targets++;
+ }
+
+ max_targets = MAX (max_targets, n_targets);
+ }
+
+ if (max_targets == 0)
+ return;
+
+ source_ensure_decl (data, " AtkRelationSet *tmp_relation_set;\n");
+ source_ensure_decl (data, " AtkRelationType tmp_relationship;\n");
+ source_ensure_decl (data, " AtkRelation *tmp_relation;\n");
+ glade_atk_source_add (buffer,
+ " tmp_relation_set = atk_object_ref_relation_set (atko);\n");
+
+ /* Output the declaration of the temporary targets array. */
+ decl = g_strdup_printf (" AtkObject *%s_relation_targets[%i];\n",
+ data->wname, max_targets);
+ source_ensure_decl (data, decl);
+ g_free (decl);
+
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ GladeRelation *relation = elem->data;
+ gint n_targets = 0, target_num = 0;
+ GList *target;
+ const gchar *relation_name;
+
+ /* Remember that target widgets may be NULL if the target widget is
+ destroyed, so we count how many non-NULL targets there are. */
+ for (target = relation->targets; target; target = target->next)
+ {
+ if (target->data)
+ n_targets++;
+ }
+
+ if (n_targets == 0)
+ continue;
+
+ /* We have to get a reference to all the AtkObjects and add them to the
+ targets array. */
+ for (target = relation->targets; target; target = target->next)
+ {
+ GtkWidget *target_widget = target->data;
+ gchar *target_name;
+
+ target_name = source_create_valid_identifier (gtk_widget_get_name (target_widget));
+ glade_atk_source_add (buffer,
+ " %s_relation_targets[%i] = gtk_widget_get_accessible (%s);\n",
+ data->wname, target_num, target_name);
+ g_free (target_name);
+ target_num++;
+ }
+
+ /* We have to output code to lookup the relationship code from the
+ string name, as it may be an externally-defined relationship so the
+ code may change. */
+ relation_name = atk_relation_type_get_name (relation->relationship);
+
+ glade_atk_source_add (buffer,
+ " tmp_relationship = atk_relation_type_for_name (%s);\n",
+ source_make_string (relation_name, FALSE));
+ glade_atk_source_add (buffer,
+ " tmp_relation = atk_relation_new (%s_relation_targets, %i, tmp_relationship);\n",
+ data->wname, target_num);
+
+
+ glade_atk_source_add (buffer,
+ " atk_relation_set_add (tmp_relation_set, tmp_relation);\n"
+ " g_object_unref (G_OBJECT (tmp_relation));\n");
+ }
+
+ glade_atk_source_add (buffer, " g_object_unref (G_OBJECT (tmp_relation_set));\n");
+}
+
+
+/* This generates the source code to set the ATK properties, event descriptions
+ and relations. */
+void
+glade_atk_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ AtkObject *atko;
+ GString *buffer;
+
+ atko = gtk_widget_get_accessible (widget);
+
+ /* We output all the ATK code into a buffer. Then if it isn't empty
+ we output the declaration for the AtkObject and the get_accessible()
+ call. */
+ buffer = g_string_sized_new (1024);
+
+ glade_atk_write_atk_properties_source (widget, atko, data, buffer);
+
+ if (ATK_IS_ACTION (atko))
+ glade_atk_write_actions_source (widget, ATK_ACTION (atko), data, buffer);
+
+ glade_atk_write_relations_source (widget, atko, data, buffer);
+
+ if (buffer->len > 0)
+ {
+ source_ensure_decl (data, " AtkObject *atko;\n");
+
+ source_add_to_buffer (data, GLADE_ATK_SOURCE,
+ " atko = gtk_widget_get_accessible (%s);\n%s\n",
+ data->wname, buffer->str);
+ }
+
+ g_string_free (buffer, TRUE);
+}
+
diff --git a/tools/glade/glade/glade_atk.h b/tools/glade/glade/glade_atk.h
new file mode 100644
index 00000000..bbeee1b0
--- /dev/null
+++ b/tools/glade/glade/glade_atk.h
@@ -0,0 +1,71 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-2002 Damon Chaplin
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * This file contains most of the ATK-related code in Glade.
+ * It handles the properties, actions and relations in the property editor.
+ */
+
+#ifndef GLADE_ATK_H
+#define GLADE_ATK_H
+
+#include <gtk/gtknotebook.h>
+#include "gbwidget.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* This creates the ATK properties page of the property editor. */
+void glade_atk_create_property_page (GtkNotebook *notebook);
+
+/* This shows the widget's ATK properties in the property editor. */
+void glade_atk_get_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+
+/* This updates any relations dialogs which are currently visible, when the
+ widget being shown in the property editor changes (maybe to NULL). */
+void glade_atk_update_relation_dialogs (void);
+
+/* This applies the ATK properties from the property editor. */
+void glade_atk_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data);
+
+/* This saves the ATK properties in the XML file. */
+void glade_atk_save_properties (GtkWidget * widget,
+ GbWidgetGetArgData * data);
+
+/* This loads the ATK properties from the XML file. It is called after all
+ widgets are created, so it can resolve relation targets properly. */
+void glade_atk_load_properties (GtkWidget * widget,
+ GladeWidgetInfo * info,
+ GHashTable *all_widgets);
+
+/* This generates the source code to set the ATK properties. */
+void glade_atk_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_ATK_H */
diff --git a/tools/glade/glade/glade_clipboard.c b/tools/glade/glade/glade_clipboard.c
new file mode 100644
index 00000000..cde84f87
--- /dev/null
+++ b/tools/glade/glade/glade_clipboard.c
@@ -0,0 +1,654 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#else
+#include <gtk/gtk.h>
+#endif
+
+#include "gladeconfig.h"
+
+#include "editor.h"
+#include "glade_clipboard.h"
+#include "gbwidget.h"
+#include "load.h"
+#include "tree.h"
+#include "utils.h"
+#include "gb.h"
+#include "glade_project_window.h"
+
+typedef struct _GladeClipboardItem GladeClipboardItem;
+
+struct _GladeClipboardItem
+{
+ GladeProject *project;
+ GtkType type;
+ gchar *xml_data;
+ gboolean names_unique;
+};
+
+
+static GtkWindowClass *parent_class = NULL;
+
+static void glade_clipboard_class_init (GladeClipboardClass * klass);
+static void glade_clipboard_init (GladeClipboard * clipboard);
+
+static void glade_clipboard_cut_or_copy (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget,
+ gboolean cut);
+static void glade_clipboard_add (GladeClipboard *clipboard,
+ GladeProject *project,
+ gboolean names_unique,
+ GtkWidget *widget,
+ gchar *xml_data);
+static GladeClipboardItem* glade_clipboard_get_current_item (GladeClipboard *clipboard);
+
+static void glade_clipboard_on_project_destroy (GladeProject *project,
+ GladeClipboardItem *item);
+
+
+#define GLADE_PASTE_BUFFER_INCREMENT 1024
+
+
+GType
+glade_clipboard_get_type (void)
+{
+ static GType glade_clipboard_type = 0;
+
+ if (!glade_clipboard_type)
+ {
+ GtkTypeInfo glade_clipboard_info =
+ {
+ "GladeClipboard",
+ sizeof (GladeClipboard),
+ sizeof (GladeClipboardClass),
+ (GtkClassInitFunc) glade_clipboard_class_init,
+ (GtkObjectInitFunc) glade_clipboard_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ glade_clipboard_type = gtk_type_unique (gtk_window_get_type (),
+ &glade_clipboard_info);
+ }
+ return glade_clipboard_type;
+}
+
+
+static void
+glade_clipboard_class_init (GladeClipboardClass * klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) klass;
+
+ parent_class = gtk_type_class (gtk_window_get_type ());
+}
+
+
+static void
+glade_clipboard_init (GladeClipboard * clipboard)
+{
+ GtkWidget *vbox, *scrolled_win;
+
+ gtk_window_set_title (GTK_WINDOW (clipboard), _ ("Clipboard"));
+ gtk_window_set_policy (GTK_WINDOW (clipboard), FALSE, TRUE, FALSE);
+ gtk_window_set_wmclass (GTK_WINDOW (clipboard), "clipboard", "Glade");
+ gtk_window_set_default_size (GTK_WINDOW (clipboard), 150, 200);
+ gtk_window_add_accel_group (GTK_WINDOW (clipboard),
+ glade_get_global_accel_group ());
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_widget_show (vbox);
+ gtk_container_add (GTK_CONTAINER (clipboard), vbox);
+
+ clipboard->clist = gtk_clist_new (1);
+ gtk_clist_set_row_height (GTK_CLIST (clipboard->clist), 23);
+ gtk_widget_set_usize (clipboard->clist, 100, 100);
+ gtk_clist_set_column_width (GTK_CLIST (clipboard->clist), 0, 100);
+ gtk_clist_set_selection_mode (GTK_CLIST (clipboard->clist),
+ GTK_SELECTION_BROWSE);
+ gtk_widget_show (clipboard->clist);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), clipboard->clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_win);
+
+ gtk_signal_connect (GTK_OBJECT (clipboard), "delete_event",
+ GTK_SIGNAL_FUNC (glade_util_close_window_on_delete),
+ NULL);
+
+ gtk_signal_connect_after (GTK_OBJECT (clipboard), "hide",
+ GTK_SIGNAL_FUNC (glade_project_window_uncheck_clipboard_menu_item),
+ NULL);
+}
+
+
+GtkWidget *
+glade_clipboard_new (void)
+{
+ return GTK_WIDGET (gtk_type_new (glade_clipboard_get_type ()));
+}
+
+
+void
+glade_clipboard_cut (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget)
+{
+ glade_clipboard_cut_or_copy (clipboard, project, widget, TRUE);
+}
+
+
+void
+glade_clipboard_copy (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget)
+{
+ glade_clipboard_cut_or_copy (clipboard, project, widget, FALSE);
+}
+
+
+static void
+glade_clipboard_cut_or_copy (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget,
+ gboolean cut)
+{
+ GbWidgetGetArgData data = { 0 };
+ gchar *old_locale, *saved_locale;
+ GList *selection;
+ gboolean is_component;
+
+ if (widget == NULL)
+ {
+ selection = editor_get_selection ();
+ if (selection)
+ widget = GTK_WIDGET (selection->data);
+ }
+
+ if (widget == NULL || GB_IS_PLACEHOLDER (widget))
+ return;
+
+ data.project = project;
+ data.action = GB_SAVING;
+ data.copying_to_clipboard = TRUE;
+ data.error = NULL;
+
+ /* Initialize the output buffer. */
+ data.buffer = g_string_sized_new (1024);
+ data.indent = 0;
+
+ /* We don't need the translatable strings. */
+ data.save_translatable_strings = FALSE;
+ data.translatable_strings = NULL;
+
+ old_locale = setlocale (LC_NUMERIC, NULL);
+ saved_locale = g_strdup (old_locale);
+ setlocale (LC_NUMERIC, "C");
+
+ g_string_append (data.buffer,
+ "<?xml version=\"1.0\" standalone=\"no\"?> <!--*- mode: xml -*-->\n"
+ "<!DOCTYPE glade-interface SYSTEM \"http://glade.gnome.org/glade-project-2.0.dtd\">\n"
+ "\n"
+ "<glade-interface>\n");
+
+ /* If the widget is not a toplevel widget, we add a dummy parent to it.
+ This is so that we keep the packing properties of the widget. */
+ is_component = glade_util_is_component (widget);
+ if (!is_component)
+ {
+ g_string_append (data.buffer,
+ "<widget class=\"GtkWindow\" id=\"glade-dummy-container\">\n");
+ data.indent++;
+ }
+
+ gb_widget_save (widget, &data);
+
+ if (!is_component)
+ {
+ g_string_append (data.buffer,
+ "</widget>\n");
+ }
+
+ g_string_append (data.buffer,
+ "\n</glade-interface>\n");
+
+ setlocale (LC_NUMERIC, saved_locale);
+ g_free (saved_locale);
+
+ if (data.error == NULL)
+ {
+#if 0
+ g_print ("Adding to clipboard:\n%s\n", data.buffer->str);
+#endif
+ glade_clipboard_add (GLADE_CLIPBOARD (clipboard), project, cut,
+ widget, data.buffer->str);
+ if (cut)
+ editor_delete_widget (widget);
+ }
+ else
+ /* This shouldn't happen. */
+ g_warning ("Error saving widget to clipboard");
+
+ g_string_free (data.buffer, TRUE);
+}
+
+
+static void
+initialize_all_widgets_cb (GtkWidget *widget, GbWidgetSetArgData *data)
+{
+ const gchar *widget_name;
+
+ /* If this is the widget we are replacing, just return. We don't want to
+ add it or its descendants to all_widgets. They will no longer exist, so
+ ATK relations can't use them. */
+ if (widget == data->replacing_widget)
+ return;
+
+ /* Add this widget to the all_widgets hash. */
+ if (GB_IS_GB_WIDGET (widget))
+ {
+ widget_name = gtk_widget_get_name (widget);
+ if (widget_name && *widget_name)
+ {
+#if 0
+ g_print ("Initializing pointer to widget: %s, %p\n",
+ widget_name, widget);
+#endif
+ g_hash_table_insert (data->all_widgets, (gpointer) widget_name,
+ widget);
+ }
+ }
+
+ /* Now recursively add the children. */
+ gb_widget_children_foreach (widget, (GtkCallback) initialize_all_widgets_cb,
+ data);
+}
+
+
+/* This adds all widgets that are in the window being pasted into to the
+ all_widgets hash, so ATK relations to other widgets will be set when
+ pasting. */
+static void
+glade_clipboard_initialize_all_widgets (GbWidgetSetArgData *data)
+{
+ GtkWidget *toplevel;
+
+ /* If we aren't pasting into a component, just return. */
+ if (!data->replacing_widget)
+ return;
+
+ toplevel = glade_util_get_toplevel (data->replacing_widget);
+
+ initialize_all_widgets_cb (toplevel, data);
+}
+
+
+/* The widget argument is the widget to be pasted over, i.e. the widget in
+ the current interface that will be replaced by the clipboard item.
+ If it is NULL, the currently selected widget will be used. */
+void
+glade_clipboard_paste (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget)
+{
+ GladeClipboardItem *item;
+ GbWidgetSetArgData data = { 0 };
+ GtkWidget *parent, *new_widget = NULL;
+ gchar *saved_locale, *saved_timezone, *child_name;
+ GList *selection;
+ gboolean is_component = FALSE;
+
+ item = glade_clipboard_get_current_item (clipboard);
+ if (item == NULL)
+ return;
+
+ if (widget == NULL)
+ {
+ selection = editor_get_selection ();
+ if (selection)
+ widget = GTK_WIDGET (selection->data);
+ }
+
+ if (gtk_type_is_a (item->type, gtk_window_get_type ())
+ || gtk_type_is_a (item->type, gtk_menu_get_type ()))
+ is_component = TRUE;
+
+ /* We can only paste toplevel components, i.e. windows and menus, into the
+ project, and not into other widgets. */
+ if (widget == NULL)
+ {
+ if (!is_component)
+ {
+ glade_util_show_message_box (_("You need to select a widget to paste into"), widget);
+ return;
+ }
+ }
+ else
+ {
+ if (is_component)
+ widget = NULL;
+ }
+
+ if (widget)
+ {
+ /* Don't allow pasting into any windows/dialogs. */
+ if (GTK_IS_WINDOW (widget)
+ || GTK_IS_DIALOG (widget)
+ || GTK_IS_COLOR_SELECTION_DIALOG (widget)
+ || GTK_IS_INPUT_DIALOG (widget)
+ || GTK_IS_FONT_SELECTION_DIALOG (widget)
+ || GTK_IS_FILE_SELECTION (widget)
+#ifdef USE_GNOME
+ || GNOME_IS_APP (widget)
+ || GNOME_IS_DIALOG (widget)
+#endif
+ )
+ {
+ glade_util_show_message_box (_("You can't paste into windows or dialogs."), widget);
+ return;
+ }
+
+ /* SPECIAL CODE: Don't allow pasting into dialog widgets. */
+ child_name = gb_widget_get_child_name (widget);
+ if (child_name)
+ {
+ if (!strcmp (child_name, GladeChildOKButton)
+ || !strcmp (child_name, GladeChildCancelButton)
+ || !strcmp (child_name, GladeChildHelpButton)
+ || !strcmp (child_name, GladeChildApplyButton)
+ || !strcmp (child_name, GladeChildSaveButton)
+ || !strcmp (child_name, GladeChildCloseButton)
+ || !strcmp (child_name, GladeChildDialogVBox)
+ || !strcmp (child_name, GladeChildDialogActionArea)
+ || !strcmp (child_name, GladeChildComboEntry)
+ || !strcmp (child_name, GladeChildComboList)
+ || !strcmp (child_name, GladeChildFontSelection)
+ || !strcmp (child_name, GladeChildColorSelection)
+ || !strcmp (child_name, GladeChildGnomeEntry)
+ )
+ {
+ glade_util_show_message_box (_("You can't paste into the selected widget, since\nit is created automatically by its parent."), widget);
+ return;
+ }
+ }
+
+ /* Only allow menuitems to be pasted into menus or menubars. */
+ if (GTK_IS_MENU_SHELL (widget)
+ && !gtk_type_is_a (item->type, gtk_menu_item_get_type ()))
+ {
+ glade_util_show_message_box (_("Only menu items can be pasted into a menu or menu bar."), widget);
+ return;
+ }
+
+ /* Only allow menuitems to replace menuitems. */
+ if (GTK_IS_MENU_ITEM (widget)
+ && !gtk_type_is_a (item->type, gtk_menu_item_get_type ()))
+ {
+ glade_util_show_message_box (_("Only menu items can be pasted into a menu or menu bar."), widget);
+ return;
+ }
+
+ /* Only buttons can be pasted into a dialog action area. */
+ if (widget->parent)
+ {
+ child_name = gb_widget_get_child_name (widget->parent);
+ if (child_name && !strcmp (child_name, GladeChildDialogActionArea)
+ && item->type != GTK_TYPE_BUTTON)
+ {
+ glade_util_show_message_box (_("Only buttons can be pasted into a dialog action area."), widget);
+ return;
+ }
+ }
+
+#ifdef USE_GNOME
+ if (BONOBO_IS_DOCK (widget))
+ {
+ if (!gtk_type_is_a (item->type, bonobo_dock_item_get_type ()))
+ {
+ glade_util_show_message_box (_("Only GnomeDockItem widgets can be pasted into a GnomeDock."), widget);
+ return;
+ }
+ }
+
+ if (BONOBO_IS_DOCK_ITEM (widget))
+ {
+ if (!gtk_type_is_a (item->type, bonobo_dock_item_get_type ()))
+ {
+ glade_util_show_message_box (_("Only GnomeDockItem widgets can be pasted over a GnomeDockItem."), widget);
+ return;
+ }
+ glade_util_show_message_box (_("Sorry - pasting over a GnomeDockItem is not implemented yet."), widget);
+ return;
+ }
+
+ if (gtk_type_is_a (item->type, bonobo_dock_item_get_type ()))
+ {
+ if (!BONOBO_IS_DOCK (widget) && !BONOBO_IS_DOCK_ITEM (widget))
+ {
+ glade_util_show_message_box (_("GnomeDockItem widgets can only be pasted into a GnomeDock."), widget);
+ return;
+ }
+ }
+#endif
+ }
+
+ data.project = project;
+ data.filename = NULL;
+ data.xml_buffer = item->xml_data;
+ data.status = GLADE_STATUS_OK;
+ data.all_widgets = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* We normally create new names for the widgets pasted, discarding the names
+ in the XML data. However, if the widgets were cut to the clipboard, and
+ we are pasting into the same project for the first time, then we use
+ the original names. */
+ data.discard_names = TRUE;
+ if (project == item->project)
+ {
+ if (item->names_unique)
+ {
+ data.discard_names = FALSE;
+ item->names_unique = FALSE;
+ }
+ }
+
+ /* We always try to replace the selected widget, unless it is a GtkFixed,
+ GtkLayout, or GtkPacker, in which case we add the pasted widget as a
+ child. If we didn't do this, then it would be quite difficult to paste
+ children into these widgets. I did consider adding the widget as a child
+ when pasting into other containers like boxes and tables, but then we
+ have a problem with composite widgets, where we may accidentally paste
+ inside the composite (e.g. inside its toplevel vbox).
+ For Gnome, we also allow pasting GnomeDockItems into GnomeDocks. */
+ parent = NULL;
+ data.replacing_widget = NULL;
+ if (widget)
+ {
+ if (GTK_IS_FIXED (widget)
+ || GTK_IS_LAYOUT (widget)
+#ifdef USE_GNOME
+ || BONOBO_IS_DOCK (widget)
+#endif
+ )
+ {
+ parent = widget;
+ }
+ else
+ {
+ parent = widget->parent;
+ data.replacing_widget = widget;
+ }
+ }
+
+ /* Initialize the all_widgets hash with all widget names in the component,
+ except the widget being replaced and any of its descendants. This is
+ done so that ATK relations to targets in the component will still be OK.
+ */
+ glade_clipboard_initialize_all_widgets (&data);
+
+ tree_freeze ();
+
+ /* Set the locale to "C". */
+ saved_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
+ setlocale (LC_NUMERIC, "C");
+
+ /* Set the timezone to "UTC". */
+ saved_timezone = glade_util_set_timezone ("UTC");
+
+ /* Now parse the clipboard data. */
+ data.interface = glade_parser_parse_buffer (data.xml_buffer,
+ strlen (data.xml_buffer), NULL);
+ if (!data.interface || data.interface->n_toplevels != 1)
+ {
+ /* I don't think this should happen, except due to bugs. */
+ g_warning ("Error pasting from clipboard");
+ glade_interface_destroy (data.interface);
+ g_hash_table_destroy (data.all_widgets);
+ return;
+ }
+
+ /* If the widget is a toplevel component, we use the top widget info and
+ no child info. If not, we use the first child, as the toplevel will be
+ a dummy container. */
+ data.child_info = NULL;
+ data.widget_info = data.interface->toplevels[0];
+
+ if (!is_component)
+ {
+ if (data.widget_info->n_children != 1
+ || data.widget_info->children == NULL)
+ {
+ data.status = GLADE_STATUS_ERROR;
+ }
+ else
+ {
+ data.child_info = &data.widget_info->children[0];
+ data.widget_info = data.child_info->child;
+ }
+ }
+
+ /* Create the widget. */
+ if (data.status == GLADE_STATUS_OK)
+ new_widget = gb_widget_load (NULL, &data, parent);
+
+ /* Destroy the parse data. */
+ glade_interface_destroy (data.interface);
+
+ /* Reset the timezone. */
+ glade_util_reset_timezone (saved_timezone);
+
+ /* Reset the locale. */
+ setlocale (LC_NUMERIC, saved_locale);
+ g_free (saved_locale);
+
+ tree_thaw ();
+
+ g_hash_table_destroy (data.all_widgets);
+
+ if (data.status != GLADE_STATUS_OK)
+ {
+ /* I don't think this should happen, except due to bugs. */
+ g_warning ("Error pasting from clipboard");
+ return;
+ }
+
+ /* If a window was pasted, show it. */
+ if (GTK_IS_WINDOW (new_widget))
+ glade_project_show_component (project, new_widget);
+}
+
+
+/* This adds the XML for a widget (and any descendants) to the clipboard.
+ If the widget has been cut and is later pasted into the same project,
+ then the same widget names can be used. Otherwise new widget names have
+ to be created. The widget parameter is used to get the widget's name and
+ class and to look up its pixmap to display in the clipboard.
+ The xml_data parameter is copied. */
+static void
+glade_clipboard_add (GladeClipboard *clipboard,
+ GladeProject *project,
+ gboolean names_unique,
+ GtkWidget *widget,
+ gchar *xml_data)
+{
+ GladeClipboardItem *item;
+ GbWidget *gbwidget;
+ gchar *name;
+
+ name = (char*) gtk_widget_get_name (widget);
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ item = g_new (GladeClipboardItem, 1);
+ item->project = project;
+ item->type = GTK_OBJECT_TYPE (widget);
+ item->xml_data = g_strdup (xml_data);
+ item->names_unique = names_unique;
+
+ /* Connect to the project's destroy signal to set the pointer to NULL, so
+ we never have invalid pointers. */
+ gtk_signal_connect (GTK_OBJECT (project), "destroy",
+ GTK_SIGNAL_FUNC (glade_clipboard_on_project_destroy),
+ item);
+
+ gtk_clist_insert (GTK_CLIST (clipboard->clist), 0, &name);
+ gtk_clist_set_row_data (GTK_CLIST (clipboard->clist), 0, item);
+
+ gtk_clist_set_pixtext (GTK_CLIST (clipboard->clist), 0, 0, name, 3,
+ gbwidget->gdkpixmap, gbwidget->mask);
+
+ gtk_clist_select_row (GTK_CLIST (clipboard->clist), 0, 0);
+}
+
+
+/* This returns the currently-selected GladeClipboardItem, or NULL if no item
+ is currently selected (i.e. the clipboard is empty). */
+static GladeClipboardItem*
+glade_clipboard_get_current_item (GladeClipboard *clipboard)
+{
+ GList *selection;
+
+ selection = GTK_CLIST (clipboard->clist)->selection;
+ if (selection == NULL)
+ return NULL;
+
+ return (GladeClipboardItem*) gtk_clist_get_row_data (GTK_CLIST (clipboard->clist), GPOINTER_TO_INT (selection->data));
+}
+
+
+static void
+glade_clipboard_on_project_destroy (GladeProject *project,
+ GladeClipboardItem *item)
+{
+ if (item)
+ item->project = NULL;
+}
diff --git a/tools/glade/glade/glade_clipboard.h b/tools/glade/glade/glade_clipboard.h
new file mode 100644
index 00000000..7d1b626c
--- /dev/null
+++ b/tools/glade/glade/glade_clipboard.h
@@ -0,0 +1,77 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_CLIPBOARD_H
+#define GLADE_CLIPBOARD_H
+
+#include <gtk/gtkwindow.h>
+
+#include "glade_project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * GladeClipboard is a subclass of GtkWindow, which shows all of the widgets
+ * in the cut buffers, allowing the user to select which widget to paste.
+ */
+
+
+#define GLADE_CLIPBOARD(obj) GTK_CHECK_CAST (obj, glade_clipboard_get_type (), GladeClipboard)
+#define GLADE_CLIPBOARD_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_clipboard_get_type (), GladeClipboardClass)
+#define GLADE_IS_CLIPBOARD(obj) GTK_CHECK_TYPE (obj, glade_clipboard_get_type ())
+
+typedef struct _GladeClipboard GladeClipboard;
+typedef struct _GladeClipboardClass GladeClipboardClass;
+
+struct _GladeClipboard
+{
+ GtkWindow window;
+
+ /* The list of widgets in the cut buffers. */
+ GtkWidget *clist;
+
+};
+
+struct _GladeClipboardClass
+{
+ GtkWindowClass parent_class;
+};
+
+
+GType glade_clipboard_get_type (void);
+GtkWidget* glade_clipboard_new (void);
+
+/* These cut/copy/paste widgets in the given project. If NULL is passed as
+ the widget parameter, the currently selected widget will be used. */
+void glade_clipboard_cut (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget);
+void glade_clipboard_copy (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget);
+void glade_clipboard_paste (GladeClipboard *clipboard,
+ GladeProject *project,
+ GtkWidget *widget);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_CLIPBOARD_H */
diff --git a/tools/glade/glade/glade_gnome.c b/tools/glade/glade/glade_gnome.c
new file mode 100644
index 00000000..36665ea2
--- /dev/null
+++ b/tools/glade/glade/glade_gnome.c
@@ -0,0 +1,1032 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file contains general Gnome-related declarations & code.
+ */
+
+#include <config.h>
+
+#ifdef USE_GNOME
+
+#include <gnome.h>
+
+#include "glade_gnome.h"
+#include "glade_project.h"
+#include "source.h"
+#include "utils.h"
+
+
+static void glade_gnome_write_menu_item_standard_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data);
+static void glade_gnome_write_radio_menu_item_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data,
+ GString *source_buffer,
+ gchar *label,
+ gchar *tooltip,
+ gchar *handler,
+ gchar *accel_key_buffer,
+ gchar *accel_mods);
+static void glade_gnome_finish_radio_menu_item_group_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData *data);
+static gboolean glade_gnome_is_first_radio_menu_item_in_group (GtkMenuItem *menuitem);
+
+
+
+/*
+ * I intend to tidy up all the code for choice properties at some point,
+ * so we don't duplicate them and we use simple convenience functions for them.
+ */
+
+/* Choices for the BonoboDockItem placement. */
+const gint GladePlacementValues[] =
+{
+ BONOBO_DOCK_TOP,
+ BONOBO_DOCK_RIGHT,
+ BONOBO_DOCK_BOTTOM,
+ BONOBO_DOCK_LEFT,
+ BONOBO_DOCK_FLOATING
+};
+const gint GladePlacementSize = sizeof (GladePlacementValues) / sizeof (gint);
+const gchar *GladePlacementSymbols[] =
+{
+ "BONOBO_DOCK_TOP",
+ "BONOBO_DOCK_RIGHT",
+ "BONOBO_DOCK_BOTTOM",
+ "BONOBO_DOCK_LEFT",
+ "BONOBO_DOCK_FLOATING"
+};
+
+
+/* Choices for the BonoboDockItem Orientation. */
+const gchar *GladeOrientationChoices[] =
+{
+ "Horizontal",
+ "Vertical",
+ NULL
+};
+const gint GladeOrientationValues[] =
+{
+ GTK_ORIENTATION_HORIZONTAL,
+ GTK_ORIENTATION_VERTICAL
+};
+const gint GladeOrientationSize = sizeof (GladeOrientationValues) / sizeof (GladeOrientationValues[0]);
+const gchar *GladeOrientationSymbols[] =
+{
+ "GTK_ORIENTATION_HORIZONTAL",
+ "GTK_ORIENTATION_VERTICAL"
+};
+
+
+/*************************************************************************
+ * Stock Gnome Menu Items.
+ *************************************************************************/
+
+/* These are indices of a few special items, so if you change the
+ GladeStockMenuItemValues array be sure to update this. */
+const gint GladeStockMenuItemNew = 3;
+const gint GladeStockMenuHelpTree = 37;
+
+/* These are copied from gnome-libs/libgnomeui/gnome-app-helper.h
+ The first item is 'None' to indicate no stock item is being used. */
+GnomeUIInfo GladeStockMenuItemValues[] =
+{
+ /* 0 */
+ {
+ GNOME_APP_UI_ITEM, N_("None"), NULL, NULL, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL
+ },
+ /* 1 */
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 2 */
+ GNOMEUIINFO_MENU_FILE_TREE (NULL),
+ /* 3 - see GladeStockMenuItemNew above. */
+ GNOMEUIINFO_MENU_NEW_ITEM (N_("_New"), NULL, NULL, NULL),
+ GNOMEUIINFO_MENU_OPEN_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_AS_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REVERT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PRINT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PRINT_SETUP_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLOSE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_QUIT_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 13 */
+ GNOMEUIINFO_MENU_EDIT_TREE (NULL),
+ GNOMEUIINFO_MENU_CUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_COPY_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PASTE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SELECT_ALL_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLEAR_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_UNDO_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REDO_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_FIND_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_FIND_AGAIN_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REPLACE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PROPERTIES_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 26 */
+ GNOMEUIINFO_MENU_VIEW_TREE (NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 28 */
+ GNOMEUIINFO_MENU_SETTINGS_TREE (NULL),
+ GNOMEUIINFO_MENU_PREFERENCES_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 31 */
+ GNOMEUIINFO_MENU_FILES_TREE (NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 33 */
+ GNOMEUIINFO_MENU_WINDOWS_TREE (NULL),
+ GNOMEUIINFO_MENU_NEW_WINDOW_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 37 */
+ GNOMEUIINFO_MENU_HELP_TREE (NULL),
+ GNOMEUIINFO_MENU_ABOUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 40 */
+ GNOMEUIINFO_MENU_GAME_TREE (NULL),
+ GNOMEUIINFO_MENU_NEW_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PAUSE_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_RESTART_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_UNDO_MOVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REDO_MOVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_HINT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SCORES_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_END_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+
+/* These were created by a perl script using the above. */
+const gchar* GladeStockMenuItemSymbols[] =
+{
+ NULL,
+ NULL,
+ "GNOMEUIINFO_MENU_FILE_TREE",
+ "GNOMEUIINFO_MENU_NEW_ITEM",
+ "GNOMEUIINFO_MENU_OPEN_ITEM",
+ "GNOMEUIINFO_MENU_SAVE_ITEM",
+ "GNOMEUIINFO_MENU_SAVE_AS_ITEM",
+ "GNOMEUIINFO_MENU_REVERT_ITEM",
+ "GNOMEUIINFO_MENU_PRINT_ITEM",
+ "GNOMEUIINFO_MENU_PRINT_SETUP_ITEM",
+ "GNOMEUIINFO_MENU_CLOSE_ITEM",
+ "GNOMEUIINFO_MENU_EXIT_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_EDIT_TREE",
+ "GNOMEUIINFO_MENU_CUT_ITEM",
+ "GNOMEUIINFO_MENU_COPY_ITEM",
+ "GNOMEUIINFO_MENU_PASTE_ITEM",
+ "GNOMEUIINFO_MENU_SELECT_ALL_ITEM",
+ "GNOMEUIINFO_MENU_CLEAR_ITEM",
+ "GNOMEUIINFO_MENU_UNDO_ITEM",
+ "GNOMEUIINFO_MENU_REDO_ITEM",
+ "GNOMEUIINFO_MENU_FIND_ITEM",
+ "GNOMEUIINFO_MENU_FIND_AGAIN_ITEM",
+ "GNOMEUIINFO_MENU_REPLACE_ITEM",
+ "GNOMEUIINFO_MENU_PROPERTIES_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_VIEW_TREE",
+ NULL,
+ "GNOMEUIINFO_MENU_SETTINGS_TREE",
+ "GNOMEUIINFO_MENU_PREFERENCES_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_FILES_TREE",
+ NULL,
+ "GNOMEUIINFO_MENU_WINDOWS_TREE",
+ "GNOMEUIINFO_MENU_NEW_WINDOW_ITEM",
+ "GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_HELP_TREE",
+ "GNOMEUIINFO_MENU_ABOUT_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_GAME_TREE",
+ "GNOMEUIINFO_MENU_NEW_GAME_ITEM",
+ "GNOMEUIINFO_MENU_PAUSE_GAME_ITEM",
+ "GNOMEUIINFO_MENU_RESTART_GAME_ITEM",
+ "GNOMEUIINFO_MENU_UNDO_MOVE_ITEM",
+ "GNOMEUIINFO_MENU_REDO_MOVE_ITEM",
+ "GNOMEUIINFO_MENU_HINT_ITEM",
+ "GNOMEUIINFO_MENU_SCORES_ITEM",
+ "GNOMEUIINFO_MENU_END_GAME_ITEM",
+ NULL
+};
+
+const gint GladeStockMenuItemSize = sizeof (GladeStockMenuItemSymbols) / sizeof (GladeStockMenuItemSymbols[0]);
+
+
+/*************************************************************************
+ * Functions to output GnomeUIInfo structs in the source code.
+ *************************************************************************/
+
+/* This creates the start of the GnomeUIInfo structs, and is called by the
+ write_source functions of menus and menubars if we are building a Gnome
+ application. The menuitems call glade_gnome_write_menu_item_source() to
+ add to this, and the entire structure is added to one of the main source
+ buffers at the end of gb_widget_write_source (), by calling
+ glade_gnome_finish_menu_source(). */
+void
+glade_gnome_start_menu_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData * data)
+{
+ GString *source_buffer;
+ GtkWidget *parent_item;
+ gint uiinfo_index = 0, stock_item_index;
+
+ source_buffer = g_string_sized_new (1024);
+ g_string_sprintf (source_buffer, "static GnomeUIInfo %s_uiinfo[] =\n{\n",
+ data->real_wname);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo", source_buffer);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo-name",
+ g_strdup (data->real_wname));
+
+ /* See if this is the start of the 'Help' menu, and if it is output the
+ GNOMEUIINFO_HELP item which inserts all the topics from topic.dat. */
+ if (glade_project_get_gnome_help_support (data->project)
+ && GTK_IS_MENU (menu_shell))
+ {
+ parent_item = gtk_menu_get_attach_widget (GTK_MENU (menu_shell));
+
+ if (parent_item)
+ {
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent_item), GladeMenuItemStockIndexKey));
+ if (stock_item_index == GladeStockMenuHelpTree)
+ {
+ g_string_sprintfa (source_buffer, " GNOMEUIINFO_HELP (%s),\n",
+ source_make_string (data->program_name,
+ FALSE));
+ uiinfo_index++;
+ }
+ }
+ }
+
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo-index",
+ GINT_TO_POINTER (uiinfo_index));
+}
+
+
+/* This is called after a menu or menubar has been output. It finishes off
+ the GnomeUIInfo struct and adds it to the GLADE_UIINFO source buffer. */
+void
+glade_gnome_finish_menu_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData * data)
+{
+ GString *source_buffer;
+ gchar *uiinfo_name;
+
+ /* Finish off any radio group. */
+ glade_gnome_finish_radio_menu_item_group_source (menu_shell, data);
+
+ source_buffer = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-uiinfo");
+ g_return_if_fail (source_buffer != NULL);
+
+ uiinfo_name = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-uiinfo-name");
+ g_return_if_fail (uiinfo_name != NULL);
+
+ g_string_append (source_buffer, " GNOMEUIINFO_END\n};\n\n");
+ g_string_append (data->source_buffers[GLADE_UIINFO], source_buffer->str);
+ g_string_free (source_buffer, TRUE);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo", NULL);
+
+ g_free (uiinfo_name);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo-name", NULL);
+}
+
+
+/* This is called by the write_source functions of all menu items when
+ outputting Gnome source code. It adds to the GnomeUIInfo structs stored
+ in the parent menu/menubar. */
+void
+glade_gnome_write_menu_item_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GString *source_buffer;
+ gint stock_item_index;
+ gboolean has_child_menu = FALSE;
+ GList *tmp_list;
+ GladeSignal *activate_signal = NULL;
+ GladeAccelerator *activate_accel = NULL;
+ gchar *handler = NULL, *child_uiinfo_name = NULL;
+
+ source_buffer = gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent), "glade-uiinfo");
+ g_return_if_fail (source_buffer != NULL);
+
+ /* First check if it is a separator, since they are simple. */
+ if (GTK_IS_SEPARATOR_MENU_ITEM (widget) || GTK_BIN (widget)->child == NULL)
+ {
+ g_string_append (source_buffer, " GNOMEUIINFO_SEPARATOR,\n");
+ glade_gnome_write_menu_item_standard_source (widget, data);
+ return;
+ }
+
+ if (widget->submenu)
+ {
+ const char *child_menu_name = gtk_widget_get_name (widget->submenu);
+
+ has_child_menu = TRUE;
+ child_uiinfo_name = source_create_valid_identifier (child_menu_name);
+ }
+
+
+ /* Find 'activate' handler in widget data. */
+ tmp_list = data->widget_data->signals;
+ while (tmp_list)
+ {
+ GladeSignal *signal = (GladeSignal *) tmp_list->data;
+ if (!strcmp (signal->name, "activate"))
+ {
+ activate_signal = signal;
+ handler = source_create_valid_identifier (signal->handler);
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+ /* Find 'activate' accelerator in widget data. */
+ tmp_list = data->widget_data->accelerators;
+ while (tmp_list)
+ {
+ GladeAccelerator *accel = (GladeAccelerator *) tmp_list->data;
+ if (!strcmp (accel->signal, "activate"))
+ {
+ activate_accel = accel;
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+ /* See if it is a stock item. */
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ GladeMenuItemStockIndexKey));
+ if (stock_item_index > 0)
+ {
+ GnomeUIInfo *uiinfo;
+
+ uiinfo = &GladeStockMenuItemValues[stock_item_index];
+
+ /* Special code for the New item. If it has children it is
+ GNOMEUIINFO_MENU_NEW_SUBTREE, else it is GNOMEUIINFO_MENU_NEW_ITEM
+ and we must also output the label and tooltip. */
+ if (stock_item_index == GladeStockMenuItemNew)
+ {
+ if (has_child_menu)
+ {
+ g_string_sprintfa (source_buffer,
+ " GNOMEUIINFO_MENU_NEW_SUBTREE (%s_uiinfo),\n",
+ child_uiinfo_name);
+ }
+ else
+ {
+ gchar *label, *tooltip;
+
+ label = glade_util_get_label_text (GTK_BIN (widget)->child);
+ tooltip = data->widget_data->tooltip ? g_strdup (source_make_static_string (data->widget_data->tooltip, data->use_gettext)) : NULL;
+
+ g_string_sprintfa (source_buffer,
+ " GNOMEUIINFO_MENU_NEW_ITEM (%s, %s, %s, NULL),\n",
+ source_make_static_string (label, data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ handler ? handler : "NULL");
+ g_free (tooltip);
+ g_free (label);
+ }
+ }
+ /* See if it is a subtree item. */
+ else if (uiinfo->type == GNOME_APP_UI_SUBTREE_STOCK)
+ {
+ if (has_child_menu)
+ {
+ g_string_sprintfa (source_buffer, " %s (%s_uiinfo),\n",
+ GladeStockMenuItemSymbols[stock_item_index],
+ child_uiinfo_name);
+ }
+ else
+ {
+ /* The stock subtree item should really have children, but if it
+ doesn't, we just output an empty GnomeUIInfo struct here. */
+ g_string_sprintfa (source_buffer, " %s (%s_uiinfo),\n",
+ GladeStockMenuItemSymbols[stock_item_index],
+ data->real_wname);
+ g_string_sprintfa (data->source_buffers[GLADE_UIINFO],
+ "static GnomeUIInfo %s_uiinfo[] =\n{\n"
+ " GNOMEUIINFO_END\n};\n\n",
+ data->real_wname);
+ }
+ }
+ /* It must be a normal stock item. */
+ else
+ {
+ g_string_sprintfa (source_buffer, " %s (%s, NULL),\n",
+ GladeStockMenuItemSymbols[stock_item_index],
+ handler ? handler : "NULL");
+ }
+ }
+ else
+ /* It is an ordinary menu item, so we need to output its type, label,
+ tooltip, accelerator, and icon (stock or ordinary), and also check
+ if it has a child menu. */
+ {
+ gchar *type, *label, *tooltip, *icon_name = NULL, *accel_mods;
+ gchar *pixmap_type, *pixmap_info, *pixmap_filename;
+ gchar accel_key_buffer[128];
+ gboolean free_pixmap_info;
+
+ label = glade_util_get_label_text (GTK_BIN (widget)->child);
+ tooltip = data->widget_data->tooltip ? g_strdup (source_make_static_string (data->widget_data->tooltip, data->use_gettext)) : NULL;
+
+ /* Determine if the item has an icon and if it is a stock icon or an
+ xpm file. */
+ free_pixmap_info = FALSE;
+ if (GTK_IS_IMAGE_MENU_ITEM (widget))
+ {
+ GtkWidget *image;
+ image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (widget));
+ if (image)
+ icon_name = gtk_object_get_data (GTK_OBJECT (image), GladeIconKey);
+ }
+ if (icon_name && icon_name[0])
+ {
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ pixmap_type = "GNOME_APP_PIXMAP_STOCK";
+ pixmap_info = g_strdup (source_make_string (icon_name, FALSE));
+ free_pixmap_info = TRUE;
+ }
+ else
+ {
+ pixmap_type = "GNOME_APP_PIXMAP_FILENAME";
+ pixmap_filename = g_strdup_printf ("%s%c%s", data->program_name,
+ G_DIR_SEPARATOR,
+ g_basename (icon_name));
+ pixmap_info = g_strdup (source_make_string (pixmap_filename,
+ FALSE));
+ g_free (pixmap_filename);
+ free_pixmap_info = TRUE;
+ }
+ }
+ else
+ {
+ pixmap_type = "GNOME_APP_PIXMAP_NONE";
+ pixmap_info = "NULL";
+ }
+
+ strcpy (accel_key_buffer, "0");
+ accel_mods = "0";
+ if (activate_accel)
+ {
+ /* Make sure we don't overflow the buffer. */
+ if (strlen (activate_accel->key) < 100)
+ {
+ strcpy (accel_key_buffer, "GDK_");
+ strcat (accel_key_buffer, activate_accel->key);
+ }
+ else
+ g_warning ("Overflow of accel_key_buffer");
+
+ accel_mods = glade_util_create_modifiers_string (activate_accel->modifiers);
+ }
+
+ if (has_child_menu)
+ {
+ type = "GNOME_APP_UI_SUBTREE";
+ g_string_sprintfa (source_buffer,
+ " {\n"
+ " %s, %s,\n"
+ " %s,\n"
+ " %s_uiinfo, NULL, NULL,\n"
+ " %s, %s,\n"
+ " %s, (GdkModifierType) %s, NULL\n"
+ " },\n",
+ type,
+ source_make_static_string (label,
+ data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ child_uiinfo_name,
+ pixmap_type, pixmap_info,
+ accel_key_buffer, accel_mods);
+
+ }
+ else
+ {
+ if (GTK_IS_RADIO_MENU_ITEM (widget))
+ {
+ glade_gnome_write_radio_menu_item_source (widget, data,
+ source_buffer, label,
+ tooltip, handler,
+ accel_key_buffer,
+ accel_mods);
+ }
+ else
+ {
+ if (GTK_IS_CHECK_MENU_ITEM (widget))
+ {
+ type = "GNOME_APP_UI_TOGGLEITEM";
+ pixmap_type = "GNOME_APP_PIXMAP_NONE";
+ if (free_pixmap_info)
+ g_free (pixmap_info);
+ pixmap_info = "NULL";
+ free_pixmap_info = FALSE;
+ }
+ else
+ type = "GNOME_APP_UI_ITEM";
+
+ g_string_sprintfa (source_buffer,
+ " {\n"
+ " %s, %s,\n"
+ " %s,\n"
+ " (gpointer) %s, NULL, NULL,\n"
+ " %s, %s,\n"
+ " %s, (GdkModifierType) %s, NULL\n"
+ " },\n",
+ type,
+ source_make_static_string (label,
+ data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ handler ? handler : "NULL",
+ pixmap_type, pixmap_info,
+ accel_key_buffer, accel_mods);
+ }
+ }
+
+ if (free_pixmap_info)
+ g_free (pixmap_info);
+ g_free (tooltip);
+ g_free (label);
+ }
+
+ glade_gnome_write_menu_item_standard_source (widget, data);
+
+
+ /* If there is an "activate" signal handler, we may need to output the empty
+ handler function and declaration, depending on its last modification
+ time. */
+ if (activate_signal)
+ {
+ /* Check if we need to output it. */
+ if (data->creating_callback_files
+ || (activate_signal->last_modification_time > data->last_write_time))
+ {
+ gb_widget_write_signal_handler_source (GTK_WIDGET (widget), data,
+ "activate", handler);
+ }
+ }
+
+ g_free (handler);
+ g_free (child_uiinfo_name);
+}
+
+
+/* This outputs code to save the pointer to the widget and possibly set its
+ name, using the index into the GnomeUIInfo struct. */
+static void
+glade_gnome_write_menu_item_standard_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gchar *uiinfo_name, *uiinfo_name_key, *uiinfo_index_key;
+ gint uiinfo_index;
+
+ if (GTK_IS_RADIO_MENU_ITEM (widget))
+ {
+ uiinfo_name_key = "glade-radio-group-uiinfo-name";
+ uiinfo_index_key = "glade-radio-group-uiinfo-index";
+ }
+ else
+ {
+ uiinfo_name_key = "glade-uiinfo-name";
+ uiinfo_index_key = "glade-uiinfo-index";
+ }
+
+ uiinfo_name = gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ uiinfo_name_key);
+ g_return_if_fail (uiinfo_name != NULL);
+
+ uiinfo_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent), uiinfo_index_key));
+
+ if (data->set_widget_names)
+ source_add (data,
+ " gtk_widget_set_name (%s_uiinfo[%i].widget, \"%s\");\n",
+ uiinfo_name, uiinfo_index, data->real_wname);
+
+ if (!data->use_component_struct)
+ {
+ source_add_to_buffer (data, GLADE_OBJECT_HOOKUP,
+ " GLADE_HOOKUP_OBJECT (%s, %s_uiinfo[%i].widget, %s);\n",
+ data->component_name,
+ uiinfo_name, uiinfo_index,
+ source_make_string (data->real_wname, FALSE));
+ }
+
+ if (GTK_IS_CHECK_MENU_ITEM (widget) && wdata->flags & GLADE_ACTIVE)
+ source_add (data,
+ " gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (%s_uiinfo[%i].widget), TRUE);\n",
+ uiinfo_name, uiinfo_index);
+
+ if (!(wdata->flags & GLADE_SENSITIVE))
+ source_add (data,
+ " gtk_widget_set_sensitive (%s_uiinfo[%i].widget, FALSE);\n",
+ uiinfo_name, uiinfo_index);
+
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ uiinfo_index_key, GINT_TO_POINTER (uiinfo_index + 1));
+}
+
+
+/* This outputs the source for a radio menu item. The group of radio items
+ is placed in a separate GnomeUIInfo struct, and a pointer to that is added
+ in the menus GnomeUIInfo.
+ First we check if the radio item is the start of a new group.
+ If it is, we finish off any previous group and start a new one. */
+static void
+glade_gnome_write_radio_menu_item_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data,
+ GString *source_buffer,
+ gchar *label,
+ gchar *tooltip,
+ gchar *handler,
+ gchar *accel_key_buffer,
+ gchar *accel_mods)
+{
+ GString *group_source_buffer;
+ gint uiinfo_index;
+
+ if (glade_gnome_is_first_radio_menu_item_in_group (widget))
+ {
+ /* Finish off any existing group. */
+ glade_gnome_finish_radio_menu_item_group_source (GTK_MENU_SHELL (GTK_WIDGET (widget)->parent), data);
+
+ /* Start the new group. */
+ group_source_buffer = g_string_sized_new (1024);
+ g_string_sprintf (group_source_buffer,
+ "static GnomeUIInfo %s_uiinfo[] =\n{\n",
+ data->real_wname);
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo", group_source_buffer);
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo-name",
+ g_strdup (data->real_wname));
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo-index",
+ GINT_TO_POINTER (0));
+
+ /* Insert the radio group into the menu's GnomeUIInfo struct. */
+ g_string_sprintfa (source_buffer,
+ " {\n"
+ " GNOME_APP_UI_RADIOITEMS, NULL, NULL, %s_uiinfo,\n"
+ " NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0,\n"
+ " (GdkModifierType) 0, NULL\n"
+ " },\n",
+ data->real_wname);
+
+ /* We need to increment the index of the parent uiinfo, so that the
+ GNOME_APP_UI_RADIOITEMS element is skipped. */
+ uiinfo_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent), "glade-uiinfo-index"));
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-uiinfo-index",
+ GINT_TO_POINTER (uiinfo_index + 1));
+ }
+ else
+ {
+ group_source_buffer = gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo");
+ g_return_if_fail (group_source_buffer != NULL);
+ }
+
+ g_string_sprintfa (group_source_buffer,
+ " {\n"
+ " GNOME_APP_UI_ITEM, %s,\n"
+ " %s,\n"
+ " (gpointer) %s, NULL, NULL,\n"
+ " GNOME_APP_PIXMAP_NONE, NULL,\n"
+ " %s, (GdkModifierType) %s, NULL\n"
+ " },\n",
+ source_make_static_string (label,
+ data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ handler ? handler : "NULL",
+ accel_key_buffer, accel_mods);
+}
+
+
+/* This checks if the menu has any unfinished radio group GnomeUIInfo struct
+ attached. If it does it is added to the final source buffer and freed. */
+static void
+glade_gnome_finish_radio_menu_item_group_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData *data)
+{
+ GString *group_source_buffer;
+ gchar *group_uiinfo_name;
+
+ group_source_buffer = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-radio-group-uiinfo");
+ if (!group_source_buffer)
+ return;
+
+ group_uiinfo_name = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-radio-group-uiinfo-name");
+ g_return_if_fail (group_uiinfo_name != NULL);
+
+ /* Finish the struct and add it onto the final source buffer. */
+ g_string_append (group_source_buffer, " GNOMEUIINFO_END\n};\n\n");
+ g_string_append (data->source_buffers[GLADE_UIINFO],
+ group_source_buffer->str);
+
+ /* Now free it and reset the pointer. */
+ g_string_free (group_source_buffer, TRUE);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-radio-group-uiinfo",
+ NULL);
+
+ g_free (group_uiinfo_name);
+ gtk_object_set_data (GTK_OBJECT (menu_shell),
+ "glade-radio-group-uiinfo-name", NULL);
+}
+
+
+/* This returns TRUE if the given radio menu item is the first item in a
+ radio group. FIXME: radio items must be next to each other in GNOME menus,
+ but we don't enforce that in the menu editor. */
+static gboolean
+glade_gnome_is_first_radio_menu_item_in_group (GtkMenuItem *menuitem)
+{
+ GList *children, *elem;
+ GtkWidget *prev_item;
+ GSList *group, *prev_group;
+
+ children = GTK_MENU_SHELL (GTK_WIDGET (menuitem)->parent)->children;
+
+ elem = g_list_find (children, menuitem);
+ g_return_val_if_fail (elem != NULL, FALSE);
+
+ /* If the item is the first item, it must start a new group. */
+ if (elem == children)
+ return TRUE;
+
+ /* If the previous item is not a radio item, it must be in a new group. */
+ prev_item = GTK_WIDGET (elem->prev->data);
+ if (!GTK_IS_RADIO_MENU_ITEM (prev_item))
+ return TRUE;
+
+ /* If the item's group isn't the same as the previous item's, it must start
+ a new group. */
+ group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
+ prev_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (prev_item));
+
+ if (group != prev_group)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/*************************************************************************
+ * Utility Functions.
+ *************************************************************************/
+
+/* If the given widget is a dock item inside a GnomeApp it returns the
+ GnomeApp, otherwise it returns NULL. */
+GnomeApp*
+glade_gnome_is_app_dock_item (GtkWidget *widget)
+{
+ GtkWidget *dock, *app;
+
+ if (!BONOBO_IS_DOCK_ITEM (widget))
+ return NULL;
+
+ if (!widget->parent)
+ return NULL;
+
+ /* Floating items are direct children of a BonoboDock.
+ Other items are children of a BonoboDockBand. */
+ if (BONOBO_IS_DOCK (widget->parent))
+ {
+ dock = widget->parent;
+ }
+ else
+ {
+ if (!BONOBO_IS_DOCK_BAND (widget->parent))
+ return NULL;
+ dock = widget->parent->parent;
+ if (!dock || !BONOBO_IS_DOCK (dock))
+ return NULL;
+ }
+
+ if (!dock->parent || !GTK_IS_VBOX (dock->parent))
+ return NULL;
+
+ app = dock->parent->parent;
+ if (!app || !GNOME_IS_APP (app))
+ return NULL;
+
+ return GNOME_APP (app);
+}
+
+
+/* Tries to translate the text in Glade's domain, and if there is no
+ translation try the gnome-libs domain. */
+gchar*
+glade_gnome_gettext (const gchar *text)
+{
+#ifdef ENABLE_NLS
+ char *s;
+
+ s = gettext (text);
+ if (s == text)
+ s = dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE, text);
+
+ return s;
+#else
+ return text;
+#endif
+}
+
+
+/* The indices come from GladeStockMenuItemValues in glade_gnome.c */
+static gint FileMenuIndices[] = { 3, 4, 5, 6, -1, 11 };
+static GnomeUIInfo FileMenu[] =
+{
+ GNOMEUIINFO_MENU_NEW_ITEM (N_("_New"), N_("Create a new file"),
+ NULL, NULL),
+ GNOMEUIINFO_MENU_OPEN_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_AS_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_QUIT_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+static gint EditMenuIndices[] = { 14, 15, 16, 18, -1, 24, -1, 29 };
+static GnomeUIInfo EditMenu[] =
+{
+ GNOMEUIINFO_MENU_CUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_COPY_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PASTE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLEAR_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_PROPERTIES_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_PREFERENCES_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+static gint ViewMenuIndices[] = { -1 };
+static GnomeUIInfo ViewMenu[] =
+{
+ GNOMEUIINFO_END
+};
+
+static gint HelpMenuIndices[] = { 38 };
+static GnomeUIInfo HelpMenu[] =
+{
+ GNOMEUIINFO_MENU_ABOUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+static gint MainMenuIndices[] = { 2, 13, 26, 37 };
+static GnomeUIInfo MainMenu[] =
+{
+ GNOMEUIINFO_MENU_FILE_TREE (FileMenu),
+ GNOMEUIINFO_MENU_EDIT_TREE (EditMenu),
+ GNOMEUIINFO_MENU_VIEW_TREE (ViewMenu),
+ GNOMEUIINFO_MENU_HELP_TREE (HelpMenu),
+ GNOMEUIINFO_END
+};
+
+
+static void
+glade_gnome_setup_menu_items (GnomeUIInfo *uiinfo, gint *indices)
+{
+ gint i = 0;
+ gchar *name, *dest;
+ const gchar *src;
+
+ while (uiinfo->type != GNOME_APP_UI_ENDOFINFO)
+ {
+ if (uiinfo->widget)
+ {
+ if (indices[i] == -1)
+ {
+ gb_widget_create_from (uiinfo->widget, "separator");
+ }
+ else
+ {
+ name = g_malloc (strlen (uiinfo->label));
+ /* Convert spaces to underscores, and ignore periods (e.g. in
+ "Open...") and underscores (e.g. in "_Open"). */
+ for (src = uiinfo->label, dest = name; *src; src++)
+ {
+ if (*src == ' ')
+ *dest++ = '_';
+ else if (*src == '.')
+ continue;
+ else if (*src == '_')
+ continue;
+ else
+ *dest++ = *src;
+ }
+ *dest = '\0';
+
+ gb_widget_create_from (uiinfo->widget, name);
+
+ gtk_object_set_data (GTK_OBJECT (uiinfo->widget),
+ GladeMenuItemStockIndexKey,
+ GINT_TO_POINTER (indices[i]));
+
+ /* If the item has a child menu, turn it into a GbWidget.
+ If not, add a default handler to the item. */
+ if (GTK_IS_MENU_ITEM (uiinfo->widget)
+ && GTK_MENU_ITEM (uiinfo->widget)->submenu)
+ {
+ gchar *submenu_name;
+
+ submenu_name = g_strdup_printf ("%s_menu",
+ uiinfo->widget->name);
+ gtk_widget_set_name (GTK_MENU_ITEM (uiinfo->widget)->submenu,
+ submenu_name);
+ g_free (submenu_name);
+ gb_widget_create_from (GTK_MENU_ITEM (uiinfo->widget)->submenu, NULL);
+ }
+ else
+ {
+ GladeWidgetData *wdata;
+ GladeSignal *signal;
+ gchar *start = "on_", *end = "_activate";
+
+ signal = g_new (GladeSignal, 1);
+ signal->name = g_strdup ("activate");
+ /* Generate a default handler name. */
+ signal->handler = g_malloc (strlen (uiinfo->widget->name) + 1
+ + strlen (start) + strlen (end));
+ strcpy (signal->handler, start);
+ strcat (signal->handler, uiinfo->widget->name);
+ strcat (signal->handler, end);
+
+ signal->object = NULL;
+ signal->after = FALSE;
+ signal->data = NULL;
+ signal->last_modification_time = time (NULL);
+
+ wdata = gtk_object_get_data (GTK_OBJECT (uiinfo->widget),
+ GB_WIDGET_DATA_KEY);
+ wdata->signals = g_list_append (wdata->signals, signal);
+ }
+ }
+ }
+ uiinfo++;
+ i++;
+ }
+}
+
+
+/* This sets up defaults menus for GtkMenuBar and GnomeApp widgets. */
+void
+glade_gnome_setup_initial_menus (GtkWidget *widget)
+{
+ /* We create a standard menubar and toolbar which the user can edit or
+ simply delete anything they don't want. */
+ if (GNOME_IS_APP (widget))
+ gnome_app_create_menus (GNOME_APP (widget), MainMenu);
+ else if (GTK_IS_MENU_BAR (widget))
+ gnome_app_fill_menu (GTK_MENU_SHELL (widget), MainMenu, NULL, TRUE, 0);
+ else
+ g_assert_not_reached ();
+
+ /* Turn all the menus & menuitems into GbWidgets and add default
+ handlers. */
+ glade_gnome_setup_menu_items (FileMenu, FileMenuIndices);
+ glade_gnome_setup_menu_items (EditMenu, EditMenuIndices);
+ glade_gnome_setup_menu_items (ViewMenu, ViewMenuIndices);
+ glade_gnome_setup_menu_items (HelpMenu, HelpMenuIndices);
+ glade_gnome_setup_menu_items (MainMenu, MainMenuIndices);
+}
+
+
+
+
+#endif /* USE_GNOME */
diff --git a/tools/glade/glade/glade_gnome.h b/tools/glade/glade/glade_gnome.h
new file mode 100644
index 00000000..a818b2b2
--- /dev/null
+++ b/tools/glade/glade/glade_gnome.h
@@ -0,0 +1,111 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef GLADE_GNOME_H
+#define GLADE_GNOME_H
+
+/*
+ * This file contains general Gnome-related declarations & code.
+ */
+
+#ifdef USE_GNOME
+
+#include <gnome.h>
+
+#include "gbwidget.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* The domain used for libgnomeui, used when we need to get translated strings
+ from there. */
+#define GLADE_LIBGNOMEUI_GETTEXT_PACKAGE "libgnomeui-2.0"
+
+/*************************************************************************
+ * Common choice properties.
+ *************************************************************************/
+
+/* Choices for the GnomeDockItem placement. */
+extern const gint GladePlacementValues[];
+extern const gint GladePlacementSize;
+extern const gchar *GladePlacementSymbols[];
+
+/* Choices for the GnomeDockItem placement. */
+extern const gint GladeOrientationValues[];
+extern const gint GladeOrientationSize;
+extern const gchar *GladeOrientationChoices[];
+extern const gchar *GladeOrientationSymbols[];
+
+
+/*************************************************************************
+ * Stock Gnome Menu Items.
+ *************************************************************************/
+
+/* These are the stock menu items, and the symbols we use to denote them.
+ Note that Gnome doesn't have symbols to identify these so we have to make
+ our own up. */
+extern GnomeUIInfo GladeStockMenuItemValues[];
+extern const gchar *GladeStockMenuItemSymbols[];
+extern const gint GladeStockMenuItemSize;
+/* This is the index of the 'New' item, which is treated specially. If it
+ has children it is assumed to be GNOMEUIINFO_MENU_NEW_SUBTREE. If not,
+ it is assumed to be GNOMEUIINFO_MENU_NEW_ITEM, and the label can be set,
+ e.g. '_New Project'. */
+extern const gint GladeStockMenuItemNew;
+
+
+/*************************************************************************
+ * Common functions for outputting source code.
+ *************************************************************************/
+
+/* This outputs the GnomeUIInfo structs for menu items when building a Gnome
+ application. */
+void glade_gnome_start_menu_source (GtkMenuShell *widget,
+ GbWidgetWriteSourceData *data);
+void glade_gnome_finish_menu_source (GtkMenuShell *widget,
+ GbWidgetWriteSourceData *data);
+void glade_gnome_write_menu_item_source (GtkMenuItem *widget,
+ GbWidgetWriteSourceData *data);
+
+
+/*************************************************************************
+ * Utility functions.
+ *************************************************************************/
+
+/* Returns the GnomeApp if the widget is a dock item within a GnomeApp. */
+GnomeApp* glade_gnome_is_app_dock_item (GtkWidget *widget);
+
+/* This sets up defaults menus for GtkMenuBar and GnomeApp widgets. */
+void glade_gnome_setup_initial_menus (GtkWidget *widget);
+
+/* Tries to translate the text in the gnome-libs domain, and if there is no
+ translation try Glade's domain. */
+gchar* glade_gnome_gettext (const gchar *text);
+
+void gb_bonobo_dock_item_save_packing_properties (GtkWidget *parent,
+ GtkWidget *widget,
+ GbWidgetGetArgData * data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* USE_GNOME */
+
+#endif /* GLADE_GNOME_H */
diff --git a/tools/glade/glade/glade_gnomedblib.c b/tools/glade/glade/glade_gnomedblib.c
new file mode 100644
index 00000000..50936b28
--- /dev/null
+++ b/tools/glade/glade/glade_gnomedblib.c
@@ -0,0 +1,96 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ * Copyright (C) 2001 Carlos Perelló Marín <carlos@gnome-db.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME_DB
+
+#include "glade.h"
+#include "gbwidget.h"
+
+/* I've commented this out to avoid warnings. */
+/*gchar *libname = "GNOME 1.0";*/
+
+GbWidget *gb_gnome_db_combo_init ();
+GbWidget *gb_gnome_db_connection_properties_init();
+GbWidget *gb_gnome_db_data_source_selector_init ();
+GbWidget *gb_gnome_db_dsn_config_druid_init ();
+GbWidget *gb_gnome_db_dsnconfig_init ();
+GbWidget *gb_gnome_db_editor_init();
+GbWidget *gb_gnome_db_error_init ();
+GbWidget *gb_gnome_db_errordlg_init ();
+GbWidget *gb_gnome_db_form_init ();
+GbWidget *gb_gnome_db_gray_bar_init();
+GbWidget *gb_gnome_db_grid_init ();
+GbWidget *gb_gnome_db_login_init ();
+GbWidget *gb_gnome_db_logindlg_init ();
+GbWidget *gb_gnome_db_provider_selector_init ();
+GbWidget *gb_gnome_db_table_editor_init ();
+
+static GladeWidgetInitData gnome_db[] = {
+ { "GnomeDbLoginDialog", gb_gnome_db_logindlg_init },
+ { "GnomeDbLogin", gb_gnome_db_login_init },
+ { "GnomeDbErrorDialog", gb_gnome_db_errordlg_init },
+ { "GnomeDbError", gb_gnome_db_error_init },
+
+ { "GnomeDbDsnConfig", gb_gnome_db_dsnconfig_init },
+ { "GnomeDbDsnConfigDruid", gb_gnome_db_dsn_config_druid_init },
+ { "GnomeDbProviderSelector", gb_gnome_db_provider_selector_init },
+
+ { "GnomeDbDataSourceSelector", gb_gnome_db_data_source_selector_init },
+ { "GnomeDbTableEditor", gb_gnome_db_table_editor_init },
+ { "GnomeDbForm", gb_gnome_db_form_init },
+
+ { "GnomeDbGrid", gb_gnome_db_grid_init },
+ { "GnomeDbCombo", gb_gnome_db_combo_init },
+ { "GnomeDbGrayBar", gb_gnome_db_gray_bar_init },
+
+ { "GnomeDbEditor", gb_gnome_db_editor_init },
+ { "GnomeDbConnectionProperties", gb_gnome_db_connection_properties_init },
+
+
+ /* These may be added back at some point. */
+ /*{ "GnomeDbIconList", gb_gnome_db_iconlist_init },*/
+
+ { NULL, NULL }
+};
+
+
+static GladeWidgetInitData notshown[] =
+{
+ { NULL, NULL }
+};
+
+
+static GladePaletteSectionData sections[] =
+{
+ /* Note that glade_palette_set_show_gnome_widgets() has some of these
+ strings hard-coded now, so keep up-to-date. */
+ { "Gnome _DB", gnome_db },
+ { "NotShown", notshown },
+ { NULL, NULL }
+};
+
+
+GladePaletteSectionData *get_gnome_db_widgets()
+{
+ return sections;
+}
+
+#endif
diff --git a/tools/glade/glade/glade_gnomedblib.h b/tools/glade/glade/glade_gnomedblib.h
new file mode 100644
index 00000000..1205f2df
--- /dev/null
+++ b/tools/glade/glade/glade_gnomedblib.h
@@ -0,0 +1,36 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef GLADE_GNOMEDBLIB_H
+#define GLADE_GNOMEDBLIB_H
+
+#include "glade.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GladePaletteSectionData* get_gnome_db_widgets(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* GLADE_GNOMEDBLIB_H */
diff --git a/tools/glade/glade/glade_gnomelib.c b/tools/glade/glade/glade_gnomelib.c
new file mode 100644
index 00000000..9854fb2c
--- /dev/null
+++ b/tools/glade/glade/glade_gnomelib.c
@@ -0,0 +1,127 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+
+#include "glade.h"
+#include "gbwidget.h"
+
+/* I've commented this out to avoid warnings. */
+/*gchar *libname = "GNOME 1.0";*/
+
+GbWidget *gb_gnome_about_init ();
+GbWidget *gb_gnome_app_init ();
+GbWidget *gb_gnome_appbar_init ();
+GbWidget *gb_gnome_canvas_init ();
+GbWidget *gb_gnome_color_picker_init ();
+GbWidget *gb_gnome_date_edit_init ();
+GbWidget *gb_gnome_dialog_init ();
+GbWidget *gb_bonobo_dock_init ();
+GbWidget *gb_bonobo_dock_band_init ();
+GbWidget *gb_bonobo_dock_item_init ();
+GbWidget *gb_gnome_druid_init ();
+GbWidget *gb_gnome_druid_page_edge_init ();
+GbWidget *gb_gnome_druid_page_standard_init ();
+GbWidget *gb_gnome_entry_init ();
+GbWidget *gb_gnome_file_entry_init ();
+GbWidget *gb_gnome_font_picker_init ();
+GbWidget *gb_gnome_href_init ();
+GbWidget *gb_gnome_icon_entry_init ();
+GbWidget *gb_gnome_icon_list_init ();
+GbWidget *gb_gnome_icon_selection_init ();
+GbWidget *gb_gnome_message_box_init ();
+#if 0
+GbWidget *gb_gnome_paper_selector_init ();
+#endif
+GbWidget *gb_gnome_pixmap_init ();
+GbWidget *gb_gnome_pixmap_entry_init ();
+GbWidget *gb_gnome_property_box_init ();
+GbWidget *gb_bonobo_control_init ();
+
+static GladeWidgetInitData gnome_page[] =
+{
+ { "GnomeApp", gb_gnome_app_init },
+ { "GnomeDruid", gb_gnome_druid_init },
+ { "GnomeCanvas", gb_gnome_canvas_init },
+ { "GnomeIconSelection", gb_gnome_icon_selection_init },
+
+ { "GnomeIconEntry", gb_gnome_icon_entry_init },
+ { "GnomeHRef", gb_gnome_href_init },
+ { "GnomeDateEdit", gb_gnome_date_edit_init },
+ { "GnomeAppBar", gb_gnome_appbar_init },
+
+
+#if 0
+ { "GnomePaperSelector", gb_gnome_paper_selector_init },
+#endif
+
+
+ { "BonoboWidget", gb_bonobo_control_init },
+
+ { NULL, NULL }
+};
+
+static GladeWidgetInitData gnome_deprecated[] =
+{
+ { "GnomePixmap", gb_gnome_pixmap_init },
+
+ { "GnomeDialog", gb_gnome_dialog_init },
+ { "GnomeMessageBox", gb_gnome_message_box_init },
+ { "GnomePropertyBox", gb_gnome_property_box_init },
+ { "GnomeAbout", gb_gnome_about_init },
+
+ { "GnomeIconList", gb_gnome_icon_list_init },
+ { "GnomeEntry", gb_gnome_entry_init },
+ { "GnomeFileEntry", gb_gnome_file_entry_init },
+ { "GnomePixmapEntry", gb_gnome_pixmap_entry_init },
+
+ { "GnomeColorPicker", gb_gnome_color_picker_init },
+ { "GnomeFontPicker", gb_gnome_font_picker_init },
+
+ { NULL, NULL }
+};
+
+static GladeWidgetInitData notshown[] =
+{
+ { "BonoboDock", gb_bonobo_dock_init },
+ { "BonoboDockItem", gb_bonobo_dock_item_init },
+ { "GnomeDruidPageEdge", gb_gnome_druid_page_edge_init },
+ { "GnomeDruidPageStandard", gb_gnome_druid_page_standard_init },
+
+ /* Unfinished. */
+ { NULL, NULL }
+};
+
+static GladePaletteSectionData sections[] =
+{
+ /* Note that glade_palette_set_show_gnome_widgets() has some of these
+ strings hard-coded now, so keep up-to-date. */
+ { N_("_Gnome"), gnome_page },
+ { N_("Dep_recated"), gnome_deprecated },
+ { "NotShown", notshown },
+ { NULL, NULL }
+};
+
+GladePaletteSectionData *get_gnome_widgets()
+{
+ return sections;
+}
+
+#endif
diff --git a/tools/glade/glade/glade_gnomelib.h b/tools/glade/glade/glade_gnomelib.h
new file mode 100644
index 00000000..8bf7094f
--- /dev/null
+++ b/tools/glade/glade/glade_gnomelib.h
@@ -0,0 +1,37 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef GLADE_GNOMELIB_H
+#define GLADE_GNOMELIB_H
+
+#include "glade.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GladePaletteSectionData* get_gnome_widgets (void);
+
+void gb_bonobo_control_init (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* GLADE_GNOMELIB_H */
diff --git a/tools/glade/glade/glade_gtk12lib.c b/tools/glade/glade/glade_gtk12lib.c
new file mode 100644
index 00000000..736f0629
--- /dev/null
+++ b/tools/glade/glade/glade_gtk12lib.c
@@ -0,0 +1,256 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include "glade.h"
+#include "gbwidget.h"
+
+/* I've commented this out to avoid warnings. */
+/*static gchar *libname = "GTK+ 1.2";*/
+
+GbWidget *gb_label_init ();
+GbWidget *gb_entry_init ();
+GbWidget *gb_button_init ();
+GbWidget *gb_toggle_button_init ();
+GbWidget *gb_check_button_init ();
+GbWidget *gb_radio_button_init ();
+GbWidget *gb_option_menu_init ();
+GbWidget *gb_combo_init ();
+GbWidget *gb_combo_box_init ();
+GbWidget *gb_combo_box_entry_init ();
+GbWidget *gb_list_init ();
+GbWidget *gb_clist_init ();
+GbWidget *gb_spin_button_init ();
+GbWidget *gb_hscale_init ();
+GbWidget *gb_vscale_init ();
+GbWidget *gb_hruler_init ();
+GbWidget *gb_vruler_init ();
+GbWidget *gb_hscrollbar_init ();
+GbWidget *gb_vscrollbar_init ();
+GbWidget *gb_menu_bar_init ();
+GbWidget *gb_statusbar_init ();
+GbWidget *gb_toolbar_init ();
+GbWidget *gb_progress_bar_init ();
+GbWidget *gb_arrow_init ();
+GbWidget *gb_image_init ();
+GbWidget *gb_drawing_area_init ();
+GbWidget *gb_hseparator_init ();
+GbWidget *gb_vseparator_init ();
+GbWidget *gb_hbox_init ();
+GbWidget *gb_vbox_init ();
+GbWidget *gb_table_init ();
+GbWidget *gb_fixed_init ();
+GbWidget *gb_hbutton_box_init ();
+GbWidget *gb_vbutton_box_init ();
+GbWidget *gb_frame_init ();
+GbWidget *gb_aspect_frame_init ();
+GbWidget *gb_hpaned_init ();
+GbWidget *gb_vpaned_init ();
+GbWidget *gb_handle_box_init ();
+GbWidget *gb_notebook_init ();
+GbWidget *gb_alignment_init ();
+GbWidget *gb_event_box_init ();
+GbWidget *gb_scrolled_window_init ();
+GbWidget *gb_viewport_init ();
+GbWidget *gb_expander_init ();
+GbWidget *gb_curve_init ();
+GbWidget *gb_gamma_curve_init ();
+GbWidget *gb_color_selection_init ();
+GbWidget *gb_preview_init ();
+GbWidget *gb_window_init ();
+GbWidget *gb_dialog_init ();
+GbWidget *gb_file_chooser_button_init ();
+GbWidget *gb_file_chooser_widget_init ();
+GbWidget *gb_file_chooser_dialog_init ();
+GbWidget *gb_file_selection_init ();
+GbWidget *gb_color_selection_dialog_init ();
+GbWidget *gb_input_dialog_init ();
+GbWidget *gb_list_item_init ();
+GbWidget *gb_menu_init ();
+GbWidget *gb_menu_item_init ();
+GbWidget *gb_check_menu_item_init ();
+GbWidget *gb_radio_menu_item_init ();
+GbWidget *gb_image_menu_item_init ();
+GbWidget *gb_separator_menu_item_init ();
+GbWidget *gb_ctree_init ();
+GbWidget *gb_accel_label_init ();
+GbWidget *gb_font_selection_init ();
+GbWidget *gb_font_selection_dialog_init ();
+GbWidget *gb_calendar_init();
+GbWidget *gb_custom_init();
+GbWidget *gb_layout_init();
+GbWidget *gb_text_view_init();
+GbWidget *gb_tree_view_init();
+GbWidget *gb_color_button_init();
+GbWidget *gb_font_button_init();
+GbWidget *gb_tool_item_init ();
+GbWidget *gb_tool_button_init ();
+GbWidget *gb_toggle_tool_button_init ();
+GbWidget *gb_radio_tool_button_init ();
+GbWidget *gb_separator_tool_item_init ();
+GbWidget *gb_about_dialog_init ();
+GbWidget *gb_icon_view_init ();
+GbWidget *gb_menu_tool_button_init ();
+GbWidget *gb_cell_view_init ();
+
+
+static GladeWidgetInitData gtk_standard[] =
+{
+ { "GtkWindow", gb_window_init },
+ { "GtkMenuBar", gb_menu_bar_init },
+ { "GtkToolbar", gb_toolbar_init },
+ { "GtkHandleBox", gb_handle_box_init },
+
+ { "GtkToolButton", gb_tool_button_init },
+ { "GtkToggleToolButton", gb_toggle_tool_button_init },
+ { "GtkRadioToolButton", gb_radio_tool_button_init },
+ { "GtkSeparatorToolItem", gb_separator_tool_item_init },
+
+ { "GtkLabel", gb_label_init },
+ { "GtkEntry", gb_entry_init },
+ { "GtkComboBoxEntry", gb_combo_box_entry_init },
+ { "GtkTextView", gb_text_view_init },
+
+ { "GtkButton", gb_button_init },
+ { "GtkToggleButton", gb_toggle_button_init },
+ { "GtkCheckButton", gb_check_button_init },
+ { "GtkRadioButton", gb_radio_button_init },
+
+ { "GtkComboBox", gb_combo_box_init },
+ { "GtkSpinButton", gb_spin_button_init },
+ { "GtkTreeView", gb_tree_view_init },
+ { "GtkIconView", gb_icon_view_init },
+
+ { "GtkHSeparator", gb_hseparator_init },
+ { "GtkVSeparator", gb_vseparator_init },
+ { "GtkImage", gb_image_init },
+ { "GtkDrawingArea", gb_drawing_area_init },
+
+ { "GtkDialog", gb_dialog_init },
+ { "GtkFileChooserDialog", gb_file_chooser_dialog_init },
+ { "GtkColorSelectionDialog", gb_color_selection_dialog_init },
+ { "GtkFontSelectionDialog", gb_font_selection_dialog_init },
+
+ { "GtkHBox", gb_hbox_init },
+ { "GtkVBox", gb_vbox_init },
+ { "GtkTable", gb_table_init },
+ { "GtkFixed", gb_fixed_init },
+
+ { "GtkHButtonBox", gb_hbutton_box_init },
+ { "GtkVButtonBox", gb_vbutton_box_init },
+ { "GtkHPaned", gb_hpaned_init },
+ { "GtkVPaned", gb_vpaned_init },
+
+ { "GtkNotebook", gb_notebook_init },
+ { "GtkFrame", gb_frame_init },
+ { "GtkScrolledWindow", gb_scrolled_window_init },
+ { "GtkStatusbar", gb_statusbar_init },
+
+
+ { NULL, NULL }
+};
+
+
+static GladeWidgetInitData gtk_advanced[] =
+{
+ { "GtkAboutDialog", gb_about_dialog_init },
+ { "GtkInputDialog", gb_input_dialog_init },
+ { "GtkMenuToolButton", gb_menu_tool_button_init },
+ { "GtkToolItem", gb_tool_item_init },
+
+ { "GtkHScale", gb_hscale_init },
+ { "GtkVScale", gb_vscale_init },
+ { "GtkHRuler", gb_hruler_init },
+ { "GtkVRuler", gb_vruler_init },
+
+ { "GtkAlignment", gb_alignment_init },
+ { "GtkEventBox", gb_event_box_init },
+ { "GtkCalendar", gb_calendar_init },
+ { "GtkProgressBar", gb_progress_bar_init },
+
+ { "GtkLayout", gb_layout_init },
+ { "GtkAspectFrame", gb_aspect_frame_init },
+ { "GtkArrow", gb_arrow_init },
+ { "GtkExpander", gb_expander_init },
+
+
+ { "GtkCurve", gb_curve_init },
+ { "GtkGammaCurve", gb_gamma_curve_init },
+ { "GtkHScrollbar", gb_hscrollbar_init },
+ { "GtkVScrollbar", gb_vscrollbar_init },
+
+ { "GtkFileChooserWidget", gb_file_chooser_widget_init },
+ { "GtkColorSelection", gb_color_selection_init },
+ { "GtkFontSelection", gb_font_selection_init },
+ { "GtkCellView", gb_cell_view_init },
+
+ { "GtkFileChooserButton", gb_file_chooser_button_init },
+ { "GtkColorButton", gb_color_button_init },
+ { "GtkFontButton", gb_font_button_init },
+ { "GtkMenu", gb_menu_init },
+
+ { "GtkViewport", gb_viewport_init },
+
+ { "Custom", gb_custom_init }, /* Our special custom widget. */
+
+ { NULL, NULL }
+};
+
+static GladeWidgetInitData gtk_deprecated[] =
+{
+ { "GtkCList", gb_clist_init },
+ { "GtkCTree", gb_ctree_init },
+ { "GtkList", gb_list_init },
+ { "GtkCombo", gb_combo_init },
+
+ { "GtkFileSelection", gb_file_selection_init },
+ { "GtkOptionMenu", gb_option_menu_init },
+ { "GtkPreview", gb_preview_init },
+
+ { NULL, NULL }
+};
+
+static GladeWidgetInitData notshown[] =
+{
+ { "GtkAccelLabel", gb_accel_label_init },
+ { "GtkListItem", gb_list_item_init },
+ { "GtkMenuItem", gb_menu_item_init },
+ { "GtkCheckMenuItem", gb_check_menu_item_init },
+ { "GtkRadioMenuItem", gb_radio_menu_item_init },
+ { "GtkImageMenuItem", gb_image_menu_item_init },
+ { "GtkSeparatorMenuItem", gb_separator_menu_item_init },
+
+ { NULL, NULL }
+};
+
+static GladePaletteSectionData sections[] =
+{
+ /* Note that glade_palette_set_show_gnome_widgets() has some of these
+ strings hard-coded now, so keep up-to-date. */
+ { N_("GTK+ _Basic"), gtk_standard },
+ { N_("GTK+ _Additional"), gtk_advanced },
+ { N_("Dep_recated"), gtk_deprecated },
+ { "NotShown", notshown },
+ { NULL, NULL }
+};
+
+GladePaletteSectionData *get_gtk_widgets()
+{
+ return sections;
+}
diff --git a/tools/glade/glade/glade_gtk12lib.h b/tools/glade/glade/glade_gtk12lib.h
new file mode 100644
index 00000000..98bd1b32
--- /dev/null
+++ b/tools/glade/glade/glade_gtk12lib.h
@@ -0,0 +1,34 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef GLADE_GTK12LIB_H
+#define GLADE_GTK12LIB_H
+
+#include "glade.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+GladePaletteSectionData* get_gtk_widgets(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* GLADE_GTK12LIB_H */
diff --git a/tools/glade/glade/glade_keys_dialog.c b/tools/glade/glade/glade_keys_dialog.c
new file mode 100644
index 00000000..cdede5f2
--- /dev/null
+++ b/tools/glade/glade/glade_keys_dialog.c
@@ -0,0 +1,254 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * The Accelerator Keys dialog for selecting an accelerator key.
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkclist.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkscrolledwindow.h>
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#endif
+
+#include "keys.h"
+#include "glade_keys_dialog.h"
+#include "gbwidget.h"
+
+static void glade_keys_dialog_class_init (GladeKeysDialogClass *klass);
+static void glade_keys_dialog_init (GladeKeysDialog *dialog);
+
+static GtkDialogClass *parent_class = NULL;
+
+
+GType
+glade_keys_dialog_get_type (void)
+{
+ static GType glade_keys_dialog_type = 0;
+
+ if (!glade_keys_dialog_type)
+ {
+ GtkTypeInfo glade_keys_dialog_info =
+ {
+ "GladeKeysDialog",
+ sizeof (GladeKeysDialog),
+ sizeof (GladeKeysDialogClass),
+ (GtkClassInitFunc) glade_keys_dialog_class_init,
+ (GtkObjectInitFunc) glade_keys_dialog_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ glade_keys_dialog_type = gtk_type_unique (gtk_dialog_get_type (),
+ &glade_keys_dialog_info);
+ }
+
+ return glade_keys_dialog_type;
+}
+
+static void
+glade_keys_dialog_class_init (GladeKeysDialogClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = (GtkObjectClass*) klass;
+ widget_class = (GtkWidgetClass*) klass;
+
+ parent_class = gtk_type_class (gtk_dialog_get_type ());
+}
+
+
+static void
+glade_keys_dialog_init (GladeKeysDialog *dialog)
+{
+ GtkWidget *scrolled_win;
+ int i, row;
+ gchar *titles[1];
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Select Accelerator Key"));
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "accelerator_key", "Glade");
+
+ titles[0] = _("Keys");
+ dialog->clist = gtk_clist_new_with_titles (1, titles);
+ gtk_clist_column_titles_passive (GTK_CLIST (dialog->clist));
+ gtk_widget_set_usize (dialog->clist, 200, 300);
+ gtk_widget_show (dialog->clist);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), dialog->clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scrolled_win,
+ TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_win);
+
+ /* Insert events & descriptions */
+ gtk_clist_freeze (GTK_CLIST (dialog->clist));
+
+ i = 0;
+ while (GbKeys[i].name)
+ {
+ row = gtk_clist_append (GTK_CLIST (dialog->clist),
+ (gchar**) (&GbKeys[i].name));
+ gtk_clist_set_row_data (GTK_CLIST (dialog->clist), row,
+ GINT_TO_POINTER (i));
+ i++;
+ }
+
+ gtk_clist_thaw (GTK_CLIST (dialog->clist));
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+
+GtkWidget*
+glade_keys_dialog_new ()
+{
+ GladeKeysDialog *dialog;
+
+ dialog = gtk_type_new (glade_keys_dialog_get_type ());
+
+ return GTK_WIDGET (dialog);
+}
+
+
+/* This returns TRUE if a key is currently selected, and the given pointer
+ is set to the key value. */
+gboolean
+glade_keys_dialog_get_key (GladeKeysDialog *dialog,
+ guint *key)
+{
+ GList *selection = GTK_CLIST (dialog->clist)->selection;
+ gint row, index;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ index = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (dialog->clist), row));
+ *key = GbKeys[index].key;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* This returns the name of the key currently selected, or NULL if none is
+ selected. */
+gchar*
+glade_keys_dialog_get_key_symbol (GladeKeysDialog *dialog)
+{
+ GList *selection = GTK_CLIST (dialog->clist)->selection;
+ gint row, index;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ index = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (dialog->clist), row));
+ return GbKeys[index].name;
+ }
+ return NULL;
+}
+
+
+/* This sets the current key, using the given key value. */
+void
+glade_keys_dialog_set_key (GladeKeysDialog *dialog,
+ guint key)
+{
+ gint row, index;
+
+ for (row = 0; row < GTK_CLIST (dialog->clist)->rows; row++)
+ {
+ index = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (dialog->clist), row));
+ if (GbKeys[index].key == key)
+ {
+ gtk_clist_select_row (GTK_CLIST (dialog->clist), row, 0);
+ break;
+ }
+ }
+}
+
+
+/* This sets the current key, using the given key name. */
+void
+glade_keys_dialog_set_key_symbol (GladeKeysDialog *dialog,
+ const gchar *key)
+{
+ gint row, index;
+
+ for (row = 0; row < GTK_CLIST (dialog->clist)->rows; row++)
+ {
+ index = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (dialog->clist), row));
+ if (!strcmp (GbKeys[index].name, key))
+ {
+ gtk_clist_select_row (GTK_CLIST (dialog->clist), row, 0);
+ break;
+ }
+ }
+}
+
+
+/* This finds the key value corresponding to the given string, which may be
+ a symbol in gdkkeysyms.h, e.g. 'GDK_Tab', or a simple character, e.g. 'S'.
+ Note that for GTK 1.0 this is a gchar, but for GTK 1.2 it is a guint. */
+guint
+glade_keys_dialog_find_key (const gchar *symbol)
+{
+ static GHashTable *keys_hash = NULL;
+ guint key;
+ gint i;
+
+ /* If this is the first call, create the GHashTable. */
+ if (keys_hash == NULL)
+ {
+ keys_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 0; GbKeys[i].name; i++)
+ {
+ if (GbKeys[i].key == 0)
+ g_warning ("GDK Key value is 0 - will not be found");
+ g_hash_table_insert (keys_hash, GbKeys[i].name,
+ GUINT_TO_POINTER (GbKeys[i].key));
+ }
+ }
+
+ /* Lookup the key in the GHashTable. */
+ key = GPOINTER_TO_UINT (g_hash_table_lookup (keys_hash, symbol));
+ if (key)
+ return key;
+
+ /* If it's not found, return the first char. */
+ return (guint) symbol[0];
+}
+
+
diff --git a/tools/glade/glade/glade_keys_dialog.h b/tools/glade/glade/glade_keys_dialog.h
new file mode 100644
index 00000000..d9e1440b
--- /dev/null
+++ b/tools/glade/glade/glade_keys_dialog.h
@@ -0,0 +1,86 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLADE_KEYS_DIALOG_H
+#define GLADE_KEYS_DIALOG_H
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkdialog.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GLADE_KEYS_DIALOG(obj) GTK_CHECK_CAST (obj, glade_keys_dialog_get_type (), GladeKeysDialog)
+#define GLADE_KEYS_DIALOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_keys_dialog_get_type (), GladeKeysDialogClass)
+#define GLADE_IS_KEYS_DIALOG(obj) GTK_CHECK_TYPE (obj, glade_keys_dialog_get_type ())
+
+
+typedef struct _GladeKeysDialog GladeKeysDialog;
+typedef struct _GladeKeysDialogClass GladeKeysDialogClass;
+
+struct _GladeKeysDialog
+{
+ GtkDialog dialog;
+
+ GtkWidget *clist;
+};
+
+struct _GladeKeysDialogClass
+{
+ GtkDialogClass parent_class;
+};
+
+
+GType glade_keys_dialog_get_type (void);
+GtkWidget* glade_keys_dialog_new (void);
+
+/* This returns TRUE if a key is currently selected, and the given pointer
+ is set to the key value. */
+gboolean glade_keys_dialog_get_key (GladeKeysDialog *dialog,
+ guint *key);
+
+/* This returns the name of the key currently selected, or NULL if none is
+ selected. */
+gchar* glade_keys_dialog_get_key_symbol (GladeKeysDialog *dialog);
+
+/* This sets the current key, using the given key value. */
+void glade_keys_dialog_set_key (GladeKeysDialog *dialog,
+ guint key);
+
+/* This sets the current key, using the given key name. */
+void glade_keys_dialog_set_key_symbol (GladeKeysDialog *dialog,
+ const gchar *key);
+
+
+/* This finds the key value corresponding to the given string, which may be
+ a symbol in gdkkeysyms.h, e.g. 'GDK_Tab', or a simple character, e.g. 'S'.
+ Note that for GTK 1.0 this is a gchar, but for GTK 1.1 it is a guint. */
+guint glade_keys_dialog_find_key (const gchar *symbol);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* GLADE_KEYS_DIALOG_H */
diff --git a/tools/glade/glade/glade_menu_editor.c b/tools/glade/glade/glade_menu_editor.c
new file mode 100644
index 00000000..2535f4b0
--- /dev/null
+++ b/tools/glade/glade/glade_menu_editor.c
@@ -0,0 +1,3729 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * The Menu Editor window, based on initial work by Javier Arriero País
+ * and John Looney.
+ */
+
+#include <string.h>
+#include <time.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkarrow.h>
+#include <gtk/gtkaccellabel.h>
+#include <gtk/gtkclist.h>
+#include <gtk/gtkcombo.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtkfilechooserdialog.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkhbbox.h>
+#include <gtk/gtkhseparator.h>
+#include <gtk/gtkiconfactory.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtklist.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenubar.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkradiomenuitem.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkseparatormenuitem.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktearoffmenuitem.h>
+#include <gtk/gtkvbox.h>
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#include "glade_gnome.h"
+#endif
+
+#include "gb.h"
+#include "glade_menu_editor.h"
+#include "glade_keys_dialog.h"
+#include "glade_project.h"
+#include "gbwidget.h"
+#include "tree.h"
+#include "utils.h"
+
+#define GladeMenuEditorIndexKey "glade-menu-editor-index-key"
+#define GladeMenuEditorStockIDKey "glade-menu-editor-stock-id"
+
+/* How many pixels to indent levels of the menu hierarchy in the clist. */
+#define GB_INDENT 10
+
+/* The text to display if the item is a separator. */
+#define GB_SEPARATOR_TEXT "---"
+
+/* This sets the order of the clist columns. */
+#define GB_MENUED_NUM_COLS 8
+
+#define GLD_COL_LABEL 0
+#define GLD_COL_TYPE 1
+#define GLD_COL_ACCEL 2
+#define GLD_COL_NAME 3
+#define GLD_COL_HANDLER 4
+#define GLD_COL_ACTIVE 5
+#define GLD_COL_GROUP 6
+#define GLD_COL_ICON 7
+
+typedef enum
+ {
+ GB_MENU_ITEM_NORMAL,
+ GB_MENU_ITEM_CHECK,
+ GB_MENU_ITEM_RADIO
+ }
+GbMenuItemType;
+
+
+/* This holds information on one menu item. */
+typedef struct _GbMenuItemData GbMenuItemData;
+struct _GbMenuItemData
+ {
+ gint stock_item_index; /* Stock menu item index, 0 == None. */
+ gchar *label; /* Text to display. */
+ gchar *name; /* Widget name. */
+ gchar *handler; /* Handler to call when selected. */
+ time_t last_mod_time; /* The time the handler was last updated. */
+ gchar *icon; /* Icon filename, or Stock icon name. */
+ gchar *tooltip; /* Tooltip text. */
+ GbMenuItemType type; /* Type - normal/check/radio. */
+ gboolean active; /* If the item is initially active. */
+ GbMenuItemData *group; /* Points to the item data of the first widget
+ in the radio group, or NULL if it is in its
+ own group or is the first item in group. */
+ guint8 modifiers; /* Control/Shift/Alt flags. */
+ gchar *key; /* Name of accelerator key. */
+
+ gint level; /* Level in menu hierarchy. */
+ gboolean generate_name; /* If the name should be auto-generated. */
+ gboolean generate_handler; /* If the handler should be auto-generated. */
+
+ GladeWidgetData *wdata; /* The widget data associated with the old
+ menu item, if there was one. */
+ };
+
+
+static void glade_menu_editor_class_init (GladeMenuEditorClass * klass);
+static void glade_menu_editor_init (GladeMenuEditor * dialog);
+static void glade_menu_editor_destroy (GtkObject *object);
+
+/* If the menu widget we are editing is destroyed, the menu editor is destroyed
+ as well. */
+static void glade_menu_editor_on_menu_destroyed (GtkWidget *menu,
+ GtkWidget *menued);
+
+static void on_menu_editor_ok (GtkWidget *button,
+ GladeMenuEditor *menued);
+static void on_menu_editor_apply (GtkWidget *button,
+ GladeMenuEditor *menued);
+static void on_menu_editor_close (GtkWidget *widget,
+ GladeMenuEditor *menued);
+
+/* This sets the menubar/popup menu whose children are displayed in the
+ menu editor, i.e. converted to items in the clist. */
+static void glade_menu_editor_set_menu (GladeMenuEditor *menued,
+ GtkMenuShell *menu);
+
+/* This updates the given widget, based on the settings in the menu editor.
+ It removes all the current children of the menu and recreates it. */
+static void glade_menu_editor_update_menu (GladeMenuEditor *menued);
+
+
+static gboolean on_key_press (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer user_data);
+static void on_clist_select_row (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data);
+static void on_clist_unselect_row (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data);
+static void on_entry_changed (GtkWidget * entry,
+ gpointer user_data);
+static void on_icon_button_clicked (GtkWidget * button,
+ gpointer user_data);
+static void on_icon_filesel_response (GtkWidget * filesel,
+ gint response_id,
+ GladeMenuEditor *menued);
+static void on_stock_item_entry_changed (GtkWidget * entry,
+ gpointer user_data);
+static gboolean on_label_entry_key_press (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer user_data);
+static void on_radiobutton_toggled (GtkWidget * togglebutton,
+ gpointer user_data);
+static void on_checkbutton_toggled (GtkWidget * togglebutton,
+ gpointer user_data);
+static void on_state_button_toggled (GtkToggleButton * togglebutton,
+ gpointer user_data);
+static void on_accel_key_button_clicked (GtkButton * button,
+ gpointer user_data);
+static void on_up_button_clicked (GtkButton * button,
+ gpointer user_data);
+static void on_down_button_clicked (GtkButton * button,
+ gpointer user_data);
+static void on_left_button_clicked (GtkButton * button,
+ gpointer user_data);
+static void on_right_button_clicked (GtkButton * button,
+ gpointer user_data);
+static void on_add_button_clicked (GtkWidget * button,
+ gpointer user_data);
+static void on_add_child_button_clicked (GtkWidget * button,
+ gpointer user_data);
+static void on_add_separator_button_clicked (GtkWidget * button,
+ gpointer user_data);
+static void add_item (GladeMenuEditor * menued,
+ gboolean as_child,
+ gboolean separator);
+static void on_delete_button_clicked (GtkWidget * widget,
+ gpointer user_data);
+
+static void on_keys_dialog_clist_select (GtkWidget * widget,
+ gint row,
+ gint column,
+ GdkEventButton * bevent,
+ GladeMenuEditor * menued);
+static void on_keys_dialog_response (GtkWidget * widget, gint response_id,
+ GladeMenuEditor * menued);
+
+static gint get_selected_row (GladeMenuEditor * menued);
+static GbMenuItemData* get_selected_item (GladeMenuEditor * menued);
+static void set_interface_state (GladeMenuEditor * menued);
+static gchar *get_accel_string (gchar * key,
+ guint8 modifiers);
+static void insert_item (GtkCList * clist,
+ GbMenuItemData * item,
+ gint row);
+static void ensure_visible (GtkWidget *clist,
+ gint row);
+static void update_current_item (GladeMenuEditor * menued);
+static gboolean item_property_changed (gchar *new, gchar *old);
+static gchar* copy_item_property (gchar *property);
+static void clear_form (GladeMenuEditor * menued,
+ gboolean full);
+static void show_item_properties (GladeMenuEditor * menued);
+static void insert_items (GtkWidget * clist,
+ GList * items,
+ gint row);
+static GList *remove_item_and_children (GtkWidget * clist,
+ gint row);
+static GtkWidget* create_radio_menu_item (GtkMenuShell *menu,
+ GbMenuItemData *item,
+ GHashTable *group_hash);
+static gchar* generate_name (GladeMenuEditor *menued,
+ gchar *label);
+static gchar* generate_handler (GladeMenuEditor *menued,
+ gint row,
+ gchar *label,
+ gchar *name);
+static void check_generated_handlers (GladeMenuEditor *menued);
+static gboolean is_parent (GladeMenuEditor *menued,
+ gint row);
+static void set_submenu (GladeMenuEditor *menued,
+ GtkMenuShell *menu,
+ gint level);
+static void glade_menu_editor_reset (GladeMenuEditor *menued);
+static void glade_menu_editor_free_item (GbMenuItemData *item);
+
+static void update_radio_groups (GladeMenuEditor * menued);
+static void normalize_radio_groups (GladeMenuEditor * menued);
+static GbMenuItemData* find_radio_group (GtkRadioMenuItem *menuitem,
+ GList **groups,
+ GbMenuItemData *item);
+static void remove_from_radio_group (GladeMenuEditor * menued,
+ GbMenuItemData *item);
+
+static GtkWindowClass *parent_class = NULL;
+
+
+GType
+glade_menu_editor_get_type (void)
+{
+ static GType glade_menu_editor_type = 0;
+
+ if (!glade_menu_editor_type)
+ {
+ GtkTypeInfo glade_menu_editor_info =
+ {
+ "GladeMenuEditor",
+ sizeof (GladeMenuEditor),
+ sizeof (GladeMenuEditorClass),
+ (GtkClassInitFunc) glade_menu_editor_class_init,
+ (GtkObjectInitFunc) glade_menu_editor_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ glade_menu_editor_type = gtk_type_unique (gtk_window_get_type (),
+ &glade_menu_editor_info);
+ }
+
+ return glade_menu_editor_type;
+}
+
+static void
+glade_menu_editor_class_init (GladeMenuEditorClass * class)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = (GtkObjectClass *) class;
+ widget_class = (GtkWidgetClass *) class;
+
+ parent_class = gtk_type_class (gtk_window_get_type ());
+
+ object_class->destroy = glade_menu_editor_destroy;
+}
+
+
+/* FIXME: This is mostly a temporary hack until GtkEntry is fixed in GTK+
+ 2.0.x so we don't get "changed" twice when we call gtk_entry_set_text().
+ Though we also need this to set it to "" when NULL is passed in. */
+static void
+set_entry_text (GtkEntry *entry,
+ const gchar *text)
+{
+ gint tmp_pos;
+
+ GtkEditable *editable;
+
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+
+ if (!text)
+ text = "";
+
+ editable = GTK_EDITABLE (entry);
+
+ g_signal_handlers_block_by_func (editable, on_entry_changed, NULL);
+ gtk_editable_delete_text (GTK_EDITABLE(entry), 0, -1);
+ g_signal_handlers_unblock_by_func (editable, on_entry_changed, NULL);
+
+ tmp_pos = 0;
+ gtk_editable_insert_text (editable, text, strlen (text), &tmp_pos);
+}
+
+
+static void
+glade_menu_editor_init (GladeMenuEditor * menued)
+{
+ menued->keys_dialog = NULL;
+ menued->filesel = NULL;
+ menued->project = NULL;
+ menued->menu = NULL;
+ menued->updating_widgets = FALSE;
+ menued->gnome_support = FALSE;
+}
+
+
+static void
+glade_menu_editor_construct (GladeMenuEditor * menued,
+ GladeProject * project)
+{
+ GtkWidget *vbox2, *vbox1, *scrolled_win;
+ GtkWidget *hbox1;
+ GtkWidget *vbox3;
+ GtkWidget *table1;
+ GtkWidget *eventbox3;
+ GtkWidget *eventbox2;
+ GtkWidget *eventbox1;
+ GtkWidget *table2;
+ GSList *table2_group = NULL;
+ GtkWidget *table3;
+ GtkWidget *accel_key_button;
+ GtkWidget *hbox2;
+ GtkWidget *label9;
+ GtkWidget *label8;
+ GtkWidget *hbuttonbox3;
+ GtkWidget *arrow1;
+ GtkWidget *arrow2;
+ GtkWidget *arrow3;
+ GtkWidget *arrow4;
+ GtkWidget *button_table;
+ GtkWidget *hseparator1;
+ GtkWidget *hbuttonbox1;
+ GtkWidget *listitem;
+ GtkTooltips *tooltips;
+ gchar *titles[GB_MENUED_NUM_COLS];
+ gint row;
+ GSList *elem;
+ gchar *stock_id;
+ GtkWidget *icon_hbox;
+ gchar *label_text;
+ gint idx;
+#ifdef USE_GNOME
+ GnomeUIInfo *uiinfo;
+ GtkWidget *pixmap, *label, *hbox, *separator;
+#endif
+
+ menued->project = project;
+#ifdef USE_GNOME
+ if (glade_project_get_gnome_support (project))
+ menued->gnome_support = TRUE;
+#endif
+
+ tooltips = gtk_tooltips_new ();
+
+ gtk_container_set_border_width (GTK_CONTAINER (menued), 8);
+ gtk_window_set_title (GTK_WINDOW (menued), _ ("Menu Editor"));
+ gtk_window_set_policy (GTK_WINDOW (menued), FALSE, TRUE, FALSE);
+ gtk_window_set_wmclass (GTK_WINDOW (menued), "menu_editor", "Glade");
+
+ vbox2 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox2);
+ gtk_container_add (GTK_CONTAINER (menued), vbox2);
+
+ hbox1 = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox1);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0);
+
+ vbox1 = gtk_vbox_new (FALSE, 4);
+ gtk_widget_show (vbox1);
+ gtk_box_pack_start (GTK_BOX (hbox1), vbox1, TRUE, TRUE, 0);
+
+ titles[GLD_COL_LABEL] = _("Label");
+ titles[GLD_COL_TYPE] = _("Type");
+ titles[GLD_COL_ACCEL] = _("Accelerator");
+ titles[GLD_COL_NAME] = _("Name");
+ titles[GLD_COL_HANDLER] = _("Handler");
+ titles[GLD_COL_ACTIVE] = _("Active");
+ titles[GLD_COL_GROUP] = _("Group");
+ titles[GLD_COL_ICON] = _("Icon");
+
+ menued->clist = gtk_clist_new_with_titles (GB_MENUED_NUM_COLS, titles);
+ gtk_widget_show (menued->clist);
+ GTK_WIDGET_SET_FLAGS (menued->clist, GTK_CAN_FOCUS);
+ gtk_signal_connect (GTK_OBJECT (menued->clist), "key_press_event",
+ GTK_SIGNAL_FUNC (on_key_press),
+ NULL);
+ gtk_widget_set_usize (menued->clist, 300, -1);
+ gtk_signal_connect (GTK_OBJECT (menued->clist), "select_row",
+ GTK_SIGNAL_FUNC (on_clist_select_row), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->clist), "unselect_row",
+ GTK_SIGNAL_FUNC (on_clist_unselect_row), NULL);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_LABEL, 144);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_TYPE, 42);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_ACCEL, 120);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_NAME, 100);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_HANDLER, 172);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_ICON, 172);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_ACTIVE, 42);
+ gtk_clist_set_column_width (GTK_CLIST (menued->clist), GLD_COL_GROUP, 75);
+ gtk_clist_column_titles_show (GTK_CLIST (menued->clist));
+ gtk_clist_column_titles_passive (GTK_CLIST (menued->clist));
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), menued->clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (vbox1), scrolled_win, TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_win);
+
+ hbuttonbox3 = gtk_hbutton_box_new ();
+ gtk_widget_show (hbuttonbox3);
+ gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox3, FALSE, TRUE, 0);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox3),
+ GTK_BUTTONBOX_SPREAD);
+ gtk_box_set_spacing (GTK_BOX (hbuttonbox3), 6);
+
+ menued->up_button = gtk_button_new ();
+ gtk_widget_show (menued->up_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox3), menued->up_button);
+ gtk_tooltips_set_tip (tooltips, menued->up_button, _ ("Move the item and its children up one place in the list"), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->up_button), "clicked",
+ GTK_SIGNAL_FUNC (on_up_button_clicked),
+ NULL);
+
+ arrow1 = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT);
+ gtk_widget_show (arrow1);
+ gtk_container_add (GTK_CONTAINER (menued->up_button), arrow1);
+
+ menued->down_button = gtk_button_new ();
+ gtk_widget_show (menued->down_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox3), menued->down_button);
+ gtk_tooltips_set_tip (tooltips, menued->down_button, _ ("Move the item and its children down one place in the list"), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->down_button), "clicked",
+ GTK_SIGNAL_FUNC (on_down_button_clicked),
+ NULL);
+
+ arrow2 = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+ gtk_widget_show (arrow2);
+ gtk_container_add (GTK_CONTAINER (menued->down_button), arrow2);
+
+ menued->left_button = gtk_button_new ();
+ gtk_widget_show (menued->left_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox3), menued->left_button);
+ gtk_tooltips_set_tip (tooltips, menued->left_button, _ ("Move the item and its children up one level"), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->left_button), "clicked",
+ GTK_SIGNAL_FUNC (on_left_button_clicked),
+ NULL);
+
+ arrow3 = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_OUT);
+ gtk_widget_show (arrow3);
+ gtk_container_add (GTK_CONTAINER (menued->left_button), arrow3);
+
+ menued->right_button = gtk_button_new ();
+ gtk_widget_show (menued->right_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox3), menued->right_button);
+ gtk_tooltips_set_tip (tooltips, menued->right_button, _ ("Move the item and its children down one level"), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->right_button), "clicked",
+ GTK_SIGNAL_FUNC (on_right_button_clicked),
+ NULL);
+
+ arrow4 = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
+ gtk_widget_show (arrow4);
+ gtk_container_add (GTK_CONTAINER (menued->right_button), arrow4);
+
+ vbox3 = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox3);
+ gtk_box_pack_start (GTK_BOX (hbox1), vbox3, FALSE, TRUE, 0);
+
+ table1 = gtk_table_new (5, 3, FALSE);
+ gtk_widget_show (table1);
+ gtk_box_pack_start (GTK_BOX (vbox3), table1, FALSE, TRUE, 0);
+ gtk_table_set_row_spacings (GTK_TABLE (table1), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table1), 4);
+ row = 0;
+
+ menued->stock_items = gtk_stock_list_ids ();
+ menued->stock_items = g_slist_sort (menued->stock_items,
+ glade_util_compare_stock_labels);
+
+ if (!menued->gnome_support)
+ {
+ eventbox1 = gtk_event_box_new ();
+ gtk_widget_show (eventbox1);
+ gtk_table_attach (GTK_TABLE (table1), eventbox1, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox1, _ ("The stock item to use."),
+ NULL);
+
+ menued->stock_label = gtk_label_new (_ ("Stock Item:"));
+ gtk_widget_show (menued->stock_label);
+ gtk_container_add (GTK_CONTAINER (eventbox1), menued->stock_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->stock_label), 0, 0.5);
+
+ menued->stock_combo = gtk_combo_new ();
+ gb_widget_set_usize (menued->stock_combo, 100, -1);
+ gtk_table_attach (GTK_TABLE (table1), menued->stock_combo, 1, 3,
+ row, row + 1, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_combo_set_value_in_list (GTK_COMBO (menued->stock_combo),
+ FALSE, FALSE);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (menued->stock_combo)->entry),
+ FALSE);
+ gtk_widget_show (menued->stock_combo);
+
+ listitem = gtk_list_item_new_with_label (_("None"));
+ gtk_widget_show (listitem);
+ gtk_container_add (GTK_CONTAINER (GTK_COMBO (menued->stock_combo)->list),
+ listitem);
+
+ for (elem = menued->stock_items, idx = 1; elem; elem = elem->next, idx++)
+ {
+ GtkStockItem item;
+ GtkWidget *listitem, *hbox, *image, *label;
+ GtkIconSet *icon_set;
+ GtkIconSize *sizes;
+ gint n_sizes, i;
+ gboolean has_menu_size;
+
+ stock_id = elem->data;
+
+#if 0
+ g_print ("Stock ID: %s\n", stock_id);
+#endif
+
+ /* Only show GTK+ stock items. */
+ if (strncmp (stock_id, "gtk-", 4) != 0)
+ continue;
+
+ /* Check that the icon has a menu size. */
+ has_menu_size = FALSE;
+ icon_set = gtk_icon_factory_lookup_default (stock_id);
+ if (icon_set)
+ {
+ gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
+ for (i = 0; i < n_sizes; i++)
+ {
+ if (sizes[i] == GTK_ICON_SIZE_MENU)
+ has_menu_size = TRUE;
+ }
+ g_free (sizes);
+ }
+
+ if (!has_menu_size)
+ {
+#if 0
+ g_print ("Skipping: %s\n", stock_id);
+#endif
+ continue;
+ }
+
+ if (gtk_stock_lookup (stock_id, &item))
+ {
+ listitem = gtk_list_item_new ();
+ gtk_object_set_data (GTK_OBJECT (listitem),
+ GladeMenuEditorIndexKey,
+ GINT_TO_POINTER (idx));
+ gtk_widget_show (listitem);
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (listitem), hbox);
+ gtk_widget_show (hbox);
+
+ image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+
+ if (image)
+ {
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ }
+
+ label = gtk_type_new (GTK_TYPE_ACCEL_LABEL);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label), item.label);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ gtk_combo_set_item_string (GTK_COMBO (menued->stock_combo),
+ GTK_ITEM (listitem), stock_id);
+
+ gtk_container_add (GTK_CONTAINER (GTK_COMBO (menued->stock_combo)->list), listitem);
+ }
+ else
+ {
+#if 0
+ g_print ("Lookup failed for stock_id: %s (probably a stock image only\n", stock_id);
+#endif
+ }
+ }
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (menued->stock_combo)->entry),
+ "changed",
+ GTK_SIGNAL_FUNC (on_stock_item_entry_changed),
+ NULL);
+ row++;
+ }
+
+#ifdef USE_GNOME
+ if (menued->gnome_support)
+ {
+ /* Gnome stock item. */
+ eventbox1 = gtk_event_box_new ();
+ gtk_widget_show (eventbox1);
+ gtk_table_attach (GTK_TABLE (table1), eventbox1, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox1,
+ _ ("The stock Gnome item to use."), NULL);
+
+ menued->stock_label = gtk_label_new (_ ("Stock Item:"));
+ gtk_widget_show (menued->stock_label);
+ gtk_container_add (GTK_CONTAINER (eventbox1), menued->stock_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->stock_label), 0, 0.5);
+
+ menued->stock_combo = gtk_combo_new ();
+ gb_widget_set_usize (menued->stock_combo, 100, -1);
+ gtk_table_attach (GTK_TABLE (table1), menued->stock_combo, 1, 3,
+ row, row + 1, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_combo_set_value_in_list (GTK_COMBO (menued->stock_combo),
+ FALSE, FALSE);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (menued->stock_combo)->entry),
+ FALSE);
+ gtk_widget_show (menued->stock_combo);
+
+ for (uiinfo = GladeStockMenuItemValues;
+ uiinfo->type != GNOME_APP_UI_ENDOFINFO;
+ uiinfo++)
+ {
+ pixmap = NULL;
+ label = NULL;
+ label_text = NULL;
+
+ if (uiinfo->type == GNOME_APP_UI_ITEM_CONFIGURABLE)
+ gnome_app_ui_configure_configurable (uiinfo);
+
+ uiinfo->widget = NULL;
+
+ switch (uiinfo->type) {
+ case GNOME_APP_UI_SEPARATOR:
+ uiinfo->widget = gtk_list_item_new ();
+ gtk_widget_show (uiinfo->widget);
+ separator = gtk_hseparator_new();
+ gtk_widget_show (separator);
+ gtk_container_add (GTK_CONTAINER (uiinfo->widget), separator);
+ gtk_widget_set_sensitive (uiinfo->widget, FALSE);
+ gtk_combo_set_item_string (GTK_COMBO (menued->stock_combo),
+ GTK_ITEM (uiinfo->widget), "");
+ gtk_container_add (GTK_CONTAINER (GTK_COMBO (menued->stock_combo)->list), uiinfo->widget);
+ break;
+ case GNOME_APP_UI_ITEM:
+ case GNOME_APP_UI_SUBTREE_STOCK:
+ if (uiinfo->pixmap_type == GNOME_APP_PIXMAP_STOCK)
+ pixmap = gtk_image_new_from_stock (uiinfo->pixmap_info, GTK_ICON_SIZE_MENU);
+
+ if (uiinfo->label && uiinfo->label[0])
+ {
+ uiinfo->widget = gtk_list_item_new ();
+ gtk_widget_show (uiinfo->widget);
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (uiinfo->widget), hbox);
+ gtk_widget_show (hbox);
+
+ if (!pixmap && uiinfo->type != GNOME_APP_UI_SUBTREE_STOCK)
+ {
+ /* Create a dummy widget to fill in the space. */
+ pixmap = gtk_alignment_new (0, 0, 0, 0);
+ gtk_widget_set_size_request (pixmap, 16, -1);
+ }
+
+ if (pixmap)
+ {
+ gtk_widget_show (pixmap);
+ gtk_box_pack_start (GTK_BOX (hbox), pixmap,
+ FALSE, FALSE, 0);
+ }
+
+ label = gtk_accel_label_new ("");
+ /* Most of the label text is from Gnome, but 2 of them are
+ ours, so we use a utility function to find the translation.
+ */
+ label_text = glade_gnome_gettext (uiinfo->label);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label),
+ label_text);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ gtk_combo_set_item_string (GTK_COMBO (menued->stock_combo),
+ GTK_ITEM (uiinfo->widget),
+ label_text);
+
+ gtk_container_add (GTK_CONTAINER (GTK_COMBO (menued->stock_combo)->list), uiinfo->widget);
+ }
+ break;
+
+ default:
+ g_warning ("Invalid UIINFO item type");
+ }
+ }
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (menued->stock_combo)->entry),
+ "changed",
+ GTK_SIGNAL_FUNC (on_stock_item_entry_changed),
+ NULL);
+
+ row++;
+ }
+#endif /* USE_GNOME */
+
+ /* Item Label. */
+ eventbox1 = gtk_event_box_new ();
+ gtk_widget_show (eventbox1);
+ gtk_table_attach (GTK_TABLE (table1), eventbox1, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox1, _ ("The text of the menu item, or empty for separators."), NULL);
+
+ menued->label_label = gtk_label_new (_ ("Label:"));
+ gtk_widget_show (menued->label_label);
+ gtk_container_add (GTK_CONTAINER (eventbox1), menued->label_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->label_label), 0, 0.5);
+
+ menued->label_entry = gtk_entry_new ();
+ gtk_widget_show (menued->label_entry);
+ gtk_table_attach (GTK_TABLE (table1), menued->label_entry, 1, 3,
+ row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (menued->label_entry), "changed",
+ GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->label_entry), "key_press_event",
+ GTK_SIGNAL_FUNC (on_label_entry_key_press),
+ NULL);
+ row++;
+
+ /* Item Name. */
+ eventbox2 = gtk_event_box_new ();
+ gtk_widget_show (eventbox2);
+ gtk_table_attach (GTK_TABLE (table1), eventbox2, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox2, _ ("The name of the widget"),
+ NULL);
+
+ menued->name_label = gtk_label_new (_ ("Name:"));
+ gtk_widget_show (menued->name_label);
+ gtk_container_add (GTK_CONTAINER (eventbox2), menued->name_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->name_label), 0, 0.5);
+
+ menued->name_entry = gtk_entry_new ();
+ gtk_widget_show (menued->name_entry);
+ gtk_table_attach (GTK_TABLE (table1), menued->name_entry, 1, 3, row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (menued->name_entry), "changed",
+ GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+ row++;
+
+ /* Item Handler. */
+ eventbox3 = gtk_event_box_new ();
+ gtk_widget_show (eventbox3);
+ gtk_table_attach (GTK_TABLE (table1), eventbox3, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox3, _ ("The function to be called when the item is selected"), NULL);
+
+ menued->handler_label = gtk_label_new (_ ("Handler:"));
+ gtk_widget_show (menued->handler_label);
+ gtk_container_add (GTK_CONTAINER (eventbox3), menued->handler_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->handler_label), 0, 0.5);
+
+ menued->handler_entry = gtk_entry_new ();
+ gtk_widget_show (menued->handler_entry);
+ gtk_table_attach (GTK_TABLE (table1), menued->handler_entry, 1, 3,
+ row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (menued->handler_entry), "changed",
+ GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+ row++;
+
+ /* Item Icon. */
+ eventbox1 = gtk_event_box_new ();
+ gtk_widget_show (eventbox1);
+ gtk_table_attach (GTK_TABLE (table1), eventbox1, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox1, _ ("An optional icon to show on the left of the menu item."), NULL);
+
+ menued->icon_label = gtk_label_new (_ ("Icon:"));
+ gtk_widget_show (menued->icon_label);
+ gtk_container_add (GTK_CONTAINER (eventbox1), menued->icon_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->icon_label), 0, 0.5);
+
+ icon_hbox = gtk_hbox_new (FALSE, 2);
+ gtk_table_attach (GTK_TABLE (table1), icon_hbox, 1, 3, row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (icon_hbox);
+
+ menued->icon_widget = gtk_combo_new ();
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (menued->icon_widget)->entry),
+ FALSE);
+ gb_widget_set_usize (menued->icon_widget, 100, -1);
+
+ /* Add a "None" item first, so it is easy to reset the pixmap. */
+ listitem = gtk_list_item_new_with_label (_("None"));
+ gtk_widget_show (listitem);
+ gtk_container_add (GTK_CONTAINER (GTK_COMBO (menued->icon_widget)->list),
+ listitem);
+
+ for (elem = menued->stock_items; elem; elem = elem->next)
+ {
+ GtkStockItem item;
+ GtkWidget *listitem, *hbox, *image, *label;
+ GtkIconSet *icon_set;
+ GtkIconSize *sizes;
+ gint n_sizes, i;
+ gboolean has_menu_size;
+
+ stock_id = elem->data;
+
+#if 0
+ g_print ("Stock ID: %s\n", stock_id);
+#endif
+
+ /* Show only GTK+ stock items in GTK+ projects. */
+ if (!menued->gnome_support && (strncmp (stock_id, "gtk-", 4) != 0))
+ continue;
+#if 0
+ /* Only show GnomeDB stock items if GnomeDB support is on. */
+ if (!menued->gnome_db_support && !strncmp (stock_id, "gnome-db-", 9))
+ continue;
+#endif
+
+ /* Check that the icon has a menu size. */
+ has_menu_size = FALSE;
+ icon_set = gtk_icon_factory_lookup_default (stock_id);
+ if (icon_set)
+ {
+ gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
+ for (i = 0; i < n_sizes; i++)
+ {
+ if (sizes[i] == GTK_ICON_SIZE_MENU)
+ has_menu_size = TRUE;
+ }
+ g_free (sizes);
+ }
+
+ if (!has_menu_size)
+ {
+#if 0
+ g_print ("Skipping: %s\n", stock_id);
+#endif
+ continue;
+ }
+
+ image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+ if (image)
+ {
+ listitem = gtk_list_item_new ();
+ /* We store a pointer to the stock_id from the stock_items list,
+ so we don't need to free it, but if stock_items is destroyed it
+ will no longer be valid. */
+ gtk_object_set_data (GTK_OBJECT (listitem),
+ GladeMenuEditorStockIDKey, stock_id);
+ gtk_widget_show (listitem);
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (listitem), hbox);
+ gtk_widget_show (hbox);
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+
+ if (gtk_stock_lookup (stock_id, &item))
+ label_text = item.label;
+ else
+ /* FIXME: We have no name to use for the image. */
+ label_text = stock_id;
+
+ label = gtk_type_new (GTK_TYPE_ACCEL_LABEL);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label), label_text);
+
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_combo_set_item_string (GTK_COMBO (menued->icon_widget),
+ GTK_ITEM (listitem), stock_id);
+ gtk_container_add (GTK_CONTAINER (GTK_COMBO (menued->icon_widget)->list),
+ listitem);
+ }
+ }
+
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (menued->icon_widget)->entry),
+ "changed", GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+
+ gtk_widget_show (menued->icon_widget);
+ gtk_box_pack_start (GTK_BOX (icon_hbox), menued->icon_widget,
+ TRUE, TRUE, 0);
+
+ menued->icon_button = gtk_button_new_with_label ("...");
+ gtk_widget_show (menued->icon_button);
+ gtk_box_pack_start (GTK_BOX (icon_hbox), menued->icon_button,
+ FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (menued->icon_button), "clicked",
+ GTK_SIGNAL_FUNC (on_icon_button_clicked), NULL);
+ row++;
+
+ /* Tooltip. */
+ eventbox3 = gtk_event_box_new ();
+ gtk_widget_show (eventbox3);
+ gtk_table_attach (GTK_TABLE (table1), eventbox3, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox3, _ ("The tip to show when the mouse is over the item"), NULL);
+
+ menued->tooltip_label = gtk_label_new (_ ("Tooltip:"));
+ gtk_widget_show (menued->tooltip_label);
+ gtk_container_add (GTK_CONTAINER (eventbox3), menued->tooltip_label);
+ gtk_misc_set_alignment (GTK_MISC (menued->tooltip_label), 0, 0.5);
+
+ menued->tooltip_entry = gtk_entry_new ();
+ gtk_widget_show (menued->tooltip_entry);
+ gtk_table_attach (GTK_TABLE (table1), menued->tooltip_entry, 1, 3,
+ row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (menued->tooltip_entry), "changed",
+ GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+ row++;
+
+ /* Buttons to add/delete items. */
+ button_table = gtk_table_new (2, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (button_table), 1);
+ gtk_table_set_col_spacings (GTK_TABLE (button_table), 2);
+ gtk_widget_show (button_table);
+ gtk_box_pack_start (GTK_BOX (vbox3), button_table, FALSE, TRUE, 0);
+
+ menued->add_button = gtk_button_new_with_mnemonic (_("_Add"));
+ gtk_widget_show (menued->add_button);
+ gtk_table_attach (GTK_TABLE (button_table), menued->add_button,
+ 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, menued->add_button,
+ _ ("Add a new item below the selected item."), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->add_button), "clicked",
+ GTK_SIGNAL_FUNC (on_add_button_clicked),
+ NULL);
+
+ menued->add_child_button = gtk_button_new_with_mnemonic (_("Add _Child"));
+ gtk_widget_show (menued->add_child_button);
+ gtk_table_attach (GTK_TABLE (button_table), menued->add_child_button,
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, menued->add_child_button,
+ _ ("Add a new child item below the selected item."),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->add_child_button), "clicked",
+ GTK_SIGNAL_FUNC (on_add_child_button_clicked),
+ NULL);
+
+ menued->add_separator_button = gtk_button_new_with_mnemonic (_("Add _Separator"));
+ gtk_widget_show (menued->add_separator_button);
+ gtk_table_attach (GTK_TABLE (button_table), menued->add_separator_button,
+ 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, menued->add_separator_button,
+ _ ("Add a separator below the selected item."), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->add_separator_button), "clicked",
+ GTK_SIGNAL_FUNC (on_add_separator_button_clicked),
+ NULL);
+
+ menued->delete_button = gtk_button_new_with_mnemonic (_("_Delete"));
+ gtk_widget_show (menued->delete_button);
+ gtk_table_attach (GTK_TABLE (button_table), menued->delete_button,
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, menued->delete_button,
+ _ ("Delete the current item"), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->delete_button), "clicked",
+ GTK_SIGNAL_FUNC (on_delete_button_clicked),
+ NULL);
+
+ /* Type radio options and toggle options. */
+ menued->type_frame = gtk_frame_new (_ ("Item Type:"));
+ gtk_widget_show (menued->type_frame);
+ gtk_box_pack_start (GTK_BOX (vbox3), menued->type_frame, FALSE, TRUE, 0);
+
+ table2 = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table2), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table2), 1);
+ gtk_widget_show (table2);
+ gtk_container_add (GTK_CONTAINER (menued->type_frame), table2);
+ gtk_container_set_border_width (GTK_CONTAINER (table2), 4);
+
+ eventbox1 = gtk_event_box_new ();
+ gtk_widget_show (eventbox1);
+ gtk_table_attach (GTK_TABLE (table2), eventbox1, 1, 2, 1, 2,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox1,
+ _ ("If the item is initially on."), NULL);
+
+ menued->state_label = gtk_label_new (_("Active:"));
+ gtk_misc_set_alignment (GTK_MISC (menued->state_label), 0, 0.5);
+ gtk_widget_show (menued->state_label);
+ gtk_container_add (GTK_CONTAINER (eventbox1), menued->state_label);
+
+ menued->state_togglebutton = gtk_toggle_button_new_with_label (_("No"));
+ gtk_widget_show (menued->state_togglebutton);
+ gtk_table_attach (GTK_TABLE (table2), menued->state_togglebutton, 2, 3, 1, 2,
+ GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+ hbox2 = gtk_hbox_new (FALSE, 4);
+ gtk_widget_show (hbox2);
+ gtk_table_attach (GTK_TABLE (table2), hbox2, 1, 3, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ eventbox1 = gtk_event_box_new ();
+ gtk_widget_show (eventbox1);
+ gtk_box_pack_start (GTK_BOX (hbox2), eventbox1, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox1,
+ _ ("The radio menu item's group"), NULL);
+
+ menued->group_label = gtk_label_new (_ ("Group:"));
+ gtk_misc_set_alignment (GTK_MISC (menued->group_label), 0, 0.5);
+ gtk_widget_show (menued->group_label);
+ gtk_container_add (GTK_CONTAINER (eventbox1), menued->group_label);
+
+ menued->group_combo = gtk_combo_new ();
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (menued->group_combo)->entry),
+ FALSE);
+ gtk_widget_set_usize (GTK_COMBO (menued->group_combo)->entry, 60, -1);
+ gtk_widget_show (menued->group_combo);
+ gtk_box_pack_start (GTK_BOX (hbox2), menued->group_combo, TRUE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (menued->group_combo)->entry),
+ "changed", GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+
+ menued->radio_radiobutton = gtk_radio_button_new_with_label (table2_group,
+ _ ("Radio"));
+ table2_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (menued->radio_radiobutton));
+ gtk_widget_show (menued->radio_radiobutton);
+ gtk_table_attach (GTK_TABLE (table2), menued->radio_radiobutton, 0, 1, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ menued->check_radiobutton = gtk_radio_button_new_with_label (table2_group,
+ _ ("Check"));
+ table2_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (menued->check_radiobutton));
+ gtk_widget_show (menued->check_radiobutton);
+ gtk_table_attach (GTK_TABLE (table2), menued->check_radiobutton, 0, 1, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ menued->normal_radiobutton = gtk_radio_button_new_with_label (table2_group,
+ _ ("Normal"));
+ table2_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (menued->normal_radiobutton));
+ gtk_widget_show (menued->normal_radiobutton);
+ gtk_table_attach (GTK_TABLE (table2), menued->normal_radiobutton, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->normal_radiobutton), TRUE);
+
+
+ /* Accelerator key options. */
+ menued->accel_frame = gtk_frame_new (_ ("Accelerator:"));
+ gtk_widget_show (menued->accel_frame);
+ gtk_box_pack_start (GTK_BOX (vbox3), menued->accel_frame, FALSE, TRUE, 0);
+
+ table3 = gtk_table_new (2, 2, FALSE);
+ gtk_widget_show (table3);
+ gtk_container_add (GTK_CONTAINER (menued->accel_frame), table3);
+ gtk_container_set_border_width (GTK_CONTAINER (table3), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table3), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table3), 4);
+
+ hbox2 = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox2);
+ gtk_table_attach (GTK_TABLE (table3), hbox2, 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ menued->accel_key_entry = gtk_entry_new ();
+ gtk_widget_set_usize (menued->accel_key_entry, 100, -1);
+ gtk_widget_show (menued->accel_key_entry);
+ gtk_box_pack_start (GTK_BOX (hbox2), menued->accel_key_entry,
+ TRUE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (menued->accel_key_entry), "changed",
+ GTK_SIGNAL_FUNC (on_entry_changed), NULL);
+
+ accel_key_button = gtk_button_new_with_label ("...");
+ gtk_widget_show (accel_key_button);
+ gtk_box_pack_start (GTK_BOX (hbox2), accel_key_button,
+ FALSE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (accel_key_button), "clicked",
+ GTK_SIGNAL_FUNC (on_accel_key_button_clicked),
+ NULL);
+
+ hbox2 = gtk_hbox_new (TRUE, 0);
+ gtk_widget_show (hbox2);
+ gtk_table_attach (GTK_TABLE (table3), hbox2, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ menued->accel_ctrl_checkbutton = gtk_check_button_new_with_label (_ ("Ctrl"));
+ gtk_widget_show (menued->accel_ctrl_checkbutton);
+ gtk_box_pack_start (GTK_BOX (hbox2), menued->accel_ctrl_checkbutton,
+ TRUE, TRUE, 0);
+
+ menued->accel_shift_checkbutton = gtk_check_button_new_with_label (_ ("Shift"));
+ gtk_widget_show (menued->accel_shift_checkbutton);
+ gtk_box_pack_start (GTK_BOX (hbox2), menued->accel_shift_checkbutton,
+ TRUE, TRUE, 0);
+
+ menued->accel_alt_checkbutton = gtk_check_button_new_with_label (_ ("Alt"));
+ gtk_widget_show (menued->accel_alt_checkbutton);
+ gtk_box_pack_start (GTK_BOX (hbox2), menued->accel_alt_checkbutton,
+ TRUE, TRUE, 0);
+
+ label9 = gtk_label_new (_ ("Key:"));
+ gtk_widget_show (label9);
+ gtk_table_attach (GTK_TABLE (table3), label9, 0, 1, 1, 2,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label9), 0, 0.5);
+
+ label8 = gtk_label_new (_ ("Modifiers:"));
+ gtk_widget_show (label8);
+ gtk_table_attach (GTK_TABLE (table3), label8, 0, 1, 0, 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label8), 0, 0.5);
+
+
+ hseparator1 = gtk_hseparator_new ();
+ gtk_widget_show (hseparator1);
+ gtk_box_pack_start (GTK_BOX (vbox2), hseparator1, FALSE, TRUE, 8);
+
+
+ /* OK, Apply & Cancel buttons. */
+ hbuttonbox1 = gtk_hbutton_box_new ();
+ gtk_widget_show (hbuttonbox1);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox1, FALSE, TRUE, 0);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 8);
+
+ menued->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_widget_show (menued->cancel_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox1), menued->cancel_button);
+ GTK_WIDGET_SET_FLAGS (menued->cancel_button, GTK_CAN_DEFAULT);
+
+ menued->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+ gtk_widget_show (menued->apply_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox1), menued->apply_button);
+ GTK_WIDGET_SET_FLAGS (menued->apply_button, GTK_CAN_DEFAULT);
+
+ menued->ok_button = gtk_button_new_from_stock (GTK_STOCK_OK);
+ gtk_widget_show (menued->ok_button);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox1), menued->ok_button);
+ GTK_WIDGET_SET_FLAGS (menued->ok_button, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default (menued->ok_button);
+
+
+ /* Now set up all the signal handlers. */
+ gtk_signal_connect_after (GTK_OBJECT (menued->normal_radiobutton), "toggled",
+ GTK_SIGNAL_FUNC (on_radiobutton_toggled), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (menued->check_radiobutton), "toggled",
+ GTK_SIGNAL_FUNC (on_radiobutton_toggled), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (menued->radio_radiobutton), "toggled",
+ GTK_SIGNAL_FUNC (on_radiobutton_toggled), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->state_togglebutton), "toggled",
+ GTK_SIGNAL_FUNC (on_state_button_toggled), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->accel_ctrl_checkbutton), "toggled",
+ GTK_SIGNAL_FUNC (on_checkbutton_toggled), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->accel_shift_checkbutton), "toggled",
+ GTK_SIGNAL_FUNC (on_checkbutton_toggled), NULL);
+ gtk_signal_connect (GTK_OBJECT (menued->accel_alt_checkbutton), "toggled",
+ GTK_SIGNAL_FUNC (on_checkbutton_toggled), NULL);
+
+ gtk_signal_connect (GTK_OBJECT (menued->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (on_menu_editor_ok), menued);
+ gtk_signal_connect (GTK_OBJECT (menued->apply_button), "clicked",
+ GTK_SIGNAL_FUNC (on_menu_editor_apply), menued);
+ gtk_signal_connect (GTK_OBJECT (menued->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (on_menu_editor_close), menued);
+
+ set_interface_state (menued);
+}
+
+
+GtkWidget*
+glade_menu_editor_new (GladeProject *project,
+ GtkMenuShell *menu)
+{
+ GladeMenuEditor *menued;
+
+ menued = gtk_type_new (glade_menu_editor_get_type ());
+ glade_menu_editor_construct (menued, project);
+ glade_menu_editor_set_menu (menued, menu);
+
+ return GTK_WIDGET (menued);
+}
+
+static void
+glade_menu_editor_destroy (GtkObject *object)
+{
+ GladeMenuEditor *menued;
+ GSList *elem;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GLADE_IS_MENU_EDITOR (object));
+
+ menued = GLADE_MENU_EDITOR (object);
+
+ /* Free all the GbMenuItemData elements & disconnect our destroy handler
+ on the menu widget. */
+ glade_menu_editor_reset (menued);
+
+ if (menued->keys_dialog)
+ {
+ gtk_widget_destroy (menued->keys_dialog);
+ menued->keys_dialog = NULL;
+ }
+
+ if (menued->filesel)
+ {
+ gtk_widget_destroy (menued->filesel);
+ menued->filesel = NULL;
+ }
+
+ for (elem = menued->stock_items; elem; elem = elem->next)
+ g_free (elem->data);
+ g_slist_free (menued->stock_items);
+ menued->stock_items = NULL;
+}
+
+
+/**************************************************************************
+ * Signal Handlers
+ **************************************************************************/
+
+static void
+on_clist_select_row (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (clist));
+
+ show_item_properties (menued);
+
+ if (event && !GTK_WIDGET_HAS_FOCUS (clist))
+ gtk_widget_grab_focus (clist);
+
+ set_interface_state (menued);
+}
+
+static void
+on_clist_unselect_row (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (clist));
+
+ clear_form (menued, FALSE);
+
+ if (event && !GTK_WIDGET_HAS_FOCUS (clist))
+ gtk_widget_grab_focus (clist);
+
+ set_interface_state (menued);
+}
+
+/* This will only call update_current_item if the text is different to the
+ corresponding item field, since we don't want to propogate updates when
+ we are setting the entry. */
+static void
+on_entry_changed (GtkWidget * entry,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkCList *clist;
+ GbMenuItemData *item;
+ gchar *text, *item_text;
+ gboolean changed = FALSE;
+ gint row;
+
+#if 0
+ g_print ("In on_entry_changed\n");
+#endif
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (entry));
+
+ /* If we are setting the widget values, just return. */
+#if 1
+ if (menued->updating_widgets)
+ return;
+#endif
+
+ clist = GTK_CLIST (menued->clist);
+ row = get_selected_row (menued);
+#if 0
+ g_print ("Selected row: %i\n", row);
+#endif
+ if (row == -1)
+ return;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (menued->clist),
+ row);
+#if 0
+ g_print ("Item %p Label:%s Name:%s Handler:%s\n", item, item->label,
+ item->name, item->handler);
+#endif
+
+ text = (gchar*) gtk_entry_get_text (GTK_ENTRY (entry));
+
+ if (entry == menued->label_entry)
+ {
+ item_text = item->label;
+ }
+ else if (entry == menued->name_entry)
+ {
+ item_text = item->name;
+ }
+ else if (entry == menued->handler_entry)
+ {
+ item_text = item->handler;
+ }
+ else if (entry == GTK_COMBO (menued->icon_widget)->entry)
+ {
+ /* If the user selects the 'None' item from the combo, we reset the
+ text to "" and return. This callback will be called again. */
+ if (!strcmp (text, _("None")))
+ {
+ set_entry_text (GTK_ENTRY (entry), "");
+ return;
+ }
+
+ item_text = item->icon;
+ }
+ else if (entry == menued->tooltip_entry)
+ {
+ item_text = item->tooltip;
+ }
+ else if (entry == GTK_COMBO (menued->group_combo)->entry)
+ {
+ item_text = item->group ? item->group->name : item->name;
+ }
+ else if (entry == menued->accel_key_entry)
+ {
+ item_text = item->key;
+ }
+ else
+ return;
+
+ if (item_text == NULL)
+ {
+ if (strlen (text) > 0)
+ changed = TRUE;
+ }
+ else
+ {
+ if (strcmp (text, item_text))
+ changed = TRUE;
+ }
+
+ if (changed)
+ {
+ if (entry == menued->label_entry)
+ {
+ if (item->generate_name)
+ {
+ glade_project_release_widget_name (menued->project, item->name);
+ g_free (item->name);
+ item->name = generate_name (menued, text);
+ set_entry_text (GTK_ENTRY (menued->name_entry),
+ item->name ? item->name : "");
+ gtk_clist_set_text (clist, row, GLD_COL_NAME,
+ item->name ? item->name : "");
+ if (item->generate_handler)
+ {
+ g_free (item->handler);
+
+ item->handler = generate_handler (menued, row, text,
+ item->name);
+ set_entry_text (GTK_ENTRY (menued->handler_entry),
+ item->handler ? item->handler : "");
+ gtk_clist_set_text (clist, row, GLD_COL_HANDLER,
+ item->handler ? item->handler : "");
+ }
+ }
+ }
+ else if (entry == menued->name_entry)
+ {
+ item->generate_name = FALSE;
+ if (item->generate_handler)
+ {
+ g_free (item->handler);
+ item->handler = generate_handler (menued, row, item->label,
+ text);
+ set_entry_text (GTK_ENTRY (menued->handler_entry),
+ item->handler ? item->handler : "");
+ gtk_clist_set_text (clist, row, GLD_COL_HANDLER,
+ item->handler ? item->handler : "");
+ }
+ }
+ else if (entry == menued->handler_entry)
+ {
+ item->generate_handler = FALSE;
+ }
+
+ update_current_item (menued);
+ set_interface_state (menued);
+ }
+}
+
+
+/* This will only call update_current_item if the text is different to the
+ corresponding item field, since we don't want to propogate updates when
+ we are setting the entry. */
+static void
+on_stock_item_entry_changed (GtkWidget * entry,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkCList *clist;
+ GbMenuItemData *item;
+ gint row;
+ GtkListItem *listitem;
+ gint stock_item_index = 0;
+ const gchar *text;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (entry));
+
+ text = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (menued->stock_combo)->entry));
+ /* FIXME GTK+ 1.3.x bug workaround. It emits "changed" twice, once when the
+ existing text is deleted. So we just return if the text is empty. */
+ if (text[0] == '\0')
+ return;
+
+ clist = GTK_CLIST (menued->clist);
+ row = get_selected_row (menued);
+ if (row == -1)
+ return;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (menued->clist),
+ row);
+
+ /* Find the index of the selected item. */
+ listitem = glade_util_gtk_combo_find (GTK_COMBO (menued->stock_combo));
+ g_return_if_fail (listitem != NULL);
+
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ stock_item_index = g_list_index (GTK_LIST (GTK_COMBO (menued->stock_combo)->list)->children, listitem);
+#endif
+ }
+ else
+ {
+ GtkStockItem item;
+
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (listitem), GladeMenuEditorIndexKey));
+ if (gtk_stock_lookup (text, &item))
+ text = item.label;
+ else
+ stock_item_index = 0;
+ }
+
+ if (item->stock_item_index != stock_item_index)
+ {
+ item->stock_item_index = stock_item_index;
+
+ /* If the stock item is reset to 'None', get a new item name, and reset
+ generate_name/handler to TRUE. */
+ if (stock_item_index == 0)
+ {
+ item->generate_name = TRUE;
+ item->generate_handler = TRUE;
+
+ item->label = glade_project_new_widget_name (menued->project,
+ "item");
+ item->name = g_strdup (item->label);
+ item->handler = generate_handler (menued, row, item->label,
+ item->name);
+ show_item_properties (menued);
+
+ gtk_clist_set_text (clist, row, GLD_COL_LABEL,
+ item->label ? item->label : GB_SEPARATOR_TEXT);
+ gtk_clist_set_text (clist, row, GLD_COL_NAME,
+ item->name ? item->name : "");
+ gtk_clist_set_text (clist, row, GLD_COL_HANDLER,
+ item->handler ? item->handler : "");
+ }
+ else
+ {
+ /* These will trigger callbacks, and will generate the name
+ and handler if appropriate. */
+ set_entry_text (GTK_ENTRY (menued->label_entry), text);
+
+ /* Stock menu items are all normal items. */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->normal_radiobutton), TRUE);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->group_combo)->entry), "");
+
+ /* Reset the accelerator keys, as that is handled automatically. */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_ctrl_checkbutton), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_shift_checkbutton), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_alt_checkbutton), FALSE);
+ set_entry_text (GTK_ENTRY (menued->accel_key_entry), "");
+ }
+ }
+
+ set_interface_state (menued);
+}
+
+
+static gboolean
+on_label_entry_key_press (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (widget));
+
+ /* If the Return key is pressed, we add a new item beneath the selected item.
+ This makes it very easy to add several menus. If the Control key is
+ pressed, we add the item as a child, otherwise we add it as a sibling. */
+ if (event->keyval == GDK_Return)
+ {
+ if (event->state & GDK_CONTROL_MASK)
+ {
+ add_item (menued, TRUE, FALSE);
+ /* Since we are added a child, we may need to set the parent's
+ handler to NULL if it has been auto-generated. */
+ check_generated_handlers (menued);
+ }
+ else
+ {
+ add_item (menued, FALSE, FALSE);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static void
+on_radiobutton_toggled (GtkWidget * togglebutton,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GbMenuItemData *item;
+ GbMenuItemType type = 0;
+ gboolean changed = FALSE;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (togglebutton)));
+ item = get_selected_item (menued);
+ if (item == NULL)
+ return;
+
+ if (togglebutton == menued->normal_radiobutton)
+ type = GB_MENU_ITEM_NORMAL;
+ else if (togglebutton == menued->check_radiobutton)
+ type = GB_MENU_ITEM_CHECK;
+ else if (togglebutton == menued->radio_radiobutton)
+ type = GB_MENU_ITEM_RADIO;
+
+ if (GTK_TOGGLE_BUTTON (togglebutton)->active)
+ {
+ if (type != item->type)
+ changed = TRUE;
+ }
+ else
+ {
+ if (type == item->type)
+ changed = TRUE;
+ }
+
+ if (changed)
+ {
+ update_current_item (menued);
+ set_interface_state (menued);
+ }
+}
+
+static void
+on_checkbutton_toggled (GtkWidget * togglebutton,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GbMenuItemData *item;
+ guint active;
+ guint8 currently_active = 0;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (togglebutton)));
+ active = GTK_TOGGLE_BUTTON (togglebutton)->active;
+ item = get_selected_item (menued);
+ if (item == NULL)
+ return;
+ if (togglebutton == menued->accel_ctrl_checkbutton)
+ currently_active = item->modifiers & GDK_CONTROL_MASK;
+ if (togglebutton == menued->accel_shift_checkbutton)
+ currently_active = item->modifiers & GDK_SHIFT_MASK;
+ if (togglebutton == menued->accel_alt_checkbutton)
+ currently_active = item->modifiers & GDK_MOD1_MASK;
+
+ if ((active && !currently_active) || (!active && currently_active))
+ {
+ update_current_item (menued);
+ set_interface_state (menued);
+ }
+}
+
+static void
+on_state_button_toggled (GtkToggleButton * togglebutton,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GbMenuItemData *item;
+ GtkWidget *label;
+ guint active;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (togglebutton)));
+ active = GTK_TOGGLE_BUTTON (togglebutton)->active;
+ label = GTK_BIN (togglebutton)->child;
+ gtk_label_set_text (GTK_LABEL (label), active ? _("Yes") : _("No"));
+
+ item = get_selected_item (menued);
+ if (item == NULL)
+ return;
+ if ((item->active && !active) || (!item->active && active))
+ update_current_item (menued);
+}
+
+
+/**************************************************************************
+ * Accelerator Keys Dialog.
+ **************************************************************************/
+static void
+on_accel_key_button_clicked (GtkButton * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+
+ if (menued->keys_dialog == NULL)
+ {
+ menued->keys_dialog = glade_keys_dialog_new ();
+ gtk_window_set_position (GTK_WINDOW (menued->keys_dialog),
+ GTK_WIN_POS_MOUSE);
+ gtk_window_set_transient_for (GTK_WINDOW (menued->keys_dialog),
+ GTK_WINDOW (menued));
+ gtk_signal_connect (GTK_OBJECT (GLADE_KEYS_DIALOG (menued->keys_dialog)->clist),
+ "select_row",
+ GTK_SIGNAL_FUNC (on_keys_dialog_clist_select),
+ menued);
+ gtk_signal_connect (GTK_OBJECT (GLADE_KEYS_DIALOG (menued->keys_dialog)),
+ "response",
+ GTK_SIGNAL_FUNC (on_keys_dialog_response),
+ menued);
+ }
+
+ gtk_widget_show (GTK_WIDGET (menued->keys_dialog));
+}
+
+static void
+on_keys_dialog_clist_select (GtkWidget * widget, gint row, gint column,
+ GdkEventButton * bevent, GladeMenuEditor * menued)
+{
+ if (bevent && bevent->type == GDK_2BUTTON_PRESS)
+ on_keys_dialog_response (widget, GTK_RESPONSE_OK, menued);
+}
+
+static void
+on_keys_dialog_response (GtkWidget * widget, gint response_id,
+ GladeMenuEditor * menued)
+{
+ gchar *key_symbol;
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ key_symbol = glade_keys_dialog_get_key_symbol (GLADE_KEYS_DIALOG (menued->keys_dialog));
+ if (key_symbol)
+ {
+ set_entry_text (GTK_ENTRY (menued->accel_key_entry), key_symbol);
+ }
+ }
+
+ glade_util_close_window (menued->keys_dialog);
+}
+
+
+/**************************************************************************
+ * Arrow Button callbacks.
+ **************************************************************************/
+
+static void
+on_up_button_clicked (GtkButton * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkWidget *clist;
+ GbMenuItemData *item, *prev_item;
+ gint row, new_row, i, level;
+ GList *items;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ clist = menued->clist;
+ row = get_selected_row (menued);
+ if (row == -1 || row == 0)
+ return;
+
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ level = item->level;
+
+ /* Find the new position of the item and its children. */
+ new_row = -1;
+ for (i = row - 1; i >= 0; i--)
+ {
+ prev_item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist),
+ i);
+ if (prev_item->level == level)
+ {
+ new_row = i;
+ break;
+ }
+ else if (prev_item->level < level)
+ break;
+ }
+
+ /* Return if we can't move the item up. */
+ if (new_row == -1)
+ return;
+
+ /* Remove item and children. */
+ items = remove_item_and_children (clist, row);
+
+ /* Now insert at new position. */
+ insert_items (clist, items, new_row);
+ ensure_visible (clist, new_row);
+
+ g_list_free (items);
+
+ /* Make sure all items in the group point to the first one. */
+ normalize_radio_groups (menued);
+
+ gtk_clist_select_row (GTK_CLIST (clist), new_row, 0);
+ set_interface_state (menued);
+}
+
+static void
+on_down_button_clicked (GtkButton * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkWidget *clist;
+ GbMenuItemData *item, *next_item;
+ gint row, new_row, i, level;
+ gboolean found_next_item;
+ GList *items;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ clist = menued->clist;
+ row = get_selected_row (menued);
+ if (row == -1 || row == GTK_CLIST (clist)->rows - 1)
+ return;
+
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ level = item->level;
+
+ /* Find the new position of the item and its children. */
+ new_row = -1;
+ found_next_item = FALSE;
+ for (i = row + 1; i < GTK_CLIST (clist)->rows; i++)
+ {
+ next_item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist),
+ i);
+ /* We have to skip all the children of the next item as well. */
+ if (next_item->level == level)
+ {
+ if (found_next_item)
+ {
+ new_row = i;
+ break;
+ }
+ else
+ found_next_item = TRUE;
+ }
+ else if (next_item->level < level)
+ break;
+ }
+
+ /* Return if we can't move the item up. */
+ if (new_row == -1)
+ {
+ if (found_next_item)
+ new_row = i;
+ else
+ return;
+ }
+
+ /* Remove item and children. */
+ items = remove_item_and_children (clist, row);
+ /* Remember that the new_row needs to be shifted because we deleted items. */
+ new_row -= g_list_length (items);
+
+ /* Now insert at new position. */
+ insert_items (clist, items, new_row);
+ ensure_visible (clist, new_row);
+
+ g_list_free (items);
+
+ /* Make sure all items in the group point to the first one. */
+ normalize_radio_groups (menued);
+
+ gtk_clist_select_row (GTK_CLIST (clist), new_row, 0);
+ set_interface_state (menued);
+}
+
+static void
+on_left_button_clicked (GtkButton * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkWidget *clist;
+ GbMenuItemData *item;
+ gint row, i, level;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ clist = menued->clist;
+ row = get_selected_row (menued);
+ if (row == -1)
+ return;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ level = item->level;
+ if (item->level > 0)
+ item->level--;
+ gtk_clist_set_shift (GTK_CLIST (clist), row, 0, 0, item->level * GB_INDENT);
+
+ for (i = row + 1; i < GTK_CLIST (clist)->rows; i++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), i);
+ if (item->level <= level)
+ break;
+ item->level--;
+ gtk_clist_set_shift (GTK_CLIST (clist), i, 0, 0,
+ item->level * GB_INDENT);
+ }
+ check_generated_handlers (menued);
+ set_interface_state (menued);
+}
+
+static void
+on_right_button_clicked (GtkButton * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkWidget *clist;
+ GbMenuItemData *item, *prev_item;
+ gint row, i, level;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ clist = menued->clist;
+ row = get_selected_row (menued);
+ if (row == -1 || row == 0)
+ return;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ prev_item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist),
+ row - 1);
+ if (prev_item->level < item->level)
+ return;
+
+ level = item->level;
+ item->level++;
+ gtk_clist_set_shift (GTK_CLIST (clist), row, 0, 0, item->level * GB_INDENT);
+
+ for (i = row + 1; i < GTK_CLIST (clist)->rows; i++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), i);
+ if (item->level <= level)
+ break;
+ item->level++;
+ gtk_clist_set_shift (GTK_CLIST (clist), i, 0, 0,
+ item->level * GB_INDENT);
+ }
+
+ check_generated_handlers (menued);
+ set_interface_state (menued);
+}
+
+static void
+on_add_button_clicked (GtkWidget * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ add_item (menued, FALSE, FALSE);
+}
+
+static void
+on_add_child_button_clicked (GtkWidget * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ add_item (menued, TRUE, FALSE);
+}
+
+
+/**************************************************************************
+ *
+ **************************************************************************/
+
+static void
+on_add_separator_button_clicked (GtkWidget * button,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+ add_item (menued, FALSE, TRUE);
+}
+
+static gboolean
+on_key_press (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer user_data)
+{
+ switch (event->keyval)
+ {
+ case GDK_Delete:
+ on_delete_button_clicked (widget, NULL);
+ break;
+ }
+
+ return FALSE;
+}
+
+static void
+on_delete_button_clicked (GtkWidget * widget,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ GtkWidget *clist;
+ GbMenuItemData *item;
+ gint row, level, i;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
+ clist = menued->clist;
+ row = get_selected_row (menued);
+ if (row == -1)
+ return;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ level = item->level;
+
+ gtk_clist_remove (GTK_CLIST (clist), row);
+
+ /* Update any other items in the same radio group. */
+ if (item->type == GB_MENU_ITEM_RADIO)
+ remove_from_radio_group (menued, item);
+
+ glade_menu_editor_free_item (item);
+
+ /* Move all children up a level */
+ for (i = row; i < GTK_CLIST (clist)->rows; i++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), i);
+ if (item->level <= level)
+ break;
+ item->level--;
+ gtk_clist_set_shift (GTK_CLIST (clist), i, 0, 0,
+ item->level * GB_INDENT);
+ }
+
+ gtk_clist_select_row (GTK_CLIST (clist), row, 0);
+ set_interface_state (menued);
+}
+
+
+/**************************************************************************
+ * File Selection for selecting icon xpm files.
+ **************************************************************************/
+#define GLADE_RESPONSE_CLEAR 1
+
+static void
+on_icon_button_clicked (GtkWidget * widget,
+ gpointer user_data)
+{
+ GladeMenuEditor *menued;
+ gchar *icon;
+
+ menued = GLADE_MENU_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
+
+ if (menued->filesel == NULL)
+ {
+ menued->filesel = gtk_file_chooser_dialog_new (_("Select icon"),
+ GTK_WINDOW (menued),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_CLEAR, GLADE_RESPONSE_CLEAR,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (menued->filesel),
+ GTK_RESPONSE_OK);
+
+ g_signal_connect (menued->filesel, "response",
+ GTK_SIGNAL_FUNC (on_icon_filesel_response), menued);
+ g_signal_connect (menued->filesel, "delete_event",
+ G_CALLBACK (gtk_true), NULL);
+ }
+
+ icon = (gchar*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (menued->icon_widget)->entry));
+ if (icon && *icon)
+ glade_util_set_file_selection_filename (menued->filesel, icon);
+
+ gtk_window_present (GTK_WINDOW (menued->filesel));
+}
+
+
+static void
+on_icon_filesel_response (GtkWidget * filesel,
+ gint response_id,
+ GladeMenuEditor *menued)
+{
+ gchar *filename;
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ filename = glade_util_get_file_selection_filename (filesel);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->icon_widget)->entry),
+ filename);
+ g_free (filename);
+ }
+ else if (response_id == GLADE_RESPONSE_CLEAR)
+ {
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->icon_widget)->entry),
+ "");
+ }
+
+ glade_util_close_window (menued->filesel);
+}
+
+
+/**************************************************************************
+ * Utility functions
+ **************************************************************************/
+
+
+/* This returns the index of the currently selected row in the clist, or -1
+ if no item is currently selected. */
+static gint
+get_selected_row (GladeMenuEditor * menued)
+{
+ if (GTK_CLIST (menued->clist)->selection == NULL)
+ return -1;
+ return GPOINTER_TO_INT (GTK_CLIST (menued->clist)->selection->data);
+}
+
+/* This returns the currently selected item, or NULL if no item is currently
+ selected. */
+static GbMenuItemData*
+get_selected_item (GladeMenuEditor * menued)
+{
+ GbMenuItemData *item;
+ gint row;
+
+ row = get_selected_row (menued);
+ if (row == -1)
+ return NULL;
+ item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), row);
+ return item;
+}
+
+/* This set the sensitivity of the buttons according to the current state. */
+static void
+set_interface_state (GladeMenuEditor * menued)
+{
+ GbMenuItemData *item, *tmp_item;
+ GtkCList *clist;
+ gboolean up_button_sens = FALSE, down_button_sens = FALSE;
+ gboolean left_button_sens = FALSE, right_button_sens = FALSE;
+ gboolean add_button_sens = FALSE, delete_button_sens = FALSE;
+ gboolean state_sens = FALSE, group_sens = FALSE;
+ gboolean form_sens = FALSE, type_sens = FALSE, accel_sens = FALSE;
+ gboolean label_sens = FALSE, icon_sens = FALSE;
+ gint index;
+
+ clist = GTK_CLIST (menued->clist);
+
+ /* Figure out which of the arrow buttons should be sensitive. */
+
+ /* The Add button is always sensitive, since empty labels are separators. */
+ add_button_sens = TRUE;
+
+ /* The Delete button and the entire form are sensitive if an item is
+ selected in the clist. */
+ index = get_selected_row (menued);
+ if (index != -1)
+ {
+ form_sens = TRUE;
+ type_sens = TRUE;
+ label_sens = TRUE;
+ icon_sens = TRUE;
+ delete_button_sens = TRUE;
+
+ if (index > 0)
+ up_button_sens = TRUE;
+ if (index < clist->rows - 1)
+ down_button_sens = TRUE;
+
+ item = (GbMenuItemData *) gtk_clist_get_row_data (clist, index);
+ if (item->level > 0)
+ left_button_sens = TRUE;
+
+ /* The accelerator modifier and key are sensitive if this is not a
+ toplevel item on a menubar. */
+ if (!GTK_IS_MENU_BAR (menued->menu) || item->level != 0)
+ accel_sens = TRUE;
+
+ if (index > 0)
+ {
+ tmp_item = (GbMenuItemData *) gtk_clist_get_row_data (clist,
+ index - 1);
+ if (tmp_item->level >= item->level)
+ right_button_sens = TRUE;
+ }
+
+ /* Figure out if the radio group widgets should be sensitive. */
+ if (GTK_TOGGLE_BUTTON (menued->radio_radiobutton)->active)
+ {
+ group_sens = TRUE;
+ state_sens = TRUE;
+ icon_sens = FALSE;
+ }
+
+ if (GTK_TOGGLE_BUTTON (menued->check_radiobutton)->active)
+ {
+ state_sens = TRUE;
+ icon_sens = FALSE;
+ }
+
+ if (item->stock_item_index)
+ {
+ /* For the 'New' menu item, a label and tooltip must be provided. */
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ if (item->stock_item_index != GladeStockMenuItemNew)
+ label_sens = FALSE;
+#endif
+ }
+ else
+ {
+ /* We don't allow the "New" label to be changed for GTK+ stock
+ items now, to be compatable with libglade. It did make it a
+ bit too complicated anyway. */
+#if 0
+ const char *stock_id = g_slist_nth_data (menued->stock_items,
+ item->stock_item_index - 1);
+ if (strcmp (stock_id, GTK_STOCK_NEW))
+#endif
+ label_sens = FALSE;
+ }
+
+ icon_sens = FALSE;
+ type_sens = FALSE;
+ accel_sens = FALSE;
+ }
+ }
+
+ /* Now set the sensitivity of the widgets. */
+ gtk_widget_set_sensitive (menued->stock_label, form_sens);
+ gtk_widget_set_sensitive (menued->stock_combo, form_sens);
+
+ gtk_widget_set_sensitive (menued->icon_label, icon_sens);
+ gtk_widget_set_sensitive (menued->icon_widget, icon_sens);
+ gtk_widget_set_sensitive (menued->icon_button, icon_sens);
+
+ gtk_widget_set_sensitive (menued->name_label, form_sens);
+ gtk_widget_set_sensitive (menued->name_entry, form_sens);
+ gtk_widget_set_sensitive (menued->handler_label, form_sens);
+ gtk_widget_set_sensitive (menued->handler_entry, form_sens);
+
+ gtk_widget_set_sensitive (menued->label_label, label_sens);
+ gtk_widget_set_sensitive (menued->label_entry, label_sens);
+ gtk_widget_set_sensitive (menued->tooltip_label, label_sens);
+ gtk_widget_set_sensitive (menued->tooltip_entry, label_sens);
+
+ gtk_widget_set_sensitive (menued->add_button, add_button_sens);
+ gtk_widget_set_sensitive (menued->add_separator_button, add_button_sens);
+ gtk_widget_set_sensitive (menued->delete_button, delete_button_sens);
+
+ gtk_widget_set_sensitive (menued->type_frame, type_sens);
+ gtk_widget_set_sensitive (menued->state_label, state_sens);
+ gtk_widget_set_sensitive (menued->state_togglebutton, state_sens);
+ gtk_widget_set_sensitive (menued->group_label, group_sens);
+ gtk_widget_set_sensitive (menued->group_combo, group_sens);
+
+ gtk_widget_set_sensitive (menued->accel_frame, accel_sens);
+}
+
+
+/* This gets a string representing the accelerator key + modifiers.
+ It returns a pointer to a static buffer. */
+static gchar *
+get_accel_string (gchar * key, guint8 modifiers)
+{
+ static gchar buffer[32];
+
+ buffer[0] = '\0';
+ if (modifiers & GDK_CONTROL_MASK)
+ strcat (buffer, "C+");
+ if (modifiers & GDK_SHIFT_MASK)
+ strcat (buffer, "S+");
+ if (modifiers & GDK_MOD1_MASK)
+ strcat (buffer, "A+");
+ if (key)
+ strcat (buffer, key);
+ return buffer;
+}
+
+
+static gchar*
+get_stock_item_label (GladeMenuEditor * menued, gint stock_item_index)
+{
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ /* Most of the label text is from Gnome, but 2 of them are ours,
+ so we use a utility function to find the translation. */
+ return glade_gnome_gettext (GladeStockMenuItemValues[stock_item_index].label);
+#else
+ /* This shouldn't happen. */
+ g_warning ("Trying to use GNOME stock items in GTK+ version of Glade");
+ return NULL;
+#endif
+ }
+ else
+ {
+ gchar *stock_id;
+
+ if (stock_item_index <= 0)
+ return _("None");
+
+ stock_id = g_slist_nth_data (menued->stock_items, stock_item_index - 1);
+ return stock_id;
+
+#if 0
+ GtkStockItem item;
+ gtk_stock_lookup (stock_id, &item);
+ return item.label;
+#endif
+ }
+}
+
+
+/* This shows the properties of the item currently selected in the clist. */
+static void
+show_item_properties (GladeMenuEditor * menued)
+{
+ GbMenuItemData *item;
+ GtkWidget *clist;
+
+ clist = menued->clist;
+ item = get_selected_item (menued);
+ if (item == NULL)
+ return;
+
+ menued->updating_widgets = TRUE;
+
+ /* Now set them to the item's properties. */
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->stock_combo)->entry),
+ get_stock_item_label (menued, item->stock_item_index));
+#if 0
+ g_print ("Setting label_entry to: %s\n", item->label);
+#endif
+ set_entry_text (GTK_ENTRY (menued->label_entry), item->label);
+#if 0
+ g_print ("Setting name_entry to: %s\n", item->name);
+#endif
+ set_entry_text (GTK_ENTRY (menued->name_entry), item->name);
+#if 0
+ g_print ("Setting handler_entry to: %s\n", item->handler);
+#endif
+ set_entry_text (GTK_ENTRY (menued->handler_entry), item->handler);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->icon_widget)->entry),
+ item->icon);
+ set_entry_text (GTK_ENTRY (menued->tooltip_entry), item->tooltip);
+
+ if (item->type == GB_MENU_ITEM_NORMAL)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->normal_radiobutton), TRUE);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->group_combo)->entry), "");
+ }
+ else if (item->type == GB_MENU_ITEM_CHECK)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->check_radiobutton), TRUE);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->group_combo)->entry), "");
+ }
+ else
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->radio_radiobutton), TRUE);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->group_combo)->entry),
+ item->group ? item->group->name : item->name);
+ }
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->state_togglebutton), item->active);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_ctrl_checkbutton), (item->modifiers & GDK_CONTROL_MASK) ? TRUE : FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_shift_checkbutton), (item->modifiers & GDK_SHIFT_MASK) ? TRUE : FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_alt_checkbutton), (item->modifiers & GDK_MOD1_MASK) ? TRUE : FALSE);
+ set_entry_text (GTK_ENTRY (menued->accel_key_entry),
+ item->key ? item->key : "");
+
+ update_radio_groups (menued);
+
+ menued->updating_widgets = FALSE;
+}
+
+/* This adds a new menuitem. If separator is FALSE, it adds a normal item
+ with the label 'New Item'. If separator is TRUE it adds a separator.
+ It is added to the clist beneath the currently selected item, or at the
+ end of the list if no item is selected. If as_child is TRUE it adds the
+ item as a child of the selected item, else it adds it as a sibling.
+*/
+static void
+add_item (GladeMenuEditor * menued,
+ gboolean as_child,
+ gboolean separator)
+{
+ GbMenuItemData *item, *selected_item;
+ GtkWidget *clist;
+ gint row;
+
+ item = g_new0 (GbMenuItemData, 1);
+ item->stock_item_index = 0;
+ if (separator)
+ {
+ item->label = NULL;
+ item->name = glade_project_new_widget_name (menued->project,
+ _("separator"));
+ }
+ else
+ {
+ item->label = glade_project_new_widget_name (menued->project, "item");
+ item->name = g_strdup (item->label);
+ }
+ item->handler = generate_handler (menued, -1, item->label, item->name);
+ /* This is a flag to indicate that the last_mod_time should be set when
+ the 'Apply' button is clicked. */
+ item->last_mod_time = (time_t) -2;
+ item->icon = NULL;
+ item->tooltip = NULL;
+ item->type = GB_MENU_ITEM_NORMAL;
+ item->active = FALSE;
+ item->group = NULL;
+ item->modifiers = 0;
+ item->key = NULL;
+ item->level = 0;
+ item->generate_name = TRUE;
+ item->generate_handler = TRUE;
+
+ clist = menued->clist;
+ row = get_selected_row (menued);
+ if (row != -1)
+ {
+ selected_item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ item->level = selected_item->level + (as_child ? 1 : 0);
+ insert_item (GTK_CLIST (clist), item, row + 1);
+ gtk_clist_select_row (GTK_CLIST (clist), row + 1, 0);
+ ensure_visible (clist, row + 1);
+ }
+ else
+ {
+ item->level = 0;
+ insert_item (GTK_CLIST (clist), item, -1);
+ gtk_clist_select_row (GTK_CLIST (clist), GTK_CLIST (clist)->rows - 1, 0);
+ ensure_visible (clist, GTK_CLIST (clist)->rows - 1);
+ }
+
+ set_interface_state (menued);
+ gtk_widget_grab_focus (menued->label_entry);
+ gtk_editable_select_region (GTK_EDITABLE (menued->label_entry), 0, -1);
+}
+
+/* This adds the item to the clist at the given position. */
+static void
+insert_item (GtkCList * clist, GbMenuItemData * item, gint row)
+{
+ gchar *rowdata[GB_MENUED_NUM_COLS];
+
+ /* Empty labels are understood to be separators. */
+ if (item->label && strlen (item->label) > 0)
+ rowdata[GLD_COL_LABEL] = item->label;
+ else
+ rowdata[GLD_COL_LABEL] = GB_SEPARATOR_TEXT;
+ if (item->type == GB_MENU_ITEM_NORMAL)
+ rowdata[GLD_COL_TYPE] = "";
+ else if (item->type == GB_MENU_ITEM_CHECK)
+ rowdata[GLD_COL_TYPE] = _("Check");
+ else if (item->type == GB_MENU_ITEM_RADIO)
+ rowdata[GLD_COL_TYPE] = _("Radio");
+ rowdata[GLD_COL_ACCEL] = get_accel_string (item->key, item->modifiers);
+ rowdata[GLD_COL_NAME] = item->name ? item->name : "";
+ rowdata[GLD_COL_HANDLER] = item->handler ? item->handler : "";
+ rowdata[GLD_COL_ICON] = item->icon ? item->icon : "";
+ rowdata[GLD_COL_ACTIVE] = item->active ? _("Yes") : "";
+ rowdata[GLD_COL_GROUP] = item->group ? item->group->name : item->name;
+ if (item->type != GB_MENU_ITEM_RADIO || !rowdata[GLD_COL_GROUP])
+ rowdata[GLD_COL_GROUP] = "";
+
+ if (row >= 0)
+ gtk_clist_insert (clist, row, rowdata);
+ else
+ row = gtk_clist_append (GTK_CLIST (clist), rowdata);
+
+ gtk_clist_set_row_data (GTK_CLIST (clist), row, item);
+ gtk_clist_set_shift (GTK_CLIST (clist), row, 0, 0, item->level * GB_INDENT);
+}
+
+/* This makes sure the given row is visible. */
+static void
+ensure_visible (GtkWidget *clist,
+ gint row)
+{
+ if (gtk_clist_row_is_visible (GTK_CLIST (clist), row)
+ != GTK_VISIBILITY_FULL)
+ gtk_clist_moveto(GTK_CLIST(clist), row, -1, 0.5, 0);
+}
+
+
+static GbMenuItemData*
+find_group_item (GladeMenuEditor * menued, char *group_name)
+{
+ gint rows, row;
+
+ if (!group_name || !group_name[0])
+ return NULL;
+
+ rows = GTK_CLIST (menued->clist)->rows;
+
+ for (row = 0; row < rows; row++)
+ {
+ GbMenuItemData *item;
+ item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), row);
+
+ if (item->name && !strcmp (item->name, group_name))
+ return item;
+ }
+
+ return NULL;
+}
+
+
+/* This updates the currently selected item in the clist, updating each field
+ if it is different to the settings in the form elements. */
+static void
+update_current_item (GladeMenuEditor * menued)
+{
+ GbMenuItemData *item, *group_item;
+ GtkCList *clist;
+ gchar *name, *label, *handler, *tooltip, *group_name, *key;
+ gchar *icon;
+ GbMenuItemType type;
+ gint row;
+ guint8 modifiers;
+ gboolean active, update_accelerator = FALSE;
+
+ clist = GTK_CLIST (menued->clist);
+ row = get_selected_row (menued);
+ if (row == -1)
+ return;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (menued->clist),
+ row);
+
+ name = (gchar*) gtk_entry_get_text (GTK_ENTRY (menued->name_entry));
+ if (item_property_changed (name, item->name))
+ {
+ g_free (item->name);
+ item->name = copy_item_property (name);
+ gtk_clist_set_text (clist, row, GLD_COL_NAME,
+ item->name ? item->name : "");
+ }
+
+ label = (gchar*) gtk_entry_get_text (GTK_ENTRY (menued->label_entry));
+ if (item_property_changed (label, item->label))
+ {
+ g_free (item->label);
+ item->label = copy_item_property (label);
+ gtk_clist_set_text (clist, row, GLD_COL_LABEL,
+ item->label ? item->label : GB_SEPARATOR_TEXT);
+ }
+
+ handler = (gchar*) gtk_entry_get_text (GTK_ENTRY (menued->handler_entry));
+ if (item_property_changed (handler, item->handler))
+ {
+ g_free (item->handler);
+ item->handler = copy_item_property (handler);
+ gtk_clist_set_text (clist, row, GLD_COL_HANDLER,
+ item->handler ? item->handler : "");
+
+ /* This is a flag to indicate that the last_mod_time should be set when
+ the 'Apply' button is clicked. */
+ item->last_mod_time = (time_t) -2;
+ }
+
+ icon = (gchar*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (menued->icon_widget)->entry));
+ if (item_property_changed (icon, item->icon))
+ {
+ g_free (item->icon);
+ item->icon = copy_item_property (icon);
+ gtk_clist_set_text (clist, row, GLD_COL_ICON,
+ item->icon ? item->icon : "");
+ }
+
+ tooltip = (gchar*) gtk_entry_get_text (GTK_ENTRY (menued->tooltip_entry));
+ if (item_property_changed (tooltip, item->tooltip))
+ {
+ g_free (item->tooltip);
+ item->tooltip = copy_item_property (tooltip);
+ }
+
+ if (GTK_TOGGLE_BUTTON (menued->normal_radiobutton)->active)
+ type = GB_MENU_ITEM_NORMAL;
+ else if (GTK_TOGGLE_BUTTON (menued->check_radiobutton)->active)
+ type = GB_MENU_ITEM_CHECK;
+ else
+ type = GB_MENU_ITEM_RADIO;
+ if (item->type != type)
+ {
+ /* If the item is changing from a radio item to something else, make
+ sure other items in the same group no longer point to it. */
+ if (item->type == GB_MENU_ITEM_RADIO)
+ remove_from_radio_group (menued, item);
+
+ item->type = type;
+ if (type == GB_MENU_ITEM_NORMAL)
+ gtk_clist_set_text (clist, row, GLD_COL_TYPE, "");
+ else if (type == GB_MENU_ITEM_CHECK)
+ gtk_clist_set_text (clist, row, GLD_COL_TYPE, _("Check"));
+ else if (type == GB_MENU_ITEM_RADIO)
+ gtk_clist_set_text (clist, row, GLD_COL_TYPE, _("Radio"));
+ }
+
+ active = GTK_TOGGLE_BUTTON (menued->state_togglebutton)->active
+ ? TRUE : FALSE;
+ if (active != item->active)
+ {
+ item->active = active;
+ gtk_clist_set_text (clist, row, GLD_COL_ACTIVE, active ? _("Yes") : "");
+ }
+
+ group_name = (gchar*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (menued->group_combo)->entry));
+ group_item = find_group_item (menued, group_name);
+ if (group_item != item->group)
+ {
+ char *group_text = group_item ? group_item->name : item->name;
+ if (item->type != GB_MENU_ITEM_RADIO)
+ group_text = NULL;
+ item->group = group_item;
+ gtk_clist_set_text (clist, row, GLD_COL_GROUP,
+ group_text ? group_text : "");
+ }
+
+ key = (gchar*) gtk_entry_get_text (GTK_ENTRY (menued->accel_key_entry));
+ if (item_property_changed (key, item->key))
+ {
+ g_free (item->key);
+ item->key = copy_item_property (key);
+ update_accelerator = TRUE;
+ }
+
+ modifiers = 0;
+ if (GTK_TOGGLE_BUTTON (menued->accel_ctrl_checkbutton)->active)
+ modifiers |= GDK_CONTROL_MASK;
+ if (GTK_TOGGLE_BUTTON (menued->accel_shift_checkbutton)->active)
+ modifiers |= GDK_SHIFT_MASK;
+ if (GTK_TOGGLE_BUTTON (menued->accel_alt_checkbutton)->active)
+ modifiers |= GDK_MOD1_MASK;
+ if (modifiers != item->modifiers)
+ {
+ item->modifiers = modifiers;
+ update_accelerator = TRUE;
+ }
+
+ if (update_accelerator)
+ gtk_clist_set_text (clist, row, GLD_COL_ACCEL,
+ get_accel_string (item->key, item->modifiers));
+
+ set_interface_state (menued);
+}
+
+/* This checks if the new value is different to the old, but an empty string
+ in new is taken to be equal to NULL as well. */
+static gboolean
+item_property_changed (gchar *new, gchar *old)
+{
+ if (old == NULL)
+ return (new == NULL || new[0] == '\0') ? FALSE : TRUE;
+ if (new == NULL)
+ return TRUE;
+ if (!strcmp (old, new))
+ return FALSE;
+ return TRUE;
+}
+
+/* This returns a copy of the given property string, or NULL if it is an
+ empty string. */
+static gchar*
+copy_item_property (gchar *property)
+{
+ if (property[0] == '\0')
+ return NULL;
+ return g_strdup (property);
+}
+
+
+/* This clears the form, ready to add a new item. If full is TRUE it resets
+ the type checkbuttons, group and accelerator modifiers. When adding items
+ full is set to FALSE so the user can add several items of the same type. */
+static void
+clear_form (GladeMenuEditor * menued,
+ gboolean full)
+{
+ gtk_list_select_item (GTK_LIST (GTK_COMBO (menued->stock_combo)->list), 0);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->icon_widget)->entry), "");
+ set_entry_text (GTK_ENTRY (menued->label_entry), "");
+ set_entry_text (GTK_ENTRY (menued->name_entry), "");
+ set_entry_text (GTK_ENTRY (menued->handler_entry), "");
+ set_entry_text (GTK_ENTRY (menued->tooltip_entry), "");
+ set_entry_text (GTK_ENTRY (menued->accel_key_entry), "");
+
+ if (full)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->normal_radiobutton), TRUE);
+ set_entry_text (GTK_ENTRY (GTK_COMBO (menued->group_combo)->entry),
+ "");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_ctrl_checkbutton), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_shift_checkbutton), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menued->accel_alt_checkbutton), FALSE);
+ }
+}
+
+
+/* This removes an item and its children from the clist, and returns a list
+ of the removed items. */
+static GList *
+remove_item_and_children (GtkWidget * clist,
+ gint row)
+{
+ GList *items = NULL;
+ GbMenuItemData *item;
+ gint level;
+
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ level = item->level;
+ items = g_list_append (items, item);
+ gtk_clist_remove (GTK_CLIST (clist), row);
+
+ while (row < GTK_CLIST (clist)->rows)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ if (item->level > level)
+ {
+ items = g_list_append (items, item);
+ gtk_clist_remove (GTK_CLIST (clist), row);
+ }
+ else
+ break;
+ }
+ return items;
+}
+
+/* This inserts the given list of items at the given position in the clist. */
+static void
+insert_items (GtkWidget * clist,
+ GList * items,
+ gint row)
+{
+ GbMenuItemData *item;
+
+ while (items)
+ {
+ item = (GbMenuItemData *) items->data;
+ insert_item (GTK_CLIST (clist), item, row++);
+ items = items->next;
+ }
+}
+
+
+/* This returns the default name of the widget, given its label. The returned
+ string should be freed at some point. */
+static gchar*
+generate_name (GladeMenuEditor *menued,
+ gchar *label)
+{
+ gchar *prefix, *name, *src, *dest;
+
+ /* For empty labels, i.e. separators, use 'separator'. */
+ if (label == NULL || label[0] == '\0')
+ {
+ return glade_project_new_widget_name (menued->project, _("separator"));
+ }
+
+ prefix = g_malloc (strlen (label) + 1);
+ /* Convert spaces to underscores, and ignore periods (e.g. in "Open...")
+ and underscores (e.g. in "_Open"). */
+ for (src = label, dest = prefix; *src; src++)
+ {
+ if (*src == ' ')
+ *dest++ = '_';
+ else if (*src == '.')
+ continue;
+ else if (*src == '_')
+ continue;
+ else
+ *dest++ = *src;
+ }
+ *dest = '\0';
+
+ if (dest >= prefix + strlen (label) + 1)
+ g_warning ("Buffer overflow");
+
+ /* Get rid of any trailing digits. */
+ dest--;
+ while (*dest >= '0' && *dest <= '9')
+ {
+ *dest = '\0';
+ dest--;
+ }
+
+ name = glade_project_new_widget_name (menued->project, prefix);
+ g_free (prefix);
+
+ return name;
+}
+
+/* This returns the default 'activate' handler name, given the name of the
+ item. The returned string should be freed at some point. */
+static gchar*
+generate_handler (GladeMenuEditor *menued, gint row, gchar *label, gchar *name)
+{
+ gchar *handler, *start = "on_", *end = "_activate";
+
+ /* For empty labels, i.e. separators, and items with submenus, there is no
+ handler by default. */
+ if (label == NULL || label[0] == '\0' || is_parent (menued, row))
+ return NULL;
+
+ handler = g_malloc (strlen (name) + strlen (start) + strlen (end) + 1);
+ strcpy (handler, start);
+ strcat (handler, name);
+ strcat (handler, end);
+
+ return handler;
+}
+
+
+/* This makes sure the default handlers are updated as items are moved around.
+ */
+static void
+check_generated_handlers (GladeMenuEditor *menued)
+{
+ GtkCList *clist;
+ GbMenuItemData *item;
+ gint row;
+ gchar *handler;
+
+ clist = GTK_CLIST (menued->clist);
+ for (row = 0; row < clist->rows; row++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (clist, row);
+ if (item->generate_handler)
+ {
+ handler = generate_handler (menued, row, item->label, item->name);
+ if (item_property_changed (handler, item->handler))
+ {
+ g_free (item->handler);
+ item->handler = handler;
+ gtk_clist_set_text (clist, row, GLD_COL_HANDLER, handler);
+ }
+ else
+ {
+ g_free (handler);
+ }
+ }
+ }
+}
+
+
+/* This returns TRUE id the item in the given row is a parent, or FALSE
+ if the row doesn't exist or isn't a parent. */
+static gboolean
+is_parent (GladeMenuEditor *menued,
+ gint row)
+{
+ GtkCList *clist;
+ GbMenuItemData *item, *next_item;
+
+ clist = GTK_CLIST (menued->clist);
+ if (row < 0 || row >= clist->rows - 1)
+ return FALSE;
+ item = (GbMenuItemData *) gtk_clist_get_row_data (clist, row);
+ next_item = (GbMenuItemData *) gtk_clist_get_row_data (clist, row + 1);
+ if (next_item->level > item->level)
+ return TRUE;
+ return FALSE;
+}
+
+
+static void
+on_menu_editor_ok (GtkWidget *button,
+ GladeMenuEditor *menued)
+{
+ glade_menu_editor_update_menu (menued);
+ gtk_widget_destroy (GTK_WIDGET (menued));
+}
+
+static void
+on_menu_editor_apply (GtkWidget *button,
+ GladeMenuEditor *menued)
+{
+ glade_menu_editor_update_menu (menued);
+}
+
+
+static void
+on_menu_editor_close (GtkWidget *widget,
+ GladeMenuEditor *menued)
+{
+ gtk_widget_destroy (GTK_WIDGET (menued));
+}
+
+
+/**************************************************************************
+ * Public functions
+ **************************************************************************/
+
+/* This checks if the given icon string is a stock icon name, and if it is
+ it returns the stock ID instead. If not, it just returns the icon. */
+static gchar*
+get_stock_id_from_icon_name (GladeMenuEditor *menued,
+ gchar *icon)
+{
+ if (!icon || *icon == '\0')
+ return NULL;
+
+ /* We use the stock id instead of the text now, so we don't need this. */
+#if 0
+ GList *clist;
+
+ clist = GTK_LIST (GTK_COMBO (menued->icon_widget)->list)->children;
+
+ while (clist && clist->data)
+ {
+ gchar* ltext = glade_util_gtk_combo_func (GTK_LIST_ITEM (clist->data));
+ if (!ltext)
+ continue;
+ if (!strcmp (ltext, icon))
+ {
+ gchar *stock_id = gtk_object_get_data (GTK_OBJECT (clist->data),
+ GladeMenuEditorStockIDKey);
+ return stock_id;
+ }
+ clist = clist->next;
+ }
+#endif
+
+ return icon;
+}
+
+
+/* This updates the menu, based on the settings in the menu editor.
+ It removes all the current children of the menu and recreates it.
+ Note that it has to reload all the xpm files for pixmaps, so its not
+ very efficient, but they're small so it shouldn't be too bad. */
+static void
+glade_menu_editor_update_menu (GladeMenuEditor *menued)
+{
+ GbMenuItemData *item;
+ GtkWidget *menuitem, *label, *prev_item = NULL, *child_menu;
+ GtkCList *clist;
+ GtkMenuShell *current_menu;
+ GList *menus;
+ GHashTable *group_hash;
+ gchar *child_name;
+ gint i, level;
+ GbWidget *gbwidget;
+ GladeWidgetData *wdata;
+ GtkAccelGroup *accel_group;
+ GtkWidget *pixmap = NULL;
+ gboolean use_pixmap_menu_item;
+ gchar *stock_id, *icon_name;
+#ifdef USE_GNOME
+ GnomeUIInfo *uiinfo = NULL;
+#endif
+
+ /* Remove existing children of the menu. Note that this will result in the
+ old widget names being released, so we need to reserve the new names,
+ even if they are the same. */
+ while (menued->menu->children)
+ {
+ menuitem = menued->menu->children->data;
+ gtk_widget_destroy (menuitem);
+ }
+
+ /* FIXME: This seems to be necessary to re-initialise the menu. I don't know
+ why. */
+ menued->menu->menu_flag = TRUE;
+
+ clist = GTK_CLIST (menued->clist);
+
+ /* Now reserve all the the new widget names. */
+ for (i = 0; i < clist->rows; i++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (clist, i);
+
+ if (item->name && item->name[0])
+ glade_project_reserve_name (menued->project, item->name);
+ }
+
+ /* Now add widgets according to the items in the menu editor clist. */
+ level = 0;
+ menus = g_list_append (NULL, menued->menu);
+ group_hash = g_hash_table_new (NULL, NULL);
+
+ /* Make sure all items in the group point to the first one. */
+ normalize_radio_groups (menued);
+
+ for (i = 0; i < clist->rows; i++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (clist, i);
+
+ icon_name = get_stock_id_from_icon_name (menued, item->icon);
+ stock_id = NULL;
+
+ if (item->level > level)
+ {
+ child_menu = gb_widget_new_full ("GtkMenu", FALSE, NULL, NULL, 0, 0,
+ NULL, GB_CREATING, NULL);
+ child_name = g_strdup_printf ("%s_menu", prev_item->name);
+ gtk_widget_set_name (child_menu, child_name);
+ g_free (child_name);
+ level = item->level;
+ /* We use the menus GList as a stack, pushing menus onto the
+ front. */
+ menus = g_list_prepend (menus, child_menu);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (prev_item), child_menu);
+ tree_add_widget (child_menu);
+ }
+ while (item->level < level)
+ {
+ /* This removes/pops the first menu in the list. */
+ menus = g_list_remove_link (menus, menus);
+ level--;
+ }
+ current_menu = GTK_MENU_SHELL (menus->data);
+
+ pixmap = NULL;
+ if (item->label && strlen (item->label) > 0)
+ {
+ label = gtk_accel_label_new ("");
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label), item->label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+
+ use_pixmap_menu_item = FALSE;
+
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ if (item->stock_item_index)
+ {
+ uiinfo = &GladeStockMenuItemValues[item->stock_item_index];
+ if (uiinfo->pixmap_type == GNOME_APP_PIXMAP_STOCK)
+ {
+ pixmap = gtk_image_new_from_stock (uiinfo->pixmap_info,
+ GTK_ICON_SIZE_MENU);
+ use_pixmap_menu_item = TRUE;
+ }
+ }
+#endif
+ }
+ else
+ {
+ if (item->stock_item_index)
+ {
+ stock_id = g_slist_nth_data (menued->stock_items,
+ item->stock_item_index - 1);
+#if 0
+ g_print ("Stock ID for icon: %s\n", stock_id);
+#endif
+ pixmap = gtk_image_new_from_stock (stock_id,
+ GTK_ICON_SIZE_MENU);
+ use_pixmap_menu_item = TRUE;
+ }
+ }
+
+ if (!item->stock_item_index && icon_name)
+ {
+ pixmap = gb_widget_new ("GtkImage", NULL);
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ gtk_image_set_from_stock (GTK_IMAGE (pixmap), icon_name,
+ GTK_ICON_SIZE_MENU);
+ }
+ else
+ {
+ gtk_image_set_from_file (GTK_IMAGE (pixmap), icon_name);
+
+ /* Add the pixmap to the project, so the file is copied.
+ It should be removed from the project in the menuitem
+ GbWidget.destroy function. */
+ glade_project_add_pixmap (menued->project, icon_name);
+ }
+ gb_widget_set_child_name (pixmap, GladeChildMenuItemImage);
+ use_pixmap_menu_item = TRUE;
+ }
+
+ if (item->type == GB_MENU_ITEM_NORMAL)
+ {
+ if (use_pixmap_menu_item)
+ {
+ menuitem = gtk_image_menu_item_new ();
+ if (pixmap)
+ {
+ gtk_widget_show (pixmap);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ pixmap);
+ }
+ }
+ else
+ {
+ menuitem = gtk_menu_item_new ();
+ }
+ gtk_container_add (GTK_CONTAINER (menuitem), label);
+ }
+ else if (item->type == GB_MENU_ITEM_CHECK)
+ {
+ menuitem = gtk_check_menu_item_new ();
+ if (item->active)
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ TRUE);
+ gtk_container_add (GTK_CONTAINER (menuitem), label);
+ }
+ else
+ {
+ menuitem = create_radio_menu_item (current_menu,
+ item, group_hash);
+ if (item->active)
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ TRUE);
+ gtk_container_add (GTK_CONTAINER (menuitem), label);
+ }
+
+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), menuitem);
+ }
+ else
+ {
+ /* This creates a separator. */
+ menuitem = gtk_separator_menu_item_new ();
+ }
+ gtk_widget_show (menuitem);
+
+ /* Save the stock name and icon in the menuitem. */
+ if (item->stock_item_index)
+ {
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ gtk_object_set_data (GTK_OBJECT (menuitem),
+ GladeMenuItemStockIndexKey,
+ GINT_TO_POINTER (item->stock_item_index));
+#endif
+ }
+ else
+ {
+ gchar *stock_id;
+
+ stock_id = g_slist_nth_data (menued->stock_items,
+ item->stock_item_index - 1);
+
+ gtk_object_set_data_full (GTK_OBJECT (menuitem),
+ GladeMenuItemStockIDKey,
+ g_strdup (stock_id),
+ g_free);
+ }
+ }
+ else if (item->icon && pixmap)
+ {
+ gtk_object_set_data_full (GTK_OBJECT (pixmap), GladeIconKey,
+ g_strdup (icon_name), g_free);
+ }
+
+
+ /* Turn it into a GbWidget, and add the 'activate' handler and the
+ accelerator. */
+ if (item->name == NULL || item->name[0] == '\0')
+ {
+ g_free (item->name);
+ item->name = glade_project_new_widget_name (menued->project, "item");
+ }
+
+ gbwidget = gb_widget_lookup_class (gtk_type_name (GTK_OBJECT_TYPE (menuitem)));
+
+ if (item->wdata)
+ wdata = glade_widget_data_copy (item->wdata);
+ else
+ wdata = glade_widget_data_new (gbwidget);
+
+ wdata->gbwidget = gbwidget;
+
+ gb_widget_create_from_full (menuitem, NULL, wdata);
+ gtk_widget_set_name (menuitem, item->name);
+
+ if (item->active)
+ wdata->flags |= GLADE_ACTIVE;
+ else
+ wdata->flags &= ~GLADE_ACTIVE;
+
+ g_free (wdata->tooltip);
+ wdata->tooltip = g_strdup (item->tooltip);
+ /* FIXME: Should set tooltip? Or for Gnome install in appbar? */
+
+ if (item->handler && strlen (item->handler) > 0)
+ {
+ GladeSignal *signal = g_new (GladeSignal, 1);
+ signal->name = g_strdup ("activate");
+ signal->handler = g_strdup (item->handler);
+ signal->object = NULL;
+ signal->after = FALSE;
+ signal->data = NULL;
+
+ /* If the last mod time is set to the special value, we set it to
+ the current time now. */
+ if (item->last_mod_time == (time_t) -2) {
+ item->last_mod_time = time (NULL);
+ if (item->last_mod_time == (time_t) -1)
+ g_warning ("Can't get current time");
+ }
+
+ signal->last_modification_time = item->last_mod_time;
+ wdata->signals = g_list_append (wdata->signals, signal);
+ }
+
+ if (item->key && strlen (item->key) > 0)
+ {
+ GladeAccelerator *accel = g_new (GladeAccelerator, 1);
+ guint key;
+ accel->modifiers = item->modifiers;
+ accel->key = g_strdup (item->key);
+ accel->signal = g_strdup ("activate");
+ wdata->accelerators = g_list_append (wdata->accelerators, accel);
+
+ /* We can only add accelerators to menus, not menubars. */
+ if (GTK_IS_MENU (current_menu))
+ {
+ key = glade_keys_dialog_find_key (item->key);
+ accel_group = GTK_MENU (current_menu)->accel_group;
+ gtk_widget_add_accelerator (menuitem, "activate", accel_group,
+ key, item->modifiers,
+ GTK_ACCEL_VISIBLE);
+ }
+ }
+
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ /* For stock menu items, we use the configured accelerator keys. */
+ if (GTK_IS_MENU (current_menu)
+ && item->stock_item_index && uiinfo->accelerator_key != 0)
+ {
+ accel_group = GTK_MENU (current_menu)->accel_group;
+ gtk_widget_add_accelerator (menuitem, "activate", accel_group,
+ uiinfo->accelerator_key,
+ uiinfo->ac_mods,
+ GTK_ACCEL_VISIBLE);
+ }
+#endif
+ }
+ else
+ {
+ /* For stock menu items, we use the configured accelerator keys. */
+ if (GTK_IS_MENU (current_menu) && item->stock_item_index && stock_id)
+ {
+ GtkStockItem item;
+
+ gtk_stock_lookup (stock_id, &item);
+ if (item.keyval)
+ {
+ accel_group = GTK_MENU (current_menu)->accel_group;
+ gtk_widget_add_accelerator (menuitem, "activate",
+ accel_group,
+ item.keyval, item.modifier,
+ GTK_ACCEL_VISIBLE);
+ }
+ }
+ }
+
+ /* Add the menuitem to the current menu. */
+ gtk_menu_shell_append (current_menu, menuitem);
+ tree_add_widget (menuitem);
+ prev_item = menuitem;
+ }
+ g_list_free (menus);
+ g_hash_table_destroy (group_hash);
+
+ /* Make sure the displayed item is correct. */
+ show_item_properties (menued);
+}
+
+
+/* This creates a radio menu item using the appropriate radio group.
+ If the item's group is not NULL and doesn't points to the item itself,
+ then it will search the list of groups to find the group. If it can't find
+ a group, or it didn't have one it creates a new group.
+ If it creates a new group it adds this item to the list of groups. */
+static GtkWidget*
+create_radio_menu_item (GtkMenuShell *menu,
+ GbMenuItemData *item,
+ GHashTable *group_hash)
+{
+ GtkWidget *menuitem;
+ GSList *group = NULL;
+
+ if (item->group && item->group != item)
+ {
+ GtkRadioMenuItem *group_widget = g_hash_table_lookup (group_hash,
+ item->group);
+ if (group_widget)
+ group = gtk_radio_menu_item_get_group (group_widget);
+ }
+
+ menuitem = gtk_radio_menu_item_new (group);
+ if (!group)
+ g_hash_table_insert (group_hash, item, menuitem);
+
+ return menuitem;
+}
+
+
+static void
+glade_menu_editor_on_menu_destroyed (GtkWidget *menu,
+ GtkWidget *menued)
+{
+ gtk_widget_destroy (menued);
+}
+
+
+/* This converts the given menu/menubar into the list of items displayed in
+ the menu editor. */
+static void
+glade_menu_editor_set_menu (GladeMenuEditor *menued,
+ GtkMenuShell *menu)
+{
+ /* First clear any current items and radio groups. */
+ glade_menu_editor_reset (menued);
+
+ /* Connect to the destroy signal of the menu widget, so we can destroy the
+ menu editor when the widget is destroyed. */
+ menued->menu_destroy_handler_id = gtk_signal_connect (GTK_OBJECT (menu),
+ "destroy",
+ GTK_SIGNAL_FUNC (glade_menu_editor_on_menu_destroyed),
+ menued);
+
+ /* Now add each of the menus/menuitems in the given menu. */
+ menued->menu = menu;
+
+ set_submenu (menued, menu, 0);
+}
+
+
+/* This checks if the given icon_name is a stock ID, and if it is it returns
+ the text to display instead. If not, it returns icon_name. */
+static gchar*
+get_icon_name_from_stock_id (GladeMenuEditor *menued,
+ gchar *icon_name)
+{
+ /* We use the stock id instead of the text now. */
+#if 0
+ GtkStockItem item;
+ if (icon_name && gtk_stock_lookup (icon_name, &item))
+ return item.label;
+ else
+#endif
+
+ return icon_name;
+}
+
+
+/* This recursively adds menus. */
+static void
+set_submenu (GladeMenuEditor *menued,
+ GtkMenuShell *menu,
+ gint level)
+{
+ GbMenuItemData *item;
+ GtkWidget *menuitem, *label;
+ GList *child, *tmp_list;
+ GladeWidgetData *wdata;
+ gchar *icon_name;
+ GList *groups = NULL;
+
+ child = menu->children;
+ while (child)
+ {
+ menuitem = GTK_WIDGET (child->data);
+
+ if (!GTK_IS_MENU_ITEM (menuitem))
+ {
+ g_warning ("Menu widget is not a menu item");
+ child = child->next;
+ continue;
+ }
+ /* FIXME: We can't handle tearoff menuitems at present. */
+ if (GTK_IS_TEAROFF_MENU_ITEM (menuitem))
+ {
+ child = child->next;
+ continue;
+ }
+
+ wdata = (GladeWidgetData*) gtk_object_get_data (GTK_OBJECT(menuitem),
+ GB_WIDGET_DATA_KEY);
+ if (wdata == NULL)
+ {
+ g_warning ("Menu widget has no GladeWidgetData");
+ child = child->next;
+ continue;
+ }
+
+ item = g_new0 (GbMenuItemData, 1);
+
+ if (menued->gnome_support)
+ {
+#ifdef USE_GNOME
+ item->stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menuitem), GladeMenuItemStockIndexKey));
+#endif
+ }
+ else
+ {
+ gchar *stock_id;
+ GSList *elem;
+ gint idx;
+
+ stock_id = gtk_object_get_data (GTK_OBJECT (menuitem),
+ GladeMenuItemStockIDKey);
+ item->stock_item_index = 0;
+ if (stock_id)
+ {
+ for (elem = menued->stock_items, idx = 1; elem;
+ elem = elem->next, idx++)
+ {
+ if (!strcmp (elem->data, stock_id))
+ {
+ item->stock_item_index = idx;
+ break;
+ }
+ }
+ }
+ }
+
+ item->name = g_strdup (gtk_widget_get_name (menuitem));
+ item->label = NULL;
+ item->handler = NULL;
+ item->last_mod_time = 0;
+ item->icon = NULL;
+
+ /* If it isn't a stock item, we check if it has an icon set. */
+ if (item->stock_item_index == 0 && GTK_IS_IMAGE_MENU_ITEM (menuitem))
+ {
+ GtkWidget *image;
+ image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menuitem));
+ if (image)
+ {
+ icon_name = gtk_object_get_data (GTK_OBJECT (image), GladeIconKey);
+ item->icon = g_strdup (get_icon_name_from_stock_id (menued, icon_name));
+ }
+ }
+
+ item->tooltip = g_strdup (wdata->tooltip);
+ item->type = GB_MENU_ITEM_NORMAL;
+ item->active = FALSE;
+ item->group = NULL;
+ item->modifiers = 0;
+ item->key = NULL;
+ item->level = level;
+ item->generate_name = FALSE;
+ item->generate_handler = FALSE;
+ item->wdata = glade_widget_data_copy (wdata);
+
+ if (GTK_IS_RADIO_MENU_ITEM (menuitem))
+ {
+ item->type = GB_MENU_ITEM_RADIO;
+ item->group = find_radio_group (GTK_RADIO_MENU_ITEM (menuitem),
+ &groups, item);
+ }
+ else if (GTK_IS_CHECK_MENU_ITEM (menuitem))
+ item->type = GB_MENU_ITEM_CHECK;
+
+ label = GTK_BIN (menuitem)->child;
+ if (label && GTK_IS_LABEL (label))
+ item->label = glade_util_get_label_text (label);
+
+ if (GTK_IS_CHECK_MENU_ITEM (menuitem)
+ && GTK_CHECK_MENU_ITEM (menuitem)->active)
+ item->active = TRUE;
+
+ /* Find 'activate' handler in widget data. */
+ tmp_list = item->wdata->signals;
+ while (tmp_list)
+ {
+ GladeSignal *signal = (GladeSignal *) tmp_list->data;
+ if (!strcmp (signal->name, "activate"))
+ {
+ item->handler = g_strdup (signal->handler);
+ item->last_mod_time = signal->last_modification_time;
+
+ /* Remove the signal from our copy of the GladeWidgetData. */
+ glade_widget_data_free_signal (signal);
+ item->wdata->signals = g_list_remove (item->wdata->signals,
+ signal);
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+ /* Find 'activate' accelerator in widget data. */
+ tmp_list = item->wdata->accelerators;
+ while (tmp_list)
+ {
+ GladeAccelerator *accel = (GladeAccelerator *) tmp_list->data;
+ if (!strcmp (accel->signal, "activate"))
+ {
+ item->key = g_strdup (accel->key);
+ item->modifiers = accel->modifiers;
+
+ /* Remove the accel from our copy of the GladeWidgetData. */
+ glade_widget_data_free_accel (accel);
+ item->wdata->accelerators = g_list_remove (item->wdata->accelerators,
+ accel);
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+
+ insert_item (GTK_CLIST (menued->clist), item, -1);
+
+ if (GTK_MENU_ITEM (menuitem)->submenu)
+ {
+ set_submenu (menued,
+ GTK_MENU_SHELL (GTK_MENU_ITEM (menuitem)->submenu),
+ level + 1);
+ }
+
+ child = child->next;
+ }
+
+ g_list_free (groups);
+}
+
+
+/* This clears the clist, freeing all GbMenuItemDatas, and resets the radio
+ group combo, freeing all the current radio groups. */
+static void
+glade_menu_editor_reset (GladeMenuEditor *menued)
+{
+ GbMenuItemData *item;
+ gint i;
+
+ /* Disconnect our destroy handler on the menu widget. */
+ if (menued->menu)
+ {
+ gtk_signal_disconnect (GTK_OBJECT (menued->menu),
+ menued->menu_destroy_handler_id);
+ menued->menu = NULL;
+ }
+
+ for (i = 0; i < GTK_CLIST (menued->clist)->rows; i++)
+ {
+ item = (GbMenuItemData *) gtk_clist_get_row_data (GTK_CLIST (menued->clist), i);
+ glade_menu_editor_free_item (item);
+
+ }
+ gtk_clist_clear (GTK_CLIST (menued->clist));
+
+ gtk_list_clear_items (GTK_LIST (GTK_COMBO (menued->group_combo)->list),
+ 0, -1);
+}
+
+
+static void
+glade_menu_editor_free_item (GbMenuItemData *item)
+{
+ g_free (item->name);
+ g_free (item->label);
+ g_free (item->handler);
+ g_free (item->icon);
+ g_free (item->tooltip);
+ g_free (item->key);
+
+ if (item->wdata)
+ glade_widget_data_free (item->wdata);
+
+ g_free (item);
+}
+
+
+/* Make sure all item group fields point to the first item in the group. */
+static void
+normalize_radio_groups (GladeMenuEditor * menued)
+{
+ GbMenuItemData *item, *group;
+ GList *groups = NULL;
+ gint rows, row;
+
+ /* Step through each row checking each radio item. */
+ rows = GTK_CLIST (menued->clist)->rows;
+ for (row = 0; row < rows; row++)
+ {
+ item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), row);
+ if (item->type != GB_MENU_ITEM_RADIO)
+ continue;
+
+ /* Follow the chain of groups until we get the real one. */
+ group = item->group;
+ while (group && group->group && group->group != group)
+ group = group->group;
+
+ /* If it is a new group, add it to the list. */
+ if (!group || group == item)
+ {
+ groups = g_list_prepend (groups, item);
+ item->group = NULL;
+ }
+ /* Else check if the group item is after the current one. If it is,
+ then we make the current item the group leader. We assume that if
+ we haven't seen the group item yet, it must be after this one. */
+ else if (!g_list_find (groups, group))
+ {
+ groups = g_list_prepend (groups, item);
+ group->group = item;
+ item->group = NULL;
+ }
+ else
+ {
+ item->group = group;
+ }
+ }
+
+ g_list_free (groups);
+}
+
+
+/* This recreates the list of available radio groups, and puts them in the
+ combo's drop-down list. */
+static void
+update_radio_groups (GladeMenuEditor * menued)
+{
+ GbMenuItemData *item, *tmp_item;
+ GList *groups = NULL, *elem;
+ gint item_row, row, parent_row, rows;
+ GtkCombo *combo;
+ GtkList *list;
+ GtkWidget *li;
+
+ /* Make sure all item group fields point to the first item in the group. */
+ normalize_radio_groups (menued);
+
+ item_row = get_selected_row (menued);
+ if (item_row == -1)
+ {
+ gtk_list_clear_items (GTK_LIST (GTK_COMBO (menued->group_combo)->list),
+ 0, -1);
+ return;
+ }
+
+ item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), item_row);
+
+ /* Step backwards to find the parent item. */
+ parent_row = -1;
+ for (row = item_row - 1; row > 0; row--)
+ {
+ tmp_item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), row);
+ if (tmp_item->level < item->level)
+ {
+ parent_row = row;
+ break;
+ }
+ }
+
+ /* Now step through the items, checking all items that are on the same
+ level as the current one, until we reach the end of the list or find an
+ item on a higher level. */
+ rows = GTK_CLIST (menued->clist)->rows;
+ for (row = parent_row + 1; row < rows; row++)
+ {
+ tmp_item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), row);
+ if (tmp_item->level < item->level)
+ break;
+
+ if (tmp_item->level == item->level
+ && tmp_item->type == GB_MENU_ITEM_RADIO
+ && tmp_item->name && tmp_item->name[0])
+ {
+ /* If the item has its group set to NULL or itself, then it is a new
+ group, so add its name. */
+ if (!tmp_item->group || tmp_item->group == tmp_item)
+ groups = g_list_prepend (groups, tmp_item->name);
+ }
+ }
+
+ groups = g_list_sort (groups, (GCompareFunc)strcmp);
+
+ combo = GTK_COMBO (menued->group_combo);
+ list = GTK_LIST (combo->list);
+
+ /* We have to block the combo's list's selection changed signal, or it
+ causes problems. */
+ gtk_signal_handler_block (GTK_OBJECT (list),
+ GTK_COMBO (menued->group_combo)->list_change_id);
+
+ gtk_list_clear_items (list, 0, -1);
+
+ /* Add the special 'New' item to create a new group. */
+ li = gtk_list_item_new_with_label (_("New"));
+ gtk_widget_show (li);
+ gtk_container_add (GTK_CONTAINER (list), li);
+ gtk_combo_set_item_string (combo, GTK_ITEM (li), "");
+
+ /* Add a separator. */
+ li = gtk_list_item_new ();
+ gtk_widget_show (li);
+ gtk_container_add (GTK_CONTAINER (list), li);
+
+ for (elem = groups; elem; elem = elem->next)
+ {
+ li = gtk_list_item_new_with_label (elem->data);
+ gtk_widget_show (li);
+ gtk_container_add (GTK_CONTAINER (list), li);
+ }
+
+ gtk_signal_handler_unblock (GTK_OBJECT (list),
+ GTK_COMBO (menued->group_combo)->list_change_id);
+ g_list_free (groups);
+}
+
+
+/* This finds the group item to use for the given radiomenuitem widget.
+ It searches the list of group items to find the first one that is also in
+ the radiomenuitem's group list. If none is found, it creates a new group
+ and adds it to the list. */
+static GbMenuItemData*
+find_radio_group (GtkRadioMenuItem *menuitem, GList **groups,
+ GbMenuItemData *item)
+{
+ GSList *item_group_list;
+ GList *elem;
+
+ item_group_list = menuitem->group;
+
+ /* The groups list contains pairs of GSList + GbMenuItemData*. */
+ for (elem = *groups; elem; elem = elem->next->next)
+ {
+ GSList *elem_group = elem->data;
+ GbMenuItemData *elem_item = elem->next->data;
+
+ if (elem_group == item_group_list)
+ return elem_item;
+ }
+
+ /* We couldn't find an existing group that matches, so we create a new one.
+ */
+ *groups = g_list_prepend (*groups, item);
+ *groups = g_list_prepend (*groups, item_group_list);
+ return NULL;
+}
+
+
+/* This is called to make sure that no items have the given item as their
+ group leader. It is called when an item is removed, or when its type is
+ changed from a radio item to something else.
+
+ It steps through the list, checking for radio items with
+ the group field set to the given item. The first time it finds one, it
+ creates a new group. It sets the group field of all other items in the
+ same group to the new first item in the group. */
+static void
+remove_from_radio_group (GladeMenuEditor * menued,
+ GbMenuItemData *item)
+{
+ GbMenuItemData *new_group_item = NULL;
+ gint rows, row;
+
+ rows = GTK_CLIST (menued->clist)->rows;
+ for (row = 0; row < rows; row++)
+ {
+ GbMenuItemData *tmp_item;
+ tmp_item = gtk_clist_get_row_data (GTK_CLIST (menued->clist), row);
+
+ if (tmp_item->type == GB_MENU_ITEM_RADIO
+ && tmp_item->group == item && tmp_item != item)
+ {
+ if (new_group_item)
+ {
+ tmp_item->group = new_group_item;
+ }
+ else
+ {
+ tmp_item->group = NULL;
+ new_group_item = tmp_item;
+ }
+ }
+ }
+}
+
diff --git a/tools/glade/glade/glade_menu_editor.h b/tools/glade/glade/glade_menu_editor.h
new file mode 100644
index 00000000..96e0d555
--- /dev/null
+++ b/tools/glade/glade/glade_menu_editor.h
@@ -0,0 +1,138 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLADE_MENU_EDITOR_H
+#define GLADE_MENU_EDITOR_H
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmenushell.h>
+#include <gtk/gtkwindow.h>
+
+#include "glade_project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GLADE_MENU_EDITOR(obj) GTK_CHECK_CAST (obj, glade_menu_editor_get_type (), GladeMenuEditor)
+#define GLADE_MENU_EDITOR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_menu_editor_get_type (), GladeMenuEditorClass)
+#define GLADE_IS_MENU_EDITOR(obj) GTK_CHECK_TYPE (obj, glade_menu_editor_get_type ())
+
+
+typedef struct _GladeMenuEditor GladeMenuEditor;
+typedef struct _GladeMenuEditorClass GladeMenuEditorClass;
+
+struct _GladeMenuEditor
+{
+ GtkWindow window;
+
+ GtkWidget *clist;
+
+ GtkWidget *stock_label;
+ GtkWidget *stock_combo;
+ GtkWidget *icon_label;
+ GtkWidget *icon_widget;
+ GtkWidget *icon_button;
+
+ GtkWidget *label_label;
+ GtkWidget *label_entry;
+ GtkWidget *name_label;
+ GtkWidget *name_entry;
+ GtkWidget *handler_label;
+ GtkWidget *handler_entry;
+ GtkWidget *tooltip_label;
+ GtkWidget *tooltip_entry;
+ GtkWidget *type_frame;
+ GtkWidget *normal_radiobutton;
+ GtkWidget *check_radiobutton;
+ GtkWidget *radio_radiobutton;
+ GtkWidget *right_justify_label;
+ GtkWidget *right_justify_togglebutton;
+ GtkWidget *state_label;
+ GtkWidget *state_togglebutton;
+ GtkWidget *group_label;
+ GtkWidget *group_combo;
+ GtkWidget *accel_frame;
+ GtkWidget *accel_key_entry;
+ GtkWidget *accel_ctrl_checkbutton;
+ GtkWidget *accel_shift_checkbutton;
+ GtkWidget *accel_alt_checkbutton;
+ GtkWidget *up_button;
+ GtkWidget *down_button;
+ GtkWidget *left_button;
+ GtkWidget *right_button;
+ GtkWidget *add_button;
+ GtkWidget *add_child_button;
+ GtkWidget *add_separator_button;
+ GtkWidget *delete_button;
+
+ GtkWidget *ok_button;
+ GtkWidget *apply_button;
+ GtkWidget *cancel_button;
+
+ /* This is our key selection dialog, used for selecting accelerator keys. */
+ GtkWidget *keys_dialog;
+
+ /* This is our file selection dialog, used for selecting icons. */
+ GtkWidget *filesel;
+
+ /* This is the menu widget we are editing and the project it is in. */
+ GladeProject *project;
+ GtkMenuShell *menu;
+
+ /* This is set if Glade is compiled with GNOME support and the project has
+ GNOME support turned on. We use the GnomeUIInfo stuff for menus in GNOME,
+ rather than the GTK+ stock system. */
+ gboolean gnome_support;
+
+ /* This is the id of the handler connected to the menu widget's destroy
+ signal, so we can destroy the menu editor if the menu is destroyed. */
+ guint menu_destroy_handler_id;
+
+ /* This is TRUE if we are updating the entry fields and so should ignore
+ changed signals. */
+ gboolean updating_widgets;
+
+ /* The list of GTK+ stock items. */
+ GSList *stock_items;
+};
+
+struct _GladeMenuEditorClass
+{
+ GtkWindowClass parent_class;
+};
+
+
+GType glade_menu_editor_get_type (void);
+
+/* This creates a menu editor to edit the given menubar or popup menu in
+ the given project. When the user selects the 'OK' or 'Apply' buttons,
+ the menu widget will be updated. If the menu is destroyed, the menu editor
+ is automatically destroyed as well. */
+GtkWidget* glade_menu_editor_new (GladeProject *project,
+ GtkMenuShell *menu);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* GLADE_MENU_EDITOR_H */
diff --git a/tools/glade/glade/glade_palette.c b/tools/glade/glade/glade_palette.c
new file mode 100644
index 00000000..a8c8b9e1
--- /dev/null
+++ b/tools/glade/glade/glade_palette.c
@@ -0,0 +1,544 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <string.h>
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkhseparator.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkpixmap.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtksignal.h>
+
+#include "graphics/selector.xpm"
+#include "glade_palette.h"
+#include "glade.h"
+
+GtkWidget *glade_palette = NULL;
+
+#define GLADE_CLASS_ID_KEY "GladeClassID"
+
+static void glade_palette_class_init (GladePaletteClass * klass);
+static void glade_palette_init (GladePalette * glade_palette);
+
+static GladePaletteSection *new_section (GladePalette * palette,
+ const gchar * section);
+static void rebuild_page (gpointer key,
+ GladePaletteSection * page,
+ GladePalette * palette);
+static void remove_button (gpointer button,
+ gpointer table);
+static void add_button (GtkWidget * button,
+ GladePaletteSection * sect);
+static void on_palette_button_toggled (GtkWidget * button,
+ GladePalette * palette);
+static void on_section_button_clicked (GtkWidget * button,
+ GladePalette * palette);
+
+enum
+{
+ SELECT_ITEM,
+ UNSELECT_ITEM,
+ LAST_SIGNAL
+};
+
+static guint glade_palette_signals[LAST_SIGNAL] = {0};
+
+static GtkWindowClass *parent_class = NULL;
+
+
+GType
+glade_palette_get_type (void)
+{
+ static GType palette_type = 0;
+
+ if (!palette_type)
+ {
+ GtkTypeInfo palette_info =
+ {
+ "GladePalette",
+ sizeof (GladePalette),
+ sizeof (GladePaletteClass),
+ (GtkClassInitFunc) glade_palette_class_init,
+ (GtkObjectInitFunc) glade_palette_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ palette_type = gtk_type_unique (gtk_window_get_type (), &palette_info);
+ }
+ return palette_type;
+}
+
+
+static void
+glade_palette_class_init (GladePaletteClass * klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) klass;
+
+ parent_class = gtk_type_class (gtk_window_get_type ());
+
+ glade_palette_signals[SELECT_ITEM] =
+ gtk_signal_new ("select_item",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GladePaletteClass, select_item),
+ gtk_marshal_VOID__STRING,
+ GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
+ glade_palette_signals[UNSELECT_ITEM] =
+ gtk_signal_new ("unselect_item",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GladePaletteClass, unselect_item),
+ gtk_marshal_VOID__STRING,
+ GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
+
+ klass->select_item = NULL;
+ klass->unselect_item = NULL;
+}
+
+
+/* Ensure the correct button is depressed when the page is switched with
+ keyboard accelerators. */
+static void
+on_notebook_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
+ guint page_num, GladePalette *palette)
+{
+ GSList *elem;
+ gint last_page;
+
+ last_page = g_list_length (notebook->children) - 1;
+
+ for (elem = palette->section_button_group; elem; elem = elem->next)
+ {
+ GladePaletteSection *sect = gtk_object_get_data (GTK_OBJECT (elem->data), "section");
+
+ if ((sect->page == -1 && page_num == last_page)
+ || sect->page == page_num)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (elem->data), TRUE);
+ break;
+ }
+ }
+}
+
+
+static void
+glade_palette_init (GladePalette * palette)
+{
+ GtkWidget *seperator, *hbox;
+ GdkPixmap *gdkpixmap;
+ GdkBitmap *gdkmask;
+ GtkWidget *pixmap;
+ GtkReliefStyle relief_style;
+
+ palette->width = 4;
+ palette->selected_widget = NULL;
+ palette->hold_selected_widget = FALSE;
+ palette->sections = g_hash_table_new (g_str_hash, g_str_equal);
+ palette->tooltips = gtk_tooltips_new ();
+
+ palette->vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (palette), palette->vbox);
+ gtk_widget_show (palette->vbox);
+
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (palette->vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show (hbox);
+
+ relief_style = GTK_RELIEF_NONE;
+
+ palette->selector = gtk_radio_button_new (NULL);
+ gtk_button_set_relief (GTK_BUTTON (palette->selector), relief_style);
+
+ gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (GTK_WIDGET (palette)), &gdkmask, NULL, selector_xpm);
+ pixmap = gtk_pixmap_new (gdkpixmap, gdkmask);
+ gtk_container_add (GTK_CONTAINER (GLADE_PALETTE (palette)->selector),
+ pixmap);
+ gtk_widget_show (pixmap);
+
+ palette->widget_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (palette->selector));
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (palette->selector), FALSE);
+ gtk_box_pack_start (GTK_BOX (hbox), palette->selector, FALSE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (palette->selector), "toggled",
+ (GtkSignalFunc) on_palette_button_toggled, palette);
+ gtk_widget_show (palette->selector);
+ /* Don't translate 'Selector' here, since it is not displayed, and we test
+ for it later. */
+ gtk_object_set_data (GTK_OBJECT (palette->selector), GLADE_CLASS_ID_KEY,
+ "Selector");
+ gtk_tooltips_set_tip (palette->tooltips, palette->selector,
+ _ ("Selector"), NULL);
+
+ palette->selected_item_label = gtk_label_new (_ ("Selector"));
+ gtk_misc_set_alignment (GTK_MISC (palette->selected_item_label), 0, 0.5);
+ gtk_widget_show (palette->selected_item_label);
+
+ gtk_widget_set_usize (palette->selected_item_label, 10, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), palette->selected_item_label,
+ TRUE, TRUE, 0);
+
+ seperator = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (palette->vbox), seperator, FALSE, TRUE, 3);
+ gtk_widget_show (seperator);
+
+ palette->notebook = gtk_notebook_new ();
+ /* We use gtk_box_pack_end, so we can later add buttons for new categories
+ at the right place with gtk_box_pack_start */
+ gtk_box_pack_end (GTK_BOX (palette->vbox), palette->notebook,
+ TRUE, TRUE, 0);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (palette->notebook), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (palette->notebook), FALSE);
+ gtk_widget_show (palette->notebook);
+
+ gtk_signal_connect (GTK_OBJECT (palette->notebook), "switch_page",
+ GTK_SIGNAL_FUNC (on_notebook_switch_page), palette);
+
+ seperator = gtk_hseparator_new ();
+ gtk_box_pack_end (GTK_BOX (palette->vbox), seperator, FALSE, TRUE, 3);
+ gtk_widget_show (seperator);
+}
+
+
+GtkWidget *
+glade_palette_new ()
+{
+ return GTK_WIDGET (gtk_type_new (glade_palette_get_type ()));
+}
+
+
+void
+glade_palette_add_widget (GladePalette *palette,
+ const gchar *section,
+ const gchar *name,
+ GdkPixmap *gdkpixmap,
+ GdkBitmap *mask,
+ const gchar *tooltip)
+{
+ GladePaletteSection *sect;
+ GtkWidget *button;
+ GtkWidget *pixmap;
+ GtkReliefStyle relief_style;
+
+ g_return_if_fail (palette != NULL);
+ g_return_if_fail (GLADE_IS_PALETTE (palette));
+ g_return_if_fail (gdkpixmap != NULL);
+
+ if (!(sect = g_hash_table_lookup (palette->sections, section)))
+ sect = new_section (palette, section);
+
+ relief_style = GTK_RELIEF_NONE;
+
+ button = gtk_radio_button_new (palette->widget_button_group);
+ gtk_button_set_relief (GTK_BUTTON (button), relief_style);
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+ palette->widget_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+
+ pixmap = gtk_pixmap_new (gdkpixmap, mask);
+ gtk_container_add (GTK_CONTAINER (button), pixmap);
+ gtk_widget_show (pixmap);
+
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (button), GLADE_CLASS_ID_KEY,
+ (gpointer) name);
+ gtk_signal_connect (GTK_OBJECT (button), "toggled",
+ (GtkSignalFunc) on_palette_button_toggled, palette);
+
+ gtk_tooltips_set_tip (palette->tooltips, button, tooltip, NULL);
+
+ sect->buttons = g_list_append (sect->buttons, button);
+ g_hash_table_insert (sect->buttonhash, (gpointer) name, button);
+ /* so we can use the same code as from rebuild_page */
+ gtk_widget_ref (button);
+ add_button (button, sect);
+}
+
+
+void
+glade_palette_remove_widget (GladePalette * palette,
+ const gchar * section,
+ const gchar * name)
+{
+ GladePaletteSection *sect;
+ GtkWidget *button;
+
+ sect = g_hash_table_lookup (palette->sections, section);
+ g_return_if_fail (sect != NULL);
+ button = GTK_WIDGET (g_hash_table_lookup (sect->buttonhash, name));
+ g_return_if_fail (button != NULL);
+ g_hash_table_remove (sect->buttonhash, name);
+ sect->buttons = g_list_remove (sect->buttons, button);
+ gtk_container_remove (GTK_CONTAINER (sect->table), button);
+ rebuild_page ((gpointer)section, sect, palette);
+}
+
+
+void
+glade_palette_set_width (GladePalette * palette, guint columns)
+{
+ palette->width = columns;
+ g_hash_table_foreach (palette->sections, (GHFunc) rebuild_page, palette);
+}
+
+
+static GladePaletteSection *
+new_section (GladePalette * palette,
+ const gchar * section)
+{
+ GladePaletteSection *sect;
+ GtkWidget *button;
+ gboolean deprecated_page = FALSE;
+
+ if (!strcmp (section, _("Dep_recated")))
+ deprecated_page = TRUE;
+
+ sect = g_new (GladePaletteSection, 1);
+ sect->x = sect->y = 0;
+ sect->table = gtk_table_new (1, palette->width, TRUE);
+ gtk_widget_show (sect->table);
+ sect->buttons = NULL;
+ sect->buttonhash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ sect->section_button = button = gtk_radio_button_new_with_mnemonic (palette->section_button_group, section);
+ gtk_widget_set_name (button, section);
+ gtk_widget_set_usize (button, 20, -1);
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+ palette->section_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+ gtk_widget_show (button);
+ gtk_object_set_data (GTK_OBJECT (button), "section", sect);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_section_button_clicked), palette);
+ g_hash_table_insert (palette->sections, (gpointer) section, sect);
+
+ /* Place the deprecated section last. */
+ if (deprecated_page)
+ {
+ sect->page = -1;
+ gtk_notebook_append_page (GTK_NOTEBOOK (palette->notebook), sect->table,
+ NULL);
+ gtk_box_pack_end (GTK_BOX (palette->vbox), button, FALSE, TRUE, 0);
+ }
+ else
+ {
+ sect->page = palette->next_page_to_add++;
+ gtk_notebook_insert_page (GTK_NOTEBOOK (palette->notebook), sect->table,
+ NULL, sect->page);
+ gtk_box_pack_start (GTK_BOX (palette->vbox), button, FALSE, TRUE, 0);
+ }
+
+ return sect;
+}
+
+static void
+rebuild_page (gpointer key,
+ GladePaletteSection * sect,
+ GladePalette * palette)
+{
+ g_list_foreach (g_list_first (sect->buttons), remove_button, sect->table);
+ sect->x = 0;
+ sect->y = 0;
+ gtk_table_resize (GTK_TABLE (sect->table), 1, palette->width);
+ g_list_foreach (g_list_first (sect->buttons), (GFunc) add_button, sect);
+}
+
+static void
+remove_button (gpointer button,
+ gpointer table)
+{
+ g_return_if_fail (button != NULL);
+ g_return_if_fail (table != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (table));
+ g_return_if_fail (GTK_IS_WIDGET (button));
+ gtk_widget_ref (GTK_WIDGET (button));
+ gtk_container_remove (GTK_CONTAINER (table), GTK_WIDGET (button));
+}
+
+static void
+add_button (GtkWidget * button,
+ GladePaletteSection * sect)
+{
+ GladePalette *palette;
+
+ /* notebook vbox palette */
+ palette = GLADE_PALETTE (GTK_WIDGET (sect->table)->parent->parent->parent);
+ if (sect->x >= palette->width)
+ {
+ /* new row */
+ sect->x = 0;
+ sect->y++;
+ }
+ gtk_table_attach (GTK_TABLE (sect->table), button, sect->x, sect->x + 1,
+ sect->y, sect->y + 1, 0, 0, 0, 0);
+ gtk_widget_unref (button);
+ sect->x++;
+}
+
+
+static void
+on_palette_button_toggled (GtkWidget * button,
+ GladePalette * palette)
+{
+ GdkModifierType modifiers;
+
+ if ((GTK_TOGGLE_BUTTON (button)->active))
+ {
+ if (button == palette->selector)
+ {
+ palette->selected_widget = NULL;
+ gtk_label_set_text (GTK_LABEL (palette->selected_item_label),
+ _("Selector"));
+ palette->hold_selected_widget = FALSE;
+ }
+ else
+ {
+ palette->selected_widget = gtk_object_get_data (GTK_OBJECT (button),
+ GLADE_CLASS_ID_KEY);
+ gtk_label_set_text (GTK_LABEL (palette->selected_item_label),
+ palette->selected_widget);
+ gdk_window_get_pointer (button->window, NULL, NULL, &modifiers);
+ palette->hold_selected_widget = (modifiers & GDK_CONTROL_MASK)
+ ? TRUE : FALSE;
+ }
+ gtk_signal_emit (GTK_OBJECT (palette),
+ glade_palette_signals[SELECT_ITEM],
+ palette->selected_widget);
+ }
+ else
+ {
+ gtk_signal_emit (GTK_OBJECT (palette),
+ glade_palette_signals[UNSELECT_ITEM],
+ palette->selected_widget);
+ }
+}
+
+
+static void
+on_section_button_clicked (GtkWidget * button,
+ GladePalette * palette)
+{
+ GladePaletteSection *sect;
+
+ sect = (GladePaletteSection*) gtk_object_get_data (GTK_OBJECT (button),
+ "section");
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (palette->notebook), sect->page);
+}
+
+
+/* Resets the palette so that the selector is selected, unless the existing
+ item was selected while holding the Ctrl key. */
+void
+glade_palette_reset_selection (GladePalette *palette,
+ gboolean allow_hold)
+{
+ if (!palette->hold_selected_widget || !allow_hold)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->selector), TRUE);
+}
+
+
+/* Returns TRUE if the selector is currently selected. */
+gboolean
+glade_palette_is_selector_on (GladePalette *palette)
+{
+ return (palette->selected_widget == NULL) ? TRUE : FALSE;
+}
+
+
+/* Returns the class name of the currently selected widget. */
+gchar *
+glade_palette_get_widget_class (GladePalette *palette)
+{
+ return palette->selected_widget;
+}
+
+
+static void
+glade_palette_set_show_section (GladePalette *palette,
+ GladePaletteSection *sect,
+ gboolean show)
+{
+ if (show)
+ gtk_widget_show (sect->section_button);
+ else
+ gtk_widget_hide (sect->section_button);
+}
+
+
+static void
+set_button_visibility (GladePaletteSection *sect,
+ const gchar *name,
+ gboolean show)
+{
+ GtkWidget *button = g_hash_table_lookup (sect->buttonhash, name);
+ if (button)
+ {
+ if (show)
+ gtk_widget_show (button);
+ else
+ gtk_widget_hide (button);
+ }
+}
+
+
+/* Shows or hides the GNOME widgets. */
+void
+glade_palette_set_show_gnome_widgets (GladePalette *palette,
+ gboolean show_gnome,
+ gboolean show_gnome_db)
+{
+ GladePaletteSection *sect;
+
+ /* Show the main page, and make the selector active. */
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (palette->notebook), 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->selector), TRUE);
+
+ /* Show or hide the Gnome page if it exists. */
+ sect = g_hash_table_lookup (palette->sections, "_Gnome");
+ if (sect)
+ glade_palette_set_show_section (palette, sect, show_gnome);
+
+ /* Show or hide the GnomeDB page if it exists. */
+ sect = g_hash_table_lookup (palette->sections, "Gnome _DB");
+ if (sect)
+ glade_palette_set_show_section (palette, sect, show_gnome_db);
+
+ /* Show or hide the GNOME widgets on the Deprecated page if they exist. */
+ sect = g_hash_table_lookup (palette->sections, "Dep_recated");
+ if (sect)
+ {
+ set_button_visibility (sect, "GnomeDialog", show_gnome);
+ set_button_visibility (sect, "GnomeMessageBox", show_gnome);
+ set_button_visibility (sect, "GnomePropertyBox", show_gnome);
+ set_button_visibility (sect, "GnomePixmap", show_gnome);
+ set_button_visibility (sect, "GnomeColorPicker", show_gnome);
+ set_button_visibility (sect, "GnomeFontPicker", show_gnome);
+ set_button_visibility (sect, "GnomeAbout", show_gnome);
+ set_button_visibility (sect, "GnomeIconList", show_gnome);
+ set_button_visibility (sect, "GnomeEntry", show_gnome);
+ set_button_visibility (sect, "GnomeFileEntry", show_gnome);
+ set_button_visibility (sect, "GnomePixmapEntry", show_gnome);
+ }
+}
+
diff --git a/tools/glade/glade/glade_palette.h b/tools/glade/glade/glade_palette.h
new file mode 100644
index 00000000..c3095dac
--- /dev/null
+++ b/tools/glade/glade/glade_palette.h
@@ -0,0 +1,150 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef GLADE_PALETTE_H
+#define GLADE_PALETTE_H
+
+#include <gtk/gtkwindow.h>
+#include <gtk/gtktooltips.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This is the only palette. */
+extern GtkWidget *glade_palette;
+
+
+#define GLADE_PALETTE(obj) GTK_CHECK_CAST (obj, glade_palette_get_type (), GladePalette)
+#define GLADE_PALETTE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_palette_get_type (), GladePaletteClass)
+#define GLADE_IS_PALETTE(obj) GTK_CHECK_TYPE (obj, glade_palette_get_type ())
+
+
+typedef struct _GladePaletteSection GladePaletteSection;
+typedef struct _GladePalette GladePalette;
+typedef struct _GladePaletteClass GladePaletteClass;
+
+struct _GladePaletteSection
+{
+ /* The notebook page number for the section. */
+ gint page;
+
+ /* The button to switch to this section. */
+ GtkWidget *section_button;
+
+ /* The table containing all the widget icons for the section. */
+ GtkWidget *table;
+
+ /* The position in the table where the next button for this section will be
+ added. */
+ guint x;
+ guint y;
+
+ /* A list of the buttons in the section. */
+ GList *buttons;
+
+ /* A hash of the buttons in the section, so you can look a button up by
+ name. */
+ GHashTable *buttonhash;
+};
+
+struct _GladePalette
+{
+ GtkWindow window;
+
+ GtkTooltips *tooltips;
+ GtkWidget *vbox;
+ GtkWidget *selector;
+ GtkWidget *selected_item_label;
+ GtkWidget *notebook;
+
+ /* The number of columns of widgets. */
+ guint width;
+
+ /* The name of the class of the currently selected widget, or 'Selector'. */
+ gchar *selected_widget;
+
+ /* Whether the widget was selected with the 'Ctrl' key, which means that it
+ will remain selected until the selector is selected again. */
+ gboolean hold_selected_widget;
+
+ /* The radio group of all the widget buttons and the selector. */
+ GSList *widget_button_group;
+
+ /* The radio group of the section buttons. */
+ GSList *section_button_group;
+
+ /* A hash table of GladePaletteSection's, keyed by section name. */
+ GHashTable *sections;
+
+ /* The number of the next notebook page to add. Note that the deprecated
+ page is always last. */
+ gint next_page_to_add;
+};
+
+struct _GladePaletteClass
+{
+ GtkWindowClass parent_class;
+
+ void (*select_item) (GladePalette *palette,
+ gchar *item_name);
+ void (*unselect_item) (GladePalette *palette,
+ gchar *item_name);
+};
+
+
+GType glade_palette_get_type (void);
+GtkWidget* glade_palette_new (void);
+
+/* Sets the number of columns of widgets in the palette. */
+void glade_palette_set_width (GladePalette *palette,
+ guint columns);
+
+/* Adds a widget to a section of the palette. */
+void glade_palette_add_widget (GladePalette *palette,
+ const gchar *section,
+ const gchar *name,
+ GdkPixmap *gdkpixmap,
+ GdkBitmap *mask,
+ const gchar *tooltip);
+
+/* Removes a widget from the palette. */
+void glade_palette_remove_widget (GladePalette *palette,
+ const gchar *section,
+ const gchar *name);
+
+/* Returns TRUE if the selector is currently selected. */
+gboolean glade_palette_is_selector_on (GladePalette *palette);
+
+/* Returns the class name of the selected widget. */
+gchar* glade_palette_get_widget_class (GladePalette *palette);
+
+/* Resets the palette selection to the Selector, unless the currently selected
+ item was selected with the Ctrl key held down (and allow_hold is TRUE). */
+void glade_palette_reset_selection (GladePalette *palette,
+ gboolean allow_hold);
+
+/* Shows or hides the GNOME widgets. */
+void glade_palette_set_show_gnome_widgets(GladePalette *palette,
+ gboolean show_gnome,
+ gboolean show_gnome_db);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PALETTE_H */
diff --git a/tools/glade/glade/glade_plugin.c b/tools/glade/glade/glade_plugin.c
new file mode 100644
index 00000000..ceae962b
--- /dev/null
+++ b/tools/glade/glade/glade_plugin.c
@@ -0,0 +1,176 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * File : glade_plugin.c
+ * Description : Provides support for plugin widget libraries which use Args.
+ * Unfinished, experimental code at present.
+ * For Gnome, we may want to think about bonobo components,
+ * rather like COM/ActiveX components in Delphi/VB.
+ */
+
+#include "gladeconfig.h"
+
+#ifndef _WIN32
+#include <gmodule.h>
+#endif
+#include <gtk/gtk.h>
+
+#include "gbwidget.h"
+#include "glade_plugin.h"
+#include "palette.h"
+#include "utils.h"
+
+
+/* This loads extra libraries of widgets which we will access via the GTK+
+ Arg functions. */
+void
+glade_plugin_load_plugins (void)
+{
+#if 0
+ /* FIXME: Here we just test for /usr/local/gnome/lib/libdruid.so, but we'll
+ support some user configuration later. */
+ gchar *module_dir = "/usr/local/gnome/lib";
+ gchar *module_file = "druid";
+
+ typedef gboolean (*GladePluginInitFunc) (gint **widget_types,
+ gchar ****xpm_data);
+
+ GModule *module;
+ gchar *library_file;
+ gpointer symbol_value;
+ GladePluginInitFunc plugin_init_func;
+ gboolean status;
+ gint *widget_types;
+ gchar ***widget_xpms;
+ gint i;
+
+ /* Check if dynamic loading is supported by the current platform. */
+ if (!g_module_supported ())
+ return;
+
+ library_file = g_module_build_path (module_dir, module_file);
+ if (!glade_util_file_exists (library_file))
+ return;
+
+ module = g_module_open (library_file, 0);
+ g_return_if_fail (module != NULL);
+
+ /* Try to find the initialization function. */
+ if (!g_module_symbol (module, "glade_plugin_init", &symbol_value))
+ {
+ g_warning ("Plugin library contains no initialization function: %s\n",
+ library_file);
+ return;
+ }
+
+ plugin_init_func = (GladePluginInitFunc) symbol_value;
+ status = (*plugin_init_func) (&widget_types, &widget_xpms);
+ g_return_if_fail (status == TRUE);
+
+ g_return_if_fail (widget_types != NULL);
+
+ for (i = 0; widget_types[i]; i++)
+ {
+ GbWidget *gbwidget;
+ gchar *class_name;
+
+ gbwidget = glade_plugin_new ();
+ if (widget_xpms)
+ {
+ gbwidget->pixmap_struct = widget_xpms[i];
+ }
+
+ class_name = gtk_type_name (widget_types[i]);
+ gbwidget->tooltip = class_name;
+ gb_widget_register_gbwidget (class_name, gbwidget);
+ palette_add_gbwidget (gbwidget, "Plugins", class_name);
+ }
+#endif
+}
+
+
+/* This finds out which Args the widget (and any ancestors) support. */
+static void
+glade_plugin_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+#if 0
+ GtkObjectClass *klass;
+ GtkArg *args;
+ guint32 *arg_flags;
+ guint n_args;
+ gint arg;
+ gchar flags[16], *pos;
+ GtkType type;
+
+ g_print ("In glade_plugin_create_properties\n");
+
+ klass = GTK_OBJECT (widget)->klass;
+ g_return_if_fail (klass != NULL);
+
+ type = klass->type;
+ while (type != 0)
+ {
+ args = gtk_object_query_args (type, &arg_flags, &n_args);
+
+ for (arg = 0; arg < n_args; arg++)
+ {
+ pos = flags;
+ /* We use one-character flags for simplicity. */
+ if (arg_flags[arg] & GTK_ARG_READABLE)
+ *pos++ = 'r';
+ if (arg_flags[arg] & GTK_ARG_WRITABLE)
+ *pos++ = 'w';
+ if (arg_flags[arg] & GTK_ARG_CONSTRUCT)
+ *pos++ = 'x';
+ if (arg_flags[arg] & GTK_ARG_CONSTRUCT_ONLY)
+ *pos++ = 'X';
+ if (arg_flags[arg] & GTK_ARG_CHILD_ARG)
+ *pos++ = 'c';
+ *pos = '\0';
+
+ g_print ("ARG: %s (%s:%s)\n",
+ args[arg].name, gtk_type_name (args[arg].type), flags);
+ }
+
+ g_free (args);
+ g_free (arg_flags);
+
+ type = gtk_type_parent (type);
+ }
+#endif
+}
+
+
+/* This creates a new GbWidget which may have different tooltip/icon fields,
+ but the functions will all be the same, since we can handle Args
+ generically. */
+GbWidget*
+glade_plugin_new ()
+{
+ GbWidget *gbwidget;
+
+ gbwidget = g_new (GbWidget, 1);
+ gb_widget_init_struct (gbwidget);
+ gbwidget->gb_widget_create_properties = glade_plugin_create_properties;
+
+ return gbwidget;
+}
+
+
diff --git a/tools/glade/glade/glade_plugin.h b/tools/glade/glade/glade_plugin.h
new file mode 100644
index 00000000..4c0d8712
--- /dev/null
+++ b/tools/glade/glade/glade_plugin.h
@@ -0,0 +1,52 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * File : glade_plugin.h
+ * Description : Provides support for plugin widget libraries which use Args.
+ * Unfinished, experimental code at present.
+ * For Gnome, we may want to think about bonobo components,
+ * rather like COM/ActiveX components in Delphi/VB.
+ */
+#ifndef GLADE_PLUGIN_H
+#define GLADE_PLUGIN_H
+
+#include "gladeconfig.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This loads extra libraries of widgets which we will access via the GTK+
+ Arg functions. */
+void glade_plugin_load_plugins (void);
+
+
+/* This creates a new GbWidget which may have different tooltip/icon fields,
+ but the functions will all be the same, since we can handle Args
+ generically. */
+GbWidget* glade_plugin_new (void);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PLUGIN_H */
diff --git a/tools/glade/glade/glade_project.c b/tools/glade/glade/glade_project.c
new file mode 100644
index 00000000..26714933
--- /dev/null
+++ b/tools/glade/glade/glade_project.c
@@ -0,0 +1,1992 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <string.h>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include <dirent.h>
+
+#include <libxml/parser.h>
+
+#include <gtk/gtkmenu.h>
+#include <gtk/gtk.h>
+#include "gladeconfig.h"
+
+#include "editor.h"
+#include "glade_menu_editor.h"
+#include "glade_project.h"
+#include "load.h"
+#include "property.h"
+#include "save.h"
+#include "source.h"
+#include "tree.h"
+#include "utils.h"
+
+/* FIXME: This is the current project. We only support one open at present. */
+GladeProject *current_project = NULL;
+
+
+/* The order must match the GladeLanguageType enum in glade_project.h. */
+gchar *GladeLanguages[] = { "C", "C++" , "Ada 95", "Perl", "Eiffel" };
+#if 1
+gint GladeNumLanguages = 3; /* Only C, C++ and Ada ported to GTK+ 2. */
+#else
+gint GladeNumLanguages = sizeof (GladeLanguages) / sizeof (GladeLanguages[0]);
+#endif
+
+static void glade_project_class_init (GladeProjectClass * klass);
+static void glade_project_init (GladeProject *project);
+static void glade_project_destroy (GtkObject *object);
+
+static GladeError* glade_project_write_c_source (GladeProject *project);
+static GladeError* glade_project_write_cxx_source (GladeProject *project);
+static GladeError* glade_project_write_ada95_source (GladeProject *project);
+static GladeError* glade_project_write_perl_source (GladeProject *project);
+static GladeError* glade_project_write_eiffel_source (GladeProject *project);
+
+static void free_key (gchar *key,
+ gchar *value,
+ gpointer data);
+
+static gchar* glade_project_find_id (GladeProject *project,
+ const gchar *name);
+static void glade_project_real_ensure_widgets_named (GtkWidget *widget,
+ GladeProject *project);
+
+enum
+{
+ ADD_COMPONENT,
+ REMOVE_COMPONENT,
+ COMPONENT_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint glade_project_signals[LAST_SIGNAL] = {0};
+
+static GtkObjectClass *parent_class = NULL;
+
+
+GType
+glade_project_get_type (void)
+{
+ static GType glade_project_type = 0;
+
+ if (!glade_project_type)
+ {
+ GtkTypeInfo glade_project_info =
+ {
+ "GladeProject",
+ sizeof (GladeProject),
+ sizeof (GladeProjectClass),
+ (GtkClassInitFunc) glade_project_class_init,
+ (GtkObjectInitFunc) glade_project_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ glade_project_type = gtk_type_unique (gtk_object_get_type (),
+ &glade_project_info);
+ }
+
+ return glade_project_type;
+}
+
+static void
+glade_project_class_init (GladeProjectClass * klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) klass;
+
+ parent_class = gtk_type_class (gtk_object_get_type ());
+
+ glade_project_signals[ADD_COMPONENT] =
+ gtk_signal_new ("add_component",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GladeProjectClass, add_component),
+ gtk_marshal_VOID__OBJECT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_OBJECT);
+ glade_project_signals[REMOVE_COMPONENT] =
+ gtk_signal_new ("remove_component",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GladeProjectClass, remove_component),
+ gtk_marshal_VOID__OBJECT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_OBJECT);
+ glade_project_signals[COMPONENT_CHANGED] =
+ gtk_signal_new ("component_changed",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GladeProjectClass, component_changed),
+ gtk_marshal_VOID__OBJECT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_OBJECT);
+
+ klass->add_component = NULL;
+ klass->remove_component = NULL;
+ klass->component_changed = NULL;
+
+ object_class->destroy = glade_project_destroy;
+}
+
+
+static void
+glade_project_init (GladeProject * project)
+{
+ project->xml_filename = NULL;
+
+ /* The default project name, used when new projects are created. */
+ project->name = NULL;
+ project->program_name = NULL;
+ project->directory = NULL;
+ project->source_directory = NULL;
+ project->pixmaps_directory = NULL;
+
+ project->language = GLADE_LANGUAGE_C;
+ property_show_lang_specific_page (project->language);
+
+ project->changed = FALSE;
+
+ project->unique_id_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ project->components = NULL;
+
+ project->pixmap_filenames = NULL;
+
+ project->current_directory = NULL;
+
+ project->gettext_support = TRUE;
+
+#ifdef USE_GNOME
+ project->gnome_support = TRUE;
+#else
+ project->gnome_support = FALSE;
+#endif
+
+ project->gnome_db_support = FALSE;
+ project->gnome_help_support = FALSE;
+
+ project->use_widget_names = FALSE;
+ project->output_main_file = TRUE;
+ project->output_support_files = TRUE;
+ project->output_build_files = TRUE;
+ project->backup_source_files = TRUE;
+
+ project->main_source_file = g_strdup ("interface.c");
+ project->main_header_file = g_strdup ("interface.h");
+ project->handler_source_file = g_strdup ("callbacks.c");
+ project->handler_header_file = g_strdup ("callbacks.h");
+
+ project->support_source_file = g_strdup ("support.c");
+ project->support_header_file = g_strdup ("support.h");
+
+ project->output_translatable_strings = FALSE;
+ project->translatable_strings_file = NULL;
+}
+
+
+GladeProject*
+glade_project_new (void)
+{
+ /* FIXME: Currently we only support one project open, so we have to destroy
+ any existing project, and reset everything. */
+ if (current_project)
+ {
+ property_set_widget (NULL);
+ editor_clear_selection (NULL);
+ gtk_object_destroy (GTK_OBJECT (current_project));
+ /* Delete all GbStyles and reset hash table. Do this after all widgets
+ are destroyed. */
+#ifdef GLADE_STYLE_SUPPORT
+ gb_widget_reset_gb_styles ();
+#endif
+ }
+
+ current_project = GLADE_PROJECT (gtk_type_new (glade_project_get_type()));
+ return current_project;
+}
+
+
+static void
+glade_project_destroy (GtkObject *object)
+{
+ GladeProject *project;
+ GList *tmp_list;
+
+ project = GLADE_PROJECT (object);
+
+ g_free (project->xml_filename);
+ project->xml_filename = NULL;
+
+ g_free (project->name);
+ project->name = NULL;
+
+ g_free (project->program_name);
+ project->program_name = NULL;
+
+ g_free (project->directory);
+ project->directory = NULL;
+
+ g_free (project->source_directory);
+ project->source_directory = NULL;
+
+ g_free (project->pixmaps_directory);
+ project->pixmaps_directory = NULL;
+
+ /* Destroy all project components. */
+ tmp_list = project->components;
+ while (tmp_list)
+ {
+ gtk_widget_destroy (GTK_WIDGET (tmp_list->data));
+ tmp_list = tmp_list->next;
+ }
+ g_list_free (project->components);
+ project->components = NULL;
+
+ /* Empty the tree. Do this after the widgets are destroyed as it is a bit
+ safer since the widgets won't ever have invalid pointers to the tree
+ nodes. */
+ tree_clear ();
+
+ /* Destroy the unique id hash. */
+ if (project->unique_id_hash)
+ {
+ g_hash_table_foreach (project->unique_id_hash, (GHFunc) free_key, NULL);
+ g_hash_table_destroy (project->unique_id_hash);
+ project->unique_id_hash = NULL;
+ }
+
+ /* Free all pixmap filenames. */
+ tmp_list = project->pixmap_filenames;
+ while (tmp_list)
+ {
+ g_free (tmp_list->data);
+ tmp_list = tmp_list->next;
+ }
+ g_list_free (project->pixmap_filenames);
+ project->pixmap_filenames = NULL;
+
+ g_free (project->current_directory);
+ project->current_directory = NULL;
+
+ g_free (project->main_source_file);
+ project->main_source_file = NULL;
+
+ g_free (project->main_header_file);
+ project->main_header_file = NULL;
+
+ g_free (project->handler_source_file);
+ project->handler_source_file = NULL;
+
+ g_free (project->handler_header_file);
+ project->handler_header_file = NULL;
+
+ g_free (project->support_source_file);
+ project->support_source_file = NULL;
+
+ g_free (project->support_header_file);
+ project->support_header_file = NULL;
+}
+
+
+/* This is called for each id in the unique id hash. We have to free the
+ id strings, since they were g_strdup'ed. */
+static void
+free_key (gchar *key,
+ gchar *value,
+ gpointer data)
+{
+ g_free (key);
+}
+
+
+gboolean
+glade_project_open (const gchar *xml_filename,
+ GladeProject **project_return)
+{
+ gboolean status;
+ GladeProject *project;
+
+ project = glade_project_new ();
+ project->xml_filename = g_strdup (xml_filename);
+
+ tree_freeze ();
+
+ status = load_project_file (project);
+
+ tree_thaw ();
+
+ if (!status)
+ {
+ gtk_object_destroy (GTK_OBJECT (project));
+ current_project = NULL;
+ }
+ else
+ {
+ *project_return = project;
+ }
+ return status;
+}
+
+
+GladeError*
+glade_project_save (GladeProject *project)
+{
+ GladeError *error;
+
+ error = glade_util_ensure_directory_exists (project->directory);
+ if (error)
+ return error;
+
+ /* Copy any pixmaps to the project's pixmaps directory. */
+ error = glade_project_copy_all_pixmaps (project);
+ if (error)
+ return error;
+
+ error = save_project_file (project);
+ if (error == NULL)
+ glade_project_set_changed (project, FALSE);
+
+ return error;
+}
+
+
+GladeError*
+glade_project_write_source (GladeProject *project)
+{
+ GladeError *error;
+
+ /* First we check that we have a project directory, a source directory,
+ and a pixmaps directory, and that the source directory is the same as
+ the project directory or is a subdirectory of it. */
+ if (project->directory == NULL)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("The project directory is not set.\n"
+ "Please set it using the Project Options dialog.\n"));
+ }
+
+ if (project->source_directory == NULL)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("The source directory is not set.\n"
+ "Please set it using the Project Options dialog.\n"));
+ }
+
+ if (!glade_util_directories_equivalent (project->directory,
+ project->source_directory)
+ && !glade_util_directory_contains_file (project->directory,
+ project->source_directory))
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Invalid source directory:\n\n"
+ "The source directory must be the project directory\n"
+ "or a subdirectory of the project directory.\n"));
+ }
+
+ if (project->pixmaps_directory == NULL)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("The pixmaps directory is not set.\n"
+ "Please set it using the Project Options dialog.\n"));
+ }
+
+ /* Copy any pixmaps to the project's pixmaps directory. */
+ error = glade_project_copy_all_pixmaps (project);
+ if (error)
+ return error;
+
+ /* We call a function according to the project's language. */
+ switch (project->language)
+ {
+ case GLADE_LANGUAGE_C:
+ return glade_project_write_c_source (project);
+ case GLADE_LANGUAGE_CPP:
+ return glade_project_write_cxx_source (project);
+ case GLADE_LANGUAGE_ADA95:
+ return glade_project_write_ada95_source (project);
+ case GLADE_LANGUAGE_PERL:
+ return glade_project_write_perl_source (project);
+ case GLADE_LANGUAGE_EIFFEL:
+ return glade_project_write_eiffel_source (project);
+ default:
+ break;
+ }
+
+ /* Shouldn't get here. */
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Sorry - generating source for %s is not implemented yet"),
+ GladeLanguages[project->language]);
+}
+
+
+/* C source code output is built in to Glade, so we just call the main
+ C source code generation function here. */
+static GladeError*
+glade_project_write_c_source (GladeProject *project)
+{
+ return source_write (project);
+}
+
+/*
+ * Iterate through the list of widgets to ensure we're not using any
+ * deprecated widgets in the project when emitting C++ code.
+ */
+static gboolean
+check_deprecated_widget (GList* list)
+{
+ GtkWidget* widget;
+ GList* tmpList;
+ gboolean status;
+
+ for (; list != NULL; list = list->next )
+ {
+ widget = GTK_WIDGET (list->data);
+
+ if (GTK_IS_CONTAINER (widget))
+ {
+ tmpList = gtk_container_get_children (GTK_CONTAINER (widget));
+ status = check_deprecated_widget (tmpList);
+ g_list_free (tmpList);
+
+ if (!status)
+ {
+ return FALSE;
+ }
+ }
+
+ /* Check if any deprecated widgets are being used. Note that we only
+ check for widgets created by Glade, since GtkCombo uses a GtkList
+ internally and we don't want to disallow that. */
+ if (GB_IS_GB_WIDGET (widget)
+ && (GTK_IS_CLIST (widget) ||
+ GTK_IS_CTREE (widget) ||
+ GTK_IS_LIST (widget) ||
+ GTK_IS_PIXMAP (widget) ||
+ GTK_IS_PREVIEW (widget) ))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Use system() to run glade-- on the XML file to generate C++ source code. */
+static GladeError*
+glade_project_write_cxx_source (GladeProject *project)
+{
+ gchar *command_buffer;
+ gint status;
+
+ /*
+ * Ensure that our project does not have deprecated widgets
+ * that gtkmm-2 doesn't support.
+ */
+ if ( !check_deprecated_widget (project->components))
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Your project uses deprecated widgets that Gtkmm-2\n"
+ "does not support. Check your project for these\n"
+ "widgets, and use their replacements."));
+ }
+
+ command_buffer = g_strdup_printf ("glade-- %s", project->xml_filename);
+ status = system (command_buffer);
+ g_free (command_buffer);
+
+ if (status != 0)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Error running glade-- to generate the C++ source code.\n"
+ "Check that you have glade-- installed and that it is in your PATH.\n"
+ "Then try running 'glade-- <project_file.glade>' in a terminal."));
+ }
+
+ return NULL;
+}
+
+
+/* Use system() to run gate on the XML file to generate Ada95 source code. */
+static GladeError*
+glade_project_write_ada95_source (GladeProject *project)
+{
+ gchar *command_buffer;
+ gint status;
+
+#ifdef _WIN32
+ chdir(project->directory);
+#endif
+
+ command_buffer = g_strdup_printf ("gate %s", project->xml_filename);
+ status = system (command_buffer);
+ g_free (command_buffer);
+
+ if (status != 0)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Error running gate to generate the Ada95 source code.\n"
+ "Check that you have gate installed and that it is in your PATH.\n"
+ "Then try running 'gate <project_file.glade>' in a terminal."));
+ }
+
+ return NULL;
+}
+
+
+/* Use system() to run gate on the XML file to generate Ada95 source code. */
+static GladeError*
+glade_project_write_perl_source (GladeProject *project)
+{
+ gchar *command_buffer;
+ gint status;
+
+ command_buffer = g_strdup_printf ("glade2perl %s", project->xml_filename);
+ status = system (command_buffer);
+ g_free (command_buffer);
+
+ if (status != 0)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Error running glade2perl to generate the Perl source code.\n"
+ "Check that you have glade2perl installed and that it is in your PATH.\n"
+ "Then try running 'glade2perl <project_file.glade>' in a terminal."));
+ }
+
+ return NULL;
+}
+
+
+/* Use system() to run eglade on the XML file to generate Eiffel source code. */
+static GladeError*
+glade_project_write_eiffel_source (GladeProject *project)
+{
+ gchar *command_buffer;
+ gint status;
+
+ command_buffer = g_strdup_printf ("eglade %s", project->xml_filename);
+ status = system (command_buffer);
+ g_free (command_buffer);
+
+ if (status != 0)
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("Error running eglade to generate the Eiffel source code.\n"
+ "Check that you have eglade installed and that it is in your PATH.\n"
+ "Then try running 'eglade <project_file.glade>' in a terminal."));
+ }
+
+ return NULL;
+}
+
+
+/* This should be called by anything which changes the project - adding or
+ removing widgets, changing properties, setting project options etc.
+ FIXME: It's not used throughout Glade yet. */
+void
+glade_project_set_changed (GladeProject *project,
+ gboolean changed)
+{
+ project->changed = changed;
+}
+
+
+gchar*
+glade_project_get_name (GladeProject *project)
+{
+ return project->name;
+}
+
+
+void
+glade_project_set_name (GladeProject *project,
+ const gchar *name)
+{
+ if (glade_util_strings_equivalent (project->name, name))
+ return;
+ g_free (project->name);
+ project->name = g_strdup (name);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_program_name (GladeProject *project)
+{
+ return project->program_name;
+}
+
+
+void
+glade_project_set_program_name (GladeProject *project,
+ const gchar *program_name)
+{
+ if (glade_util_strings_equivalent (project->program_name, program_name))
+ return;
+ g_free (project->program_name);
+ project->program_name = g_strdup (program_name);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_xml_filename (GladeProject *project)
+{
+ return project->xml_filename;
+}
+
+
+void
+glade_project_set_xml_filename (GladeProject *project,
+ const gchar *filename)
+{
+ gchar *xml_directory;
+
+ if (glade_util_strings_equivalent (project->xml_filename, filename))
+ return;
+ g_free (project->xml_filename);
+ project->xml_filename = g_strdup (filename);
+ xml_directory = glade_util_dirname (filename);
+
+ /* If the project directories are not set, set them to defaults based on
+ the directory the XML file is in. */
+ if (!project->directory || project->directory[0] == '\0')
+ {
+ project->directory = g_strdup (xml_directory);
+ }
+
+ if (!project->source_directory || project->source_directory[0] == '\0')
+ {
+ project->source_directory = glade_util_make_path (project->directory,
+ "src");
+ }
+
+ if (!project->pixmaps_directory || project->pixmaps_directory[0] == '\0')
+ {
+ project->pixmaps_directory = glade_util_make_path (project->directory,
+ "pixmaps");
+ }
+
+ g_free (xml_directory);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_directory (GladeProject *project)
+{
+ return project->directory;
+}
+
+
+void
+glade_project_set_directory (GladeProject *project,
+ const gchar *directory)
+{
+ if (glade_util_strings_equivalent (project->directory, directory))
+ return;
+ g_free (project->directory);
+ project->directory = g_strdup (directory);
+ glade_project_set_changed (project, TRUE);
+
+ /* If the pixmaps directory is not set, set it to defaults based on
+ the source directory. */
+ if (directory && directory[0] != '\0')
+ {
+ if (!project->pixmaps_directory || project->pixmaps_directory[0] == '\0')
+ {
+ project->pixmaps_directory = glade_util_make_path (directory,
+ "pixmaps");
+ }
+ }
+}
+
+
+gchar*
+glade_project_get_source_directory (GladeProject *project)
+{
+ return project->source_directory;
+}
+
+
+void
+glade_project_set_source_directory (GladeProject *project,
+ const gchar *directory)
+{
+ if (glade_util_strings_equivalent (project->source_directory, directory))
+ return;
+ g_free (project->source_directory);
+ project->source_directory = g_strdup (directory);
+
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_pixmaps_directory (GladeProject *project)
+{
+ return project->pixmaps_directory;
+}
+
+
+void
+glade_project_set_pixmaps_directory (GladeProject *project,
+ const gchar *directory)
+{
+ if (glade_util_strings_equivalent (project->pixmaps_directory, directory))
+ return;
+ g_free (project->pixmaps_directory);
+ project->pixmaps_directory = g_strdup (directory);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gint
+glade_project_get_language (GladeProject *project)
+{
+ return project->language;
+}
+
+
+void
+glade_project_set_language (GladeProject *project,
+ GladeLanguageType language)
+{
+ if (project->language == language)
+ return;
+ project->language = language;
+ property_show_lang_specific_page (language);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_set_language_name (GladeProject *project,
+ const gchar *language_name)
+{
+ gint language;
+
+ if (language_name == NULL || language_name[0] == '\0')
+ return FALSE;
+
+ for (language = 0; language < GladeNumLanguages; language++)
+ {
+ if (!strcmp (language_name, GladeLanguages[language]))
+ {
+ glade_project_set_language (project, language);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void
+glade_project_add_component (GladeProject *project,
+ GtkWidget *component)
+{
+ project->components = g_list_append (project->components, component);
+ tree_add_widget (component);
+ gtk_signal_emit (GTK_OBJECT (project),
+ glade_project_signals[ADD_COMPONENT], component);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+void
+glade_project_show_component (GladeProject *project,
+ GtkWidget *component)
+{
+ /* Popup menus are shown in the menu editor. */
+ if (GTK_IS_MENU (component))
+ {
+ GtkWidget *menued;
+
+ menued = glade_menu_editor_new (project, GTK_MENU_SHELL (component));
+ gtk_widget_show (menued);
+ }
+ else if (GTK_IS_WINDOW (component))
+ {
+ gtk_widget_show (component);
+ /* This maps the window, which de-iconifies it according to the ICCCM. */
+ gdk_window_show (component->window);
+ /* This raises is to the top, in case it was hidden. */
+ gdk_window_raise (component->window);
+ }
+ else
+ g_warning ("Don't know how to show component.");
+}
+
+
+void
+glade_project_component_changed (GladeProject *project,
+ GtkWidget *component)
+{
+ gtk_signal_emit (GTK_OBJECT (project),
+ glade_project_signals[COMPONENT_CHANGED], component);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+void
+glade_project_foreach_component (GladeProject *project,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GList *tmp_list;
+
+ g_return_if_fail (project != NULL);
+
+ tmp_list = project->components;
+ while (tmp_list)
+ {
+ (*callback) (GTK_WIDGET (tmp_list->data), callback_data);
+ tmp_list = tmp_list->next;
+ }
+}
+
+
+void
+glade_project_remove_component (GladeProject *project,
+ GtkWidget *component)
+{
+ project->components = g_list_remove (project->components, component);
+ gtk_signal_emit (GTK_OBJECT (project),
+ glade_project_signals[REMOVE_COMPONENT], component);
+
+ /* FIXME: These could be better. */
+ property_set_widget (NULL);
+ editor_clear_selection (NULL);
+
+ gtk_widget_destroy (component);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+/* These add/remove pixmaps to the project. The same filename can appear
+ more than once in the project's list of pixmaps, so refcounting isn't
+ needed. The filename is copied. */
+void
+glade_project_add_pixmap (GladeProject *project,
+ const gchar *filename)
+{
+ if (filename && filename[0])
+ {
+#if 0
+ g_print ("Adding pixmap: %s\n", filename);
+#endif
+ project->pixmap_filenames = g_list_prepend (project->pixmap_filenames,
+ g_strdup (filename));
+ glade_project_set_changed (project, TRUE);
+ }
+}
+
+
+/* This removes the given pixmap from the project. If the pixmap isn't in
+ the project it is ignored. */
+void
+glade_project_remove_pixmap (GladeProject *project,
+ const gchar *filename)
+{
+ GList *element;
+
+ if (!filename)
+ return;
+
+#if 0
+ g_print ("Removing pixmap: %s\n", filename);
+#endif
+
+ element = project->pixmap_filenames;
+ while (element)
+ {
+ if (!strcmp (element->data, filename))
+ {
+ project->pixmap_filenames = g_list_remove_link (project->pixmap_filenames, element);
+ g_free (element->data);
+ g_list_free (element);
+
+ glade_project_set_changed (project, TRUE);
+ break;
+ }
+ element = element->next;
+ }
+}
+
+
+/* This ensures that all pixmaps are in the project's pixmaps directory,
+ by copying them if necessary. Note that it doesn't change the pixmap
+ filenames in the list. They will be updated the next time the project is
+ opened. */
+GladeError*
+glade_project_copy_all_pixmaps (GladeProject *project)
+{
+ gchar *pixmaps_dir, *filename, *new_filename;
+ gint pixmaps_dir_len;
+ GList *element;
+ GladeError *error = NULL;
+ gboolean checked_pixmaps_dir = FALSE;
+
+ pixmaps_dir = glade_project_get_pixmaps_directory (project);
+ if (!pixmaps_dir || pixmaps_dir[0] == '\0')
+ {
+ return glade_error_new_general (GLADE_STATUS_ERROR,
+ _("The pixmap directory is not set.\n"
+ "Please set it using the Project Options dialog.\n"));
+ }
+
+ pixmaps_dir_len = strlen (pixmaps_dir);
+
+ element = project->pixmap_filenames;
+ while (element)
+ {
+ filename = (gchar*) element->data;
+
+ /* If the start of the pixmap filename doesn't match the pixmaps
+ directory, we make sure it is copied there. */
+ if (!glade_util_directory_contains_file (pixmaps_dir, filename))
+ {
+ new_filename = glade_util_make_path (pixmaps_dir,
+ g_basename (filename));
+
+ /* Check if it already exists, and copy if it doesn't. */
+ if (!glade_util_file_exists (new_filename))
+ {
+ /* We only want to do this once. */
+ if (!checked_pixmaps_dir)
+ {
+ checked_pixmaps_dir = TRUE;
+ error = glade_util_ensure_directory_exists (project->pixmaps_directory);
+ if (error)
+ {
+ g_free (new_filename);
+ break;
+ }
+ }
+
+ error = glade_util_copy_file (filename, new_filename);
+ g_free (new_filename);
+ if (error)
+ break;
+ }
+ }
+ element = element->next;
+ }
+
+ return error;
+}
+
+
+gchar*
+glade_project_get_current_directory (GladeProject *project)
+{
+ return project->current_directory;
+}
+
+
+void
+glade_project_set_current_directory (GladeProject *project,
+ const gchar *directory)
+{
+ g_free (project->current_directory);
+ project->current_directory = g_strdup (directory);
+}
+
+
+gboolean
+glade_project_get_gnome_support (GladeProject *project)
+{
+ return project->gnome_support;
+}
+
+
+void
+glade_project_set_gnome_support (GladeProject *project,
+ gboolean gnome_support)
+{
+ if (project->gnome_support == gnome_support)
+ return;
+
+ /* If we don't have Gnome support compiled-in, we can't build a Gnome app. */
+#ifndef USE_GNOME
+ if (gnome_support == TRUE)
+ return;
+#endif
+
+ project->gnome_support = gnome_support;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_gnome_db_support (GladeProject *project)
+{
+ return project->gnome_db_support;
+}
+
+
+void
+glade_project_set_gnome_db_support (GladeProject *project,
+ gboolean gnome_db_support)
+{
+ if (project->gnome_db_support == gnome_db_support)
+ return;
+
+ project->gnome_db_support = gnome_db_support;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+/*
+ * C Output options.
+ */
+gboolean
+glade_project_get_gettext_support (GladeProject *project)
+{
+ return project->gettext_support;
+}
+
+
+void
+glade_project_set_gettext_support (GladeProject *project,
+ gboolean gettext_support)
+{
+ if (project->gettext_support == gettext_support)
+ return;
+ project->gettext_support = gettext_support;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_use_widget_names (GladeProject *project)
+{
+ return project->use_widget_names;
+}
+
+
+void
+glade_project_set_use_widget_names (GladeProject *project,
+ gboolean use_widget_names)
+{
+ if (project->use_widget_names == use_widget_names)
+ return;
+ project->use_widget_names = use_widget_names;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_output_main_file (GladeProject *project)
+{
+ return project->output_main_file;
+}
+
+
+void
+glade_project_set_output_main_file (GladeProject *project,
+ gboolean output_main_file)
+{
+ if (project->output_main_file == output_main_file)
+ return;
+ project->output_main_file = output_main_file;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_output_support_files (GladeProject *project)
+{
+ return project->output_support_files;
+}
+
+
+void
+glade_project_set_output_support_files (GladeProject *project,
+ gboolean output_support_files)
+{
+ if (project->output_support_files == output_support_files)
+ return;
+ project->output_support_files = output_support_files;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_output_build_files (GladeProject *project)
+{
+ return project->output_build_files;
+}
+
+
+void
+glade_project_set_output_build_files (GladeProject *project,
+ gboolean output_build_files)
+{
+ if (project->output_build_files == output_build_files)
+ return;
+ project->output_build_files = output_build_files;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_backup_source_files (GladeProject *project)
+{
+ return project->backup_source_files;
+}
+
+
+void
+glade_project_set_backup_source_files (GladeProject *project,
+ gboolean backup_source_files)
+{
+ if (project->backup_source_files == backup_source_files)
+ return;
+ project->backup_source_files = backup_source_files;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gboolean
+glade_project_get_gnome_help_support (GladeProject *project)
+{
+ return project->gnome_help_support;
+}
+
+
+void
+glade_project_set_gnome_help_support (GladeProject *project,
+ gboolean gnome_help_support)
+{
+ if (project->gnome_help_support == gnome_help_support)
+ return;
+
+ project->gnome_help_support = gnome_help_support;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+/* FIXME: These will be removed when the source code output is improved. */
+void
+glade_project_get_source_files (GladeProject *project,
+ gchar **main_source_file,
+ gchar **main_header_file,
+ gchar **handler_source_file,
+ gchar **handler_header_file)
+{
+ *main_source_file = project->main_source_file;
+ *main_header_file = project->main_header_file;
+ *handler_source_file = project->handler_source_file;
+ *handler_header_file = project->handler_header_file;
+}
+
+
+void
+glade_project_set_source_files (GladeProject *project,
+ const gchar *main_source_file,
+ const gchar *main_header_file,
+ const gchar *handler_source_file,
+ const gchar *handler_header_file)
+{
+ if (glade_util_strings_equivalent (project->main_source_file,
+ main_source_file)
+ && glade_util_strings_equivalent (project->main_header_file,
+ main_header_file)
+ && glade_util_strings_equivalent (project->handler_source_file,
+ handler_source_file)
+ && glade_util_strings_equivalent (project->handler_header_file,
+ handler_header_file))
+ return;
+
+ g_free (project->main_source_file);
+ g_free (project->main_header_file);
+ g_free (project->handler_source_file);
+ g_free (project->handler_header_file);
+ project->main_source_file = g_strdup (main_source_file);
+ project->main_header_file = g_strdup (main_header_file);
+ project->handler_source_file = g_strdup (handler_source_file);
+ project->handler_header_file = g_strdup (handler_header_file);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_support_source_file (GladeProject *project)
+{
+ return project->support_source_file;
+}
+
+
+void
+glade_project_set_support_source_file (GladeProject *project,
+ const gchar* support_source_file)
+{
+ if (glade_util_strings_equivalent (project->support_source_file,
+ support_source_file))
+ return;
+ g_free (project->support_source_file);
+ project->support_source_file = g_strdup (support_source_file);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_support_header_file (GladeProject *project)
+{
+ return project->support_header_file;
+}
+
+
+void
+glade_project_set_support_header_file (GladeProject *project,
+ const gchar* support_header_file)
+{
+ if (glade_util_strings_equivalent (project->support_header_file,
+ support_header_file))
+ return;
+ g_free (project->support_header_file);
+ project->support_header_file = g_strdup (support_header_file);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+/*
+ * libglade options.
+ */
+
+gboolean
+glade_project_get_output_translatable_strings (GladeProject *project)
+{
+ return project->output_translatable_strings;
+}
+
+
+void
+glade_project_set_output_translatable_strings (GladeProject *project,
+ gboolean output_translatable_strings)
+{
+ if (project->output_translatable_strings == output_translatable_strings)
+ return;
+ project->output_translatable_strings = output_translatable_strings;
+ glade_project_set_changed (project, TRUE);
+}
+
+
+gchar*
+glade_project_get_translatable_strings_file (GladeProject *project)
+{
+ return project->translatable_strings_file;
+}
+
+
+void
+glade_project_set_translatable_strings_file (GladeProject *project,
+ const gchar* file)
+{
+ if (glade_util_strings_equivalent (project->translatable_strings_file, file))
+ return;
+ g_free (project->translatable_strings_file);
+ project->translatable_strings_file = g_strdup (file);
+ glade_project_set_changed (project, TRUE);
+}
+
+
+/*
+ * Loading Project Options.
+ */
+typedef enum {
+ PARSER_OPTION,
+ PARSER_UNKNOWN
+} OptionsParserState;
+
+typedef struct _GladeOptionsParseState GladeOptionsParseState;
+struct _GladeOptionsParseState {
+ OptionsParserState state;
+
+ GladeProject *project;
+
+ gchar *base_directory;
+
+ GString *option_name;
+ GString *option_value;
+};
+
+
+/* This sets one project option, as it is loaded by the SAX parser. */
+void
+glade_project_load_option (GladeOptionsParseState *state)
+{
+ GladeProject *project;
+ gchar *base, *option_name, *option_value;
+
+ project = state->project;
+ base = state->base_directory;
+ option_name = state->option_name->str;
+ option_value = state->option_value->str;
+
+#if 0
+ g_print ("Setting Option:'%s' to '%s'\n", option_name, option_value);
+#endif
+
+ if (!strcmp (option_name, "name"))
+ {
+ g_free (project->name);
+ project->name = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "program_name"))
+ {
+ g_free (project->program_name);
+ project->program_name = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "directory") && base)
+ {
+ g_free (project->directory);
+ project->directory = glade_util_make_absolute_path (base, option_value);
+ }
+ else if (!strcmp (option_name, "source_directory") && base)
+ {
+ g_free (project->source_directory);
+ project->source_directory = glade_util_make_absolute_path (base,
+ option_value);
+ }
+ else if (!strcmp (option_name, "pixmaps_directory") && base)
+ {
+ g_free (project->pixmaps_directory);
+ project->pixmaps_directory = glade_util_make_absolute_path (base,
+ option_value);
+ }
+ else if (!strcmp (option_name, "language"))
+ {
+ if (!glade_project_set_language_name (project, option_value))
+ g_warning ("Invalid source language");
+ }
+ else if (!strcmp (option_name, "gnome_support"))
+ {
+ gboolean gnome_support = load_parse_bool (NULL, option_value);
+#ifndef USE_GNOME
+ if (gnome_support == TRUE)
+ {
+ g_warning ("Glade has been compiled without support for Gnome.");
+ }
+#endif
+ project->gnome_support = gnome_support;
+ }
+ else if (!strcmp (option_name, "gnome_db_support"))
+ {
+ gboolean gnome_db_support = load_parse_bool (NULL, option_value);
+#ifndef USE_GNOME_DB
+ if (gnome_db_support == TRUE)
+ {
+ g_warning ("Glade has been compiled without support for Gnome DB.");
+ }
+#endif
+ project->gnome_db_support = gnome_db_support;
+ }
+ else if (!strcmp (option_name, "gettext_support"))
+ {
+ project->gettext_support = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "use_widget_names"))
+ {
+ project->use_widget_names = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "output_main_file"))
+ {
+ project->output_main_file = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "output_support_files"))
+ {
+ project->output_support_files = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "output_build_files"))
+ {
+ project->output_build_files = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "backup_source_files"))
+ {
+ project->backup_source_files = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "gnome_help_support"))
+ {
+ project->gnome_help_support = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "main_source_file"))
+ {
+ g_free (project->main_source_file);
+ project->main_source_file = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "main_header_file"))
+ {
+ g_free (project->main_header_file);
+ project->main_header_file = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "handler_source_file"))
+ {
+ g_free (project->handler_source_file);
+ project->handler_source_file = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "handler_header_file"))
+ {
+ g_free (project->handler_header_file);
+ project->handler_header_file = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "support_source_file"))
+ {
+ g_free (project->support_source_file);
+ project->support_source_file = glade_util_copy_string (option_value);
+ }
+ else if (!strcmp (option_name, "support_header_file"))
+ {
+ g_free (project->support_header_file);
+ project->support_header_file = glade_util_copy_string (option_value);
+ }
+
+ else if (!strcmp (option_name, "output_translatable_strings"))
+ {
+ project->output_translatable_strings = load_parse_bool (NULL, option_value);
+ }
+ else if (!strcmp (option_name, "translatable_strings_file") && base)
+ {
+ g_free (project->translatable_strings_file);
+ project->translatable_strings_file = glade_util_make_absolute_path (base, option_value);
+ }
+
+ else
+ {
+ g_warning ("Unknown project option: %s\n", option_name);
+ }
+}
+
+
+static xmlEntityPtr
+glade_options_parser_get_entity(GladeOptionsParseState *state, const xmlChar *name)
+{
+ return xmlGetPredefinedEntity(name);
+}
+
+static void
+glade_options_parser_warning(GladeOptionsParseState *state, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_WARNING, msg, args);
+ va_end(args);
+}
+
+static void
+glade_options_parser_error(GladeOptionsParseState *state, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_CRITICAL, msg, args);
+ va_end(args);
+}
+
+static void
+glade_options_parser_fatal_error(GladeOptionsParseState *state, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_ERROR, msg, args);
+ va_end(args);
+}
+
+static void
+glade_options_parser_start_document(GladeOptionsParseState *state)
+{
+ state->state = PARSER_UNKNOWN;
+
+ state->option_name = g_string_sized_new (128);
+ state->option_value = g_string_sized_new (1024);
+}
+
+static void
+glade_options_parser_end_document(GladeOptionsParseState *state)
+{
+ g_string_free (state->option_name, TRUE);
+ g_string_free (state->option_value, TRUE);
+}
+
+static void
+glade_options_parser_start_element(GladeOptionsParseState *state,
+ const xmlChar *name, const xmlChar **attrs)
+{
+ g_string_assign (state->option_name, name);
+ g_string_truncate (state->option_value, 0);
+
+ state->state = PARSER_OPTION;
+}
+
+static void
+glade_options_parser_end_element(GladeOptionsParseState *state, const xmlChar *name)
+{
+ if (state->state != PARSER_OPTION)
+ return;
+
+ glade_project_load_option (state);
+
+ state->state = PARSER_UNKNOWN;
+}
+
+static void
+glade_options_parser_characters(GladeOptionsParseState *state, const xmlChar *chars, int len)
+{
+ switch (state->state) {
+ case PARSER_OPTION:
+ g_string_append_len (state->option_value, chars, len);
+ break;
+ default:
+ /* don't care about content in any other states */
+ break;
+ }
+}
+
+static xmlSAXHandler glade_options_parser = {
+ 0, /* internalSubset */
+ 0, /* isStandalone */
+ 0, /* hasInternalSubset */
+ 0, /* hasExternalSubset */
+ 0, /* resolveEntity */
+ (getEntitySAXFunc)glade_options_parser_get_entity, /* getEntity */
+ 0, /* entityDecl */
+ 0, /* notationDecl */
+ 0, /* attributeDecl */
+ 0, /* elementDecl */
+ 0, /* unparsedEntityDecl */
+ 0, /* setDocumentLocator */
+ (startDocumentSAXFunc)glade_options_parser_start_document, /* startDocument */
+ (endDocumentSAXFunc)glade_options_parser_end_document, /* endDocument */
+ (startElementSAXFunc)glade_options_parser_start_element, /* startElement */
+ (endElementSAXFunc)glade_options_parser_end_element, /* endElement */
+ 0, /* reference */
+ (charactersSAXFunc)glade_options_parser_characters, /* characters */
+ 0, /* ignorableWhitespace */
+ 0, /* processingInstruction */
+ (commentSAXFunc)0, /* comment */
+ (warningSAXFunc)glade_options_parser_warning, /* warning */
+ (errorSAXFunc)glade_options_parser_error, /* error */
+ (fatalErrorSAXFunc)glade_options_parser_fatal_error, /* fatalError */
+};
+
+
+
+
+/* Returns TRUE if the options file was found and loaded OK. */
+gboolean
+glade_project_load_options (GladeProject *project)
+{
+ gchar *filename, *base;
+ gboolean retval = FALSE;
+
+ /* Check if the options file exists. If it doesn't we use defaults for
+ everything. */
+ filename = g_strdup_printf ("%sp", GladeSessionFile ? GladeSessionFile : project->xml_filename);
+ base = project->xml_filename ? g_dirname (project->xml_filename) : NULL;
+
+ if (glade_util_file_exists (filename))
+ {
+ GladeOptionsParseState state = { 0 };
+
+ state.project = project;
+ state.base_directory = base;
+
+ if (xmlSAXUserParseFile (&glade_options_parser, &state, filename) < 0)
+ {
+ g_warning("document not well formed!");
+ }
+ else
+ {
+ retval = TRUE;
+ }
+ }
+
+ /* Check that the directory options are set to defaults, but only if we
+ have a project filename set. We may not have one when loading a session
+ file. */
+ if (base)
+ {
+ if (project->directory == NULL)
+ project->directory = g_strdup (base);
+ if (project->source_directory == NULL)
+ project->source_directory = glade_util_make_absolute_path (base, "src");
+ if (project->pixmaps_directory == NULL)
+ project->pixmaps_directory = glade_util_make_absolute_path (base,
+ "pixmaps");
+ }
+
+ g_free (filename);
+ g_free (base);
+
+ return retval;
+}
+
+
+/*
+ * Saving Project Options.
+ */
+static void
+save_option (GString *buffer, gint indent, gchar *tag_name, gchar *tag_value)
+{
+ gint i;
+
+ for (i = 0; i < indent; i++)
+ g_string_append (buffer, " ");
+
+ g_string_append_printf (buffer, "<%s>%s</%s>\n",
+ tag_name, tag_value ? tag_value : "", tag_name);
+}
+
+
+static void
+save_bool_option (GString *buffer, gint indent, gchar *tag_name,
+ gboolean tag_value)
+{
+ save_option (buffer, indent, tag_name, tag_value ? "TRUE" : "FALSE");
+}
+
+
+GladeError*
+glade_project_save_options (GladeProject *project,
+ FILE *fp)
+{
+ GladeError *error = NULL;
+ GString *buffer;
+ gchar *base_dir, *dir, *file;
+ gint indent = 1, bytes_written;
+
+ buffer = g_string_sized_new (1024);
+
+ g_string_append (buffer, "<glade-project>\n");
+
+ save_option (buffer, indent, "name", project->name);
+ save_option (buffer, indent, "program_name", project->program_name);
+
+ /* All directories are saved relative to the xml file's directory. */
+ base_dir = glade_util_dirname (project->xml_filename);
+
+ /* We use defaults for most properties so only a few properties need to be
+ saved. */
+
+ dir = glade_util_make_relative_path (base_dir, project->directory);
+ if (strcmp (dir, ""))
+ save_option (buffer, indent, "directory", dir);
+ g_free (dir);
+
+ dir = glade_util_make_relative_path (base_dir, project->source_directory);
+ if (strcmp (dir, "src"))
+ save_option (buffer, indent, "source_directory", dir);
+ g_free (dir);
+
+ dir = glade_util_make_relative_path (base_dir, project->pixmaps_directory);
+ if (strcmp (dir, "pixmaps"))
+ save_option (buffer, indent, "pixmaps_directory", dir);
+ g_free (dir);
+
+ if (project->language != GLADE_LANGUAGE_C)
+ save_option (buffer, indent, "language", GladeLanguages[project->language]);
+ if (!project->gnome_support)
+ save_bool_option (buffer, indent, "gnome_support", project->gnome_support);
+
+ if (project->gnome_db_support)
+ save_bool_option (buffer, indent, "gnome_db_support", project->gnome_db_support);
+
+
+ /*
+ * C Options.
+ */
+ if (!project->gettext_support)
+ save_bool_option (buffer, indent, "gettext_support", project->gettext_support);
+ if (project->use_widget_names)
+ save_bool_option (buffer, indent, "use_widget_names", project->use_widget_names);
+ if (!project->output_main_file)
+ save_bool_option (buffer, indent, "output_main_file", project->output_main_file);
+ if (!project->output_support_files)
+ save_bool_option (buffer, indent, "output_support_files", project->output_support_files);
+ if (!project->output_build_files)
+ save_bool_option (buffer, indent, "output_build_files", project->output_build_files);
+ if (!project->backup_source_files)
+ save_bool_option (buffer, indent, "backup_source_files", project->backup_source_files);
+ if (project->gnome_help_support)
+ save_bool_option (buffer, indent, "gnome_help_support", project->gnome_help_support);
+
+ if (!project->main_source_file
+ || strcmp (project->main_source_file, "interface.c"))
+ save_option (buffer, indent, "main_source_file", project->main_source_file);
+ if (!project->main_header_file
+ || strcmp (project->main_header_file, "interface.h"))
+ save_option (buffer, indent, "main_header_file", project->main_header_file);
+ if (!project->handler_source_file
+ || strcmp (project->handler_source_file, "callbacks.c"))
+ save_option (buffer, indent, "handler_source_file", project->handler_source_file);
+ if (!project->handler_header_file
+ || strcmp (project->handler_header_file, "callbacks.h"))
+ save_option (buffer, indent, "handler_header_file", project->handler_header_file);
+ if (!project->support_source_file
+ || strcmp (project->support_source_file, "support.c"))
+ save_option (buffer, indent, "support_source_file", project->support_source_file);
+ if (!project->support_header_file
+ || strcmp (project->support_header_file, "support.h"))
+ save_option (buffer, indent, "support_header_file", project->support_header_file);
+
+ if (project->output_translatable_strings)
+ save_bool_option (buffer, indent, "output_translatable_strings", TRUE);
+ if (project->translatable_strings_file
+ && project->translatable_strings_file[0])
+ {
+ file = glade_util_make_relative_path (base_dir, project->translatable_strings_file);
+ if (strcmp (file, ""))
+ save_option (buffer, indent, "translatable_strings_file", file);
+ g_free (file);
+ }
+
+ g_free (base_dir);
+
+ g_string_append (buffer, "</glade-project>\n");
+
+ bytes_written = fwrite (buffer->str, sizeof (gchar), buffer->len, fp);
+ if (bytes_written != buffer->len)
+ error = glade_error_new_system (_("Error writing project XML file\n"));
+
+ g_string_free (buffer, TRUE);
+
+ return error;
+}
+
+
+/*
+ * Functions to do with ensuring widget names are unique.
+ */
+
+/* This returns a unique name for a widget using the given base name, often
+ a widget class name. If the base name starts with 'Gtk' or 'Gnome' then
+ that is taken off. The base name is converted to lower case and a number is
+ added on to the end of it to ensure that no other widget in the project
+ uses the same name. */
+gchar*
+glade_project_new_widget_name (GladeProject *project,
+ const gchar *base_name)
+{
+ char new_widget_name[128], *id_start;
+ gint widget_id, i, new_widget_name_len;
+
+ /* Check we won't overflow the buffer. */
+ g_return_val_if_fail (strlen (base_name) < 100, g_strdup (base_name));
+
+ /* Skip 'Gtk' or 'Gnome' at the start of all class names. */
+ if (!strncmp (base_name, "Gtk", 3))
+ base_name += 3;
+ else if (!strncmp (base_name, "Gnome", 5))
+ base_name += 5;
+
+ strcpy (new_widget_name, base_name);
+
+ /* Remove any id number at the end of the name. */
+ id_start = glade_project_find_id (project, new_widget_name);
+ if (id_start)
+ *id_start = '\0';
+
+ /* convert name to lower case (only normal ASCII chars) */
+ new_widget_name_len = strlen (new_widget_name);
+ for (i = 0; i < new_widget_name_len; i++)
+ {
+ if ((new_widget_name[i] >= 'A') && (new_widget_name[i] <= 'Z'))
+ new_widget_name[i] += 'a' - 'A';
+ }
+
+ widget_id = GPOINTER_TO_INT (g_hash_table_lookup (project->unique_id_hash,
+ new_widget_name));
+ if (widget_id == 0)
+ {
+ widget_id = 1;
+ g_hash_table_insert (project->unique_id_hash, g_strdup (new_widget_name),
+ GINT_TO_POINTER (widget_id));
+ }
+ else
+ {
+ widget_id++;
+ /* We don't need to g_strdup new_widget_name since it is already in the
+ hash. */
+ g_hash_table_insert (project->unique_id_hash, new_widget_name,
+ GINT_TO_POINTER (widget_id));
+ }
+
+ /* Add the ID onto the end of the name. */
+ sprintf (new_widget_name + strlen (new_widget_name), "%i", widget_id);
+
+ MSG1 ("Allocating new widget name: %s", new_widget_name);
+ return g_strdup (new_widget_name);
+}
+
+
+/* This releases a widget name, so that it can possibly be used again.
+ It will only be reused if it is the last ID with the same prefix. This is
+ still useful as it means that if a name is generated based on something
+ the user edits (e.g. a menuitem label), only the final name is reserved -
+ all the intermediate names get released so we don't waste IDs. */
+void
+glade_project_release_widget_name (GladeProject *project,
+ const gchar *name)
+{
+ gchar buffer[128];
+ const gchar *id_start;
+ gint id = 0, current_id;
+ gpointer hash_key, hash_value;
+ gboolean found;
+
+ id_start = glade_project_find_id (project, name);
+ if (id_start == NULL)
+ return;
+
+ /* Make sure we won't overflow the buffer. */
+ g_return_if_fail (id_start - name < 127);
+
+ id = atoi (id_start);
+ if (id == 0)
+ return;
+
+ strncpy (buffer, name, id_start - name);
+ buffer[id_start - name] = '\0';
+
+ found = g_hash_table_lookup_extended (project->unique_id_hash, buffer,
+ &hash_key, &hash_value);
+ if (found)
+ {
+ current_id = GPOINTER_TO_INT (hash_value);
+ /* We only release the ID if it is the last one. */
+ if (current_id == id)
+ {
+ /* If the current ID is 1, remove it from the hash completely. */
+ if (current_id == 1)
+ {
+ g_hash_table_remove (project->unique_id_hash, buffer);
+ g_free (hash_key);
+ }
+ else
+ {
+ /* We don't need to g_strdup buffer since it is already in the
+ hash. */
+ g_hash_table_insert (project->unique_id_hash, buffer,
+ GINT_TO_POINTER (id - 1));
+ }
+ }
+ }
+}
+
+
+/* Check if the name has a trailing ID number, and if so compare it to the
+ current maximum in the ID hash and update if necessary. */
+void
+glade_project_reserve_name (GladeProject *project,
+ const gchar *name)
+{
+ gchar buffer[128];
+ const gchar *id_start;
+ gint id = 0, current_id;
+
+ id_start = glade_project_find_id (project, name);
+ if (id_start == NULL)
+ return;
+
+ /* Make sure we won't overflow the buffer. */
+ g_return_if_fail (id_start - name < 127);
+
+ id = atoi (id_start);
+ if (id == 0)
+ return;
+
+ strncpy (buffer, name, id_start - name);
+ buffer[id_start - name] = '\0';
+
+ current_id = GPOINTER_TO_INT (g_hash_table_lookup (project->unique_id_hash,
+ buffer));
+ if (current_id == 0)
+ {
+ g_hash_table_insert (project->unique_id_hash, g_strdup (buffer),
+ GINT_TO_POINTER (id));
+ }
+ else if (id > current_id)
+ {
+ /* We don't need to g_strdup buffer since it is already in the hash. */
+ g_hash_table_insert (project->unique_id_hash, buffer,
+ GINT_TO_POINTER (id));
+ }
+}
+
+
+/* This returns the start of the ID number at the end of the widget name,
+ or NULL if there is no number. */
+static gchar*
+glade_project_find_id (GladeProject *project,
+ const gchar *name)
+{
+ gint pos;
+
+ pos = strlen (name) - 1;
+ if (pos <= 0)
+ return NULL;
+
+ /* Step back from the end of the string to find the first digit. */
+ while (pos > 0 && name[pos] >= '0' && name[pos] <= '9')
+ pos--;
+
+ /* We may have gone too far, so check. */
+ if (!(name[pos] >= '0' && name[pos] <= '9'))
+ pos++;
+
+ /* If there is no trailing number return NULL. */
+ if (name[pos] == '\0')
+ return NULL;
+
+ return (gchar*) &name[pos];
+}
+
+
+/* This recursively descends a widget tree, ensuring that all widgets have
+ names. If any names are NULL, default names are created for them. */
+void
+glade_project_ensure_widgets_named (GladeProject *project,
+ GtkWidget *widget)
+{
+ /* We have to switch the arguments for the recursive calls to work. */
+ glade_project_real_ensure_widgets_named (widget, project);
+}
+
+
+static void
+glade_project_real_ensure_widgets_named (GtkWidget *widget,
+ GladeProject *project)
+{
+ if (GB_IS_GB_WIDGET (widget) && widget->name == NULL)
+ {
+ gchar *class = gb_widget_get_class_id (widget);
+ gtk_widget_set_name (widget,
+ glade_project_new_widget_name (project, class));
+ MSG1 ("set default name for widget: %s\n", gtk_widget_get_name (widget));
+ }
+
+ gb_widget_children_foreach (widget, (GtkCallback) glade_project_real_ensure_widgets_named, project);
+}
diff --git a/tools/glade/glade/glade_project.h b/tools/glade/glade/glade_project.h
new file mode 100644
index 00000000..f26c5b3e
--- /dev/null
+++ b/tools/glade/glade/glade_project.h
@@ -0,0 +1,373 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_PROJECT_H
+#define GLADE_PROJECT_H
+
+#include "gbwidget.h"
+#include "glade.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * GladeProject is a subclass of GtkObject and contains a project's data,
+ * which is viewed in a GladeProjectView.
+ */
+
+#define GLADE_PROJECT(obj) GTK_CHECK_CAST (obj, glade_project_get_type (), GladeProject)
+#define GLADE_PROJECT_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_project_get_type (), GladeProjectClass)
+#define GLADE_IS_PROJECT(obj) GTK_CHECK_TYPE (obj, glade_project_get_type ())
+
+
+typedef enum
+{
+ GLADE_LANGUAGE_C,
+ GLADE_LANGUAGE_CPP,
+ GLADE_LANGUAGE_ADA95,
+ GLADE_LANGUAGE_PERL,
+ GLADE_LANGUAGE_EIFFEL
+} GladeLanguageType;
+
+extern gchar *GladeLanguages[];
+extern gint GladeNumLanguages;
+
+typedef struct _GladeProjectClass GladeProjectClass;
+
+/* All directories are absolute paths in GladeProject, but some are saved in
+ the XML file as relative paths so the project can be placed in different
+ directories (e.g. it should still work if multiple developers check it out
+ from a CVS repository into different directories.) */
+struct _GladeProject
+{
+ GtkObject object;
+
+ gchar *name;
+
+ /* The name of the executable to build. */
+ gchar *program_name;
+
+ /* This is the XML file. */
+ gchar *xml_filename;
+
+ /* This is the project directory, which defaults to the directory which the
+ XML file is in. */
+ gchar *directory;
+
+ /* These are the directories for the source code and pixmaps files, and
+ default to the project directory and the 'pixmaps' subdirectory. */
+ gchar *source_directory;
+ gchar *pixmaps_directory;
+
+ /* The currently selected language of the project, an index into
+ GladeLanguages[]. */
+ GladeLanguageType language;
+
+ /* If the project has changed since the last time it was saved.
+ FIXME: this isn't completely supported yet. */
+ gboolean changed;
+
+ /* The windows, dialogs & popup menus making up the project. */
+ GList *components;
+
+ /* A hash table used to ensure that all widget names are unique. */
+ GHashTable *unique_id_hash;
+
+ /* A list of absolute pixmap filenames used in the project. The same file
+ may appear more than once, so we don't need to use refcounting. */
+ GList *pixmap_filenames;
+
+ /* This is the project's 'current directory', used when opening/saving
+ files. We may want separate directories for opening/saving/writing
+ source. */
+ gchar *current_directory;
+
+ /* This is TRUE if we are building a Gnome application. It defaults to
+ TRUE if Glade has been compiled with Gnome support, though it can be
+ set to FALSE. If Glade doesn't have Gnome support it must be FALSE,
+ and we need to check that any projects loaded aren't Gnome projects. */
+ gboolean gnome_support;
+
+ /* This is TRUE to add support for Gnome DB. */
+ gboolean gnome_db_support;
+
+
+ /*
+ * C Source code options.
+ */
+
+ /* This is TRUE if translatable strings are output using the standard
+ gettext macros, _("") and N_(""). */
+ gboolean gettext_support;
+
+ /* This is TRUE if gtk_widget_set_name () is called to set the name of
+ each widget when they are created. Useful when using rc files. */
+ gboolean use_widget_names;
+
+ /* This is TRUE if a main.c file is output with a main() function.
+ Though an existing main.c will not be overwritten. */
+ gboolean output_main_file;
+
+ /* This is TRUE if a support file (support.c by default) is output with the
+ get_widget() function and other support functions. */
+ gboolean output_support_files;
+
+ /* This is TRUE if Makefile.am, configure.in, autogen.sh, m4 macros etc.
+ are output. */
+ gboolean output_build_files;
+
+ /* This is TRUE if backups are made of the source files. */
+ gboolean backup_source_files;
+
+ /* This is TRUE to add support for Gnome Help. Currently we just output
+ the GNOME_UIINFO_HELP macro at the top of the Help GnomeUIInfo structs,
+ but we will output a template help file with build files in future. */
+ gboolean gnome_help_support;
+
+ /* FIXME: These will be deleted soon, when we support better code output. */
+ gchar *main_source_file;
+ gchar *main_header_file;
+ gchar *handler_source_file;
+ gchar *handler_header_file;
+
+ gchar *support_source_file;
+ gchar *support_header_file;
+
+
+ /*
+ * libglade options.
+ */
+
+ /* This is TRUE to output a file containing all the translatable strings in
+ the interface, wrapped in gettext macros. When using libglade, this file
+ can be added to an app's POTFILES.in so the interface is translated. */
+ gboolean output_translatable_strings;
+
+ /* This is the file in which translatable strings are saved, useful when
+ XML interfaces are loaded dynamically by libglade. */
+ gchar *translatable_strings_file;
+};
+
+
+struct _GladeProjectClass
+{
+ GtkObjectClass parent_class;
+
+ void (*add_component) (GladeProject *project,
+ GtkWidget *component);
+ void (*remove_component) (GladeProject *project,
+ GtkWidget *component);
+ void (*component_changed) (GladeProject *project,
+ GtkWidget *component);
+};
+
+
+/* FIXME: Currently we only support one project open at once, and this is it.
+ But we will support multiple projects in future, so try not to use this
+ too much. */
+extern GladeProject *current_project;
+
+
+GType glade_project_get_type (void);
+GladeProject* glade_project_new (void);
+
+/* Note that even if this command succeeds, there may be some error messages
+ which should be displayed (e.g. some widget properties may be invalid).
+ The list of error messages should be freed, as well as each message. */
+gboolean glade_project_open (const gchar *xml_filename,
+ GladeProject **project);
+GladeError* glade_project_save (GladeProject *project);
+
+/* If an error occurs a GladeError will be returned, which should be freed. */
+GladeError* glade_project_write_source (GladeProject *project);
+
+/* This sets/resets the project's changed flag. */
+void glade_project_set_changed (GladeProject *project,
+ gboolean changed);
+
+/*
+ * These are for ensuring that widget names are unique.
+ */
+
+/* This returns a new unique widget name, based on the given base name
+ (often a widget class name). Any leading 'Gtk' or 'Gnome' is stripped,
+ it is converted to lower case, and a number is appended to ensure it is
+ unique. */
+gchar* glade_project_new_widget_name (GladeProject *project,
+ const gchar *base_name);
+
+/* This releases the given name, so it may possibly be reused in future.
+ It is used when a widget is destroyed or its name is changed. */
+void glade_project_release_widget_name (GladeProject *project,
+ const gchar *name);
+
+/* This reserves the given name, so that no other widgets will be given it.
+ It is used when loading the XML file. */
+void glade_project_reserve_name (GladeProject *project,
+ const gchar *name);
+
+/* This ensures that the given widget and all its descendants have been named,
+ creating default names for them if necessary. */
+void glade_project_ensure_widgets_named (GladeProject *project,
+ GtkWidget *widget);
+
+/*
+ * These are for loading & saving the project options to the XML file.
+ */
+gboolean glade_project_load_options (GladeProject *project);
+GladeError* glade_project_save_options (GladeProject *project,
+ FILE *fp);
+
+
+/*
+ * Accessor functions.
+ */
+gchar* glade_project_get_name (GladeProject *project);
+void glade_project_set_name (GladeProject *project,
+ const gchar *name);
+
+gchar* glade_project_get_program_name (GladeProject *project);
+void glade_project_set_program_name (GladeProject *project,
+ const gchar *program_name);
+
+gchar* glade_project_get_xml_filename (GladeProject *project);
+void glade_project_set_xml_filename (GladeProject *project,
+ const gchar *filename);
+
+gchar* glade_project_get_directory (GladeProject *project);
+void glade_project_set_directory (GladeProject *project,
+ const gchar *directory);
+
+gchar* glade_project_get_source_directory (GladeProject *project);
+void glade_project_set_source_directory (GladeProject *project,
+ const gchar *directory);
+
+gchar* glade_project_get_pixmaps_directory (GladeProject *project);
+void glade_project_set_pixmaps_directory (GladeProject *project,
+ const gchar *directory);
+
+gint glade_project_get_language (GladeProject *project);
+void glade_project_set_language (GladeProject *project,
+ GladeLanguageType language);
+gboolean glade_project_set_language_name (GladeProject *project,
+ const gchar *language_name);
+
+gboolean glade_project_get_gnome_support (GladeProject *project);
+void glade_project_set_gnome_support (GladeProject *project,
+ gboolean gnome_support);
+
+gboolean glade_project_get_gnome_db_support (GladeProject *project);
+void glade_project_set_gnome_db_support (GladeProject *project,
+ gboolean gnome_db_support);
+
+void glade_project_add_component (GladeProject *project,
+ GtkWidget *component);
+void glade_project_show_component (GladeProject *project,
+ GtkWidget *component);
+void glade_project_component_changed (GladeProject *project,
+ GtkWidget *component);
+void glade_project_foreach_component (GladeProject *project,
+ GtkCallback callback,
+ gpointer callback_data);
+void glade_project_remove_component (GladeProject *project,
+ GtkWidget *component);
+
+void glade_project_add_associated_window (GladeProject *project,
+ GtkWidget *window);
+void glade_project_remove_associated_window (GladeProject *project,
+ GtkWidget *window);
+
+/* These add/remove pixmaps to the project. The same filename can appear
+ more than once in the project's list of pixmaps, so refcounting isn't
+ needed. The filename is copied. */
+void glade_project_add_pixmap (GladeProject *project,
+ const gchar *filename);
+void glade_project_remove_pixmap (GladeProject *project,
+ const gchar *filename);
+
+/* This ensures that all pixmaps are in the project's pixmaps directory,
+ by copying them if necessary. */
+GladeError* glade_project_copy_all_pixmaps (GladeProject *project);
+
+gchar* glade_project_get_current_directory (GladeProject *project);
+void glade_project_set_current_directory (GladeProject *project,
+ const gchar *directory);
+
+
+/*
+ * C Output options.
+ */
+gboolean glade_project_get_gettext_support (GladeProject *project);
+void glade_project_set_gettext_support (GladeProject *project,
+ gboolean gettext_support);
+gboolean glade_project_get_use_widget_names (GladeProject *project);
+void glade_project_set_use_widget_names (GladeProject *project,
+ gboolean use_widget_names);
+gboolean glade_project_get_output_main_file (GladeProject *project);
+void glade_project_set_output_main_file (GladeProject *project,
+ gboolean output_main_file);
+gboolean glade_project_get_output_support_files (GladeProject *project);
+void glade_project_set_output_support_files (GladeProject *project,
+ gboolean output_support_files);
+gboolean glade_project_get_output_build_files (GladeProject *project);
+void glade_project_set_output_build_files (GladeProject *project,
+ gboolean output_build_files);
+gboolean glade_project_get_backup_source_files (GladeProject *project);
+void glade_project_set_backup_source_files (GladeProject *project,
+ gboolean backup_source_files);
+gboolean glade_project_get_gnome_help_support (GladeProject *project);
+void glade_project_set_gnome_help_support (GladeProject *project,
+ gboolean gnome_help_support);
+
+/* These will be removed when the source code output is improved. */
+void glade_project_get_source_files (GladeProject *project,
+ gchar **main_source_file,
+ gchar **main_header_file,
+ gchar **handler_source_file,
+ gchar **handler_header_file);
+void glade_project_set_source_files (GladeProject *project,
+ const gchar *main_source_file,
+ const gchar *main_header_file,
+ const gchar *handler_source_file,
+ const gchar *handler_header_file);
+
+gchar* glade_project_get_support_source_file (GladeProject *project);
+void glade_project_set_support_source_file (GladeProject *project,
+ const gchar* support_source_file);
+
+gchar* glade_project_get_support_header_file (GladeProject *project);
+void glade_project_set_support_header_file (GladeProject *project,
+ const gchar* support_header_file);
+
+
+/*
+ * libglade options.
+ */
+gboolean glade_project_get_output_translatable_strings (GladeProject *project);
+void glade_project_set_output_translatable_strings (GladeProject *project,
+ gboolean output_translatable_strings);
+
+gchar* glade_project_get_translatable_strings_file (GladeProject *project);
+void glade_project_set_translatable_strings_file (GladeProject *project,
+ const gchar* file);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PROJECT_H */
diff --git a/tools/glade/glade/glade_project_options.c b/tools/glade/glade/glade_project_options.c
new file mode 100644
index 00000000..a1f19624
--- /dev/null
+++ b/tools/glade/glade/glade_project_options.c
@@ -0,0 +1,1433 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <ctype.h>
+#include <string.h>
+
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtkfilechooserdialog.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkhbbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkvbox.h>
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#endif
+
+#include "glade_project_options.h"
+#include "utils.h"
+
+
+static GtkWindowClass *parent_class = NULL;
+
+
+static void glade_project_options_class_init (GladeProjectOptionsClass * klass);
+static void glade_project_options_init (GladeProjectOptions * project_options);
+static void glade_project_options_destroy (GtkObject *object);
+
+static void glade_project_options_set_project (GladeProjectOptions *options,
+ GladeProject *project);
+static void glade_project_options_directory_changed (GtkWidget * entry,
+ GladeProjectOptions *options);
+static void glade_project_options_name_changed (GtkWidget * entry,
+ GladeProjectOptions *options);
+static void glade_project_options_program_name_changed (GtkWidget * entry,
+ GladeProjectOptions *options);
+static void glade_project_options_xml_filename_changed (GtkWidget * entry,
+ GladeProjectOptions *options);
+static void glade_project_options_generate_name (GladeProjectOptions *options);
+static void glade_project_options_generate_program_name (GladeProjectOptions *options);
+static void glade_project_options_generate_xml_filename (GladeProjectOptions *options);
+static gchar* glade_project_options_generate_project_name_from_directory (gchar *directory);
+static gchar* glade_project_options_generate_program_name_from_project_name (gchar *project_name);
+static gchar* glade_project_options_generate_xml_filename_from_program_name (gchar *program_name);
+static void glade_project_options_translatable_strings_toggled (GtkWidget *widget,
+ GladeProjectOptions *options);
+static void glade_project_options_show_file_selection (GtkWidget *widget,
+ gpointer data);
+static void on_filesel_response (GtkWidget *widget,
+ gint response_id,
+ GladeProjectOptions *options);
+static void glade_project_options_ok (GtkWidget *widget,
+ GladeProjectOptions *options);
+static gchar* get_entry_text (GtkWidget *entry);
+static gboolean glade_project_options_check_valid (GladeProjectOptions *options);
+
+GType
+glade_project_options_get_type (void)
+{
+ static GType glade_project_options_type = 0;
+
+ if (!glade_project_options_type)
+ {
+ GtkTypeInfo glade_project_options_info =
+ {
+ "GladeProjectOptions",
+ sizeof (GladeProjectOptions),
+ sizeof (GladeProjectOptionsClass),
+ (GtkClassInitFunc) glade_project_options_class_init,
+ (GtkObjectInitFunc) glade_project_options_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ glade_project_options_type = gtk_type_unique (gtk_window_get_type (),
+ &glade_project_options_info);
+ }
+ return glade_project_options_type;
+}
+
+
+static void
+glade_project_options_class_init (GladeProjectOptionsClass * klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) klass;
+
+ parent_class = gtk_type_class (gtk_window_get_type ());
+
+ object_class->destroy = glade_project_options_destroy;
+}
+
+static void
+set_accessible_description (GtkWidget *widget, const gchar *desc)
+{
+ AtkObject *atk_widget;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ atk_widget = gtk_widget_get_accessible (widget);
+
+ if (desc)
+ atk_object_set_description (atk_widget, desc);
+}
+
+
+static void
+glade_project_options_init (GladeProjectOptions * options)
+{
+ GtkTooltips *tooltips;
+ GtkWidget *main_vbox, *notebook;
+ GtkWidget *general_options_vbox, *c_options_vbox, *libglade_options_vbox;
+ GtkWidget *vbox, *table, *label, *button, *eventbox, *alignment;
+ GtkWidget *hbox, *hbbox, *radio_button, *frame;
+ gint row, language;
+ GSList *group;
+
+ options->generate_program_name = FALSE;
+ options->generate_xml_filename = FALSE;
+ options->language_buttons = NULL;
+ options->filesel = NULL;
+ options->auto_generation_level = 0;
+
+ tooltips = gtk_tooltips_new ();
+
+ gtk_container_set_border_width (GTK_CONTAINER (options), 4);
+ gtk_window_set_position (GTK_WINDOW (options), GTK_WIN_POS_MOUSE);
+ gtk_window_set_title (GTK_WINDOW (options), _("Project Options"));
+ gtk_window_set_policy (GTK_WINDOW (options), FALSE, TRUE, FALSE);
+ gtk_window_set_wmclass (GTK_WINDOW (options), "project_options", "Glade");
+
+ main_vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_add (GTK_CONTAINER (options), main_vbox);
+ gtk_widget_show (main_vbox);
+
+ notebook = gtk_notebook_new ();
+ gtk_widget_show (notebook);
+ gtk_box_pack_start (GTK_BOX (main_vbox), notebook, TRUE, TRUE, 0);
+
+
+ /*
+ * General Page.
+ */
+
+ label = gtk_label_new (_("General"));
+ gtk_widget_show (label);
+
+ general_options_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (general_options_vbox);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), general_options_vbox,
+ label);
+ gtk_container_set_border_width (GTK_CONTAINER (general_options_vbox), 7);
+
+ frame = gtk_frame_new (_("Basic Options:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (general_options_vbox), frame, FALSE, TRUE, 4);
+
+ table = gtk_table_new (3, 4, TRUE);
+ gtk_widget_show (table);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+
+ /* Project Directory. */
+ row = 0;
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 0, 1, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The project directory"), NULL);
+
+ label = gtk_label_new (_("Project Directory:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ hbox = gtk_hbox_new (FALSE, 4);
+ gtk_widget_show (hbox);
+ gtk_table_attach (GTK_TABLE (table), hbox,
+ 1, 4, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+ options->directory_entry = gtk_entry_new ();
+ gtk_widget_show (options->directory_entry);
+ gtk_box_pack_start (GTK_BOX (hbox), options->directory_entry,
+ TRUE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (options->directory_entry), "changed",
+ GTK_SIGNAL_FUNC (glade_project_options_directory_changed),
+ options);
+
+ button = gtk_button_new_with_label (_("Browse..."));
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 8, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (glade_project_options_show_file_selection),
+ NULL);
+
+ /* Project Name. */
+ row++;
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 0, 1, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The name of the current project"), NULL);
+
+ label = gtk_label_new (_("Project Name:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->name_entry = gtk_entry_new ();
+ gtk_widget_set_usize (options->name_entry, 80, -1);
+ gtk_widget_show (options->name_entry);
+ gtk_table_attach (GTK_TABLE (table), options->name_entry,
+ 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (options->name_entry), "changed",
+ GTK_SIGNAL_FUNC (glade_project_options_name_changed),
+ options);
+
+ /* Program Name. */
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 2, 3, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The name of the program"), NULL);
+
+ label = gtk_label_new (_("Program Name:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->program_name_entry = gtk_entry_new ();
+ gtk_widget_set_usize (options->program_name_entry, 80, -1);
+ gtk_widget_show (options->program_name_entry);
+ gtk_table_attach (GTK_TABLE (table), options->program_name_entry,
+ 3, 4, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (options->program_name_entry), "changed",
+ GTK_SIGNAL_FUNC (glade_project_options_program_name_changed),
+ options);
+
+ /* Project XML File. */
+ row++;
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 0, 1, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The project file"), NULL);
+
+ label = gtk_label_new (_("Project File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->xml_filename_entry = gtk_entry_new ();
+ gtk_widget_set_usize (options->xml_filename_entry, 80, -1);
+ gtk_widget_show (options->xml_filename_entry);
+ gtk_table_attach (GTK_TABLE (table), options->xml_filename_entry,
+ 1, 4, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ gtk_signal_connect (GTK_OBJECT (options->xml_filename_entry), "changed",
+ GTK_SIGNAL_FUNC (glade_project_options_xml_filename_changed),
+ options);
+
+
+ /* Project Source Directory. */
+ frame = gtk_frame_new (_("Subdirectories:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (general_options_vbox), frame, FALSE, TRUE, 4);
+
+ table = gtk_table_new (1, 4, TRUE);
+ gtk_widget_show (table);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+
+ row = 0;
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 0, 1, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The directory to save generated source code"),
+ NULL);
+
+ label = gtk_label_new (_("Source Directory:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->source_directory_entry = gtk_entry_new ();
+ gtk_widget_set_usize (options->source_directory_entry, 80, -1);
+ gtk_widget_show (options->source_directory_entry);
+ gtk_table_attach (GTK_TABLE (table), options->source_directory_entry,
+ 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+
+ /* Project Pixmaps Directory. */
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 2, 3, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The directory to store pixmaps"),
+ NULL);
+
+ label = gtk_label_new (_("Pixmaps Directory:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->pixmaps_directory_entry = gtk_entry_new ();
+ gtk_widget_set_usize (options->pixmaps_directory_entry, 80, -1);
+ gtk_widget_show (options->pixmaps_directory_entry);
+ gtk_table_attach (GTK_TABLE (table), options->pixmaps_directory_entry,
+ 3, 4, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+
+ /* Project License. */
+ /* Take this out until we actually use it. */
+#if 0
+ row++;
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 0, 1, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The license which is added at the top of generated files"), NULL);
+
+ label = gtk_label_new (_("License:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->license_option_menu = gtk_option_menu_new ();
+ gtk_widget_show (options->license_option_menu);
+ gtk_table_attach (GTK_TABLE (table), options->license_option_menu,
+ 1, 3, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+ menu = gtk_menu_new ();
+ menuitem = gtk_menu_item_new_with_label ("GNU General Public License");
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (options->license_option_menu),
+ menu);
+#endif
+
+ /* Source Language. */
+ frame = gtk_frame_new (_("Language:"));
+ /* Change this to 0 if you don't want the language option (C/C++/Perl). */
+#if 1
+ gtk_widget_show (frame);
+#endif
+ gtk_box_pack_start (GTK_BOX (general_options_vbox), frame, FALSE, TRUE, 4);
+
+ alignment = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
+ gtk_widget_show (alignment);
+ gtk_container_add (GTK_CONTAINER (frame), alignment);
+
+ hbox = gtk_hbox_new (TRUE, 4);
+ gtk_widget_show (hbox);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
+ gtk_container_add (GTK_CONTAINER (alignment), hbox);
+
+ options->language_buttons = g_new (GtkWidget*, GladeNumLanguages);
+ group = NULL;
+ for (language = 0; language < GladeNumLanguages; language++)
+ {
+ radio_button = gtk_radio_button_new_with_label (group,
+ GladeLanguages[language]);
+ gtk_widget_show (radio_button);
+ gtk_box_pack_start (GTK_BOX (hbox), radio_button, FALSE, TRUE, 4);
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_button));
+
+ options->language_buttons[language] = radio_button;
+ }
+
+ /* Gnome Support. */
+#ifdef USE_GNOME
+ frame = gtk_frame_new (_("Gnome:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (general_options_vbox), frame, FALSE, TRUE, 4);
+
+ hbox = gtk_hbox_new (TRUE, 4);
+ gtk_widget_show (hbox);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+
+ options->gnome_support = gtk_check_button_new_with_label (_("Enable Gnome Support"));
+ /* This can't be changed now. */
+ gtk_widget_set_sensitive (options->gnome_support, FALSE);
+ gtk_widget_show (options->gnome_support);
+ gtk_box_pack_start (GTK_BOX (hbox), options->gnome_support, TRUE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, options->gnome_support,
+ _("If a Gnome application is to be built"), NULL);
+
+#ifdef USE_GNOME_DB
+ options->gnome_db_support = gtk_check_button_new_with_label (_("Enable Gnome DB Support"));
+ gtk_widget_show (options->gnome_db_support);
+ gtk_box_pack_start (GTK_BOX (hbox), options->gnome_db_support, TRUE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, options->gnome_db_support,
+ _("If a Gnome DB application is to be built"), NULL);
+#endif /* USE_GNOME_DB */
+
+#endif /* USE_GNOME */
+
+
+ /*
+ * C Options Page.
+ */
+
+ label = gtk_label_new (_("C Options"));
+ gtk_widget_show (label);
+
+ c_options_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (c_options_vbox);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), c_options_vbox, label);
+ gtk_container_set_border_width (GTK_CONTAINER (c_options_vbox), 7);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), _("<b>Note:</b> for large applications the use of libglade is recommended."));
+ gtk_widget_set_size_request (label, 400, -1);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (c_options_vbox), label, FALSE, TRUE, 4);
+
+ hbox = gtk_hbox_new (TRUE, 4);
+ gtk_widget_show (hbox);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
+ gtk_box_pack_start (GTK_BOX (c_options_vbox), hbox, FALSE, TRUE, 4);
+
+ frame = gtk_frame_new (_("General Options:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+
+ vbox = gtk_vbox_new (TRUE, 0);
+ gtk_widget_show (vbox);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+
+ /* Gettext Support. */
+ options->gettext_support = gtk_check_button_new_with_label (_("Gettext Support"));
+ gtk_widget_show (options->gettext_support);
+ gtk_box_pack_start (GTK_BOX (vbox), options->gettext_support,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->gettext_support,
+ _("If strings are marked for translation by gettext"),
+ NULL);
+
+ /* Setting widget names. */
+ options->use_widget_names = gtk_check_button_new_with_label (_("Set Widget Names"));
+ gtk_widget_show (options->use_widget_names);
+ gtk_box_pack_start (GTK_BOX (vbox), options->use_widget_names,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->use_widget_names,
+ _("If widget names are set in the source code"),
+ NULL);
+
+ /* Backing up source files. */
+ options->backup_source_files = gtk_check_button_new_with_label (_("Backup Source Files"));
+ gtk_widget_show (options->backup_source_files);
+ gtk_box_pack_start (GTK_BOX (vbox), options->backup_source_files,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->backup_source_files,
+ _("If copies of old source files are made"),
+ NULL);
+
+ /* Gnome Help System support. */
+ options->gnome_help_support = gtk_check_button_new_with_label (_("Gnome Help Support"));
+#ifdef USE_GNOME
+ gtk_widget_show (options->gnome_help_support);
+#endif
+ gtk_box_pack_start (GTK_BOX (vbox), options->gnome_help_support,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->gnome_help_support,
+ _("If support for the Gnome Help system should be included"),
+ NULL);
+
+ frame = gtk_frame_new (_("File Output Options:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+
+ vbox = gtk_vbox_new (TRUE, 0);
+ gtk_widget_show (vbox);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+
+ /* Outputting main file. */
+ options->output_main_file = gtk_check_button_new_with_label (_("Output main.c File"));
+ gtk_widget_show (options->output_main_file);
+ gtk_box_pack_start (GTK_BOX (vbox), options->output_main_file,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->output_main_file,
+ _("If a main.c file is output containing a main() function, if it doesn't already exist"),
+ NULL);
+
+ /* Outputting support files. */
+ options->output_support_files = gtk_check_button_new_with_label (_("Output Support Functions"));
+ gtk_widget_show (options->output_support_files);
+ gtk_box_pack_start (GTK_BOX (vbox), options->output_support_files,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->output_support_files,
+ _("If the support functions are output"),
+ NULL);
+
+ /* Outputting build files. */
+ options->output_build_files = gtk_check_button_new_with_label (_("Output Build Files"));
+ gtk_widget_show (options->output_build_files);
+ gtk_box_pack_start (GTK_BOX (vbox), options->output_build_files,
+ FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, options->output_build_files,
+ _("If files for building the source code are output, including Makefile.am and configure.in, if they don't already exist"),
+ NULL);
+
+ /* Main source file. */
+ frame = gtk_frame_new (_("Interface Creation Functions:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (c_options_vbox), frame, FALSE, TRUE, 4);
+
+ hbox = gtk_hbox_new (TRUE, 4);
+ gtk_widget_show (hbox);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_box_pack_start (GTK_BOX (hbox), eventbox, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox, _("The file in which the functions to create the interface are written"), NULL);
+
+ label = gtk_label_new (_("Source File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->main_source_entry = gtk_entry_new ();
+ gtk_widget_show (options->main_source_entry);
+ gtk_widget_set_usize (options->main_source_entry, 80, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), options->main_source_entry,
+ TRUE, TRUE, 0);
+
+ /* Main header file. */
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_box_pack_start (GTK_BOX (hbox), eventbox, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox, _("The file in which the declarations of the functions to create the interface are written"), NULL);
+
+ label = gtk_label_new (_("Header File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->main_header_entry = gtk_entry_new ();
+ gtk_widget_show (options->main_header_entry);
+ gtk_widget_set_usize (options->main_header_entry, 80, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), options->main_header_entry,
+ TRUE, TRUE, 0);
+
+ set_accessible_description (options->main_source_entry, _("Source file for interface creation functions"));
+ set_accessible_description (options->main_header_entry, _("Header file for interface creation functions"));
+
+ /* Handler source file. */
+ frame = gtk_frame_new (_("Signal Handler & Callback Functions:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (c_options_vbox), frame, FALSE, TRUE, 4);
+
+ hbox = gtk_hbox_new (TRUE, 4);
+ gtk_widget_show (hbox);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_box_pack_start (GTK_BOX (hbox), eventbox, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox, _("The file in which the empty signal handler and callback functions are written"), NULL);
+
+ label = gtk_label_new (_("Source File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->handler_source_entry = gtk_entry_new ();
+ gtk_widget_show (options->handler_source_entry);
+ gtk_widget_set_usize (options->handler_source_entry, 80, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), options->handler_source_entry,
+ TRUE, TRUE, 0);
+
+ /* Handler header file. */
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_box_pack_start (GTK_BOX (hbox), eventbox, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox, _("The file in which the declarations of the signal handler and callback functions are written"), NULL);
+
+ label = gtk_label_new (_("Header File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->handler_header_entry = gtk_entry_new ();
+ gtk_widget_show (options->handler_header_entry);
+ gtk_widget_set_usize (options->handler_header_entry, 80, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), options->handler_header_entry,
+ TRUE, TRUE, 0);
+
+ set_accessible_description (options->handler_source_entry, _("Source file for signal handler and callback functions"));
+ set_accessible_description (options->handler_header_entry, _("Header file for signal handler and callback functions"));
+
+ /* Support source file. */
+ frame = gtk_frame_new (_("Support Functions:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (c_options_vbox), frame, FALSE, TRUE, 4);
+
+ hbox = gtk_hbox_new (TRUE, 4);
+ gtk_widget_show (hbox);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_box_pack_start (GTK_BOX (hbox), eventbox, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox, _("The file in which the support functions are written"), NULL);
+
+ label = gtk_label_new (_("Source File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->support_source_entry = gtk_entry_new ();
+ gtk_widget_show (options->support_source_entry);
+ gtk_widget_set_usize (options->support_source_entry, 80, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), options->support_source_entry,
+ TRUE, TRUE, 0);
+
+ /* Support header file. */
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_box_pack_start (GTK_BOX (hbox), eventbox, FALSE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox, _("The file in which the declarations of the support functions are written"), NULL);
+
+ label = gtk_label_new (_("Header File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ options->support_header_entry = gtk_entry_new ();
+ gtk_widget_show (options->support_header_entry);
+ gtk_widget_set_usize (options->support_header_entry, 80, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), options->support_header_entry,
+ TRUE, TRUE, 0);
+
+ set_accessible_description (options->support_source_entry, _("Source file for support functions"));
+ set_accessible_description (options->support_header_entry, _("Header file for support functions"));
+
+ /*
+ * libglade Options Page.
+ */
+
+ label = gtk_label_new (_("LibGlade Options"));
+ gtk_widget_show (label);
+
+ libglade_options_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (libglade_options_vbox);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), libglade_options_vbox,
+ label);
+ gtk_container_set_border_width (GTK_CONTAINER (libglade_options_vbox), 7);
+
+ frame = gtk_frame_new (_("Translatable Strings:"));
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (libglade_options_vbox), frame, FALSE, TRUE, 4);
+
+ table = gtk_table_new (2, 3, FALSE);
+ gtk_widget_show (table);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+
+ row = 0;
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), _("<b>Note:</b> this option is deprecated - use intltool instead."));
+ gtk_widget_set_size_request (label, 400, -1);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table), label,
+ 0, 3, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ row++;
+
+ /* Output translatable strings. */
+ options->output_translatable_strings = gtk_check_button_new_with_label (_("Save Translatable Strings"));
+ gtk_widget_show (options->output_translatable_strings);
+ gtk_table_attach (GTK_TABLE (table), options->output_translatable_strings,
+ 0, 3, row, row + 1, GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, options->output_translatable_strings,
+ _("If translatable strings are saved in a separate C source file, to enable translation of interfaces loaded by libglade"),
+ NULL);
+
+ /* Translatable Strings File. */
+ row++;
+ eventbox = gtk_event_box_new ();
+ gtk_widget_show (eventbox);
+ gtk_table_attach (GTK_TABLE (table), eventbox, 0, 1, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+ gtk_tooltips_set_tip (tooltips, eventbox,
+ _("The C source file to save all translatable strings in"), NULL);
+
+ label = gtk_label_new (_("File:"));
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ options->translatable_strings_filename_label = label;
+
+ options->translatable_strings_filename_entry = gtk_entry_new ();
+ gtk_widget_show (options->translatable_strings_filename_entry);
+ gtk_table_attach (GTK_TABLE (table),
+ options->translatable_strings_filename_entry,
+ 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+
+ /* The button box with OK & Cancel buttons. */
+ hbbox = gtk_hbutton_box_new ();
+ gtk_widget_show (hbbox);
+ gtk_box_pack_start (GTK_BOX (main_vbox), hbbox, TRUE, TRUE, 0);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing (GTK_BOX (hbbox), 8);
+
+ options->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ GTK_WIDGET_SET_FLAGS (options->cancel_button, GTK_CAN_DEFAULT);
+ gtk_widget_show (options->cancel_button);
+ gtk_container_add (GTK_CONTAINER (hbbox), options->cancel_button);
+ gtk_signal_connect_object (GTK_OBJECT (options->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (options));
+
+ options->ok_button = gtk_button_new_from_stock (GTK_STOCK_OK);
+ GTK_WIDGET_SET_FLAGS (options->ok_button, GTK_CAN_DEFAULT);
+ gtk_widget_show (options->ok_button);
+ gtk_container_add (GTK_CONTAINER (hbbox), options->ok_button);
+ gtk_widget_grab_default (options->ok_button);
+ gtk_signal_connect (GTK_OBJECT (options->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (glade_project_options_ok), options);
+
+ gtk_signal_connect (GTK_OBJECT (options), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscDestroys));
+
+ gtk_widget_grab_focus (options->directory_entry);
+}
+
+
+GtkWidget *
+glade_project_options_new (GladeProject *project)
+{
+ GladeProjectOptions *options;
+
+ g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
+
+ options = GLADE_PROJECT_OPTIONS (gtk_type_new (glade_project_options_get_type ()));
+ glade_project_options_set_project (options, project);
+
+ return GTK_WIDGET (options);
+}
+
+
+static void
+glade_project_options_destroy (GtkObject *object)
+{
+ GladeProjectOptions *options;
+
+ options = GLADE_PROJECT_OPTIONS (object);
+
+ g_free (options->language_buttons);
+ options->language_buttons = NULL;
+
+ /* FIXME: Maybe we need to disconnect the destroy signal handler added to
+ the project. */
+
+ if (options->filesel)
+ {
+ gtk_widget_destroy (options->filesel);
+ options->filesel = NULL;
+ }
+}
+
+
+/* This sets which project which we show the options of. */
+static void
+glade_project_options_set_project (GladeProjectOptions *options,
+ GladeProject *project)
+{
+ GladeError *error;
+ gchar *base = NULL, *next_project_dir = NULL;
+ gint next_project_num = -1;
+
+ g_return_if_fail (GLADE_IS_PROJECT (project));
+
+ options->project = project;
+ options->generate_name = FALSE;
+ options->generate_program_name = FALSE;
+ options->generate_xml_filename = FALSE;
+
+ /* If the project directory has been set, we show it, else we show the
+ next free project directory in $HOME/Projects as the default. */
+ if (project->directory && project->directory[0])
+ {
+ base = project->directory;
+ gtk_entry_set_text (GTK_ENTRY (options->directory_entry), base);
+ }
+ else
+ {
+ error = glade_util_get_next_free_project_directory (&next_project_dir,
+ &next_project_num);
+ if (!error)
+ {
+ base = next_project_dir;
+ gtk_entry_set_text (GTK_ENTRY (options->directory_entry), base);
+ }
+ else
+ {
+ g_warning ("Couldn't find next free project directory.");
+ gtk_entry_set_text (GTK_ENTRY (options->directory_entry), "");
+ }
+ }
+
+ /* Project name. */
+ if (project->name && project->name[0])
+ {
+ gchar *generated_project_name;
+
+ gtk_entry_set_text (GTK_ENTRY (options->name_entry), project->name);
+
+ /* See if it matches what would have been auto-generated. */
+ generated_project_name = glade_project_options_generate_project_name_from_directory (base);
+ if (!strcmp (generated_project_name, project->name))
+ options->generate_name = TRUE;
+ g_free (generated_project_name);
+ }
+ else
+ {
+ glade_project_options_generate_name (options);
+ options->generate_name = TRUE;
+ }
+
+ /* Program name. */
+ if (project->program_name && project->program_name[0])
+ {
+ gchar *generated_program_name;
+
+ gtk_entry_set_text (GTK_ENTRY (options->program_name_entry),
+ project->program_name);
+
+ /* See if it matches what would have been auto-generated. */
+ generated_program_name = glade_project_options_generate_program_name_from_project_name (project->name);
+ if (!strcmp (generated_program_name, project->program_name))
+ options->generate_program_name = TRUE;
+ g_free (generated_program_name);
+ }
+ else
+ {
+ glade_project_options_generate_program_name (options);
+ options->generate_program_name = TRUE;
+ }
+
+ /* XML filename. */
+ if (project->xml_filename && project->xml_filename[0])
+ {
+ gchar *xml_filename_relative, *generated_filename;
+
+ xml_filename_relative = glade_util_make_relative_path (base, project->xml_filename);
+ gtk_entry_set_text (GTK_ENTRY (options->xml_filename_entry),
+ xml_filename_relative);
+
+ /* See if it matches what would have been auto-generated. */
+ generated_filename = glade_project_options_generate_xml_filename_from_program_name (project->program_name);
+ if (!strcmp (generated_filename, xml_filename_relative))
+ options->generate_xml_filename = TRUE;
+ g_free (generated_filename);
+ g_free (xml_filename_relative);
+ }
+ else
+ {
+ glade_project_options_generate_xml_filename (options);
+ options->generate_xml_filename = TRUE;
+ }
+
+ /* Source directory. */
+ if (project->source_directory && project->source_directory[0])
+ {
+ gchar *srcdir_relative;
+
+ srcdir_relative = glade_util_make_relative_path (base, project->source_directory);
+ gtk_entry_set_text (GTK_ENTRY (options->source_directory_entry),
+ srcdir_relative);
+ g_free (srcdir_relative);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (options->source_directory_entry),
+ "src");
+ }
+
+ /* Pixmaps directory. */
+ if (project->pixmaps_directory && project->pixmaps_directory[0])
+ {
+ gchar *pixmaps_relative;
+
+ pixmaps_relative = glade_util_make_relative_path (base, project->pixmaps_directory);
+ gtk_entry_set_text (GTK_ENTRY (options->pixmaps_directory_entry),
+ pixmaps_relative);
+ g_free (pixmaps_relative);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (options->pixmaps_directory_entry),
+ "pixmaps");
+ }
+
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->language_buttons[project->language]), TRUE);
+
+#ifdef USE_GNOME
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->gnome_support),
+ project->gnome_support);
+#ifdef USE_GNOME_DB
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->gnome_db_support),
+ project->gnome_db_support);
+#endif
+#endif
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->gettext_support),
+ project->gettext_support);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->use_widget_names),
+ project->use_widget_names);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->output_main_file),
+ project->output_main_file);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->output_support_files),
+ project->output_support_files);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->output_build_files),
+ project->output_build_files);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->backup_source_files),
+ project->backup_source_files);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->gnome_help_support),
+ project->gnome_help_support);
+
+ gtk_entry_set_text (GTK_ENTRY (options->main_source_entry),
+ project->main_source_file
+ ? project->main_source_file : "");
+ gtk_entry_set_text (GTK_ENTRY (options->main_header_entry),
+ project->main_header_file
+ ? project->main_header_file : "");
+ gtk_entry_set_text (GTK_ENTRY (options->handler_source_entry),
+ project->handler_source_file
+ ? project->handler_source_file : "");
+ gtk_entry_set_text (GTK_ENTRY (options->handler_header_entry),
+ project->handler_header_file
+ ? project->handler_header_file : "");
+
+ gtk_entry_set_text (GTK_ENTRY (options->support_source_entry),
+ project->support_source_file
+ ? project->support_source_file : "");
+ gtk_entry_set_text (GTK_ENTRY (options->support_header_entry),
+ project->support_header_file
+ ? project->support_header_file : "");
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->output_translatable_strings),
+ project->output_translatable_strings);
+ if (project->translatable_strings_file
+ && project->translatable_strings_file[0])
+ {
+ gchar *filename;
+
+ filename = glade_util_make_relative_path (base, project->translatable_strings_file);
+ gtk_entry_set_text (GTK_ENTRY (options->translatable_strings_filename_entry),
+ filename);
+ g_free (filename);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (options->translatable_strings_filename_entry), "");
+ }
+ gtk_signal_connect (GTK_OBJECT (options->output_translatable_strings),
+ "toggled",
+ GTK_SIGNAL_FUNC (glade_project_options_translatable_strings_toggled),
+ options);
+
+ /* Set the sensitivity of the options. */
+ gtk_widget_set_sensitive (options->translatable_strings_filename_label,
+ project->output_translatable_strings);
+ gtk_widget_set_sensitive (options->translatable_strings_filename_entry,
+ project->output_translatable_strings);
+
+
+ /* Connect to the project's destroy signal so we can destroy ourself. */
+ gtk_signal_connect_object (GTK_OBJECT (project), "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (options));
+
+ g_free (next_project_dir);
+}
+
+
+static void
+glade_project_options_directory_changed (GtkWidget * entry,
+ GladeProjectOptions *options)
+{
+ if (options->generate_name)
+ glade_project_options_generate_name (options);
+}
+
+
+static void
+glade_project_options_name_changed (GtkWidget * entry,
+ GladeProjectOptions *options)
+{
+ if (options->generate_program_name)
+ glade_project_options_generate_program_name (options);
+
+ /* If this option has been edited by the user, turn auto-generation off. */
+ if (options->auto_generation_level == 0)
+ options->generate_name = FALSE;
+}
+
+
+static void
+glade_project_options_program_name_changed (GtkWidget * entry,
+ GladeProjectOptions *options)
+{
+ if (options->generate_xml_filename)
+ glade_project_options_generate_xml_filename (options);
+
+ /* If this option has been edited by the user, turn auto-generation off. */
+ if (options->auto_generation_level == 0)
+ options->generate_program_name = FALSE;
+}
+
+
+static void
+glade_project_options_xml_filename_changed (GtkWidget * entry,
+ GladeProjectOptions *options)
+{
+ /* If this option has been edited by the user, turn auto-generation off. */
+ if (options->auto_generation_level == 0)
+ options->generate_xml_filename = FALSE;
+}
+
+
+static void
+glade_project_options_generate_name (GladeProjectOptions *options)
+{
+ gchar *directory, *project_name;
+
+ directory = (char*) gtk_entry_get_text (GTK_ENTRY (options->directory_entry));
+ project_name = glade_project_options_generate_project_name_from_directory (directory);
+ options->auto_generation_level++;
+ gtk_entry_set_text (GTK_ENTRY (options->name_entry), project_name);
+ options->auto_generation_level--;
+ g_free (project_name);
+}
+
+
+static gchar*
+glade_project_options_generate_project_name_from_directory (gchar *directory)
+{
+ gchar *project_name;
+
+ if (directory == NULL)
+ return g_strdup ("");
+
+ project_name = g_strdup (g_basename (directory));
+ if (project_name[0] != '\0')
+ project_name[0] = toupper (project_name[0]);
+ return project_name;
+}
+
+
+static void
+glade_project_options_generate_program_name (GladeProjectOptions *options)
+{
+ gchar *project_name, *program_name;
+
+ project_name = (char*) gtk_entry_get_text (GTK_ENTRY (options->name_entry));
+ program_name = glade_project_options_generate_program_name_from_project_name (project_name);
+ options->auto_generation_level++;
+ gtk_entry_set_text (GTK_ENTRY (options->program_name_entry), program_name);
+ options->auto_generation_level--;
+ g_free (program_name);
+}
+
+
+static gchar*
+glade_project_options_generate_program_name_from_project_name (gchar *project_name)
+{
+ gchar *program_name, *pos;
+
+ if (project_name == NULL)
+ return g_strdup ("");
+
+ program_name = g_strdup (project_name);
+ g_strdown (program_name);
+ /* Try to convert any characters which shouldn't be in a program name to '-'.
+ We'll allow alphanumerics and characters in [.+-_] */
+ for (pos = program_name; *pos; pos++)
+ {
+ if (!(isalnum (*pos) || *pos == '.' || *pos == '+' || *pos == '-'
+ || *pos == '_'))
+ *pos = '-';
+ }
+ return program_name;
+}
+
+
+static void
+glade_project_options_generate_xml_filename (GladeProjectOptions *options)
+{
+ gchar *program_name, *xml_filename;
+
+ program_name = (char*) gtk_entry_get_text (GTK_ENTRY (options->program_name_entry));
+ xml_filename = glade_project_options_generate_xml_filename_from_program_name (program_name);
+ options->auto_generation_level++;
+ gtk_entry_set_text (GTK_ENTRY (options->xml_filename_entry), xml_filename);
+ options->auto_generation_level--;
+ g_free (xml_filename);
+}
+
+
+static gchar*
+glade_project_options_generate_xml_filename_from_program_name (gchar *program_name)
+{
+ gchar *xml_filename;
+
+ if (program_name == NULL)
+ return g_strdup ("");
+
+ xml_filename = g_strdup_printf ("%s.glade", program_name);
+ return xml_filename;
+}
+
+
+static void
+glade_project_options_translatable_strings_toggled (GtkWidget *widget,
+ GladeProjectOptions *options)
+{
+ gboolean sensitive;
+
+ sensitive = GTK_TOGGLE_BUTTON (options->output_translatable_strings)->active;
+
+ /* Set the sensitivity of the options. */
+ gtk_widget_set_sensitive (options->translatable_strings_filename_label,
+ sensitive);
+ gtk_widget_set_sensitive (options->translatable_strings_filename_entry,
+ sensitive);
+}
+
+
+static void
+glade_project_options_show_file_selection (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectOptions *options;
+ gchar *filename;
+
+ options = GLADE_PROJECT_OPTIONS (gtk_widget_get_toplevel (widget));
+
+ if (options->filesel == NULL)
+ {
+ options->filesel = gtk_file_chooser_dialog_new (_("Select the Project Directory"),
+ GTK_WINDOW (options),
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (options->filesel),
+ GTK_RESPONSE_OK);
+
+ g_signal_connect (options->filesel, "response",
+ GTK_SIGNAL_FUNC (on_filesel_response), options);
+ g_signal_connect (options->filesel, "delete_event",
+ G_CALLBACK (gtk_true), NULL);
+ }
+
+ filename = (char*) gtk_entry_get_text (GTK_ENTRY (options->directory_entry));
+ if (glade_util_file_exists (filename))
+ {
+ glade_util_set_file_selection_filename (options->filesel, filename);
+ }
+
+ gtk_window_present (GTK_WINDOW (options->filesel));
+}
+
+
+static void
+on_filesel_response (GtkWidget *widget,
+ gint response_id,
+ GladeProjectOptions *options)
+{
+ gchar *filename;
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ filename = glade_util_get_file_selection_filename (options->filesel);
+ if (filename)
+ gtk_entry_set_text (GTK_ENTRY (options->directory_entry), filename);
+ g_free (filename);
+ }
+
+ glade_util_close_window (options->filesel);
+}
+
+
+static void
+glade_project_options_ok (GtkWidget *widget,
+ GladeProjectOptions *options)
+{
+ GladeProject *project;
+ gchar *xml_filename, *directory, *source_directory, *pixmaps_directory;
+ gchar *strings_filename;
+ gint language;
+
+ project = options->project;
+
+ /* First check that the options are valid, according to the requested action.
+ If not, we need to stop the signal so the dialog isn't closed. */
+ if (!glade_project_options_check_valid (options))
+ {
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "clicked");
+ return;
+ }
+
+ /* The project directory is the only aboslute path. Everything else is
+ relative to it, so needs to be turned into an absolute path here. */
+ directory = get_entry_text (options->directory_entry);
+ glade_project_set_directory (project, directory);
+
+ glade_project_set_name (project, get_entry_text (options->name_entry));
+ glade_project_set_program_name (project, get_entry_text (options->program_name_entry));
+
+ pixmaps_directory = get_entry_text (options->pixmaps_directory_entry);
+ pixmaps_directory = glade_util_make_absolute_path (directory,
+ pixmaps_directory);
+ glade_project_set_pixmaps_directory (project, pixmaps_directory);
+ g_free (pixmaps_directory);
+
+ source_directory = get_entry_text (options->source_directory_entry);
+ source_directory = glade_util_make_absolute_path (directory,
+ source_directory);
+ glade_project_set_source_directory (project, source_directory);
+ g_free (source_directory);
+
+ xml_filename = get_entry_text (options->xml_filename_entry);
+ xml_filename = glade_util_make_absolute_path (directory, xml_filename);
+ glade_project_set_xml_filename (project, xml_filename);
+ g_free (xml_filename);
+
+ for (language = 0; language < GladeNumLanguages; language++)
+ {
+
+ if (GTK_TOGGLE_BUTTON (options->language_buttons[language])->active)
+ {
+ glade_project_set_language_name (project, GladeLanguages[language]);
+ break;
+ }
+ }
+
+
+#ifdef USE_GNOME
+ glade_project_set_gnome_support (project, GTK_TOGGLE_BUTTON (options->gnome_support)->active ? TRUE : FALSE);
+#ifdef USE_GNOME_DB
+ glade_project_set_gnome_db_support (project, GTK_TOGGLE_BUTTON (options->gnome_db_support)->active ? TRUE : FALSE);
+#endif
+#endif
+
+ glade_project_set_gettext_support (project, GTK_TOGGLE_BUTTON (options->gettext_support)->active ? TRUE : FALSE);
+
+ glade_project_set_use_widget_names (project, GTK_TOGGLE_BUTTON (options->use_widget_names)->active ? TRUE : FALSE);
+
+ glade_project_set_output_main_file (project, GTK_TOGGLE_BUTTON (options->output_main_file)->active ? TRUE : FALSE);
+
+ glade_project_set_output_support_files (project, GTK_TOGGLE_BUTTON (options->output_support_files)->active ? TRUE : FALSE);
+
+ glade_project_set_output_build_files (project, GTK_TOGGLE_BUTTON (options->output_build_files)->active ? TRUE : FALSE);
+
+ glade_project_set_backup_source_files (project, GTK_TOGGLE_BUTTON (options->backup_source_files)->active ? TRUE : FALSE);
+
+ glade_project_set_gnome_help_support (project, GTK_TOGGLE_BUTTON (options->gnome_help_support)->active ? TRUE : FALSE);
+
+ glade_project_set_source_files (project,
+ get_entry_text (options->main_source_entry),
+ get_entry_text (options->main_header_entry),
+ get_entry_text (options->handler_source_entry),
+ get_entry_text (options->handler_header_entry));
+ glade_project_set_support_source_file (project, get_entry_text (options->support_source_entry));
+ glade_project_set_support_header_file (project, get_entry_text (options->support_header_entry));
+
+ glade_project_set_output_translatable_strings (project, GTK_TOGGLE_BUTTON (options->output_translatable_strings)->active ? TRUE : FALSE);
+
+ strings_filename = get_entry_text (options->translatable_strings_filename_entry);
+ strings_filename = glade_util_make_absolute_path (directory,
+ strings_filename);
+ glade_project_set_translatable_strings_file (project, strings_filename);
+ g_free (strings_filename);
+
+ g_free (directory);
+ gtk_widget_destroy (GTK_WIDGET (options));
+}
+
+
+/* This returns a pointer to the text in the given entry, or NULL if the entry
+ is empty. */
+static gchar*
+get_entry_text (GtkWidget *entry)
+{
+ gchar *text;
+
+ text = (char*) gtk_entry_get_text (GTK_ENTRY (entry));
+ if (text && text[0] != '\0')
+ return text;
+ else
+ return NULL;
+}
+
+
+void
+glade_project_options_set_action (GladeProjectOptions *options,
+ GladeProjectOptionsAction action)
+{
+ options->action = action;
+}
+
+
+/* This checks that all the options needed for the required action have been
+ set, and returns TRUE if so. */
+static gboolean
+glade_project_options_check_valid (GladeProjectOptions *options)
+{
+ gchar *error = NULL;
+ gchar *directory, *xml_filename, *project_name, *program_name;
+ gchar *source_directory, *pixmaps_directory;
+ gboolean output_translatable_strings;
+ gchar *translatable_strings_filename;
+
+ directory = get_entry_text (options->directory_entry);
+ xml_filename = get_entry_text (options->xml_filename_entry);
+ project_name = get_entry_text (options->name_entry);
+ program_name = get_entry_text (options->program_name_entry);
+ source_directory = get_entry_text (options->source_directory_entry);
+ pixmaps_directory = get_entry_text (options->pixmaps_directory_entry);
+ output_translatable_strings = GTK_TOGGLE_BUTTON (options->output_translatable_strings)->active;
+ translatable_strings_filename = get_entry_text (options->translatable_strings_filename_entry);
+
+ switch (options->action)
+ {
+ case GLADE_PROJECT_OPTIONS_ACTION_NORMAL:
+ if (output_translatable_strings
+ && (translatable_strings_filename == NULL
+ || translatable_strings_filename[0] == '\0'))
+ error = _("You need to set the Translatable Strings File option");
+ break;
+ case GLADE_PROJECT_OPTIONS_ACTION_SAVE:
+ if (directory == NULL || directory[0] == '\0')
+ error = _("You need to set the Project Directory option");
+ else if (xml_filename == NULL || xml_filename[0] == '\0')
+ error = _("You need to set the Project File option");
+ else if (output_translatable_strings
+ && (translatable_strings_filename == NULL
+ || translatable_strings_filename[0] == '\0'))
+ error = _("You need to set the Translatable Strings File option");
+ break;
+ case GLADE_PROJECT_OPTIONS_ACTION_BUILD:
+ if (directory == NULL || directory[0] == '\0')
+ error = _("You need to set the Project Directory option");
+ else if (xml_filename == NULL || xml_filename[0] == '\0')
+ error = _("You need to set the Project File option");
+ else if (output_translatable_strings
+ && (translatable_strings_filename == NULL
+ || translatable_strings_filename[0] == '\0'))
+ error = _("You need to set the Translatable Strings File option");
+ else if (project_name == NULL || project_name[0] == '\0')
+ error = _("You need to set the Project Name option");
+ else if (program_name == NULL || program_name[0] == '\0')
+ error = _("You need to set the Program Name option");
+#if 0
+ else if (source_directory == NULL || source_directory[0] == '\0')
+ error = _("You need to set the Source Directory option");
+#endif
+ else if (pixmaps_directory == NULL || pixmaps_directory[0] == '\0')
+ error = _("You need to set the Pixmaps Directory option");
+ break;
+ }
+
+ if (error)
+ {
+ glade_util_show_message_box (error, GTK_WIDGET (options));
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/tools/glade/glade/glade_project_options.h b/tools/glade/glade/glade_project_options.h
new file mode 100644
index 00000000..120ce78b
--- /dev/null
+++ b/tools/glade/glade/glade_project_options.h
@@ -0,0 +1,142 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_PROJECT_OPTIONS_H
+#define GLADE_PROJECT_OPTIONS_H
+
+#include <gtk/gtkwindow.h>
+
+#include "glade_project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * GladeProjectOptions is a subclass of GtkWindow, used to set the project
+ * options.
+ */
+
+#define GLADE_PROJECT_OPTIONS(obj) GTK_CHECK_CAST (obj, glade_project_options_get_type (), GladeProjectOptions)
+#define GLADE_PROJECT_OPTIONS_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_project_options_get_type (), GladeProjectOptionsClass)
+#define GLADE_IS_PROJECT_OPTIONS(obj) GTK_CHECK_TYPE (obj, glade_project_options_get_type ())
+
+typedef enum
+{
+ GLADE_PROJECT_OPTIONS_ACTION_NORMAL,
+ GLADE_PROJECT_OPTIONS_ACTION_SAVE,
+ GLADE_PROJECT_OPTIONS_ACTION_BUILD
+} GladeProjectOptionsAction;
+
+
+typedef struct _GladeProjectOptions GladeProjectOptions;
+typedef struct _GladeProjectOptionsClass GladeProjectOptionsClass;
+
+struct _GladeProjectOptions
+{
+ GtkWindow window;
+
+ /* This is the project whose options we are editing. */
+ GladeProject *project;
+
+ /* This is the action which will be taken after the dialog is closed.
+ We will ensure that any options needed for the action are set properly
+ before the dialog is closed. */
+ GladeProjectOptionsAction action;
+
+ /*
+ * General options page.
+ */
+ GtkWidget *name_entry;
+ gboolean generate_name;
+ GtkWidget *program_name_entry;
+ gboolean generate_program_name;
+ GtkWidget *xml_filename_entry;
+ gboolean generate_xml_filename;
+ GtkWidget *directory_entry;
+ GtkWidget *source_directory_entry;
+ GtkWidget *pixmaps_directory_entry;
+
+ GtkWidget **language_buttons;
+
+ /* Take this out until we support it. */
+ /*GtkWidget *license_option_menu;*/
+
+ GtkWidget *gnome_support;
+ GtkWidget *gnome_db_support;
+
+ /*
+ * C options page.
+ */
+ GtkWidget *gettext_support;
+ GtkWidget *use_widget_names;
+ GtkWidget *output_main_file;
+ GtkWidget *output_support_files;
+ GtkWidget *output_build_files;
+ GtkWidget *backup_source_files;
+ GtkWidget *gnome_help_support;
+
+ GtkWidget *main_source_entry;
+ GtkWidget *main_header_entry;
+ GtkWidget *handler_source_entry;
+ GtkWidget *handler_header_entry;
+ GtkWidget *support_source_entry;
+ GtkWidget *support_header_entry;
+
+ /*
+ * libglade options page.
+ */
+ GtkWidget *output_translatable_strings;
+ GtkWidget *translatable_strings_filename_label;
+ GtkWidget *translatable_strings_filename_entry;
+
+
+ /*
+ * C options page.
+ */
+ GtkWidget *ok_button;
+ GtkWidget *cancel_button;
+
+ /* This is the file selection dialog we use for all file selections. */
+ GtkWidget *filesel;
+
+ /* This is incremented when we are auto-generating the project name, program
+ name & xml filename. It is used to tell whether an options is being
+ auto-generated or the user has edited it. */
+ gint auto_generation_level;
+};
+
+
+struct _GladeProjectOptionsClass
+{
+ GtkWindowClass parent_class;
+};
+
+
+
+
+GType glade_project_options_get_type (void);
+GtkWidget* glade_project_options_new (GladeProject *project);
+
+void glade_project_options_set_action (GladeProjectOptions *options,
+ GladeProjectOptionsAction action);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PROJECT_OPTIONS_H */
diff --git a/tools/glade/glade/glade_project_view.c b/tools/glade/glade/glade_project_view.c
new file mode 100644
index 00000000..730f63e2
--- /dev/null
+++ b/tools/glade/glade/glade_project_view.c
@@ -0,0 +1,311 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <gtk/gtk.h>
+#include "editor.h"
+#include "glade_project_view.h"
+#include "utils.h"
+
+GladeProjectView *current_project_view = NULL;
+
+static GtkCListClass *parent_class = NULL;
+
+static void glade_project_view_class_init (GladeProjectViewClass * klass);
+static void glade_project_view_init (GladeProjectView * project_view);
+
+void set_project_callback (GtkWidget *component,
+ GladeProjectView *project_view);
+
+static void glade_project_view_real_add_component (GladeProject *project,
+ GtkWidget *component,
+ GladeProjectView *project_view);
+static void glade_project_view_real_remove_component (GladeProject *project,
+ GtkWidget *component,
+ GladeProjectView *project_view);
+static void glade_project_view_component_changed (GladeProject *project,
+ GtkWidget *component,
+ GladeProjectView *project_view);
+static void glade_project_view_select_component (GladeProjectView *project_view,
+ gint row,
+ gint column,
+ GdkEventButton *bevent,
+ gpointer data);
+
+GType
+glade_project_view_get_type (void)
+{
+ static GType glade_project_view_type = 0;
+
+ if (!glade_project_view_type)
+ {
+ GtkTypeInfo glade_project_view_info =
+ {
+ "GladeProjectView",
+ sizeof (GladeProjectView),
+ sizeof (GladeProjectViewClass),
+ (GtkClassInitFunc) glade_project_view_class_init,
+ (GtkObjectInitFunc) glade_project_view_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ glade_project_view_type = gtk_type_unique (gtk_clist_get_type (),
+ &glade_project_view_info);
+ }
+ return glade_project_view_type;
+}
+
+
+static void
+glade_project_view_class_init (GladeProjectViewClass * klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) klass;
+
+ parent_class = gtk_type_class (gtk_clist_get_type ());
+}
+
+
+static void
+glade_project_view_init (GladeProjectView * project_view)
+{
+ project_view->project = NULL;
+ /* This no longer exists in GTK+ 2.0, so I hope it isn't needed. */
+ /*gtk_clist_construct (GTK_CLIST (project_view), 1, NULL);*/
+}
+
+
+GtkWidget *
+glade_project_view_new ()
+{
+ GtkWidget *project_view;
+
+ project_view = GTK_WIDGET (gtk_type_new (glade_project_view_get_type ()));
+ gtk_clist_column_titles_hide (GTK_CLIST (project_view));
+ gtk_clist_set_row_height (GTK_CLIST (project_view), 20);
+ gtk_clist_set_column_width (GTK_CLIST (project_view), 0, 140);
+ gtk_widget_set_usize (project_view, 172, 100);
+ gtk_signal_connect (GTK_OBJECT (project_view), "select_row",
+ GTK_SIGNAL_FUNC (glade_project_view_select_component),
+ NULL);
+
+ /* FIXME: We only support one project view at present. */
+ current_project_view = GLADE_PROJECT_VIEW (project_view);
+
+ return project_view;
+}
+
+
+GladeProject*
+glade_project_view_get_project (GladeProjectView *project_view)
+{
+ return project_view->project;
+}
+
+
+void
+glade_project_view_set_project (GladeProjectView *project_view,
+ GladeProject *project)
+{
+ if (project_view->project == project)
+ return;
+
+ project_view->project = project;
+ gtk_clist_clear (GTK_CLIST (project_view));
+
+ if (project)
+ {
+ glade_project_foreach_component (project,
+ (GtkCallback) set_project_callback,
+ project_view);
+ gtk_signal_connect (GTK_OBJECT (project), "add_component",
+ GTK_SIGNAL_FUNC (glade_project_view_real_add_component),
+ project_view);
+ gtk_signal_connect (GTK_OBJECT (project), "remove_component",
+ GTK_SIGNAL_FUNC (glade_project_view_real_remove_component),
+ project_view);
+ gtk_signal_connect (GTK_OBJECT (project), "component_changed",
+ GTK_SIGNAL_FUNC (glade_project_view_component_changed),
+ project_view);
+ }
+}
+
+
+void
+set_project_callback (GtkWidget *component,
+ GladeProjectView *project_view)
+{
+ GbWidget *gbwidget;
+ gchar *name;
+ gint row;
+
+ name = (gchar*) gtk_widget_get_name (component);
+ gbwidget = gb_widget_lookup (component);
+ g_return_if_fail (gbwidget != NULL);
+
+ row = gtk_clist_append (GTK_CLIST (project_view), &name);
+ gtk_clist_set_row_data (GTK_CLIST (project_view), row, component);
+ gtk_clist_set_pixtext (GTK_CLIST (project_view), row, 0, name, 3,
+ gbwidget->gdkpixmap, gbwidget->mask);
+}
+
+
+static void
+glade_project_view_real_add_component (GladeProject *project,
+ GtkWidget *component,
+ GladeProjectView *project_view)
+{
+ GbWidget * gbwidget;
+ gchar *name;
+ gint row;
+
+ name = (gchar*) gtk_widget_get_name (component);
+ gbwidget = gb_widget_lookup (component);
+ g_return_if_fail (gbwidget != NULL);
+
+ row = gtk_clist_append (GTK_CLIST (project_view), &name);
+ gtk_clist_set_row_data (GTK_CLIST (project_view), row, component);
+ gtk_clist_set_pixtext (GTK_CLIST (project_view), row, 0, name, 3,
+ gbwidget->gdkpixmap, gbwidget->mask);
+}
+
+
+static void
+glade_project_view_real_remove_component (GladeProject *project,
+ GtkWidget *component,
+ GladeProjectView *project_view)
+{
+ gint row;
+
+ row = gtk_clist_find_row_from_data (GTK_CLIST (project_view), component);
+ g_return_if_fail (row != -1);
+ gtk_clist_remove (GTK_CLIST (project_view), row);
+}
+
+
+/* This is called when a 'component_changed' signal has been emitted by the
+ GladeProject. Currently that only happens when the component's name has
+ changed. */
+static void
+glade_project_view_component_changed (GladeProject *project,
+ GtkWidget *component,
+ GladeProjectView *project_view)
+{
+ gchar *name, *old_name;
+ gint row;
+ guint8 spacing;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+
+ row = gtk_clist_find_row_from_data (GTK_CLIST (project_view), component);
+ g_return_if_fail (row != -1);
+ gtk_clist_get_pixtext (GTK_CLIST (project_view), row, 0, &old_name, &spacing,
+ &pixmap, &mask);
+ name = (gchar*) gtk_widget_get_name (component);
+ gtk_clist_set_pixtext (GTK_CLIST (project_view), row, 0, name, spacing,
+ pixmap, mask);
+}
+
+
+void
+glade_project_view_clear_component_selection (GladeProjectView *project_view,
+ GtkWidget *widget)
+{
+ GtkWidget *component;
+ GList *selection, *list;
+ gint row;
+
+ list = g_list_copy (GTK_CLIST (project_view)->selection);
+
+ selection = list;
+ while (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ component = gtk_clist_get_row_data (GTK_CLIST (project_view), row);
+ if (component != widget)
+ {
+ gtk_clist_unselect_row (GTK_CLIST (project_view), row, 0);
+ }
+ selection = selection->next;
+ }
+
+ g_list_free (list);
+}
+
+
+static void
+glade_project_view_select_component (GladeProjectView *project_view,
+ gint row,
+ gint column,
+ GdkEventButton *bevent,
+ gpointer data)
+{
+ GtkWidget *component;
+
+ component = (GtkWidget*) gtk_clist_get_row_data (GTK_CLIST (project_view),
+ row);
+ g_return_if_fail (component != NULL);
+
+ /* Select the widget, so it can be copied/pasted. */
+ editor_clear_selection (component);
+ if (!editor_is_selected (component))
+ {
+ editor_select_widget_control (component);
+ }
+
+ /* Show the properties of the component. */
+ gb_widget_show_properties (component);
+
+ /* If the component is double-clicked we also show it. */
+ if (bevent && bevent->type == GDK_2BUTTON_PRESS)
+ glade_project_show_component (project_view->project, component);
+}
+
+
+gboolean
+glade_project_view_has_selection (GladeProjectView *project_view)
+{
+ if (GTK_CLIST (project_view)->selection)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+void
+glade_project_view_delete_selection (GladeProjectView *project_view)
+{
+ GtkWidget *component;
+ GList *selection;
+
+ selection = GTK_CLIST (project_view)->selection;
+ while (selection)
+ {
+ component = gtk_clist_get_row_data (GTK_CLIST (project_view),
+ GPOINTER_TO_INT (selection->data));
+ glade_project_remove_component (project_view->project, component);
+
+ /* The deletion may have changed the selection, so we simply start at
+ the beginning of the list each time. */
+ selection = GTK_CLIST (project_view)->selection;
+ }
+}
diff --git a/tools/glade/glade/glade_project_view.h b/tools/glade/glade/glade_project_view.h
new file mode 100644
index 00000000..93213735
--- /dev/null
+++ b/tools/glade/glade/glade_project_view.h
@@ -0,0 +1,85 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_PROJECT_VIEW_H
+#define GLADE_PROJECT_VIEW_H
+
+#include <gtk/gtkclist.h>
+
+#include "glade_project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * GladeProjectView is a subclass of GtkCList, used to show the project
+ * components. (It may change to a subclass of CTree later).
+ *
+ * I've made it a separate widget so it can be placed anywhere in an
+ * interface, e.g. an IDE may place it in a notebook, with one notebook page
+ * containing the source files in the project, and another containing a
+ * GladeProjectView to show the components/widgets in a project.
+ */
+
+#define GLADE_PROJECT_VIEW(obj) GTK_CHECK_CAST (obj, glade_project_view_get_type (), GladeProjectView)
+#define GLADE_PROJECT_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, glade_project_view_get_type (), GladeProjectViewClass)
+#define GLADE_IS_PROJECT_VIEW(obj) GTK_CHECK_TYPE (obj, glade_project_view_get_type ())
+
+
+typedef struct _GladeProjectView GladeProjectView;
+typedef struct _GladeProjectViewClass GladeProjectViewClass;
+
+struct _GladeProjectView
+{
+ GtkCList clist;
+
+ GladeProject *project;
+};
+
+
+struct _GladeProjectViewClass
+{
+ GtkCListClass parent_class;
+};
+
+
+/* FIXME: Currently we only support one project view at once, and this is it.
+ But we will support multiple projects in future, so try not to use this
+ too much. */
+extern GladeProjectView *current_project_view;
+
+
+GType glade_project_view_get_type (void);
+GtkWidget* glade_project_view_new (void);
+
+GladeProject* glade_project_view_get_project (GladeProjectView *project_view);
+void glade_project_view_set_project (GladeProjectView *project_view,
+ GladeProject *project);
+
+gboolean glade_project_view_has_selection (GladeProjectView *project_view);
+/* Deselect all components, except the given widget */
+void glade_project_view_clear_component_selection (GladeProjectView *project_view,
+ GtkWidget *widget);
+void glade_project_view_delete_selection(GladeProjectView *project_view);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PROJECT_VIEW_H */
diff --git a/tools/glade/glade/glade_project_window.c b/tools/glade/glade/glade_project_window.c
new file mode 100644
index 00000000..4a609fd5
--- /dev/null
+++ b/tools/glade/glade/glade_project_window.c
@@ -0,0 +1,2108 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <locale.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkcheckmenuitem.h>
+#include <gtk/gtkfilechooserdialog.h>
+#include <gtk/gtkhbbox.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenubar.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkseparatormenuitem.h>
+#include <gtk/gtkstatusbar.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtktextview.h>
+#include <gtk/gtkvbox.h>
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#endif
+
+#include "glade.h"
+#include "glade_clipboard.h"
+#include "glade_palette.h"
+#include "glade_project_options.h"
+#include "glade_project_window.h"
+#include "editor.h"
+#include "gbwidget.h"
+#include "load.h"
+#include "property.h"
+#include "tree.h"
+#include "utils.h"
+
+/* This is the main project window. */
+static GladeProjectWindow *project_window;
+
+/* This is used to store a pointer to a GladeProjectWindow in the main window.
+ */
+static gchar *GladeProjectWindowKey = "GladeProjectWindowKey";
+
+/* The menuitem's to show/hide the various windows. */
+static GtkWidget *palette_item = NULL;
+static GtkWidget *property_editor_item = NULL;
+static GtkWidget *widget_tree_item = NULL;
+static GtkWidget *clipboard_item = NULL;
+
+/* stuff for opening a file when dragged into glade */
+enum
+{
+ TARGET_URI_LIST
+};
+
+static GtkTargetEntry drop_types[] =
+{
+ {"text/uri-list", 0, TARGET_URI_LIST}
+};
+
+
+static gboolean glade_project_window_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ GladeProjectWindow *project_window);
+static void glade_project_window_destroy (GtkWidget *widget,
+ gpointer data);
+
+static void glade_project_window_new_project (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_on_new_project_ok (GladeProjectWindow *project_window);
+static void glade_project_window_on_open_project (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_real_open_project (GtkWidget *widget,
+ gint response_id,
+ GladeProjectWindow *project_window);
+
+static void glade_project_window_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint time, gpointer data);
+#if 0
+static void glade_project_window_show_loading_errors (GladeProjectWindow *project_window,
+ GList *errors);
+#endif
+static GtkWidget* glade_project_window_new_errors_dialog (GladeProjectWindow *project_window,
+ GtkWidget **text_return);
+
+static void glade_project_window_on_edit_options (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_edit_options (GladeProjectWindow *project_window,
+ GladeProjectOptionsAction action);
+static void glade_project_window_save_project (GtkWidget *widget,
+ gpointer data);
+#if 0
+static void glade_project_window_on_save_project_as (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_save_project_as (GladeProjectWindow *project_window);
+static void glade_project_window_save_as_callback (GtkWidget *widget,
+ gint response_id,
+ GladeProjectWindow *project_window);
+#endif
+static gboolean glade_project_window_real_save_project (GladeProjectWindow *project_window,
+ gboolean warn_before_overwrite);
+static void glade_project_window_write_source (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_real_write_source (GladeProjectWindow *project_window);
+static void glade_project_window_show_error (GladeProjectWindow *project_window,
+ GladeError *error,
+ gchar *title);
+
+static void glade_project_window_quit (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_show_quit_dialog (GladeProjectWindow *project_window);
+
+static void glade_project_window_cut (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_copy (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_paste (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_delete (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_real_delete (GladeProjectWindow *project_window);
+
+static void glade_project_window_toggle_palette (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_toggle_property_editor (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_toggle_widget_tree (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_toggle_clipboard (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_toggle_tooltips (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_toggle_grid (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_edit_grid_settings (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_toggle_snap (GtkWidget *widget,
+ gpointer data);
+static void glade_project_window_edit_snap_settings (GtkWidget *widget,
+ gpointer data);
+
+static void glade_project_window_about (GtkWidget *widget,
+ gpointer data);
+
+static gint glade_project_window_key_press_event (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data);
+
+static void glade_project_window_options_ok (GtkWidget *widget,
+ GladeProjectWindow *project_window);
+static void glade_project_window_update_title (GladeProjectWindow *project_window);
+
+
+
+#ifdef USE_GNOME
+static void
+glade_project_window_show_help_doc (const gchar *docname,
+ GtkWidget *transient_widget)
+{
+ GError *error = NULL;
+
+ gnome_help_display (docname, NULL, &error);
+ if (error) {
+ char *message;
+ message = g_strdup_printf (_("Couldn't show help file: %s.\n\nError: %s"),
+ docname, error->message);
+ glade_util_show_message_box (message, transient_widget);
+ g_free (message);
+ g_error_free (error);
+ }
+}
+
+
+static void
+glade_project_window_show_glade_faq (GtkWidget *menuitem,
+ gpointer data)
+{
+ glade_project_window_show_help_doc ("glade-faq", menuitem);
+}
+#endif
+
+
+/*
+ * These are the menubar and toolbar definitions for Gnome.
+ */
+#ifdef USE_GNOME
+static GnomeUIInfo FileMenu[] =
+{
+ GNOMEUIINFO_MENU_NEW_ITEM (N_("_New"), N_("Create a new project"),
+ glade_project_window_new_project, NULL),
+ GNOMEUIINFO_MENU_OPEN_ITEM (glade_project_window_on_open_project, NULL),
+ GNOMEUIINFO_MENU_SAVE_ITEM (glade_project_window_save_project, NULL),
+ /*GNOMEUIINFO_MENU_SAVE_AS_ITEM (glade_project_window_on_save_project_as,
+ NULL),*/
+ GNOMEUIINFO_SEPARATOR,
+ {
+ GNOME_APP_UI_ITEM, N_("_Build"),
+ N_("Output the project source code"),
+ glade_project_window_write_source, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GTK_STOCK_CONVERT,
+ 'B', GDK_CONTROL_MASK, NULL
+ },
+ {
+ GNOME_APP_UI_ITEM, N_("Op_tions..."),
+ N_("Edit the project options"),
+ glade_project_window_on_edit_options, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GTK_STOCK_PROPERTIES,
+ 0, 0, NULL
+ },
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_QUIT_ITEM (glade_project_window_quit, NULL),
+ GNOMEUIINFO_END
+};
+
+static GnomeUIInfo EditMenu[] =
+{
+ GNOMEUIINFO_MENU_CUT_ITEM (glade_project_window_cut, NULL),
+ GNOMEUIINFO_MENU_COPY_ITEM (glade_project_window_copy, NULL),
+ GNOMEUIINFO_MENU_PASTE_ITEM (glade_project_window_paste, NULL),
+ { GNOME_APP_UI_ITEM, N_("_Delete"), N_("Delete the selected widget"),
+ glade_project_window_delete, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_TRASH,
+ GDK_DELETE, 0, NULL },
+ GNOMEUIINFO_END
+};
+
+
+/* These must match the indices of the appropriate items in the settings
+ GnomeUIInfo array. We need them to set the initial state. */
+#define GLADE_PALETTE_ITEM 0
+#define GLADE_PROPERTY_EDITOR_ITEM 1
+#define GLADE_WIDGET_TREE_ITEM 2
+#define GLADE_CLIPBOARD_ITEM 3
+
+static GnomeUIInfo ViewMenu[] =
+{
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("Show _Palette"), N_("Show the palette of widgets"),
+ glade_project_window_toggle_palette, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("Show Property _Editor"),
+ N_("Show the property editor"),
+ glade_project_window_toggle_property_editor, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("Show Widget _Tree"),
+ N_("Show the widget tree"),
+ glade_project_window_toggle_widget_tree, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("Show _Clipboard"),
+ N_("Show the clipboard"),
+ glade_project_window_toggle_clipboard, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ GNOMEUIINFO_END
+};
+
+
+/* These must match the indices of the appropriate items in the settings
+ GnomeUIInfo array. We need them to set the initial state. */
+#define GLADE_SHOW_GRID_ITEM 0
+#define GLADE_SNAP_TO_GRID_ITEM 1
+#define GLADE_SHOW_TOOLTIPS_ITEM 2
+
+static GnomeUIInfo SettingsMenu[] =
+{
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("Show _Grid"),
+ N_("Show the grid (in fixed containers only)"),
+ glade_project_window_toggle_grid, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("_Snap to Grid"),
+ N_("Snap widgets to the grid"),
+ glade_project_window_toggle_snap, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_TOGGLEITEM, N_("Show _Widget Tooltips"),
+ N_("Show the tooltips of created widgets"),
+ glade_project_window_toggle_tooltips, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+
+ GNOMEUIINFO_SEPARATOR,
+
+ {
+ GNOME_APP_UI_ITEM, N_("Set Grid _Options..."),
+ N_("Set the grid style and spacing"),
+ glade_project_window_edit_grid_settings, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_ITEM, N_("Set Snap O_ptions..."),
+ N_("Set options for snapping to the grid"),
+ glade_project_window_edit_snap_settings, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+ GNOMEUIINFO_END
+};
+
+static GnomeUIInfo HelpMenu[] =
+{
+ GNOMEUIINFO_HELP ("glade-user-guide"),
+ {
+ GNOME_APP_UI_ITEM, N_("_FAQ"),
+ N_("View the Glade FAQ"),
+ glade_project_window_show_glade_faq, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL,
+ 0, 0, NULL
+ },
+
+ GNOMEUIINFO_SEPARATOR,
+
+ GNOMEUIINFO_MENU_ABOUT_ITEM (glade_project_window_about, NULL),
+ GNOMEUIINFO_END
+};
+
+static GnomeUIInfo MainMenu[] =
+{
+ GNOMEUIINFO_SUBTREE (N_("_Project"), FileMenu),
+ GNOMEUIINFO_MENU_EDIT_TREE (EditMenu),
+ GNOMEUIINFO_MENU_VIEW_TREE (ViewMenu),
+ GNOMEUIINFO_MENU_SETTINGS_TREE (SettingsMenu),
+ GNOMEUIINFO_MENU_HELP_TREE (HelpMenu),
+ GNOMEUIINFO_END
+};
+
+static GnomeUIInfo ToolBar[] =
+{
+ {
+ GNOME_APP_UI_ITEM, N_("New"), N_("New Project"),
+ glade_project_window_new_project, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_NEW, 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_ITEM, N_("Open"), N_("Open Project"),
+ glade_project_window_on_open_project, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_OPEN, 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_ITEM, N_("Save"), N_("Save Project"),
+ glade_project_window_save_project, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_SAVE, 0, 0, NULL
+ },
+ GNOMEUIINFO_SEPARATOR,
+ {
+ GNOME_APP_UI_ITEM, N_("Options"), N_("Project Options"),
+ glade_project_window_on_edit_options, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GTK_STOCK_PROPERTIES, 0, 0, NULL
+ },
+ {
+ GNOME_APP_UI_ITEM, N_("Build"), N_("Build the Source Code"),
+ glade_project_window_write_source, NULL, NULL,
+ GNOME_APP_PIXMAP_STOCK, GTK_STOCK_CONVERT, 0, 0, NULL
+ },
+ GNOMEUIINFO_END
+};
+#endif
+
+
+#ifdef USE_GNOME
+GladeProjectWindow*
+glade_project_window_new (void)
+{
+ GtkWidget *scrolled_win;
+ GtkWidget *show_grid_item, *snap_to_grid_item, *show_tooltips_item;
+
+ project_window = g_new (GladeProjectWindow, 1);
+ project_window->current_directory = NULL;
+
+ project_window->window = gnome_app_new ("Glade", "Glade");
+ gtk_widget_set_name (project_window->window, "GladeProjectWindow");
+ gtk_window_set_wmclass (GTK_WINDOW (project_window->window),
+ "project", "Glade");
+
+ /* We want all the keyboard accelerators from the menus to work anywhere in
+ the Glade GUI, including windows being designed. So we add the accel
+ group to every window. */
+ GNOME_APP (project_window->window)->accel_group = glade_get_global_accel_group ();
+ gtk_window_add_accel_group (GTK_WINDOW (project_window->window),
+ glade_get_global_accel_group ());
+
+ /* Save a pointer to the GladeProjectWindow, so we can find it in callbacks.
+ */
+ gtk_object_set_data (GTK_OBJECT (project_window->window),
+ GladeProjectWindowKey, project_window);
+
+ gtk_window_move (GTK_WINDOW (project_window->window), 0, 0);
+
+ gtk_signal_connect (GTK_OBJECT (project_window->window), "destroy",
+ GTK_SIGNAL_FUNC (glade_project_window_destroy), NULL);
+ gtk_signal_connect (GTK_OBJECT (project_window->window), "delete_event",
+ GTK_SIGNAL_FUNC (glade_project_window_delete_event),
+ project_window);
+ gtk_signal_connect_after (GTK_OBJECT (project_window->window),
+ "key_press_event",
+ GTK_SIGNAL_FUNC (glade_project_window_key_press_event),
+ NULL);
+
+ /* support for opening a file by dragging onto the project window */
+ gtk_drag_dest_set (project_window->window,
+ GTK_DEST_DEFAULT_ALL,
+ drop_types, G_N_ELEMENTS (drop_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ g_signal_connect (G_OBJECT (project_window->window), "drag-data-received",
+ G_CALLBACK (glade_project_window_drag_data_received), NULL);
+
+ gnome_app_create_menus (GNOME_APP (project_window->window), MainMenu);
+
+ /* Set the states of the toggle items. */
+ palette_item = ViewMenu[GLADE_PALETTE_ITEM].widget;
+ property_editor_item = ViewMenu[GLADE_PROPERTY_EDITOR_ITEM].widget;
+ widget_tree_item = ViewMenu[GLADE_WIDGET_TREE_ITEM].widget;
+ clipboard_item = ViewMenu[GLADE_CLIPBOARD_ITEM].widget;
+
+ show_grid_item = SettingsMenu[GLADE_SHOW_GRID_ITEM].widget;
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (show_grid_item),
+ editor_get_show_grid ());
+
+ snap_to_grid_item = SettingsMenu[GLADE_SNAP_TO_GRID_ITEM].widget;
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (snap_to_grid_item),
+ editor_get_snap_to_grid ());
+
+ show_tooltips_item = SettingsMenu[GLADE_SHOW_TOOLTIPS_ITEM].widget;
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (show_tooltips_item),
+ gb_widget_get_show_tooltips ());
+
+
+ gnome_app_create_toolbar (GNOME_APP (project_window->window), ToolBar);
+
+ /* Create list of components */
+ project_window->project_view = glade_project_view_new ();
+ gtk_widget_show (project_window->project_view);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win),
+ project_window->project_view);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show(scrolled_win);
+
+ gnome_app_set_contents (GNOME_APP (project_window->window), scrolled_win);
+
+ /* Create status bar. */
+ project_window->statusbar = gtk_statusbar_new ();
+ gnome_app_set_statusbar (GNOME_APP (project_window->window),
+ project_window->statusbar);
+ gnome_app_install_statusbar_menu_hints (GTK_STATUSBAR (project_window->statusbar), MainMenu);
+
+ return project_window;
+}
+
+#else
+
+#if 0
+static GtkItemFactoryEntry menu_items[] =
+{
+ { "/_File", NULL,
+ 0, 0, "<Branch>" },
+ { "/File/tearoff1", NULL,
+ 0, 0, "<Tearoff>" },
+ { "/File/_New Project", NULL,
+ glade_project_window_new_project, 0, "<StockItem>", GTK_STOCK_NEW },
+ { "/File/_Open", NULL,
+ glade_project_window_on_open_project, 0, "<StockItem>", GTK_STOCK_OPEN },
+ { "/File/_Save", NULL,
+ glade_project_window_save_project, 0, "<StockItem>", GTK_STOCK_SAVE },
+ { "/File/sep1", NULL,
+ 0, 0, "<Separator>" },
+ { "/File/_Build Source Code", NULL,
+ glade_project_window_write_source, 0, "<StockItem>", GTK_STOCK_CONVERT },
+ { "/File/_Project Options", NULL,
+ glade_project_window_on_edit_options, 0, "<StockItem>", GTK_STOCK_PROPERTIES },
+ { "/File/_Quit", NULL,
+ glade_project_window_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
+
+ { "/_Edit", NULL,
+ 0, 0, "<Branch>" },
+
+ { "/_View", NULL,
+ 0, 0, "<Branch>" },
+
+ { "/_Help", NULL,
+ 0, 0, "<LastBranch>" },
+ { "/Help/_About", NULL,
+ glade_project_window_about, 0 },
+};
+
+static int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
+#endif
+
+static void
+add_stock_menu_item (GtkMenu *menu, gchar *stock_id, gchar *label,
+ GtkSignalFunc callback, GtkAccelGroup *accel_group,
+ GtkTooltips *tooltips, gchar *tip)
+{
+ GtkWidget *menuitem;
+
+ menuitem = gtk_image_menu_item_new_from_stock (stock_id, accel_group);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ if (label)
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child),
+ label);
+
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate", callback, NULL);
+
+ gtk_tooltips_set_tip (tooltips, menuitem, tip, NULL);
+ gtk_widget_show (menuitem);
+}
+
+
+GladeProjectWindow*
+glade_project_window_new (void)
+{
+ GtkTooltips *tooltips;
+
+ GtkWidget *menubar;
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+ GtkWidget *image;
+ GtkWidget *toolbar;
+ GdkColormap *colormap;
+ GtkAccelGroup *accel_group;
+ GtkWidget *scrolled_win;
+ GtkWidget *vbox_main;
+ GtkIconSize icon_size;
+ GtkToolbarChild *toolbar_child;
+ GList *elem;
+
+ project_window = g_new (GladeProjectWindow, 1);
+ project_window->current_directory = NULL;
+
+ project_window->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_name (project_window->window, "GladeProjectWindow");
+ gtk_window_set_title (GTK_WINDOW (project_window->window), "Glade");
+ gtk_window_set_wmclass (GTK_WINDOW (project_window->window),
+ "project", "Glade");
+
+ /* Save a pointer to the GladeProjectWindow, so we can find it in callbacks.
+ */
+ gtk_object_set_data (GTK_OBJECT (project_window->window),
+ GladeProjectWindowKey, project_window);
+
+ gtk_window_move (GTK_WINDOW (project_window->window), 0, 0);
+
+ gtk_signal_connect (GTK_OBJECT (project_window->window), "destroy",
+ GTK_SIGNAL_FUNC (glade_project_window_destroy), NULL);
+ gtk_signal_connect (GTK_OBJECT (project_window->window), "delete_event",
+ GTK_SIGNAL_FUNC (glade_project_window_delete_event),
+ project_window);
+ gtk_signal_connect_after (GTK_OBJECT (project_window->window),
+ "key_press_event",
+ GTK_SIGNAL_FUNC (glade_project_window_key_press_event),
+ NULL);
+
+ tooltips = gtk_tooltips_new ();
+
+ vbox_main = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (project_window->window), vbox_main);
+ gtk_widget_show (vbox_main);
+
+ /* Create accelerator table */
+ accel_group = glade_get_global_accel_group ();
+ gtk_window_add_accel_group (GTK_WINDOW (project_window->window),
+ accel_group);
+
+#if 0
+ /* Create the menubar items, using the factory. */
+ item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
+ accel_group);
+ gtk_object_set_data_full (GTK_OBJECT (project_window->window), "<main>",
+ item_factory, (GtkDestroyNotify) gtk_object_unref);
+ gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_main),
+ gtk_item_factory_get_widget (item_factory, "<main>"),
+ FALSE, FALSE, 0);
+ gtk_widget_show_all (vbox_main);
+#endif
+
+ /* create menu bar */
+ menubar = gtk_menu_bar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox_main), menubar, FALSE, TRUE, 0);
+ gtk_widget_show (menubar);
+
+ /* create File menu */
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Project"));
+ gtk_container_add (GTK_CONTAINER (menubar), menuitem);
+ gtk_widget_show (menuitem);
+
+ menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_NEW, _("_New"),
+ GTK_SIGNAL_FUNC (glade_project_window_new_project),
+ accel_group, tooltips, _("Create a new project"));
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_OPEN, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_on_open_project),
+ accel_group, tooltips, _("Open an existing project"));
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_SAVE, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_save_project),
+ accel_group, tooltips, _("Save project"));
+
+ /*
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_SAVE_AS, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_save_project_as),
+ accel_group, tooltips, _("Save project to a new file"));
+ */
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Build"));
+ image = gtk_image_new_from_stock (GTK_STOCK_CONVERT, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
+ gtk_widget_show (image);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_write_source),
+ NULL);
+ gtk_widget_add_accelerator (menuitem, "activate", accel_group,
+ 'B', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Output the project source code"), NULL);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_image_menu_item_new_with_mnemonic (_("Op_tions..."));
+ image = gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
+ gtk_widget_show (image);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_on_edit_options),
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem, _("Edit the project options"),
+ NULL);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_QUIT, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_quit),
+ accel_group, tooltips, _("Quit Glade"));
+
+
+ /* Create Edit menu */
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Edit"));
+ gtk_container_add (GTK_CONTAINER (menubar), menuitem);
+ gtk_widget_show (menuitem);
+
+ menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_CUT, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_cut),
+ accel_group, tooltips,
+ _("Cut the selected widget to the clipboard"));
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_COPY, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_copy),
+ accel_group, tooltips,
+ _("Copy the selected widget to the clipboard"));
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_PASTE, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_paste),
+ accel_group, tooltips,
+ _("Paste the widget from the clipboard over the selected widget"));
+
+ add_stock_menu_item (GTK_MENU (menu), GTK_STOCK_DELETE, NULL,
+ GTK_SIGNAL_FUNC (glade_project_window_delete),
+ accel_group, tooltips,
+ _("Delete the selected widget"));
+
+
+ /* Create View menu */
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_View"));
+ gtk_container_add (GTK_CONTAINER (menubar), menuitem);
+ gtk_widget_show (menuitem);
+
+ menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show _Palette"));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_palette),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem, _("Show the palette of widgets"),
+ NULL);
+ palette_item = menuitem;
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show Property _Editor"));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_property_editor),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Show the property editor"), NULL);
+ property_editor_item = menuitem;
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show Widget _Tree"));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_widget_tree),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Show the widget tree"), NULL);
+ widget_tree_item = menuitem;
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show _Clipboard"));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_clipboard),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Show the clipboard"), NULL);
+ clipboard_item = menuitem;
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show _Widget Tooltips"));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ gb_widget_get_show_tooltips ());
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_tooltips),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Show the tooltips of created widgets"), NULL);
+ gtk_widget_show (menuitem);
+
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Grid"));
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ /* Create Grid submenu */
+ menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("_Show Grid"));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ editor_get_show_grid ());
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_grid),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Show the grid (in fixed containers only)"), NULL);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("Set Grid _Options..."));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_edit_grid_settings),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Set the spacing between grid lines"), NULL);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("S_nap to Grid"));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ editor_get_snap_to_grid ());
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_toggle_snap),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Snap widgets to the grid (in fixed containers only)"),
+ NULL);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("Set Snap O_ptions..."));
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_edit_snap_settings),
+ NULL);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_tooltips_set_tip (tooltips, menuitem,
+ _("Set which parts of a widget snap to the grid"), NULL);
+ gtk_widget_show (menuitem);
+
+ /* Create Help menu */
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Help"));
+ gtk_container_add (GTK_CONTAINER (menubar), menuitem);
+ gtk_widget_show (menuitem);
+
+ menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+
+ /* Don't show these yet as we have no help pages.
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Contents"));
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Index"));
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+ */
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_About..."));
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (glade_project_window_about),
+ NULL);
+ gtk_widget_show (menuitem);
+
+ /* Create toolbar */
+ toolbar = gtk_toolbar_new ();
+ /*gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_HALF);*/
+ gtk_box_pack_start (GTK_BOX (vbox_main), toolbar, FALSE, TRUE, 0);
+ gtk_widget_show (toolbar);
+
+ colormap = gtk_widget_get_colormap (toolbar);
+
+ /* I've taken this out to try to make the window smaller. */
+#if 0
+ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_NEW,
+ _("New Project"), "",
+ GTK_SIGNAL_FUNC (glade_project_window_new_project),
+ NULL, -1);
+#endif
+ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_OPEN,
+ _("Open Project"), "",
+ GTK_SIGNAL_FUNC (glade_project_window_on_open_project),
+ NULL, -1);
+ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_SAVE,
+ _("Save Project"), "",
+ GTK_SIGNAL_FUNC (glade_project_window_save_project),
+ NULL, -1);
+ gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+
+ icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar));
+ image = gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, icon_size);
+ gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "",
+ _("Project Options"), "", image,
+ GTK_SIGNAL_FUNC (glade_project_window_on_edit_options),
+ NULL);
+ elem = g_list_last (GTK_TOOLBAR (toolbar)->children);
+ toolbar_child = elem->data;
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (toolbar_child->label),
+ _("Optio_ns"));
+
+ image = gtk_image_new_from_stock (GTK_STOCK_CONVERT, icon_size);
+ gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "",
+ _("Write Source Code"), "", image,
+ GTK_SIGNAL_FUNC (glade_project_window_write_source),
+ NULL);
+ elem = g_list_last (GTK_TOOLBAR (toolbar)->children);
+ toolbar_child = elem->data;
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (toolbar_child->label),
+ _("_Build"));
+
+ /* Create list of components */
+ project_window->project_view = glade_project_view_new ();
+ gtk_widget_show (project_window->project_view);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win),
+ project_window->project_view);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show(scrolled_win);
+ gtk_box_pack_start (GTK_BOX (vbox_main), scrolled_win, TRUE, TRUE, 0);
+
+ /* Create status bar. */
+ project_window->statusbar = gtk_statusbar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox_main), project_window->statusbar,
+ FALSE, FALSE, 0);
+ gtk_widget_show (project_window->statusbar);
+
+ return project_window;
+}
+#endif
+
+
+/* This returns the GladeProjectWindow given any widget in the window,
+ e.g. a menuitem or a toolbar item, or NULL if not found. */
+static GladeProjectWindow*
+get_glade_project_window (GtkWidget *widget)
+{
+ /* We just use a global now. */
+ return project_window;
+
+#if 0
+ return (gtk_object_get_data (GTK_OBJECT (glade_util_get_toplevel (widget)),
+ GladeProjectWindowKey));
+#endif
+}
+
+
+static gboolean
+glade_project_window_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ GladeProjectWindow *project_window)
+{
+ glade_project_window_show_quit_dialog (project_window);
+ return TRUE;
+}
+
+
+static void
+glade_project_window_destroy (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ gtk_widget_destroy (project_window->window);
+ g_free (project_window->current_directory);
+ g_free (project_window);
+
+ gtk_exit (0);
+}
+
+
+static void
+glade_project_window_new_project (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+ GtkWidget *dialog, *label;
+ gint response;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ /* If we don't currently have a project, there's no point in prompting for
+ confirmation. */
+ if (current_project == NULL)
+ {
+ glade_project_window_on_new_project_ok (project_window);
+ return;
+ }
+
+ dialog = gtk_dialog_new_with_buttons (_("Glade"),
+ GTK_WINDOW (project_window->window),
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ label = gtk_label_new (_("Are you sure you want to create a new project?"));
+ gtk_misc_set_padding (GTK_MISC (label), 20, 20);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label,
+ TRUE, TRUE, 0);
+ gtk_widget_show (label);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "new_project", "Glade");
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (response == GTK_RESPONSE_OK)
+ glade_project_window_on_new_project_ok (project_window);
+}
+
+
+/* This sets the palette sensitive if a project is open or insensitive if
+ not, and shows/hides the GNOME widgets as appropriate. */
+static void
+glade_project_window_setup_interface (GladeProjectWindow *project_window)
+{
+ gboolean gnome_support = TRUE;
+ gboolean gnome_db_support = TRUE;
+
+ /* Make sure the arrow is selected in the palette. */
+ glade_palette_reset_selection (GLADE_PALETTE (glade_palette), FALSE);
+
+ if (current_project)
+ {
+ gnome_support = glade_project_get_gnome_support (current_project);
+ gnome_db_support = glade_project_get_gnome_db_support (current_project);
+ }
+
+ glade_palette_set_show_gnome_widgets (GLADE_PALETTE (glade_palette),
+ gnome_support, gnome_db_support);
+
+ gtk_widget_set_sensitive (GTK_BIN (glade_palette)->child,
+ current_project ? TRUE : FALSE);
+}
+
+
+static void
+glade_project_window_on_new_project_ok (GladeProjectWindow *project_window)
+{
+ GladeProject *project;
+
+ /* In the GNOME version we need to ask the user to specify whether they
+ want a GTK+ or GNOME project. The menu stock systems are different. */
+#ifdef USE_GNOME
+#define RESPONSE_GNOME 1
+#define RESPONSE_GTK 2
+
+ GtkWidget *dialog, *label;
+ gint response;
+
+ dialog = gtk_dialog_new_with_buttons (_("New Project"),
+ GTK_WINDOW (project_window->window),
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ _("New _GTK+ Project"), RESPONSE_GTK,
+ _("New G_NOME Project"), RESPONSE_GNOME,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_GNOME);
+ label = gtk_label_new (_("Which type of project do you want to create?"));
+ gtk_misc_set_padding (GTK_MISC (label), 20, 20);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label,
+ TRUE, TRUE, 0);
+ gtk_widget_show (label);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "new_project_type", "Glade");
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+
+ if (response == GTK_RESPONSE_CANCEL)
+ return;
+
+ project = glade_project_new ();
+
+ /* In the GNOME version, gnome_support defaults to TRUE, so we turn it off
+ if the user requested a GTK+ project. */
+ if (response == RESPONSE_GTK)
+ glade_project_set_gnome_support (project, FALSE);
+
+#else
+
+ project = glade_project_new ();
+
+#endif
+
+ glade_project_view_set_project (GLADE_PROJECT_VIEW (project_window->project_view), project);
+ glade_project_window_update_title (project_window);
+
+ gtk_statusbar_pop (GTK_STATUSBAR (project_window->statusbar), 1);
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("New project created."));
+
+ /* Make sure the palette is sensitive now and shows the appropriate
+ widgets. */
+ glade_project_window_setup_interface (project_window);
+}
+
+
+static void
+glade_project_window_on_open_project (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+ GtkWidget *filesel;
+ GtkFileFilter *filter;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ filesel = gtk_file_chooser_dialog_new (_("Open Project"),
+ GTK_WINDOW (project_window->window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
+
+ g_signal_connect (filesel, "response",
+ GTK_SIGNAL_FUNC (glade_project_window_real_open_project),
+ project_window);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "Glade Files");
+ gtk_file_filter_add_pattern (filter, "*.glade");
+ gtk_file_filter_add_pattern (filter, "*.glade2");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "All Files");
+ gtk_file_filter_add_pattern (filter, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+
+ if (project_window->current_directory)
+ glade_util_set_file_selection_filename (filesel, project_window->current_directory);
+
+ gtk_widget_show (filesel);
+}
+
+
+static void
+glade_project_window_real_open_project (GtkWidget *filesel,
+ gint response_id,
+ GladeProjectWindow *project_window)
+{
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ gchar *filename = glade_util_get_file_selection_filename (filesel);
+ if (filename)
+ glade_project_window_open_project (project_window, filename);
+ g_free (filename);
+ }
+ gtk_widget_destroy (filesel);
+}
+
+
+void
+glade_project_window_open_project (GladeProjectWindow *project_window,
+ const gchar *filename)
+{
+ GladeProject *project;
+ gboolean status;
+
+ /* Clear the project view. Otherwise we may show an invalid project for
+ a while. */
+ glade_project_view_set_project (GLADE_PROJECT_VIEW (project_window->project_view), NULL);
+
+ if (filename)
+ {
+ g_free (project_window->current_directory);
+ project_window->current_directory = glade_util_dirname (filename);
+ }
+
+ status = glade_project_open (filename, &project);
+
+ gtk_statusbar_pop (GTK_STATUSBAR (project_window->statusbar), 1);
+ if (status)
+ {
+ glade_project_view_set_project (GLADE_PROJECT_VIEW (project_window->project_view), project);
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("Project opened."));
+ }
+ else
+ {
+ /* For GNOME we set the current project to NULL - we can't create a new
+ project without asking if it is for GNOMR or GTK+. For GTK+ we can
+ create a new empty GTK+ project. */
+#ifdef USE_GNOME
+ project = NULL;
+#else
+ project = glade_project_new ();
+#endif
+ glade_project_view_set_project (GLADE_PROJECT_VIEW (project_window->project_view), project);
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("Error opening project."));
+ }
+
+ /* Make sure the palette is sensitive if needed and show the appropriate
+ widgets. */
+ glade_project_window_setup_interface (project_window);
+
+ glade_project_window_update_title (project_window);
+}
+
+
+static void
+glade_project_window_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint time, gpointer data)
+{
+ GladeProjectWindow *project_window;
+ gchar *uri_list;
+ GList *list = NULL;
+
+ if (info != TARGET_URI_LIST)
+ return;
+
+ /*
+ * Mmh... it looks like on Windows selection_data->data is not
+ * NULL terminated, so we need to make sure our local copy is.
+ */
+ uri_list = g_new (gchar, selection_data->length + 1);
+ memcpy (uri_list, selection_data->data, selection_data->length);
+ uri_list[selection_data->length] = 0;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ /* For now, if more than a file is dragged into glade we actually
+ * only try the first one... we can open only one anyway.
+ */
+ list = glade_util_uri_list_parse (uri_list);
+ if (list->data)
+ glade_project_window_open_project (project_window, list->data);
+
+ /* we can now free each string in the list */
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+}
+
+
+/* This shows the errors in a dialog, and frees them. */
+/* Currently unused, since we switched to using libxml. */
+#if 0
+static void
+glade_project_window_show_loading_errors (GladeProjectWindow *project_window,
+ GList *errors)
+{
+ GtkWidget *dialog, *text;
+ GtkTextBuffer *buffer;
+ GList *element;
+ gchar *message, buf[16];
+
+ dialog = glade_project_window_new_errors_dialog (project_window, &text);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Errors opening project file"));
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "error", "Glade");
+
+ sprintf (buf, "\n%i", g_list_length (errors));
+ gtk_text_buffer_insert_at_cursor (buffer, buf, -1);
+
+ message = _(" errors opening project file:");
+ gtk_text_buffer_insert_at_cursor (buffer, message, -1);
+ gtk_text_buffer_insert_at_cursor (buffer, "\n\n", 2);
+
+ element = errors;
+ while (element)
+ {
+ message = (gchar*) element->data;
+ gtk_text_buffer_insert_at_cursor (buffer, message, -1);
+ g_free (message);
+ element = element->next;
+ }
+ g_list_free (errors);
+
+ gtk_widget_show (dialog);
+}
+#endif
+
+
+static GtkWidget*
+glade_project_window_new_errors_dialog (GladeProjectWindow *project_window,
+ GtkWidget **text_return)
+{
+ GtkWidget *dialog, *vbox, *text, *hbbox, *ok_button, *scrolled_win;
+
+ dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 2);
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_widget_show (vbox);
+ gtk_container_add (GTK_CONTAINER (dialog), vbox);
+
+ text = gtk_text_view_new ();
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
+ gtk_widget_show (text);
+ gtk_widget_set_usize (text, 400, 150);
+ GTK_WIDGET_UNSET_FLAGS (text, GTK_CAN_FOCUS);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), text);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
+ gtk_widget_show(scrolled_win);
+
+ hbbox = gtk_hbutton_box_new ();
+ gtk_widget_show (hbbox);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbbox), GTK_BUTTONBOX_END);
+ gtk_box_pack_start (GTK_BOX (vbox), hbbox, FALSE, TRUE, 0);
+
+ ok_button = gtk_button_new_with_label (_("OK"));
+ gtk_widget_show (ok_button);
+ GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
+ gtk_container_add (GTK_CONTAINER (hbbox), ok_button);
+ gtk_widget_grab_default (ok_button);
+ gtk_signal_connect_object (GTK_OBJECT (ok_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (dialog));
+ gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscDestroys));
+
+ *text_return = text;
+ return dialog;
+}
+
+
+/* This shows a warning dialog when the user tries to use a command like
+ Save/Options/Build when we currently have no project. */
+static void
+glade_project_window_show_no_project_warning (GladeProjectWindow *project_window)
+{
+ glade_util_show_message_box (_("There is no project currently open.\n"
+ "Create a new project with the Project/New command."),
+ project_window->window);
+}
+
+
+static void
+glade_project_window_on_edit_options (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ glade_project_window_edit_options (project_window,
+ GLADE_PROJECT_OPTIONS_ACTION_NORMAL);
+}
+
+
+/* The action specifies what to do when 'OK' is clicked. It can be NULL, to
+ simply update the options, or 'Save' or 'Build' to save the XML file, or
+ build the source code. */
+static void
+glade_project_window_edit_options (GladeProjectWindow *project_window,
+ GladeProjectOptionsAction action)
+{
+ GladeProject *project;
+ GtkWidget *options;
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (project)
+ {
+ options = glade_project_options_new (project);
+ gtk_signal_connect (GTK_OBJECT (GLADE_PROJECT_OPTIONS (options)->ok_button),
+ "clicked",
+ GTK_SIGNAL_FUNC (glade_project_window_options_ok),
+ project_window);
+ if (action)
+ glade_project_options_set_action (GLADE_PROJECT_OPTIONS (options),
+ action);
+ if (GTK_IS_WINDOW (project_window->window))
+ gtk_window_set_transient_for (GTK_WINDOW (options),
+ GTK_WINDOW (project_window->window));
+
+ gtk_widget_show (options);
+ }
+ else
+ {
+ glade_project_window_show_no_project_warning (project_window);
+ }
+}
+
+
+static void
+glade_project_window_options_ok (GtkWidget *widget,
+ GladeProjectWindow *project_window)
+{
+ GladeProjectOptions *options;
+ GladeProjectOptionsAction action;
+ gboolean saved;
+
+ options = GLADE_PROJECT_OPTIONS (gtk_widget_get_toplevel (widget));
+ action = options->action;
+
+ glade_project_window_update_title (project_window);
+ glade_project_window_setup_interface (project_window);
+
+ gtk_widget_destroy (GTK_WIDGET (options));
+
+ switch (action)
+ {
+ case GLADE_PROJECT_OPTIONS_ACTION_NORMAL:
+ /* Don't need to do anything here. */
+ break;
+ case GLADE_PROJECT_OPTIONS_ACTION_SAVE:
+ glade_project_window_real_save_project (project_window, FALSE);
+ break;
+ case GLADE_PROJECT_OPTIONS_ACTION_BUILD:
+ saved = glade_project_window_real_save_project (project_window, FALSE);
+ if (saved)
+ glade_project_window_real_write_source (project_window);
+ break;
+ }
+}
+
+
+static void
+glade_project_window_save_project (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+ GladeProject *project;
+ gchar *xml_filename = NULL;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (project)
+ {
+ xml_filename = glade_project_get_xml_filename (project);
+
+ /* If the XML filename isn't set, show the project options dialog,
+ and tell it we are saving. */
+ if (xml_filename == NULL || xml_filename[0] == '\0')
+ glade_project_window_edit_options (project_window,
+ GLADE_PROJECT_OPTIONS_ACTION_SAVE);
+ else
+ glade_project_window_real_save_project (project_window, FALSE);
+ }
+ else
+ {
+ glade_project_window_show_no_project_warning (project_window);
+ }
+}
+
+
+#if 0
+static void
+glade_project_window_on_save_project_as (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ glade_project_window_save_project_as (project_window);
+}
+
+
+static void
+glade_project_window_save_project_as (GladeProjectWindow *project_window)
+{
+ GtkWidget *filesel;
+
+ filesel = gtk_file_chooser_dialog_new (_("Save Project"),
+ GTK_WINDOW (project_window->window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
+
+ g_signal_connect (options->filesel, "response",
+ GTK_SIGNAL_FUNC (glade_project_window_save_as_callback),
+ project_window);
+
+ if (project_window->current_directory)
+ glade_util_set_file_selection_filename (filesel, project_window->current_directory);
+
+ gtk_widget_show (filesel);
+}
+
+
+static void
+glade_project_window_save_as_callback (GtkWidget *filesel,
+ gint response_id,
+ GladeProjectWindow *project_window)
+{
+ GladeProject *project;
+ gchar *filename;
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ filename = glade_util_get_file_selection_filename (filesel);
+
+ g_free (project_window->current_directory);
+ project_window->current_directory = glade_util_dirname (filename);
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (project)
+ {
+ glade_project_set_xml_filename (project, filename);
+ glade_project_window_real_save_project (project_window, TRUE);
+ }
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (filesel);
+}
+#endif
+
+
+/* Returns TRUE if the XML file is saved OK.
+ FIXME: Doesn't use warn_before_overwrite. */
+static gboolean
+glade_project_window_real_save_project (GladeProjectWindow *project_window,
+ gboolean warn_before_overwrite)
+{
+ GladeProject *project;
+ GladeError *error;
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ g_return_val_if_fail (project != NULL, GLADE_STATUS_ERROR);
+
+ error = glade_project_save (project);
+
+ gtk_statusbar_pop (GTK_STATUSBAR (project_window->statusbar), 1);
+ if (error)
+ {
+ glade_project_window_show_error (project_window, error,
+ _("Error saving project"));
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("Error saving project."));
+ glade_error_free (error);
+ return FALSE;
+ }
+ else
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("Project saved."));
+ return TRUE;
+}
+
+
+static void
+glade_project_window_write_source (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+ GladeProject *project;
+ gchar *directory, *xml_filename, *project_name, *program_name;
+ gchar *source_directory, *pixmaps_directory;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (!project)
+ {
+ glade_project_window_show_no_project_warning (project_window);
+ return;
+ }
+
+ /* First we need to make sure we have an XML file, a project name, and a
+ program name. */
+ directory = glade_project_get_directory (project);
+ xml_filename = glade_project_get_xml_filename (project);
+ project_name = glade_project_get_name (project);
+ program_name = glade_project_get_program_name (project);
+ source_directory = glade_project_get_source_directory (project);
+ pixmaps_directory = glade_project_get_pixmaps_directory (project);
+
+ /* First check we have all the options we need. If not show the project
+ options dialog, and tell it we are building the source. */
+ if (directory == NULL || directory[0] == '\0'
+ || xml_filename == NULL || xml_filename[0] == '\0'
+ || project_name == NULL || project_name[0] == '\0'
+ || program_name == NULL || program_name[0] == '\0'
+ || source_directory == NULL || source_directory[0] == '\0'
+ || pixmaps_directory == NULL || pixmaps_directory[0] == '\0')
+ {
+ glade_project_window_edit_options (project_window,
+ GLADE_PROJECT_OPTIONS_ACTION_BUILD);
+ return;
+ }
+
+ /* If there is an error saving the XML file we simply return. The user
+ will already have been informed of the error. */
+ if (!glade_project_window_real_save_project (project_window, FALSE))
+ return;
+ glade_project_window_real_write_source (project_window);
+}
+
+
+static void
+glade_project_window_real_write_source (GladeProjectWindow *project_window)
+{
+ GladeProject *project;
+ GladeError *error;
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ g_return_if_fail (project != NULL);
+
+ error = glade_project_write_source (project);
+
+ gtk_statusbar_pop (GTK_STATUSBAR (project_window->statusbar), 1);
+ if (error)
+ {
+ glade_project_window_show_error (project_window, error,
+ _("Errors writing source code"));
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("Error writing source."));
+ glade_error_free (error);
+ return;
+ }
+
+ gtk_statusbar_push (GTK_STATUSBAR (project_window->statusbar), 1,
+ _("Source code written."));
+}
+
+
+/* This shows a single GladeError in a dialog. */
+static void
+glade_project_window_show_error (GladeProjectWindow *project_window,
+ GladeError *error,
+ gchar *title)
+{
+ GtkWidget *dialog, *text;
+ GtkTextBuffer *buffer;
+ gchar *message;
+
+ dialog = glade_project_window_new_errors_dialog (project_window, &text);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ gtk_window_set_title (GTK_WINDOW (dialog), title);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "error", "Glade");
+ if (GTK_IS_WINDOW (project_window->window))
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ GTK_WINDOW (project_window->window));
+
+ gtk_text_buffer_insert_at_cursor (buffer, error->message, -1);
+
+ /* For system errors, we also output the system error message. */
+ if (error->status == GLADE_STATUS_SYSTEM_ERROR)
+ {
+ /* Insert a blank line between our message and the system message. */
+ gtk_text_buffer_insert_at_cursor (buffer, "\n", 1);
+
+ message = _("System error message:");
+ gtk_text_buffer_insert_at_cursor (buffer, message, -1);
+
+ /* Place the system error message on the next line, indented slightly. */
+ gtk_text_buffer_insert_at_cursor (buffer, "\n ", -1);
+
+ message = (char*) g_strerror (error->system_errno);
+ gtk_text_buffer_insert_at_cursor (buffer, message, -1);
+ }
+
+ gtk_widget_show (dialog);
+}
+
+
+static void
+glade_project_window_quit (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ glade_project_window_show_quit_dialog (project_window);
+}
+
+
+static void
+glade_project_window_show_quit_dialog (GladeProjectWindow *project_window)
+{
+ GtkWidget *dialog, *label;
+
+ dialog = gtk_dialog_new_with_buttons (_("Glade"),
+ GTK_WINDOW (project_window->window),
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_QUIT, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ label = gtk_label_new (_("Are you sure you want to quit?"));
+ gtk_misc_set_padding (GTK_MISC (label), 20, 20);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label,
+ TRUE, TRUE, 0);
+ gtk_widget_show (label);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "quit", "Glade");
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+ {
+ glade_save_settings (project_window, glade_palette, win_property,
+ win_tree, glade_clipboard);
+ gtk_widget_destroy (project_window->window);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+
+static void
+glade_project_window_cut (GtkWidget *widget,
+ gpointer user_data)
+{
+ GladeProjectWindow *project_window;
+ GladeProject *project;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (project == NULL)
+ return;
+
+ glade_clipboard_cut (GLADE_CLIPBOARD (glade_clipboard), project, NULL);
+}
+
+
+static void
+glade_project_window_copy (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+ GladeProject *project;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (project == NULL)
+ return;
+
+ glade_clipboard_copy (GLADE_CLIPBOARD (glade_clipboard), project, NULL);
+}
+
+
+static void
+glade_project_window_paste (GtkWidget *widget,
+ gpointer user_data)
+{
+ GladeProjectWindow *project_window;
+ GladeProject *project;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+ if (project == NULL)
+ return;
+
+ glade_clipboard_paste (GLADE_CLIPBOARD (glade_clipboard), project, NULL);
+}
+
+
+static void
+glade_project_window_delete (GtkWidget *widget,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+
+ project_window = get_glade_project_window (widget);
+ g_return_if_fail (project_window != NULL);
+
+ glade_project_window_real_delete (project_window);
+}
+
+
+/* If one or more items in the project view is selected, we delete them.
+ If not, we delete any widgets selected in the interface.
+ FIXME: I'm not sure of the correct way to handle the Delete key. Should we
+ be using X selections to determine what is currently selected? */
+static void
+glade_project_window_real_delete (GladeProjectWindow *project_window)
+{
+ if (glade_project_view_has_selection (GLADE_PROJECT_VIEW (project_window->project_view)))
+ glade_project_view_delete_selection (GLADE_PROJECT_VIEW (project_window->project_view));
+ else
+ editor_on_delete ();
+}
+
+
+static void
+refresh_menu_item (GtkWidget *menuitem, GtkWidget *window)
+{
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ GTK_WIDGET_VISIBLE (window));
+}
+
+void
+glade_project_window_refresh_menu_items (void)
+{
+ refresh_menu_item (palette_item, glade_palette);
+ refresh_menu_item (property_editor_item, win_property);
+ refresh_menu_item (widget_tree_item, win_tree);
+ refresh_menu_item (clipboard_item, glade_clipboard);
+}
+
+
+void
+glade_project_window_uncheck_palette_menu_item (void)
+{
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (palette_item),
+ FALSE);
+}
+
+
+void
+glade_project_window_uncheck_property_editor_menu_item (void)
+{
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (property_editor_item),
+ FALSE);
+}
+
+
+void
+glade_project_window_uncheck_widget_tree_menu_item (void)
+{
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget_tree_item),
+ FALSE);
+}
+
+
+void
+glade_project_window_uncheck_clipboard_menu_item (void)
+{
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (clipboard_item),
+ FALSE);
+}
+
+
+static void
+glade_project_window_toggle_palette (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean show_palette;
+
+ show_palette = GTK_CHECK_MENU_ITEM (widget)->active;
+ if (show_palette)
+ glade_show_palette ();
+ else
+ glade_hide_palette ();
+}
+
+
+static void
+glade_project_window_toggle_property_editor (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean show_property_editor;
+
+ show_property_editor = GTK_CHECK_MENU_ITEM (widget)->active;
+ if (show_property_editor)
+ glade_show_property_editor ();
+ else
+ glade_hide_property_editor ();
+}
+
+
+static void
+glade_project_window_toggle_widget_tree (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean show_widget_tree;
+
+ show_widget_tree = GTK_CHECK_MENU_ITEM (widget)->active;
+ if (show_widget_tree)
+ glade_show_widget_tree ();
+ else
+ glade_hide_widget_tree ();
+}
+
+
+static void
+glade_project_window_toggle_clipboard (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean show_clipboard;
+
+ show_clipboard = GTK_CHECK_MENU_ITEM (widget)->active;
+ if (show_clipboard)
+ glade_show_clipboard ();
+ else
+ glade_hide_clipboard ();
+}
+
+
+static void
+glade_project_window_toggle_tooltips (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean show_tooltips;
+
+ show_tooltips = GTK_CHECK_MENU_ITEM (widget)->active;
+ gb_widget_set_show_tooltips (show_tooltips);
+}
+
+
+static void
+glade_project_window_toggle_grid (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean show_grid;
+
+ show_grid = GTK_CHECK_MENU_ITEM (widget)->active;
+ editor_set_show_grid (show_grid);
+}
+
+
+static void
+glade_project_window_edit_grid_settings (GtkWidget *widget,
+ gpointer data)
+{
+ editor_show_grid_settings_dialog (widget);
+}
+
+
+static void
+glade_project_window_toggle_snap (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean snap_to_grid;
+
+ snap_to_grid = GTK_CHECK_MENU_ITEM (widget)->active;
+ editor_set_snap_to_grid (snap_to_grid);
+}
+
+
+static void
+glade_project_window_edit_snap_settings (GtkWidget *widget,
+ gpointer data)
+{
+ editor_show_snap_settings_dialog (widget);
+}
+
+
+static void
+glade_project_window_about (GtkWidget *widget,
+ gpointer data)
+{
+ /* VERSION comes from configure.in - the only place it should be defined */
+
+#ifdef USE_GNOME
+ static GtkWidget *about = NULL;
+
+ if (about == NULL )
+ {
+ const gchar *author[] = { "Damon Chaplin <damon@gnome.org>",
+ "Martijn van Beers <martijn@earthling.net>",
+ "Jacob Berkman <jacob@ximian.com>",
+ NULL };
+ const gchar *documenter[] = { NULL };
+ GtkWidget *transient_parent;
+ GdkPixbuf *pixbuf = NULL;
+ char *filename;
+
+ filename = gnome_program_locate_file (gnome_program_get (),
+ GNOME_FILE_DOMAIN_APP_PIXMAP,
+ "glade-2.png", /* "glade-2/glade_logo.png", */
+ TRUE, NULL);
+ if (filename)
+ pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+
+ about = gnome_about_new (_("Glade"),
+ VERSION,
+ _("(C) 1998-2002 Damon Chaplin"),
+ _("Glade is a User Interface Builder for GTK+ and GNOME."),
+ author, documenter, NULL, pixbuf);
+ if (pixbuf)
+ gdk_pixbuf_unref (pixbuf);
+
+ /* set the widget pointer to NULL when the widget is destroyed */
+ g_signal_connect (G_OBJECT (about), "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &about);
+ gtk_window_set_wmclass (GTK_WINDOW (about), "about", "Glade");
+ transient_parent = glade_util_get_toplevel (widget);
+ if (GTK_IS_WINDOW (transient_parent))
+ gtk_window_set_transient_for (GTK_WINDOW (about),
+ GTK_WINDOW (transient_parent));
+
+ gtk_widget_show_all (GTK_WIDGET (about));
+ }
+ gtk_window_present (GTK_WINDOW (about));
+
+#else
+ static GtkWidget *about = NULL;
+
+ if (about == NULL )
+ {
+ GtkWidget *vbox, *image, *label;
+ GtkWindow *transient_parent;
+ char *filename, *text;
+
+ transient_parent = GTK_WINDOW (glade_util_get_toplevel (widget));
+ about = gtk_dialog_new_with_buttons (_("About Glade"),
+ transient_parent,
+ 0,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_window_set_resizable (GTK_WINDOW (about), FALSE);
+ g_signal_connect (G_OBJECT (about), "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ /* set the widget pointer to NULL when the widget is destroyed */
+ g_signal_connect (G_OBJECT (about), "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &about);
+ gtk_window_set_wmclass (GTK_WINDOW (about), "about", "Glade");
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about)->vbox),
+ vbox, TRUE, TRUE, 0);
+
+ filename = g_strdup_printf ("%s/pixmaps/glade-2.png", GLADE_DATADIR);
+ image = gtk_image_new_from_file (filename);
+ g_free (filename);
+ gtk_box_pack_start (GTK_BOX (vbox), image, TRUE, TRUE, 8);
+
+ text = g_strdup_printf ("<span size=\"xx-large\" weight=\"bold\">Glade "
+ VERSION "</span>\n\n"
+ "%s\n\n"
+ "<span size=\"small\">%s</span>",
+ _("Glade is a User Interface Builder for GTK+ and GNOME."),
+ _("(C) 1998-2002 Damon Chaplin"));
+
+ label = gtk_label_new (text);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+ gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+ gtk_widget_show_all (GTK_WIDGET (about));
+ }
+ gtk_window_present (GTK_WINDOW (about));
+#endif
+}
+
+
+static gint
+glade_project_window_key_press_event (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data)
+{
+ GladeProjectWindow *project_window;
+
+ project_window = get_glade_project_window (widget);
+ g_return_val_if_fail (project_window != NULL, FALSE);
+
+ switch (event->keyval)
+ {
+ case GDK_Delete:
+ glade_project_window_real_delete (project_window);
+ break;
+ }
+ return TRUE;
+}
+
+
+void
+glade_project_window_set_project (GladeProjectWindow *project_window,
+ GladeProject *project)
+{
+ glade_project_view_set_project (GLADE_PROJECT_VIEW (project_window->project_view),
+ project);
+ glade_project_window_update_title (project_window);
+}
+
+
+static void
+glade_project_window_update_title (GladeProjectWindow *project_window)
+{
+ GladeProject *project;
+ gchar *title, *project_name = NULL;
+
+ project = glade_project_view_get_project (GLADE_PROJECT_VIEW (project_window->project_view));
+
+ if (project)
+ project_name = glade_project_get_name (project);
+
+ if (!project_name || !project_name[0])
+ project_name = _("<untitled>");
+
+ title = g_strdup_printf ("Glade: %s", project_name);
+ gtk_window_set_title (GTK_WINDOW (project_window->window), title);
+ g_free (title);
+}
diff --git a/tools/glade/glade/glade_project_window.h b/tools/glade/glade/glade_project_window.h
new file mode 100644
index 00000000..41b06bfc
--- /dev/null
+++ b/tools/glade/glade/glade_project_window.h
@@ -0,0 +1,77 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_PROJECT_WINDOW_H
+#define GLADE_PROJECT_WINDOW_H
+
+#include "glade_project_view.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * GladeProjectWindow is the main project window, containing a mennubar,
+ * toolbar, statusbar and a GladeProjectView to show the project components.
+ * It is not a widget, it just creates a window. I did it this way because
+ * for Gnome we need to use a GnomeApp instead of a GtkWindow, and I didn't
+ * want to use conditional code to subsclass the different widgets.
+ */
+
+typedef struct _GladeProjectWindow GladeProjectWindow;
+
+struct _GladeProjectWindow
+{
+ /* The main GtkWindow/GnomeApp. */
+ GtkWidget *window;
+
+ /* The GladeProjectView, showing the components in the project. */
+ GtkWidget *project_view;
+
+ /* The statusbar, for status messages, e.g. 'Project Saved'. */
+ GtkWidget *statusbar;
+
+ /* The current directory, for opening projects. */
+ gchar *current_directory;
+};
+
+
+GladeProjectWindow* glade_project_window_new (void);
+
+void glade_project_window_open_project (GladeProjectWindow *project_window,
+ const gchar *filename);
+
+void glade_project_window_set_project (GladeProjectWindow *project_window,
+ GladeProject *project);
+
+
+void glade_project_window_refresh_menu_items (void);
+
+void glade_project_window_uncheck_palette_menu_item (void);
+
+void glade_project_window_uncheck_property_editor_menu_item (void);
+
+void glade_project_window_uncheck_widget_tree_menu_item (void);
+
+void glade_project_window_uncheck_clipboard_menu_item (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PROJECT_WINDOW_H */
diff --git a/tools/glade/glade/glade_widget_data.c b/tools/glade/glade/glade_widget_data.c
new file mode 100644
index 00000000..b201777f
--- /dev/null
+++ b/tools/glade/glade/glade_widget_data.c
@@ -0,0 +1,408 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-2000 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Defines the extra data that Glade keeps for each widget, and functions to
+ * manipulate it.
+ */
+
+#include "gladeconfig.h"
+
+#include "glade_widget_data.h"
+
+
+static GList* glade_widget_data_copy_signals (GList *signals);
+static GladeSignal* glade_widget_data_copy_signal (GladeSignal *signal);
+static GList* glade_widget_data_copy_accels (GList *accels);
+static GladeAccelerator* glade_widget_data_copy_accel(GladeAccelerator *accel);
+static GList* glade_widget_data_copy_relations (GList *relations);
+static GladeRelation* glade_widget_data_copy_relation (GladeRelation *relation);
+
+
+
+GladeWidgetData *
+glade_widget_data_new (GbWidget *gbwidget)
+{
+ GladeWidgetData *wdata;
+
+ g_return_val_if_fail (gbwidget != NULL, NULL);
+
+ wdata = g_new (GladeWidgetData, 1);
+
+ wdata->flags = GLADE_VISIBLE | GLADE_SENSITIVE | GLADE_STYLE_IS_UNNAMED
+ | GLADE_STYLE_PROPAGATE | GLADE_SIZE_NOT_ALLOCATED;
+ wdata->width = 0;
+ wdata->height = 0;
+ wdata->events = 0;
+ wdata->tooltip = NULL;
+ wdata->signals = NULL;
+ wdata->accelerators = NULL;
+ wdata->relations = NULL;
+#ifdef GLADE_STYLE_SUPPORT
+ wdata->gbstyle = gb_widget_default_gb_style;
+ gb_widget_ref_gb_style (gb_widget_default_gb_style);
+#endif
+
+ /* C options. */
+ wdata->source_file = NULL;
+ wdata->public_field = 1;
+
+ /* C++ options. */
+ wdata->cxx_separate_file = 0;
+ wdata->cxx_separate_class = 0;
+ wdata->cxx_visibility = 0;
+
+ wdata->gbwidget = gbwidget;
+
+ return wdata;
+}
+
+
+GladeWidgetData *
+glade_widget_data_copy (GladeWidgetData *wdata)
+{
+ GladeWidgetData *new_wdata = g_new (GladeWidgetData, 1);
+
+ new_wdata->flags = wdata->flags;
+ new_wdata->width = wdata->width;
+ new_wdata->height = wdata->height;
+ new_wdata->events = wdata->events;
+ new_wdata->tooltip = g_strdup (wdata->tooltip);
+
+ new_wdata->signals = glade_widget_data_copy_signals (wdata->signals);
+ new_wdata->accelerators = glade_widget_data_copy_accels (wdata->accelerators);
+ new_wdata->relations = glade_widget_data_copy_relations (wdata->relations);
+
+ /* C options. */
+ new_wdata->source_file = g_strdup (wdata->source_file);
+ new_wdata->public_field = wdata->public_field;
+
+ /* C++ options. */
+ new_wdata->cxx_separate_file = wdata->cxx_separate_file;
+ new_wdata->cxx_separate_class = wdata->cxx_separate_class;
+ new_wdata->cxx_visibility = wdata->cxx_visibility;
+
+ new_wdata->gbwidget = wdata->gbwidget;
+
+ return new_wdata;
+}
+
+
+static GList*
+glade_widget_data_copy_signals (GList *signals)
+{
+ GList *signals_copy = NULL, *elem;
+ GladeSignal *signal;
+
+ for (elem = signals; elem; elem = elem->next)
+ {
+ signal = (GladeSignal*) elem->data;
+ signals_copy = g_list_prepend (signals_copy,
+ glade_widget_data_copy_signal (signal));
+ }
+
+ return g_list_reverse (signals_copy);
+}
+
+
+static GladeSignal*
+glade_widget_data_copy_signal (GladeSignal *signal)
+{
+ GladeSignal *signal_copy;
+
+ signal_copy = g_new (GladeSignal, 1);
+
+ signal_copy->name = g_strdup (signal->name);
+ signal_copy->handler = g_strdup (signal->handler);
+ signal_copy->object = g_strdup (signal->object);
+ signal_copy->after = signal->after;
+ signal_copy->data = g_strdup (signal->data);
+ signal_copy->last_modification_time = signal->last_modification_time;
+
+ return signal_copy;
+}
+
+
+static GList*
+glade_widget_data_copy_accels (GList *accels)
+{
+ GList *accels_copy = NULL, *elem;
+ GladeAccelerator *accel;
+
+ for (elem = accels; elem; elem = elem->next)
+ {
+ accel = (GladeAccelerator*) elem->data;
+ accels_copy = g_list_prepend (accels_copy,
+ glade_widget_data_copy_accel (accel));
+ }
+
+ return g_list_reverse (accels_copy);
+}
+
+
+static GladeAccelerator*
+glade_widget_data_copy_accel (GladeAccelerator *accel)
+{
+ GladeAccelerator *accel_copy;
+
+ accel_copy = g_new (GladeAccelerator, 1);
+
+ accel_copy->modifiers = accel->modifiers;
+ accel_copy->key = g_strdup (accel->key);
+ accel_copy->signal = g_strdup (accel->signal);
+
+ return accel_copy;
+}
+
+
+static GList*
+glade_widget_data_copy_relations (GList *relations)
+{
+ GList *relations_copy = NULL, *elem;
+ GladeRelation *relation;
+
+ for (elem = relations; elem; elem = elem->next)
+ {
+ relation = (GladeRelation*) elem->data;
+ relations_copy = g_list_prepend (relations_copy,
+ glade_widget_data_copy_relation (relation));
+ }
+
+ return g_list_reverse (relations_copy);
+}
+
+
+static GladeRelation*
+glade_widget_data_copy_relation (GladeRelation *relation)
+{
+ GladeRelation *relation_copy;
+ GList *elem;
+
+ relation_copy = g_new (GladeRelation, 1);
+
+ relation_copy->relationship = relation->relationship;
+
+ relation_copy->targets = NULL;
+ for (elem = relation->targets; elem; elem = elem->next)
+ {
+ GtkWidget *target = elem->data;
+ relation_copy->targets = g_list_prepend (relation_copy->targets, target);
+ /* We add a weak pointer to the widget, so the element data will be
+ set to NULL if the widget is destroyed. */
+ g_object_add_weak_pointer (G_OBJECT (target),
+ &relation_copy->targets->data);
+ }
+ relation_copy->targets = g_list_reverse (relation_copy->targets);
+
+ return relation_copy;
+}
+
+
+void
+glade_widget_data_free (GladeWidgetData *wdata)
+{
+ g_free (wdata->tooltip);
+ g_free (wdata->source_file);
+
+ glade_widget_data_clear_accels (wdata);
+ glade_widget_data_clear_signals (wdata);
+ glade_widget_data_clear_relations (wdata);
+
+ g_free (wdata);
+}
+
+
+void
+glade_widget_data_clear_accels (GladeWidgetData *wdata)
+{
+ GList *item;
+ GladeAccelerator *accel;
+
+ item = wdata->accelerators;
+ while (item)
+ {
+ accel = (GladeAccelerator *) item->data;
+ glade_widget_data_free_accel (accel);
+ item = item->next;
+ }
+ g_list_free (wdata->accelerators);
+ wdata->accelerators = NULL;
+}
+
+
+void
+glade_widget_data_free_accel (GladeAccelerator *accel)
+{
+ g_free (accel->key);
+ g_free (accel->signal);
+}
+
+
+void
+glade_widget_data_set_accels (GladeWidgetData *wdata,
+ GList *accels)
+{
+ glade_widget_data_clear_accels (wdata);
+ wdata->accelerators = accels;
+}
+
+
+void
+glade_widget_data_clear_signals (GladeWidgetData *wdata)
+{
+ GList *item;
+ GladeSignal *signal;
+
+ item = wdata->signals;
+ while (item)
+ {
+ signal = (GladeSignal *) item->data;
+ glade_widget_data_free_signal (signal);
+ item = item->next;
+ }
+ g_list_free (wdata->signals);
+ wdata->signals = NULL;
+}
+
+
+void
+glade_widget_data_free_signal (GladeSignal *signal)
+{
+ g_free (signal->name);
+ g_free (signal->handler);
+ g_free (signal->object);
+ g_free (signal->data);
+}
+
+
+void
+glade_widget_data_set_signals (GladeWidgetData *wdata,
+ GList *signals)
+{
+ glade_widget_data_clear_signals (wdata);
+ wdata->signals = signals;
+}
+
+
+void
+glade_widget_data_clear_relations (GladeWidgetData *wdata)
+{
+ GList *item;
+ GladeRelation *relation;
+
+ item = wdata->relations;
+ while (item)
+ {
+ relation = (GladeRelation *) item->data;
+ glade_widget_data_free_relation (relation);
+ item = item->next;
+ }
+ g_list_free (wdata->relations);
+ wdata->relations = NULL;
+}
+
+
+void
+glade_widget_data_free_relation (GladeRelation *relation)
+{
+ GList *elem;
+
+ /* We need to remove the weak pointers. */
+ for (elem = relation->targets; elem; elem = elem->next)
+ g_object_remove_weak_pointer (G_OBJECT (elem->data), &elem->data);
+
+ g_list_free (relation->targets);
+}
+
+
+/* The relations should already have weak pointers added to the widgets. */
+void
+glade_widget_data_set_relations (GladeWidgetData *wdata,
+ GList *relations)
+{
+ glade_widget_data_clear_relations (wdata);
+ wdata->relations = relations;
+}
+
+
+/* This sets one relation type, used when the relation dialog is applied.
+ The targets should be weak pointers to the widgets. */
+void
+glade_widget_data_set_relation (GladeWidgetData *wdata,
+ AtkRelationType relationship,
+ GList *targets)
+{
+ GList *elem;
+ GladeRelation *relation;
+
+ /* If we already have a relation of this type then replace the targets,
+ else add a new relation. */
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ relation = (GladeRelation *) elem->data;
+
+ if (relation->relationship == relationship)
+ {
+ glade_widget_data_free_relation (relation);
+ relation->targets = targets;
+ return;
+ }
+ }
+
+ relation = g_new (GladeRelation, 1);
+ relation->relationship = relationship;
+ relation->targets = targets;
+
+ wdata->relations = g_list_prepend (wdata->relations, relation);
+}
+
+
+/* This adds one target widget to a relation, or creates a new relation if
+ it doesn't exist yet. It will use a weak pointer to the widget. */
+void
+glade_widget_data_add_relation (GladeWidgetData *wdata,
+ AtkRelationType relationship,
+ GtkWidget *target)
+{
+ GList *elem;
+ GladeRelation *relation;
+
+ /* If we already have a relation of this type then add the new target,
+ else add a new relation. */
+ for (elem = wdata->relations; elem; elem = elem->next)
+ {
+ relation = (GladeRelation *) elem->data;
+
+ if (relation->relationship == relationship)
+ {
+ relation->targets = g_list_prepend (relation->targets, target);
+ g_object_add_weak_pointer (G_OBJECT (target),
+ &relation->targets->data);
+ return;
+ }
+ }
+
+ relation = g_new (GladeRelation, 1);
+ relation->relationship = relationship;
+ relation->targets = g_list_append (NULL, target);
+ g_object_add_weak_pointer (G_OBJECT (target),
+ &relation->targets->data);
+
+ wdata->relations = g_list_prepend (wdata->relations, relation);
+}
+
diff --git a/tools/glade/glade/glade_widget_data.h b/tools/glade/glade/glade_widget_data.h
new file mode 100644
index 00000000..51210da7
--- /dev/null
+++ b/tools/glade/glade/glade_widget_data.h
@@ -0,0 +1,145 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-2000 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_WIDGET_DATA_H
+#define GLADE_WIDGET_DATA_H
+
+/*
+ * Defines the extra data that Glade keeps for each widget, and functions to
+ * manipulate it.
+ */
+
+#include <time.h>
+#include <atk/atkobject.h>
+#include <atk/atkrelation.h>
+#include "glade.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Flags in GladeWidgetData */
+enum
+{
+ GLADE_VISIBLE = 1 << 0, /* If the widget is initially visible */
+ GLADE_SENSITIVE = 1 << 1, /* If the widget is initially sensitive */
+ GLADE_GRAB_DEFAULT = 1 << 2, /* If it grabs the default */
+ GLADE_GRAB_FOCUS = 1 << 3, /* If it grabs the focus */
+ GLADE_STYLE_IS_UNNAMED = 1 << 4, /* If it's using its own unnamed style */
+ GLADE_STYLE_PROPAGATE = 1 << 5, /* If it propgates style to children */
+ GLADE_ACTIVE = 1 << 6, /* If it is initially active (toggles) */
+ GLADE_WIDTH_SET = 1 << 7, /* If the width is set explicitly */
+ GLADE_HEIGHT_SET = 1 << 8, /* If the height is set explicitly */
+
+ GLADE_SIZE_NOT_ALLOCATED = 1 << 9 /* Internally used so that a widget's size
+ and position properties aren't
+ displayed until its area has been
+ allocated. */
+};
+
+typedef struct _GladeWidgetData GladeWidgetData;
+struct _GladeWidgetData
+{
+ guint16 flags;
+ gint16 width;
+ gint16 height;
+ gint events;
+ gchar *tooltip;
+ GList *signals; /* A list of GladeSignal*. */
+ GList *accelerators; /* A list of GladeAccelerator*. */
+ GList *relations; /* A list of GladeRelation*. */
+#ifdef GLADE_STYLE_SUPPORT
+ GbStyle *gbstyle;
+#endif
+
+ /* C options (currently not used). */
+ gchar *source_file;
+ guint public_field : 1;
+
+ /* C++ options. */
+ guint cxx_separate_file : 1;
+ guint cxx_separate_class : 1;
+ guint cxx_visibility : 2; /* 0=private 1=protected 2=public */
+
+ GbWidget *gbwidget;
+};
+
+typedef struct _GladeSignal GladeSignal;
+struct _GladeSignal
+{
+ gchar *name;
+ gchar *handler;
+ gchar *object;
+ gboolean after;
+ gchar *data;
+ /* This records the last time that handler, object or data were changed,
+ since we have to change the prototype output when they change.
+ name can't be changed, or it would become a completely different signal */
+ time_t last_modification_time;
+};
+
+typedef struct _GladeAccelerator GladeAccelerator;
+struct _GladeAccelerator
+{
+ GdkModifierType modifiers;
+ gchar *key;
+ gchar *signal;
+};
+
+typedef struct _GladeRelation GladeRelation;
+struct _GladeRelation
+{
+ AtkRelationType relationship;
+ /* A list of GtkWidget*, with weak pointers to the widgets, so if the
+ widget gets destroyed the pointer is set to NULL. */
+ GList *targets;
+};
+
+
+GladeWidgetData* glade_widget_data_new (GbWidget *gbwidget);
+GladeWidgetData* glade_widget_data_copy (GladeWidgetData *wdata);
+
+void glade_widget_data_free (GladeWidgetData *wdata);
+
+void glade_widget_data_clear_accels (GladeWidgetData *wdata);
+void glade_widget_data_set_accels (GladeWidgetData *wdata,
+ GList *accels);
+void glade_widget_data_free_accel (GladeAccelerator *accel);
+
+void glade_widget_data_clear_signals (GladeWidgetData *wdata);
+void glade_widget_data_set_signals (GladeWidgetData *wdata,
+ GList *signals);
+void glade_widget_data_free_signal (GladeSignal *signal);
+
+void glade_widget_data_clear_relations(GladeWidgetData *wdata);
+void glade_widget_data_set_relations (GladeWidgetData *wdata,
+ GList *relations);
+void glade_widget_data_set_relation (GladeWidgetData *wdata,
+ AtkRelationType relationship,
+ GList *targets);
+void glade_widget_data_add_relation (GladeWidgetData *wdata,
+ AtkRelationType relationship,
+ GtkWidget *target);
+void glade_widget_data_free_relation (GladeRelation *relation);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_WIDGET_DATA_H */
diff --git a/tools/glade/glade/gladeconfig.h b/tools/glade/glade/gladeconfig.h
new file mode 100644
index 00000000..aad46f7a
--- /dev/null
+++ b/tools/glade/glade/gladeconfig.h
@@ -0,0 +1,64 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* This header should be included by all Glade sources. */
+
+#ifndef GLADE_CONFIG_H
+#define GLADE_CONFIG_H
+
+#include <config.h>
+
+#include "debug.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Internationalization. */
+#ifdef USE_GNOME
+#include <libgnome/gnome-i18n.h>
+#else
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#undef _
+#define _(String) dgettext (GETTEXT_PACKAGE, String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop (String)
+#else
+#define N_(String) (String)
+#endif /* gettext_noop */
+#else
+/* Stubs that do something close enough. */
+#define textdomain(String) (String)
+#define gettext(String) (String)
+#define dgettext(Domain,Message) (Message)
+#define dcgettext(Domain,Message,Type) (Message)
+#define bindtextdomain(Domain,Directory) (Domain)
+#define _(String) (String)
+#define N_(String) (String)
+#endif /* ENABLE_NLS */
+
+#endif /* USE_GNOME */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_CONFIG_H */
diff --git a/tools/glade/glade/gnome-db/Makefile.am b/tools/glade/glade/gnome-db/Makefile.am
new file mode 100644
index 00000000..e2547f54
--- /dev/null
+++ b/tools/glade/glade/gnome-db/Makefile.am
@@ -0,0 +1,23 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libgnomedbwidgets.a
+
+INCLUDES = $(GLADE_CFLAGS) \
+ $(GLADE_DEPRECATION_CFLAGS)
+
+libgnomedbwidgets_a_SOURCES = \
+ gnomedbcombo.c \
+ gnomedbconnectprop.c \
+ gnomedbdsnconfig.c \
+ gnomedbdsndruid.c \
+ gnomedbeditor.c \
+ gnomedberror.c \
+ gnomedberrordlg.c \
+ gnomedbform.c \
+ gnomedbgraybar.c \
+ gnomedbgrid.c \
+ gnomedblogin.c \
+ gnomedblogindlg.c \
+ gnomedbprovidersel.c \
+ gnomedbsourcesel.c \
+ gnomedbtableeditor.c
diff --git a/tools/glade/glade/gnome-db/gnomedbcombo.c b/tools/glade/glade/gnome-db/gnomedbcombo.c
new file mode 100644
index 00000000..c06cb38c
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbcombo.c
@@ -0,0 +1,136 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <libgnomedb/gnome-db-combo.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-combo.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbCombo, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_combo_new (GbWidgetNewData *data)
+{
+ return gnome_db_combo_new ();
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_combo_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_combo_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_combo_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbCombo, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_combo_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_combo_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_combo_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_combo_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_combo_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_combo_xpm;
+ gbwidget.tooltip = _("Data-bound combo");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_combo_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_combo_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_combo_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_combo_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_db_combo_write_source;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_combo_create_popup_menu;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbconnectprop.c b/tools/glade/glade/gnome-db/gnomedbconnectprop.c
new file mode 100644
index 00000000..4f9bfe0f
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbconnectprop.c
@@ -0,0 +1,93 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <libgnomedb/gnome-db-connection-properties.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-connection-properties.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbEditor, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+
+GtkWidget*
+gb_gnome_db_connection_properties_new(GbWidgetNewData *data)
+{
+ return (GtkWidget *) gnome_db_connection_properties_new(NULL);
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_connection_properties_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_connection_properties_new (NULL);\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+}
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_gnome_db_connection_properties_init ()
+{
+ /* Initialise the GTK type */
+ volatile GType type;
+ type = gnome_db_connection_properties_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_connection_properties_xpm;
+ gbwidget.tooltip = _("GnomeDbConnectionProperties");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_connection_properties_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_connection_properties_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gnome-db/gnomedbdsnconfig.c b/tools/glade/glade/gnome-db/gnomedbdsnconfig.c
new file mode 100644
index 00000000..be57bc6b
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbdsnconfig.c
@@ -0,0 +1,147 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 2001 Carlos Perelló Marín <carlos@gnome-db.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <libgnomedb/gnome-db-dsn-config.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-dsnconfig.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbDsnConfig, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_dsnconfig_new (GbWidgetNewData *data)
+{
+ return gnome_db_dsn_config_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_dsnconfig_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_dsnconfig_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_dsnconfig_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbBrowser, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_dsnconfig_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_dsnconfig_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_dsn_config_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_dsnconfig_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_dsn_config_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_dsnconfig_xpm;
+ gbwidget.tooltip = _("DSN Configurator");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_dsnconfig_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_dsnconfig_write_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_dsnconfig_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_dsnconfig_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_dsnconfig_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_dsnconfig_create_popup_menu;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gnome-db/gnomedbdsndruid.c b/tools/glade/glade/gnome-db/gnomedbdsndruid.c
new file mode 100644
index 00000000..e0661cc6
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbdsndruid.c
@@ -0,0 +1,161 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <libgnomedb/gnome-db-dsn-config-druid.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-dsn-druid.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbDsnConfigDruid, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_gnome_db_dsn_config_druid_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+static void
+gb_gnome_db_dsn_config_druid_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+static void
+gb_gnome_db_dsn_config_druid_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+static void
+gb_gnome_db_dsn_config_druid_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbDsnConfigDruid, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_db_dsn_config_druid_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_dsn_config_druid_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_dsn_config_druid_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_dsn_config_druid_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_dsn_config_druid_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_dsn_druid_xpm;
+ gbwidget.tooltip = _("DSN Config Druid");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_write_source = gb_gnome_db_dsn_config_druid_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_db_dsn_config_druid_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_dsn_config_druid_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_dsn_config_druid_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_dsn_config_druid_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_dsn_config_druid_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbeditor.c b/tools/glade/glade/gnome-db/gnomedbeditor.c
new file mode 100644
index 00000000..4c90fdf9
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbeditor.c
@@ -0,0 +1,188 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <libgnomedb/gnome-db-editor.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-editor.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Editable = "GnomeDbEditor::editable";
+static gchar *Highlight = "GnomeDbEditor::highlight";
+static gchar *Text = "GnomeDbEditor::text";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbEditor, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+
+GtkWidget*
+gb_gnome_db_editor_new(GbWidgetNewData *data)
+{
+ return (GtkWidget *) gnome_db_editor_new();
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_editor_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Editable, _("Editable:"), _("If the text can be edited"));
+ property_add_bool (Highlight, _("Highlight text:"), _("If selected, text will be highlighted inside the widget"));
+ property_add_string (Text, _("Text:"), _("The text to display"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_editor_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ gchar *wtext;
+ wtext = (gchar *) gnome_db_editor_get_all_text(GNOME_DB_EDITOR(widget));
+ gb_widget_output_translatable_string (data, Text, wtext);
+ gb_widget_output_bool(data, Editable, gnome_db_editor_get_editable(GNOME_DB_EDITOR(widget)));
+#ifdef HAVE_GTKSOURCEVIEW
+ gb_widget_output_bool(data, Highlight, gnome_db_editor_get_highlight(GNOME_DB_EDITOR(widget)));
+#else
+#endif
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_editor_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean editable, highlight;
+ gchar *text;
+
+ editable = gb_widget_input_bool (data, Editable);
+ if (data->apply)
+ gnome_db_editor_set_editable (GNOME_DB_EDITOR (widget), editable);
+
+#ifdef HAVE_GTKSOURCEVIEW
+ highlight = gb_widget_input_bool (data, Highlight);
+ if (data->apply)
+ gnome_db_editor_set_highlight (GNOME_DB_EDITOR (widget), highlight);
+#else
+#endif
+
+ text = gb_widget_input_string (data, Text);
+ if (data->apply)
+ gnome_db_editor_set_text (GNOME_DB_EDITOR (widget), text, -1);
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_editor_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *entry_text = (gchar *)gnome_db_editor_get_all_text (GNOME_DB_EDITOR (widget));
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_editor_new ();\n", data->wname);
+ }
+
+ if (entry_text != NULL)
+ {
+ glade_util_get_translation_properties (widget, Text, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_db_editor_set_text (GNOME_DB_EDITOR (%s), %s, -1);\n",
+ data->wname,
+ source_make_string_full (entry_text,
+ data->use_gettext && translatable,
+ context));
+ }
+
+ if (!gnome_db_editor_get_editable (GNOME_DB_EDITOR(widget)))
+ {
+ source_add (data, " gnome_db_editor_set_editable (GNOME_DB_EDITOR (%s), FALSE);\n",
+ data->wname);
+ }
+ if (!gnome_db_editor_get_highlight (GNOME_DB_EDITOR(widget)))
+ {
+ source_add (data, " gnome_db_editor_set_highlight (GNOME_DB_EDITOR (%s), FALSE);\n",
+ data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget *
+gb_gnome_db_editor_init ()
+{
+ /* Initialise the GTK type */
+ volatile GType type;
+ type = gnome_db_editor_get_type ();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct (&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_editor_xpm;
+ gbwidget.tooltip = _("GnomeDbEditor");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_gnome_db_editor_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_editor_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_editor_set_properties;
+ gbwidget.gb_widget_new = gb_gnome_db_editor_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_editor_write_source;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gnome-db/gnomedberror.c b/tools/glade/glade/gnome-db/gnomedberror.c
new file mode 100644
index 00000000..52816f20
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedberror.c
@@ -0,0 +1,148 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <libgnomedb/gnome-db-error.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-error.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbError, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_error_new (GbWidgetNewData *data)
+{
+ return gnome_db_error_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_error_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_error_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_error_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbError, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_error_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_error_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_error_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_error_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_error_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_error_xpm;
+ gbwidget.tooltip = _("Database error viewer");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_error_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_error_write_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_error_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_error_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_error_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_error_create_popup_menu;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedberrordlg.c b/tools/glade/glade/gnome-db/gnomedberrordlg.c
new file mode 100644
index 00000000..696be87d
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedberrordlg.c
@@ -0,0 +1,232 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtkmain.h>
+#include <libgnomedb/gnome-db-error-dialog.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-error-dlg.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GnomeDbErrorDlg|GtkWindow::title";
+static gchar *Type = "GnomeDbErrorDlg|GtkWindow::type";
+static gchar *Position = "GnomeDbErrorDlg|GtkWindow::window_position";
+static gchar *Modal = "GnomeDbErrorDlg|GtkWindow::modal";
+static gchar *DefaultWidth = "GnomeDbErrorDlg|GtkWindow::default_width";
+static gchar *DefaultHeight = "GnomeDbErrorDlg|GtkWindow::default_height";
+static gchar *Shrink = "GnomeDbErrorDlg|GtkWindow::allow_shrink";
+static gchar *Grow = "GnomeDbErrorDlg|GtkWindow::allow_grow";
+static gchar *AutoShrink = "GnomeDbErrorDlg|GtkWindow::auto_shrink";
+static gchar *IconName = "GnomeDbErrorDlg|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomeDbErrorDlg|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "GnomeDbErrorDlg|GtkWindow::resizable";
+static gchar *DestroyWithParent = "GnomeDbErrorDlg|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomeDbErrorDlg|GtkWindow::icon";
+
+static gchar *Role = "GnomeDbErrorDlg|GtkWindow::role";
+static gchar *TypeHint = "GnomeDbErrorDlg|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomeDbErrorDlg|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomeDbErrorDlg|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomeDbErrorDlg|GtkWindow::decorated";
+static gchar *Gravity = "GnomeDbErrorDlg|GtkWindow::gravity";
+static gchar *Urgency = "GnomeDbErrorDlg|GtkWindow::urgency_hint";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbErrorDlg, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_errordlg_new (GbWidgetNewData *data)
+{
+ GtkWidget *widget;
+ GList *elem;
+
+ widget = gnome_db_error_dialog_new (_("Error"));
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (widget), "close",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gtk_object_set_data (GTK_OBJECT (widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_errordlg_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_errordlg_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_errordlg_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbErrorDlg, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_errordlg_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_errordlg_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ gchar *title;
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ title = GTK_WINDOW (widget)->title;
+ source_add (data, " %s = gnome_db_error_dialog_new (%s);\n",
+ data->wname,
+ title ? source_make_string_full (title, data->use_gettext && translatable, context) : "NULL");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_errordlg_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_error_dialog_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_error_dlg_xpm;
+ gbwidget.tooltip = _("Database error dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_errordlg_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_errordlg_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_errordlg_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_errordlg_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_db_errordlg_write_source;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_errordlg_create_popup_menu;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbform.c b/tools/glade/glade/gnome-db/gnomedbform.c
new file mode 100644
index 00000000..08ea9b5d
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbform.c
@@ -0,0 +1,161 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <libgnomedb/gnome-db-form.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-form.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbForm, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_gnome_db_form_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+static void
+gb_gnome_db_form_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+static void
+gb_gnome_db_form_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+static void
+gb_gnome_db_form_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbForm, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_db_form_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_form_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_form_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_form_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_form_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_form_xpm;
+ gbwidget.tooltip = _("Form");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_write_source = gb_gnome_db_form_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_db_form_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_form_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_form_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_form_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_form_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbgraybar.c b/tools/glade/glade/gnome-db/gnomedbgraybar.c
new file mode 100644
index 00000000..4e32a988
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbgraybar.c
@@ -0,0 +1,149 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <libgnomedb/gnome-db-gray-bar.h>
+#include <gtk/gtkentry.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-graybar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+static gchar *Text = "GnomeDbGrayBar::text";
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbGrayBar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_gray_bar_new (GbWidgetNewData *data)
+{
+ return gnome_db_gray_bar_new ("");
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_gray_bar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (Text, _("Text:"), _("Text inside the gray bar"));
+}
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_gray_bar_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar *wtext;
+ wtext = (gchar *)gnome_db_gray_bar_get_text (GNOME_DB_GRAY_BAR(widget));
+ gb_widget_output_translatable_string (data, Text, wtext);
+}
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_gray_bar_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ const gchar *text;
+
+ text = gb_widget_input_string (data, Text);
+ if (data->apply)
+ gnome_db_gray_bar_set_text (GNOME_DB_GRAY_BAR (widget), text);
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_gray_bar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *text;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ text = gnome_db_gray_bar_get_text(GNOME_DB_GRAY_BAR (widget));
+
+ glade_util_get_translation_properties (widget, Text, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gnome_db_gray_bar_new (%s);\n",
+ data->wname,
+ source_make_string_full (text,
+ data->use_gettext && translatable,
+ context));
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_gray_bar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_gray_bar_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_graybar_xpm;
+ gbwidget.tooltip = _("Gray Bar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_gray_bar_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_gray_bar_write_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_gray_bar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_gray_bar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_gray_bar_set_properties;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbgrid.c b/tools/glade/glade/gnome-db/gnomedbgrid.c
new file mode 100644
index 00000000..d899a3a8
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbgrid.c
@@ -0,0 +1,144 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <libgnomedb/gnome-db-grid.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-grid.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbGrid, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_grid_new (GbWidgetNewData *data)
+{
+ return gnome_db_grid_new ();
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_grid_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_grid_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_grid_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbGrid, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_grid_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_grid_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_grid_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_grid_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_grid_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_grid_xpm;
+ gbwidget.tooltip = _("Data-bound grid");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_grid_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_grid_write_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_grid_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_grid_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_grid_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_grid_create_popup_menu;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedblogin.c b/tools/glade/glade/gnome-db/gnomedblogin.c
new file mode 100644
index 00000000..b50720b4
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedblogin.c
@@ -0,0 +1,148 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <libgnomedb/gnome-db-login.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-login.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbLogin, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_login_new (GbWidgetNewData *data)
+{
+ return gnome_db_login_new (NULL);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_login_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_login_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_login_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbLogin, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_login_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_login_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_login_new (NULL);\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_login_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_login_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_login_xpm;
+ gbwidget.tooltip = _("Database login widget");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_login_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_login_write_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_login_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_login_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_login_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_login_create_popup_menu;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedblogindlg.c b/tools/glade/glade/gnome-db/gnomedblogindlg.c
new file mode 100644
index 00000000..a4239814
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedblogindlg.c
@@ -0,0 +1,234 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtkmain.h>
+#include <libgnomedb/gnome-db-login.h>
+#include <libgnomedb/gnome-db-login-dialog.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-login-dlg.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GnomeDbLoginDlg|GtkWindow::title";
+static gchar *Type = "GnomeDbLoginDlg|GtkWindow::type";
+static gchar *Position = "GnomeDbLoginDlg|GtkWindow::window_position";
+static gchar *Modal = "GnomeDbLoginDlg|GtkWindow::modal";
+static gchar *DefaultWidth = "GnomeDbLoginDlg|GtkWindow::default_width";
+static gchar *DefaultHeight = "GnomeDbLoginDlg|GtkWindow::default_height";
+static gchar *Shrink = "GnomeDbLoginDlg|GtkWindow::allow_shrink";
+static gchar *Grow = "GnomeDbLoginDlg|GtkWindow::allow_grow";
+static gchar *AutoShrink = "GnomeDbLoginDlg|GtkWindow::auto_shrink";
+static gchar *IconName = "GnomeDbLoginDlg|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomeDbLoginDlg|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "GnomeDbLoginDlg|GtkWindow::resizable";
+static gchar *DestroyWithParent = "GnomeDbLoginDlg|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomeDbLoginDlg|GtkWindow::icon";
+
+static gchar *Role = "GnomeDbLoginDlg|GtkWindow::role";
+static gchar *TypeHint = "GnomeDbLoginDlg|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomeDbLoginDlg|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomeDbLoginDlg|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomeDbLoginDlg|GtkWindow::decorated";
+static gchar *Gravity = "GnomeDbLoginDlg|GtkWindow::gravity";
+static gchar *Urgency = "GnomeDbLoginDlg|GtkWindow::urgency_hint";
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbLoginDlg, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_db_logindlg_new (GbWidgetNewData *data)
+{
+ GtkWidget *widget, *login;
+ GList *elem;
+
+ login = gnome_db_login_new (NULL);
+
+ widget = gnome_db_login_dialog_new (_("Login"));
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (widget), "close",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gtk_object_set_data (GTK_OBJECT (widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_logindlg_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_logindlg_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_logindlg_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbLoginDlg, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_logindlg_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_logindlg_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ gchar *title;
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ title = GTK_WINDOW (widget)->title;
+ source_add (data, " %s = gnome_db_login_dialog_new (%s);\n",
+ data->wname,
+ title ? source_make_string_full (title, data->use_gettext && translatable, context) : "NULL");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_logindlg_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_login_dialog_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_login_dlg_xpm;
+ gbwidget.tooltip = _("Database login dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_logindlg_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_logindlg_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_logindlg_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_logindlg_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_db_logindlg_write_source;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_logindlg_create_popup_menu;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbprovidersel.c b/tools/glade/glade/gnome-db/gnomedbprovidersel.c
new file mode 100644
index 00000000..69dd669b
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbprovidersel.c
@@ -0,0 +1,161 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <libgnomedb/gnome-db-provider-selector.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-provider-sel.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbProviderSelector, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_gnome_db_provider_selector_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+static void
+gb_gnome_db_provider_selector_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+static void
+gb_gnome_db_provider_selector_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+static void
+gb_gnome_db_provider_selector_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbProviderSelector, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_db_provider_selector_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_provider_selector_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_provider_selector_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_provider_selector_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_provider_selector_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_provider_sel_xpm;
+ gbwidget.tooltip = _("Provider Selector");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_write_source = gb_gnome_db_provider_selector_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_db_provider_selector_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_provider_selector_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_provider_selector_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_provider_selector_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_provider_selector_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbsourcesel.c b/tools/glade/glade/gnome-db/gnomedbsourcesel.c
new file mode 100644
index 00000000..3398e499
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbsourcesel.c
@@ -0,0 +1,161 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999-2002 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <libgnomedb/gnome-db-data-source-selector.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-db-sourcesel.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbDataSourceSelector, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_gnome_db_data_source_selector_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+static void
+gb_gnome_db_data_source_selector_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+static void
+gb_gnome_db_data_source_selector_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+static void
+gb_gnome_db_data_source_selector_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbDataSourceSelector, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_db_data_source_selector_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_data_source_selector_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_data_source_selector_new (NULL);\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_data_source_selector_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_data_source_selector_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_db_sourcesel_xpm;
+ gbwidget.tooltip = _("Data Source Selector");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_write_source = gb_gnome_db_data_source_selector_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_db_data_source_selector_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_data_source_selector_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_data_source_selector_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_data_source_selector_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_data_source_selector_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome-db/gnomedbtableeditor.c b/tools/glade/glade/gnome-db/gnomedbtableeditor.c
new file mode 100644
index 00000000..e7b7cf8f
--- /dev/null
+++ b/tools/glade/glade/gnome-db/gnomedbtableeditor.c
@@ -0,0 +1,144 @@
+/* GNOME DB library
+ * Copyright (C), 1999-2001 The Free Software Foundation
+ *
+ * AUTHORS:
+ * Rodrigo Moya <rodrigo@gnome-db.org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * Revision 0.1
+ */
+#include <config.h>
+
+#include <libgnomedb/gnome-db-table-editor.h>
+
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+/* This has to be changed to the correct pixmap! */
+#include "../graphics/gnome-db-table-editor.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDbTableEditor, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+
+static GtkWidget*
+gb_gnome_db_table_editor_new (GbWidgetNewData *data)
+{
+ return gnome_db_table_editor_new ();
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_db_table_editor_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_db_table_editor_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_db_table_editor_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDbGrid, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_db_table_editor_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_db_table_editor_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_db_table_editor_new ();\n", data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_db_table_editor_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_db_table_editor_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct =gnome_db_table_editor_xpm;
+ gbwidget.tooltip = _("Table Editor "); /* Please FIXME*/
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_db_table_editor_new;
+ gbwidget.gb_widget_write_source = gb_gnome_db_table_editor_write_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_db_table_editor_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_db_table_editor_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_db_table_editor_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_db_table_editor_create_popup_menu;
+
+ return &gbwidget;
+}
diff --git a/tools/glade/glade/gnome/Makefile.am b/tools/glade/glade/gnome/Makefile.am
new file mode 100644
index 00000000..02f3da2d
--- /dev/null
+++ b/tools/glade/glade/gnome/Makefile.am
@@ -0,0 +1,33 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libgnomewidgets.a
+
+# maybe this should just be $(GLADE_GNOME_CFLAGS) ?
+INCLUDES = $(GLADE_CFLAGS) \
+ $(GLADE_DEPRECATION_CFLAGS)
+
+libgnomewidgets_a_SOURCES = \
+ bonobodock.c \
+ bonobodockitem.c \
+ gnomeabout.c \
+ gnomeapp.c \
+ gnomeappbar.c \
+ gnomecanvas.c \
+ gnomecolorpicker.c \
+ gnomecontrol.c \
+ gnomedateedit.c \
+ gnomedialog.c \
+ gnomedruid.c \
+ gnomedruidpageedge.c \
+ gnomedruidpagestandard.c \
+ gnomeentry.c \
+ gnomefileentry.c \
+ gnomefontpicker.c \
+ gnomehref.c \
+ gnomeiconentry.c \
+ gnomeiconlist.c \
+ gnomeiconselection.c \
+ gnomemessagebox.c \
+ gnomepixmap.c \
+ gnomepixmapentry.c \
+ gnomepropertybox.c
diff --git a/tools/glade/glade/gnome/bonobodock.c b/tools/glade/glade/gnome/bonobodock.c
new file mode 100644
index 00000000..24a2db34
--- /dev/null
+++ b/tools/glade/glade/gnome/bonobodock.c
@@ -0,0 +1,510 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+#include "../tree.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/bonobo-dock.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *AllowFloating = "BonoboDock::allow_floating";
+
+
+static void gb_bonobo_dock_add_band_on_left (GtkWidget * menuitem,
+ GtkWidget * dock);
+static void gb_bonobo_dock_add_band_on_right (GtkWidget * menuitem,
+ GtkWidget * dock);
+static void gb_bonobo_dock_add_band_on_top (GtkWidget * menuitem,
+ GtkWidget * dock);
+static void gb_bonobo_dock_add_band_on_bottom (GtkWidget * menuitem,
+ GtkWidget * dock);
+static void gb_bonobo_dock_add_band_floating (GtkWidget * menuitem,
+ GtkWidget * dock);
+static void gb_bonobo_dock_add_band (GtkWidget * dock,
+ BonoboDockPlacement placement);
+
+static void gb_bonobo_dock_init_widget (GtkWidget *widget);
+static void gb_bonobo_dock_size_request (GtkWidget *widget,
+ GtkRequisition *requisition,
+ gpointer user_data);
+static void gb_bonobo_dock_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ gpointer user_data);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class BonoboDock, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_bonobo_dock_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = bonobo_dock_new ();
+
+ /* FIXME: GnomeLibs 1.0.1 bug workaround to resize floating items. */
+ gb_bonobo_dock_init_widget (new_widget);
+
+ return new_widget;
+}
+
+
+/* FIXME: GnomeLibs 1.0.1 bug workaround to resize floating items. */
+static void
+gb_bonobo_dock_create_from_widget (GtkWidget *widget,
+ GbWidgetCreateFromData *data)
+{
+ gb_bonobo_dock_init_widget (widget);
+}
+
+
+/* FIXME: GnomeLibs 1.0.1 bug workaround to resize floating items. */
+static void
+gb_bonobo_dock_init_widget (GtkWidget *widget)
+{
+ gtk_signal_connect_after (GTK_OBJECT (widget), "size_request",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_size_request),
+ NULL);
+ gtk_signal_connect_after (GTK_OBJECT (widget), "size_allocate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_size_allocate),
+ NULL);
+}
+
+
+/* FIXME: GnomeLibs 1.0.1 bug workaround to resize floating items.
+ Calls gtk_widget_size_request() for all floating items, just so that they
+ calculate their requisition. */
+static void
+gb_bonobo_dock_size_request (GtkWidget *widget, GtkRequisition *requisition,
+ gpointer user_data)
+{
+ GList *lp;
+ GtkWidget *w;
+ GtkRequisition float_item_requisition;
+
+ lp = BONOBO_DOCK (widget)->floating_children;
+ while (lp != NULL)
+ {
+ w = lp->data;
+ lp = lp->next;
+ gtk_widget_size_request (w, &float_item_requisition);
+ }
+}
+
+
+/* FIXME: GnomeLibs 1.0.1 bug workaround to resize floating items.
+ Calls gtk_widget_size_allocate() for all floating items, allocating
+ whatever the item wants in its requisition. */
+static void
+gb_bonobo_dock_size_allocate (GtkWidget *widget, GtkAllocation *allocation,
+ gpointer user_data)
+{
+ GList *lp;
+ GtkWidget *w;
+ GtkAllocation float_item_allocation;
+
+ lp = BONOBO_DOCK (widget)->floating_children;
+ while (lp != NULL)
+ {
+ w = lp->data;
+ lp = lp->next;
+
+ float_item_allocation.x = 0;
+ float_item_allocation.y = 0;
+ float_item_allocation.width = w->requisition.width;
+ float_item_allocation.height = w->requisition.height;
+ gtk_widget_size_allocate (w, &float_item_allocation);
+ }
+}
+
+
+void
+gb_bonobo_dock_add_child (GtkWidget *widget, GtkWidget * child,
+ GbWidgetSetArgData *data)
+{
+ gchar *orientation_string, *placement_string;
+ BonoboDockPlacement placement;
+ GtkOrientation orientation;
+ gint band_num, position, offset, placement_index, orientation_index;
+
+ if (BONOBO_IS_DOCK_ITEM (child))
+ {
+ data->loading_type = GB_CHILD_PROPERTIES;
+
+ placement_string = load_choice (data, "placement");
+ placement = BONOBO_DOCK_TOP;
+ if (placement_string && placement_string[0])
+ {
+ placement_index = glade_util_string_array_index (GladePlacementSymbols,
+ GladePlacementSize,
+ placement_string);
+ if (placement_index != -1)
+ placement = GladePlacementValues[placement_index];
+ }
+
+ if (placement == BONOBO_DOCK_FLOATING)
+ {
+ orientation_string = load_choice (data, "orientation");
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ if (orientation_string && orientation_string[0])
+ {
+ orientation_index = glade_util_string_array_index (GladeOrientationSymbols, GladeOrientationSize, orientation_string);
+ if (orientation_index != -1)
+ orientation = GladeOrientationValues[orientation_index];
+ }
+
+ /* FIXME: Where fo we put the floating item? Use 300,300 for now. */
+ bonobo_dock_add_floating_item (BONOBO_DOCK (widget),
+ BONOBO_DOCK_ITEM (child),
+ 300, 300, orientation);
+ }
+ else
+ {
+ gboolean new_band = FALSE;
+
+ band_num = load_int (data, "band");
+ position = load_int (data, "position");
+ offset = load_int (data, "offset");
+
+ /* When loading, we don't want to create a new band explicitly,
+ but when pasting we do (though I'm not sure yet). */
+ if (data->xml_buffer)
+ new_band = TRUE;
+
+ bonobo_dock_add_item (BONOBO_DOCK (widget), BONOBO_DOCK_ITEM (child),
+ placement, band_num, position, offset,
+ new_band /* FIXME: what should this be. */);
+ }
+
+ data->loading_type = GB_STANDARD_PROPERTIES;
+ }
+ else
+ {
+ bonobo_dock_set_client_area (BONOBO_DOCK (widget), child);
+ }
+
+ /* Floating dock items must be shown after adding to the dock, or they do
+ not appear (GnomeLibs 1.0.1). */
+ gtk_widget_show (child);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_bonobo_dock_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (AllowFloating, _("Allow Floating:"),
+ _("If floating dock items are allowed"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_bonobo_dock_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, AllowFloating,
+ BONOBO_DOCK (widget)->floating_items_allowed);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_bonobo_dock_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean allow_floating;
+
+ allow_floating = gb_widget_input_bool (data, AllowFloating);
+ if (data->apply)
+ {
+ bonobo_dock_allow_floating_items (BONOBO_DOCK (widget), allow_floating);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a BonoboDock, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_bonobo_dock_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_label (_("Add dock band on top"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_add_band_on_top),
+ widget);
+
+ menuitem = gtk_menu_item_new_with_label (_("Add dock band on bottom"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_add_band_on_bottom),
+ widget);
+
+ menuitem = gtk_menu_item_new_with_label (_("Add dock band on left"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_add_band_on_left),
+ widget);
+
+ menuitem = gtk_menu_item_new_with_label (_("Add dock band on right"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_add_band_on_right),
+ widget);
+
+ menuitem = gtk_menu_item_new_with_label (_("Add floating dock item"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_add_band_floating),
+ widget);
+}
+
+static void
+gb_bonobo_dock_add_band_on_left (GtkWidget * menuitem, GtkWidget * dock)
+{
+ gb_bonobo_dock_add_band (dock, BONOBO_DOCK_LEFT);
+}
+
+static void
+gb_bonobo_dock_add_band_on_right (GtkWidget * menuitem, GtkWidget * dock)
+{
+ gb_bonobo_dock_add_band (dock, BONOBO_DOCK_RIGHT);
+}
+
+static void
+gb_bonobo_dock_add_band_on_top (GtkWidget * menuitem, GtkWidget * dock)
+{
+ gb_bonobo_dock_add_band (dock, BONOBO_DOCK_TOP);
+}
+
+static void
+gb_bonobo_dock_add_band_on_bottom (GtkWidget * menuitem, GtkWidget * dock)
+{
+ gb_bonobo_dock_add_band (dock, BONOBO_DOCK_BOTTOM);
+}
+
+static void
+gb_bonobo_dock_add_band_floating (GtkWidget * menuitem, GtkWidget * dock)
+{
+ gb_bonobo_dock_add_band (dock, BONOBO_DOCK_FLOATING);
+}
+
+static void
+gb_bonobo_dock_add_band (GtkWidget * dock, BonoboDockPlacement placement)
+{
+ GtkWidget *dock_item, *placeholder;
+ gint x, y;
+
+ dock_item = gb_widget_new ("BonoboDockItem", NULL);
+
+ placeholder = editor_new_placeholder ();
+ gtk_container_add (GTK_CONTAINER (dock_item), placeholder);
+
+ if (placement == BONOBO_DOCK_FLOATING)
+ {
+ gdk_window_get_pointer (NULL, &x, &y, NULL);
+ /* Place the floating item slightly to the left and above the pointer,
+ but make sure it is on the screen. */
+ x = MAX (0, x - 50);
+ y = MAX (0, y - 50);
+ bonobo_dock_add_floating_item (BONOBO_DOCK (dock),
+ BONOBO_DOCK_ITEM (dock_item),
+ x, y, GTK_ORIENTATION_HORIZONTAL);
+ }
+ else
+ {
+ bonobo_dock_add_item (BONOBO_DOCK (dock), BONOBO_DOCK_ITEM (dock_item),
+ placement, -1, 0, 0, TRUE);
+ }
+
+ /* Floating dock items must be shown after adding to the dock, or they do
+ not appear (GnomeLibs 1.0.1). */
+ gtk_widget_show (dock_item);
+
+ /* Show the properties of the new dock item. */
+ gb_widget_show_properties (dock_item);
+
+ tree_add_widget (dock_item);
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_bonobo_dock_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ /* If our parent is a GnomeApp we don't create the BonoboDock here. */
+ if (widget->parent && GTK_IS_VBOX (widget->parent)
+ && widget->parent->parent && GNOME_IS_APP (widget->parent->parent))
+ {
+ data->create_widget = FALSE;
+ source_add (data, " %s = GNOME_APP (%s)->dock;\n",
+ data->wname, data->component_name);
+ }
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = bonobo_dock_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!BONOBO_DOCK (widget)->floating_items_allowed)
+ {
+ source_add (data,
+ " bonobo_dock_allow_floating_items (BONOBO_DOCK (%s), FALSE);\n",
+ data->wname);
+ }
+
+ /* Set the initial positions for any floating dock items. */
+ gtk_object_set_data (GTK_OBJECT (widget), "glade-dock-item-x",
+ GINT_TO_POINTER (100));
+ gtk_object_set_data (GTK_OBJECT (widget), "glade-dock-item-y",
+ GINT_TO_POINTER (100));
+}
+
+
+/* Outputs source to add a child menu to a BonoboDock. */
+static void
+gb_bonobo_dock_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ if (BONOBO_IS_DOCK_ITEM (child))
+ {
+ gchar *orientation;
+ gint x, y;
+
+ /* FIXME: We should support adding normal dock items eventually. */
+ if (!glade_gnome_is_app_dock_item (child))
+ g_warning ("Can't add normal dock items to a BonoboDock: %s",
+ data->wname);
+
+ if (!BONOBO_DOCK_ITEM (child)->is_floating)
+ g_warning ("Can't add non-floating dock items to a BonoboDock: %s",
+ data->wname);
+
+ if (BONOBO_DOCK_ITEM (child)->orientation == GTK_ORIENTATION_HORIZONTAL)
+ orientation = "GTK_ORIENTATION_HORIZONTAL";
+ else
+ orientation = "GTK_ORIENTATION_VERTICAL";
+
+ /* We add the floating item to the layout. I think that is OK.
+ FIXME: Ideally we don't want the position of the floating item to
+ be set explicitly, so the user has to position in. But I don't know
+ if that can be done. So what should we do? */
+
+ x = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "glade-dock-item-x"));
+ y = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent),
+ "glade-dock-item-y"));
+
+ source_add (data,
+ " bonobo_dock_layout_add_floating_item (BONOBO_DOCK_LAYOUT (GNOME_APP (%s)->layout),\n"
+ " BONOBO_DOCK_ITEM (%s), %i, %i,\n"
+ " %s);\n",
+ data->component_name, data->wname, x, y, orientation);
+
+ gtk_object_set_data (GTK_OBJECT (parent), "glade-dock-item-x",
+ GINT_TO_POINTER (x + 50));
+ gtk_object_set_data (GTK_OBJECT (parent), "glade-dock-item-y",
+ GINT_TO_POINTER (y + 50));
+ }
+ else
+ {
+ source_add (data,
+ " gnome_app_set_contents (GNOME_APP (%s), %s);\n",
+ data->component_name, data->wname);
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_bonobo_dock_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = bonobo_dock_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = bonobo_dock_xpm;
+ gbwidget.tooltip = _("Gnome Dock");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_bonobo_dock_new;
+ gbwidget.gb_widget_create_from_widget = gb_bonobo_dock_create_from_widget;
+ gbwidget.gb_widget_add_child = gb_bonobo_dock_add_child;
+ gbwidget.gb_widget_create_properties = gb_bonobo_dock_create_properties;
+ gbwidget.gb_widget_get_properties = gb_bonobo_dock_get_properties;
+ gbwidget.gb_widget_set_properties = gb_bonobo_dock_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_bonobo_dock_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_bonobo_dock_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_bonobo_dock_write_add_child_source;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/bonobodockitem.c b/tools/glade/glade/gnome/bonobodockitem.c
new file mode 100644
index 00000000..8c871210
--- /dev/null
+++ b/tools/glade/glade/gnome/bonobodockitem.c
@@ -0,0 +1,786 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include <bonobo.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/bonobo-dock-item.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *ShadowType = "BonoboDockItem::shadow_type";
+static gchar *Orientation = "BonoboDockItem::orientation";
+
+/* These 5 are boolean flags in the property editor, but saved as one property,
+ "behavior" in the XML. */
+static gchar *Locked = "BonoboDockItem::locked";
+static gchar *Exclusive = "BonoboDockItem::exclusive";
+static gchar *NeverFloating = "BonoboDockItem::never_floating";
+static gchar *NeverVertical = "BonoboDockItem::never_vertical";
+static gchar *NeverHorizontal = "BonoboDockItem::never_horizontal";
+
+/* These are only used for loading & saving - they are not displayed in the
+ property editor. */
+static gchar *Placement = "BonoboDockItem::placement";
+static gchar *BandNum = "BonoboDockItem::band";
+static gchar *Position = "BonoboDockItem::position";
+static gchar *Offset = "BonoboDockItem::offset";
+static gchar *Behavior = "BonoboDockItem::behavior";
+
+static const gchar *GbShadowChoices[] =
+{"None", "In", "Out",
+ "Etched In", "Etched Out", NULL};
+static const gint GbShadowValues[] =
+{
+ GTK_SHADOW_NONE,
+ GTK_SHADOW_IN,
+ GTK_SHADOW_OUT,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_SHADOW_ETCHED_OUT
+};
+static const gchar *GbShadowSymbols[] =
+{
+ "GTK_SHADOW_NONE",
+ "GTK_SHADOW_IN",
+ "GTK_SHADOW_OUT",
+ "GTK_SHADOW_ETCHED_IN",
+ "GTK_SHADOW_ETCHED_OUT"
+};
+
+
+static void gb_bonobo_dock_item_init_widget (GtkWidget *widget);
+static void gb_bonobo_dock_item_drag_end (GtkWidget *widget,
+ gpointer user_data);
+
+static void gb_bonobo_dock_item_add_item_before (GtkWidget * menuitem,
+ BonoboDockItem * dock_item);
+static void gb_bonobo_dock_item_add_item_after (GtkWidget * menuitem,
+ BonoboDockItem * dock_item);
+static void gb_bonobo_dock_item_add_item (BonoboDockItem * existing_dock_item,
+ gboolean after);
+static gboolean gb_bonobo_dock_item_find_position (BonoboDockItem * dock_item,
+ BonoboDockPlacement *placement,
+ gint *band_num,
+ gint *position,
+ gint *offset);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class BonoboDockItem, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_bonobo_dock_item_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = bonobo_dock_item_new (NULL, BONOBO_DOCK_ITEM_BEH_NORMAL);
+
+ gb_bonobo_dock_item_init_widget (new_widget);
+
+ return new_widget;
+}
+
+
+static void
+gb_bonobo_dock_item_create_from_widget (GtkWidget *widget,
+ GbWidgetCreateFromData *data)
+{
+ gb_bonobo_dock_item_init_widget (widget);
+}
+
+
+static void
+gb_bonobo_dock_item_init_widget (GtkWidget *widget)
+{
+ /* Connect a handler so we can update the properties if the item is moved. */
+ gtk_signal_connect_after (GTK_OBJECT (widget), "dock_drag_end",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_item_drag_end),
+ NULL);
+}
+
+
+/* If the widgets properties are currently shown, we update them if necessary.
+ */
+static void
+gb_bonobo_dock_item_drag_end (GtkWidget *widget, gpointer user_data)
+{
+ if (property_get_widget () == widget)
+ {
+ /* The orientation is only useful for floating items. */
+ property_set_sensitive (Orientation,
+ BONOBO_DOCK_ITEM (widget)->is_floating);
+ }
+}
+
+
+void
+gb_bonobo_dock_item_add_child (GtkWidget *widget, GtkWidget * child,
+ GbWidgetSetArgData *data)
+{
+ /* Try to set up menubars and toolbars just like GnomeApp does.
+ We don't do anything now. I'm not sure what we should do. */
+
+ gtk_container_add (GTK_CONTAINER (widget), child);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_bonobo_dock_item_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Locked, _("Locked:"),
+ _("If the dock item is locked in position"));
+ property_add_bool (Exclusive, _("Exclusive:"),
+ _("If the dock item is always the only item in its band"));
+ property_add_bool (NeverFloating, _("Never Floating:"),
+ _("If the dock item is never allowed to float in its own window"));
+ property_add_bool (NeverVertical, _("Never Vertical:"),
+ _("If the dock item is never allowed to be vertical"));
+ property_add_bool (NeverHorizontal, _("Never Horizontal:"),
+ _("If the dock item is never allowed to be horizontal"));
+
+ property_add_choice (ShadowType, _("Shadow:"),
+ _("The type of shadow around the dock item"),
+ GbShadowChoices);
+ property_add_choice (Orientation, _("Orientation:"),
+ _("The orientation of a floating dock item"),
+ GladeOrientationChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_bonobo_dock_item_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gint i;
+
+ if (BONOBO_DOCK_ITEM (widget)->is_floating)
+ {
+ /* Orientation is only relevant when floating. */
+ for (i = 0; i < GladeOrientationSize; i++)
+ {
+ if (GladeOrientationValues[i] == BONOBO_DOCK_ITEM (widget)->orientation)
+ {
+ gb_widget_output_choice (data, Orientation, i,
+ GladeOrientationSymbols[i]);
+ }
+ }
+ }
+
+ if (data->action == GB_SHOWING)
+ {
+ gb_widget_output_bool (data, Locked, BONOBO_DOCK_ITEM (widget)->behavior & BONOBO_DOCK_ITEM_BEH_LOCKED);
+ gb_widget_output_bool (data, Exclusive, BONOBO_DOCK_ITEM (widget)->behavior & BONOBO_DOCK_ITEM_BEH_EXCLUSIVE);
+ gb_widget_output_bool (data, NeverFloating, BONOBO_DOCK_ITEM (widget)->behavior & BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING);
+ gb_widget_output_bool (data, NeverVertical, BONOBO_DOCK_ITEM (widget)->behavior & BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL);
+ gb_widget_output_bool (data, NeverHorizontal, BONOBO_DOCK_ITEM (widget)->behavior & BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL);
+ }
+
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]); i++)
+ {
+ if (GbShadowValues[i] == BONOBO_DOCK_ITEM (widget)->shadow_type)
+ gb_widget_output_choice (data, ShadowType, i, GbShadowSymbols[i]);
+ }
+
+ if (data->action == GB_SHOWING)
+ {
+ /* The orientation is only useful for floating items. */
+ property_set_sensitive (Orientation,
+ BONOBO_DOCK_ITEM (widget)->is_floating);
+ }
+}
+
+
+/* SPECIAL CODE: "placement", "band", "position", "offset" and "behavior"
+ are now packing properties, so we have this special function to save
+ them, which is called directly in gb_widget_save(). */
+void
+gb_bonobo_dock_item_save_packing_properties (GtkWidget *parent,
+ GtkWidget *widget,
+ GbWidgetGetArgData * data)
+{
+ char *behavior;
+
+ save_start_tag (data, "packing");
+
+ if (BONOBO_DOCK_ITEM (widget)->is_floating)
+ {
+ gb_widget_output_string (data, Placement, "BONOBO_DOCK_FLOATING");
+ }
+ else
+ {
+ BonoboDockPlacement placement;
+ gint band_num, position, offset, idx;
+
+ if (gb_bonobo_dock_item_find_position (BONOBO_DOCK_ITEM (widget),
+ &placement, &band_num,
+ &position, &offset))
+ {
+ idx = glade_util_int_array_index (GladePlacementValues,
+ GladePlacementSize,
+ placement);
+ if (idx != -1)
+ gb_widget_output_string (data, Placement,
+ GladePlacementSymbols[idx]);
+
+ gb_widget_output_int (data, BandNum, band_num);
+ gb_widget_output_int (data, Position, position);
+ gb_widget_output_int (data, Offset, offset);
+ }
+ else
+ {
+ g_warning ("Dock band not found");
+ }
+ }
+
+ behavior = glade_util_string_from_flags (BONOBO_TYPE_DOCK_ITEM_BEHAVIOR,
+ BONOBO_DOCK_ITEM (widget)->behavior);
+ save_string (data, Behavior, behavior);
+ g_free (behavior);
+
+ save_end_tag (data, "packing");
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_bonobo_dock_item_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean locked, exclusive, never_floating, never_vertical, never_horizontal;
+ gchar *shadow, *orientation;
+ BonoboDockItemBehavior behavior;
+ gint i;
+
+ /* This is a bit of a hack, as some of the properties are now saved as
+ packing properties instead of normal properties. */
+ if (data->action == GB_LOADING)
+ {
+ gchar *behavior_string;
+
+ data->loading_type = GB_CHILD_PROPERTIES;
+
+ behavior_string = load_string (data, Behavior);
+ behavior = glade_util_flags_from_string (BONOBO_TYPE_DOCK_ITEM_BEHAVIOR,
+ behavior_string);
+
+ data->loading_type = GB_STANDARD_PROPERTIES;
+ }
+ else
+ {
+ behavior = BONOBO_DOCK_ITEM (widget)->behavior;
+
+ locked = gb_widget_input_bool (data, Locked);
+ if (data->apply)
+ {
+ if (locked)
+ behavior |= BONOBO_DOCK_ITEM_BEH_LOCKED;
+ else
+ behavior &= ~BONOBO_DOCK_ITEM_BEH_LOCKED;
+
+ /* This avoids any problems with redrawing the selection. */
+ if (data->action == GB_APPLYING)
+ editor_clear_selection (NULL);
+
+ gtk_widget_queue_resize (widget);
+ }
+
+ exclusive = gb_widget_input_bool (data, Exclusive);
+ if (data->apply)
+ {
+ if (exclusive)
+ behavior |= BONOBO_DOCK_ITEM_BEH_EXCLUSIVE;
+ else
+ behavior &= ~BONOBO_DOCK_ITEM_BEH_EXCLUSIVE;
+ }
+
+ never_floating = gb_widget_input_bool (data, NeverFloating);
+ if (data->apply)
+ {
+ if (never_floating)
+ behavior |= BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING;
+ else
+ behavior &= ~BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING;
+ }
+
+ never_vertical = gb_widget_input_bool (data, NeverVertical);
+ if (data->apply)
+ {
+ if (never_vertical)
+ behavior |= BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL;
+ else
+ behavior &= ~BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL;
+ }
+
+ never_horizontal = gb_widget_input_bool (data, NeverHorizontal);
+ if (data->apply)
+ {
+ if (never_horizontal)
+ behavior |= BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL;
+ else
+ behavior &= ~BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL;
+ }
+ }
+
+ /* BonoboDockItem has no method for setting the behavior. */
+ BONOBO_DOCK_ITEM (widget)->behavior = behavior;
+
+
+ shadow = gb_widget_input_choice (data, ShadowType);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbShadowValues) / sizeof (GbShadowValues[0]);
+ i++)
+ {
+ if (!strcmp (shadow, GbShadowChoices[i])
+ || !strcmp (shadow, GbShadowSymbols[i]))
+ {
+ bonobo_dock_item_set_shadow_type (BONOBO_DOCK_ITEM (widget),
+ GbShadowValues[i]);
+ break;
+ }
+ }
+ }
+
+ orientation = gb_widget_input_choice (data, Orientation);
+ if (data->apply)
+ {
+ for (i = 0; i < GladeOrientationSize; i++)
+ {
+ if (!strcmp (orientation, GladeOrientationChoices[i])
+ || !strcmp (orientation, GladeOrientationSymbols[i]))
+ {
+ bonobo_dock_item_set_orientation (BONOBO_DOCK_ITEM (widget),
+ GladeOrientationValues[i]);
+
+ /* This avoids any problems with redrawing the selection. */
+ if (data->action == GB_APPLYING)
+ editor_clear_selection (NULL);
+
+ /* FIXME: A test to see if changing orientation works. */
+ if (BONOBO_DOCK_ITEM (widget)->bin.child)
+ gtk_widget_queue_resize (BONOBO_DOCK_ITEM (widget)->bin.child);
+
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a BonoboDockItem, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_bonobo_dock_item_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+
+ /* We can't add items next to floating items or items that have the
+ BONOBO_DOCK_ITEM_BEH_EXCLUSIVE flag set. */
+ if (!BONOBO_DOCK_ITEM (widget)->is_floating
+ && !(BONOBO_DOCK_ITEM (widget)->behavior & BONOBO_DOCK_ITEM_BEH_EXCLUSIVE))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add dock item before"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_item_add_item_before),
+ widget);
+
+ menuitem = gtk_menu_item_new_with_label (_("Add dock item after"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_bonobo_dock_item_add_item_after),
+ widget);
+ }
+}
+
+
+static void
+gb_bonobo_dock_item_add_item_before (GtkWidget * menuitem,
+ BonoboDockItem * dock_item)
+{
+ gb_bonobo_dock_item_add_item (dock_item, FALSE);
+}
+
+
+static void
+gb_bonobo_dock_item_add_item_after (GtkWidget * menuitem,
+ BonoboDockItem * dock_item)
+{
+ gb_bonobo_dock_item_add_item (dock_item, TRUE);
+}
+
+
+static void
+gb_bonobo_dock_item_add_item (BonoboDockItem * existing_dock_item,
+ gboolean after)
+{
+ BonoboDock *dock;
+ BonoboDockBand *dock_band;
+ GtkWidget *dock_item, *placeholder;
+ BonoboDockPlacement placement;
+ gint band_num, position, offset;
+
+ if (!gb_bonobo_dock_item_find_position (BONOBO_DOCK_ITEM (existing_dock_item),
+ &placement, &band_num,
+ &position, &offset))
+ {
+ g_warning ("Dock band not found");
+ return;
+ }
+
+ dock_band = BONOBO_DOCK_BAND (GTK_WIDGET (existing_dock_item)->parent);
+ dock = BONOBO_DOCK (GTK_WIDGET (dock_band)->parent);
+
+ /* Create the new dock item. */
+ dock_item = gb_widget_new ("BonoboDockItem", NULL);
+
+ placeholder = editor_new_placeholder ();
+ gtk_container_add (GTK_CONTAINER (dock_item), placeholder);
+
+ /* Now add it at the required position. */
+ if (after)
+ position++;
+ bonobo_dock_add_item (dock, BONOBO_DOCK_ITEM (dock_item), placement, band_num,
+ position, 0, FALSE);
+
+ gtk_widget_show (dock_item);
+
+ /* Show the properties of the new dock item. */
+ gb_widget_show_properties (dock_item);
+}
+
+
+/* This gets the placement, band number, position and offset of dock items
+ which are not floating. It returns TRUE if the dock item is found. */
+static gboolean
+gb_bonobo_dock_item_find_position (BonoboDockItem * dock_item,
+ BonoboDockPlacement *placement,
+ gint *band_num,
+ gint *position,
+ gint *offset)
+{
+ BonoboDock *dock;
+ BonoboDockBand *dock_band;
+ BonoboDockBandChild *dock_band_child;
+ gint pos;
+ GList *elem;
+
+ g_return_val_if_fail (BONOBO_IS_DOCK_BAND (GTK_WIDGET (dock_item)->parent),
+ FALSE);
+ dock_band = BONOBO_DOCK_BAND (GTK_WIDGET (dock_item)->parent);
+
+ g_return_val_if_fail (BONOBO_IS_DOCK (GTK_WIDGET (dock_band)->parent), FALSE);
+ dock = BONOBO_DOCK (GTK_WIDGET (dock_band)->parent);
+
+ /* First we find out which band the existing dock item is. */
+ if ((*band_num = g_list_index (dock->top_bands, dock_band)) != -1)
+ *placement = BONOBO_DOCK_TOP;
+ else if ((*band_num = g_list_index (dock->bottom_bands, dock_band)) != -1)
+ *placement = BONOBO_DOCK_BOTTOM;
+ else if ((*band_num = g_list_index (dock->left_bands, dock_band)) != -1)
+ *placement = BONOBO_DOCK_LEFT;
+ else if ((*band_num = g_list_index (dock->right_bands, dock_band)) != -1)
+ *placement = BONOBO_DOCK_RIGHT;
+ else
+ return FALSE;
+
+ /* Now find the position of the existing dock item within the band. */
+ for (elem = dock_band->children, pos = 0;
+ elem != NULL;
+ elem = elem->next, pos++)
+ {
+ dock_band_child = (BonoboDockBandChild*) elem->data;
+ if (dock_band_child->widget == GTK_WIDGET (dock_item))
+ {
+ *position = pos;
+ *offset = dock_band_child->offset;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_bonobo_dock_item_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ /* If we are in a GnomeApp's dock, we don't create the dock item here, or
+ add it to the BonoboDock, since it is created automatically when the item
+ is added to the GnomeApp. */
+ if (glade_gnome_is_app_dock_item (widget)
+ && !BONOBO_DOCK_ITEM (widget)->is_floating)
+ {
+ return;
+ }
+
+ if (data->create_widget)
+ {
+ BonoboDockItemBehavior behavior;
+ const gchar *prefix = "\n ";
+ const gchar *prefix2 = "\n | ";
+
+ behavior = BONOBO_DOCK_ITEM (widget)->behavior;
+
+ source_add (data,
+ " %s = bonobo_dock_item_new (%s,",
+ data->wname, source_make_string (data->real_wname, FALSE));
+ if (behavior == 0)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NORMAL);\n", prefix);
+ }
+ else
+ {
+ if (behavior & BONOBO_DOCK_ITEM_BEH_EXCLUSIVE)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_EXCLUSIVE",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NEVER_FLOATING",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_LOCKED)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_LOCKED",
+ prefix);
+ }
+
+ source_add (data, ");\n");
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+}
+
+
+/* Outputs source to add a child menu to a BonoboDock. */
+static void
+gb_bonobo_dock_item_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ GnomeApp *app;
+
+ /* If we're adding a dock item to a GnomeApp's dock, we use
+ the special functions to add it here. */
+ if ((app = glade_gnome_is_app_dock_item (parent)))
+ {
+ /* Children of floating items are added as normal. */
+ if (BONOBO_DOCK_ITEM (parent)->is_floating)
+ {
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else if (GTK_IS_MENU_BAR (child))
+ {
+ source_add (data,
+ " gnome_app_create_menus (GNOME_APP (%s), %s_uiinfo);\n",
+ data->component_name, data->real_wname);
+
+ /* Output the code to install the menu hints, if the GnomeApp has
+ a status bar. This must be output after the code to create the
+ GnomeAppBar is output, so we add it to the same buffer as the
+ signal connections. */
+ if (app->statusbar)
+ {
+ source_add_to_buffer (data, GLADE_SIGNAL_CONNECTIONS,
+ " gnome_app_install_menu_hints (GNOME_APP (%s), %s_uiinfo);\n",
+ data->component_name, data->real_wname);
+ }
+ }
+ else
+ {
+ BonoboDockPlacement placement;
+ BonoboDockItemBehavior behavior;
+ const gchar *placement_string;
+ gint idx, band_num, position, offset;
+ gchar *prefix, *prefix2;
+
+ if (gb_bonobo_dock_item_find_position (BONOBO_DOCK_ITEM (parent),
+ &placement, &band_num,
+ &position, &offset))
+ {
+ idx = glade_util_int_array_index (GladePlacementValues,
+ GladePlacementSize,
+ placement);
+ if (idx == -1)
+ {
+ g_warning ("BonoboDock placement not found");
+ placement = 0;
+ }
+ placement_string = GladePlacementSymbols[idx];
+
+ if (GTK_IS_TOOLBAR (child))
+ {
+ source_add (data,
+ " gnome_app_add_toolbar (GNOME_APP (%s), GTK_TOOLBAR (%s), %s,\n",
+ data->component_name, data->wname,
+ source_make_string (data->wname, FALSE));
+ }
+ else
+ {
+ source_add (data,
+ " gnome_app_add_docked (GNOME_APP (%s), %s, %s,\n",
+ data->component_name, data->wname,
+ source_make_string (data->wname, FALSE));
+ }
+
+ source_add (data, " ");
+ behavior = BONOBO_DOCK_ITEM (parent)->behavior;
+ prefix = "";
+ prefix2 = "\n | ";
+ if (behavior == BONOBO_DOCK_ITEM_BEH_NORMAL)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NORMAL", prefix);
+ }
+ else
+ {
+ if (behavior & BONOBO_DOCK_ITEM_BEH_EXCLUSIVE)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_EXCLUSIVE",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NEVER_FLOATING",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL",
+ prefix);
+ prefix = prefix2;
+ }
+ if (behavior & BONOBO_DOCK_ITEM_BEH_LOCKED)
+ {
+ source_add (data, "%sBONOBO_DOCK_ITEM_BEH_LOCKED",
+ prefix);
+ prefix = prefix2;
+ }
+ }
+
+ source_add (data,
+ ",\n"
+ " %s, %i, %i, %i);\n",
+ placement_string, band_num, position, offset);
+ }
+ }
+ }
+ else
+ {
+ g_warning ("Skipping adding dock item to parent - unimplemented.");
+ }
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_bonobo_dock_item_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = bonobo_dock_item_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = bonobo_dock_item_xpm;
+ gbwidget.tooltip = _("Gnome Dock Item");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_bonobo_dock_item_new;
+ gbwidget.gb_widget_create_from_widget = gb_bonobo_dock_item_create_from_widget;
+ gbwidget.gb_widget_add_child = gb_bonobo_dock_item_add_child;
+ gbwidget.gb_widget_create_popup_menu = gb_bonobo_dock_item_create_popup_menu;
+ gbwidget.gb_widget_create_properties = gb_bonobo_dock_item_create_properties;
+ gbwidget.gb_widget_get_properties = gb_bonobo_dock_item_get_properties;
+ gbwidget.gb_widget_set_properties = gb_bonobo_dock_item_set_properties;
+ gbwidget.gb_widget_write_source = gb_bonobo_dock_item_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_bonobo_dock_item_write_add_child_source;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeabout.c b/tools/glade/glade/gnome/gnomeabout.c
new file mode 100644
index 00000000..730f369e
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeabout.c
@@ -0,0 +1,554 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-about.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Logo = "GnomeAbout::logo";
+static gchar *Copyright = "GnomeAbout::copyright";
+static gchar *Comments = "GnomeAbout::comments";
+
+static gchar *Authors = "GnomeAbout::authors";
+static gchar *Documenters = "GnomeAbout::documenters";
+static gchar *TranslatorCredits = "GnomeAbout::translator_credits";
+
+static gchar *IconName = "GnomeAbout|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomeAbout|GtkWindow::focus_on_map";
+static gchar *DestroyWithParent = "GnomeAbout|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomeAbout|GtkWindow::icon";
+
+static gchar *Role = "GnomeAbout|GtkWindow::role";
+static gchar *TypeHint = "GnomeAbout|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomeAbout|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomeAbout|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomeAbout|GtkWindow::decorated";
+static gchar *Gravity = "GnomeAbout|GtkWindow::gravity";
+
+#define GLADE_TRANSLATORS_STRING "translator_credits"
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/* Pinched from gnome-about.c */
+#define GNOME_RESPONSE_CREDITS 1
+
+static void
+gb_gnome_about_response_cb (GtkDialog *dialog, gint response, gpointer data)
+{
+ /* We only let the response signal continue if it is going to show the
+ Credits sub-dialog. Otherwise we stop the signal. If the window close
+ button is pressed, our standard delete-event handler will hide the
+ dialog. But we must ensure the dialog isn't destroyed when it is closed.
+ */
+ if (response != GNOME_RESPONSE_CREDITS) {
+ g_signal_stop_emission_by_name (dialog, "response");
+ }
+}
+
+
+/*
+ * Creates a new GtkWidget of class GnomeAbout, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_about_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ gchar *project_name;
+ const gchar *authors[] = { NULL };
+
+ project_name = glade_project_get_name (data->project);
+ new_widget = gnome_about_new (project_name ? project_name : "",
+ "x.x", NULL, NULL, authors, authors, NULL, NULL);
+
+ /* We want it to be treated as a normal window. */
+ gtk_window_set_type_hint (GTK_WINDOW (new_widget),
+ GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ /* Make the About dialog modal by default. */
+ /* We can't do this in GNOME 2, as the Credits sub-dialog won't work. */
+ /*gtk_object_set_data (GTK_OBJECT (new_widget), Modal, "TRUE");*/
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "response",
+ GTK_SIGNAL_FUNC (gb_gnome_about_response_cb), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ /* Set the default comment string for the translator credits. */
+ glade_util_set_translation_properties (new_widget, TranslatorCredits,
+ TRUE, "TRANSLATORS: Replace this string with your names, one name per line.", FALSE);
+
+ return new_widget;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_about_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ IconName, FocusOnMap,
+ NULL, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, NULL);
+
+ property_add_filename (Logo, _("Logo:"), _("The pixmap to use as the logo"));
+ property_add_text (Copyright, _("Copyright:"), _("The copyright notice"), 2);
+ property_add_text (Comments, _("Comments:"), _("Additional information, such as a description of the package and its home page on the web"), 3);
+
+ property_add_text (Authors, _("Authors:"), _("The authors of the package, one on each line"), 2);
+ property_add_text (Documenters, _("Documenters:"), _("The documenters of the package, one on each line"), 2);
+ property_add_text (TranslatorCredits, _("Translators:"), _("The translators of the package. This should normally be left empty so that translators can add their names in the po files"), 2);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_about_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ char *translator_credits, *copyright, *comments, *translator_credits_output;
+
+ gb_window_get_standard_properties (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ IconName, FocusOnMap,
+ NULL, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, NULL);
+
+ g_object_get (G_OBJECT (widget),
+ "copyright", &copyright,
+ "comments", &comments,
+ "translator-credits", &translator_credits,
+ NULL);
+
+ gb_widget_output_pixmap_filename (data, Logo,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ Logo));
+ gb_widget_output_translatable_text (data, Copyright, copyright);
+ gb_widget_output_translatable_text (data, Comments, comments);
+
+ gb_widget_output_text (data, Authors,
+ gtk_object_get_data (GTK_OBJECT (widget), Authors));
+ gb_widget_output_text (data, Documenters,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ Documenters));
+
+ /* If we are saving, and translator_credits isn't set but is translatable,
+ we save the string "translator_credits". Translators can then
+ replace this with their own names in the po files. */
+ translator_credits_output = translator_credits;
+ if (data->action == GB_SAVING
+ && (!translator_credits || *translator_credits == '\0'))
+ {
+ gchar *comments_text;
+ gboolean translatable, context;
+
+ glade_util_get_translation_properties (widget, TranslatorCredits,
+ &translatable,
+ &comments_text, &context);
+ if (translatable)
+ translator_credits_output = GLADE_TRANSLATORS_STRING;
+ }
+
+ gb_widget_output_translatable_text (data, TranslatorCredits,
+ translator_credits_output);
+
+ g_free (copyright);
+ g_free (comments);
+ g_free (translator_credits);
+}
+
+static GValueArray *
+carray_from_text (GbWidgetSetArgData *data, GtkWidget *widget, const char *key)
+{
+ GValueArray *array = NULL;
+ char *str;
+
+ str = gb_widget_input_text (data, key);
+ if (data->apply)
+ {
+ char **strv;
+ int i;
+
+ gtk_object_set_data_full (GTK_OBJECT (widget), key, g_strdup (str),
+ str ? g_free : NULL);
+
+ strv = g_strsplit (str, "\n", 0);
+ array = g_value_array_new (0);
+
+ for (i = 0; strv[i]; i++) {
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, strv[i]);
+ array = g_value_array_append (array, &value);
+ }
+
+ g_strfreev (strv);
+ }
+ if (data->action == GB_APPLYING)
+ g_free (str);
+
+ return array;
+}
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_about_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GValueArray *authors, *documenters;
+ gchar *copyright, *comments, *translators;
+ gchar *filename, *old_filename;
+ GdkPixbuf *logo = NULL;
+ GObject *object;
+ gboolean redraw = FALSE;
+
+ object = G_OBJECT (widget);
+
+ gb_window_set_standard_properties (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ IconName, FocusOnMap,
+ NULL, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, NULL);
+
+ filename = gb_widget_input_pixmap_filename (data, Logo);
+ if (data->apply)
+ {
+ if (filename && filename[0] == '\0')
+ filename = NULL;
+
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), Logo);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), Logo,
+ g_strdup (filename), filename ? g_free : NULL);
+ glade_project_add_pixmap (data->project, filename);
+ logo = filename ? gdk_pixbuf_new_from_file (filename, NULL) : NULL;
+ g_object_set (object, "logo", logo, NULL);
+ if (logo)
+ g_object_unref (logo);
+ }
+ if (data->action == GB_LOADING)
+ g_free (filename);
+
+ copyright = gb_widget_input_text (data, Copyright);
+ if (data->apply)
+ {
+ g_object_set (object, "copyright", copyright, NULL);
+ redraw = TRUE;
+ }
+ if (data->action == GB_APPLYING)
+ g_free (copyright);
+
+ comments = gb_widget_input_text (data, Comments);
+ if (data->apply)
+ {
+ g_object_set (object, "comments", comments, NULL);
+ redraw = TRUE;
+ }
+ if (data->action == GB_APPLYING)
+ g_free (comments);
+
+
+ translators = gb_widget_input_text (data, TranslatorCredits);
+ if (data->apply)
+ {
+ if (!strcmp (translators, GLADE_TRANSLATORS_STRING))
+ g_object_set (object, "translator-credits", "", NULL);
+ else
+ g_object_set (object, "translator-credits", translators, NULL);
+ }
+ if (data->action == GB_APPLYING)
+ g_free (translators);
+
+ authors = carray_from_text (data, widget, Authors);
+ if (data->apply)
+ g_object_set (object, "authors", authors, NULL);
+ if (authors)
+ g_value_array_free (authors);
+
+ documenters = carray_from_text (data, widget, Documenters);
+ if (data->apply)
+ g_object_set (object, "documenters", documenters, NULL);
+ if (documenters)
+ g_value_array_free (documenters);
+
+ /* If the window is resized the selection rectangles mess it up, so we
+ queue a redraw. */
+ if (redraw)
+ gtk_widget_queue_draw (widget);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeAbout, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_about_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_about_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ gchar *project_name = glade_project_get_name (data->project);
+ char *copyright, *about_comments, *translators;
+ char *authors, **authorsv, *documenters, **documentersv;
+ gchar *logo_filename;
+ char *pixbuf_name = NULL;
+ gint i;
+ gboolean translatable, context;
+ gchar *comments;
+
+ g_object_get (G_OBJECT (widget),
+ "copyright", &copyright,
+ "comments", &about_comments,
+ "translator-credits", &translators,
+ NULL);
+
+ authors = gtk_object_get_data (GTK_OBJECT (widget), Authors);
+ documenters = gtk_object_get_data (GTK_OBJECT (widget), Documenters);
+
+ /* Output the array of authors. */
+ if (authors && *authors)
+ {
+ source_add_decl (data, " const gchar *authors[] = {\n");
+ authorsv = g_strsplit (authors, "\n", 0);
+ for (i = 0; authorsv[i]; i++)
+ {
+ if (authorsv[i][0])
+ source_add_decl (data, " %s,\n",
+ source_make_string (authorsv[i], FALSE));
+ }
+ source_add_decl (data, " NULL\n };\n");
+ g_strfreev (authorsv);
+ }
+ else
+ {
+ source_add_decl (data, " const gchar *authors[] = { NULL };\n");
+ }
+
+ /* Output the array of documenters. */
+ if (documenters && *documenters)
+ {
+ source_add_decl (data, " const gchar *documenters[] = {\n");
+ documentersv = g_strsplit (documenters, "\n", 0);
+ for (i = 0; documentersv[i]; i++)
+ {
+ if (documentersv[i][0])
+ source_add_decl (data, " %s,\n",
+ source_make_string (documentersv[i], FALSE));
+ }
+ source_add_decl (data, " NULL\n };\n");
+ g_strfreev (documentersv);
+ }
+ else
+ {
+ source_add_decl (data, " const gchar *documenters[] = { NULL };\n");
+ }
+
+ /* If translators is set, then we use that specific string.
+ If it is not set, then if gettext support is enabled we output code
+ to call gettext to translate the special "translator_credits" string,
+ and use that if it is translated. */
+ glade_util_get_translation_properties (widget, TranslatorCredits,
+ &translatable,
+ &comments, &context);
+ if (translators && translators[0])
+ {
+ source_add_translator_comments_to_buffer (data, GLADE_DECLARATIONS, translatable, comments);
+ source_add_decl (data, " gchar *translators = %s;\n",
+ source_make_string (translators, FALSE));
+ }
+ else if (data->use_gettext && translatable)
+ {
+ if (!comments || comments[0] == '\0')
+ comments = "TRANSLATORS: Replace this string with your names, one name per line.";
+
+ source_add_translator_comments_to_buffer (data, GLADE_DECLARATIONS,
+ translatable, comments);
+ source_add_decl (data,
+ " gchar *translators = _(\"%s\");\n",
+ GLADE_TRANSLATORS_STRING);
+
+ source_add (data,
+ " if (!strcmp (translators, \"%s\"))\n"
+ " translators = NULL;\n",
+ GLADE_TRANSLATORS_STRING);
+ }
+ else
+ {
+ source_add_decl (data, " gchar *translators = NULL;\n");
+ }
+
+ logo_filename = gtk_object_get_data (GTK_OBJECT (widget), Logo);
+ if (logo_filename && logo_filename[0])
+ {
+ pixbuf_name = g_strdup_printf ("%s_logo_pixbuf", data->wname);
+
+ source_add_decl (data, " GdkPixbuf *%s;\n", pixbuf_name);
+ source_create_pixbuf (data, pixbuf_name, logo_filename);
+ }
+
+ /* Now output the call to gnome_about_new(). We do it in pieces since
+ source_make_string() returns a pointer to a single static buffer. */
+ source_add (data,
+ " %s = gnome_about_new (%s, VERSION,\n",
+ data->wname,
+ source_make_string (project_name ? project_name : "",
+ FALSE));
+
+ glade_util_get_translation_properties (widget, Copyright, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " %s,\n",
+ source_make_string_full (copyright ? copyright : "",
+ data->use_gettext && translatable,
+ context));
+
+ glade_util_get_translation_properties (widget, Comments, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+ source_add (data,
+ " %s,\n",
+ source_make_string_full (about_comments ? about_comments : "",
+ data->use_gettext && translatable,
+ context));
+
+ source_add (data,
+ " authors,\n"
+ " documenters,\n"
+ " translators,\n");
+
+ source_add (data,
+ " %s);\n",
+ pixbuf_name ? pixbuf_name : "NULL");
+
+ g_free (pixbuf_name);
+ g_free (copyright);
+ g_free (about_comments);
+ g_free (translators);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_window_write_standard_source (widget, data,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ IconName, FocusOnMap,
+ NULL, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, NULL);
+}
+
+
+void
+gb_gnome_about_destroy (GtkWidget * widget,
+ GbWidgetDestroyData * data)
+{
+ gchar *filename;
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), Logo);
+ glade_project_remove_pixmap (data->project, filename);
+
+ gb_window_destroy (widget, data);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_about_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_about_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_about_xpm;
+ gbwidget.tooltip = _("Gnome About Dialog");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_about_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_about_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_about_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_about_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_about_write_source;
+ gbwidget.gb_widget_destroy = gb_gnome_about_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_about_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeapp.c b/tools/glade/glade/gnome/gnomeapp.c
new file mode 100644
index 00000000..3835f6d8
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeapp.c
@@ -0,0 +1,461 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../tree.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-app.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+static gchar *Title = "GnomeApp|GtkWindow::title";
+static gchar *Type = "GnomeApp|GtkWindow::type";
+static gchar *Position = "GnomeApp|GtkWindow::window_position";
+static gchar *Modal = "GnomeApp|GtkWindow::modal";
+static gchar *DefaultWidth = "GnomeApp|GtkWindow::default_width";
+static gchar *DefaultHeight = "GnomeApp|GtkWindow::default_height";
+static gchar *Shrink = "GnomeAppl|GtkWindow::allow_shrink";
+static gchar *Grow = "GnomeApp|GtkWindow::allow_grow";
+static gchar *AutoShrink = "GnomeApp|GtkWindow::auto_shrink";
+static gchar *IconName = "GnomeApp|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomeApp|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "GnomeApp|GtkWindow::resizable";
+static gchar *DestroyWithParent = "GnomeApp|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomeApp|GtkWindow::icon";
+
+static gchar *Role = "GnomeApp|GtkWindow::role";
+static gchar *TypeHint = "GnomeApp|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomeApp|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomeApp|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomeApp|GtkWindow::decorated";
+static gchar *Gravity = "GnomeApp|GtkWindow::gravity";
+static gchar *Urgency = "GnomeApp|GtkWindow::urgency_hint";
+
+/* This is kept as object data as we don't want config info written when it is
+ used in Glade. */
+static gchar *EnableLayoutConfig = "GnomeApp::enable_layout_config";
+
+/* This is only used within Glade. We don't save or load it, since the
+ appbar will be saved on its own if it has been added. */
+static gchar *StatusBar = "GnomeApp::status_bar";
+
+
+static void gb_gnome_app_setup_initial_app (GtkWidget *widget);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeApp, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_app_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ gchar *project_name;
+
+ project_name = glade_project_get_name (data->project);
+ new_widget = gnome_app_new (project_name ? project_name : "", project_name);
+ gtk_object_set_data (GTK_OBJECT (new_widget), EnableLayoutConfig,
+ GINT_TO_POINTER (TRUE));
+
+ /* Turn off the automatic loading/saving of the configuration, and
+ destroy the BonoboDockLayout, so that when items are added they are
+ added straight away. If we don't do this, items don't get added to
+ the widget tree. */
+ gnome_app_enable_layout_config (GNOME_APP (new_widget), FALSE);
+ g_object_unref (G_OBJECT (GNOME_APP (new_widget)->layout));
+ GNOME_APP (new_widget)->layout = NULL;
+
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gb_widget_create_from (GNOME_APP (new_widget)->dock,
+ data->action == GB_CREATING ? "BonoboDock" : NULL);
+ gb_widget_set_child_name (GNOME_APP (new_widget)->dock, GladeChildGnomeAppDock);
+
+ if (data->action == GB_CREATING)
+ gb_gnome_app_setup_initial_app (new_widget);
+
+ return new_widget;
+}
+
+
+static void
+gb_gnome_app_add_toolbar_button (GtkToolbar *toolbar,
+ const gchar *stock_id,
+ const gchar *tooltip)
+{
+ GtkWidget *button;
+ GladeWidgetData *wdata;
+
+ button = gb_widget_new ("GtkToolButton", NULL);
+
+ gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (button), stock_id);
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (button), NULL);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), NULL);
+
+ gtk_object_set_data_full (GTK_OBJECT (button),
+ GladeToolButtonStockIDKey,
+ g_strdup (stock_id), g_free);
+
+ wdata = gtk_object_get_data (GTK_OBJECT (button), GB_WIDGET_DATA_KEY);
+ wdata->tooltip = g_strdup (tooltip);
+
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), -1);
+}
+
+
+static void
+gb_gnome_app_setup_initial_app (GtkWidget *widget)
+{
+ GtkWidget *placeholder, *toolbar;
+
+ /* We create a standard menubar and toolbar which the user can edit or
+ simply delete anything they don't want. */
+ glade_gnome_setup_initial_menus (widget);
+
+ /* We need to get rid of the accelerators, since they aren't used, and
+ they would override our default accelerators. */
+ gtk_window_remove_accel_group (GTK_WINDOW (widget),
+ GNOME_APP (widget)->accel_group);
+
+ /* FIXME: GnomeLibs bug workaround. It sets the initial border width
+ to -2, which causes us lots of problems. */
+#if 0
+ gtk_container_set_border_width (GTK_CONTAINER (GNOME_APP (widget)->menubar),
+ 0);
+#endif
+ gb_widget_create_from (GNOME_APP (widget)->menubar, "GtkMenubar");
+ gb_widget_create_from (GNOME_APP (widget)->menubar->parent, "BonoboDockItem");
+
+ /* Toolbar */
+ toolbar = gtk_toolbar_new ();
+ gnome_app_set_toolbar (GNOME_APP (widget), GTK_TOOLBAR (toolbar));
+ gb_widget_create_from (toolbar, "GtkToolbar");
+ gb_widget_create_from (toolbar->parent, "BonoboDockItem");
+
+ gb_gnome_app_add_toolbar_button (GTK_TOOLBAR (toolbar), GTK_STOCK_NEW,
+ _("New File"));
+ gb_gnome_app_add_toolbar_button (GTK_TOOLBAR (toolbar), GTK_STOCK_OPEN,
+ _("Open File"));
+ gb_gnome_app_add_toolbar_button (GTK_TOOLBAR (toolbar), GTK_STOCK_SAVE,
+ _("Save File"));
+
+
+ /* Statusbar */
+ gnome_app_set_statusbar (GNOME_APP (widget),
+ gb_widget_new ("GnomeAppBar", widget));
+ gb_widget_set_child_name (GNOME_APP (widget)->statusbar, GladeChildGnomeAppBar);
+
+ /* We need to size the placeholders or the dialog is very small. */
+ placeholder = editor_new_placeholder ();
+ gtk_widget_set_usize (placeholder, 300, 200);
+ gnome_app_set_contents (GNOME_APP (widget), placeholder);
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_app_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ property_add_bool (StatusBar, _("Status Bar:"),
+ _("If the window has a status bar"));
+ property_add_bool (EnableLayoutConfig, _("Store Config:"),
+ _("If the layout is saved and restored automatically"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_app_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (data->action == GB_SHOWING)
+ {
+ gb_widget_output_bool (data, StatusBar,
+ GNOME_APP (widget)->statusbar != NULL
+ ? TRUE : FALSE);
+ }
+
+ gb_widget_output_bool (data, EnableLayoutConfig, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), EnableLayoutConfig)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_app_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean statusbar, enable_layout_config;
+
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (data->action == GB_APPLYING)
+ {
+ statusbar = gb_widget_input_bool (data, StatusBar);
+ if (data->apply)
+ {
+ if (statusbar)
+ {
+ if (!GNOME_APP (widget)->statusbar)
+ {
+ gnome_app_set_statusbar (GNOME_APP (widget),
+ gb_widget_new ("GnomeAppBar",
+ widget));
+ gb_widget_set_child_name (GNOME_APP (widget)->statusbar,
+ GladeChildGnomeAppBar);
+ tree_add_widget (GNOME_APP (widget)->statusbar);
+ }
+ }
+ else
+ {
+ if (GNOME_APP (widget)->statusbar)
+ {
+ /* This is not very clean, but there's no proper way to
+ remove the statusbar. The statusbar has an hbox inserted
+ above it which is added to the GnomeApp's vbox, so we
+ remove the hbox. */
+ GtkWidget *hbox = GNOME_APP (widget)->statusbar->parent;
+ gtk_container_remove (GTK_CONTAINER (hbox->parent), hbox);
+ GNOME_APP (widget)->statusbar = NULL;
+ }
+ }
+ }
+ }
+
+ enable_layout_config = gb_widget_input_bool (data, EnableLayoutConfig);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), EnableLayoutConfig,
+ GINT_TO_POINTER (enable_layout_config));
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeApp, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_app_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_app_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *appname;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ appname = glade_project_get_name (data->project);
+ appname = appname ? source_make_string (appname, FALSE) : "\"\"";
+ appname = g_strdup (appname);
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ /* Note that this assumes that we use the same appname for each GnomeApp.
+ FIXME: I think this is correct, but I'm not sure.
+ Note also that we don't translate the project name. Maybe we should.*/
+ source_add (data, " %s = gnome_app_new (%s, %s);\n", data->wname,
+ appname,
+ GTK_WINDOW (widget)->title
+ ? source_make_string_full (GTK_WINDOW (widget)->title,
+ data->use_gettext && translatable,
+ context)
+ : "NULL");
+ g_free (appname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (!GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ EnableLayoutConfig)))
+ {
+ source_add (data,
+ " gnome_app_enable_layout_config (GNOME_APP (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+/* Outputs source to add a child menu to a GnomeApp. */
+static void
+gb_gnome_app_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *child_name;
+
+ child_name = gb_widget_get_child_name (child);
+
+ if (child_name && (!strcmp (child_name, GladeChildGnomeAppBar)))
+ {
+ source_add (data,
+ " gnome_app_set_statusbar (GNOME_APP (%s), %s);\n",
+ parent_name, data->wname);
+ }
+ else
+ {
+ g_warning ("Adding unknown child to a GnomeApp: %s", data->wname);
+ source_add (data, " gtk_container_add (GTK_CONTAINER (%s), %s);\n",
+ parent_name, data->wname);
+ }
+}
+
+
+static void
+gb_gnome_app_add_child (GtkWidget *widget, GtkWidget * child,
+ GbWidgetSetArgData *data)
+{
+ gchar *child_name = NULL;
+
+ if (data->child_info)
+ child_name = data->child_info->internal_child;
+
+ if (child_name && (!strcmp (child_name, GladeChildGnomeAppBar)))
+ {
+ gnome_app_set_statusbar (GNOME_APP (widget), child);
+ }
+}
+
+
+static GtkWidget *
+gb_gnome_app_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildGnomeAppDock))
+ return GNOME_APP (widget)->dock;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_app_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_app_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_app_xpm;
+ gbwidget.tooltip = _("Gnome Application Window");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_app_new;
+ gbwidget.gb_widget_add_child = gb_gnome_app_add_child;
+ gbwidget.gb_widget_get_child = gb_gnome_app_get_child;
+ gbwidget.gb_widget_create_properties = gb_gnome_app_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_app_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_app_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_app_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_gnome_app_write_add_child_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_app_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeappbar.c b/tools/glade/glade/gnome/gnomeappbar.c
new file mode 100644
index 00000000..fe9b6afd
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeappbar.c
@@ -0,0 +1,198 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-appbar.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HasProgress = "GnomeApp::has_progress";
+static gchar *HasStatus = "GnomeApp::has_status";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeAppBar, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_appbar_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gnome_appbar_new (TRUE, TRUE, GNOME_PREFERENCES_NEVER);
+
+ gnome_appbar_set_status (GNOME_APPBAR (new_widget), _("Status Message."));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_appbar_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (HasProgress, _("Progress:"),
+ _("If the app bar has a progress indicator"));
+ property_add_bool (HasStatus, _("Status:"),
+ _("If the app bar has an area for status messages and user input"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_appbar_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, HasProgress,
+ GTK_WIDGET_VISIBLE (gnome_appbar_get_progress (GNOME_APPBAR (widget))));
+ gb_widget_output_bool (data, HasStatus,
+ GTK_WIDGET_VISIBLE (gnome_appbar_get_status (GNOME_APPBAR (widget))));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_appbar_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean has_progress, has_status;
+
+ has_progress = gb_widget_input_bool (data, HasProgress);
+ if (data->apply)
+ {
+ if (has_progress)
+ gtk_widget_show (GTK_WIDGET (gnome_appbar_get_progress (GNOME_APPBAR (widget))));
+ else
+ gtk_widget_hide (GTK_WIDGET (gnome_appbar_get_progress (GNOME_APPBAR (widget))));
+ }
+
+ has_status = gb_widget_input_bool (data, HasStatus);
+ if (data->apply)
+ {
+ if (has_status)
+ gtk_widget_show (gnome_appbar_get_status (GNOME_APPBAR (widget)));
+ else
+ gtk_widget_hide (gnome_appbar_get_status (GNOME_APPBAR (widget)));
+
+ /* We need to clear the selection or redrawing is messed up. */
+ editor_clear_selection (NULL);
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeAppBar, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_appbar_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_appbar_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = gnome_appbar_new (%s, %s, GNOME_PREFERENCES_NEVER);\n",
+ data->wname,
+ GTK_WIDGET_VISIBLE (gnome_appbar_get_progress (GNOME_APPBAR (widget)))
+ ? "TRUE" : "FALSE",
+ GTK_WIDGET_VISIBLE (gnome_appbar_get_status (GNOME_APPBAR (widget)))
+ ? "TRUE" : "FALSE");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* If the GnomeAppBar is in a GnomeApp, the code to install the menu hints
+ is output in gnomedockitem.c. */
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_appbar_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_appbar_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_appbar_xpm;
+ gbwidget.tooltip = _("Gnome Application Bar");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_appbar_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_appbar_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_appbar_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_appbar_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_appbar_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_appbar_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomecanvas.c b/tools/glade/glade/gnome/gnomecanvas.c
new file mode 100644
index 00000000..2f757be5
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomecanvas.c
@@ -0,0 +1,263 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-canvas.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *AntiAliased = "GnomeCanvas::aa";
+static gchar *ScrollX1 = "GnomeCanvas::scroll_x1";
+static gchar *ScrollY1 = "GnomeCanvas::scroll_y1";
+static gchar *ScrollX2 = "GnomeCanvas::scroll_x2";
+static gchar *ScrollY2 = "GnomeCanvas::scroll_y2";
+static gchar *PixelsPerUnit = "GnomeCanvas::pixels_per_unit";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeCanvas, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+/*
+static GtkWidget*
+gb_gnome_canvas_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_canvas_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (AntiAliased, _("Anti-Aliased:"),
+ _("If the canvas is anti-aliased, to smooth the edges of text and graphics"));
+ property_add_float (ScrollX1, _("X1:"), _("The minimum x coordinate"));
+ property_add_float (ScrollY1, _("Y1:"), _("The minimum y coordinate"));
+ property_add_float (ScrollX2, _("X2:"), _("The maximum x coordinate"));
+ property_add_float (ScrollY2, _("Y2:"), _("The maximum y coordinate"));
+
+ property_add_float (PixelsPerUnit, _("Pixels Per Unit:"),
+ _("The number of pixels corresponding to one unit"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_canvas_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, AntiAliased,
+ GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), AntiAliased)));
+
+ gb_widget_output_float (data, ScrollX1, GNOME_CANVAS (widget)->scroll_x1);
+ gb_widget_output_float (data, ScrollY1, GNOME_CANVAS (widget)->scroll_y1);
+ gb_widget_output_float (data, ScrollX2, GNOME_CANVAS (widget)->scroll_x2);
+ gb_widget_output_float (data, ScrollY2, GNOME_CANVAS (widget)->scroll_y2);
+
+ gb_widget_output_float (data, PixelsPerUnit,
+ GNOME_CANVAS (widget)->pixels_per_unit);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_canvas_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean antialiased;
+ gfloat value;
+ gfloat scroll_x1, scroll_y1, scroll_x2, scroll_y2;
+ gfloat old_scroll_x1, old_scroll_y1, old_scroll_x2, old_scroll_y2;
+ gfloat pixels_per_unit;
+
+ antialiased = gb_widget_input_bool (data, AntiAliased);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), AntiAliased,
+ GINT_TO_POINTER (antialiased));
+
+ /* Also check for the old name we used for this. */
+ if (data->action == GB_LOADING)
+ {
+ antialiased = gb_widget_input_bool (data, "anti_aliased");
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), AntiAliased,
+ GINT_TO_POINTER (antialiased));
+ }
+
+ scroll_x1 = old_scroll_x1 = GNOME_CANVAS (widget)->scroll_x1;
+ scroll_y1 = old_scroll_y1 = GNOME_CANVAS (widget)->scroll_y1;
+ scroll_x2 = old_scroll_x2 = GNOME_CANVAS (widget)->scroll_x2;
+ scroll_y2 = old_scroll_y2 = GNOME_CANVAS (widget)->scroll_y2;
+
+ value = gb_widget_input_float (data, ScrollX1);
+ if (data->apply)
+ scroll_x1 = value;
+ value = gb_widget_input_float (data, ScrollY1);
+ if (data->apply)
+ scroll_y1 = value;
+ value = gb_widget_input_float (data, ScrollX2);
+ if (data->apply)
+ scroll_x2 = value;
+ value = gb_widget_input_float (data, ScrollY2);
+ if (data->apply)
+ scroll_y2 = value;
+
+ if (scroll_x1 != old_scroll_x1 || scroll_y1 != old_scroll_y1
+ || scroll_x2 != old_scroll_x2 || scroll_y2 != old_scroll_y2)
+ {
+ gnome_canvas_set_scroll_region (GNOME_CANVAS (widget),
+ scroll_x1, scroll_y1,
+ scroll_x2, scroll_y2);
+ }
+
+ pixels_per_unit = gb_widget_input_float (data, PixelsPerUnit);
+ if (data->apply)
+ gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (widget), pixels_per_unit);
+}
+
+
+/*
+ * Sets the properties for the child widget specific to this type of
+ * parent widget.
+ */
+/*
+static void
+gb_gnome_canvas_set_child_props (GtkWidget * widget, GtkWidget * child, GbWidgetSetArgData * data)
+{
+
+}
+*/
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeCanvas, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_canvas_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_canvas_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ if (gtk_object_get_data (GTK_OBJECT (widget), AntiAliased))
+ {
+ source_add (data,
+ " %s = gnome_canvas_new_aa ();\n",
+ data->wname);
+ }
+ else
+ {
+ source_add (data,
+ " %s = gnome_canvas_new ();\n",
+ data->wname);
+ }
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ source_add (data,
+ " gnome_canvas_set_scroll_region (GNOME_CANVAS (%s), %g, %g, %g, %g);\n",
+ data->wname,
+ GNOME_CANVAS (widget)->scroll_x1,
+ GNOME_CANVAS (widget)->scroll_y1,
+ GNOME_CANVAS (widget)->scroll_x2,
+ GNOME_CANVAS (widget)->scroll_y2);
+
+ if (GNOME_CANVAS (widget)->pixels_per_unit != 1.0)
+ source_add (data,
+ " gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (%s), %g);\n",
+ data->wname,
+ GNOME_CANVAS (widget)->pixels_per_unit);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_canvas_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_canvas_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_canvas_xpm;
+ gbwidget.tooltip = _("GnomeCanvas");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_gnome_canvas_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_canvas_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_canvas_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_canvas_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_canvas_new;
+ gbwidget.gb_widget_set_child_props = gb_gnome_canvas_set_child_props;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_canvas_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomecolorpicker.c b/tools/glade/glade/gnome/gnomecolorpicker.c
new file mode 100644
index 00000000..346bdec8
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomecolorpicker.c
@@ -0,0 +1,233 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-colorpicker.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Dither = "GnomeColorPicker::dither";
+static gchar *UseAlpha = "GnomeColorPicker::use_alpha";
+static gchar *Title = "GnomeColorPicker::title";
+static gchar *FocusOnClick = "GnomeColorPicker|GtkButton::focus_on_click";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeColorPicker, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+static GtkWidget*
+gb_gnome_color_picker_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_color_picker_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Dither, _("Dither:"),
+ _("If the sample should use dithering to be more accurate"));
+ property_add_bool (UseAlpha, _("Use Alpha:"),
+ _("If the alpha channel should be used"));
+
+ property_add_string (Title, _("Title:"),
+ _("The title of the color selection dialog"));
+
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_color_picker_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_bool (data, Dither, gnome_color_picker_get_dither (GNOME_COLOR_PICKER (widget)));
+ gb_widget_output_bool (data, UseAlpha,
+ gnome_color_picker_get_use_alpha (GNOME_COLOR_PICKER (widget)));
+ gb_widget_output_translatable_string (data, Title,
+ gnome_color_picker_get_title (GNOME_COLOR_PICKER (widget)));
+
+ gb_widget_output_bool (data, FocusOnClick,
+ gtk_button_get_focus_on_click (GTK_BUTTON (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_color_picker_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean dither, use_alpha, focus_on_click;
+ gchar *title;
+
+ dither = gb_widget_input_bool (data, Dither);
+ if (data->apply)
+ gnome_color_picker_set_dither (GNOME_COLOR_PICKER (widget), dither);
+
+ use_alpha = gb_widget_input_bool (data, UseAlpha);
+ if (data->apply)
+ gnome_color_picker_set_use_alpha (GNOME_COLOR_PICKER (widget), use_alpha);
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ gnome_color_picker_set_title (GNOME_COLOR_PICKER (widget), title);
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_button_set_focus_on_click (GTK_BUTTON (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeColorPicker, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_color_picker_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_color_picker_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_color_picker_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (strcmp (gnome_color_picker_get_title (GNOME_COLOR_PICKER (widget)),
+ dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE, "Pick a color")))
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_color_picker_set_title (GNOME_COLOR_PICKER (%s), %s);\n",
+ data->wname,
+ source_make_string_full (gnome_color_picker_get_title (GNOME_COLOR_PICKER (widget)),
+ data->use_gettext && translatable,
+ context));
+ }
+
+ if (!gnome_color_picker_get_dither (GNOME_COLOR_PICKER (widget)))
+ {
+ source_add (data,
+ " gnome_color_picker_set_dither (GNOME_COLOR_PICKER (%s), FALSE);\n",
+ data->wname);
+
+ }
+
+ if (gnome_color_picker_get_use_alpha (GNOME_COLOR_PICKER (widget)))
+ {
+ source_add (data,
+ " gnome_color_picker_set_use_alpha (GNOME_COLOR_PICKER (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (!gtk_button_get_focus_on_click (GTK_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_button_set_focus_on_click (GTK_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_color_picker_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_color_picker_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_colorpicker_xpm;
+ gbwidget.tooltip = _("Gnome Color Picker");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_gnome_color_picker_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_color_picker_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_color_picker_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_color_picker_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_color_picker_new;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_color_picker_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomecontrol.c b/tools/glade/glade/gnome/gnomecontrol.c
new file mode 100644
index 00000000..5744fda9
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomecontrol.c
@@ -0,0 +1,757 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Glade only shows Bonobo controls which have a 'glade:show' attribute set
+ * to TRUE, e.g. with this in their .server file:
+ *
+ * <oaf_attribute name="glade:show" type="boolean" value="TRUE"/>
+ *
+ */
+
+#include <config.h>
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkspinbutton.h>
+
+#include "../gb.h"
+#include "../palette.h"
+
+#include <bonobo.h>
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-control.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* This is the key we use to store a pointer to the bonobo widget's property
+ bag. */
+static gchar *GladePropertyBagKey = "GladePropertyBagKey";
+
+/* This is the Moniker property which stores the type of control. It is saved
+ in the XML. */
+const gchar *Moniker = "BonoboWidget::moniker";
+
+
+static GbWidget *control_get_gb_widget (const char *obj_id);
+
+
+/****************************************************************************
+ * This is the dummy GbWidget we put in the palette. It only contains a
+ * new() function to create Bonobo controls. We create a GbWidget for each
+ * type of control when needed, and it is that that contains functions to
+ * create/get/set properties.
+ ****************************************************************************/
+
+/* Columns in the GtkTreeView for selecting the type of control. */
+enum {
+ COL_OBJID,
+ COL_DESC,
+ COL_LAST
+};
+
+static GtkWidget *
+control_create (GbWidgetNewData * data, char *obj_id, Bonobo_UIContainer uic)
+{
+ GtkWidget *widget;
+ BonoboControlFrame *cf;
+ Bonobo_PropertyBag pb;
+
+ g_return_val_if_fail (obj_id != NULL, NULL);
+
+ widget = bonobo_widget_new_control (obj_id, uic);
+
+ g_return_val_if_fail (widget != NULL, NULL);
+ cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
+
+ if (!cf) {
+ g_warning ("Control has no frame!");
+ gtk_widget_destroy (widget);
+
+ return NULL;
+ }
+
+ pb = bonobo_control_frame_get_control_property_bag (cf, NULL);
+
+ gtk_object_set_data (GTK_OBJECT (widget), GladePropertyBagKey, pb);
+ gtk_object_set_data (GTK_OBJECT (widget), Moniker, g_strdup (obj_id));
+
+ /* Make sure the GbWidget for this control is created & registered,
+ and set the real GbWidget for this control. */
+ data->widget_data->gbwidget = control_get_gb_widget (obj_id);
+
+ return widget;
+}
+
+static Bonobo_PropertyBag
+control_get_pb (GtkWidget *widget)
+{
+ return gtk_object_get_data (GTK_OBJECT (widget),
+ GladePropertyBagKey);
+}
+
+static Bonobo_UIContainer
+widget_get_uic (GtkWidget *widget)
+{
+ GtkWidget *top;
+
+ top = gtk_widget_get_toplevel (widget);
+
+ if (!BONOBO_IS_WINDOW (top))
+ return CORBA_OBJECT_NIL;
+
+ /* FIXME: Should we unref this somewhere? */
+ return (Bonobo_UIContainer) BONOBO_OBJREF (bonobo_window_get_ui_container (BONOBO_WINDOW (top)));
+}
+
+static void
+on_control_dialog_ok (GtkWidget *widget,
+ GbWidgetNewData *data)
+{
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *dialog;
+ GtkTreeSelection *selection;
+ char *moniker;
+ GtkWidget *new_widget;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ view = g_object_get_data (G_OBJECT (dialog), "tree_view");
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ gtk_tree_selection_get_selected (selection, &model, &iter);
+ gtk_tree_model_get (model, &iter, COL_OBJID, &moniker, -1);
+
+ new_widget = control_create (data, moniker, widget_get_uic (data->parent));
+ if (new_widget)
+ {
+ gb_widget_initialize (new_widget, data);
+ data->callback (new_widget, data);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't create the Bonobo control"),
+ NULL);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+on_control_dialog_destroy (GtkWidget *widget,
+ GbWidgetNewData *data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+static GtkListStore *
+do_query (void)
+{
+ GtkListStore *store;
+ Bonobo_ServerInfoList *servers;
+#if 0
+ /* This is the old query, but too many components are not generally useful
+ and cause problems, so we are changing to an 'opt-in' query, where
+ we only include components that have a 'glade:show' property set to TRUE.
+ */
+ const char *query = "repo_ids.has('IDL:Bonobo/Control:1.0') AND NOT "
+ "repo_ids.has('IDL:GNOME/Vertigo/PanelAppletShell:1.0')";
+#else
+ const char *query = "glade:show";
+#endif
+ char *sort[] = { "description", NULL };
+ CORBA_Environment ev;
+ int i;
+
+ Bonobo_ServerInfo *serverinfo;
+ const char *desc;
+ GtkTreeIter iter;
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+
+ CORBA_exception_init (&ev);
+
+ servers = bonobo_activation_query (query, sort, &ev);
+ if (BONOBO_EX (&ev)) {
+ g_warning ("query failed: %s\n", ev._id);
+ CORBA_exception_free (&ev);
+ return store;
+ }
+ CORBA_exception_free (&ev);
+
+#if 0
+ g_print ("got %d servers.\n", servers ? servers->_length : 0);
+#endif
+
+ for (i = 0; i < servers->_length; i++) {
+ serverinfo = &servers->_buffer[i];
+
+ desc = bonobo_server_info_prop_lookup (serverinfo, "description", NULL);
+ if (!desc)
+ desc = bonobo_server_info_prop_lookup (serverinfo, "name", NULL);
+ if (!desc)
+ desc = serverinfo->iid;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_OBJID, serverinfo->iid,
+ COL_DESC, desc,
+ -1);
+ }
+
+ CORBA_free (servers);
+
+ return store;
+}
+
+static void
+on_list_selection_changed (GtkTreeSelection *selection, GtkDialog *dialog)
+{
+ gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK,
+ gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static void
+show_control_dialog (GbWidgetNewData *data)
+{
+ GtkWidget *dialog, *vbox, *label, *list, *scroll;
+ GtkListStore *store;
+ GtkCellRenderer *ren;
+
+ dialog = glade_util_create_dialog (_("New Bonobo Control"), data->parent,
+ GTK_SIGNAL_FUNC (on_control_dialog_ok),
+ data, &vbox);
+ g_object_set (G_OBJECT (dialog),
+ "resizable", TRUE,
+ "default-width", 400,
+ "default-height", 300,
+ NULL);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK, FALSE);
+ g_signal_connect (dialog, "destroy",
+ G_CALLBACK (on_control_dialog_destroy), data);
+
+ label = gtk_label_new (_("Select a Bonobo Control"));
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ scroll = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
+ "hadjustment", NULL,
+ "vadjustment", NULL,
+ "shadow-type", GTK_SHADOW_ETCHED_IN,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
+
+ store = do_query ();
+
+ list = g_object_new (GTK_TYPE_TREE_VIEW,
+ "model", store,
+ "headers-visible", FALSE,
+ NULL);
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (list)),
+ "changed",
+ G_CALLBACK (on_list_selection_changed), dialog);
+
+ g_object_unref (store);
+
+ ren = gtk_cell_renderer_text_new ();
+
+#if 0
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list),
+ -1, _("OAFIID"), ren,
+ "text", COL_OBJID,
+ NULL);
+#endif
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list),
+ -1, _("Description"), ren,
+ "text", COL_DESC,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (scroll), list);
+
+ g_object_set_data (G_OBJECT (dialog), "tree_view", list);
+
+ gtk_widget_show_all (dialog);
+ gtk_grab_add (dialog);
+}
+
+static GtkWidget *
+gb_bonobo_control_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING) {
+ char *moniker;
+
+ moniker = load_string (data->loading_data, Moniker);
+
+ new_widget = control_create (data, moniker, widget_get_uic (data->parent));
+
+ return new_widget;
+ } else {
+ show_control_dialog (data);
+ return NULL;
+ }
+}
+
+/*
+ * Initializes the GbWidget structure.
+ */
+GbWidget *
+gb_bonobo_control_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = BONOBO_TYPE_WIDGET;
+
+ gb_widget_init_struct (&gbwidget);
+
+ gbwidget.pixmap_struct = gnome_control_xpm;
+ gbwidget.tooltip = _("Bonobo Control");
+
+ gbwidget.gb_widget_new = gb_bonobo_control_new;
+
+ return &gbwidget;
+}
+
+
+/****************************************************************************
+ * This is the GbWidget that will be created for each type of control.
+ ****************************************************************************/
+
+/* We use the moniker to ensure the property names are unique in the property
+ editor. */
+static char *
+create_prop_name (const char *moniker, const char *txt)
+{
+ return g_strconcat (moniker, "::", txt, NULL);
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_bonobo_control_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ Bonobo_PropertyBag pb = control_get_pb (widget);
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ GList *key_list, *names;
+
+ g_assert (moniker);
+
+ if (!pb)
+ return;
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+ char *title, *doc;
+ char *prop = create_prop_name (moniker, names->data);
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ title = bonobo_pbclient_get_doc_title (pb, names->data, NULL);
+ doc = bonobo_pbclient_get_doc (pb, names->data, NULL);
+
+ switch (tc->kind) {
+ case CORBA_tk_boolean:
+ property_add_bool (prop, title, doc);
+ break;
+ case CORBA_tk_string:
+ property_add_string (prop, title, doc);
+ break;
+ case CORBA_tk_short:
+ case CORBA_tk_ushort:
+ /* FIXME: _int_range() ? */
+ property_add_int (prop, title, doc);
+ break;
+ case CORBA_tk_double:
+ case CORBA_tk_float:
+ property_add_float (prop, title, doc);
+ break;
+ case CORBA_tk_ulong:
+ case CORBA_tk_long:
+ property_add_int (prop, title, doc);
+ break;
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+ g_free (prop);
+ CORBA_free (title);
+ CORBA_free (doc);
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_bonobo_control_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ Bonobo_PropertyBag pb = control_get_pb (widget);
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ GList *key_list, *names;
+
+ g_assert (moniker);
+
+ if (!pb)
+ return;
+
+ /* We save the moniker in the XML, though we don't show it in the property
+ editor. */
+ if (data->action == GB_SAVING)
+ {
+ save_string (data, Moniker, moniker);
+ }
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+ char *prop = create_prop_name (moniker, names->data);
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ switch (tc->kind) {
+ case CORBA_tk_boolean:
+ gb_widget_output_bool (data, prop,
+ bonobo_pbclient_get_boolean (pb, names->data, NULL));
+ break;
+ case CORBA_tk_string:
+ {
+ char *str = bonobo_pbclient_get_string (pb, names->data, NULL);
+
+ gb_widget_output_translatable_string (data, prop, str);
+
+ g_free (str);
+ break;
+ }
+ case CORBA_tk_ulong:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_ulong (pb, names->data, NULL));
+ break;
+ case CORBA_tk_long:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_long (pb, names->data, NULL));
+ break;
+ case CORBA_tk_short:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_short (pb, names->data, NULL));
+ break;
+ case CORBA_tk_ushort:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_ushort (pb, names->data, NULL));
+ break;
+ case CORBA_tk_float:
+ gb_widget_output_float (data, prop,
+ bonobo_pbclient_get_float (pb, names->data, NULL));
+ break;
+ case CORBA_tk_double:
+ gb_widget_output_float (data, prop,
+ bonobo_pbclient_get_double (pb, names->data, NULL));
+ break;
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+ g_free (prop);
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_bonobo_control_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ Bonobo_PropertyBag pb = control_get_pb (widget);
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ GList *key_list, *names;
+
+ g_assert (moniker);
+
+ if (!pb)
+ return;
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+ char *prop = create_prop_name (moniker, names->data);
+
+#if 0
+ g_print ("Checking property: %s\n", prop);
+#endif
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ switch (tc->kind) {
+ case CORBA_tk_boolean:
+ {
+ gboolean val;
+
+ val = gb_widget_input_bool (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_boolean (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_string:
+ {
+ const char *str;
+
+ str = gb_widget_input_string (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_string (pb, names->data, str, NULL);
+
+ break;
+ }
+ case CORBA_tk_float:
+ {
+ gfloat val;
+
+ val = gb_widget_input_float (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_float (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_double:
+ {
+ gdouble val;
+
+ val = gb_widget_input_float (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_double (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_long:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_long (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_ulong:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_ulong (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_short:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_short (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_ushort:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_ushort (pb, names->data, val, NULL);
+ break;
+ }
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+ g_free (prop);
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_bonobo_control_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ BonoboControlFrame *cf;
+ Bonobo_PropertyBag pb;
+ GList *key_list, *names;
+
+ if (data->create_widget)
+ {
+ /* Currently we don't support BonoboWindow, so it will always be NIL,
+ but if we ever do, then it just needs to set bonobo_uic when it is
+ created. */
+ source_ensure_decl (data, " Bonobo_UIContainer bonobo_uic = CORBA_OBJECT_NIL;\n");
+ source_add (data,
+ " %s = bonobo_widget_new_control (%s, bonobo_uic);\n",
+ data->wname,
+ source_make_string (moniker, FALSE));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
+ if (!cf)
+ return;
+
+ pb = bonobo_control_frame_get_control_property_bag (cf, NULL);
+
+ source_ensure_decl (data, " BonoboControlFrame *bonobo_cf;\n");
+ source_ensure_decl (data, " Bonobo_PropertyBag bonobo_pb;\n");
+
+ source_add (data,
+ " bonobo_cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (%s));\n",
+ data->wname);
+ source_add (data,
+ " bonobo_pb = bonobo_control_frame_get_control_property_bag (bonobo_cf, NULL);\n");
+
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ switch (tc->kind) {
+ case CORBA_tk_boolean: {
+ gboolean val = bonobo_pbclient_get_boolean (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_boolean (bonobo_pb, %s, %s, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val ? "TRUE" : "FALSE");
+ break;
+ }
+ case CORBA_tk_string: {
+ char *val = bonobo_pbclient_get_string (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_string (bonobo_pb, %s,",
+ source_make_string (names->data, FALSE));
+ source_add (data, " %s, NULL);\n",
+ source_make_string (val, data->use_gettext));
+ g_free (val);
+ break;
+ }
+ case CORBA_tk_ulong: {
+ gulong val = bonobo_pbclient_get_ulong (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_ulong (bonobo_pb, %s, %lu, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_long: {
+ glong val = bonobo_pbclient_get_long (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_long (bonobo_pb, %s, %li, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_short: {
+ gshort val = bonobo_pbclient_get_short (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_short (bonobo_pb, %s, %i, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_ushort: {
+ gushort val = bonobo_pbclient_get_ushort (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_ushort (bonobo_pb, %s, %u, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_float: {
+ gfloat val = bonobo_pbclient_get_float (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_float (bonobo_pb, %s, %g, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_double: {
+ gdouble val = bonobo_pbclient_get_double (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_double (bonobo_pb, %s, %g, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+
+
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+static GbWidget *
+control_get_gb_widget (const char *obj_id)
+{
+ GbWidget *gbwidget;
+
+ /* Check if this GbWidget is already registered. */
+ gbwidget = gb_widget_lookup_class (obj_id);
+
+ /* If it isn't registered, create it and register it. */
+ if (!gbwidget)
+ {
+ gbwidget = g_new (GbWidget, 1);
+
+ gb_widget_init_struct (gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget->pixmap_struct = gnome_control_xpm;
+ gbwidget->tooltip = NULL;
+
+ /* Fill in any functions that this Gbwidget has */
+ gbwidget->gb_widget_new = NULL;
+ gbwidget->gb_widget_create_properties = gb_bonobo_control_create_properties;
+ gbwidget->gb_widget_get_properties = gb_bonobo_control_get_properties;
+ gbwidget->gb_widget_set_properties = gb_bonobo_control_set_properties;
+ gbwidget->gb_widget_write_source = gb_bonobo_control_write_source;
+
+#if 0
+ g_print ("Registering Bonobo control GbWidget: %s\n", obj_id);
+#endif
+ gb_widget_register_gbwidget (obj_id, gbwidget);
+ }
+
+ return gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomedateedit.c b/tools/glade/glade/gnome/gnomedateedit.c
new file mode 100644
index 00000000..6b18973c
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomedateedit.c
@@ -0,0 +1,313 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-dateedit.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *DateEditFlags = "GnomeDateEdit::dateedit_flags";
+static gchar *ShowTime = "GnomeDateEdit::show_time";
+static gchar *Use24Format = "GnomeDateEdit::use_24_format";
+static gchar *WeekStartMonday = "GnomeDateEdit::week_start_monday";
+static gchar *LowerHour = "GnomeDateEdit::lower_hour";
+static gchar *UpperHour = "GnomeDateEdit::upper_hour";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDateEdit, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_date_edit_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gnome_date_edit_new ((time_t) 0, TRUE, TRUE);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_date_edit_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (ShowTime, _("Show Time:"),
+ _("If the time is shown as well as the date"));
+ property_add_bool (Use24Format, _("24 Hour Format:"),
+ _("If the time is shown in 24-hour format"));
+ property_add_bool (WeekStartMonday, _("Monday First:"),
+ _("If the week should start on Monday"));
+ property_add_int_range (LowerHour, _("Lower Hour:"),
+ _("The lowest hour to show in the popup"),
+ 0, 23, 1, 10, 1);
+ property_add_int_range (UpperHour, _("Upper Hour:"),
+ _("The highest hour to show in the popup"),
+ 0, 23, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_date_edit_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GnomeDateEditFlags flags;
+ int lower_hour, upper_hour;
+
+ flags = gnome_date_edit_get_flags (GNOME_DATE_EDIT (widget));
+
+ /* we save only one property, but the property editor has 3 toggle
+ buttons */
+ if (data->action == GB_SAVING) {
+ char *s = glade_util_string_from_flags (GNOME_TYPE_DATE_EDIT_FLAGS, flags);
+ gb_widget_output_string (data, DateEditFlags, s);
+ g_free (s);
+ } else {
+ gb_widget_output_bool (data, ShowTime,
+ flags & GNOME_DATE_EDIT_SHOW_TIME);
+ gb_widget_output_bool (data, Use24Format,
+ flags & GNOME_DATE_EDIT_24_HR);
+ gb_widget_output_bool (data, WeekStartMonday,
+ flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY);
+ }
+
+ g_object_get (G_OBJECT (widget),
+ "lower-hour", &lower_hour,
+ "upper-hour", &upper_hour,
+ NULL);
+
+ gb_widget_output_int (data, LowerHour, lower_hour);
+ gb_widget_output_int (data, UpperHour, upper_hour);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_date_edit_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GnomeDateEditFlags flags, old_flags;
+ gboolean value;
+ gint value_int, lower_hour, old_lower_hour, upper_hour, old_upper_hour;
+
+ old_flags = flags = gnome_date_edit_get_flags (GNOME_DATE_EDIT (widget));
+
+ /* we load only one property, but the property editor has 3 toggle
+ buttons */
+ if (data->action == GB_LOADING) {
+ char *s = gb_widget_input_string (data, DateEditFlags);
+ if (data->apply)
+ flags = glade_util_flags_from_string (GNOME_TYPE_DATE_EDIT_FLAGS, s);
+ } else {
+ value = gb_widget_input_bool (data, ShowTime)
+ ? GNOME_DATE_EDIT_SHOW_TIME : 0;
+ if (data->apply)
+ flags = (flags & ~GNOME_DATE_EDIT_SHOW_TIME) | value;
+
+ value = gb_widget_input_bool (data, Use24Format)
+ ? GNOME_DATE_EDIT_24_HR : 0;
+ if (data->apply)
+ flags = (flags & ~GNOME_DATE_EDIT_24_HR) | value;
+
+ value = gb_widget_input_bool (data, WeekStartMonday)
+ ? GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY : 0;
+ if (data->apply)
+ flags = (flags & ~GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY) | value;
+ }
+
+ if (flags != old_flags)
+ gnome_date_edit_set_flags (GNOME_DATE_EDIT (widget), flags);
+
+ g_object_get (G_OBJECT (widget),
+ "lower-hour", &old_lower_hour,
+ "upper-hour", &old_upper_hour,
+ NULL);
+
+ value_int = gb_widget_input_int (data, LowerHour);
+ if (data->apply)
+ lower_hour = value_int;
+ else
+ lower_hour = old_lower_hour;
+
+ value_int = gb_widget_input_int (data, UpperHour);
+ if (data->apply)
+ upper_hour = value_int;
+ else
+ upper_hour = old_upper_hour;
+
+ if (lower_hour != old_lower_hour || upper_hour != old_upper_hour)
+ {
+ gnome_date_edit_set_popup_range (GNOME_DATE_EDIT (widget), lower_hour,
+ upper_hour);
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDateEdit, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_date_edit_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_date_edit_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GnomeDateEditFlags flags;
+ gboolean set_flags = FALSE;
+ int upper_hour, lower_hour;
+
+ flags = gnome_date_edit_get_flags (GNOME_DATE_EDIT (widget));
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_date_edit_new ((time_t) 0, %s, %s);\n",
+ data->wname,
+ flags & GNOME_DATE_EDIT_SHOW_TIME ? "TRUE" : "FALSE",
+ flags & GNOME_DATE_EDIT_24_HR ? "TRUE" : "FALSE");
+ }
+ else
+ {
+ set_flags = TRUE;
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY)
+ set_flags = TRUE;
+
+ if (set_flags)
+ {
+ const gchar *prefix = "\n ";
+ const gchar *prefix2 = "\n | ";
+
+ source_add (data, " gnome_date_edit_set_flags (GNOME_DATE_EDIT (%s),",
+ data->wname);
+ if (flags)
+ {
+ if (flags & GNOME_DATE_EDIT_SHOW_TIME)
+ {
+ source_add (data, "%sGNOME_DATE_EDIT_SHOW_TIME", prefix);
+ prefix = prefix2;
+ }
+ if (flags & GNOME_DATE_EDIT_24_HR)
+ {
+ source_add (data, "%sGNOME_DATE_EDIT_24_HR", prefix);
+ prefix = prefix2;
+ }
+ if (flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY)
+ {
+ source_add (data, "%sGNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY",
+ prefix);
+ }
+ source_add (data, ");\n");
+ }
+ else
+ source_add (data, "0);\n");
+ }
+
+ g_object_get (G_OBJECT (widget),
+ "lower-hour", &lower_hour,
+ "upper-hour", &upper_hour,
+ NULL);
+
+ if (lower_hour != 7 || upper_hour != 19)
+
+ {
+ source_add (data, " gnome_date_edit_set_popup_range (GNOME_DATE_EDIT (%s), %i, %i);\n",
+ data->wname,
+ lower_hour,
+ upper_hour);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_date_edit_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_date_edit_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_dateedit_xpm;
+ gbwidget.tooltip = _("GnomeDateEdit");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_date_edit_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_date_edit_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_date_edit_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_date_edit_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_date_edit_write_source;
+/*
+ gbwidget.gb_widget_set_child_props = gb_gnome_date_edit_set_child_props;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_date_edit_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomedialog.c b/tools/glade/glade/gnome/gnomedialog.c
new file mode 100644
index 00000000..af0dd469
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomedialog.c
@@ -0,0 +1,358 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-dialog.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GnomeDialog|GtkWindow::title";
+static gchar *Type = "GnomeDialog|GtkWindow::type";
+static gchar *Position = "GnomeDialog|GtkWindow::window_position";
+static gchar *Modal = "GnomeDialog|GtkWindow::modal";
+static gchar *DefaultWidth = "GnomeDialog|GtkWindow::default_width";
+static gchar *DefaultHeight = "GnomeDialog|GtkWindow::default_height";
+static gchar *Shrink = "GnomeDialogl|GtkWindow::allow_shrink";
+static gchar *Grow = "GnomeDialog|GtkWindow::allow_grow";
+static gchar *AutoShrink = "GnomeDialog|GtkWindow::auto_shrink";
+static gchar *IconName = "GnomeDialog|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomeDialog|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "GnomeDialog|GtkWindow::resizable";
+static gchar *DestroyWithParent = "GnomeDialog|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomeDialog|GtkWindow::icon";
+
+static gchar *Role = "GnomeDialog|GtkWindow::role";
+static gchar *TypeHint = "GnomeDialog|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomeDialog|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomeDialog|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomeDialog|GtkWindow::decorated";
+static gchar *Gravity = "GnomeDialog|GtkWindow::gravity";
+static gchar *Urgency = "GnomeDialog|GtkWindow::urgency_hint";
+
+static gchar *AutoClose = "GnomeDialog::auto_close";
+static gchar *HideOnClose = "GnomeDialog::hide_on_close";
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDialog, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_dialog_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *placeholder;
+ GList *elem;
+
+ if (data->action == GB_CREATING)
+ {
+ /* When creating a new dialog, we add a few standard buttons, which
+ the user can change/delete easily. */
+ new_widget = gnome_dialog_new (NULL,
+ GTK_STOCK_CANCEL,
+ GTK_STOCK_OK,
+ NULL);
+
+ /* Now turn the buttons into GbWidgets so the user can edit them. */
+ elem = GNOME_DIALOG (new_widget)->buttons;
+ gb_widget_create_from (GTK_WIDGET (elem->data), "button");
+ gtk_object_set_data (GTK_OBJECT (elem->data), GladeButtonStockIDKey,
+ GTK_STOCK_CANCEL);
+
+ elem = elem->next;
+ gb_widget_create_from (GTK_WIDGET (elem->data), "button");
+ gtk_object_set_data (GTK_OBJECT (elem->data), GladeButtonStockIDKey,
+ GTK_STOCK_OK);
+
+ /* We need to size the placeholders or the dialog is very small. */
+ placeholder = editor_new_placeholder ();
+ gtk_widget_set_usize (placeholder, 300, 200);
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (new_widget)->vbox),
+ placeholder, TRUE, TRUE, 0);
+ }
+ else
+ {
+ /* When loading we create the bare dialog with no buttons. */
+ new_widget = gnome_dialog_new (NULL, NULL);
+ }
+
+ gb_widget_create_from (GNOME_DIALOG (new_widget)->vbox,
+ data->action == GB_CREATING ? "dialog-vbox" : NULL);
+ gb_widget_set_child_name (GNOME_DIALOG (new_widget)->vbox, GladeChildDialogVBox);
+
+ gb_widget_create_from (GNOME_DIALOG (new_widget)->action_area,
+ data->action == GB_CREATING ? "dialog-action_area"
+ : NULL);
+ gb_widget_set_child_name (GNOME_DIALOG (new_widget)->action_area,
+ GladeChildDialogActionArea);
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "close",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_dialog_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ property_add_bool (AutoClose, _("Auto Close:"),
+ _("If the dialog closes when any button is clicked"));
+ property_add_bool (HideOnClose, _("Hide on Close:"),
+ _("If the dialog is hidden when it is closed, instead of being destroyed"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_dialog_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ gb_widget_output_bool (data, AutoClose, GNOME_DIALOG (widget)->click_closes);
+ gb_widget_output_bool (data, HideOnClose, GNOME_DIALOG (widget)->just_hide);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_dialog_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gboolean auto_close, hide_on_close;
+
+ gb_window_set_standard_properties (widget, data,
+ Title, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ auto_close = gb_widget_input_bool (data, AutoClose);
+ if (data->apply)
+ gnome_dialog_set_close (GNOME_DIALOG (widget), auto_close);
+
+ hide_on_close = gb_widget_input_bool (data, HideOnClose);
+ if (data->apply)
+ gnome_dialog_close_hides (GNOME_DIALOG (widget), hide_on_close);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDialog, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_dialog_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_dialog_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ gchar *title;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ title = GTK_WINDOW (widget)->title;
+ source_add (data, " %s = gnome_dialog_new (%s, NULL);\n",
+ data->wname,
+ title ? source_make_string_full (title, data->use_gettext && translatable, context)
+ : "NULL");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* The title is already set above, so we pass NULL to skip it. */
+ gb_window_write_standard_source (widget, data,
+ NULL, Type, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (GNOME_DIALOG (widget)->click_closes)
+ {
+ source_add (data,
+ " gnome_dialog_set_close (GNOME_DIALOG (%s), TRUE);\n",
+ data->wname);
+ }
+
+ if (GNOME_DIALOG (widget)->just_hide)
+ {
+ source_add (data,
+ " gnome_dialog_close_hides (GNOME_DIALOG (%s), TRUE);\n",
+ data->wname);
+ }
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_DIALOG (<dialog-name>)->vbox".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (char*) gtk_widget_get_name (GNOME_DIALOG (widget)->vbox);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GNOME_DIALOG (%s)->vbox;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GNOME_DIALOG (widget)->vbox, data);
+
+ /* action_area is a child of vbox so I had to add a kludge to stop it
+ being written as a normal child - we need to do it here so that we
+ don't output code to create it. */
+ child_name = (char*) gtk_widget_get_name (GNOME_DIALOG (widget)->action_area);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GNOME_DIALOG (%s)->action_area;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GNOME_DIALOG (widget)->action_area, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_gnome_dialog_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildDialogVBox))
+ return GNOME_DIALOG (widget)->vbox;
+ else if (!strcmp (child_name, GladeChildDialogActionArea))
+ return GNOME_DIALOG (widget)->action_area;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_dialog_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_dialog_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_dialog_xpm;
+ gbwidget.tooltip = _("Gnome Dialog Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_dialog_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_dialog_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_dialog_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_dialog_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_dialog_write_source;
+ gbwidget.gb_widget_get_child = gb_gnome_dialog_get_child;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_dialog_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomedruid.c b/tools/glade/glade/gnome/gnomedruid.c
new file mode 100644
index 00000000..aa3a7aa9
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomedruid.c
@@ -0,0 +1,499 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../tree.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-druid.xpm"
+
+const char *ShowHelp = "GnomeDruid::show_help";
+
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+static void show_druid_dialog (GbWidgetNewData * data);
+static void on_druid_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_druid_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+
+static void gb_gnome_druid_add_start_page (GtkWidget * menuitem,
+ GnomeDruid *druid);
+static void gb_gnome_druid_add_finish_page (GtkWidget * menuitem,
+ GnomeDruid *druid);
+static void gb_gnome_druid_insert_page_before (GtkWidget * menuitem,
+ GnomeDruidPage *page);
+static void gb_gnome_druid_insert_page_after (GtkWidget * menuitem,
+ GnomeDruidPage *page);
+static void gb_gnome_druid_show_page (GtkWidget *parent,
+ GtkWidget *new_page);
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDruid, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_druid_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gnome_druid_new ();
+ return new_widget;
+ }
+ else
+ {
+ show_druid_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_druid_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New Gnome Druid"), data->parent,
+ GTK_SIGNAL_FUNC (on_druid_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_druid_dialog_destroy), data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of Pages:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 2, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "pages",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_druid_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *page;
+ gint pages, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "pages");
+ g_return_if_fail (spinbutton != NULL);
+ pages = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gnome_druid_new ();
+ page = gnome_druid_page_edge_new_aa (GNOME_EDGE_START);
+ gb_widget_create_from (page, "GnomeDruidPageStart");
+ gnome_druid_append_page (GNOME_DRUID (new_widget),
+ GNOME_DRUID_PAGE (page));
+ gnome_druid_set_page (GNOME_DRUID (new_widget), GNOME_DRUID_PAGE (page));
+
+ for (i = 0; i < pages - 2; i++)
+ {
+ page = gb_widget_new ("GnomeDruidPageStandard", new_widget);
+ gnome_druid_append_page (GNOME_DRUID (new_widget),
+ GNOME_DRUID_PAGE (page));
+ }
+
+ if (pages >= 2)
+ {
+ page = gnome_druid_page_edge_new_aa (GNOME_EDGE_FINISH);
+ gb_widget_create_from (page, "GnomeDruidPageFinish");
+ gnome_druid_append_page (GNOME_DRUID (new_widget),
+ GNOME_DRUID_PAGE (page));
+ }
+
+ gtk_widget_show_all (new_widget);
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_druid_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+void
+gb_gnome_druid_add_child (GtkWidget *widget,
+ GtkWidget *child,
+ GbWidgetSetArgData *data)
+{
+ gnome_druid_append_page (GNOME_DRUID (widget), GNOME_DRUID_PAGE (child));
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_druid_create_properties (GtkWidget *widget,
+ GbWidgetCreateArgData *data)
+{
+ property_add_bool (ShowHelp, _("Show Help"), _("Display the help button."));
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_druid_get_properties (GtkWidget *widget,
+ GbWidgetGetArgData *data)
+{
+ gboolean show_help;
+
+ g_object_get (G_OBJECT (widget),
+ "show-help", &show_help,
+ NULL);
+
+ gb_widget_output_bool (data, ShowHelp, show_help);
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_druid_set_properties (GtkWidget *widget,
+ GbWidgetSetArgData *data)
+{
+ gboolean show_help;
+
+ show_help = gb_widget_input_bool (data, ShowHelp);
+ if (data->apply)
+ g_object_set (G_OBJECT (widget), "show-help", show_help, NULL);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDruid, with signals pointing to
+ * other functions in this file.
+ */
+static void
+gb_gnome_druid_create_popup_menu (GtkWidget * widget,
+ GbWidgetCreateMenuData * data)
+{
+ GtkWidget *menuitem;
+ GnomeDruid *druid;
+ GList *children, *elem;
+
+ if (data->child == NULL)
+ return;
+
+ g_return_if_fail (GNOME_IS_DRUID (data->child->parent));
+ druid = GNOME_DRUID (data->child->parent);
+
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+
+ /* 'Add Start Page' is added if the druid has no pages or the first one
+ is not a start page. */
+ if (!children ||
+ !(GNOME_IS_DRUID_PAGE_EDGE (children->data) &&
+ GNOME_DRUID_PAGE_EDGE (children->data)->position == GNOME_EDGE_START))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Start Page"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_gnome_druid_add_start_page),
+ druid);
+ }
+
+ /* 'Add Finish Page' is added if the druid has no pages or the last one
+ is not a finish page. */
+ elem = g_list_last (children);
+ if (!elem ||
+ !(GNOME_IS_DRUID_PAGE_EDGE (elem->data) &&
+ GNOME_DRUID_PAGE_EDGE (elem->data)->position == GNOME_EDGE_FINISH))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Add Finish Page"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_gnome_druid_add_finish_page),
+ druid);
+ }
+
+ g_list_free (children);
+
+ /* 'Insert Page Before' is added if the current page is not the start page.
+ */
+ if (!(GNOME_IS_DRUID_PAGE_EDGE (data->child) &&
+ GNOME_DRUID_PAGE_EDGE (data->child)->position == GNOME_EDGE_START))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Insert Page Before"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_gnome_druid_insert_page_before),
+ data->child);
+ }
+
+ /* 'Insert Page After' is added if the current page is not the finish page.
+ */
+ if (!(GNOME_IS_DRUID_PAGE_EDGE (data->child) &&
+ GNOME_DRUID_PAGE_EDGE (data->child)->position == GNOME_EDGE_FINISH))
+ {
+ menuitem = gtk_menu_item_new_with_label (_("Insert Page After"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data->menu), menuitem);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gb_gnome_druid_insert_page_after),
+ data->child);
+ }
+}
+
+
+static void
+gb_gnome_druid_add_start_page (GtkWidget * menuitem,
+ GnomeDruid *druid)
+{
+ GtkWidget *new_page;
+
+ new_page = gnome_druid_page_edge_new_aa (GNOME_EDGE_START);
+ gb_widget_create_from (new_page, "GnomeDruidPageStart");
+ gtk_widget_show_all (new_page);
+
+ gnome_druid_prepend_page (druid, GNOME_DRUID_PAGE (new_page));
+
+ gb_gnome_druid_show_page (GTK_WIDGET (druid), new_page);
+
+ gnome_druid_set_page (druid, GNOME_DRUID_PAGE (new_page));
+ tree_add_widget (GTK_WIDGET (new_page));
+}
+
+
+static void
+gb_gnome_druid_add_finish_page (GtkWidget * menuitem,
+ GnomeDruid *druid)
+{
+ GtkWidget *new_page;
+
+ new_page = gnome_druid_page_edge_new_aa (GNOME_EDGE_FINISH);
+ gb_widget_create_from (new_page, "GnomeDruidPageFinish");
+ gtk_widget_show_all (new_page);
+
+ gnome_druid_append_page (druid, GNOME_DRUID_PAGE (new_page));
+
+ gb_gnome_druid_show_page (GTK_WIDGET (druid), new_page);
+
+ gnome_druid_set_page (druid, GNOME_DRUID_PAGE (new_page));
+ tree_add_widget (GTK_WIDGET (new_page));
+}
+
+
+static void
+gb_gnome_druid_insert_page_before (GtkWidget * menuitem,
+ GnomeDruidPage *page)
+{
+ GtkWidget *parent, *new_page;
+ GnomeDruidPage *prev_page;
+ GList *children, *elem;
+
+ parent = GTK_WIDGET (page)->parent;
+ g_return_if_fail (GNOME_IS_DRUID (parent));
+
+ children = gtk_container_get_children (GTK_CONTAINER (parent));
+ elem = g_list_find (children, page);
+ g_return_if_fail (elem != NULL);
+
+ new_page = gb_widget_new ("GnomeDruidPageStandard", parent);
+ gtk_widget_show_all (new_page);
+
+ if (elem->prev)
+ prev_page = GNOME_DRUID_PAGE (elem->prev->data);
+ else
+ prev_page = NULL;
+
+ g_list_free (children);
+
+ gnome_druid_insert_page (GNOME_DRUID (parent), prev_page,
+ GNOME_DRUID_PAGE (new_page));
+
+ gb_gnome_druid_show_page (parent, new_page);
+
+ gnome_druid_set_page (GNOME_DRUID (parent), GNOME_DRUID_PAGE (new_page));
+ tree_add_widget (GTK_WIDGET (new_page));
+}
+
+
+static void
+gb_gnome_druid_insert_page_after (GtkWidget * menuitem,
+ GnomeDruidPage *page)
+{
+ GtkWidget *parent, *new_page;
+
+ parent = GTK_WIDGET (page)->parent;
+ g_return_if_fail (GNOME_IS_DRUID (parent));
+
+ new_page = gb_widget_new ("GnomeDruidPageStandard", parent);
+ gtk_widget_show_all (new_page);
+
+ gnome_druid_insert_page (GNOME_DRUID (parent),
+ GNOME_DRUID_PAGE (page),
+ GNOME_DRUID_PAGE (new_page));
+
+ gb_gnome_druid_show_page (parent, new_page);
+
+ gnome_druid_set_page (GNOME_DRUID (parent), GNOME_DRUID_PAGE (new_page));
+ tree_add_widget (GTK_WIDGET (new_page));
+}
+
+
+/* FIXME: GnomeDruid bug workaround. */
+static void
+gb_gnome_druid_show_page (GtkWidget *parent, GtkWidget *new_page)
+{
+ /* Hopefully we don't need this for GNOME 2. */
+#if 0
+ if (GTK_WIDGET_REALIZED (parent))
+ gtk_widget_realize (new_page);
+
+ if (GTK_WIDGET_VISIBLE (parent) && GTK_WIDGET_VISIBLE (new_page))
+ {
+ if (GTK_WIDGET_MAPPED (parent))
+ gtk_widget_map (new_page);
+
+ gtk_widget_queue_resize (new_page);
+ }
+#endif
+}
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_druid_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ gboolean show_help;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_druid_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ g_object_get (G_OBJECT (widget),
+ "show-help", &show_help,
+ NULL);
+
+ if (show_help)
+ {
+ source_add (data,
+ " gnome_druid_set_show_help (GNOME_DRUID (%s), TRUE);\n",
+ data->wname);
+ }
+}
+
+
+/* Outputs source to add a child widget to a table. */
+static void
+gb_gnome_druid_write_add_child_source (GtkWidget * parent,
+ const gchar *parent_name,
+ GtkWidget *child,
+ GbWidgetWriteSourceData * data)
+{
+ source_add (data,
+ " gnome_druid_append_page (GNOME_DRUID (%s),\n"
+ " GNOME_DRUID_PAGE (%s));\n",
+ parent_name, data->wname);
+}
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_druid_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_druid_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_druid_xpm;
+ gbwidget.tooltip = _("Druid");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_druid_new;
+ gbwidget.gb_widget_add_child = gb_gnome_druid_add_child;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_druid_create_popup_menu;
+ gbwidget.gb_widget_write_source = gb_gnome_druid_write_source;
+ gbwidget.gb_widget_write_add_child_source = gb_gnome_druid_write_add_child_source;
+ gbwidget.gb_widget_create_properties = gb_gnome_druid_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_druid_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_druid_set_properties;
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomedruidpageedge.c b/tools/glade/glade/gnome/gnomedruidpageedge.c
new file mode 100644
index 00000000..2578d7ba
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomedruidpageedge.c
@@ -0,0 +1,537 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-druid-page-start.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *BackgroundColor = "GnomeDruidPageEdge::background_color";
+static gchar *LogoBackgroundColor = "GnomeDruidPageEdge::logo_background_color";
+static gchar *TextboxColor = "GnomeDruidPageEdge::textbox_color";
+static gchar *TextColor = "GnomeDruidPageEdge::text_color";
+static gchar *TitleColor = "GnomeDruidPageEdge::title_color";
+static gchar *Text = "GnomeDruidPageEdge::text";
+static gchar *Title = "GnomeDruidPageEdge::title";
+static gchar *LogoImage = "GnomeDruidPageEdge::logo";
+static gchar *Watermark = "GnomeDruidPageEdge::watermark";
+static gchar *TopWatermark = "GnomeDruidPageEdge::top_watermark";
+static gchar *Position = "GnomeDruidPageEdge::position";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDruidPageEdge, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_druid_page_edge_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ GnomeEdgePosition position = GNOME_EDGE_START;
+
+ if (data->action == GB_LOADING)
+ {
+ char *position_string = load_string (data->loading_data, Position);
+ if (position_string && *position_string)
+ {
+ position = glade_enum_from_string (GNOME_TYPE_EDGE_POSITION,
+ position_string);
+ }
+ else
+ {
+ g_warning ("no position property in XML file. Defaulting to GNOME_EDGE_START");
+ }
+ }
+ else
+ {
+ g_warning ("gb_gnome_druid_page_edge_new() called to create widget. Defaulting to GNOME_EDGE_START");
+ }
+
+ new_widget = gnome_druid_page_edge_new (position);
+
+ return new_widget;
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_druid_page_edge_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+ property_add_string (Title, _("Title:"),
+ _("The title of the page"));
+ property_add_text (Text, _("Text:"),
+ _("The main text of the page, "
+ "introducing people to the druid."), 5);
+ property_add_color (TitleColor, _("Title Color:"),
+ _("The color of the title text"));
+ property_add_color (TextColor, _("Text Color:"),
+ _("The color of the main text"));
+ property_add_color (BackgroundColor, _("Back. Color:"),
+ _("The background color of the page"));
+ property_add_color (LogoBackgroundColor, _("Logo Back. Color:"),
+ _("The background color around the logo"));
+ property_add_color (TextboxColor, _("Text Box Color:"),
+ _("The background color of the main text area"));
+ property_add_filename (LogoImage, _("Logo Image:"),
+ _("The logo to display in the top-right of the page"));
+ property_add_filename (Watermark, _("Side Watermark:"),
+ _("The main image to display on the side of the page."));
+ property_add_filename (TopWatermark, _("Top Watermark:"),
+ _("The watermark to display at the top of the page."));
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_druid_page_edge_get_properties (GtkWidget *widget,
+ GbWidgetGetArgData * data)
+{
+ GnomeDruidPageEdge *page;
+
+ page = GNOME_DRUID_PAGE_EDGE (widget);
+
+ if (data->action == GB_SAVING)
+ {
+ save_string (data, Position,
+ glade_string_from_enum (GNOME_TYPE_EDGE_POSITION,
+ page->position));
+ }
+
+ gb_widget_output_translatable_string (data, Title, gtk_object_get_data (GTK_OBJECT (widget), Title));
+ gb_widget_output_translatable_text (data, Text, page->text);
+
+ /* We do this to make sure the colors are set. */
+ gtk_widget_ensure_style (widget);
+
+ /* Only save colors if they have been set explicitly. */
+ if (data->action == GB_SHOWING
+ || gtk_object_get_data (GTK_OBJECT (widget), TitleColor))
+ gb_widget_output_color (data, TitleColor, &page->title_color);
+
+ if (data->action == GB_SHOWING
+ || gtk_object_get_data (GTK_OBJECT (widget), TextColor))
+ gb_widget_output_color (data, TextColor, &page->text_color);
+
+ if (data->action == GB_SHOWING
+ || gtk_object_get_data (GTK_OBJECT (widget), BackgroundColor))
+ gb_widget_output_color (data, BackgroundColor, &page->background_color);
+
+ if (data->action == GB_SHOWING
+ || gtk_object_get_data (GTK_OBJECT (widget), LogoBackgroundColor))
+ gb_widget_output_color (data, LogoBackgroundColor,
+ &page->logo_background_color);
+
+ if (data->action == GB_SHOWING
+ || gtk_object_get_data (GTK_OBJECT (widget), TextboxColor))
+ gb_widget_output_color (data, TextboxColor, &page->textbox_color);
+
+ gb_widget_output_pixmap_filename (data, LogoImage,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ LogoImage));
+ gb_widget_output_pixmap_filename (data, Watermark,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ Watermark));
+
+ gb_widget_output_pixmap_filename (data, TopWatermark,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ TopWatermark));
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+
+static void
+gb_gnome_druid_page_edge_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ GnomeDruidPageEdge *page;
+ gchar *string, *old_filename;
+ GdkColor *color;
+ GdkPixbuf *pb;
+
+ page = GNOME_DRUID_PAGE_EDGE (widget);
+
+ string = gb_widget_input_string (data, Title);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), Title, g_strdup (string));
+ gnome_druid_page_edge_set_title (page, string);
+ }
+
+ string = gb_widget_input_text (data, Text);
+ if (data->apply)
+ gnome_druid_page_edge_set_text (page, string);
+ if (data->action == GB_APPLYING)
+ g_free (string);
+
+ /* For colors, we store a flag to indicate if the color has been set.
+ Unfortunately the only way to reset a color to the default at present is
+ to remove it from the XML file. */
+ color = gb_widget_input_color (data, BackgroundColor);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), BackgroundColor, "Y");
+ gnome_druid_page_edge_set_bg_color (page, color);
+ }
+
+ color = gb_widget_input_color (data, LogoBackgroundColor);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), LogoBackgroundColor, "Y");
+ gnome_druid_page_edge_set_logo_bg_color (page, color);
+ }
+
+ color = gb_widget_input_color (data, TextboxColor);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), TextboxColor, "Y");
+ gnome_druid_page_edge_set_textbox_color (page, color);
+ }
+
+ color = gb_widget_input_color (data, TextColor);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), TextColor, "Y");
+ gnome_druid_page_edge_set_text_color (page, color);
+ }
+
+ color = gb_widget_input_color (data, TitleColor);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), TitleColor, "Y");
+ gnome_druid_page_edge_set_title_color (page, color);
+ }
+
+ string = gb_widget_input_pixmap_filename (data, LogoImage);
+ if (data->apply)
+ {
+ if (string && string[0] == '\0')
+ string = NULL;
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), LogoImage);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), LogoImage,
+ g_strdup (string), string ? g_free : NULL);
+ glade_project_add_pixmap (data->project, string);
+ pb = string ? gdk_pixbuf_new_from_file (string, NULL) : NULL;
+ gnome_druid_page_edge_set_logo (page, pb);
+ if (pb)
+ gdk_pixbuf_unref (pb);
+ }
+ if (data->action == GB_LOADING)
+ g_free (string);
+
+ string = gb_widget_input_pixmap_filename (data, Watermark);
+ if (data->apply)
+ {
+ if (string && string[0] == '\0')
+ string = NULL;
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), Watermark);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), Watermark,
+ g_strdup (string), string ? g_free : NULL);
+ glade_project_add_pixmap (data->project, string);
+ pb = string ? gdk_pixbuf_new_from_file (string, NULL) : NULL;
+ gnome_druid_page_edge_set_watermark (page, pb);
+ if (pb)
+ gdk_pixbuf_unref (pb);
+ }
+ if (data->action == GB_LOADING)
+ g_free (string);
+
+ string = gb_widget_input_pixmap_filename (data, TopWatermark);
+ if (data->apply)
+ {
+ if (string && string[0] == '\0')
+ string = NULL;
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), TopWatermark);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), TopWatermark,
+ g_strdup (string), string ? g_free : NULL);
+ glade_project_add_pixmap (data->project, string);
+ pb = string ? gdk_pixbuf_new_from_file (string, NULL) : NULL;
+ gnome_druid_page_edge_set_top_watermark (page, pb);
+ if (pb)
+ gdk_pixbuf_unref (pb);
+ }
+ if (data->action == GB_LOADING)
+ g_free (string);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDruidPageEdge, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_druid_page_edge_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_druid_page_edge_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GnomeDruidPageEdge *page;
+ GdkColor *color;
+ gchar *filename, *title;
+ gboolean translatable, context;
+ gchar *comments;
+
+ g_return_if_fail (GNOME_IS_DRUID (widget->parent));
+ page = GNOME_DRUID_PAGE_EDGE (widget);
+
+ /* We do this to make sure the colors are set. */
+ gtk_widget_ensure_style (widget);
+
+ if (data->create_widget)
+ {
+ const char *position = glade_string_from_enum (GNOME_TYPE_EDGE_POSITION,
+ page->position);
+
+ source_add (data, " %s = gnome_druid_page_edge_new (%s);\n",
+ data->wname, position);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ color = &page->background_color;
+ if (gtk_object_get_data (GTK_OBJECT (widget), BackgroundColor))
+ {
+ source_add_decl (data,
+ " GdkColor %s_bg_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ color->red, color->green, color->blue);
+ source_add (data,
+ " gnome_druid_page_edge_set_bg_color (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " &%s_bg_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ color = &page->textbox_color;
+ if (gtk_object_get_data (GTK_OBJECT (widget), TextboxColor))
+ {
+ source_add_decl (data,
+ " GdkColor %s_textbox_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ color->red, color->green, color->blue);
+ source_add (data,
+ " gnome_druid_page_edge_set_textbox_color (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " &%s_textbox_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ color = &page->logo_background_color;
+ if (gtk_object_get_data (GTK_OBJECT (widget), LogoBackgroundColor))
+ {
+ source_add_decl (data,
+ " GdkColor %s_logo_bg_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ color->red, color->green, color->blue);
+ source_add (data,
+ " gnome_druid_page_edge_set_logo_bg_color (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " &%s_logo_bg_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ color = &page->title_color;
+ if (gtk_object_get_data (GTK_OBJECT (widget), TitleColor))
+ {
+ source_add_decl (data,
+ " GdkColor %s_title_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ color->red, color->green, color->blue);
+ source_add (data,
+ " gnome_druid_page_edge_set_title_color (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " &%s_title_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ color = &page->text_color;
+ if (gtk_object_get_data (GTK_OBJECT (widget), TextColor))
+ {
+ source_add_decl (data,
+ " GdkColor %s_text_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ color->red, color->green, color->blue);
+ source_add (data,
+ " gnome_druid_page_edge_set_text_color (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " &%s_text_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ title = gtk_object_get_data (GTK_OBJECT (widget), Title);
+ if (title && *title)
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_druid_page_edge_set_title (GNOME_DRUID_PAGE_EDGE (%s), %s);\n",
+ data->wname,
+ source_make_string_full (title, data->use_gettext && translatable, context));
+ }
+
+ if (page->text && strcmp (page->text, ""))
+ {
+ glade_util_get_translation_properties (widget, Text, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_druid_page_edge_set_text (GNOME_DRUID_PAGE_EDGE (%s), %s);\n",
+ data->wname,
+ source_make_string_full (page->text, data->use_gettext && translatable, context));
+ }
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), LogoImage);
+ if (filename && filename[0])
+ {
+ source_ensure_decl (data, " GdkPixbuf *tmp_pixbuf;\n");
+
+ source_add (data,
+ " tmp_pixbuf = create_pixbuf (\"%s/%s\");\n"
+ " if (tmp_pixbuf)\n"
+ " {\n"
+ " gnome_druid_page_edge_set_logo (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " tmp_pixbuf);\n"
+ " gdk_pixbuf_unref (tmp_pixbuf);\n"
+ " }\n",
+ data->program_name, g_basename (filename), data->wname);
+ }
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), Watermark);
+ if (filename && filename[0])
+ {
+ source_ensure_decl (data, " GdkPixbuf *tmp_pixbuf;\n");
+
+ source_add (data,
+ " tmp_pixbuf = create_pixbuf (\"%s/%s\");\n"
+ " if (tmp_pixbuf)\n"
+ " {\n"
+ " gnome_druid_page_edge_set_watermark (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " tmp_pixbuf);\n"
+ " gdk_pixbuf_unref (tmp_pixbuf);\n"
+ " }\n",
+ data->program_name, g_basename (filename), data->wname);
+ }
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), TopWatermark);
+ if (filename && filename[0])
+ {
+ source_ensure_decl (data, " GdkPixbuf *tmp_pixbuf;\n");
+
+ source_add (data,
+ " tmp_pixbuf = create_pixbuf (\"%s/%s\");\n"
+ " if (tmp_pixbuf)\n"
+ " {\n"
+ " gnome_druid_page_edge_set_top_watermark (GNOME_DRUID_PAGE_EDGE (%s),\n"
+ " tmp_pixbuf);\n"
+ " gdk_pixbuf_unref (tmp_pixbuf);\n"
+ " }\n",
+ data->program_name, g_basename (filename), data->wname);
+ }
+}
+
+
+
+void
+gb_gnome_druid_page_edge_destroy (GtkWidget * widget,
+ GbWidgetDestroyData * data)
+{
+ gchar *filename;
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), LogoImage);
+ glade_project_remove_pixmap (data->project, filename);
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), TopWatermark);
+ glade_project_remove_pixmap (data->project, filename);
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), Watermark);
+ glade_project_remove_pixmap (data->project, filename);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_druid_page_edge_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_druid_page_edge_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_druid_page_start_xpm;
+ gbwidget.tooltip = _("Druid Start or Finish Page");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_druid_page_edge_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_druid_page_edge_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_druid_page_edge_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_druid_page_edge_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_druid_page_edge_write_source;
+ gbwidget.gb_widget_destroy = gb_gnome_druid_page_edge_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_druid_page_edge_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomedruidpagestandard.c b/tools/glade/glade/gnome/gnomedruidpagestandard.c
new file mode 100644
index 00000000..97ec324d
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomedruidpagestandard.c
@@ -0,0 +1,463 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-druid-page-standard.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *BackgroundColor = "GnomeDruidPageStandard::background";
+static gchar *LogoBackgroundColor = "GnomeDruidPageStandard::logo_background";
+static gchar *ContentsBackgroundColor = "GnomeDruidPageStandard::contents_background";
+static gchar *TitleColor = "GnomeDruidPageStandard::title_foreground";
+static gchar *Title = "GnomeDruidPageStandard::title";
+static gchar *LogoImage = "GnomeDruidPageStandard::logo";
+static gchar *TopWatermark = "GnomeDruidPageStandard::top_watermark";
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeDruidPageStandard, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_druid_page_standard_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *placeholder;
+
+ if (data->action == GB_CREATING)
+ {
+ new_widget = gnome_druid_page_standard_new_with_vals ("", NULL, NULL);
+ placeholder = editor_new_placeholder ();
+ gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (new_widget)->vbox),
+ placeholder, TRUE, TRUE, 0);
+ }
+ else
+ {
+ new_widget = gnome_druid_page_standard_new_with_vals ("", NULL, NULL);
+ }
+ gb_widget_create_from (GNOME_DRUID_PAGE_STANDARD (new_widget)->vbox,
+ "druid-vbox");
+ gb_widget_set_child_name (GNOME_DRUID_PAGE_STANDARD (new_widget)->vbox,
+ GladeChildGnomeDruidVBox);
+ gtk_widget_show_all (new_widget);
+ return new_widget;
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_druid_page_standard_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+ property_add_string (Title, _("Title:"),
+ _("The title of the page"));
+ property_add_color (TitleColor, _("Title Color:"),
+ _("The color of the title text"));
+ property_add_color (ContentsBackgroundColor, _("Contents Back. Color:"),
+ _("The background color around the title"));
+ property_add_color (BackgroundColor, _("Back. Color:"),
+ _("The background color of the page"));
+ property_add_color (LogoBackgroundColor, _("Logo Back. Color:"),
+ _("The background color around the logo"));
+ property_add_filename (LogoImage, _("Logo Image:"),
+ _("The logo to display in the top-right of the page"));
+ property_add_filename (TopWatermark, _("Top Watermark:"),
+ _("The image to display along the top of the page"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_druid_page_standard_get_properties (GtkWidget *widget,
+ GbWidgetGetArgData * data)
+{
+ GnomeDruidPageStandard *page;
+ GdkColor *title_color, *background_color, *logo_background_color;
+ gboolean title_color_set, background_color_set, logo_background_color_set;
+
+ page = GNOME_DRUID_PAGE_STANDARD (widget);
+
+ /* We do this to make sure the colors are set. */
+ gtk_widget_ensure_style (widget);
+
+ gb_widget_output_translatable_string (data, Title, page->title);
+
+ g_object_get (G_OBJECT (widget),
+ "title-foreground-set", &title_color_set,
+ "title-foreground-gdk", &title_color,
+ "background-set", &background_color_set,
+ "background-gdk", &background_color,
+ "logo-background-set", &logo_background_color_set,
+ "logo-background-gdk", &logo_background_color,
+ NULL);
+
+ if (data->action == GB_SHOWING || title_color_set)
+ gb_widget_output_color (data, TitleColor, title_color);
+
+ if (data->action == GB_SHOWING || background_color_set)
+ gb_widget_output_color (data, BackgroundColor, background_color);
+
+ if (data->action == GB_SHOWING || logo_background_color_set)
+ gb_widget_output_color (data, LogoBackgroundColor, logo_background_color);
+
+ gdk_color_free (title_color);
+ gdk_color_free (background_color);
+ gdk_color_free (logo_background_color);
+
+ /* FIXME: GNOME 2 bug workaround. It doesn't install the properties for
+ these, so we have to do it ourselves. */
+ if (data->action == GB_SHOWING
+ || gtk_object_get_data (GTK_OBJECT (widget), ContentsBackgroundColor))
+ gb_widget_output_color (data, ContentsBackgroundColor,
+ &page->contents_background);
+
+ gb_widget_output_pixmap_filename (data, LogoImage,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ LogoImage));
+
+ gb_widget_output_pixmap_filename (data, TopWatermark,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ TopWatermark));
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+
+static void
+gb_gnome_druid_page_standard_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ GnomeDruidPageStandard *page;
+ gchar *string, *old_filename;
+ GdkColor *color;
+ GdkPixbuf *image;
+
+ page = GNOME_DRUID_PAGE_STANDARD (widget);
+
+ string = gb_widget_input_string (data, Title);
+ if (data->apply)
+ gnome_druid_page_standard_set_title (page, string);
+
+ color = gb_widget_input_color (data, BackgroundColor);
+ if (data->apply)
+ gnome_druid_page_standard_set_bg_color (page, color);
+
+ color = gb_widget_input_color (data, LogoBackgroundColor);
+ if (data->apply)
+ gnome_druid_page_standard_set_logo_bg_color (page, color);
+
+ color = gb_widget_input_color (data, TitleColor);
+ if (data->apply)
+ gnome_druid_page_standard_set_title_color (page, color);
+
+ color = gb_widget_input_color (data, ContentsBackgroundColor);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), ContentsBackgroundColor, "Y");
+ gnome_druid_page_standard_set_contents_background (page, color);
+ }
+
+ string = gb_widget_input_pixmap_filename (data, LogoImage);
+ if (data->apply)
+ {
+ if (string && string[0] == '\0')
+ string = NULL;
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), LogoImage);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), LogoImage,
+ g_strdup (string), string ? g_free : NULL);
+ glade_project_add_pixmap (data->project, string);
+ image = string ? gdk_pixbuf_new_from_file (string, NULL) : NULL;
+ gnome_druid_page_standard_set_logo (page, image);
+ if (image)
+ gdk_pixbuf_unref (image);
+ }
+ if (data->action == GB_LOADING)
+ g_free (string);
+
+ string = gb_widget_input_pixmap_filename (data, TopWatermark);
+ if (data->apply)
+ {
+ if (string && string[0] == '\0')
+ string = NULL;
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), TopWatermark);
+ glade_project_remove_pixmap (data->project, old_filename);
+ gtk_object_set_data_full (GTK_OBJECT (widget), TopWatermark,
+ g_strdup (string), string ? g_free : NULL);
+ glade_project_add_pixmap (data->project, string);
+ image = string ? gdk_pixbuf_new_from_file (string, NULL) : NULL;
+ gnome_druid_page_standard_set_top_watermark (page, image);
+ if (image)
+ gdk_pixbuf_unref (image);
+ }
+ if (data->action == GB_LOADING)
+ g_free (string);
+}
+
+static GtkWidget *
+gb_gnome_druid_page_standard_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildGnomeDruidVBox))
+ return GNOME_DRUID_PAGE_STANDARD (widget)->vbox;
+ else
+ return NULL;
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeDruidPageStandard, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_druid_page_standard_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_druid_page_standard_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GnomeDruidPageStandard *page;
+ gchar *filename, *title;
+ gchar *wname, *child_name;
+ GdkColor title_color, background_color, logo_background_color;
+ gboolean title_color_set, background_color_set, logo_background_color_set;
+
+ page = GNOME_DRUID_PAGE_STANDARD (widget);
+
+ /* We do this to make sure the colors are set. */
+ gtk_widget_ensure_style (widget);
+
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = gnome_druid_page_standard_new ();\n",
+ data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ g_object_get (G_OBJECT (widget),
+ "title-foreground-set", &title_color_set,
+ "title-foreground-gdk", &title_color,
+ "background-set", &background_color_set,
+ "background-gdk", &background_color,
+ "logo-background-set", &logo_background_color_set,
+ "logo-background-gdk", &logo_background_color,
+ "title", &title,
+ NULL);
+
+ if (background_color_set)
+ {
+ source_add_decl (data,
+ " GdkColor %s_bg_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ background_color.red, background_color.green, background_color.blue);
+ source_add (data,
+ " gnome_druid_page_standard_set_background (GNOME_DRUID_PAGE_STANDARD (%s), &%s_bg_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ if (logo_background_color_set)
+ {
+ source_add_decl (data,
+ " GdkColor %s_logo_bg_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ logo_background_color.red, logo_background_color.green, logo_background_color.blue);
+ source_add (data,
+ " gnome_druid_page_standard_set_logo_background (GNOME_DRUID_PAGE_STANDARD (%s), &%s_logo_bg_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ if (title_color_set)
+ {
+ source_add_decl (data,
+ " GdkColor %s_title_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ title_color.red, title_color.green, title_color.blue);
+ source_add (data,
+ " gnome_druid_page_standard_set_title_foreground (GNOME_DRUID_PAGE_STANDARD (%s), &%s_title_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ if (gtk_object_get_data (GTK_OBJECT (widget), ContentsBackgroundColor))
+ {
+ GdkColor *color = &page->contents_background;
+ source_add_decl (data,
+ " GdkColor %s_contents_bg_color = { 0, %i, %i, %i };\n",
+ data->real_wname,
+ color->red, color->green, color->blue);
+ source_add (data,
+ " gnome_druid_page_standard_set_contents_background (GNOME_DRUID_PAGE_STANDARD (%s), &%s_contents_bg_color);\n",
+ data->wname, data->real_wname);
+ }
+
+ if (title && *title)
+ {
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_druid_page_standard_set_title (GNOME_DRUID_PAGE_STANDARD (%s), %s);\n",
+ data->wname,
+ source_make_string_full (title, data->use_gettext && translatable, context));
+ }
+ g_free (title);
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), LogoImage);
+ if (filename && filename[0])
+ {
+ source_ensure_decl (data, " GdkPixbuf *tmp_pixbuf;\n");
+
+ source_add (data,
+ " tmp_pixbuf = create_pixbuf (\"%s/%s\");\n"
+ " if (tmp_pixbuf)\n"
+ " {\n"
+ " gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (%s),\n"
+ " tmp_pixbuf);\n"
+ " gdk_pixbuf_unref (tmp_pixbuf);\n"
+ " }\n",
+ data->program_name, g_basename (filename), data->wname);
+ }
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), TopWatermark);
+ if (filename && filename[0])
+ {
+ source_ensure_decl (data, " GdkPixbuf *tmp_pixbuf;\n");
+
+ source_add (data,
+ " tmp_pixbuf = create_pixbuf (\"%s/%s\");\n"
+ " if (tmp_pixbuf)\n"
+ " {\n"
+ " gnome_druid_page_standard_set_top_watermark (GNOME_DRUID_PAGE_STANDARD (%s),\n"
+ " tmp_pixbuf);\n"
+ " gdk_pixbuf_unref (tmp_pixbuf);\n"
+ " }\n",
+ data->program_name, g_basename (filename), data->wname);
+ }
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_COMBO (<combo-name>)->entry".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (char*) gtk_widget_get_name (GNOME_DRUID_PAGE_STANDARD (widget)->vbox);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GNOME_DRUID_PAGE_STANDARD (%s)->vbox;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GNOME_DRUID_PAGE_STANDARD (widget)->vbox, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+void
+gb_gnome_druid_page_standard_destroy (GtkWidget * widget,
+ GbWidgetDestroyData * data)
+{
+ gchar *filename;
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), LogoImage);
+ glade_project_remove_pixmap (data->project, filename);
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), TopWatermark);
+ glade_project_remove_pixmap (data->project, filename);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_druid_page_standard_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_druid_page_standard_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_druid_page_standard_xpm;
+ gbwidget.tooltip = _("Druid Standard Page");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_druid_page_standard_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_druid_page_standard_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_druid_page_standard_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_druid_page_standard_set_properties;
+ gbwidget.gb_widget_get_child = gb_gnome_druid_page_standard_get_child;
+ gbwidget.gb_widget_write_source = gb_gnome_druid_page_standard_write_source;
+ gbwidget.gb_widget_destroy = gb_gnome_druid_page_standard_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_druid_page_standard_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeentry.c b/tools/glade/glade/gnome/gnomeentry.c
new file mode 100644
index 00000000..1f190021
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeentry.c
@@ -0,0 +1,225 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-entry.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HistoryID = "GnomeEntry::history_id";
+static gchar *MaxSaved = "GnomeEntry::max_saved";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeEntry, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_entry_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gnome_entry_new (NULL);
+
+ gb_widget_create_from (GTK_COMBO (new_widget)->entry,
+ data->action == GB_CREATING ? "combo-entry" : NULL);
+ gb_widget_set_child_name (GTK_COMBO (new_widget)->entry, GladeChildGnomeEntry);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_entry_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (HistoryID, _("History ID:"),
+ _("The ID to save the history entries under"));
+ property_add_int_range (MaxSaved, _("Max Saved:"),
+ _("The maximum number of history entries saved"),
+ 0, 10000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_entry_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_string (data, HistoryID, gtk_object_get_data (GTK_OBJECT (widget), HistoryID));
+ gb_widget_output_int (data, MaxSaved, gnome_entry_get_max_saved (GNOME_ENTRY (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_entry_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *history_id;
+ gint max_saved;
+
+ history_id = gb_widget_input_string (data, HistoryID);
+ if (data->apply)
+ gtk_object_set_data_full (GTK_OBJECT (widget), HistoryID,
+ g_strdup (history_id),
+ history_id ? g_free : NULL);
+
+ max_saved = gb_widget_input_int (data, MaxSaved);
+ if (data->apply)
+ gnome_entry_set_max_saved (GNOME_ENTRY (widget), max_saved);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeEntry, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_entry_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_entry_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+
+ if (data->create_widget)
+ {
+ gchar *history_id;
+
+ history_id = gtk_object_get_data (GTK_OBJECT (widget), HistoryID);
+ if (history_id && history_id[0])
+ source_add (data, " %s = gnome_entry_new (%s);\n",
+ data->wname, source_make_string (history_id, FALSE));
+ else
+ source_add (data, " %s = gnome_entry_new (NULL);\n",
+ data->wname);
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ /* Note that GLADE_DEFAULT_MAX_HISTORY_SAVED is copied from gnome-entry.c */
+ if (gnome_entry_get_max_saved (GNOME_ENTRY (widget)) != GLADE_DEFAULT_MAX_HISTORY_SAVED)
+ source_add (data, " gnome_entry_set_max_saved (GNOME_ENTRY (%s), %i);\n",
+ data->wname, gnome_entry_get_max_saved (GNOME_ENTRY (widget)));
+
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_COMBO (<combo-name>)->entry".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (char*) gtk_widget_get_name (GTK_COMBO (widget)->entry);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = gnome_entry_gtk_entry (GNOME_ENTRY (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GTK_COMBO (widget)->entry, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_gnome_entry_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildGnomeEntry))
+ return GTK_COMBO (widget)->entry;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_entry_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_entry_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_entry_xpm;
+ gbwidget.tooltip = _("Gnome Entry");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_entry_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_entry_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_entry_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_entry_set_properties;
+ gbwidget.gb_widget_get_child = gb_gnome_entry_get_child;
+ gbwidget.gb_widget_write_source = gb_gnome_entry_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_entry_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomefileentry.c b/tools/glade/glade/gnome/gnomefileentry.c
new file mode 100644
index 00000000..7889659a
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomefileentry.c
@@ -0,0 +1,382 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-fileentry.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Directory = "GnomeFileEntry::directory_entry";
+static gchar *HistoryID = "GnomeFileEntry|GnomeEntry::history_id";
+static gchar *MaxSaved = "GnomeFileEntry|GnomeEntry::max_saved";
+static gchar *Title = "GnomeFileEntry::browse_dialog_title";
+static gchar *Modal = "GnomeFileEntry::modal";
+static gchar *FileChooser = "GnomeFileEntry::use_filechooser";
+
+static gchar *Action = "GnomeFileEntry::filechooser_action";
+
+
+static const gchar *GbActionChoices[] =
+{"Open", "Save", "Select Folder", "Create Folder", NULL};
+static const gint GbActionValues[] =
+{
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+};
+static const gchar *GbActionSymbols[] =
+{
+ "GTK_FILE_CHOOSER_ACTION_OPEN",
+ "GTK_FILE_CHOOSER_ACTION_SAVE",
+ "GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER",
+ "GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER"
+};
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeFileEntry, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_file_entry_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *entry;
+
+ new_widget = gnome_file_entry_new (NULL, NULL);
+
+ entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (new_widget));
+ gb_widget_create_from (entry,
+ data->action == GB_CREATING ? "combo-entry" : NULL);
+ gb_widget_set_child_name (entry, GladeChildGnomeEntry);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_file_entry_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (HistoryID, _("History ID:"),
+ _("The ID to save the history entries under"));
+ property_add_int_range (MaxSaved, _("Max Saved:"),
+ _("The maximum number of history entries saved"),
+ 0, 10000, 1, 10, 1);
+ property_add_string (Title, _("Title:"),
+ _("The title of the file selection dialog"));
+ property_add_bool (Directory, _("Directory:"),
+ _("If a directory is needed rather than a file"));
+ property_add_bool (Modal, _("Modal:"),
+ _("If the file selection dialog should be modal"));
+ property_add_bool (FileChooser, _("Use FileChooser:"),
+ _("Use the new GtkFileChooser widget instead of GtkFileSelection"));
+ property_add_choice (Action, _("Action:"),
+ _("The type of file operation being performed"),
+ GbActionChoices);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_file_entry_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkWidget *gentry;
+ gboolean use_filechooser = FALSE;
+ GtkFileChooserAction action;
+ gint i;
+
+ gentry = gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (widget));
+
+ gb_widget_output_string (data, HistoryID, gtk_object_get_data (GTK_OBJECT (widget), HistoryID));
+ gb_widget_output_int (data, MaxSaved, gnome_entry_get_max_saved (GNOME_ENTRY (gentry)));
+ gb_widget_output_translatable_string (data, Title, gtk_object_get_data (GTK_OBJECT (widget), Title));
+ gb_widget_output_bool (data, Directory,
+ gnome_file_entry_get_directory_entry (GNOME_FILE_ENTRY (widget)));
+ gb_widget_output_bool (data, Modal,
+ gnome_file_entry_get_modal (GNOME_FILE_ENTRY (widget)));
+ g_object_get (G_OBJECT (widget),
+ "use_filechooser", &use_filechooser,
+ "filechooser_action", &action,
+ NULL);
+ gb_widget_output_bool (data, FileChooser, use_filechooser);
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]); i++)
+ {
+ if (GbActionValues[i] == action)
+ gb_widget_output_choice (data, Action, i, GbActionSymbols[i]);
+ }
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_file_entry_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GtkWidget *gentry;
+ gchar *history_id, *title, *action;
+ gint max_saved, i;
+ gboolean directory, modal, use_filechooser;
+
+ gentry = gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (widget));
+
+ history_id = gb_widget_input_string (data, HistoryID);
+ if (data->apply)
+ gtk_object_set_data_full (GTK_OBJECT (widget), HistoryID,
+ g_strdup (history_id),
+ history_id ? g_free : NULL);
+
+ max_saved = gb_widget_input_int (data, MaxSaved);
+ if (data->apply)
+ gnome_entry_set_max_saved (GNOME_ENTRY (gentry), max_saved);
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ {
+ gtk_object_set_data_full (GTK_OBJECT (widget), Title, g_strdup (title),
+ title ? g_free : NULL);
+ gnome_file_entry_set_title (GNOME_FILE_ENTRY (widget),
+ title && title[0] ? title : NULL);
+ }
+
+ directory = gb_widget_input_bool (data, Directory);
+ if (data->apply)
+ gnome_file_entry_set_directory_entry (GNOME_FILE_ENTRY (widget), directory);
+
+ modal = gb_widget_input_bool (data, Modal);
+ if (data->apply)
+ gnome_file_entry_set_modal (GNOME_FILE_ENTRY (widget), modal);
+
+ use_filechooser = gb_widget_input_bool (data, FileChooser);
+ if (data->apply)
+ g_object_set (G_OBJECT (widget), "use_filechooser", use_filechooser, NULL);
+
+ action = gb_widget_input_choice (data, Action);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (!strcmp (action, GbActionChoices[i])
+ || !strcmp (action, GbActionSymbols[i]))
+ {
+ g_object_set (widget, "filechooser_action", GbActionValues[i], NULL);
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeFileEntry, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_file_entry_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_file_entry_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GtkWidget *gentry, *entry;
+ gchar *title, *history_id;
+ gchar *wname, *child_name;
+ gboolean use_filechooser = FALSE;
+ GtkFileChooserAction action;
+ gboolean translatable, context;
+ gchar *comments;
+
+ gentry = gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (widget));
+
+ title = gtk_object_get_data (GTK_OBJECT (widget), Title);
+ if (title && title[0] == '\0')
+ title = NULL;
+
+ history_id = gtk_object_get_data (GTK_OBJECT (widget), HistoryID);
+ if (history_id && history_id[0] == '\0')
+ history_id = NULL;
+
+ if (data->create_widget)
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gnome_file_entry_new (%s, ",
+ data->wname,
+ history_id ? source_make_string (history_id, FALSE) : "NULL");
+
+ source_add (data, "%s);\n",
+ title ? source_make_string_full (title, data->use_gettext && translatable, context) : "NULL");
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ /* Note that GLADE_DEFAULT_MAX_HISTORY_SAVED is copied from gnome-entry.c */
+ if (gnome_entry_get_max_saved (GNOME_ENTRY (gentry)) != GLADE_DEFAULT_MAX_HISTORY_SAVED)
+ source_add (data, " gnome_entry_set_max_saved (GNOME_ENTRY (gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (%s))), %i);\n",
+ data->wname,
+ gnome_entry_get_max_saved (GNOME_ENTRY (gentry)));
+
+ if (gnome_file_entry_get_directory_entry (GNOME_FILE_ENTRY (widget)))
+ source_add (data,
+ " gnome_file_entry_set_directory_entry (GNOME_FILE_ENTRY (%s), TRUE);\n",
+ data->wname);
+
+ if (gnome_file_entry_get_modal (GNOME_FILE_ENTRY (widget)))
+ source_add (data,
+ " gnome_file_entry_set_modal (GNOME_FILE_ENTRY (%s), TRUE);\n",
+ data->wname);
+
+ g_object_get (G_OBJECT (widget),
+ "use_filechooser", &use_filechooser,
+ "filechooser_action", &action,
+ NULL);
+
+ if (use_filechooser)
+ {
+ const gchar *action_symbol = GbActionSymbols[0];
+ gint i;
+
+ for (i = 0; i < sizeof (GbActionValues) / sizeof (GbActionValues[0]);
+ i++)
+ {
+ if (GbActionValues[i] == action)
+ action_symbol = GbActionSymbols[i];
+ }
+
+ source_add (data,
+ " g_object_set (G_OBJECT (%s),\n"
+ " \"use_filechooser\", TRUE,\n"
+ " \"filechooser_action\", %s,\n"
+ " NULL);\n",
+ data->wname, action_symbol);
+ }
+
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_COMBO (<combo-name>)->entry".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ entry = GTK_COMBO (gentry)->entry;
+ child_name = (char*) gtk_widget_get_name (entry);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data,
+ " %s = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (entry, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_gnome_file_entry_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildGnomeEntry))
+ return gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (widget));
+ else
+ return NULL;
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_file_entry_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_file_entry_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_fileentry_xpm;
+ gbwidget.tooltip = _("Gnome File Entry");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_file_entry_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_file_entry_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_file_entry_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_file_entry_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_file_entry_write_source;
+ gbwidget.gb_widget_get_child = gb_gnome_file_entry_get_child;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_file_entry_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomefontpicker.c b/tools/glade/glade/gnome/gnomefontpicker.c
new file mode 100644
index 00000000..5c38972a
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomefontpicker.c
@@ -0,0 +1,406 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-fontpicker.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* Copied from gnome-font-picker.c */
+#define DEF_PREVIEW_TEXT "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
+
+static gchar *Title = "GnomeFontPicker::title";
+static gchar *PreviewText = "GnomeFontPicker::preview_text";
+static gchar *Mode = "GnomeFontPicker::mode";
+static gchar *ShowSize = "GnomeFontPicker::show_size";
+static gchar *UseFont = "GnomeFontPicker::use_font_in_label";
+static gchar *UseFontSize = "GnomeFontPicker::label_font_size";
+static gchar *FocusOnClick = "GnomeFontPicker|GtkButton::focus_on_click";
+
+static const gchar *GbModeChoices[] =
+{
+ "Pixmap",
+ "Font Information",
+ NULL
+};
+static const gint GbModeValues[] =
+{
+ GNOME_FONT_PICKER_MODE_PIXMAP,
+ GNOME_FONT_PICKER_MODE_FONT_INFO
+};
+static const gchar *GbModeSymbols[] =
+{
+ "GNOME_FONT_PICKER_MODE_PIXMAP",
+ "GNOME_FONT_PICKER_MODE_FONT_INFO"
+};
+
+
+static void gb_gnome_font_picker_set_property_states (GtkWidget *widget);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeFontPicker, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_font_picker_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gnome_font_picker_new ();
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_font_picker_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (Title, _("Title:"),
+ _("The title of the font selection dialog"));
+ property_add_string (PreviewText, _("Preview Text:"),
+ _("The preview text to show in the font selection dialog"));
+ property_add_choice (Mode, _("Mode:"),
+ _("What to display in the font picker button"),
+ GbModeChoices);
+ property_add_bool (ShowSize, _("Show Size:"),
+ _("If the font size is shown as part of the font information"));
+ property_add_bool (UseFont, _("Use Font:"),
+ _("If the selected font is used when displaying the font information"));
+ property_add_int_range (UseFontSize, _("Use Size:"),
+ _("The size of the font to use in the font picker button"),
+ 2, 1000, 1, 10, 1);
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_font_picker_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gint i, show_size, use_font_in_label, use_font_in_label_size;
+ const gchar *title, *preview_text;
+
+ /* Only save if the title is different to the default. */
+ title = gnome_font_picker_get_title (GNOME_FONT_PICKER (widget));
+ if (data->action == GB_SHOWING
+ || (title && strcmp (title, dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE,
+ "Pick a Font"))))
+ gb_widget_output_translatable_string (data, Title, title);
+
+ /* Only save if the preview text is different to the default. */
+ preview_text = gnome_font_picker_get_preview_text (GNOME_FONT_PICKER (widget));
+ if (data->action == GB_SHOWING
+ || (preview_text && strcmp (dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE,
+ DEF_PREVIEW_TEXT), preview_text)))
+ gb_widget_output_translatable_string (data, PreviewText, preview_text);
+
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == gnome_font_picker_get_mode (GNOME_FONT_PICKER (widget)))
+ gb_widget_output_choice (data, Mode, i, GbModeSymbols[i]);
+ }
+
+ g_object_get (G_OBJECT (widget),
+ "show-size", &show_size,
+ "use-font-in-label", &use_font_in_label,
+ "label-font-size", &use_font_in_label_size,
+ NULL);
+
+ gb_widget_output_bool (data, ShowSize, show_size);
+ gb_widget_output_bool (data, UseFont, use_font_in_label);
+ gb_widget_output_int (data, UseFontSize, use_font_in_label_size);
+
+ if (data->action == GB_SHOWING)
+ gb_gnome_font_picker_set_property_states (widget);
+
+ gb_widget_output_bool (data, FocusOnClick,
+ gtk_button_get_focus_on_click (GTK_BUTTON (widget)));
+}
+
+
+static void
+gb_gnome_font_picker_set_property_states (GtkWidget *widget)
+{
+ gboolean use_font_sens = FALSE, use_font_size_sens = FALSE;
+
+ if (gnome_font_picker_get_mode (GNOME_FONT_PICKER (widget)) == GNOME_FONT_PICKER_MODE_FONT_INFO)
+ {
+ use_font_sens = TRUE;
+ g_object_get (G_OBJECT (widget),
+ "use-font-in-label", &use_font_size_sens,
+ NULL);
+ }
+ property_set_sensitive (ShowSize, use_font_sens);
+ property_set_sensitive (UseFont, use_font_sens);
+ property_set_sensitive (UseFontSize, use_font_size_sens);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_font_picker_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *title, *preview_text, *mode;
+ gint i, use_font_size, new_use_font_size;
+ gboolean show_size, use_font, focus_on_click;
+ gboolean new_use_font, set_use_font = FALSE;
+ gboolean set_property_states = FALSE;
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ gnome_font_picker_set_title (GNOME_FONT_PICKER (widget),
+ title && title[0]
+ ? title : dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE,
+ "Pick a Font"));
+
+ preview_text = gb_widget_input_string (data, PreviewText);
+ if (data->apply)
+ gnome_font_picker_set_preview_text (GNOME_FONT_PICKER (widget),
+ preview_text && preview_text[0]
+ ? preview_text : DEF_PREVIEW_TEXT);
+
+ mode = gb_widget_input_choice (data, Mode);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (!strcmp (mode, GbModeChoices[i])
+ || !strcmp (mode, GbModeSymbols[i]))
+ {
+ gnome_font_picker_set_mode (GNOME_FONT_PICKER (widget),
+ GbModeValues[i]);
+ set_property_states = TRUE;
+ break;
+ }
+ }
+ }
+
+ show_size = gb_widget_input_bool (data, ShowSize);
+ if (data->apply)
+ gnome_font_picker_fi_set_show_size (GNOME_FONT_PICKER (widget),
+ show_size);
+
+ g_object_get (G_OBJECT (widget),
+ "use-font-in-label", &new_use_font,
+ "label-font-size", &new_use_font_size,
+ NULL);
+
+ use_font = gb_widget_input_bool (data, UseFont);
+ if (data->apply)
+ {
+ new_use_font = use_font;
+ set_use_font = TRUE;
+ }
+
+ use_font_size = gb_widget_input_int (data, UseFontSize);
+ if (data->apply)
+ {
+ new_use_font_size = use_font_size;
+ set_use_font = TRUE;
+ }
+
+ if (set_use_font)
+ {
+ gnome_font_picker_fi_set_use_font_in_label (GNOME_FONT_PICKER (widget),
+ new_use_font,
+ new_use_font_size);
+ set_property_states = TRUE;
+ }
+
+ if ((data->action == GB_APPLYING) && set_property_states)
+ gb_gnome_font_picker_set_property_states (widget);
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_button_set_focus_on_click (GTK_BUTTON (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeFontPicker, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_font_picker_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_font_picker_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ const gchar *title, *preview_text;
+ gint i;
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ source_add (data, " %s = gnome_font_picker_new ();\n", data->wname);
+
+ gb_widget_write_standard_source (widget, data);
+
+ title = gnome_font_picker_get_title (GNOME_FONT_PICKER (widget));
+ if (title && title[0]
+ && strcmp (title, dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE,
+ "Pick a Font")))
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_font_picker_set_title (GNOME_FONT_PICKER (%s), %s);\n",
+ data->wname, source_make_string_full (title, data->use_gettext && translatable, context));
+ }
+
+ preview_text = gnome_font_picker_get_preview_text (GNOME_FONT_PICKER (widget));
+ if (preview_text && preview_text[0]
+ && strcmp (dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE, DEF_PREVIEW_TEXT),
+ preview_text))
+ {
+ glade_util_get_translation_properties (widget, PreviewText,
+ &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " gnome_font_picker_set_preview_text (GNOME_FONT_PICKER (%s), %s);\n",
+ data->wname, source_make_string_full (preview_text,
+ data->use_gettext && translatable, context));
+ }
+
+ if (gnome_font_picker_get_mode (GNOME_FONT_PICKER (widget)) != GNOME_FONT_PICKER_MODE_PIXMAP)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == gnome_font_picker_get_mode (GNOME_FONT_PICKER (widget)))
+ source_add (data,
+ " gnome_font_picker_set_mode (GNOME_FONT_PICKER (%s),\n"
+ " %s);\n",
+ data->wname, GbModeSymbols[i]);
+ }
+ }
+
+ if (gnome_font_picker_get_mode (GNOME_FONT_PICKER (widget)) == GNOME_FONT_PICKER_MODE_FONT_INFO)
+ {
+ int show_size, use_font_in_label, label_font_size;
+ g_object_get (G_OBJECT (widget),
+ "show-size", &show_size,
+ "use-font-in-label", &use_font_in_label,
+ "label-font-size", &label_font_size,
+ NULL);
+ if (!show_size)
+ {
+ source_add (data,
+ " gnome_font_picker_fi_set_show_size (GNOME_FONT_PICKER (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (use_font_in_label)
+ {
+ source_add (data,
+ " gnome_font_picker_fi_set_use_font_in_label (GNOME_FONT_PICKER (%s),\n"
+ " TRUE, %i);\n",
+ data->wname,
+ label_font_size);
+ }
+ }
+
+ if (!gtk_button_get_focus_on_click (GTK_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_button_set_focus_on_click (GTK_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_font_picker_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_font_picker_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_fontpicker_xpm;
+ gbwidget.tooltip = _("Gnome Font Picker");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_font_picker_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_font_picker_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_font_picker_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_font_picker_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_font_picker_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_font_picker_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomehref.c b/tools/glade/glade/gnome/gnomehref.c
new file mode 100644
index 00000000..fdbeb438
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomehref.c
@@ -0,0 +1,220 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-href.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HRefURL = "GnomeHRef::url";
+static gchar *HRefLabel = "GnomeHRef::text";
+static gchar *FocusOnClick = "GnomeHRef|GtkButton::focus_on_click";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeHRef, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+/*
+static GtkWidget*
+gb_gnome_href_new (GbWidgetNewData *data)
+{
+
+}
+*/
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_href_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (HRefURL, _("URL:"),
+ _("The URL to display when the button is clicked"));
+ property_add_text (HRefLabel, _("Label:"),
+ _("The text to display in the button"), 2);
+ property_add_bool (FocusOnClick, _("Focus On Click:"), _("If the button grabs focus when it is clicked"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_href_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gchar *uri, *label;
+
+ g_object_get (G_OBJECT (widget),
+ "url", &uri,
+ "text", &label,
+ NULL);
+ gb_widget_output_string (data, HRefURL, uri);
+ gb_widget_output_translatable_text (data, HRefLabel, label);
+
+ g_free (uri);
+ g_free (label);
+
+ gb_widget_output_bool (data, FocusOnClick,
+ gtk_button_get_focus_on_click (GTK_BUTTON (widget)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_href_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *url, *label_text;
+ gboolean focus_on_click;
+
+ url = gb_widget_input_string (data, HRefURL);
+ if (data->apply)
+ gnome_href_set_url (GNOME_HREF (widget), url && url[0] ? url : "");
+
+ label_text = gb_widget_input_text (data, HRefLabel);
+ /* Support the old name we used for the property. */
+ if (!data->apply && data->action == GB_LOADING)
+ label_text = gb_widget_input_text (data, "label");
+ if (data->apply)
+ gnome_href_set_text (GNOME_HREF (widget), label_text);
+ if (data->action == GB_APPLYING)
+ g_free (label_text);
+
+ focus_on_click = gb_widget_input_bool (data, FocusOnClick);
+ if (data->apply)
+ gtk_button_set_focus_on_click (GTK_BUTTON (widget), focus_on_click);
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeHRef, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_href_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_href_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gboolean translatable, context;
+ gchar *comments;
+
+ if (data->create_widget)
+ {
+ gchar *url, *label_text;
+
+ g_object_get (G_OBJECT (widget),
+ "url", &url,
+ "text", &label_text,
+ NULL);
+
+ glade_util_get_translation_properties (widget, HRefURL, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gnome_href_new (%s, ",
+ data->wname,
+ url && *url ? source_make_string (url, FALSE) : "\"\"");
+
+ source_add (data, "%s);\n",
+ source_make_string_full (label_text, data->use_gettext && translatable, context));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!gtk_button_get_focus_on_click (GTK_BUTTON (widget)))
+ {
+ source_add (data,
+ " gtk_button_set_focus_on_click (GTK_BUTTON (%s), FALSE);\n",
+ data->wname);
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_href_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_href_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_href_xpm;
+ gbwidget.tooltip = _("Gnome HRef Link Button");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_create_properties = gb_gnome_href_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_href_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_href_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_href_write_source;
+/*
+ gbwidget.gb_widget_new = gb_gnome_href_new;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_href_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeiconentry.c b/tools/glade/glade/gnome/gnomeiconentry.c
new file mode 100644
index 00000000..55f55caf
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeiconentry.c
@@ -0,0 +1,222 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-iconentry.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *HistoryID = "GnomeIconEntry|GnomeEntry::history_id";
+static gchar *MaxSaved = "GnomeIconEntry|GnomeEntry::max_saved";
+static gchar *Title = "GnomeIconEntry::browse_dialog_title";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeIconEntry, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_icon_entry_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gnome_icon_entry_new (NULL, NULL);
+
+ /* Set MaxSaved to the default. */
+ gtk_object_set_data (GTK_OBJECT (new_widget), MaxSaved,
+ GINT_TO_POINTER (GLADE_DEFAULT_MAX_HISTORY_SAVED));
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_icon_entry_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_string (Title, _("Title:"),
+ _("The title of the file selection dialog"));
+ property_add_string (HistoryID, _("History ID:"),
+ _("The ID to save the history entries under"));
+ property_add_int_range (MaxSaved, _("Max Saved:"),
+ _("The maximum number of history entries saved"),
+ 0, 10000, 1, 10, 1);
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_icon_entry_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_widget_output_translatable_string (data, Title, gtk_object_get_data (GTK_OBJECT (widget), Title));
+ gb_widget_output_string (data, HistoryID, gtk_object_get_data (GTK_OBJECT (widget), HistoryID));
+ gb_widget_output_int (data, MaxSaved, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), MaxSaved)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_icon_entry_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *title, *history_id;
+ gint max_saved;
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ {
+ gtk_object_set_data_full (GTK_OBJECT (widget), Title, g_strdup (title),
+ title ? g_free : NULL);
+ gnome_icon_entry_set_browse_dialog_title (GNOME_ICON_ENTRY (widget),
+ title && title[0] ? title : "");
+ }
+
+ history_id = gb_widget_input_string (data, HistoryID);
+ if (data->apply)
+ gtk_object_set_data_full (GTK_OBJECT (widget), HistoryID,
+ g_strdup (history_id),
+ history_id ? g_free : NULL);
+
+ max_saved = gb_widget_input_int (data, MaxSaved);
+ if (data->apply)
+ gtk_object_set_data (GTK_OBJECT (widget), MaxSaved,
+ GINT_TO_POINTER (max_saved));
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeIconEntry, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_icon_entry_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_icon_entry_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *title, *history_id;
+ gint max_saved;
+ gboolean translatable, context;
+ gchar *comments;
+
+ title = gtk_object_get_data (GTK_OBJECT (widget), Title);
+ if (title && title[0] == '\0')
+ title = NULL;
+
+ history_id = gtk_object_get_data (GTK_OBJECT (widget), HistoryID);
+ if (history_id && history_id[0] == '\0')
+ history_id = NULL;
+
+ if (data->create_widget)
+ {
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data, " %s = gnome_icon_entry_new (%s, ",
+ data->wname,
+ history_id ? source_make_string (history_id, FALSE) : "NULL");
+
+ source_add (data, "%s);\n",
+ title ? source_make_string_full (title, data->use_gettext && translatable, context) : "NULL");
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ /* Note that GLADE_DEFAULT_MAX_HISTORY_SAVED is copied from gnome-entry.c */
+ max_saved = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ MaxSaved));
+ if (max_saved != GLADE_DEFAULT_MAX_HISTORY_SAVED)
+ source_add (data, " gnome_entry_set_max_saved (GNOME_ENTRY (gnome_icon_entry_gnome_entry (GNOME_ICON_ENTRY (%s))), %i);\n",
+ data->wname, max_saved);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_icon_entry_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_icon_entry_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_iconentry_xpm;
+ gbwidget.tooltip = _("Gnome Icon Entry");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_icon_entry_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_icon_entry_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_icon_entry_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_icon_entry_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_icon_entry_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_icon_entry_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeiconlist.c b/tools/glade/glade/gnome/gnomeiconlist.c
new file mode 100644
index 00000000..12b7d6eb
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeiconlist.c
@@ -0,0 +1,475 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-iconlist.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+#define DEFAULT_ICON_WIDTH 78
+
+/* These are pinched from GnomeIconList */
+#define DEFAULT_ROW_SPACING 4
+#define DEFAULT_COL_SPACING 2
+#define DEFAULT_TEXT_SPACING 2
+#define DEFAULT_ICON_BORDER 2
+
+static gchar *SelectionMode = "GnomeIconList::selection_mode";
+static gchar *IconWidth = "GnomeIconList::icon_width";
+static gchar *RowSpacing = "GnomeIconList::row_spacing";
+static gchar *ColSpacing = "GnomeIconList::column_spacing";
+#if 0
+/* The icon border property doesn't seem to be used. */
+static gchar *IconBorder = "GnomeIconList::icon_border";
+#endif
+static gchar *TextSpacing = "GnomeIconList::text_spacing";
+static gchar *TextEditable = "GnomeIconList::text_editable";
+static gchar *TextStatic = "GnomeIconList::text_static";
+
+static const gchar *GbModeChoices[] =
+{"Single", "Browse", "Multiple", NULL};
+static const gint GbModeValues[] =
+{
+ GTK_SELECTION_SINGLE,
+ GTK_SELECTION_BROWSE,
+ GTK_SELECTION_MULTIPLE
+};
+static const gchar *GbModeSymbols[] =
+{
+ "GTK_SELECTION_SINGLE",
+ "GTK_SELECTION_BROWSE",
+ "GTK_SELECTION_MULTIPLE"
+};
+
+static gint gb_gnome_icon_list_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data);
+static void gb_gnome_icon_list_adjustment_changed (GtkAdjustment *adjustment,
+ GtkWidget *widget);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeIconList, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_icon_list_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ GdkPixbuf *image;
+ gint i;
+
+ new_widget = gnome_icon_list_new (DEFAULT_ICON_WIDTH, NULL, 0);
+
+ image = gdk_pixbuf_new_from_xpm_data ((const char**) gnome_iconlist_xpm);
+ for (i = 0; i < 10; i++)
+ {
+ gnome_icon_list_append_pixbuf (GNOME_ICON_LIST (new_widget), image,
+ NULL,
+ "This is an example icon");
+ }
+ gdk_pixbuf_unref (image);
+ /* We save the property values in the GnomeIconList's data list, since they
+ are not available from GnomeIconList in any way.
+ We let TextEditable and TextStatic default to FALSE so we don't need to
+ set them here. */
+ gtk_object_set_data (GTK_OBJECT (new_widget), SelectionMode,
+ GINT_TO_POINTER (GTK_SELECTION_SINGLE));
+ gtk_object_set_data (GTK_OBJECT (new_widget), IconWidth,
+ GINT_TO_POINTER (DEFAULT_ICON_WIDTH));
+ gtk_object_set_data (GTK_OBJECT (new_widget), RowSpacing,
+ GINT_TO_POINTER (DEFAULT_ROW_SPACING));
+ gtk_object_set_data (GTK_OBJECT (new_widget), ColSpacing,
+ GINT_TO_POINTER (DEFAULT_COL_SPACING));
+#if 0
+ gtk_object_set_data (GTK_OBJECT (new_widget), IconBorder,
+ GINT_TO_POINTER (DEFAULT_ICON_BORDER));
+#endif
+ gtk_object_set_data (GTK_OBJECT (new_widget), TextSpacing,
+ GINT_TO_POINTER (DEFAULT_TEXT_SPACING));
+
+ /* We connect to the expose event so we can connect to the "value_changed"
+ signals of the scrollbar adjustments. The scrollbars aren't setup until
+ the widget is added to a scrolled window. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "expose_event",
+ (GtkSignalFunc) gb_gnome_icon_list_expose, NULL);
+
+ return new_widget;
+}
+
+
+/* If data is not NULL, then we are creating the widget, so the step increments
+ are set to a decent initial value. */
+static gint
+gb_gnome_icon_list_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ if (GNOME_ICON_LIST (widget)->adj)
+ gtk_signal_connect (GTK_OBJECT (GNOME_ICON_LIST (widget)->adj),
+ "value_changed",
+ (GtkSignalFunc) gb_gnome_icon_list_adjustment_changed,
+ widget);
+ if (GNOME_ICON_LIST (widget)->hadj)
+ gtk_signal_connect (GTK_OBJECT (GNOME_ICON_LIST (widget)->hadj),
+ "value_changed",
+ (GtkSignalFunc) gb_gnome_icon_list_adjustment_changed,
+ widget);
+
+ /* Disconnect this handler since we don't need it any more. */
+ gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
+ (GtkSignalFunc) gb_gnome_icon_list_expose,
+ data);
+ return FALSE;
+}
+
+
+static void
+gb_gnome_icon_list_adjustment_changed (GtkAdjustment *adjustment,
+ GtkWidget *widget)
+{
+ /* Just queue a complete clear for now. It's good enough. */
+ gtk_widget_queue_clear (widget);
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_icon_list_create_properties (GtkWidget * widget,
+ GbWidgetCreateArgData * data)
+{
+ property_add_choice (SelectionMode, _("Select Mode:"),
+ _("The selection mode"),
+ GbModeChoices);
+ property_add_int_range (IconWidth, _("Icon Width:"),
+ _("The width of each icon"),
+ 1, 10000, 1, 10, 1);
+ property_add_int_range (RowSpacing, _("Row Spacing:"),
+ _("The number of pixels between rows of icons"),
+ 0, 10000, 1, 10, 1);
+ property_add_int_range (ColSpacing, _("Col Spacing:"),
+ _("The number of pixels between columns of icons"),
+ 0, 10000, 1, 10, 1);
+#if 0
+ property_add_int_range (IconBorder, _("Icon Border:"),
+ _("The number of pixels around icons (unused?)"),
+ 0, 10000, 1, 10, 1);
+#endif
+ property_add_int_range (TextSpacing, _("Text Spacing:"),
+ _("The number of pixels between the text and the icon"),
+ 0, 10000, 1, 10, 1);
+ property_add_bool (TextEditable, _("Text Editable:"),
+ _("If the icon text can be edited by the user"));
+ property_add_bool (TextStatic, _("Text Static:"),
+ _("If the icon text is static, in which case it will not be copied by the GnomeIconList"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_icon_list_get_properties (GtkWidget *widget,
+ GbWidgetGetArgData * data)
+{
+ GnomeIconList *gil;
+ gint selection_mode, i;
+
+ gil = (GnomeIconList*) widget;
+
+ selection_mode = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ SelectionMode));
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == selection_mode)
+ gb_widget_output_choice (data, SelectionMode, i, GbModeSymbols[i]);
+ }
+
+ gb_widget_output_int (data, IconWidth, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), IconWidth)));
+ gb_widget_output_int (data, RowSpacing, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), RowSpacing)));
+ gb_widget_output_int (data, ColSpacing, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), ColSpacing)));
+#if 0
+ gb_widget_output_int (data, IconBorder, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), IconBorder)));
+#endif
+ gb_widget_output_int (data, TextSpacing, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), TextSpacing)));
+ gb_widget_output_bool (data, TextEditable, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), TextEditable)));
+ gb_widget_output_bool (data, TextStatic, GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), TextStatic)));
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_icon_list_set_properties (GtkWidget * widget,
+ GbWidgetSetArgData * data)
+{
+ gchar *mode;
+ gint icon_width, row_spacing, col_spacing, /*icon_border,*/ text_spacing, i;
+ gboolean text_editable, text_static;
+
+ mode = gb_widget_input_choice (data, SelectionMode);
+ if (data->apply)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (!strcmp (mode, GbModeChoices[i])
+ || !strcmp (mode, GbModeSymbols[i]))
+ {
+ gnome_icon_list_set_selection_mode (GNOME_ICON_LIST (widget),
+ GbModeValues[i]);
+ gtk_object_set_data (GTK_OBJECT (widget), SelectionMode,
+ GINT_TO_POINTER (GbModeValues[i]));
+ break;
+ }
+ }
+ }
+
+ icon_width = gb_widget_input_int (data, IconWidth);
+ if (data->apply)
+ {
+ gnome_icon_list_set_icon_width (GNOME_ICON_LIST (widget), icon_width);
+ gtk_object_set_data (GTK_OBJECT (widget), IconWidth,
+ GINT_TO_POINTER (icon_width));
+ }
+
+ row_spacing = gb_widget_input_int (data, RowSpacing);
+ if (data->apply)
+ {
+ gnome_icon_list_set_row_spacing (GNOME_ICON_LIST (widget), row_spacing);
+ gtk_object_set_data (GTK_OBJECT (widget), RowSpacing,
+ GINT_TO_POINTER (row_spacing));
+ }
+
+ col_spacing = gb_widget_input_int (data, ColSpacing);
+ if (data->apply)
+ {
+ gnome_icon_list_set_col_spacing (GNOME_ICON_LIST (widget), col_spacing);
+ gtk_object_set_data (GTK_OBJECT (widget), ColSpacing,
+ GINT_TO_POINTER (col_spacing));
+ }
+
+#if 0
+ icon_border = gb_widget_input_int (data, IconBorder);
+ if (data->apply)
+ {
+ gnome_icon_list_set_icon_border (GNOME_ICON_LIST (widget), icon_border);
+ gtk_object_set_data (GTK_OBJECT (widget), IconBorder,
+ GINT_TO_POINTER (icon_border));
+ }
+#endif
+
+ text_spacing = gb_widget_input_int (data, TextSpacing);
+ if (data->apply)
+ {
+ gnome_icon_list_set_text_spacing (GNOME_ICON_LIST (widget),
+ text_spacing);
+ gtk_object_set_data (GTK_OBJECT (widget), TextSpacing,
+ GINT_TO_POINTER (text_spacing));
+ }
+
+ text_editable = gb_widget_input_bool (data, TextEditable);
+ if (data->apply)
+ {
+ /* GnomeIconList doesn't have a function to set this. We may also want
+ to reconfigure any example icon items so this works. */
+ gtk_object_set_data (GTK_OBJECT (widget), TextEditable,
+ GINT_TO_POINTER (text_editable));
+ }
+
+ text_static = gb_widget_input_bool (data, TextStatic);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), TextStatic,
+ GINT_TO_POINTER (text_static));
+ }
+}
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeIconList, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_icon_list_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_icon_list_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ gint icon_width, row_spacing, col_spacing, /*icon_border,*/ text_spacing;
+ gint i, selection_mode;
+ gboolean text_editable, text_static;
+ gchar *flags;
+
+ icon_width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ IconWidth));
+ text_editable = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ TextEditable));
+ text_static = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ TextStatic));
+
+ if (data->create_widget)
+ {
+ if (text_editable && text_static)
+ flags = "GNOME_ICON_LIST_IS_EDITABLE | GNOME_ICON_LIST_STATIC_TEXT";
+ else if (text_editable)
+ flags = "GNOME_ICON_LIST_IS_EDITABLE";
+ else if (text_static)
+ flags = "GNOME_ICON_LIST_STATIC_TEXT";
+ else
+ flags = "0";
+
+ source_add (data, " %s = gnome_icon_list_new (%i, NULL, %s);\n",
+ data->wname, icon_width, flags);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ if (!data->create_widget)
+ {
+ if (icon_width != DEFAULT_ICON_WIDTH)
+ {
+ source_add (data,
+ " gnome_icon_list_set_icon_width (GNOME_ICON_LIST (%s), %i);\n",
+ data->wname, icon_width);
+ }
+ }
+
+ row_spacing = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ RowSpacing));
+ if (row_spacing != DEFAULT_ROW_SPACING)
+ {
+ source_add (data,
+ " gnome_icon_list_set_row_spacing (GNOME_ICON_LIST (%s), %i);\n",
+ data->wname, row_spacing);
+ }
+
+ col_spacing = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ ColSpacing));
+ if (col_spacing != DEFAULT_COL_SPACING)
+ {
+ source_add (data,
+ " gnome_icon_list_set_col_spacing (GNOME_ICON_LIST (%s), %i);\n",
+ data->wname, col_spacing);
+ }
+
+#if 0
+ icon_border = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ IconBorder));
+ if (icon_border != DEFAULT_ICON_BORDER)
+ {
+ source_add (data,
+ " gnome_icon_list_set_icon_border (GNOME_ICON_LIST (%s), %i);\n",
+ data->wname, icon_border);
+ }
+#endif
+
+ text_spacing = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ TextSpacing));
+ if (text_spacing != DEFAULT_TEXT_SPACING)
+ {
+ source_add (data,
+ " gnome_icon_list_set_text_spacing (GNOME_ICON_LIST (%s), %i);\n",
+ data->wname, text_spacing);
+ }
+
+ selection_mode = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ SelectionMode));
+ if (selection_mode != GTK_SELECTION_SINGLE)
+ {
+ for (i = 0; i < sizeof (GbModeValues) / sizeof (GbModeValues[0]); i++)
+ {
+ if (GbModeValues[i] == selection_mode)
+ source_add (data,
+ " gnome_icon_list_set_selection_mode (GNOME_ICON_LIST (%s), %s);\n",
+ data->wname, GbModeSymbols[i]);
+ }
+ }
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_icon_list_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_icon_list_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_iconlist_xpm;
+ gbwidget.tooltip = _("Icon List");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_icon_list_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_icon_list_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_icon_list_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_icon_list_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_icon_list_write_source;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_icon_list_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomeiconselection.c b/tools/glade/glade/gnome/gnomeiconselection.c
new file mode 100644
index 00000000..279753d7
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomeiconselection.c
@@ -0,0 +1,168 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-iconselection.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeIconSelection, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_icon_selection_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gnome_icon_selection_new ();
+ gnome_icon_selection_add_defaults (GNOME_ICON_SELECTION (new_widget));
+#if 0
+ gnome_icon_selection_show_icons (GNOME_ICON_SELECTION (new_widget));
+#endif
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+/*
+static void
+gb_gnome_icon_selection_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+/*
+static void
+gb_gnome_icon_selection_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+/*
+static void
+gb_gnome_icon_selection_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeIconSelection, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_icon_selection_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_icon_selection_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_icon_selection_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_icon_selection_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_icon_selection_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_iconselection_xpm;
+ gbwidget.tooltip = _("Icon Selection");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_icon_selection_new;
+ gbwidget.gb_widget_write_source = gb_gnome_icon_selection_write_source;
+/*
+ gbwidget.gb_widget_create_properties = gb_gnome_icon_selection_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_icon_selection_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_icon_selection_set_properties;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_icon_selection_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomemessagebox.c b/tools/glade/glade/gnome/gnomemessagebox.c
new file mode 100644
index 00000000..e8ca907a
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomemessagebox.c
@@ -0,0 +1,515 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+#include "../glade_gnome.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-messagebox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GnomeMessageBox|GtkWindow::title";
+static gchar *Position = "GnomeMessageBox|GtkWindow::window_position";
+static gchar *Modal = "GnomeMessageBox|GtkWindow::modal";
+static gchar *DefaultWidth = "GnomeMessageBox|GtkWindow::default_width";
+static gchar *DefaultHeight = "GnomeMessageBox|GtkWindow::default_height";
+static gchar *Shrink = "GnomeMessageBox|GtkWindow::allow_shrink";
+static gchar *Grow = "GnomeMessageBox|GtkWindow::allow_grow";
+static gchar *AutoShrink = "GnomeMessageBox|GtkWindow::auto_shrink";
+static gchar *IconName = "GnomeMessageBox|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomeMessageBox|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "GnomeMessageBox|GtkWindow::resizable";
+static gchar *DestroyWithParent = "GnomeMessageBox|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomeMessageBox|GtkWindow::icon";
+
+static gchar *Role = "GnomeMessageBox|GtkWindow::role";
+static gchar *TypeHint = "GnomeMessageBox|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomeMessageBox|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomeMessageBox|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomeMessageBox|GtkWindow::decorated";
+static gchar *Gravity = "GnomeMessageBox|GtkWindow::gravity";
+static gchar *Urgency = "GnomeMessageBox|GtkWindow::urgency_hint";
+
+static gchar *MessageBoxType = "GnomeMessageBox::message_box_type";
+static gchar *Message = "GnomeMessageBox::message";
+
+static gchar *AutoClose = "GnomeMessageBox|GnomeDialog::auto_close";
+static gchar *HideOnClose = "GnomeMessageBox|GnomeDialog::hide_on_close";
+
+
+static const gchar *GbMessageBoxTypeChoices[] =
+{
+ "Information",
+ "Warning",
+ "Error",
+ "Question",
+ "Generic",
+ NULL
+};
+static const gchar *GbMessageBoxTypeSymbols[] =
+{
+ "GNOME_MESSAGE_BOX_INFO",
+ "GNOME_MESSAGE_BOX_WARNING",
+ "GNOME_MESSAGE_BOX_ERROR",
+ "GNOME_MESSAGE_BOX_QUESTION",
+ "GNOME_MESSAGE_BOX_GENERIC"
+};
+static const gchar* GbMessageBoxTypePixmapStockIDs[] =
+{
+ GTK_STOCK_DIALOG_INFO,
+ GTK_STOCK_DIALOG_WARNING,
+ GTK_STOCK_DIALOG_ERROR,
+ GTK_STOCK_DIALOG_QUESTION,
+ ""
+};
+
+
+static void get_message_box_widgets (GtkWidget *dialog,
+ GtkWidget **pixmap,
+ GtkWidget **label);
+static void set_message_box_type (GtkWidget *dialog,
+ GtkWidget *pixmap,
+ gchar *type_name);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the funtion in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomeMessageBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ * If the widget needs a special destroy handler, add a signal here.
+ */
+static GtkWidget*
+gb_gnome_message_box_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+ GList *elem;
+ GtkWidget *aa;
+
+ if (data->action == GB_CREATING)
+ {
+ /* When creating a new dialog, we add a few standard buttons, which
+ the user can change/delete easily. */
+ new_widget = gnome_message_box_new ("", GNOME_MESSAGE_BOX_INFO,
+ GTK_STOCK_OK, NULL);
+
+ /* Now turn the buttons into GbWidgets so the user can edit them. */
+ elem = GNOME_DIALOG (new_widget)->buttons;
+ gb_widget_create_from (GTK_WIDGET (elem->data), "button");
+ gtk_object_set_data (GTK_OBJECT (elem->data), GladeButtonStockIDKey,
+ GTK_STOCK_OK);
+ }
+ else
+ {
+ /* FIXME: We create it with an OK button, and then remove the button,
+ to work around a bug in gnome_message_box_new() - it tries to set the
+ keyboard focus to the last button, which may not exist. It also
+ ensures that gnome_dialog_init_action_area() has been called. */
+ new_widget = gnome_message_box_new ("", GNOME_MESSAGE_BOX_INFO,
+ GNOME_STOCK_BUTTON_OK, NULL);
+ gtk_container_remove (GTK_CONTAINER (GNOME_DIALOG (new_widget)->action_area),
+ GNOME_DIALOG (new_widget)->buttons->data);
+ GNOME_DIALOG (new_widget)->buttons = NULL;
+ }
+
+ aa = GNOME_DIALOG (new_widget)->action_area;
+
+ gb_widget_create_from (GNOME_DIALOG (new_widget)->vbox,
+ data->action == GB_CREATING ? "dialog-vbox" : NULL);
+ gb_widget_set_child_name (GNOME_DIALOG (new_widget)->vbox, GladeChildDialogVBox);
+ gb_widget_create_from (aa,
+ data->action == GB_CREATING ? "dialog-action_area"
+ : NULL);
+ gb_widget_set_child_name (aa, GladeChildDialogActionArea);
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "close",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ return new_widget;
+}
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_message_box_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_choice (MessageBoxType, _("Message Type:"),
+ _("The type of the message box"),
+ GbMessageBoxTypeChoices);
+ property_add_text (Message, _("Message:"), _("The message to display"), 5);
+
+ /* We don't allow setting of the title, so we pass NULL here. */
+ gb_window_create_standard_properties (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ property_add_bool (AutoClose, _("Auto Close:"),
+ _("If the dialog closes when any button is clicked"));
+ property_add_bool (HideOnClose, _("Hide on Close:"),
+ _("If the dialog is hidden when it is closed, instead of being destroyed"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_message_box_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkWidget *pixmap, *label;
+ const gchar *label_text;
+ gint type_index;
+
+ get_message_box_widgets (widget, &pixmap, &label);
+ g_return_if_fail (pixmap != NULL);
+ g_return_if_fail (label != NULL);
+
+ type_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ MessageBoxType));
+ gb_widget_output_choice (data, MessageBoxType, type_index,
+ GbMessageBoxTypeSymbols[type_index]);
+
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ gb_widget_output_translatable_text (data, Message, label_text);
+
+ gb_window_get_standard_properties (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+ gb_widget_output_bool (data, AutoClose, GNOME_DIALOG (widget)->click_closes);
+ gb_widget_output_bool (data, HideOnClose, GNOME_DIALOG (widget)->just_hide);
+}
+
+
+/* This tries to find the pixmap and label in the message box. */
+static void
+get_message_box_widgets (GtkWidget *dialog,
+ GtkWidget **pixmap,
+ GtkWidget **label)
+{
+ GtkWidget *vbox, *hbox;
+ GtkBoxChild *child;
+ GList *elem;
+
+ *pixmap = NULL;
+ *label = NULL;
+
+ vbox = GNOME_DIALOG (dialog)->vbox;
+ if (!vbox || !GTK_IS_VBOX (vbox))
+ return;
+
+ for (elem = GTK_BOX (vbox)->children; elem; elem = elem->next)
+ {
+ child = (GtkBoxChild*)elem->data;
+ if (GTK_IS_HBOX (child->widget))
+ break;
+ }
+
+ if (!elem)
+ return;
+
+ hbox = child->widget;
+
+ elem = GTK_BOX (hbox)->children;
+ while (elem)
+ {
+ child = (GtkBoxChild*)elem->data;
+ if (GTK_IS_LABEL (child->widget))
+ *label = child->widget;
+ if (GTK_IS_IMAGE (child->widget))
+ *pixmap = child->widget;
+
+ elem = elem->next;
+ }
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_message_box_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GtkWidget *pixmap, *label;
+ gchar *message, *type_name;
+ gboolean auto_close, hide_on_close;
+
+ get_message_box_widgets (widget, &pixmap, &label);
+ g_return_if_fail (pixmap != NULL);
+ g_return_if_fail (label != NULL);
+
+ type_name = gb_widget_input_choice (data, MessageBoxType);
+ if (data->apply)
+ {
+ set_message_box_type (widget, pixmap, type_name);
+ }
+
+ message = gb_widget_input_text (data, Message);
+ if (data->apply)
+ {
+ gtk_label_set_text (GTK_LABEL (label), message);
+ }
+ if (data->action == GB_APPLYING)
+ g_free (message);
+
+ gb_window_set_standard_properties (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ auto_close = gb_widget_input_bool (data, AutoClose);
+ if (data->apply)
+ gnome_dialog_set_close (GNOME_DIALOG (widget), auto_close);
+
+ hide_on_close = gb_widget_input_bool (data, HideOnClose);
+ if (data->apply)
+ gnome_dialog_close_hides (GNOME_DIALOG (widget), hide_on_close);
+}
+
+
+/* Here we set the type of the message box, i.e. we change the pixmap. */
+static void
+set_message_box_type (GtkWidget *dialog,
+ GtkWidget *pixmap,
+ gchar *type_name)
+{
+ gint i, type_index = 0; /* Set to 0 in case we can't find it. */
+
+ /* Find out the index of the type. */
+ for (i = 0; GbMessageBoxTypeChoices[i]; i++)
+ {
+ if (!strcmp (type_name, GbMessageBoxTypeChoices[i])
+ || !strcmp (type_name, GbMessageBoxTypeSymbols[i]))
+ {
+ type_index = i;
+ break;
+ }
+ }
+
+ gtk_object_set_data (GTK_OBJECT (dialog), MessageBoxType,
+ GINT_TO_POINTER (type_index));
+
+ g_object_set (G_OBJECT (pixmap), "stock",
+ GbMessageBoxTypePixmapStockIDs[type_index], NULL);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomeMessageBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_message_box_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_message_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ GtkWidget *pixmap, *label;
+ const gchar *label_text;
+ gint type_index;
+ gchar *wname, *child_name;
+ gboolean translatable, context;
+ gchar *comments;
+
+ get_message_box_widgets (widget, &pixmap, &label);
+ g_return_if_fail (pixmap != NULL);
+ g_return_if_fail (label != NULL);
+
+ type_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ MessageBoxType));
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+
+ if (data->create_widget)
+ {
+ glade_util_get_translation_properties (widget, Message, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ source_add (data,
+ " %s = gnome_message_box_new (%s,\n"
+ " %s, NULL);\n",
+ data->wname,
+ source_make_string_full (label_text, data->use_gettext && translatable, context),
+ GbMessageBoxTypeSymbols[type_index]);
+
+#if 0
+ source_add (data,
+ " gtk_container_remove (GTK_CONTAINER (GNOME_DIALOG (%s)->action_area), GNOME_DIALOG (%s)->buttons->data);\n"
+ " GNOME_DIALOG (%s)->buttons = NULL;\n",
+ data->wname, data->wname, data->wname);
+#endif
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_window_write_standard_source (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ if (!GNOME_DIALOG (widget)->click_closes)
+ {
+ source_add (data,
+ " gnome_dialog_set_close (GNOME_DIALOG (%s), FALSE);\n",
+ data->wname);
+ }
+
+ if (GNOME_DIALOG (widget)->just_hide)
+ {
+ source_add (data,
+ " gnome_dialog_close_hides (GNOME_DIALOG (%s), TRUE);\n",
+ data->wname);
+ }
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_DIALOG (<dialog-name>)->vbox".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (char*) gtk_widget_get_name (GNOME_DIALOG (widget)->vbox);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GNOME_DIALOG (%s)->vbox;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GNOME_DIALOG (widget)->vbox, data);
+
+ /* action_area is a child of vbox so I had to add a kludge to stop it
+ being written as a normal child - we need to do it here so that we
+ don't output code to create it. */
+ child_name = (char*) gtk_widget_get_name (GNOME_DIALOG (widget)->action_area);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GNOME_DIALOG (%s)->action_area;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GNOME_DIALOG (widget)->action_area, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+
+static GtkWidget *
+gb_gnome_message_box_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildDialogVBox))
+ return GNOME_DIALOG (widget)->vbox;
+ else if (!strcmp (child_name, GladeChildDialogActionArea))
+ return GNOME_DIALOG (widget)->action_area;
+ else
+ return NULL;
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_message_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_message_box_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_messagebox_xpm;
+ gbwidget.tooltip = _("Gnome Message Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_message_box_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_message_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_message_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_message_box_set_properties;
+ gbwidget.gb_widget_get_child = gb_gnome_message_box_get_child;
+ gbwidget.gb_widget_write_source = gb_gnome_message_box_write_source;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_message_box_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomepixmap.c b/tools/glade/glade/gnome/gnomepixmap.c
new file mode 100644
index 00000000..2870dbd2
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomepixmap.c
@@ -0,0 +1,361 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-pixmap.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Filename = "GnomePixmap::filename";
+static gchar *Width = "GnomePixmap::scaled_width";
+static gchar *Height = "GnomePixmap::scaled_height";
+
+/* This is only used in Glade. It is not saved to the XML since it is implied
+ by the existence of the scaled_width & scaled_height properties. */
+static gchar *Scaled = "GnomePixmap::scaled";
+
+static void gb_gnome_pixmap_reload (GtkWidget *widget);
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomePixmap, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_pixmap_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ new_widget = gtk_type_new (gnome_pixmap_get_type ());
+ /* Set the default scaled width to 48 x 48. */
+ gtk_object_set_data (GTK_OBJECT (new_widget), Width, GINT_TO_POINTER (48));
+ gtk_object_set_data (GTK_OBJECT (new_widget), Height, GINT_TO_POINTER (48));
+
+ if (data->action == GB_CREATING)
+ gnome_pixmap_load_xpm_d (GNOME_PIXMAP (new_widget),
+ (const char**) gnome_pixmap_xpm);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_pixmap_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_filename (Filename, _("File:"), _("The pixmap filename"));
+ property_add_bool (Scaled, _("Scaled:"), _("If the pixmap is scaled"));
+ property_add_int_range (Width, _("Scaled Width:"),
+ _("The width to scale the pixmap to"),
+ 1, 10000, 1, 10, 1);
+ property_add_int_range (Height, _("Scaled Height:"),
+ _("The height to scale the pixmap to"),
+ 1, 10000, 1, 10, 1);
+}
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_pixmap_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gboolean scaled;
+ gint w, h;
+
+ gb_widget_output_pixmap_filename (data, Filename,
+ gtk_object_get_data (GTK_OBJECT (widget),
+ Filename));
+
+ scaled = gtk_object_get_data (GTK_OBJECT (widget), Scaled) != NULL
+ ? TRUE : FALSE;
+ if (data->action == GB_SHOWING)
+ {
+ gb_widget_output_bool (data, Scaled, scaled);
+ property_set_sensitive (Width, scaled);
+ property_set_sensitive (Height, scaled);
+ }
+
+ /* We only save the scaled width and height if the pixmap is scaled. */
+ w = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Width));
+ if (scaled || data->action == GB_SHOWING)
+ gb_widget_output_int (data, Width, w);
+
+ h = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Height));
+ if (scaled || data->action == GB_SHOWING)
+ gb_widget_output_int (data, Height, h);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_pixmap_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gchar *filename, *old_filename;
+ gboolean set_pixmap = FALSE, scaled;
+ gint width, height;
+
+ filename = gb_widget_input_pixmap_filename (data, Filename);
+ if (data->apply)
+ {
+ set_pixmap = TRUE;
+ if (filename && filename[0] == '\0')
+ filename = NULL;
+
+ old_filename = gtk_object_get_data (GTK_OBJECT (widget), Filename);
+ if (old_filename)
+ {
+ glade_project_remove_pixmap (data->project, old_filename);
+ g_free (old_filename);
+ }
+
+ gtk_object_set_data_full (GTK_OBJECT (widget), Filename,
+ g_strdup (filename),
+ filename ? g_free : NULL);
+ if (filename)
+ {
+ glade_project_add_pixmap (data->project, filename);
+ }
+ }
+ if (data->action == GB_LOADING)
+ g_free (filename);
+
+ scaled = gb_widget_input_bool (data, Scaled);
+ if (data->apply)
+ {
+ set_pixmap = TRUE;
+ gtk_object_set_data (GTK_OBJECT (widget), Scaled, scaled ? "Y" : NULL);
+ if (property_get_widget() == widget)
+ {
+ property_set_sensitive (Width, scaled);
+ property_set_sensitive (Height, scaled);
+ }
+ }
+
+ width = gb_widget_input_int (data, Width);
+ if (data->apply)
+ {
+ set_pixmap = TRUE;
+ if (data->action == GB_LOADING)
+ gtk_object_set_data (GTK_OBJECT (widget), Scaled, "Y");
+ gtk_object_set_data (GTK_OBJECT (widget), Width,
+ GINT_TO_POINTER (width));
+ }
+
+ height = gb_widget_input_int (data, Height);
+ if (data->apply)
+ {
+ set_pixmap = TRUE;
+ if (data->action == GB_LOADING)
+ gtk_object_set_data (GTK_OBJECT (widget), Scaled, "Y");
+ gtk_object_set_data (GTK_OBJECT (widget), Height,
+ GINT_TO_POINTER (height));
+ }
+
+ if (set_pixmap)
+ gb_gnome_pixmap_reload (widget);
+}
+
+
+static void
+gb_gnome_pixmap_reload (GtkWidget *widget)
+{
+ gchar *filename;
+ gboolean scaled;
+ gint width, height;
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), Filename);
+ scaled = gtk_object_get_data (GTK_OBJECT (widget), Scaled) != NULL
+ ? TRUE : FALSE;
+ width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Width));
+ height = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Height));
+
+ if (filename)
+ {
+ if (scaled && width > 0 && height > 0)
+ gnome_pixmap_load_file_at_size (GNOME_PIXMAP (widget), filename,
+ width, height);
+ else
+ gnome_pixmap_load_file (GNOME_PIXMAP (widget), filename);
+ }
+ else
+ {
+ if (scaled && width > 0 && height > 0)
+ gnome_pixmap_load_xpm_d_at_size (GNOME_PIXMAP (widget),
+ (const char**) gnome_pixmap_xpm,
+ width, height);
+ else
+ gnome_pixmap_load_xpm_d (GNOME_PIXMAP (widget),
+ (const char**) gnome_pixmap_xpm);
+ }
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomePixmap, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_pixmap_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_pixmap_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *filename;
+ gboolean scaled;
+ gint width, height;
+
+ filename = gtk_object_get_data (GTK_OBJECT (widget), Filename);
+ if (filename && !*filename)
+ filename = NULL;
+ scaled = gtk_object_get_data (GTK_OBJECT (widget), Scaled) != NULL
+ ? TRUE : FALSE;
+ width = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Width));
+ height = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Height));
+
+ if (data->create_widget)
+ {
+ source_add (data,
+ " %s = g_object_new (GNOME_TYPE_PIXMAP, NULL);\n",
+ data->wname);
+ }
+
+ if (filename)
+ {
+ filename = (gchar*) g_basename (filename);
+
+ source_add_decl (data, " gchar *%s_filename;\n", data->real_wname);
+ /* FIXME: Should convert filename to a valid C string? */
+ source_add (data,
+ " %s_filename = gnome_program_locate_file (NULL,\n"
+ " GNOME_FILE_DOMAIN_APP_PIXMAP, \"%s/%s\", TRUE, NULL);\n"
+ " if (%s_filename)\n",
+ data->real_wname,
+ data->program_name, filename,
+ data->real_wname);
+
+ if (scaled)
+ {
+ source_add (data,
+ " gnome_pixmap_load_file_at_size (GNOME_PIXMAP (%s), %s_filename, %i, %i);\n",
+ data->wname, data->real_wname, width, height);
+ }
+ else
+ {
+ source_add (data,
+ " gnome_pixmap_load_file (GNOME_PIXMAP (%s), %s_filename);\n",
+ data->wname, data->real_wname);
+ }
+
+ source_add (data,
+ " else\n"
+ " g_warning (%s, ",
+ source_make_string ("Couldn't find pixmap file: %s",
+ data->use_gettext));
+ source_add (data,
+ "%s);\n",
+ source_make_string (filename, FALSE));
+
+ source_add (data, " g_free (%s_filename);\n", data->real_wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+}
+
+
+void
+gb_gnome_pixmap_destroy (GtkWidget * widget, GbWidgetDestroyData * data)
+{
+ gchar *filename;
+
+ /* This can be a stock id or a filename. But glade_project_remove_pixmap()
+ will just ignore it if it isn't a project pixmap file. */
+ filename = gtk_object_get_data (GTK_OBJECT (widget), Filename);
+ glade_project_remove_pixmap (data->project, filename);
+}
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_pixmap_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_pixmap_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_pixmap_xpm;
+ gbwidget.tooltip = _("Gnome Pixmap");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_pixmap_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_pixmap_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_pixmap_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_pixmap_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_pixmap_write_source;
+ gbwidget.gb_widget_destroy = gb_gnome_pixmap_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_pixmap_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomepixmapentry.c b/tools/glade/glade/gnome/gnomepixmapentry.c
new file mode 100644
index 00000000..0dc75baa
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomepixmapentry.c
@@ -0,0 +1,319 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-pixmapentry.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Preview = "GnomePixmapEntry::do_preview";
+static gchar *HistoryID = "GnomePixmapEntry|GnomeEntry::history_id";
+static gchar *MaxSaved = "GnomePixmapEntry|GnomeEntry::max_saved";
+static gchar *Title = "GnomePixmapEntry|GnomeFileEntry::browse_dialog_title";
+static gchar *Modal = "GnomePixmapEntry|GnomeFileEntry::modal";
+static gchar *FileChooser = "GnomePixmapEntry|GnomeFileEntry::use_filechooser";
+
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomePixmapEntry, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_pixmap_entry_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget, *entry;
+
+ new_widget = gnome_pixmap_entry_new (NULL, NULL, TRUE);
+
+ entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (new_widget));
+ gb_widget_create_from (entry,
+ data->action == GB_CREATING ? "combo-entry" : NULL);
+ gb_widget_set_child_name (entry, GladeChildGnomeEntry);
+
+ return new_widget;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_gnome_pixmap_entry_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ property_add_bool (Preview, _("Preview:"),
+ _("If a small preview of the pixmap is displayed"));
+ property_add_string (HistoryID, _("History ID:"),
+ _("The ID to save the history entries under"));
+ property_add_int_range (MaxSaved, _("Max Saved:"),
+ _("The maximum number of history entries saved"),
+ 0, 10000, 1, 10, 1);
+ property_add_string (Title, _("Title:"),
+ _("The title of the file selection dialog"));
+ property_add_bool (Modal, _("Modal:"),
+ _("If the file selection dialog should be modal"));
+ property_add_bool (FileChooser, _("Use FileChooser:"),
+ _("Use the new GtkFileChooser widget instead of GtkFileSelection"));
+}
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_gnome_pixmap_entry_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ GtkWidget *gentry;
+ gboolean use_filechooser = FALSE;
+
+ gentry = gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (widget));
+
+ gb_widget_output_string (data, HistoryID, gtk_object_get_data (GTK_OBJECT (widget), HistoryID));
+ gb_widget_output_int (data, MaxSaved, gnome_entry_get_max_saved (GNOME_ENTRY (gentry)));
+ gb_widget_output_translatable_string (data, Title, gtk_object_get_data (GTK_OBJECT (widget), Title));
+ gb_widget_output_bool (data, Modal,
+ gnome_file_entry_get_modal (GNOME_FILE_ENTRY (widget)));
+ gb_widget_output_bool (data, Preview,
+ GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), Preview)));
+ g_object_get (G_OBJECT (widget), "use_filechooser", &use_filechooser,
+ NULL);
+ gb_widget_output_bool (data, FileChooser, use_filechooser);
+}
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_gnome_pixmap_entry_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ GtkWidget *gentry;
+ gchar *history_id, *title;
+ gint max_saved;
+ gboolean modal, preview, use_filechooser;
+
+ gentry = gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (widget));
+
+ preview = gb_widget_input_bool (data, Preview);
+ if (data->apply)
+ {
+ gtk_object_set_data (GTK_OBJECT (widget), Preview,
+ GINT_TO_POINTER (preview));
+ gnome_pixmap_entry_set_preview (GNOME_PIXMAP_ENTRY (widget), preview);
+ /* FIXME: In GnomeLibs 1.0.1 it doesn't resize properly without this. */
+ /*gtk_widget_queue_resize (widget);*/
+ }
+
+ history_id = gb_widget_input_string (data, HistoryID);
+ if (data->apply)
+ gtk_object_set_data_full (GTK_OBJECT (widget), HistoryID,
+ g_strdup (history_id),
+ history_id ? g_free : NULL);
+
+ max_saved = gb_widget_input_int (data, MaxSaved);
+ if (data->apply)
+ gnome_entry_set_max_saved (GNOME_ENTRY (gentry), max_saved);
+
+ title = gb_widget_input_string (data, Title);
+ if (data->apply)
+ {
+ gtk_object_set_data_full (GTK_OBJECT (widget), Title, g_strdup (title),
+ title ? g_free : NULL);
+ gnome_file_entry_set_title (GNOME_FILE_ENTRY (widget),
+ title && title[0] ? title : NULL);
+ }
+
+ modal = gb_widget_input_bool (data, Modal);
+ if (data->apply)
+ gnome_file_entry_set_modal (GNOME_FILE_ENTRY (widget), modal);
+
+ use_filechooser = gb_widget_input_bool (data, FileChooser);
+ if (data->apply)
+ g_object_set (G_OBJECT (widget), "use_filechooser", use_filechooser, NULL);
+}
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomePixmapEntry, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_pixmap_entry_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_pixmap_entry_write_source (GtkWidget * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GtkWidget *gentry, *entry;
+ gchar *title, *history_id;
+ gchar *wname, *child_name;
+ gboolean use_filechooser = FALSE;
+ gboolean translatable, context;
+ gchar *comments;
+
+ gentry = gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (widget));
+
+ title = gtk_object_get_data (GTK_OBJECT (widget), Title);
+ if (title && title[0] == '\0')
+ title = NULL;
+
+ history_id = gtk_object_get_data (GTK_OBJECT (widget), HistoryID);
+ if (history_id && history_id[0] == '\0')
+ history_id = NULL;
+
+ if (data->create_widget)
+ {
+ gboolean do_preview;
+
+ glade_util_get_translation_properties (widget, Title, &translatable,
+ &comments, &context);
+ source_add_translator_comments (data, translatable, comments);
+
+ do_preview = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ Preview));
+
+ source_add (data, " %s = gnome_pixmap_entry_new (%s, ",
+ data->wname,
+ history_id ? source_make_string (history_id, FALSE) : "NULL");
+
+ source_add (data, "%s, %s);\n",
+ title ? source_make_string_full (title, data->use_gettext && translatable, context) : "NULL",
+ do_preview ? "TRUE" : "FALSE");
+ }
+ gb_widget_write_standard_source (widget, data);
+
+ /* Note that GLADE_DEFAULT_MAX_HISTORY_SAVED is copied from gnome-entry.c */
+ if (gnome_entry_get_max_saved (GNOME_ENTRY (gentry)) != GLADE_DEFAULT_MAX_HISTORY_SAVED)
+ source_add (data, " gnome_entry_set_max_saved (GNOME_ENTRY (gnome_file_entry_gnome_entry (GNOME_FILE_ENTRY (%s))), %i);\n",
+ data->wname,
+ gnome_entry_get_max_saved (GNOME_ENTRY (gentry)));
+
+ if (gnome_file_entry_get_modal (GNOME_FILE_ENTRY (widget)))
+ source_add (data,
+ " gnome_file_entry_set_modal (GNOME_FILE_ENTRY (%s), TRUE);\n",
+ data->wname);
+
+ g_object_get (G_OBJECT (widget), "use_filechooser", &use_filechooser, NULL);
+ if (use_filechooser)
+ source_add (data,
+ " g_object_set (G_OBJECT (%s), \"use_filechooser\", TRUE, NULL);\n",
+ data->wname);
+
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_COMBO (<combo-name>)->entry".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ entry = GTK_COMBO (gentry)->entry;
+ child_name = (char*) gtk_widget_get_name (entry);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data,
+ " %s = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (%s));\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (entry, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_gnome_pixmap_entry_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildGnomeEntry))
+ return gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (widget));
+ else
+ return NULL;
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_pixmap_entry_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_pixmap_entry_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_pixmapentry_xpm;
+ gbwidget.tooltip = _("GnomePixmapEntry");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_pixmap_entry_new;
+ gbwidget.gb_widget_create_properties = gb_gnome_pixmap_entry_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_pixmap_entry_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_pixmap_entry_set_properties;
+ gbwidget.gb_widget_write_source = gb_gnome_pixmap_entry_write_source;
+ gbwidget.gb_widget_get_child = gb_gnome_pixmap_entry_get_child;
+/*
+ gbwidget.gb_widget_set_child_props = gb_gnome_pixmap_entry_set_child_props;
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_pixmap_entry_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/gnome/gnomepropertybox.c b/tools/glade/glade/gnome/gnomepropertybox.c
new file mode 100644
index 00000000..51ba9aec
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomepropertybox.c
@@ -0,0 +1,383 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include "../gb.h"
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-propertybox.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+static gchar *Title = "GnomePropertyBox|GtkWindow::title";
+static gchar *Position = "GnomePropertyBox|GtkWindow::window_position";
+static gchar *Modal = "GnomePropertyBox|GtkWindow::modal";
+static gchar *DefaultWidth = "GnomePropertyBox|GtkWindow::default_width";
+static gchar *DefaultHeight = "GnomePropertyBox|GtkWindow::default_height";
+static gchar *Shrink = "GnomePropertyBox|GtkWindow::allow_shrink";
+static gchar *Grow = "GnomePropertyBox|GtkWindow::allow_grow";
+static gchar *AutoShrink = "GnomePropertyBox|GtkWindow::auto_shrink";
+static gchar *IconName = "GnomePropertyBox|GtkWindow::icon_name";
+static gchar *FocusOnMap = "GnomePropertyBox|GtkWindow::focus_on_map";
+
+static gchar *Resizable = "GnomePropertyBox|GtkWindow::resizable";
+static gchar *DestroyWithParent = "GnomePropertyBox|GtkWindow::destroy_with_parent";
+static gchar *Icon = "GnomePropertyBox|GtkWindow::icon";
+
+static gchar *Role = "GnomePropertyBox|GtkWindow::role";
+static gchar *TypeHint = "GnomePropertyBox|GtkWindow::type_hint";
+static gchar *SkipTaskbar = "GnomePropertyBox|GtkWindow::skip_taskbar_hint";
+static gchar *SkipPager = "GnomePropertyBox|GtkWindow::skip_pager_hint";
+static gchar *Decorated = "GnomePropertyBox|GtkWindow::decorated";
+static gchar *Gravity = "GnomePropertyBox|GtkWindow::gravity";
+static gchar *Urgency = "GnomePropertyBox|GtkWindow::urgency_hint";
+
+static void show_gnome_property_box_dialog (GbWidgetNewData * data);
+static void on_gnome_property_box_dialog_ok (GtkWidget * widget,
+ GbWidgetNewData * data);
+static void on_gnome_property_box_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data);
+GtkWidget * gnome_property_box_new_tab_label ();
+
+/******
+ * NOTE: To use these functions you need to uncomment them AND add a pointer
+ * to the function in the GbWidget struct at the end of this file.
+ ******/
+
+/*
+ * Creates a new GtkWidget of class GnomePropertyBox, performing any specialized
+ * initialization needed for the widget to work correctly in this environment.
+ * If a dialog box is used to initialize the widget, return NULL from this
+ * function, and call data->callback with your new widget when it is done.
+ */
+static GtkWidget*
+gb_gnome_property_box_new (GbWidgetNewData *data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING)
+ {
+ new_widget = gnome_property_box_new ();
+
+ gb_widget_create_from (GNOME_PROPERTY_BOX (new_widget)->notebook,
+ data->action == GB_CREATING ? "notebook" : NULL);
+ gb_widget_set_child_name (GNOME_PROPERTY_BOX (new_widget)->notebook,
+ GladeChildGnomePBoxNotebook);
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "close",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ return new_widget;
+ }
+ else
+ {
+ show_gnome_property_box_dialog (data);
+ return NULL;
+ }
+}
+
+
+static void
+show_gnome_property_box_dialog (GbWidgetNewData * data)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *spinbutton;
+ GtkObject *adjustment;
+
+ dialog = glade_util_create_dialog (_("New GnomePropertyBox"), data->parent,
+ GTK_SIGNAL_FUNC (on_gnome_property_box_dialog_ok),
+ data, &vbox);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_gnome_property_box_dialog_destroy),
+ data);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Number of pages:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 5);
+ gtk_widget_show (label);
+
+ adjustment = gtk_adjustment_new (3, 1, 100, 1, 10, 10);
+ spinbutton = glade_util_spin_button_new (GTK_OBJECT (dialog), "pages",
+ GTK_ADJUSTMENT (adjustment), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, TRUE, 5);
+ gtk_widget_set_usize (spinbutton, 50, -1);
+ gtk_widget_grab_focus (spinbutton);
+ gtk_widget_show (spinbutton);
+
+ gtk_widget_show (dialog);
+ gtk_grab_add (dialog);
+}
+
+
+static void
+on_gnome_property_box_dialog_ok (GtkWidget * widget, GbWidgetNewData * data)
+{
+ GtkWidget *new_widget, *spinbutton, *window, *placeholder;
+ gint pages, i;
+
+ window = gtk_widget_get_toplevel (widget);
+
+ /* Only call callback if placeholder/fixed widget is still there */
+ if (gb_widget_can_finish_new (data))
+ {
+ spinbutton = gtk_object_get_data (GTK_OBJECT (window), "pages");
+ g_return_if_fail (spinbutton != NULL);
+ pages = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
+
+ new_widget = gnome_property_box_new ();
+
+ gb_widget_create_from (GNOME_PROPERTY_BOX (new_widget)->notebook,
+ "notebook");
+ gb_widget_set_child_name (GNOME_PROPERTY_BOX (new_widget)->notebook,
+ GladeChildGnomePBoxNotebook);
+
+ for (i = 0; i < pages; i++)
+ {
+ placeholder = editor_new_placeholder ();
+ gtk_widget_set_usize (placeholder, 300, 150);
+ gnome_property_box_append_page (GNOME_PROPERTY_BOX (new_widget),
+ placeholder,
+ gnome_property_box_new_tab_label ());
+ }
+
+ /* We connect a close signal handler which always returns TRUE so that
+ the built-in close functionality is skipped. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "close",
+ GTK_SIGNAL_FUNC (gtk_true), NULL);
+
+ /* Now we connect our normal delete_event handler. */
+ gtk_signal_connect (GTK_OBJECT (new_widget), "delete_event",
+ GTK_SIGNAL_FUNC (editor_close_window), NULL);
+
+ gtk_object_set_data (GTK_OBJECT (new_widget), TypeHint,
+ GINT_TO_POINTER (GLADE_TYPE_HINT_DIALOG_INDEX));
+
+ gb_widget_initialize (new_widget, data);
+ (*data->callback) (new_widget, data);
+ }
+ gtk_widget_destroy (window);
+}
+
+
+static void
+on_gnome_property_box_dialog_destroy (GtkWidget * widget,
+ GbWidgetNewData * data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+
+GtkWidget *
+gnome_property_box_new_tab_label ()
+{
+ GtkWidget *label;
+
+ label = gb_widget_new ("GtkLabel", NULL);
+ g_return_val_if_fail (label != NULL, NULL);
+ return label;
+}
+
+
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+
+static void
+gb_gnome_property_box_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ gb_window_create_standard_properties (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+
+static void
+gb_gnome_property_box_get_properties (GtkWidget *widget, GbWidgetGetArgData * data)
+{
+ gb_window_get_standard_properties (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+
+static void
+gb_gnome_property_box_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ gb_window_set_standard_properties (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+}
+
+
+
+
+/*
+ * Adds menu items to a context menu which is just about to appear!
+ * Add commands to aid in editing a GnomePropertyBox, with signals pointing to
+ * other functions in this file.
+ */
+/*
+static void
+gb_gnome_property_box_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data)
+{
+
+}
+*/
+
+
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_gnome_property_box_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ gchar *wname, *child_name;
+
+ if (data->create_widget)
+ {
+ source_add (data, " %s = gnome_property_box_new ();\n", data->wname);
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ gb_window_write_standard_source (widget, data,
+ Title, NULL, Position, Modal,
+ DefaultWidth, DefaultHeight,
+ Shrink, Grow, AutoShrink,
+ IconName, FocusOnMap,
+ Resizable, DestroyWithParent, Icon,
+ Role, TypeHint, SkipTaskbar,
+ SkipPager, Decorated, Gravity, Urgency);
+
+ /* We output the source code for the children here, since the code should
+ not include calls to create the widgets. We need to specify that the
+ names used are like: "GTK_DIALOG (<dialog-name>)->vbox".
+ We need to remember the dialog's name since data->wname
+ will be overwritten. */
+ wname = g_strdup (data->wname);
+
+ source_add (data, "\n");
+ child_name = (char*) gtk_widget_get_name (GNOME_PROPERTY_BOX (widget)->notebook);
+ child_name = source_create_valid_identifier (child_name);
+ source_add (data, " %s = GNOME_PROPERTY_BOX (%s)->notebook;\n",
+ child_name, wname);
+ g_free (child_name);
+ data->create_widget = FALSE;
+ gb_widget_write_source (GNOME_PROPERTY_BOX (widget)->notebook, data);
+
+ g_free (wname);
+ data->write_children = FALSE;
+}
+
+
+static GtkWidget *
+gb_gnome_property_box_get_child (GtkWidget * widget,
+ const gchar * child_name)
+{
+ if (!strcmp (child_name, GladeChildGnomePBoxNotebook))
+ return GNOME_PROPERTY_BOX (widget)->notebook;
+ else
+ return NULL;
+}
+
+
+
+/*
+ * Initializes the GbWidget structure.
+ * I've placed this at the end of the file so we don't have to include
+ * declarations of all the functions.
+ */
+GbWidget*
+gb_gnome_property_box_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = gnome_property_box_get_type();
+
+ /* Initialize the GbWidget structure */
+ gb_widget_init_struct(&gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget.pixmap_struct = gnome_propertybox_xpm;
+ gbwidget.tooltip = _("Property Dialog Box");
+
+ /* Fill in any functions that this GbWidget has */
+ gbwidget.gb_widget_new = gb_gnome_property_box_new;
+ gbwidget.gb_widget_write_source = gb_gnome_property_box_write_source;
+ gbwidget.gb_widget_get_child = gb_gnome_property_box_get_child;
+
+ gbwidget.gb_widget_create_properties = gb_gnome_property_box_create_properties;
+ gbwidget.gb_widget_get_properties = gb_gnome_property_box_get_properties;
+ gbwidget.gb_widget_set_properties = gb_gnome_property_box_set_properties;
+ gbwidget.gb_widget_destroy = gb_window_destroy;
+/*
+ gbwidget.gb_widget_create_popup_menu = gb_gnome_property_box_create_popup_menu;
+*/
+
+ return &gbwidget;
+}
+
diff --git a/tools/glade/glade/graphics/aboutdialog.xpm b/tools/glade/glade/graphics/aboutdialog.xpm
new file mode 100644
index 00000000..2e2cc181
--- /dev/null
+++ b/tools/glade/glade/graphics/aboutdialog.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * aboutdialog_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #00007B",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ................ ",
+" .+@#++++++++++++$ ",
+" .+%&+***++++=$=$$ ",
+" ................$ ",
+" .**************.$ ",
+" .**************.$ ",
+" .****$*****$***.$ ",
+" .***$$****$*$**.$ ",
+" .****$****$*$**.$ ",
+" .***$$$*$**$***.$ ",
+" .**************.$ ",
+" .**************.$ ",
+" ................$ ",
+" $$$$$$$$$$$$$$$$ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/accellabel.xpm b/tools/glade/glade/graphics/accellabel.xpm
new file mode 100644
index 00000000..1470c654
--- /dev/null
+++ b/tools/glade/glade/graphics/accellabel.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char * accellabel_xpm[] = {
+"21 21 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ",
+" ... . ",
+" . .. ",
+" . . . ",
+" .. .. . ",
+" .... . . ",
+" .... . ... ",
+" ...... ",
+" .. ... ",
+" .. .... ",
+" ........ ",
+" ........ ",
+" . ... ",
+" ... ..... ",
+" .... ...... ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/alignment.xpm b/tools/glade/glade/graphics/alignment.xpm
new file mode 100644
index 00000000..76cd89ce
--- /dev/null
+++ b/tools/glade/glade/graphics/alignment.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *alignment_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"++++++++++++ ++++++++",
+"+++++++++++ +++++++",
+"++++++++++ + + ++++++",
+"++++++++++++ ++++++++",
+"++++++++++++ ++++++++",
+"++++++++++ + + ++++++",
+"+++++++++++ +++++++",
+"++++++++++++ ++++++++",
+"++++++++OOOOOOOOO +++",
+"++++++++OXXXXXXX. +++",
+"++ ++ ++OXXXXXXX. +++",
+"+ ++++ +OXXXXXXX. +++",
+" OXXXXXXX. +++",
+"+ ++++ +OXXXXXXX. +++",
+"++ ++ ++OXXXXXXX. +++",
+"++++++++O........ +++",
+"++++++++ +++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/arrow.xpm b/tools/glade/glade/graphics/arrow.xpm
new file mode 100644
index 00000000..3149714c
--- /dev/null
+++ b/tools/glade/glade/graphics/arrow.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *arrow_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 5 1",
+" c Gray0",
+". c #d6d6d6",
+"X c #b3cece",
+"o c Gray100",
+"O c None",
+/* pixels */
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOooOOOOOOOOOOOOOOOO",
+"OOOo.ooOOOOOOOOOOOOOO",
+"OOOo...ooOOOOOOOOOOOO",
+"OOOo.....ooOOOOOOOOOO",
+"OOOo.......ooOOOOOOOO",
+"OOOo.........ooOOOOOO",
+"OOOo........... OOOO",
+"OOOo......... OOOOOO",
+"OOOo....... OOOOOOOO",
+"OOOo..... OOOOOOOOOO",
+"OOOo... OOOOOOOOOOOO",
+"OOOo. OOOOOOOOOOOOOO",
+"OOOo OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO"
+};
diff --git a/tools/glade/glade/graphics/aspectframe.xpm b/tools/glade/glade/graphics/aspectframe.xpm
new file mode 100644
index 00000000..66b9ca14
--- /dev/null
+++ b/tools/glade/glade/graphics/aspectframe.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *aspectframe_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++ + +++++++++++",
+"+...X X X X......O+",
+"+.OOX X X XOOOOO.O+",
+"+.OXX X X XXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXX.XXXXXXX.O+",
+"+.OXXXXXX...XXXXXX.O+",
+"+.OXXXXX.X.X.XXXXX.O+",
+"+.OXXXXXXX.XXXXXXX.O+",
+"+.OXX.XXXX.XXXX.XX.O+",
+"+.OX.XXXXX.XXXXX.X.O+",
+"+.O................O+",
+"+.OX.XXXXX.XXXXX.X.O+",
+"+.OXX.XXXX.XXXX.XX.O+",
+"+.OXXXXX.X.X.XXXXX.O+",
+"+.OXXXXXX...XXXXXX.O+",
+"+.OXXXXXXX.XXXXXXX.O+",
+"+..................O+",
+"+OOOOOOOOOOOOOOOOOOO+",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/bonobo-dock-item.xpm b/tools/glade/glade/graphics/bonobo-dock-item.xpm
new file mode 100644
index 00000000..38e5cfb5
--- /dev/null
+++ b/tools/glade/glade/graphics/bonobo-dock-item.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * bonobo_dock_item_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #7B7B7B",
+"@ c #D6D6D6",
+"# c #000000",
+".....................",
+".+@+@@@@@@@@@@@@@@@@#",
+".@.+@@@@@@@@@@@@@@@@#",
+".+@+@@@@@@@@@@@@@@@@#",
+".####################",
+".....................",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/bonobo-dock.xpm b/tools/glade/glade/graphics/bonobo-dock.xpm
new file mode 100644
index 00000000..08d64dad
--- /dev/null
+++ b/tools/glade/glade/graphics/bonobo-dock.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * bonobo_dock_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #7B7B7B",
+"@ c #D6D6D6",
+"# c #000000",
+".....................",
+".+@+@@@@@@@@@@@@@@@@#",
+".@.+@@@@@@@@@@@@@@@@#",
+".+@+@@@@@@@@@@@@@@@@#",
+".####################",
+".....@@@@@@@@@@@....#",
+".+@+#@@@@@@@@@@@.+@+#",
+".@.@#@@@@@@@@@@@.@.@#",
+".+++#@@@@@@@@@@@.+++#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".####@@@@@@@@@@@.####",
+"....................#",
+".+@+@@@@@@@@@@@@@@@@#",
+".@.+@@@@@@@@@@@@@@@@#",
+".+@+@@@@@@@@@@@@@@@@#",
+"#####################"};
diff --git a/tools/glade/glade/graphics/button.xpm b/tools/glade/glade/graphics/button.xpm
new file mode 100644
index 00000000..eca4d627
--- /dev/null
+++ b/tools/glade/glade/graphics/button.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * button_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@++@@+@@+@@@@#+ ",
+" .@@@+@@+@+@+@@@@@#+ ",
+" .@@@+@@+@++@@@@@@#+ ",
+" .@@@+@@+@+@+@@@@@#+ ",
+" .@@@+@@+@+@@+@@@@#+ ",
+" .@@@@++@@+@@+@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/calendar.xpm b/tools/glade/glade/graphics/calendar.xpm
new file mode 100644
index 00000000..cb4dd8c8
--- /dev/null
+++ b/tools/glade/glade/graphics/calendar.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * calendar_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #000000",
+"+ c #DEDEDE",
+"@ c #FFFFFF",
+"# c #DFDFDF",
+" ",
+".....................",
+".+++++++++++++++++++.",
+".+..+..+..+..+..+..+.",
+".+++++++++++++++++++.",
+".....................",
+".@@@@@@@@@@@@@@@@@@@.",
+".@@+@@.@@.@@.@@.@@.@.",
+".@@@@@@@@@@@@@@@@@@@.",
+".@@.@@.@@.@@.@@.@@.@.",
+".@@@@@@@@@@@@@@@@@@@.",
+".@@.@@.@@.@@.@@.@@.@.",
+".@@@@@@@@@@@@@@@@@@@.",
+".@@.@@.@@.@@.@@.@@.@.",
+".@@@@@@@@@@@@@@@@@@@.",
+".@@.@@.@@.@@+@@+@@+@.",
+".@@@@@@@@@@@@@@@@@@@.",
+".@@+@@+@@+@@+@@+@@#@.",
+".@@@@@@@@@@@@@@@@@@@.",
+".....................",
+" "};
diff --git a/tools/glade/glade/graphics/cellview.xpm b/tools/glade/glade/graphics/cellview.xpm
new file mode 100644
index 00000000..edb5aeb6
--- /dev/null
+++ b/tools/glade/glade/graphics/cellview.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static char * cellview_xpm[] = {
+"21 21 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+" ",
+" ",
+" . . ",
+" . . ",
+" . . ",
+".....................",
+" .+++++++++++++++. ",
+" .+++++++++++++++. ",
+" .++...+.++++++++. ",
+" .++.+.+.++++++++. ",
+" .++.+.+...+...++. ",
+" .++...+.+.+.++++. ",
+" .++.+.+.+.+.++++. ",
+" .++.+.+...+...++. ",
+" .+++++++++++++++. ",
+" .+++++++++++++++. ",
+".....................",
+" . . ",
+" . . ",
+" . . ",
+" "};
diff --git a/tools/glade/glade/graphics/checkbutton.xpm b/tools/glade/glade/graphics/checkbutton.xpm
new file mode 100644
index 00000000..2b8a7d94
--- /dev/null
+++ b/tools/glade/glade/graphics/checkbutton.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * checkbutton_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #A4A5A4",
+"+ c #000000",
+"@ c #FFFFFF",
+"# c #D5D2D5",
+"$ c #7B7D7B",
+" ",
+" ",
+" ",
+" ",
+" ............. ",
+" .+++++++++++@ ",
+" .+@@@@@@@@@#@ ",
+" .+@@@@@@@+$#@ ",
+" .+@@@@@@++@#@ ",
+" .+@@@@@++@@#@ ",
+" .+@$$@$+@@@#@ ",
+" .+@++$+$@@@#@ ",
+" .+@@$++@@@@#@ ",
+" .+@@@@+@@@@#@ ",
+" .+@@@@@@@@@#@ ",
+" .+##########@ ",
+" .@@@@@@@@@@@@ ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/checkmenuitem.xpm b/tools/glade/glade/graphics/checkmenuitem.xpm
new file mode 100644
index 00000000..197eee36
--- /dev/null
+++ b/tools/glade/glade/graphics/checkmenuitem.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * checkmenuitem_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #FFFFFF",
+"+ c #7B7B7B",
+"@ c #000000",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ........ ",
+" . +@ ",
+" . +@ ",
+" . +@ ",
+" . +@ @ ",
+" . +++++@ @@ ",
+" .@@@@@@@ @@@@ ",
+" @@@@@ ",
+" @@@@ ",
+" @@@ ",
+" @ @ ",
+" @ ",
+" @ ",
+" "};
diff --git a/tools/glade/glade/graphics/clist.xpm b/tools/glade/glade/graphics/clist.xpm
new file mode 100644
index 00000000..b3c04c38
--- /dev/null
+++ b/tools/glade/glade/graphics/clist.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * clist_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #000000",
+"+ c #DEDEDE",
+"@ c #FFFFFF",
+".....................",
+".++++++.++++++.+++++.",
+".++++++.++++++.+++++.",
+".++++++.++++++.+++++.",
+".....................",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".....................",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".....................",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".....................",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+".@@@@@@.@@@@@@.@@@@@.",
+"....................."};
diff --git a/tools/glade/glade/graphics/colorbutton.xpm b/tools/glade/glade/graphics/colorbutton.xpm
new file mode 100644
index 00000000..76ca023c
--- /dev/null
+++ b/tools/glade/glade/graphics/colorbutton.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * colorbutton_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #949594",
+"% c #E6A1CD",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@............$@#+ ",
+" .@@.$$$$$$$$$$.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@............$@#+ ",
+" .@@$$$$$$$$$$$$$@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/colorseldialog.xpm b/tools/glade/glade/graphics/colorseldialog.xpm
new file mode 100644
index 00000000..4a38e4c5
--- /dev/null
+++ b/tools/glade/glade/graphics/colorseldialog.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *colorseldialog_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 12 1",
+" c Gray0",
+". c #00007b",
+"X c #7b7b7b",
+"o c Blue",
+"O c Green",
+"+ c Cyan",
+"@ c Red",
+"# c Yellow",
+"$ c #d6d6d6",
+"% c #b3cece",
+"& c Gray100",
+"* c None",
+/* pixels */
+"*********************",
+"*********************",
+"*********************",
+"*********************",
+"**XXXXXXXXXXXXXXXX***",
+"**X.@#...........X **",
+"**X.+O.&&&....$ $X **",
+"**XXXXXXXXXXXXXXXX **",
+"**X&&&&&&&&&&&&&&X **",
+"**X&&&&&&&&&&&&&&X **",
+"**X&&@@@OOOooo&&&X **",
+"**X&&@@@OOOooo&&&X **",
+"**X&&@@@OOOooo&&&X **",
+"**X&&@@@OOOooo&&&X **",
+"**X&&&&&&&&&&&&&&X **",
+"**X&&&&&&&&&&&&&&X **",
+"**XXXXXXXXXXXXXXXX **",
+"*** **",
+"*********************",
+"*********************",
+"*********************"
+};
diff --git a/tools/glade/glade/graphics/colorselection.xpm b/tools/glade/glade/graphics/colorselection.xpm
new file mode 100644
index 00000000..0bb0914d
--- /dev/null
+++ b/tools/glade/glade/graphics/colorselection.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char *colorselection_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 8 1",
+" c Gray0",
+". c #7b7b7b",
+"X c Blue",
+"o c Green",
+"O c Red",
+"+ c #b3cece",
+"@ c Gray100",
+"# c None",
+/* pixels */
+"#####################",
+"#####################",
+"#####################",
+"#####################",
+"#####################",
+"##................###",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@OOOoooXXX@@@. ##",
+"##.@@OOOoooXXX@@@. ##",
+"##.@@OOOoooXXX@@@. ##",
+"##.@@OOOoooXXX@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##................ ##",
+"### ##",
+"#####################",
+"#####################",
+"#####################"
+};
diff --git a/tools/glade/glade/graphics/combo.xpm b/tools/glade/glade/graphics/combo.xpm
new file mode 100644
index 00000000..3b4055b6
--- /dev/null
+++ b/tools/glade/glade/graphics/combo.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *combo_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+" ",
+" +++++++++++++ OOOOO ",
+" +++++++++++++ OOO ",
+" +++++++++++++ O ",
+" ",
+" +++++++++++++ ++++++",
+" +++++++++++++ XXXXX ",
+" +.........+++ XX XX ",
+" +++++++++++++ X X ",
+" +++++++++++++ XXXXX ",
+" +...........+ ",
+" +++++++++++++ +++++ ",
+" +++++++++++++ +XXXX ",
+" +..........++ ..... ",
+" +++++++++++++ +++++ ",
+" +++++++++++++ XXXXX ",
+" +...........+ X X ",
+" +++++++++++++ XX XX ",
+" +++++++++++++ XXXXX ",
+" "
+};
diff --git a/tools/glade/glade/graphics/combobox.xpm b/tools/glade/glade/graphics/combobox.xpm
new file mode 100644
index 00000000..8b04b90a
--- /dev/null
+++ b/tools/glade/glade/graphics/combobox.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *combobox_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"OOOOOOOOOOOOOOOOOOOO ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXOOOOXX. ",
+"OXXXXXXXXXXXXOXX XX. ",
+"OXXXXXXXXXXXXO XX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"O................... ",
+" ",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/comboboxentry.xpm b/tools/glade/glade/graphics/comboboxentry.xpm
new file mode 100644
index 00000000..dfa03b1c
--- /dev/null
+++ b/tools/glade/glade/graphics/comboboxentry.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *comboboxentry_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+" ",
+" +++++++++++++ OOOOO ",
+" +++++++++++++ OOO ",
+" +++++++++++++ O ",
+" ",
+" +++++++++++++ ++++++",
+" +++++++++++++ XXXXX ",
+" +.........+++ XX XX ",
+" +++++++++++++ X X ",
+" +++++++++++++ XXXXX ",
+" +...........+ ",
+" +++++++++++++ +++++ ",
+" +++++++++++++ +XXXX ",
+" +..........++ ..... ",
+" +++++++++++++ +++++ ",
+" +++++++++++++ XXXXX ",
+" +...........+ X X ",
+" +++++++++++++ XX XX ",
+" +++++++++++++ XXXXX ",
+" "
+};
diff --git a/tools/glade/glade/graphics/ctree.xpm b/tools/glade/glade/graphics/ctree.xpm
new file mode 100644
index 00000000..96673148
--- /dev/null
+++ b/tools/glade/glade/graphics/ctree.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * ctree_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #000000",
+"+ c #DEDEDE",
+"@ c #FFFFFF",
+"# c #FFFF00",
+"$ c #00FF00",
+".....................",
+".+++++++++++++.+++++.",
+".+++++++++++++.+++++.",
+".+++++++++++++.+++++.",
+".....................",
+".@@@@@@@@@@@@@.@@@@@.",
+".@@@@@@@@@@@@@.@@@@@.",
+".@@@...@@@@@@@.@@@@@.",
+".@@@.#.@@@@@@@.......",
+".@@@...@@@@@@@.@@@@@.",
+".@@@@.@@@@@@@@.@@@@@.",
+".@@@@.@@...@@@.@@@@@.",
+".@@@@....$.@@@.......",
+".@@@@.@@...@@@.@@@@@.",
+".@@@@.@@@@@@@@.@@@@@.",
+".@@@@.@@...@@@.@@@@@.",
+".@@@@....$.@@@.......",
+".@@@@@@@...@@@.@@@@@.",
+".@@@@@@@@@@@@@.@@@@@.",
+".@@@@@@@@@@@@@.@@@@@.",
+"....................."};
diff --git a/tools/glade/glade/graphics/curve.xpm b/tools/glade/glade/graphics/curve.xpm
new file mode 100644
index 00000000..eb30712d
--- /dev/null
+++ b/tools/glade/glade/graphics/curve.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *curve_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 5 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c None",
+/* pixels */
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OO.................OO",
+"OO.XXX.XXX.XXX.X .OO",
+"OO.XXX.XXX.XXX X.OO",
+"OO.XXX.XXX.X XXX.OO",
+"OO........ ......OO",
+"OO.XXX.XX XXX.XXX.OO",
+"OO.XXX.X .XXX.XXX.OO",
+"OO.XXX. X.XXX.XXX.OO",
+"OO.... ...........OO",
+"OO.XXX XXX.XXX.XXX.OO",
+"OO.XX .XXX.XXX.XXX.OO",
+"OO.XX .XXX.XXX.XXX.OO",
+"OO.. .............OO",
+"OO.X X.XXX.XXX.XXX.OO",
+"OO. X.XXX.XXX.XXX.OO",
+"OO. XX.XXX.XXX.XXX.OO",
+"OO.................OO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO"
+};
diff --git a/tools/glade/glade/graphics/custom.xpm b/tools/glade/glade/graphics/custom.xpm
new file mode 100644
index 00000000..7b5cd917
--- /dev/null
+++ b/tools/glade/glade/graphics/custom.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * custom_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #0000FF",
+" ",
+" ",
+" ................+ ",
+" .@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@#+ ",
+" .@@@@@$$$$@@@@@#+ ",
+" .@@@@$$$$$$@@@@#+ ",
+" .@@@$$$@@@$$@@@#+ ",
+" .@@@$$@@@@@$@@@#+ ",
+" .@@@$$@@@@@@@@@#+ ",
+" .@@@$$@@@@@@@@@#+ ",
+" .@@@$$@@@@@$@@@#+ ",
+" .@@@$$$@@@$$@@@#+ ",
+" .@@@@$$$$$$@@@@#+ ",
+" .@@@@@$$$$@@@@@#+ ",
+" .@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@#+ ",
+" .###############+ ",
+" +++++++++++++++++ ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/custom_bg.xpm b/tools/glade/glade/graphics/custom_bg.xpm
new file mode 100644
index 00000000..dabb1809
--- /dev/null
+++ b/tools/glade/glade/graphics/custom_bg.xpm
@@ -0,0 +1,15 @@
+/* XPM */
+static char * custom_bg_xpm[] = {
+"8 8 4 1",
+" c None",
+". c #BBBBBB",
+"+ c #D6D6D6",
+"@ c #6B5EFF",
+".+..+...",
+"+..@@@..",
+"..@...++",
+"..@...++",
+"+.@..+..",
+".++@@@..",
+"..++....",
+"..++...."};
diff --git a/tools/glade/glade/graphics/dialog.xpm b/tools/glade/glade/graphics/dialog.xpm
new file mode 100644
index 00000000..00473b65
--- /dev/null
+++ b/tools/glade/glade/graphics/dialog.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *dialog_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 11 1",
+" c Gray0",
+". c #00007b",
+"X c #7b7b7b",
+"o c Green",
+"O c Cyan",
+"+ c Red",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray100",
+"& c None",
+/* pixels */
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&XXXXXXXXXXXXXXXX&&&",
+"&&X.+@............ &&",
+"&&X.Oo.%%%....# # &&",
+"&&XXXXXXXXXXXXXXXX &&",
+"&&X%%%%%%%%%%%%%%X &&",
+"&&X%%%%%%%%%%%%%%X &&",
+"&&X%%X%XX%XX%XX%%X &&",
+"&&X%%%%%%%%%%%%%%X &&",
+"&&X%%%%%%%%%%%%%%X &&",
+"&&X%%%XXX%%XXX%%%X &&",
+"&&X%%%X %%X %%%X &&",
+"&&X%%%%%%%%%%%%%%X &&",
+"&&XXXXXXXXXXXXXXXX &&",
+"&&& &&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&"
+};
diff --git a/tools/glade/glade/graphics/drawingarea.xpm b/tools/glade/glade/graphics/drawingarea.xpm
new file mode 100644
index 00000000..4770628b
--- /dev/null
+++ b/tools/glade/glade/graphics/drawingarea.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *drawingarea_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c Blue",
+"X c Red",
+"o c Yellow",
+"O c #b3cece",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"++ +++++++++",
+"++ XXXXXXXX +++++++++",
+"++ XXXXXXXX +++++",
+"++ XXXXXXX ooooo ++++",
+"++ XXXXXX ooooooo +++",
+"++ XXXXX ooooooooo ++",
+"++ XXXXX ooooooooo ++",
+"++ XXXXX ooooooooo ++",
+"++ XXXXX ooooooooo ++",
+"++ ooooooo +++",
+"++++ ..... ooooo ++++",
+"++++ ...... +++++",
+"++++ ......... ++++++",
+"++++ ......... ++++++",
+"++++ ......... ++++++",
+"++++ ++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/entry.xpm b/tools/glade/glade/graphics/entry.xpm
new file mode 100644
index 00000000..cb900413
--- /dev/null
+++ b/tools/glade/glade/graphics/entry.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *entry_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"....................O",
+". XO",
+". OOOOOOOOOOOOOOOOOXO",
+". OOOOOOOOOOOOOOO OXO",
+". OOOOOOOO OOOOOO OXO",
+". OOOOOOOO OOOOOO OXO",
+". OOO OO X OOO OXO",
+". OO XOX O O. OO OXO",
+". OOOOOO O OOO OO OXO",
+". OOO O OOO OO OXO",
+". OO XOO O OOO OO OXO",
+". OO XOO O OO. OO OXO",
+". OOO O OOO OXO",
+". OOOOOOOOOOOOOOO OXO",
+". OOOOOOOOOOOOOOOOOXO",
+".XXXXXXXXXXXXXXXXXXXO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/eventbox.xpm b/tools/glade/glade/graphics/eventbox.xpm
new file mode 100644
index 00000000..73da445d
--- /dev/null
+++ b/tools/glade/glade/graphics/eventbox.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *eventbox_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c Blue",
+"o c #d6d6d6",
+"O c #b3cece",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@X+@@@@@@@@@",
+"@@@@@@@@@XX+@@@@@@@@@",
+"@@@@@@@@XX+@@@@@@@@@@",
+"@@@@@@@XX+@@@@@@@@@@@",
+"@@@@@@@@XX+@@@@@@@@@@",
+"@@@@@@@@@XX+@@@@@@@@@",
+"@@@@@@@@@@XX+@@@@@@@@",
+"@@@++++++XX++++++ @@@",
+"@@@+ooooXX+ooooo. @@@",
+"@@@+oooXX+oooooo. @@@",
+"@@@+ooooXX+ooooo. @@@",
+"@@@+oooooXX+oooo. @@@",
+"@@@+ooooooXX+ooo. @@@",
+"@@@+oooooooooooo. @@@",
+"@@@+oooooooooooo. @@@",
+"@@@+oooooooooooo. @@@",
+"@@@+............. @@@",
+"@@@ @@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/expander.xpm b/tools/glade/glade/graphics/expander.xpm
new file mode 100644
index 00000000..7aff2542
--- /dev/null
+++ b/tools/glade/glade/graphics/expander.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static char * expander_xpm[] = {
+"21 21 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" .. ",
+" .+. ",
+" .++. ... . ",
+" .+++. . . . ",
+" .++++. . . ... ... ",
+" .+++. ... . . . ",
+" .++. . . . . . ",
+" .+. . . ... ... ",
+" .. ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/filechooserbutton.xpm b/tools/glade/glade/graphics/filechooserbutton.xpm
new file mode 100644
index 00000000..886566ed
--- /dev/null
+++ b/tools/glade/glade/graphics/filechooserbutton.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * filechooserbutton_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #FFFF00",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@++@@@@@@@@#+ ",
+" .@@@@@+$$+++@@@@@#+ ",
+" .@@@@@+$$$$$+@@@@#+ ",
+" .@@@@@+$$$$$+@@@@#+ ",
+" .@@@@@+$$$$$+@@@@#+ ",
+" .@@@@@+++++++@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/filechooserdialog.xpm b/tools/glade/glade/graphics/filechooserdialog.xpm
new file mode 100644
index 00000000..3d2e9529
--- /dev/null
+++ b/tools/glade/glade/graphics/filechooserdialog.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * filechooserdialog_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #00007B",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ................ ",
+" .+@#+++++++++++.$ ",
+" .+%&+***++++=$=.$ ",
+" ................$ ",
+" .**************.$ ",
+" .*****$$*******.$ ",
+" .****$##$$$****.$ ",
+" .****$#####$***.$ ",
+" .****$#####$***.$ ",
+" .****$#####$***.$ ",
+" .****$$$$$$$***.$ ",
+" .**************.$ ",
+" ................$ ",
+" $$$$$$$$$$$$$$$$ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/filechooserwidget.xpm b/tools/glade/glade/graphics/filechooserwidget.xpm
new file mode 100644
index 00000000..560af2b6
--- /dev/null
+++ b/tools/glade/glade/graphics/filechooserwidget.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * filechooserwidget_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #7B7B7B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #FFFF00",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ................ ",
+" .++++++++++++++.@ ",
+" .++++++++++++++.@ ",
+" .+++++@@+++++++.@ ",
+" .++++@##@@@++++.@ ",
+" .++++@#####@+++.@ ",
+" .++++@#####@+++.@ ",
+" .++++@#####@+++.@ ",
+" .++++@@@@@@@+++.@ ",
+" .++++++++++++++.@ ",
+" .++++++++++++++.@ ",
+" ................@ ",
+" @@@@@@@@@@@@@@@@ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/fileseldialog.xpm b/tools/glade/glade/graphics/fileseldialog.xpm
new file mode 100644
index 00000000..cbe792e9
--- /dev/null
+++ b/tools/glade/glade/graphics/fileseldialog.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * fileseldialog_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #00007B",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ................ ",
+" .+@#+++++++++++.$ ",
+" .+%&+***++++=$=.$ ",
+" ................$ ",
+" .**************.$ ",
+" .*****$$*******.$ ",
+" .****$##$$$****.$ ",
+" .****$#####$***.$ ",
+" .****$#####$***.$ ",
+" .****$#####$***.$ ",
+" .****$$$$$$$***.$ ",
+" .**************.$ ",
+" ................$ ",
+" $$$$$$$$$$$$$$$$ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/fixed.xpm b/tools/glade/glade/graphics/fixed.xpm
new file mode 100644
index 00000000..1e50253a
--- /dev/null
+++ b/tools/glade/glade/graphics/fixed.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * fixed_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@.....+@@@@@@@@@@@#+",
+".@.@@@#+@@@@@@@@@@@#+",
+".@.@@@#+@@@@.....+@#+",
+".@.####+@@@@.@@@#+@#+",
+".@++++++@@@@.@@@#+@#+",
+".@@@@@@@@@@@.####+@#+",
+".@@@@@@@@@@@++++++@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@.....+@@@@@@@@#+",
+".@@@@.@@@#+@@@@@@@@#+",
+".@@@@.@@@#+@@@@@@@@#+",
+".@@@@.####+@@@@@@@@#+",
+".@@@@++++++@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/fontbutton.xpm b/tools/glade/glade/graphics/fontbutton.xpm
new file mode 100644
index 00000000..6b2b39e9
--- /dev/null
+++ b/tools/glade/glade/graphics/fontbutton.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * fontbutton_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #FFFF9C",
+"% c #FF0000",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@$$$$$@@@@@#+ ",
+" .@@@@@@%%%%$@@@@@#+ ",
+" .@@@@@%$$%%$@@@@@#+ ",
+" .@@@@@@@%$%$%%%@@#+ ",
+" .@@@%$$%%%%%$$$%@#+ ",
+" .@@%$%%%$$%%$@@$@#+ ",
+" .@@@$%$$%@$%$@@@@#+ ",
+" .@@@$%$%@@$%$$$%@#+ ",
+" .@@@$%$$%@@$%%%$@#+ ",
+" .@@@$%%%$@@@$$$@@#+ ",
+" .@@@@$$$@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/fontsel.xpm b/tools/glade/glade/graphics/fontsel.xpm
new file mode 100644
index 00000000..cd397292
--- /dev/null
+++ b/tools/glade/glade/graphics/fontsel.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char *fontsel_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 8 1",
+" c Gray0",
+". c #7b7b7b",
+"X c Gray61",
+"o c #d6d6d6",
+"O c #b3cece",
+"+ c Gray87",
+"@ c Gray100",
+"# c None",
+/* pixels */
+"#####################",
+"#####################",
+"#####################",
+"#####################",
+"#####################",
+"##................###",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@X o@@@. ##",
+"##.@@@@@@+ @X@@@. ##",
+"##.@@@@@ @@@@@@. ##",
+"##.@@@@@@ @@@@@. ##",
+"##.@@@ + @@@@@@@. ##",
+"##.@@@o X@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##.@@@@@@@@@@@@@@. ##",
+"##................ ##",
+"### ##",
+"#####################",
+"#####################",
+"#####################"
+};
diff --git a/tools/glade/glade/graphics/fontseldialog.xpm b/tools/glade/glade/graphics/fontseldialog.xpm
new file mode 100644
index 00000000..1e8e82e0
--- /dev/null
+++ b/tools/glade/glade/graphics/fontseldialog.xpm
@@ -0,0 +1,40 @@
+/* XPM */
+static char *fontseldialog_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 13 1",
+" c Gray0",
+". c #00007b",
+"X c #7b7b7b",
+"o c Green",
+"O c Cyan",
+"+ c Red",
+"@ c Yellow",
+"# c Gray61",
+"$ c #d6d6d6",
+"% c #b3cece",
+"& c Gray87",
+"* c Gray100",
+"= c None",
+/* pixels */
+"=====================",
+"=====================",
+"=====================",
+"=====================",
+"==XXXXXXXXXXXXXXXX===",
+"==X.+@...........X ==",
+"==X.Oo.***....$ $X ==",
+"==XXXXXXXXXXXXXXXX ==",
+"==X**************X ==",
+"==X*******# $***X ==",
+"==X******& *#***X ==",
+"==X***** ******X ==",
+"==X****** *****X ==",
+"==X*** & *******X ==",
+"==X***$ #*******X ==",
+"==X**************X ==",
+"==XXXXXXXXXXXXXXXX ==",
+"=== ==",
+"=====================",
+"=====================",
+"====================="
+};
diff --git a/tools/glade/glade/graphics/frame.xpm b/tools/glade/glade/graphics/frame.xpm
new file mode 100644
index 00000000..c8c8b578
--- /dev/null
+++ b/tools/glade/glade/graphics/frame.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *frame_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++ + +++++++++++",
+"+...X X X X......O+",
+"+.OOX X X XOOOOO.O+",
+"+.OXX X X XXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+.OXXXXXXXXXXXXXXX.O+",
+"+..................O+",
+"+OOOOOOOOOOOOOOOOOOO+",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/gammacurve.xpm b/tools/glade/glade/graphics/gammacurve.xpm
new file mode 100644
index 00000000..da0dcc74
--- /dev/null
+++ b/tools/glade/glade/graphics/gammacurve.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *gammacurve_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"++++++++++++++++++OOO",
+".................+OX.",
+".XXX.XXX.XXX.X .+O..",
+".XXX.XXX.XXX X.++++",
+".XXX.XXX.X XXX.+OOO",
+"........ ......+OX.",
+".XXX.XX XXX.XXX.+O..",
+".XXX.X .XXX.XXX.++++",
+".XXX. X.XXX.XXX.+OOO",
+".... ...........+OX.",
+".XXX XXX.XXX.XXX.+O..",
+".XX .XXX.XXX.XXX.++++",
+".XX .XXX.XXX.XXX.+OOO",
+".. .............+OX.",
+".X X.XXX.XXX.XXX.+O..",
+". X.XXX.XXX.XXX.++++",
+". XX.XXX.XXX.XXX.+OOO",
+".................+OX.",
+"++++++++++++++++++O..",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/glade-atk.xpm b/tools/glade/glade/graphics/glade-atk.xpm
new file mode 100644
index 00000000..d6a051b1
--- /dev/null
+++ b/tools/glade/glade/graphics/glade-atk.xpm
@@ -0,0 +1,112 @@
+/* XPM */
+static char * glade_atk_xpm[] = {
+"20 20 89 1",
+" c None",
+". c #AEAFAE",
+"+ c #FFFFFF",
+"@ c #C4C4F1",
+"# c #4646D3",
+"$ c #8484E2",
+"% c #3535D0",
+"& c #0000C4",
+"* c #D5D5F5",
+"= c #6363DB",
+"- c #1515C9",
+"; c #EEEEFB",
+"> c #F7F7FD",
+", c #6969DC",
+"' c #B7B7EE",
+") c #7A7AE0",
+"! c #0606C5",
+"~ c #DDDDF7",
+"{ c #5656D8",
+"] c #B2B2ED",
+"^ c #6464DB",
+"/ c #6868DC",
+"( c #9F9FE9",
+"_ c #BCBCEF",
+": c #7373DE",
+"< c #2929CD",
+"[ c #EFEFFB",
+"} c #2121CC",
+"| c #8282E2",
+"1 c #E7E7FA",
+"2 c #E7E7F9",
+"3 c #E6E6F9",
+"4 c #F0F0FB",
+"5 c #7474DF",
+"6 c #FBFBFE",
+"7 c #9090E5",
+"8 c #CACAF3",
+"9 c #FEFEFF",
+"0 c #1616C9",
+"a c #ACACEC",
+"b c #D0D0F4",
+"c c #0808C6",
+"d c #3636D0",
+"e c #FDFDFF",
+"f c #E9E9FA",
+"g c #E4E4F8",
+"h c #E5E5F9",
+"i c #C1C1F1",
+"j c #4A4AD5",
+"k c #9B9BE8",
+"l c #EAEAFA",
+"m c #E2E2F8",
+"n c #0909C6",
+"o c #CECEF4",
+"p c #F3F3FC",
+"q c #1A1ACA",
+"r c #A7A7EB",
+"s c #F5F5FD",
+"t c #5656D7",
+"u c #8181E2",
+"v c #2424CC",
+"w c #0101C4",
+"x c #A6A6EA",
+"y c #2E2ECF",
+"z c #F8F8FD",
+"A c #2323CC",
+"B c #F4F4FC",
+"C c #2222CC",
+"D c #1919CA",
+"E c #A6A6EB",
+"F c #F2F2FC",
+"G c #2727CD",
+"H c #4E4ED6",
+"I c #9696E7",
+"J c #0707C6",
+"K c #E3E3F9",
+"L c #3737D1",
+"M c #1313C8",
+"N c #8F8FE5",
+"O c #7D7DE1",
+"P c #3030CF",
+"Q c #1010C8",
+"R c #AFAFEC",
+"S c #FCFCFE",
+"T c #5E5EDA",
+"U c #4040D3",
+"V c #4F4FD6",
+"W c #8B8BE4",
+"X c #ECECFA",
+"....................",
+".+++++@#$++++++++++.",
+".+++++%&&*+++++++++.",
+".+++++=&-;+++++++++.",
+".+++++>,'++++++++++.",
+".+++++)&!~+++++++++.",
+".+++++{&&]+++++++++.",
+".+++++^&&/((_++++++.",
+".+++~,:&&&&&<++++++.",
+".++[}/|&&)1234+++++.",
+".++5%67&&&&&&!8++++.",
+".+90a+bc&&&&&&de+++.",
+".+f&g++hiiiiij&k+++.",
+".+l&m++++++++*n-;op.",
+".+9qr+++++++stu&vwx.",
+".++)yz++++++uABCDE+.",
+".++FGH[+++9IJ_+b4++.",
+".+++KLM,NOPQR++++++.",
+".++++SaTUVWX+++++++.",
+"...................."};
diff --git a/tools/glade/glade/graphics/glade_logo.png b/tools/glade/glade/graphics/glade_logo.png
new file mode 100644
index 00000000..4786e6d2
--- /dev/null
+++ b/tools/glade/glade/graphics/glade_logo.png
Binary files differ
diff --git a/tools/glade/glade/graphics/gnome-about.xpm b/tools/glade/glade/graphics/gnome-about.xpm
new file mode 100644
index 00000000..af965f43
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-about.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * gnome_about_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #CC5972",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+".................... ",
+".+@#+++++++++++++++.$",
+".+%&+***+**+++++=+=.$",
+"....................$",
+".******************.$",
+".**$***$****$***$**.$",
+".***$*$******$*$***.$",
+".****$********$****.$",
+".***$*$**$$**$*$***.$",
+".**$***$*$$*$***$**.$",
+".******************.$",
+".****...****...****.$",
+".****.$$****.$$****.$",
+".******************.$",
+"....................$",
+" $$$$$$$$$$$$$$$$$$$$",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-animator.xpm b/tools/glade/glade/graphics/gnome-animator.xpm
new file mode 100644
index 00000000..e51f6e6f
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-animator.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * gnome_animator_xpm[] = {
+"21 21 8 1",
+" c None",
+". c #898989",
+"+ c #C4C4C4",
+"@ c #FFFF74",
+"# c #FFFFFF",
+"$ c #FFFFBF",
+"% c #000000",
+"& c #FFFF00",
+" ",
+" ",
+" ",
+" ",
+" .+ ",
+" +@@.++ ",
+" ++#.$$@@.. ",
+" +$$++@@$.@@... ",
+" +$@$.@$@.@@@@@. ",
+" +++$$$+.++.@@@%%. ",
+"+$$+@$@$@+ .@@%&&%%% ",
+"+$$+++++++ ...%&&&&&%",
+"+$$$$$+ %&&&&&%",
+"+$$$$$+ %&&&&&%",
+"+++++++ %%%%%%%",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-app.xpm b/tools/glade/glade/graphics/gnome-app.xpm
new file mode 100644
index 00000000..713889aa
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-app.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * gnome_app_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #CC5972",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+".................... ",
+".+@#+++++++++++++++.$",
+".+%&+***+**+++++=+=.$",
+"....................$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+".=*****************.$",
+"....................$",
+" $$$$$$$$$$$$$$$$$$$$",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-appbar.xpm b/tools/glade/glade/graphics/gnome-appbar.xpm
new file mode 100644
index 00000000..cd622401
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-appbar.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_appbar_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #7B7B7B",
+"+ c #000000",
+"@ c #FFFFFF",
+"# c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+".....................",
+".++++++++++++@++++++@",
+".+###########@+#####@",
+".+###########@+#####@",
+".+###########@+#####@",
+".@@@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-calculator.xpm b/tools/glade/glade/graphics/gnome-calculator.xpm
new file mode 100644
index 00000000..8e4666ea
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-calculator.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_calculator_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ",
+" ",
+" ",
+" ............ ",
+" ........++.. ",
+" ........++.. ",
+" ............ ",
+" .@@@@@@@@@@. ",
+" .@@@@@@@@@@. ",
+" .@+#+#+#+#@. ",
+" .@########@. ",
+" .@+#+#+#+#@. ",
+" .@########@. ",
+" .@+#+#+#+#@. ",
+" .@########@. ",
+" .@+#+#+#+#@. ",
+" .@########@. ",
+" .@@@@@@@@@@. ",
+" ............ ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-canvas.xpm b/tools/glade/glade/graphics/gnome-canvas.xpm
new file mode 100644
index 00000000..3daf84e1
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-canvas.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * gnome_canvas_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #7B797B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #7B7B7B",
+"% c #FFFF00",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++++++@+++@@@+++#+",
+".@++####$@++@%%%@++#+",
+".@++####$@+@%%%%%@+#+",
+".@++####$@+@%%%%%@+#+",
+".@++$$$$$@++@%%%@++#+",
+".@+@@@@@@@+++@@@+++#+",
+".@+++++++++++++++++#+",
+".@+++++++@+++++++++#+",
+".@+++++++@+++++++++#+",
+".@+++@@@+@@@+++@@++#+",
+".@++@++@+@++@+@++++#+",
+".@++@++@+@++@+@++++#+",
+".@+++@@@+@@@+++@@++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/gnome-colorpicker.xpm b/tools/glade/glade/graphics/gnome-colorpicker.xpm
new file mode 100644
index 00000000..ca6831e2
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-colorpicker.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * gnome_colorpicker_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #949594",
+"% c #E6A1CD",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@............$@#+ ",
+" .@@.$$$$$$$$$$.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@.$%%%%%%%%%.$@#+ ",
+" .@@............$@#+ ",
+" .@@$$$$$$$$$$$$$@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-control.xpm b/tools/glade/glade/graphics/gnome-control.xpm
new file mode 100644
index 00000000..569925f7
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-control.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * gnome_control_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #FFFFFF",
+"+ c #D6D6D6",
+"@ c #7B7B7B",
+"# c #A1A6C9",
+"$ c #000000",
+" ..... ",
+" ........+++@....... ",
+" #######.+++@####### ",
+" @@@@@@@.+++@@@@@@@@ ",
+" @@@@@ ",
+" .#@ ",
+" .#@ ",
+" ..............$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .++++++++++++@$ ",
+" .@@@@@@@@@@@@@$ ",
+" $$$$$$$$$$$$$$$ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-dateedit.xpm b/tools/glade/glade/graphics/gnome-dateedit.xpm
new file mode 100644
index 00000000..18954671
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-dateedit.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_dateedit_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DEDEDE",
+"# c #FF0000",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+".....................",
+".+++++++++++++++.@@@.",
+".+++++++++++++++..@..",
+".....................",
+" ",
+" ####### ",
+" #+++++# ",
+" #++.++# ",
+" #+..++# ",
+" #++.++# ",
+" #+...+# ",
+" #+++++# ",
+" ####### "};
diff --git a/tools/glade/glade/graphics/gnome-db-browser.xpm b/tools/glade/glade/graphics/gnome-db-browser.xpm
new file mode 100644
index 00000000..9b978f61
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-browser.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_browser_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+@@@@@@@@@@ ",
+".++.+++++@++++++++@ ",
+"..+.+..++@@@@@@@@@@ ",
+".++.+++++@++++++++@ ",
+"...@@@@@@@@@@##+#+@ ",
+" @++++++++@+++++@ ",
+" @@@@@@@@@@@@@@@@ ",
+" @++++++++@ ",
+" @+#+@@@@@@@@@@ ",
+" @+++@++++++++@ ",
+" @@@@@@@@@@@@@@ ",
+" @++++++++@ ",
+" @+##+##++@ ",
+" @++++++++@ ",
+" @@@@@@@@@@ "};
diff --git a/tools/glade/glade/graphics/gnome-db-combo.xpm b/tools/glade/glade/graphics/gnome-db-combo.xpm
new file mode 100644
index 00000000..14e8c991
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-combo.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_combo_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.@@@@@@@@@@@@@@@@ ",
+"..+.@++++++++++@...@ ",
+".++.@++++++++++@@.@@ ",
+"....@@@@@@@@@@@@@@@@ ",
+" @++++++++++++++@ ",
+" @+#########++++@ ",
+" @++++++++++++++@ ",
+" @+############+@ ",
+" @++++++++++++++@ ",
+" @+##########+++@ ",
+" @++++++++++++++@ ",
+" @@@@@@@@@@@@@@@@ ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-connection-properties.xpm b/tools/glade/glade/graphics/gnome-db-connection-properties.xpm
new file mode 100644
index 00000000..126aa35d
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-connection-properties.xpm
@@ -0,0 +1,94 @@
+/* XPM */
+static char * gnome_db_connection_properties_xpm[] = {
+"21 21 70 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #000000",
+"$ c #F6F6F6",
+"% c #B8B8B8",
+"& c #5E5E5C",
+"* c #393836",
+"= c #C9C9C9",
+"- c #838282",
+"; c #33322F",
+"> c #ACACAB",
+", c #73716B",
+"' c #9F9D99",
+") c #84817A",
+"! c #2B2B2B",
+"~ c #555555",
+"{ c #A8A8A8",
+"] c #575755",
+"^ c #A3A098",
+"/ c #AAAAAA",
+"( c #A4A4A4",
+"_ c #666663",
+": c #EBEAE6",
+"< c #C2BFB9",
+"[ c #8A8881",
+"} c #424643",
+"| c #89918B",
+"1 c #636463",
+"2 c #5C5B5A",
+"3 c #AAA7A1",
+"4 c #9C9B97",
+"5 c #CBC9C4",
+"6 c #EDEBE8",
+"7 c #B5B2AB",
+"8 c #8B8982",
+"9 c #D3D3D3",
+"0 c #5B5B5A",
+"a c #AAA7A0",
+"b c #55534D",
+"c c #53514A",
+"d c #807E75",
+"e c #AEABA4",
+"f c #9E9A92",
+"g c #827F78",
+"h c #50504F",
+"i c #99978F",
+"j c #9A9A9A",
+"k c #53524D",
+"l c #9C9991",
+"m c #949087",
+"n c #7E7C74",
+"o c #8A928C",
+"p c #656665",
+"q c #494947",
+"r c #8F8C84",
+"s c #AAA9A9",
+"t c #5B5954",
+"u c #716E66",
+"v c #6C6860",
+"w c #444341",
+"x c #87847B",
+"y c #F4F4F4",
+"z c #B7B7B7",
+"A c #706F6D",
+"B c #3B3A36",
+"C c #C4C4C4",
+"D c #81807F",
+"E c #302F2B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".+@@@@@@@@@@@@@@@@@@ ",
+"..@++++++++++++++++@#",
+".+@++++++++++++++++@#",
+"..@++++++++++++++++@#",
+".+@++++++++++++++++@#",
+"..@++++$%&*=+++++-;@#",
+" @++++>,')!~{+++]^@#",
+" @+//(_:<[}|1+++23@#",
+" @+4445678~/9+++0a@#",
+" @+bbcdefg~/9+++hi@#",
+" @+//jklmn}op+++qr@#",
+" @++++stuv!~{+++wx@#",
+" @++++yzABC+++++DE@#",
+" @++++++++++++++++@#",
+" @@@@@@@@@@@@@@@@@@#",
+" ###################"};
diff --git a/tools/glade/glade/graphics/gnome-db-connectsel.xpm b/tools/glade/glade/graphics/gnome-db-connectsel.xpm
new file mode 100644
index 00000000..3daedff3
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-connectsel.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * gnome_db_connectsel_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+"++++++++++++++++++++@",
+"+##################$@",
+"+##################$@",
+"+##################$@",
+"+############++++##$@",
+"+############+##@##$@",
+"+############+@@@##$@",
+"+##################$@",
+"+##################$@",
+"+##################$@",
+"+$$$$$$$$$$$$$$$$$$$@",
+"@@@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-dataset.xpm b/tools/glade/glade/graphics/gnome-db-dataset.xpm
new file mode 100644
index 00000000..b4a5427e
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-dataset.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_dataset_xpm[] = {
+"21 21 5 1",
+" c None",
+" c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............         ",
+".++.++.++.+.         ",
+"............         ",
+".++.+++++++.         ",
+"..+.+..+.++.         ",
+".++.+++++++.         ",
+"..+.+.+.+.+.         ",
+".++.+@@@@@@@@@@@@@@@ ",
+"..+. @+++++++++++++@ ",
+".++. @+##+##+##+##+@ ",
+".... @+++++++++++++@ ",
+"     @+++++++++++++@ ",
+"     @+@@@@@@@@@@@+@ ",
+"     @+++++++++++++@ ",
+"     @+@@@@@@@@@@@+@ ",
+"     @+++++++++++++@ ",
+"     @+@@@@@@@@@@@+@ ",
+"     @+++++++++++++@ ",
+"     @+++++++++++++@ ",
+"     @@@@@@@@@@@@@@@ ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-designer.xpm b/tools/glade/glade/graphics/gnome-db-designer.xpm
new file mode 100644
index 00000000..d1285132
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-designer.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_designer_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-dsn-druid.xpm b/tools/glade/glade/graphics/gnome-db-dsn-druid.xpm
new file mode 100644
index 00000000..9a2e914c
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-dsn-druid.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * gnome_db_dsn_druid_xpm[] = {
+"21 21 8 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #07077B",
+"$ c #000000",
+"% c #00007B",
+"& c #D6D6D6",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"@@@@@@@@@@@@@@@@@@@@ ",
+"@##################@$",
+"@#+++#++########++#@$",
+"@###############++#@$",
+"@%%%%%%%%%%%%%%%###@$",
+"@$$$$++++++++++++++@$",
+"@$@&$++++++++++++++@$",
+"@$&@$+++$++$++$++++@$",
+"@$@&$+++++$+$++$+++@$",
+"@$&@$+++$+++++$$+++@$",
+"@$&&$++++++++++++++@$",
+"@$$$$++++++++++++++@$",
+"@&+++@@@+@@@+++@@@+@$",
+"@&++++&&&+&&&+++&&&@$",
+"@@@@@@@@@@@@@@@@@@@@$",
+" $$$$$$$$$$$$$$$$$$$$",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-dsnconfig.xpm b/tools/glade/glade/graphics/gnome-db-dsnconfig.xpm
new file mode 100644
index 00000000..ae0883b6
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-dsnconfig.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_dsnconfig_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.+@@@@@@@@@@@@@@@ ",
+"..+. @+++++++++++++@ ",
+".++. @+++++++++++++@ ",
+".... @+@@+@@@@@@@@+@ ",
+" @+++++++++++++@ ",
+" @+@@+@@@@@@@@+@ ",
+" @+++++++++++++@ ",
+" @+@@+@@@@@@@@+@ ",
+" @+++++++++++++@ ",
+" @+@@+@@@@@@@@+@ ",
+" @+++++++++++++@ ",
+" @+++++++++++++@ ",
+" @@@@@@@@@@@@@@@ ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-editor.xpm b/tools/glade/glade/graphics/gnome-db-editor.xpm
new file mode 100644
index 00000000..1231a973
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-editor.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * gnome_db_editor_xpm[] = {
+"21 21 8 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #000000",
+"$ c #E8BA04",
+"% c #F92011",
+"& c #2BC60B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".+@@@@@@@@@@@@@@@@@@ ",
+"..@++++++++++++++++@#",
+".+@+$$+$+$$++++++++@#",
+"..@++++++++++++++++@#",
+".+@++++%%%%+%%%++++@#",
+"..@++++++++++++++++@#",
+" @++++++&+&&&&&+++@#",
+" @++++++++++++++++@#",
+" @++++%%%%+%++++++@#",
+" @++++++++++++++++@#",
+" @++++%%++%++%%%%+@#",
+" @++++++++++++++++@#",
+" @+$+$$+$$$$++++++@#",
+" @++++++++++++++++@#",
+" @@@@@@@@@@@@@@@@@@#",
+" ###################"};
diff --git a/tools/glade/glade/graphics/gnome-db-entry.xpm b/tools/glade/glade/graphics/gnome-db-entry.xpm
new file mode 100644
index 00000000..25197749
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-entry.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_entry_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-error-dlg.xpm b/tools/glade/glade/graphics/gnome-db-error-dlg.xpm
new file mode 100644
index 00000000..c765e962
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-error-dlg.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char * gnome_db_error_dlg_xpm[] = {
+"21 21 11 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #00007B",
+"$ c #FF0000",
+"% c #FFFF00",
+"& c #000000",
+"* c #00FFFF",
+"= c #00FF00",
+"- c #D6D6D6",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.@@@@@@@@@@@@@@@@ ",
+"..+.@#$%############&",
+".++.@#*=#+++####-&-&&",
+"....@@@@@@@@@@@@@@@@&",
+" @++++++++++++++@&",
+" @++++++$$++++++@&",
+" @++++++$$++++++@&",
+" @++++++$$++++++@&",
+" @++++++$$++++++@&",
+" @++++++++++++++@&",
+" @++++++$$++++++@&",
+" @++++++++++++++@&",
+" @@@@@@@@@@@@@@@@&",
+" &&&&&&&&&&&&&&&&"};
diff --git a/tools/glade/glade/graphics/gnome-db-error.xpm b/tools/glade/glade/graphics/gnome-db-error.xpm
new file mode 100644
index 00000000..7ecb9c95
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-error.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * gnome_db_error_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #000000",
+"$ c #FF0000",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.+++++++. ",
+"..+.@@@@@@@@@@@@@@@@ ",
+".++.@++++++++++++++@#",
+"....@++++++$$++++++@#",
+" @++++++$$++++++@#",
+" @++++++$$++++++@#",
+" @++++++$$++++++@#",
+" @++++++++++++++@#",
+" @++++++$$++++++@#",
+" @++++++++++++++@#",
+" @@@@@@@@@@@@@@@@#",
+" ################",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-export.xpm b/tools/glade/glade/graphics/gnome-db-export.xpm
new file mode 100644
index 00000000..6a21ade5
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-export.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_export_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-form.xpm b/tools/glade/glade/graphics/gnome-db-form.xpm
new file mode 100644
index 00000000..776e5586
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-form.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_form_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++++++++++++++@",
+".+@++@@@++##+#+##+++@",
+"..@+++++++++++++++++@",
+" @++@@+++###+++++++@",
+" @+++++++++++++++++@",
+" @++@+@++#+##++++++@",
+" @+++++++++++++++++@",
+" @++++@+++++++@++++@",
+" @+++@@+++++++@@+++@",
+" @++++@+++++++@++++@",
+" @+++++++++++++++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-graybar.xpm b/tools/glade/glade/graphics/gnome-db-graybar.xpm
new file mode 100644
index 00000000..b9201560
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-graybar.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_graybar_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+"++++++++++++++++++++@",
+"####################@",
+"#######+############@",
+"##+++##+############@",
+"#+###+#+#++#########@",
+"#####+#++##+########@",
+"##++++#+###+########@",
+"#+###+#+###+########@",
+"#+###+#+###+########@",
+"##++++#++++#########@",
+"####################@",
+"@@@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-grid.xpm b/tools/glade/glade/graphics/gnome-db-grid.xpm
new file mode 100644
index 00000000..dbe6a92d
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-grid.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_grid_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-iconlist.xpm b/tools/glade/glade/graphics/gnome-db-iconlist.xpm
new file mode 100644
index 00000000..6105d885
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-iconlist.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_iconlist_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............         ",
+".++.++.++.+.         ",
+"............         ",
+".++.+++++++.         ",
+"..+.+..+.++.         ",
+".++.+++++++.         ",
+"..+.+.+.+.+.         ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+@@@+@+@@@+@+@@@+@",
+"..@+++++@+++++@+++++@",
+"  @@@@@@@@@@@@@@@@@@@",
+"  @+++++@+++++@+++++@",
+"  @+###+@+###+@+###+@",
+"  @+++++@+++++@+++++@",
+"  @+###+@+###+@+###+@",
+"  @+++++@+++++@+++++@",
+"  @+###+@+###+@+###+@",
+"  @+++++@+++++@+++++@",
+"  @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-label.xpm b/tools/glade/glade/graphics/gnome-db-label.xpm
new file mode 100644
index 00000000..92cc78ee
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-label.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_label_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-list.xpm b/tools/glade/glade/graphics/gnome-db-list.xpm
new file mode 100644
index 00000000..28163ba6
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-list.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_list_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.++@@@@@@@@@@@@@ ",
+"..+.+.@+++++++++++@ ",
+".++.++@+#########+@ ",
+"......@+++++++++++@ ",
+" @+#########+@ ",
+" @+++++++++++@ ",
+" @+#########+@ ",
+" @+++++++++++@ ",
+" @+#########+@ ",
+" @+++++++++++@ ",
+" @+#########+@ ",
+" @+++++++++++@ ",
+" @@@@@@@@@@@@@ ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-log-viewer.xpm b/tools/glade/glade/graphics/gnome-db-log-viewer.xpm
new file mode 100644
index 00000000..deccde30
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-log-viewer.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_log_viewer_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-login-dlg.xpm b/tools/glade/glade/graphics/gnome-db-login-dlg.xpm
new file mode 100644
index 00000000..ed4faf28
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-login-dlg.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char * gnome_db_login_dlg_xpm[] = {
+"21 21 11 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #00007B",
+"$ c #FF0000",
+"% c #FFFF00",
+"& c #000000",
+"* c #00FFFF",
+"= c #00FF00",
+"- c #D6D6D6",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.@@@@@@@@@@@@@@@@ ",
+"..+.@#$%############&",
+".++.@#*=#+++####-&-&&",
+"....@@@@@@@@@@@@@@@@&",
+" @++++++++++++++@&",
+" @+++++&&&&&++++@&",
+" @++++&&&&&&++++@&",
+" @++++&&&&&&++++@&",
+" @++++&&&&&&&+++@&",
+" @+++++&&&&&++++@&",
+" @++++++&&&&++++@&",
+" @++++++++++++++@&",
+" @@@@@@@@@@@@@@@@&",
+" &&&&&&&&&&&&&&&&"};
diff --git a/tools/glade/glade/graphics/gnome-db-login.xpm b/tools/glade/glade/graphics/gnome-db-login.xpm
new file mode 100644
index 00000000..97d82636
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-login.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_login_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #000000",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.+++++++. ",
+"..+.@@@@@@@@@@@@@@@@ ",
+".++.@++++++++++++++@#",
+"....@+++++#####++++@#",
+" @++++######++++@#",
+" @++++######++++@#",
+" @++++#######+++@#",
+" @+++++#####++++@#",
+" @++++++####++++@#",
+" @++++++++++++++@#",
+" @@@@@@@@@@@@@@@@#",
+" ################",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-provider-sel.xpm b/tools/glade/glade/graphics/gnome-db-provider-sel.xpm
new file mode 100644
index 00000000..c00dc33e
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-provider-sel.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * gnome_db_provider_sel_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+"++++++++++++++++++++@",
+"+##################$@",
+"+##################$@",
+"+##################$@",
+"+############++++##$@",
+"+############+##@##$@",
+"+############+@@@##$@",
+"+##################$@",
+"+##################$@",
+"+##################$@",
+"+$$$$$$$$$$$$$$$$$$$@",
+"@@@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-query-builder.xpm b/tools/glade/glade/graphics/gnome-db-query-builder.xpm
new file mode 100644
index 00000000..98146ea9
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-query-builder.xpm
@@ -0,0 +1,60 @@
+/* XPM */
+static char * gnome_db_query_builder_xpm[] = {
+"21 21 36 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #7B7B7B",
+"# c #000000",
+"$ c #DDDDDD",
+"% c #474747",
+"& c #090909",
+"* c #0A0A0A",
+"= c #4E4E4E",
+"- c #E3E3E3",
+"; c #363636",
+"> c #6B6B6B",
+", c #E5E5E5",
+"' c #DEDEDE",
+") c #565656",
+"! c #404040",
+"~ c #EDEDED",
+"{ c #F3F3F3",
+"] c #D9D9D9",
+"^ c #040404",
+"/ c #FAFAFA",
+"( c #D7D7D7",
+"_ c #8B8B8B",
+": c #373737",
+"< c #FDFDFD",
+"[ c #808080",
+"} c #252525",
+"| c #666666",
+"1 c #414141",
+"2 c #EEEEEE",
+"3 c #020202",
+"4 c #ABABAB",
+"5 c #F5F5F5",
+"6 c #9B9B9B",
+"7 c #F4F4F4",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".+@@@@@@@@@@@@@@@@@@ ",
+"..@++++++++++++++++@#",
+".+@++++++++++++++++@#",
+"..@+++++$%&*=-+++++@#",
+".+@+++++;>,')!+++++@#",
+"..@++++~#{++]^+++++@#",
+" @++++/(+++_:+++++@#",
+" @+++++++<[}$+++++@#",
+" @+++++++|12++++++@#",
+" @+++++++3]+++++++@#",
+" @+++++++45+++++++@#",
+" @+++++++67+++++++@#",
+" @+++++++#-+++++++@#",
+" @++++++++++++++++@#",
+" @@@@@@@@@@@@@@@@@@#",
+" ###################"};
diff --git a/tools/glade/glade/graphics/gnome-db-report.xpm b/tools/glade/glade/graphics/gnome-db-report.xpm
new file mode 100644
index 00000000..edee0e0e
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-report.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_report_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".++.+@+++++++++++++@ ",
+"..+. @+++++++++++++@ ",
+".++. +++++++++++++++ ",
+".... @++#+###++##++@ ",
+" @+++++++++++++@ ",
+" @++###+#+##+++@ ",
+" +++++++++++++++ ",
+" @++#+#+###+#++@ ",
+" @+++++++++++++@ ",
+" @++#+##+##+#++@ ",
+" +++++++++++++++ ",
+" @+++++++++++++@ ",
+" @+++++++++++++@ ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-sourcesel.xpm b/tools/glade/glade/graphics/gnome-db-sourcesel.xpm
new file mode 100644
index 00000000..a27edd4f
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-sourcesel.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_sourcesel_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-sql-editor.xpm b/tools/glade/glade/graphics/gnome-db-sql-editor.xpm
new file mode 100644
index 00000000..e42a1cd2
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-sql-editor.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_sql_editor_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #00007B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".@@@@@@@@@@@@@@@@@@@@",
+".@++++++++++++++++++@",
+".@++++++++++++++++++@",
+".@++++++++++++++++++@",
+" @+##++++#+++++++#++@",
+" @+#++##+#+##+##+##+@",
+" @+##+##+#+##+#++#++@",
+" @++#+#++#+#++#++#++@",
+" @+##+##+#+##+##+##+@",
+" @++++++++++++++++++@",
+" @++++++++++++++++++@",
+" @++++++++++++++++++@",
+" @@@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-table-editor.xpm b/tools/glade/glade/graphics/gnome-db-table-editor.xpm
new file mode 100644
index 00000000..5bfc53a8
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-table-editor.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_table_editor_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++++++++++++++@",
+".+@+@@#@++###+++++++@",
+"..@+++++++++++++++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-db-window.xpm b/tools/glade/glade/graphics/gnome-db-window.xpm
new file mode 100644
index 00000000..0e1b5a89
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-db-window.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_db_window_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #B5B5B5",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #7B7B7B",
+"............ ",
+".++.++.++.+. ",
+"............ ",
+".++.+++++++. ",
+"..+.+..+.++. ",
+".++.+++++++. ",
+"..+.+.+.+.+. ",
+".+@@@@@@@@@@@@@@@@@@@",
+"..@+++++@+++++@+++++@",
+".+@+###+@+###+@+###+@",
+"..@+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @+###+@+###+@+###+@",
+" @+++++@+++++@+++++@",
+" @@@@@@@@@@@@@@@@@@@",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-dialog.xpm b/tools/glade/glade/graphics/gnome-dialog.xpm
new file mode 100644
index 00000000..205785b6
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-dialog.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * gnome_dialog_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #CC5972",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ................ ",
+" .+@#++++++++++++$ ",
+" .+%&+***++++=+=+$ ",
+" ................$ ",
+" .**************.$ ",
+" .**************.$ ",
+" .**.*..*..*..**.$ ",
+" .**************.$ ",
+" .**************.$ ",
+" .***...**...***.$ ",
+" .***.$$**.$$***.$ ",
+" .**************.$ ",
+" ................$ ",
+" $$$$$$$$$$$$$$$$ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-dock-band.xpm b/tools/glade/glade/graphics/gnome-dock-band.xpm
new file mode 100644
index 00000000..e5d0a378
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-dock-band.xpm
@@ -0,0 +1,49 @@
+/* XPM */
+static char *gnome_dock_band_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 22 1",
+" c None",
+". c #302f2f",
+"X c #00007f",
+"o c #403f30",
+"O c #405040",
+"+ c #505f4f",
+"@ c #505f50",
+"# c #506050",
+"$ c Gray50",
+"% c Green",
+"& c Cyan",
+"* c Red",
+"= c #908070",
+"- c #90807f",
+"; c Yellow",
+": c #a09f90",
+"> c #bfafaf",
+", c #c0bfb0",
+"< c #cfc0bf",
+"1 c #d0d0d0",
+"2 c Gray100",
+"3 c Gray0",
+/* pixels */
+" ",
+" ",
+" ",
+"$$$$$$$$$$$$$$$$$$$$ ",
+"$X*;XXXXXXXXXXXXXXX$3",
+"$X&%X222X22XXXXX1 1$3",
+"$$$$$$$$$$$$$$$$$$$$3",
+"$12222222,2,2222222$3",
+"$1222222,->-O222222$3",
+"$122222,-O,.O222222$3",
+"$122222-O,--2222222$3",
+"$122222O<--#2222222$3",
+"$1222222>-@2<222222$3",
+"$1222222<:-<-+22222$3",
+"$1222222<:=-.+22222$3",
+"$12222222<+oO222222$3",
+"$122222222222222222$3",
+"$$$$$$$$$$$$$$$$$$$$3",
+" 33333333333333333333",
+" ",
+" "
+};
diff --git a/tools/glade/glade/graphics/gnome-dock-item.xpm b/tools/glade/glade/graphics/gnome-dock-item.xpm
new file mode 100644
index 00000000..4ac0d7f0
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-dock-item.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_dock_item_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #7B7B7B",
+"@ c #D6D6D6",
+"# c #000000",
+".....................",
+".+@+@@@@@@@@@@@@@@@@#",
+".@.+@@@@@@@@@@@@@@@@#",
+".+@+@@@@@@@@@@@@@@@@#",
+".####################",
+".....................",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".@@@@@@@@@@@@@@@@@@@+",
+".++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/gnome-dock.xpm b/tools/glade/glade/graphics/gnome-dock.xpm
new file mode 100644
index 00000000..4043033f
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-dock.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_dock_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #7B7B7B",
+"@ c #D6D6D6",
+"# c #000000",
+".....................",
+".+@+@@@@@@@@@@@@@@@@#",
+".@.+@@@@@@@@@@@@@@@@#",
+".+@+@@@@@@@@@@@@@@@@#",
+".####################",
+".....@@@@@@@@@@@....#",
+".+@+#@@@@@@@@@@@.+@+#",
+".@.@#@@@@@@@@@@@.@.@#",
+".+++#@@@@@@@@@@@.+++#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".@@@#@@@@@@@@@@@.@@@#",
+".####@@@@@@@@@@@.####",
+"....................#",
+".+@+@@@@@@@@@@@@@@@@#",
+".@.+@@@@@@@@@@@@@@@@#",
+".+@+@@@@@@@@@@@@@@@@#",
+"#####################"};
diff --git a/tools/glade/glade/graphics/gnome-druid-page-finish.xpm b/tools/glade/glade/graphics/gnome-druid-page-finish.xpm
new file mode 100644
index 00000000..32a74ada
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-druid-page-finish.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_druid_page_finish_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #7B7B7B",
+"+ c #00007B",
+"@ c #000000",
+"# c #FFFFFF",
+" ",
+" ",
+" ",
+".................... ",
+".++++++++++++++++++.@",
+".+###+##++++++++##+.@",
+".+++++++++++++++##+.@",
+".++++++++++++++++++.@",
+".++++##############.@",
+".++#+##############.@",
+".++++##############.@",
+".+#++##############.@",
+".++++##############.@",
+".++++##############.@",
+".++#+##############.@",
+".++++##############.@",
+".++++##############.@",
+"....................@",
+" @@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-druid-page-standard.xpm b/tools/glade/glade/graphics/gnome-druid-page-standard.xpm
new file mode 100644
index 00000000..a1a68263
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-druid-page-standard.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * gnome_druid_page_standard_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #7B7B7B",
+"+ c #07077B",
+"@ c #000000",
+"# c #FFFFFF",
+"$ c #00007B",
+"% c #D6D6D6",
+" ",
+" ",
+" ",
+".................... ",
+".++++++++++++++++++.@",
+".+###+##++++++++##+.@",
+".+++++++++++++++##+.@",
+".$$$$$$$$$$$$$$$+++.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+".+%%%%%%%%%%%%%%%%%.@",
+"....................@",
+" @@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-druid-page-start.xpm b/tools/glade/glade/graphics/gnome-druid-page-start.xpm
new file mode 100644
index 00000000..bb36de43
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-druid-page-start.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * gnome_druid_page_start_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #7B7B7B",
+"+ c #00007B",
+"@ c #000000",
+"# c #FFFFFF",
+" ",
+" ",
+" ",
+".................... ",
+".++++++++++++++++++.@",
+".+###+##++++++++##+.@",
+".+++++++++++++++##+.@",
+".++++++++++++++++++.@",
+".++++##############.@",
+".++#+##############.@",
+".++++##############.@",
+".+#++##############.@",
+".++++##############.@",
+".++++##############.@",
+".++#+##############.@",
+".++++##############.@",
+".++++##############.@",
+"....................@",
+" @@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-druid.xpm b/tools/glade/glade/graphics/gnome-druid.xpm
new file mode 100644
index 00000000..b15e45ad
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-druid.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * gnome_druid_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #7B7B7B",
+"+ c #07077B",
+"@ c #000000",
+"# c #FFFFFF",
+"$ c #00007B",
+"% c #D6D6D6",
+" ",
+" ",
+" ",
+".................... ",
+".++++++++++++++++++.@",
+".+###+##++++++++##+.@",
+".+++++++++++++++##+.@",
+".$$$$$$$$$$$$$$$+++.@",
+".@@@@##############.@",
+".@.%@##############.@",
+".@%.@###@##@##@####.@",
+".@.%@#####@#@##@###.@",
+".@%.@###@#####@@###.@",
+".@%%@##############.@",
+".@@@@##############.@",
+".%###...#...###...#.@",
+".%####%%%#%%%###%%%.@",
+"....................@",
+" @@@@@@@@@@@@@@@@@@@@",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-entry.xpm b/tools/glade/glade/graphics/gnome-entry.xpm
new file mode 100644
index 00000000..bead2458
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-entry.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * gnome_entry_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DEDEDE",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+".....................",
+".+++++++++++++.@@@@@.",
+".+++++++++++++..@@@..",
+".+++++++++++++...@...",
+".....................",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-fileentry.xpm b/tools/glade/glade/graphics/gnome-fileentry.xpm
new file mode 100644
index 00000000..21061cab
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-fileentry.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * gnome_fileentry_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DEDEDE",
+"# c #7B7B7B",
+"$ c #D6D6D6",
+"% c #FFFF00",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+"............... ++++.",
+".+++++++++.@@@. +##$.",
+".+++++++++..@.. +$$$.",
+"............... .....",
+" ",
+" .. ",
+" .%%... ",
+" .%%%%%. ",
+" .%%%%%. ",
+" .%%%%%. ",
+" ....... ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-fontpicker.xpm b/tools/glade/glade/graphics/gnome-fontpicker.xpm
new file mode 100644
index 00000000..4b1b45b5
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-fontpicker.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * gnome_fontpicker_xpm[] = {
+"21 21 7 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #FFFF9C",
+"% c #FF0000",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@$$$$$@@@@@#+ ",
+" .@@@@@@%%%%$@@@@@#+ ",
+" .@@@@@%$$%%$@@@@@#+ ",
+" .@@@@@@@%$%$%%%@@#+ ",
+" .@@@%$$%%%%%$$$%@#+ ",
+" .@@%$%%%$$%%$@@$@#+ ",
+" .@@@$%$$%@$%$@@@@#+ ",
+" .@@@$%$%@@$%$$$%@#+ ",
+" .@@@$%$$%@@$%%%$@#+ ",
+" .@@@$%%%$@@@$$$@@#+ ",
+" .@@@@$$$@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-href.xpm b/tools/glade/glade/graphics/gnome-href.xpm
new file mode 100644
index 00000000..ddb75f54
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-href.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * gnome_href_xpm[] = {
+"21 21 8 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #DEB6A4",
+"% c #ACC29C",
+"& c #626D52",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@++@@@@@#+ ",
+" .@@@@@@@@+$$+@@@@#+ ",
+" .@@@@@@@+$.$$+@@@#+ ",
+" .@@@@+++++$$$+@@@#+ ",
+" .@@@@@+..+$$+@@@@#+ ",
+" .@@@++.%&+++@@@@@#+ ",
+" .@++.%%&++@@@@@@@#+ ",
+" .@@+%%%+@+@@@@@@@#+ ",
+" .@@@+%&+@@@@@@@@@#+ ",
+" .@@@@++@@@@@@@@@@#+ ",
+" .@@@@@+@@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-iconentry.xpm b/tools/glade/glade/graphics/gnome-iconentry.xpm
new file mode 100644
index 00000000..cd2ca01b
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-iconentry.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char * gnome_iconentry_xpm[] = {
+"21 21 11 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #00FFFF",
+"% c #DEDEDE",
+"& c #FFFF00",
+"* c #1CA81C",
+"= c #00FF00",
+"- c #0000FF",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@++++++++++++@@#+ ",
+" .@@+$$$%$$.$$$+@@#+ ",
+" .@@+$.$$%$$$&$+@@#+ ",
+" .@@+$$$$##$$$$+@@#+ ",
+" .@@+$$$++++$$$+@@#+ ",
+" .@@+***+@@+***+@@#+ ",
+" .@@+===+@-+===+@@#+ ",
+" .@@++++++++++++@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .@@@@@@@@@@@@@@@@#+ ",
+" .#################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-iconlist.xpm b/tools/glade/glade/graphics/gnome-iconlist.xpm
new file mode 100644
index 00000000..f3ba1fb4
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-iconlist.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char * gnome_iconlist_xpm[] = {
+"21 21 9 1",
+" c None",
+". c #7B797B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #00007B",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FF0000",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++$%$+++++&%&+++#+",
+".@+++%$%+++++%&%+++#+",
+".@+++$%$+++++&%&+++#+",
+".@+++++++++++++++++#+",
+".@++@+@@+@++@@@+@++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++&*&+++++&*&+++#+",
+".@+++*&*+++++***+++#+",
+".@+++&*&+++++&*&+++#+",
+".@+++++++++++++++++#+",
+".@++@+@+@+++@+@@+++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/gnome-iconselection.xpm b/tools/glade/glade/graphics/gnome-iconselection.xpm
new file mode 100644
index 00000000..3bbbc91f
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-iconselection.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * gnome_iconselection_xpm[] = {
+"21 21 8 1",
+" c None",
+". c #7B797B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #FFFF00",
+"% c #00FF00",
+"& c #FF0000",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@++++++@@+++++++++#+",
+".@+++++@$$@@@++++++#+",
+".@+++++@$$$$$@+++++#+",
+".@+++++@$$$$$@+++++#+",
+".@+++++@$$$$$@+++++#+",
+".@+++++@@@@@@@+++++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++%&%+++++%&%+++#+",
+".@+++&%&+++++&&&+++#+",
+".@+++%&%+++++%&%+++#+",
+".@+++++++++++++++++#+",
+".@++@+@+@+++@+@@+++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/gnome-less.xpm b/tools/glade/glade/graphics/gnome-less.xpm
new file mode 100644
index 00000000..2f815e32
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-less.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * gnome_less_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #D5D6D5",
+"+ c #7B797B",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #FFFFFF",
+".....................",
+"+++++++++++++++++++++",
+"+@@@@@@@@@@@@@@@#+$$+",
+"+@$$$$$$$$$$$$$$#+@$+",
+"+@$$$$$$$$$$$$$$#++$+",
+"+@$$@$@$@$$@$$@$#+.$+",
+"+@$@$@$$$@$@@$$$#+.$+",
+"+@$$@$@$$$$$$$$$#+.$+",
+"+@$$@$$@@$$$$$$$#+.$+",
+"+@$$$$$$$$$$$$$$#+$$+",
+"+@$@@$$@$@@$@$@$#+$$+",
+"+@$$@$@@$$@$$$$$#+.$+",
+"+@$$$$$$$$$$$$$$#+.$+",
+"+@$@$@@@$@$@$$$$#+.$+",
+"+@$$$$$$$$$$$$$$#+.$+",
+"+@$@@$@@$@$$$$$$#+.$+",
+"+@$@$$@$$@$@$$$$#+.$+",
+"+@$$@$$$$$$$$$$$#++$+",
+"+@$@$@@$@$$$$$$$#+$$+",
+"+################+@$+",
+"$$$$$$$$$$$$$$$$$++++"};
diff --git a/tools/glade/glade/graphics/gnome-messagebox.xpm b/tools/glade/glade/graphics/gnome-messagebox.xpm
new file mode 100644
index 00000000..62d1b0ab
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-messagebox.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * gnome_messagebox_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #CC5972",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ................ ",
+" .+@#++++++++++++$ ",
+" .+%&+***++++=+=+$ ",
+" ................$ ",
+" .**************.$ ",
+" .**...*********.$ ",
+" .*.*##.*..*..**.$ ",
+" .*.###.********.$ ",
+" .*=.#.*********.$ ",
+" .*...****...***.$ ",
+" .*$$*****.$$***.$ ",
+" .**************.$ ",
+" ................$ ",
+" $$$$$$$$$$$$$$$$ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-numberentry.xpm b/tools/glade/glade/graphics/gnome-numberentry.xpm
new file mode 100644
index 00000000..d1fe2d13
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-numberentry.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * gnome_numberentry_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DEDEDE",
+"# c #7B7B7B",
+"$ c #D6D6D6",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+"............... ++++.",
+".+++++++++.@@@. +##$.",
+".+++++++++..@.. +$$$.",
+"............... .....",
+" ",
+" ",
+" . ..@ ..@ ",
+" .. @. @. ",
+" . @.@ ..@ ",
+" . .@ @. ",
+" ... ... ..@ ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-papersel.xpm b/tools/glade/glade/graphics/gnome-papersel.xpm
new file mode 100644
index 00000000..a5605042
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-papersel.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * gnome_papersel_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #000000",
+"+ c #D6D6D6",
+"@ c #FFFFFF",
+"............... +.+ ",
+".@@@@@@@@@@@@@. ... ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@..@@@@.@@@. . ",
+".@@.@@.@@..@@@. . ",
+".@@.@@.@.@.@@@. . ",
+".@@....@....@@. . ",
+".@@.@@.@@@.@@@. . ",
+".@@.@@.@@@.@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. ... ",
+"............... +.+ ",
+" ",
+"+. .+ ",
+".............. ",
+"+. .+ "};
diff --git a/tools/glade/glade/graphics/gnome-pixmap.xpm b/tools/glade/glade/graphics/gnome-pixmap.xpm
new file mode 100644
index 00000000..991a12eb
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-pixmap.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *gnome_pixmap_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 12 1",
+" c Gray0",
+". c #007b00",
+"X c #7b7b7b",
+"o c Blue",
+"O c Green",
+"+ c Cyan",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray87",
+"& c Gray100",
+"* c None",
+/* pixels */
+"*********************",
+"*********************",
+"*********************",
+"* ",
+"* +++++%%%&+++++++++ ",
+"* +&&&++%%++&+++XX++ ",
+"* +++++++%+++++X@@X+ ",
+"* ++&&++++XX+++X@@X+ ",
+"* +++++++ XXX&++XX++ ",
+"* &+++++XXXXXX++++&+ ",
+"* +++++ +++++ ",
+"* +++++ ###### +++++ ",
+"* +++++ #o##o# +++++ ",
+"* ..... ###### ..... ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO OOOOO ",
+"* OOOOOOOOOOOOOOOOOO ",
+"* ",
+"*********************",
+"*********************"
+};
diff --git a/tools/glade/glade/graphics/gnome-pixmapentry.xpm b/tools/glade/glade/graphics/gnome-pixmapentry.xpm
new file mode 100644
index 00000000..751996c8
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-pixmapentry.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char * gnome_pixmapentry_xpm[] = {
+"21 21 9 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DEDEDE",
+"# c #7B7B7B",
+"$ c #D6D6D6",
+"% c #00FFFF",
+"& c #FFFF00",
+"* c #00FF00",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+"............... ++++.",
+".+++++++++.@@@. +##$.",
+".+++++++++..@.. +$$$.",
+"............... .....",
+" ",
+" ....... ",
+" .%%%%&. ",
+" .%%.%%. ",
+" .**.**. ",
+" .*****. ",
+" ....... ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-print-papersel.xpm b/tools/glade/glade/graphics/gnome-print-papersel.xpm
new file mode 100644
index 00000000..c8284eb4
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-print-papersel.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * gnome_print_papersel_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #000000",
+"+ c #D6D6D6",
+"@ c #FFFFFF",
+"............... +.+ ",
+".@@@@@@@@@@@@@. ... ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@..@@@@.@@@. . ",
+".@@.@@.@@..@@@. . ",
+".@@.@@.@.@.@@@. . ",
+".@@....@....@@. . ",
+".@@.@@.@@@.@@@. . ",
+".@@.@@.@@@.@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. . ",
+".@@@@@@@@@@@@@. ... ",
+"............... +.+ ",
+" ",
+"+. .+ ",
+".............. ",
+"+. .+ "};
diff --git a/tools/glade/glade/graphics/gnome-propertybox.xpm b/tools/glade/glade/graphics/gnome-propertybox.xpm
new file mode 100644
index 00000000..3a4867c2
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-propertybox.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * gnome_propertybox_xpm[] = {
+"21 21 10 1",
+" c None",
+". c #7B7B7B",
+"+ c #CC5972",
+"@ c #FF0000",
+"# c #FFFF00",
+"$ c #000000",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FFFFFF",
+"= c #D6D6D6",
+" ",
+" ",
+" ",
+".................... ",
+".+@#+++++++++++++++.$",
+".+%&+***+**+++++=+=.$",
+"....................$",
+".******************.$",
+".*.........********.$",
+".*.==.==.==......**.$",
+".*.==============$*.$",
+".*.==============$*.$",
+".*.==============$*.$",
+".*.==============$*.$",
+".*$$$$$$$$$$$$$$$$*.$",
+".*******====*====**.$",
+".*******=...*=...**.$",
+"....................$",
+" $$$$$$$$$$$$$$$$$$$$",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-spell.xpm b/tools/glade/glade/graphics/gnome-spell.xpm
new file mode 100644
index 00000000..60dab70a
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-spell.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char * gnome_spell_xpm[] = {
+"21 21 9 1",
+" c None",
+". c #000000",
+"+ c #4A6541",
+"@ c #415939",
+"# c #4A6941",
+"$ c #5A8152",
+"% c #628D5A",
+"& c #52754A",
+"* c #4A6D41",
+" ",
+" ",
+" ",
+" .. ... .. ",
+" . . . . . . ",
+" .... ... . ",
+" . . . . . . ",
+" . . ... .. .. ",
+" .. ",
+" .. .. ",
+" .+. .@. ",
+" .#. .#. ",
+" .+$.$@. ",
+" .#%&. ",
+" .+%@. ",
+" .#. ",
+" .*. ",
+" . ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gnome-stock.xpm b/tools/glade/glade/graphics/gnome-stock.xpm
new file mode 100644
index 00000000..dfebfb8f
--- /dev/null
+++ b/tools/glade/glade/graphics/gnome-stock.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *gnome_stock_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 12 1",
+" c Gray0",
+". c #007b00",
+"X c #7b7b7b",
+"o c Blue",
+"O c Green",
+"+ c Cyan",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray87",
+"& c Gray100",
+"* c None",
+/* pixels */
+"*********************",
+"*********************",
+"*********************",
+"* ",
+"* +++++%%%&+++++++++ ",
+"* +&&&++%%++&+++XX++ ",
+"* +++++++%+++++X@@X+ ",
+"* ++&&++++XX+++X@@X+ ",
+"* +++++++ XXX&++XX++ ",
+"* &+++++XXXXXX++++&+ ",
+"* +++++ +++++ ",
+"* +++++ ###### +++++ ",
+"* +++++ #o##o# +++++ ",
+"* ..... ###### ..... ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO OOOOO ",
+"* OOOOOOOOOOOOOOOOOO ",
+"* ",
+"*********************",
+"*********************"
+};
diff --git a/tools/glade/glade/graphics/gtk-clock.xpm b/tools/glade/glade/graphics/gtk-clock.xpm
new file mode 100644
index 00000000..86605ceb
--- /dev/null
+++ b/tools/glade/glade/graphics/gtk-clock.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char * gtk_clock_xpm[] = {
+"21 21 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" . .. . .. ",
+" .. . . .. . . ",
+" . . . . . . ",
+" . . . ... ",
+" . . . . . ",
+" . . . . . ",
+" ... .... ... .. ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/gtk-dial.xpm b/tools/glade/glade/graphics/gtk-dial.xpm
new file mode 100644
index 00000000..a26bfb5e
--- /dev/null
+++ b/tools/glade/glade/graphics/gtk-dial.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * gtk_dial_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #000000",
+"+ c #D6D6D6",
+"@ c #9C9C9C",
+" ",
+" . ",
+" . . . ",
+" ",
+" . +. ",
+" . +.+ ",
+" ++.+ ",
+" . +@.+ . ",
+" +@.@+ ",
+" +@.@+ ",
+" +..@+ ",
+".. ...+ ..",
+" +.+ ",
+" ",
+" . . ",
+" ",
+" . . ",
+" . . ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/handlebox.xpm b/tools/glade/glade/graphics/handlebox.xpm
new file mode 100644
index 00000000..e4d792cb
--- /dev/null
+++ b/tools/glade/glade/graphics/handlebox.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *handlebox_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@++++++++++++++++++ @",
+"@+OOOO.XXXXXXXXXXX. @",
+"@++OOO.XXXXXXXXXXX. @",
+"@+O.+O.XXXXXXXXXXX. @",
+"@+OOO..XXXXXXXXXXX. @",
+"@++OOO.XXXXXXXXXXX. @",
+"@+O.+O.XXXXXXXXXXX. @",
+"@+OOO..XXXXXXXXXXX. @",
+"@++OOO.XXXXXXXXXXX. @",
+"@+O.+O.XXXXXXXXXXX. @",
+"@+OOO..XXXXXXXXXXX. @",
+"@+................. @",
+"@ @",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/hbox.xpm b/tools/glade/glade/graphics/hbox.xpm
new file mode 100644
index 00000000..47287513
--- /dev/null
+++ b/tools/glade/glade/graphics/hbox.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * hbox_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"......+......+......+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".@@@@#+.@@@@#+.@@@@#+",
+".#####+.#####+.#####+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/hbuttonbox.xpm b/tools/glade/glade/graphics/hbuttonbox.xpm
new file mode 100644
index 00000000..77d73dc4
--- /dev/null
+++ b/tools/glade/glade/graphics/hbuttonbox.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *hbuttonbox_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+OOOOO +OOOOO +OOOOO ",
+"+OXXX. +OXXX. +OXXX. ",
+"+OXXX. +OXXX. +OXXX. ",
+"+O.... +O.... +O.... ",
+"+ + + ",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/hpaned.xpm b/tools/glade/glade/graphics/hpaned.xpm
new file mode 100644
index 00000000..c6bce497
--- /dev/null
+++ b/tools/glade/glade/graphics/hpaned.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * hpaned_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"..........+.........+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@#####@@@@@@@#+",
+".@@@@@@#...##@@@@@@#+",
+".@@@@@@#...##@@@@@@#+",
+".@@@@@@#...##@@@@@@#+",
+".@@@@@@######@@@@@@#+",
+".@@@@@@@#####@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".#########+.########+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/hruler.xpm b/tools/glade/glade/graphics/hruler.xpm
new file mode 100644
index 00000000..1a3297b0
--- /dev/null
+++ b/tools/glade/glade/graphics/hruler.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char *hruler_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 3 1",
+" c Gray0",
+". c #b3cece",
+"X c None",
+/* pixels */
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+" XXXXXXXXXXXXXXX ",
+" X XXXXXXXXXXXXXXX XX",
+" X XXXXXXXXXXXXXXX ",
+" X XXXXXXXXXXXXXXXXX ",
+" XXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXXXXXXX",
+"X XXXXXXXXXXXXXXXXX X",
+"X XXXXXXXXXXXXXXXXX X",
+"X XXXXX XXXXX XXXXX X",
+"X XXXXX XXXXX XXXXX X",
+"X XX XX XX XX XX XX X",
+"X XX XX XX XX XX XX X",
+"X XX XX XX XX XX XX X",
+"X X",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX"
+};
diff --git a/tools/glade/glade/graphics/hscale.xpm b/tools/glade/glade/graphics/hscale.xpm
new file mode 100644
index 00000000..bfdaee15
--- /dev/null
+++ b/tools/glade/glade/graphics/hscale.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *hscale_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@ @@@@@ @@@@@@@@@",
+"@@ @@ @@@ @@ @@@@@@@@",
+"@@ @@ @@@ @@ @@@@@@@@",
+"@@ @@ @@@ @@ @@@@@@@@",
+"@@ @@ @@@ @@ @@@@@@@@",
+"@@@ @@ @@ @@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+".....................",
+". +",
+". ++++++++ XXXXXXXXO+",
+". +XXX.XX. XXXXXXXXO+",
+". +XXX.XX. XXXXXXXXO+",
+". +....... XXXXXXXXO+",
+". XXXXXXXXO+",
+". OOOOOOOOOOOOOOOOOO+",
+".++++++++++++++++++++",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/hscrollbar.xpm b/tools/glade/glade/graphics/hscrollbar.xpm
new file mode 100644
index 00000000..7f7ac92f
--- /dev/null
+++ b/tools/glade/glade/graphics/hscrollbar.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *hscrollbar_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c Gray61",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+" ",
+" ...O .OOOOOO .OO...O",
+" ..OX .OXXXXX .OXO..O",
+" .OXX .OXXXXX .OXXO.O",
+" OXXX .OXXXXX .OXXX O",
+" . XX .OXXXXX .OXX .O",
+" .. X .OXXXXX .OX ..O",
+" ... . .O ...O",
+"OOOOOOOOOOOOOOOOOOOOO",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/hseparator.xpm b/tools/glade/glade/graphics/hseparator.xpm
new file mode 100644
index 00000000..41ad8aaf
--- /dev/null
+++ b/tools/glade/glade/graphics/hseparator.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char *hseparator_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 4 1",
+" c #7b7b7b",
+". c #b3cece",
+"X c Gray100",
+"o c None",
+/* pixels */
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"o o",
+"oXXXXXXXXXXXXXXXXXXXo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo",
+"ooooooooooooooooooooo"
+};
diff --git a/tools/glade/glade/graphics/iconview.xpm b/tools/glade/glade/graphics/iconview.xpm
new file mode 100644
index 00000000..b78b6711
--- /dev/null
+++ b/tools/glade/glade/graphics/iconview.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char * iconview_xpm[] = {
+"21 21 9 1",
+" c None",
+". c #7B797B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #00007B",
+"% c #00FFFF",
+"& c #00FF00",
+"* c #FF0000",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++$%$+++++&%&+++#+",
+".@+++%$%+++++%&%+++#+",
+".@+++$%$+++++&%&+++#+",
+".@+++++++++++++++++#+",
+".@++@+@@+@++@@@+@++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".@+++&*&+++++&*&+++#+",
+".@+++*&*+++++***+++#+",
+".@+++&*&+++++&*&+++#+",
+".@+++++++++++++++++#+",
+".@++@+@+@+++@+@@+++#+",
+".@+++++++++++++++++#+",
+".@+++++++++++++++++#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/image.xpm b/tools/glade/glade/graphics/image.xpm
new file mode 100644
index 00000000..9f353cc4
--- /dev/null
+++ b/tools/glade/glade/graphics/image.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *image_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 12 1",
+" c Gray0",
+". c #007b00",
+"X c #7b7b7b",
+"o c Blue",
+"O c Green",
+"+ c Cyan",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray87",
+"& c Gray100",
+"* c None",
+/* pixels */
+"*********************",
+"*********************",
+"*********************",
+"* ",
+"* +++++%%%&+++++++++ ",
+"* +&&&++%%++&+++XX++ ",
+"* +++++++%+++++X@@X+ ",
+"* ++&&++++XX+++X@@X+ ",
+"* +++++++ XXX&++XX++ ",
+"* &+++++XXXXXX++++&+ ",
+"* +++++ +++++ ",
+"* +++++ ###### +++++ ",
+"* +++++ #o##o# +++++ ",
+"* ..... ###### ..... ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO OOOOO ",
+"* OOOOOOOOOOOOOOOOOO ",
+"* ",
+"*********************",
+"*********************"
+};
diff --git a/tools/glade/glade/graphics/inputdialog.xpm b/tools/glade/glade/graphics/inputdialog.xpm
new file mode 100644
index 00000000..80bf2a9f
--- /dev/null
+++ b/tools/glade/glade/graphics/inputdialog.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *inputdialog_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 12 1",
+" c Gray0",
+". c #00007b",
+"X c #7b7b7b",
+"o c Green",
+"O c Cyan",
+"+ c Red",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray87",
+"& c Gray100",
+"* c None",
+/* pixels */
+"*********************",
+"*********************",
+"*********************",
+"*********************",
+"**XXXXXXXXXXXXXXXX***",
+"**X.+@............ **",
+"**X.Oo.&&&....# # **",
+"**XXXXXXXXXXXXXXXX **",
+"**X&&&&&&&&&&&&&&X **",
+"**X&&&&& &&&&&&&X **",
+"**X&&&&& &&&&&X **",
+"**X&&&&& &&&&&&X **",
+"**X&&&&& & %&&&&&X **",
+"**X&&&&&&&% &&&&&X **",
+"**X&&&&&&&&% &&&&X **",
+"**X&&&&&&&&&&&&&&X **",
+"**XXXXXXXXXXXXXXXX **",
+"*** **",
+"*********************",
+"*********************",
+"*********************"
+};
diff --git a/tools/glade/glade/graphics/label.xpm b/tools/glade/glade/graphics/label.xpm
new file mode 100644
index 00000000..013e13a9
--- /dev/null
+++ b/tools/glade/glade/graphics/label.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char *label_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 3 1",
+" c Gray0",
+". c #b3cece",
+"X c None",
+/* pixels */
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXX XXXXXXXXX",
+"XXXXXXXXX XXXXXXXXX",
+"XXXXXXXXX XXXXXXXXX",
+"XXXXXXXX XXXXXXXX",
+"XXXXXXXX XXXXXXXX",
+"XXXXXXXX XXXXXXX",
+"XXXXXXX X XXXXXXX",
+"XXXXXXX X XXXXXX",
+"XXXXXX XX XXXXXX",
+"XXXXXX XXXXX",
+"XXXXX XXXXX",
+"XXXXX XXXXX XXXXX",
+"XXXX XXXXX XXXX",
+"XXX XXXXX XXX",
+"XXX XXX XXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX"
+};
diff --git a/tools/glade/glade/graphics/layout.xpm b/tools/glade/glade/graphics/layout.xpm
new file mode 100644
index 00000000..f446511d
--- /dev/null
+++ b/tools/glade/glade/graphics/layout.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * layout_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #D6D6D6",
+"@ c #000000",
+"# c #7B7B7B",
+".....................",
+".+++++++++++++.+++++@",
+".+.....+++++++.++@++@",
+".+.+++#+++++++.+@@@+@",
+".+.+++#+.....+.+++++@",
+".+.####+.+++#+.@@@@@@",
+".+++++++.+++#+......@",
+".+++++++.####+..++++@",
+".+++++++++++++..++++@",
+".+++.....+++++......@",
+".+++.+++#+++++.+++++@",
+".+++.+++#+++++.+@@@+@",
+".+++.####+++++.++@++@",
+".+++++++++++++.+++++@",
+"...............@@@@@@",
+".++++@...@++++@++++++",
+".++@+@.++@+@++@++++++",
+".+@@+@.++@+@@+@++++++",
+".++@+@.++@+@++@++++++",
+".++++@.++@++++@++++++",
+".@@@@@@@@@@@@@@++++++"};
diff --git a/tools/glade/glade/graphics/list.xpm b/tools/glade/glade/graphics/list.xpm
new file mode 100644
index 00000000..9cb085d6
--- /dev/null
+++ b/tools/glade/glade/graphics/list.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char *list_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 4 1",
+" c Gray0",
+". c #b3cece",
+"X c Gray100",
+"o c None",
+/* pixels */
+"ooooooooooooooooooooo",
+"oooo oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo X XXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo X XX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo X XX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo X XX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo X XXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo XXXXXXXXXXX oooo",
+"oooo oooo",
+"ooooooooooooooooooooo"
+};
diff --git a/tools/glade/glade/graphics/listitem.xpm b/tools/glade/glade/graphics/listitem.xpm
new file mode 100644
index 00000000..999929eb
--- /dev/null
+++ b/tools/glade/glade/graphics/listitem.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *listitem_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c Red",
+"X c #b3cece",
+"o c Gray87",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"++++ ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OoooooooOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ O........OO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OooooooooOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OooooooooOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OoooooooOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ OOOOOOOOOOO ++++",
+"++++ ++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/menubar.xpm b/tools/glade/glade/graphics/menubar.xpm
new file mode 100644
index 00000000..dd351ab8
--- /dev/null
+++ b/tools/glade/glade/graphics/menubar.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * menubar_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #DEDEDE",
+" ",
+" ",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@$$$$+$$$$+$$$$+@#+",
+" .@$@@@+$@@@+$@@@+@#+",
+" .@$@@@+$@@@+$@@@+@#+",
+" .@.......#++$++++@#+",
+" .@.$$$$$$#@@@@@@@@#+",
+" .#.$####$##########+",
+" ++.$$$$$$#++++++++++",
+" .$####$#+ ",
+" .$$$$$$#+ ",
+" .$####$#+ ",
+" .$$$$$$#+ ",
+" .$####$#+ ",
+" .$$$$$$#+ ",
+" .#######+ ",
+" ++++++++ ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/menuitem.xpm b/tools/glade/glade/graphics/menuitem.xpm
new file mode 100644
index 00000000..a1da3fa3
--- /dev/null
+++ b/tools/glade/glade/graphics/menuitem.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char * menuitem_xpm[] = {
+"21 21 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" . ",
+" .. ",
+" .... ",
+" ..... ",
+" .... ",
+" ... ",
+" . . ",
+" . ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/menutoolbutton.xpm b/tools/glade/glade/graphics/menutoolbutton.xpm
new file mode 100644
index 00000000..c1b7902a
--- /dev/null
+++ b/tools/glade/glade/graphics/menutoolbutton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * menutoolbutton_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@....+....+....+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.++++.++++.++++@#+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .##################+",
+" ++++++++++++++++++++",
+" ",
+" ",
+" ...............+ ",
+" .@@@@@@@@@.@@@#+ ",
+" .@@+@@+@+@.@@@#+ ",
+" .@+@+@++@@.+#+#+ ",
+" .@+@+@++@@.@+@#+ ",
+" .@@+@@+@+@.@@@#+ ",
+" .@@@@@@@@@.@@@#+ ",
+" .##############+ ",
+" ++++++++++++++++ ",
+" "};
diff --git a/tools/glade/glade/graphics/new.xpm b/tools/glade/glade/graphics/new.xpm
new file mode 100644
index 00000000..e6318907
--- /dev/null
+++ b/tools/glade/glade/graphics/new.xpm
@@ -0,0 +1,116 @@
+/* XPM */
+static char * new_xpm[] = {
+"24 24 89 1",
+" c None",
+". c #000000",
+"+ c #ADAD9C",
+"@ c #959585",
+"# c #DCDCC5",
+"$ c #DFDFC8",
+"% c #242424",
+"& c #A7A796",
+"* c #D7D7C1",
+"= c #D9D9C3",
+"- c #DCDCC4",
+"; c #DDDDC7",
+"> c #E1E1CA",
+", c #A6A694",
+"' c #D6D6BF",
+") c #D8D8C2",
+"! c #DBDBC4",
+"~ c #DFDFC7",
+"{ c #E3E3CB",
+"] c #B2B29F",
+"^ c #7C7C7C",
+"/ c #646464",
+"( c #D5D5BD",
+"_ c #D5D5BF",
+": c #D7D7C0",
+"< c #DADAC3",
+"[ c #DEDEC6",
+"} c #E1E1C9",
+"| c #E5E5CD",
+"1 c #E9E9D1",
+"2 c #343434",
+"3 c #E7E7E7",
+"4 c #373736",
+"5 c #B8B8A6",
+"6 c #D3D3BC",
+"7 c #D9D9C2",
+"8 c #DDDDC5",
+"9 c #E0E0C8",
+"0 c #E8E8D0",
+"a c #ECECD4",
+"b c #EEEED5",
+"c c #ECECEC",
+"d c #EDEDED",
+"e c #3D3D37",
+"f c #CECEB7",
+"g c #E6E6CE",
+"h c #EAEAD2",
+"i c #F1F1D8",
+"j c #A5A594",
+"k c #EEEEE5",
+"l c #3C3C3C",
+"m c #8F8F80",
+"n c #D0D0B9",
+"o c #E4E4CB",
+"p c #EAEAD1",
+"q c #ECECD3",
+"r c #EFEFD6",
+"s c #F2F2D9",
+"t c #F3F3DA",
+"u c #EEEEE6",
+"v c #505050",
+"w c #929282",
+"x c #D1D1B9",
+"y c #E7E7CF",
+"z c #EBEBD2",
+"A c #F4F4DB",
+"B c #F5F5DC",
+"C c #969686",
+"D c #D2D2BC",
+"E c #E0E0C9",
+"F c #E9E9D0",
+"G c #EDEDD4",
+"H c #F0F0D7",
+"I c #BEBEAB",
+"J c #797973",
+"K c #D8D8C1",
+"L c #DDDDC6",
+"M c #98988F",
+"N c #E4E4CC",
+"O c #818174",
+"P c #E2E2CA",
+"Q c #BEBEAE",
+"R c #4E4E4E",
+"S c #828274",
+"T c #EBEBD3",
+"U c #BBBBA8",
+"V c #CDCDB8",
+"W c #4D4D45",
+"X c #A6A696",
+" ",
+" ",
+" . ",
+" ..+. ",
+" ..@#$% ",
+" ..&*=-;>. ",
+" ..,'**)!~{]. ",
+" .^/'(_:<[}|12 ",
+" .3456*789|0ab. ",
+" .cdef_!9g0hbij. ",
+" .kklmn9opqrist. ",
+" .uvwx-}yzbittAB. ",
+" ..CD!E{FGHtAABBI. ",
+" .JK7L>ypbitBBBBB). ",
+" .M!#$NyzbitBBBBBO. ",
+" .~9P|1qrsABBBB.. ",
+" .Q||0hGHtABB<. ",
+" R01hGrstAsS. ",
+" .TaGriss<. ",
+" .rHis1j. ",
+" .UstVW. ",
+" .tX. ",
+" .. ",
+" "};
diff --git a/tools/glade/glade/graphics/notebook.xpm b/tools/glade/glade/graphics/notebook.xpm
new file mode 100644
index 00000000..77ac20d6
--- /dev/null
+++ b/tools/glade/glade/graphics/notebook.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *notebook_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+OOOOOO.OOOO.OOOO.+++",
+"+OXXXXX.X.X..X.X..+++",
+"+OXXXXX..X.X..X.X.+++",
+"+OXXXXX.X.X..X.X..+++",
+"+OXXXXX.OOOOOOOOOOO +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+OXXXXXXXXXXXXXXXX. +",
+"+O................. +",
+"+ +",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/open.xpm b/tools/glade/glade/graphics/open.xpm
new file mode 100644
index 00000000..ae2fc3ba
--- /dev/null
+++ b/tools/glade/glade/graphics/open.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * open_xpm[] = {
+"24 24 5 1",
+" c None",
+". c #000000",
+"+ c #99907B",
+"@ c #FFFEF7",
+"# c #FFFFFF",
+" ",
+" ",
+" ",
+" ",
+" ",
+" .. ",
+" ...++. ",
+" .. ...++++@@#... ",
+" .++..++++@@@@..++. ",
+" .+++++@@@@@..++++. ",
+" .++@@@@@..++++++. ",
+" .++@@@..++++++++. ",
+" .+@@.++++++++++. ",
+" .++@.++++++++++. ",
+" .+@.++++++++++. ",
+" .++.++++++++.. ",
+" .+.++++++.. ",
+" .+.+++++. ",
+" ..+++.. ",
+" ..+.. ",
+" .. ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/optionmenu.xpm b/tools/glade/glade/graphics/optionmenu.xpm
new file mode 100644
index 00000000..9d3c56fb
--- /dev/null
+++ b/tools/glade/glade/graphics/optionmenu.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *optionmenu_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"OOOOOOOOOOOOOOOOOOOO ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXOOOOXX. ",
+"OXXXXXXXXXXXXOXX XX. ",
+"OXXXXXXXXXXXXO XX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"OXXXXXXXXXXXXXXXXXX. ",
+"O................... ",
+" ",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/options.xpm b/tools/glade/glade/graphics/options.xpm
new file mode 100644
index 00000000..d1f5b62d
--- /dev/null
+++ b/tools/glade/glade/graphics/options.xpm
@@ -0,0 +1,140 @@
+/* XPM */
+static char * options_xpm[] = {
+"24 24 113 2",
+" c None",
+". c #000000",
+"+ c #ADAD9C",
+"@ c #959585",
+"# c #DCDCC5",
+"$ c #DFDFC8",
+"% c #242424",
+"& c #A7A796",
+"* c #D7D7C1",
+"= c #D9D9C3",
+"- c #DCDCC4",
+"; c #DDDDC7",
+"> c #E1E1CA",
+", c #D8BE6A",
+"' c #A6A694",
+") c #D6D6BF",
+"! c #D8D8C2",
+"~ c #DBDBC4",
+"{ c #A2A291",
+"] c #E3E3CB",
+"^ c #B2B29F",
+"/ c #8E7D45",
+"( c #7C7C7C",
+"_ c #646464",
+": c #D5D5BD",
+"< c #D5D5BF",
+"[ c #D7D7C0",
+"} c #9E9E8D",
+"| c #ABAB98",
+"1 c #E1E1C9",
+"2 c #E5E5CD",
+"3 c #E9E9D1",
+"4 c #343434",
+"5 c #E7E7E7",
+"6 c #373736",
+"7 c #B8B8A6",
+"8 c #D3D3BC",
+"9 c #909081",
+"0 c #9F9F8E",
+"a c #DDDDC5",
+"b c #E0E0C8",
+"c c #A2A292",
+"d c #ECECD4",
+"e c #EEEED5",
+"f c #ECECEC",
+"g c #EDEDED",
+"h c #3D3D37",
+"i c #8A8A7A",
+"j c #E6E6CE",
+"k c #9A9A8A",
+"l c #EAEAD2",
+"m c #EEEEE5",
+"n c #3C3C3C",
+"o c #8F8F80",
+"p c #D0D0B9",
+"q c #999988",
+"r c #ECECD3",
+"s c #EFEFD6",
+"t c #EEEEE6",
+"u c #505050",
+"v c #929282",
+"w c #D1D1B9",
+"x c #969686",
+"y c #E7E7CF",
+"z c #EBEBD2",
+"A c #F5F5DC",
+"B c #D2D2BC",
+"C c #E9E9D0",
+"D c #EDEDD4",
+"E c #E3E3DC",
+"F c #797973",
+"G c #D8D8C1",
+"H c #919182",
+"I c #949484",
+"J c #EAEAD1",
+"K c #D9D9CC",
+"L c #BFBFB0",
+"M c #ACACA5",
+"N c #9F9F93",
+"O c #98988F",
+"P c #E4E4CC",
+"Q c #AD8E30",
+"R c #756020",
+"S c #C4C4B0",
+"T c #9D9D8D",
+"U c #818174",
+"V c #DFDFC7",
+"W c #E2E2CA",
+"X c #060605",
+"Y c #9B9B8B",
+"Z c #9C9C8C",
+"` c #BEBEAE",
+" . c #8B8B7D",
+".. c #7E7E71",
+"+. c #C0C0AC",
+"@. c #C2C2AE",
+"#. c #C3C3AF",
+"$. c #DADAC3",
+"%. c #4E4E4E",
+"&. c #E8E8D0",
+"*. c #A0A090",
+"=. c #F2F2D9",
+"-. c #F3F3DA",
+";. c #F4F4DB",
+">. c #828274",
+",. c #EBEBD3",
+"'. c #F1F1D8",
+"). c #F0F0D7",
+"!. c #A5A594",
+"~. c #BBBBA8",
+"{. c #CDCDB8",
+"]. c #4D4D45",
+"^. c #A6A696",
+" ",
+" ",
+" . ",
+" . . + . ",
+" . . @ # $ % . ",
+" . . & * = - ; > . . , . ",
+" . . ' ) * * ! ~ { ] ^ . . , / . ",
+" . ( _ ) : < [ } | 1 2 3 4 . , / . ",
+" . 5 6 7 8 9 0 a b 2 c d e . , / . ",
+" . f g h i < ~ b j k l e . , / . ",
+" . m m n o p b q q r s . , / . ",
+" . t u v w - x y z e . , / . A . ",
+" . . x B ~ x ] C D . , / . A A E . ",
+" . F G H I > y J . , / . A K L M N . ",
+" . O ~ # $ P y Q R . . S T T T T U . ",
+" . V b W 2 3 X . Y Z T T T T . . ",
+" . ` 2 2 T ...+.@.#.S A $.. ",
+" %.&.*.l D s =.-.;.=.>.. ",
+" . ,.d D s '.=.=.$.. ",
+" . s ).'.=.3 !.. ",
+" . ~.=.-.{.].. ",
+" . -.^.. ",
+" . . ",
+" "};
diff --git a/tools/glade/glade/graphics/packer.xpm b/tools/glade/glade/graphics/packer.xpm
new file mode 100644
index 00000000..1c5a267a
--- /dev/null
+++ b/tools/glade/glade/graphics/packer.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *packer_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+OOOOO ++++++++OOOOO ",
+"+OXXX. ++++++++OXXX. ",
+"+OXXX. ++++++++OXXX. ",
+"+O.... ++++++++O.... ",
+"+ ++++++++ ",
+"+++++++++++++++++++++",
+"++++++++OOOOO +++++++",
+"++++++++OXXX. +++++++",
+"++++++++OXXX. +++++++",
+"++++++++O.... +++++++",
+"++++++++ +++++++",
+"+++++++++++++++++++++",
+"+OOOOO ++++++++OOOOO ",
+"+OXXX. ++++++++OXXX. ",
+"+OXXX. ++++++++OXXX. ",
+"+O.... ++++++++O.... ",
+"+ ++++++++ ",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/pixmap.xpm b/tools/glade/glade/graphics/pixmap.xpm
new file mode 100644
index 00000000..d76a5ec8
--- /dev/null
+++ b/tools/glade/glade/graphics/pixmap.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *pixmap_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 12 1",
+" c Gray0",
+". c #007b00",
+"X c #7b7b7b",
+"o c Blue",
+"O c Green",
+"+ c Cyan",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray87",
+"& c Gray100",
+"* c None",
+/* pixels */
+"*********************",
+"*********************",
+"*********************",
+"* ",
+"* +++++%%%&+++++++++ ",
+"* +&&&++%%++&+++XX++ ",
+"* +++++++%+++++X@@X+ ",
+"* ++&&++++XX+++X@@X+ ",
+"* +++++++ XXX&++XX++ ",
+"* &+++++XXXXXX++++&+ ",
+"* +++++ +++++ ",
+"* +++++ ###### +++++ ",
+"* +++++ #o##o# +++++ ",
+"* ..... ###### ..... ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO ##oo## OOOOO ",
+"* OOOOO OOOOO ",
+"* OOOOOOOOOOOOOOOOOO ",
+"* ",
+"*********************",
+"*********************"
+};
diff --git a/tools/glade/glade/graphics/placeholder.xpm b/tools/glade/glade/graphics/placeholder.xpm
new file mode 100644
index 00000000..4068801d
--- /dev/null
+++ b/tools/glade/glade/graphics/placeholder.xpm
@@ -0,0 +1,16 @@
+/* XPM */
+static char *placeholder_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"8 8 2 1",
+" c #bbbbbb",
+". c #d6d6d6",
+/* pixels */
+" . . ",
+". . ",
+" ..",
+" ..",
+". . ",
+" . . ",
+" .. ",
+" .. "
+};
diff --git a/tools/glade/glade/graphics/popup.xpm b/tools/glade/glade/graphics/popup.xpm
new file mode 100644
index 00000000..f2cc6be9
--- /dev/null
+++ b/tools/glade/glade/graphics/popup.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *popup_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 5 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #b3cece",
+"o c Gray100",
+"O c None",
+/* pixels */
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOOOOOOO",
+"................OOOOO",
+".oooooooooooooo. OOOO",
+".oooooooooooooo. OOOO",
+".oooooooooooooo. OOOO",
+".oooooooooooooo. OOOO",
+".oooooooooooooo. OOOO",
+".oooooooooooooo. OOOO",
+".oooooooooooooo. O.OO",
+".oooooooooooooo. O.OO",
+"................ O.OO",
+"O O.O.",
+"OOOOOOOOOOOOOOOOOO.O.",
+"OOOOOO.............O.",
+"OOOOOOOOOOOOOOOOOOOO.",
+"OOOOOOOOOO...........",
+"OOOOOOOOOOOOOOOOOOOOO"
+};
diff --git a/tools/glade/glade/graphics/popupmenu.xpm b/tools/glade/glade/graphics/popupmenu.xpm
new file mode 100644
index 00000000..8b60afe3
--- /dev/null
+++ b/tools/glade/glade/graphics/popupmenu.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *popupmenu_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 5 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #b3cece",
+"o c Gray100",
+"O c None",
+/* pixels */
+"OOOOOOOOOOOOOOOOOOOOO",
+"OO........OOOOOOOOOOO",
+"OO.oooooo OOOOOOOOOO",
+"OO.ooooo........OOOOO",
+"OO.ooooo.oooooo. OOOO",
+"OO.......oooooo. OOOO",
+"OO.ooooo.oooooo. O.OO",
+"OO.ooooo........ O.OO",
+"OO.ooooo.oooooo. O.O.",
+"OO.......oooooo. O.O.",
+"OO.ooooo.oooooo. O.O.",
+"OO.ooooo........ O.O.",
+"OO.ooooo. O.O.",
+"OO........ O.OOOOO.O.",
+"OO.oooooo. O.O.....O.",
+"OO.oooooo. O.O.OOOOO.",
+"OO.oooooo. O.O.O.....",
+"OO........ O.O.OOOOOO",
+"OOO O.O.OOOOOO",
+"OOOOOOOOOOOO.O.OOOOOO",
+"OOOOO........O.OOOOOO"
+};
diff --git a/tools/glade/glade/graphics/preview.xpm b/tools/glade/glade/graphics/preview.xpm
new file mode 100644
index 00000000..ad8fdcb3
--- /dev/null
+++ b/tools/glade/glade/graphics/preview.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static char *preview_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 9 1",
+" c Gray0",
+". c Blue",
+"X c Green",
+"o c Cyan",
+"O c Red",
+"+ c Magenta",
+"@ c Yellow",
+"# c #b3cece",
+"$ c None",
+/* pixels */
+"$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$",
+"$ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ OOO@@@XXXooo...+++ ",
+"$ ",
+"$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$"
+};
diff --git a/tools/glade/glade/graphics/progressbar.xpm b/tools/glade/glade/graphics/progressbar.xpm
new file mode 100644
index 00000000..95ee6753
--- /dev/null
+++ b/tools/glade/glade/graphics/progressbar.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *progressbar_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@..................@",
+"@@.++++++. XXXXXXXX+@",
+"@@.+OOOOO. XXXXXXXX+@",
+"@@.+OOOOO. XXXXXXXX+@",
+"@@.+OOOOO. XXXXXXXX+@",
+"@@.+OOOOO. XXXXXXXX+@",
+"@@.+OOOOO. XXXXXXXX+@",
+"@@........ XXXXXXXX+@",
+"@@. XXXXXXXX+@",
+"@@++++++++++++++++++@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/radiobutton.xpm b/tools/glade/glade/graphics/radiobutton.xpm
new file mode 100644
index 00000000..a8005cab
--- /dev/null
+++ b/tools/glade/glade/graphics/radiobutton.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * radiobutton_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #949594",
+"+ c #000000",
+"@ c #FFFFFF",
+" ",
+" ",
+" ",
+" ",
+" .... ",
+" ..+++++. ",
+" .++@@@@@+. ",
+" .+@@@@@@@. ",
+" .+@@@+++@@@.@ ",
+" .+@@+++++@@.@ ",
+" .+@@+++++@@.@ ",
+" .+@@+++++@@.@ ",
+" +@@@+++@@.@ ",
+" .+@@@@@@@.@ ",
+" ..@@@@..@ ",
+" ....@@ ",
+" @@@@ ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/radiomenuitem.xpm b/tools/glade/glade/graphics/radiomenuitem.xpm
new file mode 100644
index 00000000..9f88b425
--- /dev/null
+++ b/tools/glade/glade/graphics/radiomenuitem.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * radiomenuitem_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #7B7B7B",
+"+ c #000000",
+"@ c #FFFFFF",
+" ",
+" ",
+" ",
+" ",
+" . ",
+" ... ",
+" ..+.. ",
+" ..+ +.. ",
+" ..+ +.. ",
+" ..+ +.. ",
+" @@ @@ ",
+" @@ @@ ",
+" @@ @@ + ",
+" @@@ ++ ",
+" @ ++++ ",
+" +++++ ",
+" ++++ ",
+" +++ ",
+" + + ",
+" + ",
+" "};
diff --git a/tools/glade/glade/graphics/radiotoolbutton.xpm b/tools/glade/glade/graphics/radiotoolbutton.xpm
new file mode 100644
index 00000000..6cdc4487
--- /dev/null
+++ b/tools/glade/glade/graphics/radiotoolbutton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * radiotoolbutton_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@....+....+....+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.++++.++++.++++@#+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .##################+",
+" ++++++++++++++++++++",
+" ",
+" ",
+" ++++ ",
+" +@..@# ",
+" +@.##.@# ",
+" +.#++#.# ",
+" +.#++#.# ",
+" +@.##.@# ",
+" #@..@# ",
+" #### ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/save.xpm b/tools/glade/glade/graphics/save.xpm
new file mode 100644
index 00000000..5ca816c7
--- /dev/null
+++ b/tools/glade/glade/graphics/save.xpm
@@ -0,0 +1,91 @@
+/* XPM */
+static char * save_xpm[] = {
+"24 24 64 1",
+" c None",
+". c #000000",
+"+ c #779FA8",
+"@ c #495A5E",
+"# c #BFD1D5",
+"$ c #A8C1C5",
+"% c #E4ECED",
+"& c #FFFFFF",
+"* c #EEF3F4",
+"= c #E0E9EB",
+"- c #87AAB2",
+"; c #AEC4C9",
+"> c #F5F8F9",
+", c #8BADB5",
+"' c #3E4D50",
+") c #94B2B9",
+"! c #CFDCDF",
+"~ c #E4ECEE",
+"{ c #788A8D",
+"] c #EBF1F2",
+"^ c #E8EFF0",
+"/ c #F2F6F7",
+"( c #607A7F",
+"_ c #F0F4F5",
+": c #536E75",
+"< c #A0BCC1",
+"[ c #465E63",
+"} c #4B575A",
+"| c #557278",
+"1 c #A4ABAD",
+"2 c #EAEAEA",
+"3 c #E4E4E4",
+"4 c #606364",
+"5 c #C6CACC",
+"6 c #F3F3F3",
+"7 c #F1F1F1",
+"8 c #E7E7E7",
+"9 c #E1E1E1",
+"0 c #A9B2B4",
+"a c #486166",
+"b c #34464A",
+"c c #729096",
+"d c #BCC2C3",
+"e c #F6F6F6",
+"f c #57696D",
+"g c #CFD8DA",
+"h c #DEDEDE",
+"i c #D8D8D8",
+"j c #8C9394",
+"k c #F2F2F2",
+"l c #3A474A",
+"m c #7EA4AC",
+"n c #D5DADA",
+"o c #E0E0E0",
+"p c #B4B4B4",
+"q c #657376",
+"r c #D0D5D6",
+"s c #E9E9E9",
+"t c #A7B0B2",
+"u c #D2D4D5",
+"v c #899293",
+"w c #484848",
+"x c #DDDDDD",
+"y c #8F9A9B",
+" ",
+" ",
+" ",
+" .. ",
+" ..+@. ",
+" ..#$%+. ",
+" ..#$#&*+@. ",
+" ..#$#&&&&=+. ",
+" ..-;#&&&&&&>,'. ",
+" .);!&&&&&&&&&~+. ",
+" .{)]&&&&&&&&&^+@. ",
+" .$=&&&&&&&/=+++. ",
+" .(-]&&&&_=++::+@. ",
+" .<=&&_=++[}|+:+. ",
+" .(-^=++[1234+:+@. ",
+" .)++:567890a+[b. ",
+" .c-+defg3hij+'.. ",
+" .)+:klmnopq.. ",
+" .|++rstuvw. ",
+" .a+:xy.. ",
+" ..... ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/scrolledwindow.xpm b/tools/glade/glade/graphics/scrolledwindow.xpm
new file mode 100644
index 00000000..da9951a0
--- /dev/null
+++ b/tools/glade/glade/graphics/scrolledwindow.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * scrolledwindow_xpm[] = {
+"21 21 4 1",
+" c None",
+". c #FFFFFF",
+"+ c #D6D6D6",
+"@ c #000000",
+".....................",
+".+++++++++++++.+++++@",
+".+++++++++++++.++@++@",
+".+++++++++++++.+@@@+@",
+".+++++++++++++.+++++@",
+".+++++++++++++.@@@@@@",
+".+++++++++++++......@",
+".+++++++++++++..++++@",
+".+++++++++++++..++++@",
+".+++++++++++++......@",
+".+++++++++++++.+++++@",
+".+++++++++++++.+@@@+@",
+".+++++++++++++.++@++@",
+".+++++++++++++.+++++@",
+"...............@@@@@@",
+".++++@...@++++@++++++",
+".++@+@.++@+@++@++++++",
+".+@@+@.++@+@@+@++++++",
+".++@+@.++@+@++@++++++",
+".++++@.++@++++@++++++",
+".@@@@@@@@@@@@@@++++++"};
diff --git a/tools/glade/glade/graphics/selector.xpm b/tools/glade/glade/graphics/selector.xpm
new file mode 100644
index 00000000..4c39b4dd
--- /dev/null
+++ b/tools/glade/glade/graphics/selector.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char *selector_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 3 1",
+" c Gray0",
+". c #b3cece",
+"X c None",
+/* pixels */
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXX XXXXXXXXXXXXXX",
+"XXXXXX XXXXXXXXXXXXX",
+"XXXXXX XXXXXXXXXXXX",
+"XXXXXX XXXXXXXXXXX",
+"XXXXXX XXXXXXXXXX",
+"XXXXXX XXXXXXXXX",
+"XXXXXX XXXXXXXX",
+"XXXXXX XXXXXXX",
+"XXXXXX XXXXXX",
+"XXXXXX XXXXXXXXX",
+"XXXXXX X XXXXXXXXX",
+"XXXXXX XXX XXXXXXXX",
+"XXXXXXXXXX XXXXXXXX",
+"XXXXXXXXXXX XXXXXXX",
+"XXXXXXXXXXXX XXXXXXX",
+"XXXXXXXXXXXX XXXXXX",
+"XXXXXXXXXXXXX XXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXX"
+};
diff --git a/tools/glade/glade/graphics/separatortoolitem.xpm b/tools/glade/glade/graphics/separatortoolitem.xpm
new file mode 100644
index 00000000..0705bdef
--- /dev/null
+++ b/tools/glade/glade/graphics/separatortoolitem.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * separatortoolitem_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@....+....+....+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.++++.++++.++++@#+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .##################+",
+" ++++++++++++++++++++",
+" ",
+" ",
+" #. ",
+" #. ",
+" #. ",
+" #. ",
+" #. ",
+" #. ",
+" #. ",
+" #. ",
+" #. ",
+" "};
diff --git a/tools/glade/glade/graphics/source.xpm b/tools/glade/glade/graphics/source.xpm
new file mode 100644
index 00000000..5d6aba4d
--- /dev/null
+++ b/tools/glade/glade/graphics/source.xpm
@@ -0,0 +1,107 @@
+/* XPM */
+static char * source_xpm[] = {
+"24 24 80 1",
+" c None",
+". c #000000",
+"+ c #B2A97E",
+"@ c #B6AD81",
+"# c #7A7356",
+"$ c #B0A77C",
+"% c #B5AC80",
+"& c #BAB184",
+"* c #BBB284",
+"= c #B6AD80",
+"- c #ADA57B",
+"; c #B7AE81",
+"> c #BDB486",
+", c #837C5C",
+"' c #B4AC80",
+") c #7C7557",
+"! c #C0B687",
+"~ c #BEB586",
+"{ c #B1A87D",
+"] c #B9B082",
+"^ c #C0B788",
+"/ c #AFA67B",
+"( c #AFA77C",
+"_ c #BAB183",
+": c #BBB285",
+"< c #BCB385",
+"[ c #C4BB8B",
+"} c #C6BC8C",
+"| c #C7BD8D",
+"1 c #C7BE8D",
+"2 c #C8BF8E",
+"3 c #C8BE8D",
+"4 c #C5BC8B",
+"5 c #C1B788",
+"6 c #B9B083",
+"7 c #CDC391",
+"8 c #D0C693",
+"9 c #D1C794",
+"0 c #D3C995",
+"a c #CDC491",
+"b c #C2B889",
+"c c #CAC18F",
+"d c #D5CB97",
+"e c #D6CC97",
+"f c #D6CC98",
+"g c #D7CD98",
+"h c #CEC491",
+"i c #C2B98A",
+"j c #CBC18F",
+"k c #C1B889",
+"l c #8A8261",
+"m c #D4CA96",
+"n c #C0B787",
+"o c #80785A",
+"p c #B9B183",
+"q c #827C5B",
+"r c #CFC592",
+"s c #C7BD8C",
+"t c #C3BA8A",
+"u c #CAC08F",
+"v c #D0C793",
+"w c #7C7657",
+"x c #D2C894",
+"y c #D2C995",
+"z c #CCC290",
+"A c #C4BA8A",
+"B c #D1C793",
+"C c #CEC592",
+"D c #C5BC8C",
+"E c #CFC693",
+"F c #C1B888",
+"G c #BEB486",
+"H c #C8BF8D",
+"I c #C9C08F",
+"J c #C9BF8E",
+"K c #C5BB8B",
+"L c #B2A97D",
+"M c #C2B989",
+"N c #BFB687",
+"O c #B3AA7E",
+" ",
+" ",
+" ",
+" .... ",
+" .+.@#. ",
+" .$%&*=-. ",
+" ..;>,$.. ",
+" .-')!~@. ... ",
+" ..{]~^.. ./({. . ",
+" .#._#._..&:<..@. ",
+" . ..>[}|1232456. ",
+" .2789009a2. ",
+" .bc9defge0h.. ",
+" .]ij9ekl1gm83n. ",
+" .*ic9dopqgmrs~. ",
+" .<tu8mvwuxyzA*. ",
+" ..3ax0rBxC3.. ",
+" .DuhE8rz3F. ",
+" .Gt}HIJ1K^*L. ",
+" .~..MbN..O. ",
+" . .*_;. . ",
+" ... ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/spinbutton.xpm b/tools/glade/glade/graphics/spinbutton.xpm
new file mode 100644
index 00000000..f3a313b1
--- /dev/null
+++ b/tools/glade/glade/graphics/spinbutton.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *spinbutton_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+ +",
+"+ OOOOOOOOOOO OOOOO +",
+"+ OOOOOOOOOOO OX X. +",
+"+ OOOOOOOOOOO O . +",
+"+ OOOOOOOOOOO OOOOO +",
+"+ OOOOOOOOOOO O . +",
+"+ OOOOOOOOOOO OX X. +",
+"+ OOOOOOOOOOO ..... +",
+"+ +",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/statusbar.xpm b/tools/glade/glade/graphics/statusbar.xpm
new file mode 100644
index 00000000..8576d88c
--- /dev/null
+++ b/tools/glade/glade/graphics/statusbar.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *statusbar_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@+XX.@@@@@@@@@@@@@@",
+"@@@+XX.@@@@@@@@@@@@@@",
+"@@@+XX.@@@@@@@@@@@@@@",
+"@@@+XX.@@@@@@@@@@@@@@",
+"@@@+XX++++++++++++@@@",
+"@@@+XXXXXXXXXXXXXX@@@",
+"@@@+XXXXXXXXXXXXXX@@@",
+"@@@+XX............@@@",
+"@@@+XX.OOOOOOOOOOO@@@",
+"@@@+XX.OOOOOOOOOOO@@@",
+"@@@+XX.OOOOOOOOOOO@@@",
+"@@@+XX++++++++++++@@@",
+"@@@+XXXXXXXXXXXXXX@@@",
+"@@@+XXXXXXXXXXXXXX@@@",
+"@@@ @@@",
+"@@@@@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/table.xpm b/tools/glade/glade/graphics/table.xpm
new file mode 100644
index 00000000..f5c2ef99
--- /dev/null
+++ b/tools/glade/glade/graphics/table.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * table_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"..........+.........+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".#########+.########+",
+"+++++++++++++++++++++",
+"..........+.........+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".#########+.########+",
+"+++++++++++++++++++++",
+"..........+.........+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".@@@@@@@@#+.@@@@@@@#+",
+".#########+.########+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/text.xpm b/tools/glade/glade/graphics/text.xpm
new file mode 100644
index 00000000..64153895
--- /dev/null
+++ b/tools/glade/glade/graphics/text.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * text_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #7B7B7B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #D6D6D6",
+"$ c #DEDEDE",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@+++++++++++++++++#+",
+".@+++++++@+++++++++#+",
+".@+++++++@+++++++++#+",
+".@++@@@++@$@@++$@@+#+",
+".@+.+++@+@@+$@+@+$@#+",
+".@++@@@@+@+++@+@+++#+",
+".@+@+++@+@+++@+@+++#+",
+".@+@+++@+@++$@+@+$@#+",
+".@++@@@@+@@@@++$@@+#+",
+".@+++++++++++++++++#+",
+".@+++++@+++++++++@@#+",
+".@+++++@++@@@+++@$+#+",
+".@++@@@@+@$+$@++@++#+",
+".@+@$+$@+@$++@+@@@+#+",
+".@+@+++@+@@@@+++@++#+",
+".@+@$+$@+@+++.++@++#+",
+".@++@@@@++@@@+++@++#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/togglebutton.xpm b/tools/glade/glade/graphics/togglebutton.xpm
new file mode 100644
index 00000000..96d40354
--- /dev/null
+++ b/tools/glade/glade/graphics/togglebutton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * togglebutton_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #7B7B7B",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #C5C2C5",
+" ",
+" ",
+" ",
+" ..................+ ",
+" .@@@@@@@@@@@@@@@@@+ ",
+" .@################+ ",
+" .@################+ ",
+" .@################+ ",
+" .@####@@##@##@####+ ",
+" .@###@##@#@.#@####+ ",
+" .@###@##@#@@#@####+ ",
+" .@###@##@#@#@@####+ ",
+" .@###@##@#@#.@####+ ",
+" .@####@@##@##@####+ ",
+" .@################+ ",
+" .@################+ ",
+" .@################+ ",
+" +++++++++++++++++++ ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/toggletoolbutton.xpm b/tools/glade/glade/graphics/toggletoolbutton.xpm
new file mode 100644
index 00000000..e8a58081
--- /dev/null
+++ b/tools/glade/glade/graphics/toggletoolbutton.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * toggletoolbutton_xpm[] = {
+"21 21 6 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"$ c #C5C2C5",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@....+....+....+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.++++.++++.++++@#+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .##################+",
+" ++++++++++++++++++++",
+" ",
+" ",
+" ############. ",
+" #+++++++++++. ",
+" #+$$$$$$$$$$. ",
+" #+$$+$$+$+$$. ",
+" #+$+$+$+#+$$. ",
+" #+$+$+$+#+$$. ",
+" #+$$+$$+$+$$. ",
+" #+$$$$$$$$$$. ",
+" ............. ",
+" "};
diff --git a/tools/glade/glade/graphics/toolbar.xpm b/tools/glade/glade/graphics/toolbar.xpm
new file mode 100644
index 00000000..d9a52171
--- /dev/null
+++ b/tools/glade/glade/graphics/toolbar.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *toolbar_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+OOOOOOOOOOOOOOOOOOO ",
+"+OXXXXXXXXXXXXXXXXX. ",
+"+OXOOOO OOOO OOOO X. ",
+"+OXOXXX OXXX OXXX X. ",
+"+OXOXXX OXXX OXXX X. ",
+"+OXO O O X. ",
+"+OXXXXXXXXXXXXXXXXX. ",
+"+O.................. ",
+"+ ",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/toolbutton.xpm b/tools/glade/glade/graphics/toolbutton.xpm
new file mode 100644
index 00000000..6b44dd61
--- /dev/null
+++ b/tools/glade/glade/graphics/toolbutton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * toolbutton_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@....+....+....+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.@@@+.@@@+.@@@+@#+",
+" .@.++++.++++.++++@#+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .##################+",
+" ++++++++++++++++++++",
+" ",
+" ",
+" ............+ ",
+" .@@@@@@@@@@#+ ",
+" .@@+@@+@+@@#+ ",
+" .@+@+@++@@@#+ ",
+" .@+@+@++@@@#+ ",
+" .@@+@@+@+@@#+ ",
+" .@@@@@@@@@@#+ ",
+" .###########+ ",
+" +++++++++++++ ",
+" "};
diff --git a/tools/glade/glade/graphics/toolitem.xpm b/tools/glade/glade/graphics/toolitem.xpm
new file mode 100644
index 00000000..bef1e216
--- /dev/null
+++ b/tools/glade/glade/graphics/toolitem.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * toolitem_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+" ",
+" ",
+" ",
+" ",
+" ...................+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .@@@@@@....+@@@@@@#+",
+" .@@@@@@.@@@+@@@@@@#+",
+" .@@@@@@.@@@+@@@@@@#+",
+" .@@@@@@.++++@@@@@@#+",
+" .@@@@@@@@@@@@@@@@@#+",
+" .##################+",
+" ++++++++++++++++++++",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/tools/glade/glade/graphics/tree.xpm b/tools/glade/glade/graphics/tree.xpm
new file mode 100644
index 00000000..0a15524b
--- /dev/null
+++ b/tools/glade/glade/graphics/tree.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *tree_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c Green",
+"o c Cyan",
+"O c Yellow",
+"+ c #b3cece",
+"@ c None",
+/* pixels */
+"@ @@@@@@@@@@@@@@@@@",
+"@ o @......@@@@@@@@@@",
+"@ @@@@@@@@@@@@@@@@@",
+"@@ @@@@@@@@@@@@@@@@@@",
+"@@ @@ @@@@@@@@@@@@@",
+"@@ O @......@@@@@@",
+"@@ @@ @@@@@@@@@@@@@",
+"@@ @@@ @@@@@@@@@@@@@@",
+"@@ @@@ @@ @@@@@@@@@",
+"@@ @@@ X @......@@",
+"@@ @@@ @@ @@@@@@@@@",
+"@@ @@@ @@@@@@@@@@@@@@",
+"@@ @@@ @@ @@@@@@@@@",
+"@@ @@@ X @......@@",
+"@@ @@@@@@ @@@@@@@@@",
+"@@ @@@@@@@@@@@@@@@@@@",
+"@@ @@ @@@@@@@@@@@@@",
+"@@ O @......@@@@@@",
+"@@@@@ @@@@@@@@@@@@@",
+"@@@@@@ @@@@@@@@@@@@@@",
+"@@@@@@ @@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/treeitem.xpm b/tools/glade/glade/graphics/treeitem.xpm
new file mode 100644
index 00000000..2c0bf836
--- /dev/null
+++ b/tools/glade/glade/graphics/treeitem.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char *treeitem_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 8 1",
+" c Gray0",
+". c #7b7b7b",
+"X c Red",
+"o c Yellow",
+"O c #b3cece",
+"+ c Gray87",
+"@ c Gray100",
+"# c None",
+/* pixels */
+"#####################",
+"#####################",
+"#####################",
+"###...###############",
+"## .@ #+++++#########",
+"### ###############",
+"#### ################",
+"#### #...############",
+"#### .o #XXXXXXX####",
+"#### # #XXXXXXX####",
+"#### ################",
+"#### #...############",
+"#### .@ #+++++######",
+"#### # ############",
+"#### ## #############",
+"#### ## #...#########",
+"#### ## .o #+++++###",
+"#### #### #########",
+"#####################",
+"#####################",
+"#####################"
+};
diff --git a/tools/glade/glade/graphics/unknown.xpm b/tools/glade/glade/graphics/unknown.xpm
new file mode 100644
index 00000000..7ce9bce5
--- /dev/null
+++ b/tools/glade/glade/graphics/unknown.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *unknown_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"++OOOOOOOOOOOOOOOO ++",
+"++OXXXXXXXXXXXXXX. ++",
+"++OXXXXX XXXXXX. ++",
+"++OXXXX XXXXX. ++",
+"++OXXX X XXXX. ++",
+"++OXXX XXX XXXX. ++",
+"++OXXXXXXX XXXX. ++",
+"++OXXXXXX XXXXX. ++",
+"++OXXXXXX XXXXXX. ++",
+"++OXXXXXX XXXXXX. ++",
+"++OXXXXXX XXXXXX. ++",
+"++OXXXXXXXXXXXXXX. ++",
+"++OXXXXXX XXXXXX. ++",
+"++OXXXXXX XXXXXX. ++",
+"++OXXXXXXXXXXXXXX. ++",
+"++O............... ++",
+"++ ++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/vbox.xpm b/tools/glade/glade/graphics/vbox.xpm
new file mode 100644
index 00000000..dbec9e9d
--- /dev/null
+++ b/tools/glade/glade/graphics/vbox.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * vbox_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".###################+",
+"+++++++++++++++++++++",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".###################+",
+"+++++++++++++++++++++",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/vbuttonbox.xpm b/tools/glade/glade/graphics/vbuttonbox.xpm
new file mode 100644
index 00000000..0c2bc959
--- /dev/null
+++ b/tools/glade/glade/graphics/vbuttonbox.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *vbuttonbox_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 6 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"+++++++++++++++++++++",
+"+++++++++++++++++++++",
+"++++++++OOOOO +++++++",
+"++++++++OXXX. +++++++",
+"++++++++OXXX. +++++++",
+"++++++++O.... +++++++",
+"++++++++ +++++++",
+"+++++++++++++++++++++",
+"++++++++OOOOO +++++++",
+"++++++++OXXX. +++++++",
+"++++++++OXXX. +++++++",
+"++++++++O.... +++++++",
+"++++++++ +++++++",
+"+++++++++++++++++++++",
+"++++++++OOOOO +++++++",
+"++++++++OXXX. +++++++",
+"++++++++OXXX. +++++++",
+"++++++++O.... +++++++",
+"++++++++ +++++++",
+"+++++++++++++++++++++",
+"+++++++++++++++++++++"
+};
diff --git a/tools/glade/glade/graphics/viewport.xpm b/tools/glade/glade/graphics/viewport.xpm
new file mode 100644
index 00000000..71e5e80c
--- /dev/null
+++ b/tools/glade/glade/graphics/viewport.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *viewport_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@@@@@@",
+"@...................@",
+"@. +O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@. XXXXXXXXXXXXXXX+O@",
+"@.+++++++++++++++++O@",
+"@.OOOOOOOOOOOOOOOOOO@",
+"@@@@@@@@@@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/vpaned.xpm b/tools/glade/glade/graphics/vpaned.xpm
new file mode 100644
index 00000000..96c23500
--- /dev/null
+++ b/tools/glade/glade/graphics/vpaned.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * vpaned_xpm[] = {
+"21 21 5 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #D6D6D6",
+"# c #7B7B7B",
+"....................+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@#####@@#+",
+".@@@@@@@@@@@#...##@#+",
+".############...####+",
+"++++++++++++#...##+++",
+"............######..+",
+".@@@@@@@@@@@@#####@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".@@@@@@@@@@@@@@@@@@#+",
+".###################+",
+"+++++++++++++++++++++"};
diff --git a/tools/glade/glade/graphics/vruler.xpm b/tools/glade/glade/graphics/vruler.xpm
new file mode 100644
index 00000000..630157fd
--- /dev/null
+++ b/tools/glade/glade/graphics/vruler.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char *vruler_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 3 1",
+" c Gray0",
+". c #b3cece",
+"X c None",
+/* pixels */
+"XXXX XXXXXXXXXXXXXX",
+"XXXX X XX XXXX",
+"XXXX X XXXXXXXXX XXXX",
+"XXXX XXXXXXXXX XXXX",
+"XXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXXXXXXXXXXXXXX XXXX",
+"XXXX XXXXXX XXXX",
+"XXXX XXXXXXXXXXX XXXX",
+"XXXX XXXXXXXXX XXXX",
+"XXXXXX XX XXXX",
+"XXXX XXXXXXXXXXXXXX"
+};
diff --git a/tools/glade/glade/graphics/vscale.xpm b/tools/glade/glade/graphics/vscale.xpm
new file mode 100644
index 00000000..339698fd
--- /dev/null
+++ b/tools/glade/glade/graphics/vscale.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *vscale_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 7 1",
+" c Gray0",
+". c #7b7b7b",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray87",
+"+ c Gray100",
+"@ c None",
+/* pixels */
+".........@@@@@@@@@@@@",
+". +@@@@@@@@@@@@",
+". ++++ O+@@@@@@@@@@@@",
+". +XX. O+@@@@@@@@@@@@",
+". +XX. O+@@ @@@@@ @",
+". +XX. O+@ @@ @@@ @@ ",
+". +... O+@ @@ @@@ @@ ",
+". +XX. O+@ @@ @@@ @@ ",
+". +XX. O+@ @@ @@@ @@ ",
+". +... O+@@ @@ @@ @",
+". O+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". XXXXXO+@@@@@@@@@@@@",
+". OOOOOO+@@@@@@@@@@@@",
+".++++++++@@@@@@@@@@@@"
+};
diff --git a/tools/glade/glade/graphics/vscrollbar.xpm b/tools/glade/glade/graphics/vscrollbar.xpm
new file mode 100644
index 00000000..0e902b1e
--- /dev/null
+++ b/tools/glade/glade/graphics/vscrollbar.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static char *vscrollbar_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 21 6 1",
+" c Gray0",
+". c Gray61",
+"X c #d6d6d6",
+"o c #b3cece",
+"O c Gray100",
+"+ c None",
+/* pixels */
+"++++++ +++++",
+"++++++ ...O...O+++++",
+"++++++ ..OX ..O+++++",
+"++++++ .OXXX .O+++++",
+"++++++ OXXXXX O+++++",
+"++++++ O+++++",
+"++++++ .......O+++++",
+"++++++ OOOOOO O+++++",
+"++++++ OXXXXX O+++++",
+"++++++ OXXXXX O+++++",
+"++++++ OXXXXX O+++++",
+"++++++ OXXXXX O+++++",
+"++++++ OXXXXX O+++++",
+"++++++ O O+++++",
+"++++++ .......O+++++",
+"++++++ OOOOOOOO+++++",
+"++++++ OXXXXX O+++++",
+"++++++ .OXXX .O+++++",
+"++++++ ..OX ..O+++++",
+"++++++ ... ...O+++++",
+"++++++OOOOOOOOO+++++"
+};
diff --git a/tools/glade/glade/graphics/vseparator.xpm b/tools/glade/glade/graphics/vseparator.xpm
new file mode 100644
index 00000000..3455f74d
--- /dev/null
+++ b/tools/glade/glade/graphics/vseparator.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char *vseparator_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 4 1",
+" c #7b7b7b",
+". c #b3cece",
+"X c Gray100",
+"o c None",
+/* pixels */
+"ooooooooooooooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"oooooooooo Xooooooooo",
+"ooooooooooooooooooooo"
+};
diff --git a/tools/glade/glade/graphics/window.xpm b/tools/glade/glade/graphics/window.xpm
new file mode 100644
index 00000000..8407e283
--- /dev/null
+++ b/tools/glade/glade/graphics/window.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *window_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"21 21 11 1",
+" c Gray0",
+". c #00007b",
+"X c #7b7b7b",
+"o c Green",
+"O c Cyan",
+"+ c Red",
+"@ c Yellow",
+"# c #d6d6d6",
+"$ c #b3cece",
+"% c Gray100",
+"& c None",
+/* pixels */
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&",
+"XXXXXXXXXXXXXXXXXXXX&",
+"X.+@...............X ",
+"X.Oo.%%%.%%.....# #X ",
+"XXXXXXXXXXXXXXXXXXXX ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"X#%%%%%%%%%%%%%%%%%X ",
+"XXXXXXXXXXXXXXXXXXXX ",
+"& ",
+"&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&"
+};
diff --git a/tools/glade/glade/keys.c b/tools/glade/glade/keys.c
new file mode 100644
index 00000000..060a73f3
--- /dev/null
+++ b/tools/glade/glade/keys.c
@@ -0,0 +1,1375 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gdk/gdkkeysyms.h>
+
+#include "gladeconfig.h"
+
+#include "keys.h"
+
+/*
+ * This is automatically generated by helpers/getkeys.pl
+ * Note that GTK 1.0 only supports 1-byte keysyms for accelerators,
+ * so we filter them out. GTK 1.1 can use all of them.
+ */
+const GbKey GbKeys[] =
+{
+ { GDK_A, "A" },
+ { GDK_B, "B" },
+ { GDK_C, "C" },
+ { GDK_D, "D" },
+ { GDK_E, "E" },
+ { GDK_F, "F" },
+ { GDK_G, "G" },
+ { GDK_H, "H" },
+ { GDK_I, "I" },
+ { GDK_J, "J" },
+ { GDK_K, "K" },
+ { GDK_L, "L" },
+ { GDK_M, "M" },
+ { GDK_N, "N" },
+ { GDK_O, "O" },
+ { GDK_P, "P" },
+ { GDK_Q, "Q" },
+ { GDK_R, "R" },
+ { GDK_S, "S" },
+ { GDK_T, "T" },
+ { GDK_U, "U" },
+ { GDK_V, "V" },
+ { GDK_W, "W" },
+ { GDK_X, "X" },
+ { GDK_Y, "Y" },
+ { GDK_Z, "Z" },
+ { GDK_a, "a" },
+ { GDK_b, "b" },
+ { GDK_c, "c" },
+ { GDK_d, "d" },
+ { GDK_e, "e" },
+ { GDK_f, "f" },
+ { GDK_g, "g" },
+ { GDK_h, "h" },
+ { GDK_i, "i" },
+ { GDK_j, "j" },
+ { GDK_k, "k" },
+ { GDK_l, "l" },
+ { GDK_m, "m" },
+ { GDK_n, "n" },
+ { GDK_o, "o" },
+ { GDK_p, "p" },
+ { GDK_q, "q" },
+ { GDK_r, "r" },
+ { GDK_s, "s" },
+ { GDK_t, "t" },
+ { GDK_u, "u" },
+ { GDK_v, "v" },
+ { GDK_w, "w" },
+ { GDK_x, "x" },
+ { GDK_y, "y" },
+ { GDK_z, "z" },
+
+ { GDK_F1, "F1" },
+ { GDK_F2, "F2" },
+ { GDK_F3, "F3" },
+ { GDK_F4, "F4" },
+ { GDK_F5, "F5" },
+ { GDK_F6, "F6" },
+ { GDK_F7, "F7" },
+ { GDK_F8, "F8" },
+ { GDK_F9, "F9" },
+ { GDK_F10, "F10" },
+ { GDK_F11, "F11" },
+ { GDK_F12, "F12" },
+ { GDK_F13, "F13" },
+ { GDK_F14, "F14" },
+ { GDK_F15, "F15" },
+ { GDK_F16, "F16" },
+ { GDK_F17, "F17" },
+ { GDK_F18, "F18" },
+ { GDK_F19, "F19" },
+ { GDK_F20, "F20" },
+ { GDK_F21, "F21" },
+ { GDK_F22, "F22" },
+ { GDK_F23, "F23" },
+ { GDK_F24, "F24" },
+ { GDK_F25, "F25" },
+ { GDK_F26, "F26" },
+ { GDK_F27, "F27" },
+ { GDK_F28, "F28" },
+ { GDK_F29, "F29" },
+ { GDK_F30, "F30" },
+ { GDK_F31, "F31" },
+ { GDK_F32, "F32" },
+ { GDK_F33, "F33" },
+ { GDK_F34, "F34" },
+ { GDK_F35, "F35" },
+
+ { GDK_BackSpace, "BackSpace" },
+ { GDK_Tab, "Tab" },
+ { GDK_Return, "Return" },
+ { GDK_Escape, "Escape" },
+ { GDK_Delete, "Delete" },
+ { GDK_Insert, "Insert" },
+ { GDK_space, "space" },
+
+ { GDK_Home, "Home" },
+ { GDK_Left, "Left" },
+ { GDK_Up, "Up" },
+ { GDK_Right, "Right" },
+ { GDK_Down, "Down" },
+ { GDK_Page_Up, "Page_Up" },
+ { GDK_Page_Down, "Page_Down" },
+ { GDK_End, "End" },
+
+ { GDK_KP_Space, "KP_Space" },
+ { GDK_KP_Tab, "KP_Tab" },
+ { GDK_KP_Enter, "KP_Enter" },
+ { GDK_KP_F1, "KP_F1" },
+ { GDK_KP_F2, "KP_F2" },
+ { GDK_KP_F3, "KP_F3" },
+ { GDK_KP_F4, "KP_F4" },
+ { GDK_KP_Home, "KP_Home" },
+ { GDK_KP_Left, "KP_Left" },
+ { GDK_KP_Up, "KP_Up" },
+ { GDK_KP_Right, "KP_Right" },
+ { GDK_KP_Down, "KP_Down" },
+ { GDK_KP_Prior, "KP_Prior" },
+ { GDK_KP_Page_Up, "KP_Page_Up" },
+ { GDK_KP_Next, "KP_Next" },
+ { GDK_KP_Page_Down, "KP_Page_Down" },
+ { GDK_KP_End, "KP_End" },
+ { GDK_KP_Begin, "KP_Begin" },
+ { GDK_KP_Insert, "KP_Insert" },
+ { GDK_KP_Delete, "KP_Delete" },
+ { GDK_KP_Equal, "KP_Equal" },
+ { GDK_KP_Multiply, "KP_Multiply" },
+ { GDK_KP_Add, "KP_Add" },
+ { GDK_KP_Separator, "KP_Separator" },
+ { GDK_KP_Subtract, "KP_Subtract" },
+ { GDK_KP_Decimal, "KP_Decimal" },
+ { GDK_KP_Divide, "KP_Divide" },
+ { GDK_KP_0, "KP_0" },
+ { GDK_KP_1, "KP_1" },
+ { GDK_KP_2, "KP_2" },
+ { GDK_KP_3, "KP_3" },
+ { GDK_KP_4, "KP_4" },
+ { GDK_KP_5, "KP_5" },
+ { GDK_KP_6, "KP_6" },
+ { GDK_KP_7, "KP_7" },
+ { GDK_KP_8, "KP_8" },
+ { GDK_KP_9, "KP_9" },
+
+ { GDK_0, "0" },
+ { GDK_1, "1" },
+ { GDK_2, "2" },
+ { GDK_3, "3" },
+ { GDK_4, "4" },
+ { GDK_5, "5" },
+ { GDK_6, "6" },
+ { GDK_7, "7" },
+ { GDK_8, "8" },
+ { GDK_9, "9" },
+
+ { GDK_VoidSymbol, "VoidSymbol" },
+ { GDK_Linefeed, "Linefeed" },
+ { GDK_Clear, "Clear" },
+ { GDK_Pause, "Pause" },
+ { GDK_Scroll_Lock, "Scroll_Lock" },
+ { GDK_Sys_Req, "Sys_Req" },
+ { GDK_Multi_key, "Multi_key" },
+ { GDK_Codeinput, "Codeinput" },
+ { GDK_SingleCandidate, "SingleCandidate" },
+ { GDK_MultipleCandidate, "MultipleCandidate" },
+ { GDK_PreviousCandidate, "PreviousCandidate" },
+ { GDK_Kanji, "Kanji" },
+ { GDK_Muhenkan, "Muhenkan" },
+ { GDK_Henkan_Mode, "Henkan_Mode" },
+ { GDK_Henkan, "Henkan" },
+ { GDK_Romaji, "Romaji" },
+ { GDK_Hiragana, "Hiragana" },
+ { GDK_Katakana, "Katakana" },
+ { GDK_Hiragana_Katakana, "Hiragana_Katakana" },
+ { GDK_Zenkaku, "Zenkaku" },
+ { GDK_Hankaku, "Hankaku" },
+ { GDK_Zenkaku_Hankaku, "Zenkaku_Hankaku" },
+ { GDK_Touroku, "Touroku" },
+ { GDK_Massyo, "Massyo" },
+ { GDK_Kana_Lock, "Kana_Lock" },
+ { GDK_Kana_Shift, "Kana_Shift" },
+ { GDK_Eisu_Shift, "Eisu_Shift" },
+ { GDK_Eisu_toggle, "Eisu_toggle" },
+ { GDK_Kanji_Bangou, "Kanji_Bangou" },
+ { GDK_Zen_Koho, "Zen_Koho" },
+ { GDK_Mae_Koho, "Mae_Koho" },
+ { GDK_Prior, "Prior" },
+ { GDK_Next, "Next" },
+ { GDK_Begin, "Begin" },
+ { GDK_Select, "Select" },
+ { GDK_Print, "Print" },
+ { GDK_Execute, "Execute" },
+ { GDK_Undo, "Undo" },
+ { GDK_Redo, "Redo" },
+ { GDK_Menu, "Menu" },
+ { GDK_Find, "Find" },
+ { GDK_Cancel, "Cancel" },
+ { GDK_Help, "Help" },
+ { GDK_Break, "Break" },
+ { GDK_Mode_switch, "Mode_switch" },
+ { GDK_script_switch, "script_switch" },
+ { GDK_Num_Lock, "Num_Lock" },
+ { GDK_L1, "L1" },
+ { GDK_L2, "L2" },
+ { GDK_L3, "L3" },
+ { GDK_L4, "L4" },
+ { GDK_L5, "L5" },
+ { GDK_L6, "L6" },
+ { GDK_L7, "L7" },
+ { GDK_L8, "L8" },
+ { GDK_L9, "L9" },
+ { GDK_L10, "L10" },
+ { GDK_R1, "R1" },
+ { GDK_R2, "R2" },
+ { GDK_R3, "R3" },
+ { GDK_R4, "R4" },
+ { GDK_R5, "R5" },
+ { GDK_R6, "R6" },
+ { GDK_R7, "R7" },
+ { GDK_R8, "R8" },
+ { GDK_R9, "R9" },
+ { GDK_R10, "R10" },
+ { GDK_R11, "R11" },
+ { GDK_R12, "R12" },
+ { GDK_R13, "R13" },
+ { GDK_R14, "R14" },
+ { GDK_R15, "R15" },
+ { GDK_Shift_L, "Shift_L" },
+ { GDK_Shift_R, "Shift_R" },
+ { GDK_Control_L, "Control_L" },
+ { GDK_Control_R, "Control_R" },
+ { GDK_Caps_Lock, "Caps_Lock" },
+ { GDK_Shift_Lock, "Shift_Lock" },
+ { GDK_Meta_L, "Meta_L" },
+ { GDK_Meta_R, "Meta_R" },
+ { GDK_Alt_L, "Alt_L" },
+ { GDK_Alt_R, "Alt_R" },
+ { GDK_Super_L, "Super_L" },
+ { GDK_Super_R, "Super_R" },
+ { GDK_Hyper_L, "Hyper_L" },
+ { GDK_Hyper_R, "Hyper_R" },
+ { GDK_ISO_Lock, "ISO_Lock" },
+ { GDK_ISO_Level2_Latch, "ISO_Level2_Latch" },
+ { GDK_ISO_Level3_Shift, "ISO_Level3_Shift" },
+ { GDK_ISO_Level3_Latch, "ISO_Level3_Latch" },
+ { GDK_ISO_Level3_Lock, "ISO_Level3_Lock" },
+ { GDK_ISO_Group_Shift, "ISO_Group_Shift" },
+ { GDK_ISO_Group_Latch, "ISO_Group_Latch" },
+ { GDK_ISO_Group_Lock, "ISO_Group_Lock" },
+ { GDK_ISO_Next_Group, "ISO_Next_Group" },
+ { GDK_ISO_Next_Group_Lock, "ISO_Next_Group_Lock" },
+ { GDK_ISO_Prev_Group, "ISO_Prev_Group" },
+ { GDK_ISO_Prev_Group_Lock, "ISO_Prev_Group_Lock" },
+ { GDK_ISO_First_Group, "ISO_First_Group" },
+ { GDK_ISO_First_Group_Lock, "ISO_First_Group_Lock" },
+ { GDK_ISO_Last_Group, "ISO_Last_Group" },
+ { GDK_ISO_Last_Group_Lock, "ISO_Last_Group_Lock" },
+ { GDK_ISO_Left_Tab, "ISO_Left_Tab" },
+ { GDK_ISO_Move_Line_Up, "ISO_Move_Line_Up" },
+ { GDK_ISO_Move_Line_Down, "ISO_Move_Line_Down" },
+ { GDK_ISO_Partial_Line_Up, "ISO_Partial_Line_Up" },
+ { GDK_ISO_Partial_Line_Down, "ISO_Partial_Line_Down" },
+ { GDK_ISO_Partial_Space_Left, "ISO_Partial_Space_Left" },
+ { GDK_ISO_Partial_Space_Right, "ISO_Partial_Space_Right" },
+ { GDK_ISO_Set_Margin_Left, "ISO_Set_Margin_Left" },
+ { GDK_ISO_Set_Margin_Right, "ISO_Set_Margin_Right" },
+ { GDK_ISO_Release_Margin_Left, "ISO_Release_Margin_Left" },
+ { GDK_ISO_Release_Margin_Right, "ISO_Release_Margin_Right" },
+ { GDK_ISO_Release_Both_Margins, "ISO_Release_Both_Margins" },
+ { GDK_ISO_Fast_Cursor_Left, "ISO_Fast_Cursor_Left" },
+ { GDK_ISO_Fast_Cursor_Right, "ISO_Fast_Cursor_Right" },
+ { GDK_ISO_Fast_Cursor_Up, "ISO_Fast_Cursor_Up" },
+ { GDK_ISO_Fast_Cursor_Down, "ISO_Fast_Cursor_Down" },
+ { GDK_ISO_Continuous_Underline, "ISO_Continuous_Underline" },
+ { GDK_ISO_Discontinuous_Underline, "ISO_Discontinuous_Underline" },
+ { GDK_ISO_Emphasize, "ISO_Emphasize" },
+ { GDK_ISO_Center_Object, "ISO_Center_Object" },
+ { GDK_ISO_Enter, "ISO_Enter" },
+ { GDK_dead_grave, "dead_grave" },
+ { GDK_dead_acute, "dead_acute" },
+ { GDK_dead_circumflex, "dead_circumflex" },
+ { GDK_dead_tilde, "dead_tilde" },
+ { GDK_dead_macron, "dead_macron" },
+ { GDK_dead_breve, "dead_breve" },
+ { GDK_dead_abovedot, "dead_abovedot" },
+ { GDK_dead_diaeresis, "dead_diaeresis" },
+ { GDK_dead_abovering, "dead_abovering" },
+ { GDK_dead_doubleacute, "dead_doubleacute" },
+ { GDK_dead_caron, "dead_caron" },
+ { GDK_dead_cedilla, "dead_cedilla" },
+ { GDK_dead_ogonek, "dead_ogonek" },
+ { GDK_dead_iota, "dead_iota" },
+ { GDK_dead_voiced_sound, "dead_voiced_sound" },
+ { GDK_dead_semivoiced_sound, "dead_semivoiced_sound" },
+ { GDK_dead_belowdot, "dead_belowdot" },
+ { GDK_First_Virtual_Screen, "First_Virtual_Screen" },
+ { GDK_Prev_Virtual_Screen, "Prev_Virtual_Screen" },
+ { GDK_Next_Virtual_Screen, "Next_Virtual_Screen" },
+ { GDK_Last_Virtual_Screen, "Last_Virtual_Screen" },
+ { GDK_Terminate_Server, "Terminate_Server" },
+ { GDK_AccessX_Enable, "AccessX_Enable" },
+ { GDK_AccessX_Feedback_Enable, "AccessX_Feedback_Enable" },
+ { GDK_RepeatKeys_Enable, "RepeatKeys_Enable" },
+ { GDK_SlowKeys_Enable, "SlowKeys_Enable" },
+ { GDK_BounceKeys_Enable, "BounceKeys_Enable" },
+ { GDK_StickyKeys_Enable, "StickyKeys_Enable" },
+ { GDK_MouseKeys_Enable, "MouseKeys_Enable" },
+ { GDK_MouseKeys_Accel_Enable, "MouseKeys_Accel_Enable" },
+ { GDK_Overlay1_Enable, "Overlay1_Enable" },
+ { GDK_Overlay2_Enable, "Overlay2_Enable" },
+ { GDK_AudibleBell_Enable, "AudibleBell_Enable" },
+ { GDK_Pointer_Left, "Pointer_Left" },
+ { GDK_Pointer_Right, "Pointer_Right" },
+ { GDK_Pointer_Up, "Pointer_Up" },
+ { GDK_Pointer_Down, "Pointer_Down" },
+ { GDK_Pointer_UpLeft, "Pointer_UpLeft" },
+ { GDK_Pointer_UpRight, "Pointer_UpRight" },
+ { GDK_Pointer_DownLeft, "Pointer_DownLeft" },
+ { GDK_Pointer_DownRight, "Pointer_DownRight" },
+ { GDK_Pointer_Button_Dflt, "Pointer_Button_Dflt" },
+ { GDK_Pointer_Button1, "Pointer_Button1" },
+ { GDK_Pointer_Button2, "Pointer_Button2" },
+ { GDK_Pointer_Button3, "Pointer_Button3" },
+ { GDK_Pointer_Button4, "Pointer_Button4" },
+ { GDK_Pointer_Button5, "Pointer_Button5" },
+ { GDK_Pointer_DblClick_Dflt, "Pointer_DblClick_Dflt" },
+ { GDK_Pointer_DblClick1, "Pointer_DblClick1" },
+ { GDK_Pointer_DblClick2, "Pointer_DblClick2" },
+ { GDK_Pointer_DblClick3, "Pointer_DblClick3" },
+ { GDK_Pointer_DblClick4, "Pointer_DblClick4" },
+ { GDK_Pointer_DblClick5, "Pointer_DblClick5" },
+ { GDK_Pointer_Drag_Dflt, "Pointer_Drag_Dflt" },
+ { GDK_Pointer_Drag1, "Pointer_Drag1" },
+ { GDK_Pointer_Drag2, "Pointer_Drag2" },
+ { GDK_Pointer_Drag3, "Pointer_Drag3" },
+ { GDK_Pointer_Drag4, "Pointer_Drag4" },
+ { GDK_Pointer_Drag5, "Pointer_Drag5" },
+ { GDK_Pointer_EnableKeys, "Pointer_EnableKeys" },
+ { GDK_Pointer_Accelerate, "Pointer_Accelerate" },
+ { GDK_Pointer_DfltBtnNext, "Pointer_DfltBtnNext" },
+ { GDK_Pointer_DfltBtnPrev, "Pointer_DfltBtnPrev" },
+ { GDK_3270_Duplicate, "3270_Duplicate" },
+ { GDK_3270_FieldMark, "3270_FieldMark" },
+ { GDK_3270_Right2, "3270_Right2" },
+ { GDK_3270_Left2, "3270_Left2" },
+ { GDK_3270_BackTab, "3270_BackTab" },
+ { GDK_3270_EraseEOF, "3270_EraseEOF" },
+ { GDK_3270_EraseInput, "3270_EraseInput" },
+ { GDK_3270_Reset, "3270_Reset" },
+ { GDK_3270_Quit, "3270_Quit" },
+ { GDK_3270_PA1, "3270_PA1" },
+ { GDK_3270_PA2, "3270_PA2" },
+ { GDK_3270_PA3, "3270_PA3" },
+ { GDK_3270_Test, "3270_Test" },
+ { GDK_3270_Attn, "3270_Attn" },
+ { GDK_3270_CursorBlink, "3270_CursorBlink" },
+ { GDK_3270_AltCursor, "3270_AltCursor" },
+ { GDK_3270_KeyClick, "3270_KeyClick" },
+ { GDK_3270_Jump, "3270_Jump" },
+ { GDK_3270_Ident, "3270_Ident" },
+ { GDK_3270_Rule, "3270_Rule" },
+ { GDK_3270_Copy, "3270_Copy" },
+ { GDK_3270_Play, "3270_Play" },
+ { GDK_3270_Setup, "3270_Setup" },
+ { GDK_3270_Record, "3270_Record" },
+ { GDK_3270_ChangeScreen, "3270_ChangeScreen" },
+ { GDK_3270_DeleteWord, "3270_DeleteWord" },
+ { GDK_3270_ExSelect, "3270_ExSelect" },
+ { GDK_3270_CursorSelect, "3270_CursorSelect" },
+ { GDK_3270_PrintScreen, "3270_PrintScreen" },
+ { GDK_3270_Enter, "3270_Enter" },
+ { GDK_exclam, "exclam" },
+ { GDK_quotedbl, "quotedbl" },
+ { GDK_numbersign, "numbersign" },
+ { GDK_dollar, "dollar" },
+ { GDK_percent, "percent" },
+ { GDK_ampersand, "ampersand" },
+ { GDK_apostrophe, "apostrophe" },
+ { GDK_quoteright, "quoteright" },
+ { GDK_parenleft, "parenleft" },
+ { GDK_parenright, "parenright" },
+ { GDK_asterisk, "asterisk" },
+ { GDK_plus, "plus" },
+ { GDK_comma, "comma" },
+ { GDK_minus, "minus" },
+ { GDK_period, "period" },
+ { GDK_slash, "slash" },
+ { GDK_colon, "colon" },
+ { GDK_semicolon, "semicolon" },
+ { GDK_less, "less" },
+ { GDK_equal, "equal" },
+ { GDK_greater, "greater" },
+ { GDK_question, "question" },
+ { GDK_at, "at" },
+ { GDK_bracketleft, "bracketleft" },
+ { GDK_backslash, "backslash" },
+ { GDK_bracketright, "bracketright" },
+ { GDK_asciicircum, "asciicircum" },
+ { GDK_underscore, "underscore" },
+ { GDK_grave, "grave" },
+ { GDK_quoteleft, "quoteleft" },
+ { GDK_braceleft, "braceleft" },
+ { GDK_bar, "bar" },
+ { GDK_braceright, "braceright" },
+ { GDK_asciitilde, "asciitilde" },
+ { GDK_nobreakspace, "nobreakspace" },
+ { GDK_exclamdown, "exclamdown" },
+ { GDK_cent, "cent" },
+ { GDK_sterling, "sterling" },
+ { GDK_currency, "currency" },
+ { GDK_yen, "yen" },
+ { GDK_brokenbar, "brokenbar" },
+ { GDK_section, "section" },
+ { GDK_diaeresis, "diaeresis" },
+ { GDK_copyright, "copyright" },
+ { GDK_ordfeminine, "ordfeminine" },
+ { GDK_guillemotleft, "guillemotleft" },
+ { GDK_notsign, "notsign" },
+ { GDK_hyphen, "hyphen" },
+ { GDK_registered, "registered" },
+ { GDK_macron, "macron" },
+ { GDK_degree, "degree" },
+ { GDK_plusminus, "plusminus" },
+ { GDK_twosuperior, "twosuperior" },
+ { GDK_threesuperior, "threesuperior" },
+ { GDK_acute, "acute" },
+ { GDK_mu, "mu" },
+ { GDK_paragraph, "paragraph" },
+ { GDK_periodcentered, "periodcentered" },
+ { GDK_cedilla, "cedilla" },
+ { GDK_onesuperior, "onesuperior" },
+ { GDK_masculine, "masculine" },
+ { GDK_guillemotright, "guillemotright" },
+ { GDK_onequarter, "onequarter" },
+ { GDK_onehalf, "onehalf" },
+ { GDK_threequarters, "threequarters" },
+ { GDK_questiondown, "questiondown" },
+ { GDK_Agrave, "Agrave" },
+ { GDK_Aacute, "Aacute" },
+ { GDK_Acircumflex, "Acircumflex" },
+ { GDK_Atilde, "Atilde" },
+ { GDK_Adiaeresis, "Adiaeresis" },
+ { GDK_Aring, "Aring" },
+ { GDK_AE, "AE" },
+ { GDK_Ccedilla, "Ccedilla" },
+ { GDK_Egrave, "Egrave" },
+ { GDK_Eacute, "Eacute" },
+ { GDK_Ecircumflex, "Ecircumflex" },
+ { GDK_Ediaeresis, "Ediaeresis" },
+ { GDK_Igrave, "Igrave" },
+ { GDK_Iacute, "Iacute" },
+ { GDK_Icircumflex, "Icircumflex" },
+ { GDK_Idiaeresis, "Idiaeresis" },
+ { GDK_ETH, "ETH" },
+ { GDK_Eth, "Eth" },
+ { GDK_Ntilde, "Ntilde" },
+ { GDK_Ograve, "Ograve" },
+ { GDK_Oacute, "Oacute" },
+ { GDK_Ocircumflex, "Ocircumflex" },
+ { GDK_Otilde, "Otilde" },
+ { GDK_Odiaeresis, "Odiaeresis" },
+ { GDK_multiply, "multiply" },
+ { GDK_Ooblique, "Ooblique" },
+ { GDK_Ugrave, "Ugrave" },
+ { GDK_Uacute, "Uacute" },
+ { GDK_Ucircumflex, "Ucircumflex" },
+ { GDK_Udiaeresis, "Udiaeresis" },
+ { GDK_Yacute, "Yacute" },
+ { GDK_THORN, "THORN" },
+ { GDK_Thorn, "Thorn" },
+ { GDK_ssharp, "ssharp" },
+ { GDK_agrave, "agrave" },
+ { GDK_aacute, "aacute" },
+ { GDK_acircumflex, "acircumflex" },
+ { GDK_atilde, "atilde" },
+ { GDK_adiaeresis, "adiaeresis" },
+ { GDK_aring, "aring" },
+ { GDK_ae, "ae" },
+ { GDK_ccedilla, "ccedilla" },
+ { GDK_egrave, "egrave" },
+ { GDK_eacute, "eacute" },
+ { GDK_ecircumflex, "ecircumflex" },
+ { GDK_ediaeresis, "ediaeresis" },
+ { GDK_igrave, "igrave" },
+ { GDK_iacute, "iacute" },
+ { GDK_icircumflex, "icircumflex" },
+ { GDK_idiaeresis, "idiaeresis" },
+ { GDK_eth, "eth" },
+ { GDK_ntilde, "ntilde" },
+ { GDK_ograve, "ograve" },
+ { GDK_oacute, "oacute" },
+ { GDK_ocircumflex, "ocircumflex" },
+ { GDK_otilde, "otilde" },
+ { GDK_odiaeresis, "odiaeresis" },
+ { GDK_division, "division" },
+ { GDK_oslash, "oslash" },
+ { GDK_ugrave, "ugrave" },
+ { GDK_uacute, "uacute" },
+ { GDK_ucircumflex, "ucircumflex" },
+ { GDK_udiaeresis, "udiaeresis" },
+ { GDK_yacute, "yacute" },
+ { GDK_thorn, "thorn" },
+ { GDK_ydiaeresis, "ydiaeresis" },
+ { GDK_Aogonek, "Aogonek" },
+ { GDK_breve, "breve" },
+ { GDK_Lstroke, "Lstroke" },
+ { GDK_Lcaron, "Lcaron" },
+ { GDK_Sacute, "Sacute" },
+ { GDK_Scaron, "Scaron" },
+ { GDK_Scedilla, "Scedilla" },
+ { GDK_Tcaron, "Tcaron" },
+ { GDK_Zacute, "Zacute" },
+ { GDK_Zcaron, "Zcaron" },
+ { GDK_Zabovedot, "Zabovedot" },
+ { GDK_aogonek, "aogonek" },
+ { GDK_ogonek, "ogonek" },
+ { GDK_lstroke, "lstroke" },
+ { GDK_lcaron, "lcaron" },
+ { GDK_sacute, "sacute" },
+ { GDK_caron, "caron" },
+ { GDK_scaron, "scaron" },
+ { GDK_scedilla, "scedilla" },
+ { GDK_tcaron, "tcaron" },
+ { GDK_zacute, "zacute" },
+ { GDK_doubleacute, "doubleacute" },
+ { GDK_zcaron, "zcaron" },
+ { GDK_zabovedot, "zabovedot" },
+ { GDK_Racute, "Racute" },
+ { GDK_Abreve, "Abreve" },
+ { GDK_Lacute, "Lacute" },
+ { GDK_Cacute, "Cacute" },
+ { GDK_Ccaron, "Ccaron" },
+ { GDK_Eogonek, "Eogonek" },
+ { GDK_Ecaron, "Ecaron" },
+ { GDK_Dcaron, "Dcaron" },
+ { GDK_Dstroke, "Dstroke" },
+ { GDK_Nacute, "Nacute" },
+ { GDK_Ncaron, "Ncaron" },
+ { GDK_Odoubleacute, "Odoubleacute" },
+ { GDK_Rcaron, "Rcaron" },
+ { GDK_Uring, "Uring" },
+ { GDK_Udoubleacute, "Udoubleacute" },
+ { GDK_Tcedilla, "Tcedilla" },
+ { GDK_racute, "racute" },
+ { GDK_abreve, "abreve" },
+ { GDK_lacute, "lacute" },
+ { GDK_cacute, "cacute" },
+ { GDK_ccaron, "ccaron" },
+ { GDK_eogonek, "eogonek" },
+ { GDK_ecaron, "ecaron" },
+ { GDK_dcaron, "dcaron" },
+ { GDK_dstroke, "dstroke" },
+ { GDK_nacute, "nacute" },
+ { GDK_ncaron, "ncaron" },
+ { GDK_odoubleacute, "odoubleacute" },
+ { GDK_udoubleacute, "udoubleacute" },
+ { GDK_rcaron, "rcaron" },
+ { GDK_uring, "uring" },
+ { GDK_tcedilla, "tcedilla" },
+ { GDK_abovedot, "abovedot" },
+ { GDK_Hstroke, "Hstroke" },
+ { GDK_Hcircumflex, "Hcircumflex" },
+ { GDK_Iabovedot, "Iabovedot" },
+ { GDK_Gbreve, "Gbreve" },
+ { GDK_Jcircumflex, "Jcircumflex" },
+ { GDK_hstroke, "hstroke" },
+ { GDK_hcircumflex, "hcircumflex" },
+ { GDK_idotless, "idotless" },
+ { GDK_gbreve, "gbreve" },
+ { GDK_jcircumflex, "jcircumflex" },
+ { GDK_Cabovedot, "Cabovedot" },
+ { GDK_Ccircumflex, "Ccircumflex" },
+ { GDK_Gabovedot, "Gabovedot" },
+ { GDK_Gcircumflex, "Gcircumflex" },
+ { GDK_Ubreve, "Ubreve" },
+ { GDK_Scircumflex, "Scircumflex" },
+ { GDK_cabovedot, "cabovedot" },
+ { GDK_ccircumflex, "ccircumflex" },
+ { GDK_gabovedot, "gabovedot" },
+ { GDK_gcircumflex, "gcircumflex" },
+ { GDK_ubreve, "ubreve" },
+ { GDK_scircumflex, "scircumflex" },
+ { GDK_kra, "kra" },
+ { GDK_kappa, "kappa" },
+ { GDK_Rcedilla, "Rcedilla" },
+ { GDK_Itilde, "Itilde" },
+ { GDK_Lcedilla, "Lcedilla" },
+ { GDK_Emacron, "Emacron" },
+ { GDK_Gcedilla, "Gcedilla" },
+ { GDK_Tslash, "Tslash" },
+ { GDK_rcedilla, "rcedilla" },
+ { GDK_itilde, "itilde" },
+ { GDK_lcedilla, "lcedilla" },
+ { GDK_emacron, "emacron" },
+ { GDK_gcedilla, "gcedilla" },
+ { GDK_tslash, "tslash" },
+ { GDK_ENG, "ENG" },
+ { GDK_eng, "eng" },
+ { GDK_Amacron, "Amacron" },
+ { GDK_Iogonek, "Iogonek" },
+ { GDK_Eabovedot, "Eabovedot" },
+ { GDK_Imacron, "Imacron" },
+ { GDK_Ncedilla, "Ncedilla" },
+ { GDK_Omacron, "Omacron" },
+ { GDK_Kcedilla, "Kcedilla" },
+ { GDK_Uogonek, "Uogonek" },
+ { GDK_Utilde, "Utilde" },
+ { GDK_Umacron, "Umacron" },
+ { GDK_amacron, "amacron" },
+ { GDK_iogonek, "iogonek" },
+ { GDK_eabovedot, "eabovedot" },
+ { GDK_imacron, "imacron" },
+ { GDK_ncedilla, "ncedilla" },
+ { GDK_omacron, "omacron" },
+ { GDK_kcedilla, "kcedilla" },
+ { GDK_uogonek, "uogonek" },
+ { GDK_utilde, "utilde" },
+ { GDK_umacron, "umacron" },
+ { GDK_OE, "OE" },
+ { GDK_oe, "oe" },
+ { GDK_Ydiaeresis, "Ydiaeresis" },
+ { GDK_overline, "overline" },
+ { GDK_kana_fullstop, "kana_fullstop" },
+ { GDK_kana_openingbracket, "kana_openingbracket" },
+ { GDK_kana_closingbracket, "kana_closingbracket" },
+ { GDK_kana_comma, "kana_comma" },
+ { GDK_kana_conjunctive, "kana_conjunctive" },
+ { GDK_kana_middledot, "kana_middledot" },
+ { GDK_kana_WO, "kana_WO" },
+ { GDK_kana_a, "kana_a" },
+ { GDK_kana_i, "kana_i" },
+ { GDK_kana_u, "kana_u" },
+ { GDK_kana_e, "kana_e" },
+ { GDK_kana_o, "kana_o" },
+ { GDK_kana_ya, "kana_ya" },
+ { GDK_kana_yu, "kana_yu" },
+ { GDK_kana_yo, "kana_yo" },
+ { GDK_kana_tsu, "kana_tsu" },
+ { GDK_kana_tu, "kana_tu" },
+ { GDK_prolongedsound, "prolongedsound" },
+ { GDK_kana_A, "kana_A" },
+ { GDK_kana_I, "kana_I" },
+ { GDK_kana_U, "kana_U" },
+ { GDK_kana_E, "kana_E" },
+ { GDK_kana_O, "kana_O" },
+ { GDK_kana_KA, "kana_KA" },
+ { GDK_kana_KI, "kana_KI" },
+ { GDK_kana_KU, "kana_KU" },
+ { GDK_kana_KE, "kana_KE" },
+ { GDK_kana_KO, "kana_KO" },
+ { GDK_kana_SA, "kana_SA" },
+ { GDK_kana_SHI, "kana_SHI" },
+ { GDK_kana_SU, "kana_SU" },
+ { GDK_kana_SE, "kana_SE" },
+ { GDK_kana_SO, "kana_SO" },
+ { GDK_kana_TA, "kana_TA" },
+ { GDK_kana_CHI, "kana_CHI" },
+ { GDK_kana_TI, "kana_TI" },
+ { GDK_kana_TSU, "kana_TSU" },
+ { GDK_kana_TU, "kana_TU" },
+ { GDK_kana_TE, "kana_TE" },
+ { GDK_kana_TO, "kana_TO" },
+ { GDK_kana_NA, "kana_NA" },
+ { GDK_kana_NI, "kana_NI" },
+ { GDK_kana_NU, "kana_NU" },
+ { GDK_kana_NE, "kana_NE" },
+ { GDK_kana_NO, "kana_NO" },
+ { GDK_kana_HA, "kana_HA" },
+ { GDK_kana_HI, "kana_HI" },
+ { GDK_kana_FU, "kana_FU" },
+ { GDK_kana_HU, "kana_HU" },
+ { GDK_kana_HE, "kana_HE" },
+ { GDK_kana_HO, "kana_HO" },
+ { GDK_kana_MA, "kana_MA" },
+ { GDK_kana_MI, "kana_MI" },
+ { GDK_kana_MU, "kana_MU" },
+ { GDK_kana_ME, "kana_ME" },
+ { GDK_kana_MO, "kana_MO" },
+ { GDK_kana_YA, "kana_YA" },
+ { GDK_kana_YU, "kana_YU" },
+ { GDK_kana_YO, "kana_YO" },
+ { GDK_kana_RA, "kana_RA" },
+ { GDK_kana_RI, "kana_RI" },
+ { GDK_kana_RU, "kana_RU" },
+ { GDK_kana_RE, "kana_RE" },
+ { GDK_kana_RO, "kana_RO" },
+ { GDK_kana_WA, "kana_WA" },
+ { GDK_kana_N, "kana_N" },
+ { GDK_voicedsound, "voicedsound" },
+ { GDK_semivoicedsound, "semivoicedsound" },
+ { GDK_kana_switch, "kana_switch" },
+ { GDK_Arabic_comma, "Arabic_comma" },
+ { GDK_Arabic_semicolon, "Arabic_semicolon" },
+ { GDK_Arabic_question_mark, "Arabic_question_mark" },
+ { GDK_Arabic_hamza, "Arabic_hamza" },
+ { GDK_Arabic_maddaonalef, "Arabic_maddaonalef" },
+ { GDK_Arabic_hamzaonalef, "Arabic_hamzaonalef" },
+ { GDK_Arabic_hamzaonwaw, "Arabic_hamzaonwaw" },
+ { GDK_Arabic_hamzaunderalef, "Arabic_hamzaunderalef" },
+ { GDK_Arabic_hamzaonyeh, "Arabic_hamzaonyeh" },
+ { GDK_Arabic_alef, "Arabic_alef" },
+ { GDK_Arabic_beh, "Arabic_beh" },
+ { GDK_Arabic_tehmarbuta, "Arabic_tehmarbuta" },
+ { GDK_Arabic_teh, "Arabic_teh" },
+ { GDK_Arabic_theh, "Arabic_theh" },
+ { GDK_Arabic_jeem, "Arabic_jeem" },
+ { GDK_Arabic_hah, "Arabic_hah" },
+ { GDK_Arabic_khah, "Arabic_khah" },
+ { GDK_Arabic_dal, "Arabic_dal" },
+ { GDK_Arabic_thal, "Arabic_thal" },
+ { GDK_Arabic_ra, "Arabic_ra" },
+ { GDK_Arabic_zain, "Arabic_zain" },
+ { GDK_Arabic_seen, "Arabic_seen" },
+ { GDK_Arabic_sheen, "Arabic_sheen" },
+ { GDK_Arabic_sad, "Arabic_sad" },
+ { GDK_Arabic_dad, "Arabic_dad" },
+ { GDK_Arabic_tah, "Arabic_tah" },
+ { GDK_Arabic_zah, "Arabic_zah" },
+ { GDK_Arabic_ain, "Arabic_ain" },
+ { GDK_Arabic_ghain, "Arabic_ghain" },
+ { GDK_Arabic_tatweel, "Arabic_tatweel" },
+ { GDK_Arabic_feh, "Arabic_feh" },
+ { GDK_Arabic_qaf, "Arabic_qaf" },
+ { GDK_Arabic_kaf, "Arabic_kaf" },
+ { GDK_Arabic_lam, "Arabic_lam" },
+ { GDK_Arabic_meem, "Arabic_meem" },
+ { GDK_Arabic_noon, "Arabic_noon" },
+ { GDK_Arabic_ha, "Arabic_ha" },
+ { GDK_Arabic_heh, "Arabic_heh" },
+ { GDK_Arabic_waw, "Arabic_waw" },
+ { GDK_Arabic_alefmaksura, "Arabic_alefmaksura" },
+ { GDK_Arabic_yeh, "Arabic_yeh" },
+ { GDK_Arabic_fathatan, "Arabic_fathatan" },
+ { GDK_Arabic_dammatan, "Arabic_dammatan" },
+ { GDK_Arabic_kasratan, "Arabic_kasratan" },
+ { GDK_Arabic_fatha, "Arabic_fatha" },
+ { GDK_Arabic_damma, "Arabic_damma" },
+ { GDK_Arabic_kasra, "Arabic_kasra" },
+ { GDK_Arabic_shadda, "Arabic_shadda" },
+ { GDK_Arabic_sukun, "Arabic_sukun" },
+ { GDK_Arabic_switch, "Arabic_switch" },
+ { GDK_Serbian_dje, "Serbian_dje" },
+ { GDK_Macedonia_gje, "Macedonia_gje" },
+ { GDK_Cyrillic_io, "Cyrillic_io" },
+ { GDK_Ukrainian_ie, "Ukrainian_ie" },
+ { GDK_Ukranian_je, "Ukranian_je" },
+ { GDK_Macedonia_dse, "Macedonia_dse" },
+ { GDK_Ukrainian_i, "Ukrainian_i" },
+ { GDK_Ukranian_i, "Ukranian_i" },
+ { GDK_Ukrainian_yi, "Ukrainian_yi" },
+ { GDK_Ukranian_yi, "Ukranian_yi" },
+ { GDK_Cyrillic_je, "Cyrillic_je" },
+ { GDK_Serbian_je, "Serbian_je" },
+ { GDK_Cyrillic_lje, "Cyrillic_lje" },
+ { GDK_Serbian_lje, "Serbian_lje" },
+ { GDK_Cyrillic_nje, "Cyrillic_nje" },
+ { GDK_Serbian_nje, "Serbian_nje" },
+ { GDK_Serbian_tshe, "Serbian_tshe" },
+ { GDK_Macedonia_kje, "Macedonia_kje" },
+ { GDK_Byelorussian_shortu, "Byelorussian_shortu" },
+ { GDK_Cyrillic_dzhe, "Cyrillic_dzhe" },
+ { GDK_Serbian_dze, "Serbian_dze" },
+ { GDK_numerosign, "numerosign" },
+ { GDK_Serbian_DJE, "Serbian_DJE" },
+ { GDK_Macedonia_GJE, "Macedonia_GJE" },
+ { GDK_Cyrillic_IO, "Cyrillic_IO" },
+ { GDK_Ukrainian_IE, "Ukrainian_IE" },
+ { GDK_Ukranian_JE, "Ukranian_JE" },
+ { GDK_Macedonia_DSE, "Macedonia_DSE" },
+ { GDK_Ukrainian_I, "Ukrainian_I" },
+ { GDK_Ukranian_I, "Ukranian_I" },
+ { GDK_Ukrainian_YI, "Ukrainian_YI" },
+ { GDK_Ukranian_YI, "Ukranian_YI" },
+ { GDK_Cyrillic_JE, "Cyrillic_JE" },
+ { GDK_Serbian_JE, "Serbian_JE" },
+ { GDK_Cyrillic_LJE, "Cyrillic_LJE" },
+ { GDK_Serbian_LJE, "Serbian_LJE" },
+ { GDK_Cyrillic_NJE, "Cyrillic_NJE" },
+ { GDK_Serbian_NJE, "Serbian_NJE" },
+ { GDK_Serbian_TSHE, "Serbian_TSHE" },
+ { GDK_Macedonia_KJE, "Macedonia_KJE" },
+ { GDK_Byelorussian_SHORTU, "Byelorussian_SHORTU" },
+ { GDK_Cyrillic_DZHE, "Cyrillic_DZHE" },
+ { GDK_Serbian_DZE, "Serbian_DZE" },
+ { GDK_Cyrillic_yu, "Cyrillic_yu" },
+ { GDK_Cyrillic_a, "Cyrillic_a" },
+ { GDK_Cyrillic_be, "Cyrillic_be" },
+ { GDK_Cyrillic_tse, "Cyrillic_tse" },
+ { GDK_Cyrillic_de, "Cyrillic_de" },
+ { GDK_Cyrillic_ie, "Cyrillic_ie" },
+ { GDK_Cyrillic_ef, "Cyrillic_ef" },
+ { GDK_Cyrillic_ghe, "Cyrillic_ghe" },
+ { GDK_Cyrillic_ha, "Cyrillic_ha" },
+ { GDK_Cyrillic_i, "Cyrillic_i" },
+ { GDK_Cyrillic_shorti, "Cyrillic_shorti" },
+ { GDK_Cyrillic_ka, "Cyrillic_ka" },
+ { GDK_Cyrillic_el, "Cyrillic_el" },
+ { GDK_Cyrillic_em, "Cyrillic_em" },
+ { GDK_Cyrillic_en, "Cyrillic_en" },
+ { GDK_Cyrillic_o, "Cyrillic_o" },
+ { GDK_Cyrillic_pe, "Cyrillic_pe" },
+ { GDK_Cyrillic_ya, "Cyrillic_ya" },
+ { GDK_Cyrillic_er, "Cyrillic_er" },
+ { GDK_Cyrillic_es, "Cyrillic_es" },
+ { GDK_Cyrillic_te, "Cyrillic_te" },
+ { GDK_Cyrillic_u, "Cyrillic_u" },
+ { GDK_Cyrillic_zhe, "Cyrillic_zhe" },
+ { GDK_Cyrillic_ve, "Cyrillic_ve" },
+ { GDK_Cyrillic_softsign, "Cyrillic_softsign" },
+ { GDK_Cyrillic_yeru, "Cyrillic_yeru" },
+ { GDK_Cyrillic_ze, "Cyrillic_ze" },
+ { GDK_Cyrillic_sha, "Cyrillic_sha" },
+ { GDK_Cyrillic_e, "Cyrillic_e" },
+ { GDK_Cyrillic_shcha, "Cyrillic_shcha" },
+ { GDK_Cyrillic_che, "Cyrillic_che" },
+ { GDK_Cyrillic_hardsign, "Cyrillic_hardsign" },
+ { GDK_Cyrillic_YU, "Cyrillic_YU" },
+ { GDK_Cyrillic_A, "Cyrillic_A" },
+ { GDK_Cyrillic_BE, "Cyrillic_BE" },
+ { GDK_Cyrillic_TSE, "Cyrillic_TSE" },
+ { GDK_Cyrillic_DE, "Cyrillic_DE" },
+ { GDK_Cyrillic_IE, "Cyrillic_IE" },
+ { GDK_Cyrillic_EF, "Cyrillic_EF" },
+ { GDK_Cyrillic_GHE, "Cyrillic_GHE" },
+ { GDK_Cyrillic_HA, "Cyrillic_HA" },
+ { GDK_Cyrillic_I, "Cyrillic_I" },
+ { GDK_Cyrillic_SHORTI, "Cyrillic_SHORTI" },
+ { GDK_Cyrillic_KA, "Cyrillic_KA" },
+ { GDK_Cyrillic_EL, "Cyrillic_EL" },
+ { GDK_Cyrillic_EM, "Cyrillic_EM" },
+ { GDK_Cyrillic_EN, "Cyrillic_EN" },
+ { GDK_Cyrillic_O, "Cyrillic_O" },
+ { GDK_Cyrillic_PE, "Cyrillic_PE" },
+ { GDK_Cyrillic_YA, "Cyrillic_YA" },
+ { GDK_Cyrillic_ER, "Cyrillic_ER" },
+ { GDK_Cyrillic_ES, "Cyrillic_ES" },
+ { GDK_Cyrillic_TE, "Cyrillic_TE" },
+ { GDK_Cyrillic_U, "Cyrillic_U" },
+ { GDK_Cyrillic_ZHE, "Cyrillic_ZHE" },
+ { GDK_Cyrillic_VE, "Cyrillic_VE" },
+ { GDK_Cyrillic_SOFTSIGN, "Cyrillic_SOFTSIGN" },
+ { GDK_Cyrillic_YERU, "Cyrillic_YERU" },
+ { GDK_Cyrillic_ZE, "Cyrillic_ZE" },
+ { GDK_Cyrillic_SHA, "Cyrillic_SHA" },
+ { GDK_Cyrillic_E, "Cyrillic_E" },
+ { GDK_Cyrillic_SHCHA, "Cyrillic_SHCHA" },
+ { GDK_Cyrillic_CHE, "Cyrillic_CHE" },
+ { GDK_Cyrillic_HARDSIGN, "Cyrillic_HARDSIGN" },
+ { GDK_Greek_ALPHAaccent, "Greek_ALPHAaccent" },
+ { GDK_Greek_EPSILONaccent, "Greek_EPSILONaccent" },
+ { GDK_Greek_ETAaccent, "Greek_ETAaccent" },
+ { GDK_Greek_IOTAaccent, "Greek_IOTAaccent" },
+ { GDK_Greek_IOTAdiaeresis, "Greek_IOTAdiaeresis" },
+ { GDK_Greek_OMICRONaccent, "Greek_OMICRONaccent" },
+ { GDK_Greek_UPSILONaccent, "Greek_UPSILONaccent" },
+ { GDK_Greek_UPSILONdieresis, "Greek_UPSILONdieresis" },
+ { GDK_Greek_OMEGAaccent, "Greek_OMEGAaccent" },
+ { GDK_Greek_accentdieresis, "Greek_accentdieresis" },
+ { GDK_Greek_horizbar, "Greek_horizbar" },
+ { GDK_Greek_alphaaccent, "Greek_alphaaccent" },
+ { GDK_Greek_epsilonaccent, "Greek_epsilonaccent" },
+ { GDK_Greek_etaaccent, "Greek_etaaccent" },
+ { GDK_Greek_iotaaccent, "Greek_iotaaccent" },
+ { GDK_Greek_iotadieresis, "Greek_iotadieresis" },
+ { GDK_Greek_iotaaccentdieresis, "Greek_iotaaccentdieresis" },
+ { GDK_Greek_omicronaccent, "Greek_omicronaccent" },
+ { GDK_Greek_upsilonaccent, "Greek_upsilonaccent" },
+ { GDK_Greek_upsilondieresis, "Greek_upsilondieresis" },
+ { GDK_Greek_upsilonaccentdieresis, "Greek_upsilonaccentdieresis" },
+ { GDK_Greek_omegaaccent, "Greek_omegaaccent" },
+ { GDK_Greek_ALPHA, "Greek_ALPHA" },
+ { GDK_Greek_BETA, "Greek_BETA" },
+ { GDK_Greek_GAMMA, "Greek_GAMMA" },
+ { GDK_Greek_DELTA, "Greek_DELTA" },
+ { GDK_Greek_EPSILON, "Greek_EPSILON" },
+ { GDK_Greek_ZETA, "Greek_ZETA" },
+ { GDK_Greek_ETA, "Greek_ETA" },
+ { GDK_Greek_THETA, "Greek_THETA" },
+ { GDK_Greek_IOTA, "Greek_IOTA" },
+ { GDK_Greek_KAPPA, "Greek_KAPPA" },
+ { GDK_Greek_LAMDA, "Greek_LAMDA" },
+ { GDK_Greek_LAMBDA, "Greek_LAMBDA" },
+ { GDK_Greek_MU, "Greek_MU" },
+ { GDK_Greek_NU, "Greek_NU" },
+ { GDK_Greek_XI, "Greek_XI" },
+ { GDK_Greek_OMICRON, "Greek_OMICRON" },
+ { GDK_Greek_PI, "Greek_PI" },
+ { GDK_Greek_RHO, "Greek_RHO" },
+ { GDK_Greek_SIGMA, "Greek_SIGMA" },
+ { GDK_Greek_TAU, "Greek_TAU" },
+ { GDK_Greek_UPSILON, "Greek_UPSILON" },
+ { GDK_Greek_PHI, "Greek_PHI" },
+ { GDK_Greek_CHI, "Greek_CHI" },
+ { GDK_Greek_PSI, "Greek_PSI" },
+ { GDK_Greek_OMEGA, "Greek_OMEGA" },
+ { GDK_Greek_alpha, "Greek_alpha" },
+ { GDK_Greek_beta, "Greek_beta" },
+ { GDK_Greek_gamma, "Greek_gamma" },
+ { GDK_Greek_delta, "Greek_delta" },
+ { GDK_Greek_epsilon, "Greek_epsilon" },
+ { GDK_Greek_zeta, "Greek_zeta" },
+ { GDK_Greek_eta, "Greek_eta" },
+ { GDK_Greek_theta, "Greek_theta" },
+ { GDK_Greek_iota, "Greek_iota" },
+ { GDK_Greek_kappa, "Greek_kappa" },
+ { GDK_Greek_lamda, "Greek_lamda" },
+ { GDK_Greek_lambda, "Greek_lambda" },
+ { GDK_Greek_mu, "Greek_mu" },
+ { GDK_Greek_nu, "Greek_nu" },
+ { GDK_Greek_xi, "Greek_xi" },
+ { GDK_Greek_omicron, "Greek_omicron" },
+ { GDK_Greek_pi, "Greek_pi" },
+ { GDK_Greek_rho, "Greek_rho" },
+ { GDK_Greek_sigma, "Greek_sigma" },
+ { GDK_Greek_finalsmallsigma, "Greek_finalsmallsigma" },
+ { GDK_Greek_tau, "Greek_tau" },
+ { GDK_Greek_upsilon, "Greek_upsilon" },
+ { GDK_Greek_phi, "Greek_phi" },
+ { GDK_Greek_chi, "Greek_chi" },
+ { GDK_Greek_psi, "Greek_psi" },
+ { GDK_Greek_omega, "Greek_omega" },
+ { GDK_Greek_switch, "Greek_switch" },
+ { GDK_leftradical, "leftradical" },
+ { GDK_topleftradical, "topleftradical" },
+ { GDK_horizconnector, "horizconnector" },
+ { GDK_topintegral, "topintegral" },
+ { GDK_botintegral, "botintegral" },
+ { GDK_vertconnector, "vertconnector" },
+ { GDK_topleftsqbracket, "topleftsqbracket" },
+ { GDK_botleftsqbracket, "botleftsqbracket" },
+ { GDK_toprightsqbracket, "toprightsqbracket" },
+ { GDK_botrightsqbracket, "botrightsqbracket" },
+ { GDK_topleftparens, "topleftparens" },
+ { GDK_botleftparens, "botleftparens" },
+ { GDK_toprightparens, "toprightparens" },
+ { GDK_botrightparens, "botrightparens" },
+ { GDK_leftmiddlecurlybrace, "leftmiddlecurlybrace" },
+ { GDK_rightmiddlecurlybrace, "rightmiddlecurlybrace" },
+ { GDK_topleftsummation, "topleftsummation" },
+ { GDK_botleftsummation, "botleftsummation" },
+ { GDK_topvertsummationconnector, "topvertsummationconnector" },
+ { GDK_botvertsummationconnector, "botvertsummationconnector" },
+ { GDK_toprightsummation, "toprightsummation" },
+ { GDK_botrightsummation, "botrightsummation" },
+ { GDK_rightmiddlesummation, "rightmiddlesummation" },
+ { GDK_lessthanequal, "lessthanequal" },
+ { GDK_notequal, "notequal" },
+ { GDK_greaterthanequal, "greaterthanequal" },
+ { GDK_integral, "integral" },
+ { GDK_therefore, "therefore" },
+ { GDK_variation, "variation" },
+ { GDK_infinity, "infinity" },
+ { GDK_nabla, "nabla" },
+ { GDK_approximate, "approximate" },
+ { GDK_similarequal, "similarequal" },
+ { GDK_ifonlyif, "ifonlyif" },
+ { GDK_implies, "implies" },
+ { GDK_identical, "identical" },
+ { GDK_radical, "radical" },
+ { GDK_includedin, "includedin" },
+ { GDK_includes, "includes" },
+ { GDK_intersection, "intersection" },
+ { GDK_union, "union" },
+ { GDK_logicaland, "logicaland" },
+ { GDK_logicalor, "logicalor" },
+ { GDK_partialderivative, "partialderivative" },
+ { GDK_function, "function" },
+ { GDK_leftarrow, "leftarrow" },
+ { GDK_uparrow, "uparrow" },
+ { GDK_rightarrow, "rightarrow" },
+ { GDK_downarrow, "downarrow" },
+ { GDK_blank, "blank" },
+ { GDK_soliddiamond, "soliddiamond" },
+ { GDK_checkerboard, "checkerboard" },
+ { GDK_ht, "ht" },
+ { GDK_ff, "ff" },
+ { GDK_cr, "cr" },
+ { GDK_lf, "lf" },
+ { GDK_nl, "nl" },
+ { GDK_vt, "vt" },
+ { GDK_lowrightcorner, "lowrightcorner" },
+ { GDK_uprightcorner, "uprightcorner" },
+ { GDK_upleftcorner, "upleftcorner" },
+ { GDK_lowleftcorner, "lowleftcorner" },
+ { GDK_crossinglines, "crossinglines" },
+ { GDK_horizlinescan1, "horizlinescan1" },
+ { GDK_horizlinescan3, "horizlinescan3" },
+ { GDK_horizlinescan5, "horizlinescan5" },
+ { GDK_horizlinescan7, "horizlinescan7" },
+ { GDK_horizlinescan9, "horizlinescan9" },
+ { GDK_leftt, "leftt" },
+ { GDK_rightt, "rightt" },
+ { GDK_bott, "bott" },
+ { GDK_topt, "topt" },
+ { GDK_vertbar, "vertbar" },
+ { GDK_emspace, "emspace" },
+ { GDK_enspace, "enspace" },
+ { GDK_em3space, "em3space" },
+ { GDK_em4space, "em4space" },
+ { GDK_digitspace, "digitspace" },
+ { GDK_punctspace, "punctspace" },
+ { GDK_thinspace, "thinspace" },
+ { GDK_hairspace, "hairspace" },
+ { GDK_emdash, "emdash" },
+ { GDK_endash, "endash" },
+ { GDK_signifblank, "signifblank" },
+ { GDK_ellipsis, "ellipsis" },
+ { GDK_doubbaselinedot, "doubbaselinedot" },
+ { GDK_onethird, "onethird" },
+ { GDK_twothirds, "twothirds" },
+ { GDK_onefifth, "onefifth" },
+ { GDK_twofifths, "twofifths" },
+ { GDK_threefifths, "threefifths" },
+ { GDK_fourfifths, "fourfifths" },
+ { GDK_onesixth, "onesixth" },
+ { GDK_fivesixths, "fivesixths" },
+ { GDK_careof, "careof" },
+ { GDK_figdash, "figdash" },
+ { GDK_leftanglebracket, "leftanglebracket" },
+ { GDK_decimalpoint, "decimalpoint" },
+ { GDK_rightanglebracket, "rightanglebracket" },
+ { GDK_marker, "marker" },
+ { GDK_oneeighth, "oneeighth" },
+ { GDK_threeeighths, "threeeighths" },
+ { GDK_fiveeighths, "fiveeighths" },
+ { GDK_seveneighths, "seveneighths" },
+ { GDK_trademark, "trademark" },
+ { GDK_signaturemark, "signaturemark" },
+ { GDK_trademarkincircle, "trademarkincircle" },
+ { GDK_leftopentriangle, "leftopentriangle" },
+ { GDK_rightopentriangle, "rightopentriangle" },
+ { GDK_emopencircle, "emopencircle" },
+ { GDK_emopenrectangle, "emopenrectangle" },
+ { GDK_leftsinglequotemark, "leftsinglequotemark" },
+ { GDK_rightsinglequotemark, "rightsinglequotemark" },
+ { GDK_leftdoublequotemark, "leftdoublequotemark" },
+ { GDK_rightdoublequotemark, "rightdoublequotemark" },
+ { GDK_prescription, "prescription" },
+ { GDK_minutes, "minutes" },
+ { GDK_seconds, "seconds" },
+ { GDK_latincross, "latincross" },
+ { GDK_hexagram, "hexagram" },
+ { GDK_filledrectbullet, "filledrectbullet" },
+ { GDK_filledlefttribullet, "filledlefttribullet" },
+ { GDK_filledrighttribullet, "filledrighttribullet" },
+ { GDK_emfilledcircle, "emfilledcircle" },
+ { GDK_emfilledrect, "emfilledrect" },
+ { GDK_enopencircbullet, "enopencircbullet" },
+ { GDK_enopensquarebullet, "enopensquarebullet" },
+ { GDK_openrectbullet, "openrectbullet" },
+ { GDK_opentribulletup, "opentribulletup" },
+ { GDK_opentribulletdown, "opentribulletdown" },
+ { GDK_openstar, "openstar" },
+ { GDK_enfilledcircbullet, "enfilledcircbullet" },
+ { GDK_enfilledsqbullet, "enfilledsqbullet" },
+ { GDK_filledtribulletup, "filledtribulletup" },
+ { GDK_filledtribulletdown, "filledtribulletdown" },
+ { GDK_leftpointer, "leftpointer" },
+ { GDK_rightpointer, "rightpointer" },
+ { GDK_club, "club" },
+ { GDK_diamond, "diamond" },
+ { GDK_heart, "heart" },
+ { GDK_maltesecross, "maltesecross" },
+ { GDK_dagger, "dagger" },
+ { GDK_doubledagger, "doubledagger" },
+ { GDK_checkmark, "checkmark" },
+ { GDK_ballotcross, "ballotcross" },
+ { GDK_musicalsharp, "musicalsharp" },
+ { GDK_musicalflat, "musicalflat" },
+ { GDK_malesymbol, "malesymbol" },
+ { GDK_femalesymbol, "femalesymbol" },
+ { GDK_telephone, "telephone" },
+ { GDK_telephonerecorder, "telephonerecorder" },
+ { GDK_phonographcopyright, "phonographcopyright" },
+ { GDK_caret, "caret" },
+ { GDK_singlelowquotemark, "singlelowquotemark" },
+ { GDK_doublelowquotemark, "doublelowquotemark" },
+ { GDK_cursor, "cursor" },
+ { GDK_leftcaret, "leftcaret" },
+ { GDK_rightcaret, "rightcaret" },
+ { GDK_downcaret, "downcaret" },
+ { GDK_upcaret, "upcaret" },
+ { GDK_overbar, "overbar" },
+ { GDK_downtack, "downtack" },
+ { GDK_upshoe, "upshoe" },
+ { GDK_downstile, "downstile" },
+ { GDK_underbar, "underbar" },
+ { GDK_jot, "jot" },
+ { GDK_quad, "quad" },
+ { GDK_uptack, "uptack" },
+ { GDK_circle, "circle" },
+ { GDK_upstile, "upstile" },
+ { GDK_downshoe, "downshoe" },
+ { GDK_rightshoe, "rightshoe" },
+ { GDK_leftshoe, "leftshoe" },
+ { GDK_lefttack, "lefttack" },
+ { GDK_righttack, "righttack" },
+ { GDK_hebrew_doublelowline, "hebrew_doublelowline" },
+ { GDK_hebrew_aleph, "hebrew_aleph" },
+ { GDK_hebrew_bet, "hebrew_bet" },
+ { GDK_hebrew_beth, "hebrew_beth" },
+ { GDK_hebrew_gimel, "hebrew_gimel" },
+ { GDK_hebrew_gimmel, "hebrew_gimmel" },
+ { GDK_hebrew_dalet, "hebrew_dalet" },
+ { GDK_hebrew_daleth, "hebrew_daleth" },
+ { GDK_hebrew_he, "hebrew_he" },
+ { GDK_hebrew_waw, "hebrew_waw" },
+ { GDK_hebrew_zain, "hebrew_zain" },
+ { GDK_hebrew_zayin, "hebrew_zayin" },
+ { GDK_hebrew_chet, "hebrew_chet" },
+ { GDK_hebrew_het, "hebrew_het" },
+ { GDK_hebrew_tet, "hebrew_tet" },
+ { GDK_hebrew_teth, "hebrew_teth" },
+ { GDK_hebrew_yod, "hebrew_yod" },
+ { GDK_hebrew_finalkaph, "hebrew_finalkaph" },
+ { GDK_hebrew_kaph, "hebrew_kaph" },
+ { GDK_hebrew_lamed, "hebrew_lamed" },
+ { GDK_hebrew_finalmem, "hebrew_finalmem" },
+ { GDK_hebrew_mem, "hebrew_mem" },
+ { GDK_hebrew_finalnun, "hebrew_finalnun" },
+ { GDK_hebrew_nun, "hebrew_nun" },
+ { GDK_hebrew_samech, "hebrew_samech" },
+ { GDK_hebrew_samekh, "hebrew_samekh" },
+ { GDK_hebrew_ayin, "hebrew_ayin" },
+ { GDK_hebrew_finalpe, "hebrew_finalpe" },
+ { GDK_hebrew_pe, "hebrew_pe" },
+ { GDK_hebrew_finalzade, "hebrew_finalzade" },
+ { GDK_hebrew_finalzadi, "hebrew_finalzadi" },
+ { GDK_hebrew_zade, "hebrew_zade" },
+ { GDK_hebrew_zadi, "hebrew_zadi" },
+ { GDK_hebrew_qoph, "hebrew_qoph" },
+ { GDK_hebrew_kuf, "hebrew_kuf" },
+ { GDK_hebrew_resh, "hebrew_resh" },
+ { GDK_hebrew_shin, "hebrew_shin" },
+ { GDK_hebrew_taw, "hebrew_taw" },
+ { GDK_hebrew_taf, "hebrew_taf" },
+ { GDK_Hebrew_switch, "Hebrew_switch" },
+ { GDK_Thai_kokai, "Thai_kokai" },
+ { GDK_Thai_khokhai, "Thai_khokhai" },
+ { GDK_Thai_khokhuat, "Thai_khokhuat" },
+ { GDK_Thai_khokhwai, "Thai_khokhwai" },
+ { GDK_Thai_khokhon, "Thai_khokhon" },
+ { GDK_Thai_khorakhang, "Thai_khorakhang" },
+ { GDK_Thai_ngongu, "Thai_ngongu" },
+ { GDK_Thai_chochan, "Thai_chochan" },
+ { GDK_Thai_choching, "Thai_choching" },
+ { GDK_Thai_chochang, "Thai_chochang" },
+ { GDK_Thai_soso, "Thai_soso" },
+ { GDK_Thai_chochoe, "Thai_chochoe" },
+ { GDK_Thai_yoying, "Thai_yoying" },
+ { GDK_Thai_dochada, "Thai_dochada" },
+ { GDK_Thai_topatak, "Thai_topatak" },
+ { GDK_Thai_thothan, "Thai_thothan" },
+ { GDK_Thai_thonangmontho, "Thai_thonangmontho" },
+ { GDK_Thai_thophuthao, "Thai_thophuthao" },
+ { GDK_Thai_nonen, "Thai_nonen" },
+ { GDK_Thai_dodek, "Thai_dodek" },
+ { GDK_Thai_totao, "Thai_totao" },
+ { GDK_Thai_thothung, "Thai_thothung" },
+ { GDK_Thai_thothahan, "Thai_thothahan" },
+ { GDK_Thai_thothong, "Thai_thothong" },
+ { GDK_Thai_nonu, "Thai_nonu" },
+ { GDK_Thai_bobaimai, "Thai_bobaimai" },
+ { GDK_Thai_popla, "Thai_popla" },
+ { GDK_Thai_phophung, "Thai_phophung" },
+ { GDK_Thai_fofa, "Thai_fofa" },
+ { GDK_Thai_phophan, "Thai_phophan" },
+ { GDK_Thai_fofan, "Thai_fofan" },
+ { GDK_Thai_phosamphao, "Thai_phosamphao" },
+ { GDK_Thai_moma, "Thai_moma" },
+ { GDK_Thai_yoyak, "Thai_yoyak" },
+ { GDK_Thai_rorua, "Thai_rorua" },
+ { GDK_Thai_ru, "Thai_ru" },
+ { GDK_Thai_loling, "Thai_loling" },
+ { GDK_Thai_lu, "Thai_lu" },
+ { GDK_Thai_wowaen, "Thai_wowaen" },
+ { GDK_Thai_sosala, "Thai_sosala" },
+ { GDK_Thai_sorusi, "Thai_sorusi" },
+ { GDK_Thai_sosua, "Thai_sosua" },
+ { GDK_Thai_hohip, "Thai_hohip" },
+ { GDK_Thai_lochula, "Thai_lochula" },
+ { GDK_Thai_oang, "Thai_oang" },
+ { GDK_Thai_honokhuk, "Thai_honokhuk" },
+ { GDK_Thai_paiyannoi, "Thai_paiyannoi" },
+ { GDK_Thai_saraa, "Thai_saraa" },
+ { GDK_Thai_maihanakat, "Thai_maihanakat" },
+ { GDK_Thai_saraaa, "Thai_saraaa" },
+ { GDK_Thai_saraam, "Thai_saraam" },
+ { GDK_Thai_sarai, "Thai_sarai" },
+ { GDK_Thai_saraii, "Thai_saraii" },
+ { GDK_Thai_saraue, "Thai_saraue" },
+ { GDK_Thai_sarauee, "Thai_sarauee" },
+ { GDK_Thai_sarau, "Thai_sarau" },
+ { GDK_Thai_sarauu, "Thai_sarauu" },
+ { GDK_Thai_phinthu, "Thai_phinthu" },
+ { GDK_Thai_maihanakat_maitho, "Thai_maihanakat_maitho" },
+ { GDK_Thai_baht, "Thai_baht" },
+ { GDK_Thai_sarae, "Thai_sarae" },
+ { GDK_Thai_saraae, "Thai_saraae" },
+ { GDK_Thai_sarao, "Thai_sarao" },
+ { GDK_Thai_saraaimaimuan, "Thai_saraaimaimuan" },
+ { GDK_Thai_saraaimaimalai, "Thai_saraaimaimalai" },
+ { GDK_Thai_lakkhangyao, "Thai_lakkhangyao" },
+ { GDK_Thai_maiyamok, "Thai_maiyamok" },
+ { GDK_Thai_maitaikhu, "Thai_maitaikhu" },
+ { GDK_Thai_maiek, "Thai_maiek" },
+ { GDK_Thai_maitho, "Thai_maitho" },
+ { GDK_Thai_maitri, "Thai_maitri" },
+ { GDK_Thai_maichattawa, "Thai_maichattawa" },
+ { GDK_Thai_thanthakhat, "Thai_thanthakhat" },
+ { GDK_Thai_nikhahit, "Thai_nikhahit" },
+ { GDK_Thai_leksun, "Thai_leksun" },
+ { GDK_Thai_leknung, "Thai_leknung" },
+ { GDK_Thai_leksong, "Thai_leksong" },
+ { GDK_Thai_leksam, "Thai_leksam" },
+ { GDK_Thai_leksi, "Thai_leksi" },
+ { GDK_Thai_lekha, "Thai_lekha" },
+ { GDK_Thai_lekhok, "Thai_lekhok" },
+ { GDK_Thai_lekchet, "Thai_lekchet" },
+ { GDK_Thai_lekpaet, "Thai_lekpaet" },
+ { GDK_Thai_lekkao, "Thai_lekkao" },
+ { GDK_Hangul, "Hangul" },
+ { GDK_Hangul_Start, "Hangul_Start" },
+ { GDK_Hangul_End, "Hangul_End" },
+ { GDK_Hangul_Hanja, "Hangul_Hanja" },
+ { GDK_Hangul_Jamo, "Hangul_Jamo" },
+ { GDK_Hangul_Romaja, "Hangul_Romaja" },
+ { GDK_Hangul_Codeinput, "Hangul_Codeinput" },
+ { GDK_Hangul_Jeonja, "Hangul_Jeonja" },
+ { GDK_Hangul_Banja, "Hangul_Banja" },
+ { GDK_Hangul_PreHanja, "Hangul_PreHanja" },
+ { GDK_Hangul_PostHanja, "Hangul_PostHanja" },
+ { GDK_Hangul_SingleCandidate, "Hangul_SingleCandidate" },
+ { GDK_Hangul_MultipleCandidate, "Hangul_MultipleCandidate" },
+ { GDK_Hangul_PreviousCandidate, "Hangul_PreviousCandidate" },
+ { GDK_Hangul_Special, "Hangul_Special" },
+ { GDK_Hangul_switch, "Hangul_switch" },
+ { GDK_Hangul_Kiyeog, "Hangul_Kiyeog" },
+ { GDK_Hangul_SsangKiyeog, "Hangul_SsangKiyeog" },
+ { GDK_Hangul_KiyeogSios, "Hangul_KiyeogSios" },
+ { GDK_Hangul_Nieun, "Hangul_Nieun" },
+ { GDK_Hangul_NieunJieuj, "Hangul_NieunJieuj" },
+ { GDK_Hangul_NieunHieuh, "Hangul_NieunHieuh" },
+ { GDK_Hangul_Dikeud, "Hangul_Dikeud" },
+ { GDK_Hangul_SsangDikeud, "Hangul_SsangDikeud" },
+ { GDK_Hangul_Rieul, "Hangul_Rieul" },
+ { GDK_Hangul_RieulKiyeog, "Hangul_RieulKiyeog" },
+ { GDK_Hangul_RieulMieum, "Hangul_RieulMieum" },
+ { GDK_Hangul_RieulPieub, "Hangul_RieulPieub" },
+ { GDK_Hangul_RieulSios, "Hangul_RieulSios" },
+ { GDK_Hangul_RieulTieut, "Hangul_RieulTieut" },
+ { GDK_Hangul_RieulPhieuf, "Hangul_RieulPhieuf" },
+ { GDK_Hangul_RieulHieuh, "Hangul_RieulHieuh" },
+ { GDK_Hangul_Mieum, "Hangul_Mieum" },
+ { GDK_Hangul_Pieub, "Hangul_Pieub" },
+ { GDK_Hangul_SsangPieub, "Hangul_SsangPieub" },
+ { GDK_Hangul_PieubSios, "Hangul_PieubSios" },
+ { GDK_Hangul_Sios, "Hangul_Sios" },
+ { GDK_Hangul_SsangSios, "Hangul_SsangSios" },
+ { GDK_Hangul_Ieung, "Hangul_Ieung" },
+ { GDK_Hangul_Jieuj, "Hangul_Jieuj" },
+ { GDK_Hangul_SsangJieuj, "Hangul_SsangJieuj" },
+ { GDK_Hangul_Cieuc, "Hangul_Cieuc" },
+ { GDK_Hangul_Khieuq, "Hangul_Khieuq" },
+ { GDK_Hangul_Tieut, "Hangul_Tieut" },
+ { GDK_Hangul_Phieuf, "Hangul_Phieuf" },
+ { GDK_Hangul_Hieuh, "Hangul_Hieuh" },
+ { GDK_Hangul_A, "Hangul_A" },
+ { GDK_Hangul_AE, "Hangul_AE" },
+ { GDK_Hangul_YA, "Hangul_YA" },
+ { GDK_Hangul_YAE, "Hangul_YAE" },
+ { GDK_Hangul_EO, "Hangul_EO" },
+ { GDK_Hangul_E, "Hangul_E" },
+ { GDK_Hangul_YEO, "Hangul_YEO" },
+ { GDK_Hangul_YE, "Hangul_YE" },
+ { GDK_Hangul_O, "Hangul_O" },
+ { GDK_Hangul_WA, "Hangul_WA" },
+ { GDK_Hangul_WAE, "Hangul_WAE" },
+ { GDK_Hangul_OE, "Hangul_OE" },
+ { GDK_Hangul_YO, "Hangul_YO" },
+ { GDK_Hangul_U, "Hangul_U" },
+ { GDK_Hangul_WEO, "Hangul_WEO" },
+ { GDK_Hangul_WE, "Hangul_WE" },
+ { GDK_Hangul_WI, "Hangul_WI" },
+ { GDK_Hangul_YU, "Hangul_YU" },
+ { GDK_Hangul_EU, "Hangul_EU" },
+ { GDK_Hangul_YI, "Hangul_YI" },
+ { GDK_Hangul_I, "Hangul_I" },
+ { GDK_Hangul_J_Kiyeog, "Hangul_J_Kiyeog" },
+ { GDK_Hangul_J_SsangKiyeog, "Hangul_J_SsangKiyeog" },
+ { GDK_Hangul_J_KiyeogSios, "Hangul_J_KiyeogSios" },
+ { GDK_Hangul_J_Nieun, "Hangul_J_Nieun" },
+ { GDK_Hangul_J_NieunJieuj, "Hangul_J_NieunJieuj" },
+ { GDK_Hangul_J_NieunHieuh, "Hangul_J_NieunHieuh" },
+ { GDK_Hangul_J_Dikeud, "Hangul_J_Dikeud" },
+ { GDK_Hangul_J_Rieul, "Hangul_J_Rieul" },
+ { GDK_Hangul_J_RieulKiyeog, "Hangul_J_RieulKiyeog" },
+ { GDK_Hangul_J_RieulMieum, "Hangul_J_RieulMieum" },
+ { GDK_Hangul_J_RieulPieub, "Hangul_J_RieulPieub" },
+ { GDK_Hangul_J_RieulSios, "Hangul_J_RieulSios" },
+ { GDK_Hangul_J_RieulTieut, "Hangul_J_RieulTieut" },
+ { GDK_Hangul_J_RieulPhieuf, "Hangul_J_RieulPhieuf" },
+ { GDK_Hangul_J_RieulHieuh, "Hangul_J_RieulHieuh" },
+ { GDK_Hangul_J_Mieum, "Hangul_J_Mieum" },
+ { GDK_Hangul_J_Pieub, "Hangul_J_Pieub" },
+ { GDK_Hangul_J_PieubSios, "Hangul_J_PieubSios" },
+ { GDK_Hangul_J_Sios, "Hangul_J_Sios" },
+ { GDK_Hangul_J_SsangSios, "Hangul_J_SsangSios" },
+ { GDK_Hangul_J_Ieung, "Hangul_J_Ieung" },
+ { GDK_Hangul_J_Jieuj, "Hangul_J_Jieuj" },
+ { GDK_Hangul_J_Cieuc, "Hangul_J_Cieuc" },
+ { GDK_Hangul_J_Khieuq, "Hangul_J_Khieuq" },
+ { GDK_Hangul_J_Tieut, "Hangul_J_Tieut" },
+ { GDK_Hangul_J_Phieuf, "Hangul_J_Phieuf" },
+ { GDK_Hangul_J_Hieuh, "Hangul_J_Hieuh" },
+ { GDK_Hangul_RieulYeorinHieuh, "Hangul_RieulYeorinHieuh" },
+ { GDK_Hangul_SunkyeongeumMieum, "Hangul_SunkyeongeumMieum" },
+ { GDK_Hangul_SunkyeongeumPieub, "Hangul_SunkyeongeumPieub" },
+ { GDK_Hangul_PanSios, "Hangul_PanSios" },
+ { GDK_Hangul_KkogjiDalrinIeung, "Hangul_KkogjiDalrinIeung" },
+ { GDK_Hangul_SunkyeongeumPhieuf, "Hangul_SunkyeongeumPhieuf" },
+ { GDK_Hangul_YeorinHieuh, "Hangul_YeorinHieuh" },
+ { GDK_Hangul_AraeA, "Hangul_AraeA" },
+ { GDK_Hangul_AraeAE, "Hangul_AraeAE" },
+ { GDK_Hangul_J_PanSios, "Hangul_J_PanSios" },
+ { GDK_Hangul_J_KkogjiDalrinIeung, "Hangul_J_KkogjiDalrinIeung" },
+ { GDK_Hangul_J_YeorinHieuh, "Hangul_J_YeorinHieuh" },
+ { GDK_Korean_Won, "Korean_Won" },
+ { GDK_EcuSign, "EcuSign" },
+ { GDK_ColonSign, "ColonSign" },
+ { GDK_CruzeiroSign, "CruzeiroSign" },
+ { GDK_FFrancSign, "FFrancSign" },
+ { GDK_LiraSign, "LiraSign" },
+ { GDK_MillSign, "MillSign" },
+ { GDK_NairaSign, "NairaSign" },
+ { GDK_PesetaSign, "PesetaSign" },
+ { GDK_RupeeSign, "RupeeSign" },
+ { GDK_WonSign, "WonSign" },
+ { GDK_NewSheqelSign, "NewSheqelSign" },
+ { GDK_DongSign, "DongSign" },
+ { GDK_EuroSign, "EuroSign" },
+
+ { 0, NULL }
+};
diff --git a/tools/glade/glade/keys.h b/tools/glade/glade/keys.h
new file mode 100644
index 00000000..02ada778
--- /dev/null
+++ b/tools/glade/glade/keys.h
@@ -0,0 +1,44 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_KEYS_H
+#define GLADE_KEYS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct _GbKey GbKey;
+struct _GbKey
+{
+ guint key;
+ gchar *name;
+};
+
+/* Array of GDK key values & symbols which can be used as GTK accelerator keys.
+ These are used for the GladeKeysDialog.
+ Note that in GTK 1.0 accelerator keys are a guchar which means that only
+ keys with values 0-255 can be used. In GTK 1.1 a guint is used. */
+extern const GbKey GbKeys[];
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_KEYS_H */
diff --git a/tools/glade/glade/load.c b/tools/glade/glade/load.c
new file mode 100644
index 00000000..ca0ab5af
--- /dev/null
+++ b/tools/glade/glade/load.c
@@ -0,0 +1,603 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#include "gladeconfig.h"
+
+#include <libxml/parser.h>
+
+#include "glade_atk.h"
+#include "glade_project.h"
+#include "gbwidget.h"
+#include "load.h"
+#include "save.h"
+#include "utils.h"
+
+
+static gboolean real_load_project_file (GladeProject *project,
+ gboolean found_options);
+static void load_ensure_widgets_named (GtkWidget *widget,
+ GladeProject *project);
+static void load_atk_properties (GtkWidget *widget,
+ GHashTable *all_widgets);
+
+
+
+/* We need this to make sure that numbers are read in a portable syntax,
+ instead of using the current locale. This code is from glibc info docs.
+ We also set the timezone temporarily to GMT so that we can read in dates
+ easily. */
+gboolean
+load_project_file (GladeProject *project)
+{
+ gchar *saved_locale, *saved_timezone;
+ gboolean status, found_options;
+
+ /* Set the locale to "C". */
+ saved_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
+ setlocale (LC_NUMERIC, "C");
+
+ /* Set the timezone to "UTC". */
+ saved_timezone = glade_util_set_timezone ("UTC");
+
+ /* Load the project XML file, if it exists. Load this first so we know if
+ GNOME support is on or not. */
+ found_options = glade_project_load_options (project);
+
+ status = real_load_project_file (project, found_options);
+
+ /* Reset the timezone. */
+ glade_util_reset_timezone (saved_timezone);
+
+ /* Reset the locale. */
+ setlocale (LC_NUMERIC, saved_locale);
+ g_free (saved_locale);
+
+ return status;
+}
+
+
+static gboolean
+real_load_project_file (GladeProject *project, gboolean found_options)
+{
+ GbWidgetSetArgData data = { 0 };
+ gint i;
+
+ data.project = project;
+ data.filename = GladeSessionFile ? GladeSessionFile : project->xml_filename;
+ data.xml_buffer = NULL;
+ data.status = GLADE_STATUS_OK;
+ data.all_widgets = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* We load the saved session file if that has been set. */
+ data.interface = glade_parser_parse_file (data.filename, NULL);
+ if (!data.interface)
+ return FALSE;
+
+ /* If we didn't find a project options file (.gladep), try to guess whether
+ it is a GNOME or GTK+ project from the <requires> tags. */
+ if (!found_options)
+ {
+ project->gnome_support = FALSE;
+
+ for (i = 0; i < data.interface->n_requires; i++)
+ {
+#ifdef USE_GNOME
+ if (!strcmp (data.interface->requires[i], "gnome"))
+ project->gnome_support = TRUE;
+#else
+ if (!strcmp (data.interface->requires[i], "gnome"))
+ g_warning ("Glade has been compiled without support for Gnome.");
+#endif
+
+#ifdef USE_GNOME_DB
+ if (!strcmp (data.interface->requires[i], "gnomedb"))
+ project->gnome_db_support = TRUE;
+#else
+ if (!strcmp (data.interface->requires[i], "gnomedb"))
+ g_warning ("Glade has been compiled without support for Gnome DB.");
+#endif
+ }
+ }
+
+ /* Create each component in the interface. */
+ for (i = 0; i < data.interface->n_toplevels; i++)
+ {
+ data.child_info = NULL;
+ data.widget_info = data.interface->toplevels[i];
+ gb_widget_load (NULL, &data, NULL);
+ }
+
+ /* Now traverse all widgets, loading the ATK properties. We stored a pointer
+ to the GladeWidgetInfo inside each widget, which we now use to get the ATK
+ properties from. We also use the all_widgets hash to resolve relations. */
+ glade_project_foreach_component (data.project,
+ (GtkCallback) load_atk_properties,
+ data.all_widgets);
+
+ /* Destroy the parse data. */
+ glade_interface_destroy (data.interface);
+
+ /* Now we need to ensure that all widgets have names. In particular the
+ titles of CLists & CTrees, since sometimes it is necessary to create
+ these will loading. */
+ glade_project_foreach_component (data.project,
+ (GtkCallback) load_ensure_widgets_named,
+ data.project);
+
+ g_hash_table_destroy (data.all_widgets);
+
+ return TRUE;
+}
+
+
+gchar *
+load_get_value_full (GbWidgetSetArgData * data,
+ const gchar * property_name,
+ gboolean *translatable,
+ gchar **translator_comments,
+ gboolean *context_prefix)
+{
+ GladeProperty *properties;
+ gint nproperties;
+ const gchar *tag_name;
+ gint i;
+
+ data->apply = FALSE;
+
+ if (!data->widget_info)
+ return NULL;
+
+ tag_name = property_name;
+ while (*tag_name && (*tag_name != ':' || *(tag_name + 1) != ':'))
+ tag_name++;
+ if (*tag_name)
+ tag_name += 2;
+ else
+ tag_name = property_name;
+
+ if (data->loading_type == GB_STANDARD_PROPERTIES)
+ {
+ properties = data->widget_info->properties;
+ nproperties = data->widget_info->n_properties;
+ }
+ else
+ {
+ if (data->child_info)
+ {
+ properties = data->child_info->properties;
+ nproperties = data->child_info->n_properties;
+ }
+ else
+ {
+ properties = NULL;
+ nproperties = 0;
+ }
+ }
+
+ for (i = 0; i < nproperties; i++)
+ {
+ /* If we are loading properties for a specific agent, skip any properties
+ with no agent set or a different agent. */
+ if (data->agent && (!properties[i].agent
+ || strcmp (data->agent, properties[i].agent)))
+ continue;
+
+ if (!strcmp (tag_name, properties[i].name))
+ {
+ data->apply = TRUE;
+
+ if (translatable)
+ *translatable = properties[i].translatable;
+
+ if (translator_comments)
+ *translator_comments = properties[i].translator_comments;
+
+ if (context_prefix)
+ *context_prefix = properties[i].context_prefix;
+
+ return properties[i].value;
+ }
+ }
+
+ return NULL;
+}
+
+
+gchar *
+load_get_value (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ return load_get_value_full (data, property_name, NULL, NULL, NULL);
+}
+
+
+/* FIXME: Should the functions returning strings return NULL or "" ?
+ It doesn't matter too much as load_get_value() sets data->apply to FALSE
+ if no property is found. */
+
+gchar *
+load_string (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value, *translator_comments;
+ gboolean translatable, context_prefix;
+
+ value = load_get_value_full (data, property_name, &translatable,
+ &translator_comments, &context_prefix);
+ if (data->apply)
+ glade_util_set_translation_properties (data->widget, property_name,
+ translatable, translator_comments,
+ context_prefix);
+
+ return value ? value : "";
+}
+
+
+gchar *
+load_text (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ return load_string (data, property_name);
+}
+
+
+gint
+load_int (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ return value ? atoi (value) : 0;
+}
+
+
+gfloat
+load_float (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ return value ? atof (value) : 0;
+}
+
+
+gboolean
+load_bool (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ gboolean result = load_parse_bool (data, value);
+ if (data->status == GLADE_STATUS_INVALID_VALUE)
+ {
+ g_warning ("Invalid boolean value: %s", value);
+ data->status = GLADE_STATUS_OK;
+ result = FALSE;
+ }
+ return result;
+}
+
+
+gboolean
+load_parse_bool (GbWidgetSetArgData * data,
+ const gchar * value)
+{
+ if (value != NULL)
+ {
+ if (!g_strcasecmp (value, "true") || !g_strcasecmp (value, "yes") || !strcmp (value, "1"))
+ return TRUE;
+ else if (!g_strcasecmp (value, "false") || !g_strcasecmp (value, "no") || !strcmp (value, "0"))
+ return FALSE;
+ else
+ {
+ if (data)
+ data->status = GLADE_STATUS_INVALID_VALUE;
+ MSG1 ("===Invalid boolean property: %s", value);
+ }
+ }
+ return FALSE;
+}
+
+
+gchar *
+load_choice (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ return value ? value : "";
+}
+
+
+gchar *
+load_combo (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ return value ? value : "";
+}
+
+
+GdkColor *
+load_color (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ GdkColor *result = load_parse_color (data, value);
+ if (data->status == GLADE_STATUS_INVALID_VALUE)
+ {
+ g_warning ("Invalid color: %s", value);
+ data->status = GLADE_STATUS_OK;
+ }
+ return result;
+}
+
+
+/* Colors are now saved as '#rrrrggggbbbb', where rgb are 0-65535.
+ We use gdk_color_parse() when loading, so color names can be used as well.*/
+GdkColor *
+load_parse_color (GbWidgetSetArgData * data,
+ const gchar * value)
+{
+ static GdkColor color;
+
+ if (value == NULL)
+ return NULL;
+
+ if (!gdk_color_parse (value, &color))
+ {
+ data->status = GLADE_STATUS_INVALID_VALUE;
+
+ /* If an error occurs return white. */
+ color.red = 0xFFFF;
+ color.green = 0xFFFF;
+ color.blue = 0xFFFF;
+ }
+
+ return &color;
+}
+
+
+GdkPixmap *
+load_bgpixmap (GbWidgetSetArgData * data,
+ const gchar * property_name,
+ gchar ** filename)
+{
+ /*GdkPixmap *gdkpixmap;*/
+ gchar *value = load_get_value (data, property_name);
+ *filename = value;
+ if (value)
+ {
+ /* FIXME: What do I do here? We have no widget. Could use the parent,
+ or load the pixmap in a realize callback. */
+ /*
+ gdkpixmap = gdk_pixmap_create_from_xpm (data->holding_widget->window, NULL,
+ &data->holding_widget->style->bg[GTK_STATE_NORMAL],
+ value);
+ if (!gdkpixmap)
+ load_add_error_message_with_tag (data, GLADE_LINE_PROPERTY,
+ "Couldn't load pixmap",
+ property_name, value);
+
+ return gdkpixmap;
+ */
+ }
+
+ return NULL;
+}
+
+
+gpointer
+load_dialog (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ return value ? value : "";
+}
+
+
+gchar *
+load_filename (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ /* FIXME: Convert to absolute path, using project dir as relative path??. */
+ gchar *value = load_get_value (data, property_name);
+ return value ? value : "";
+}
+
+
+/* If we are loading the XML file, we convert any relative filenames to
+ absolute ones, based on the project directory and/or pixmaps directory
+ options. The returned filename should be freed when no longer needed. */
+gchar *
+load_pixmap_filename (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ gchar *pixmaps_dir;
+
+ if (value == NULL)
+ return NULL;
+
+ if (data->xml_buffer == NULL)
+ {
+ pixmaps_dir = glade_project_get_pixmaps_directory (data->project);
+ g_return_val_if_fail (pixmaps_dir != NULL, NULL);
+ g_return_val_if_fail (pixmaps_dir[0] != '\0', NULL);
+ return glade_util_make_absolute_path (pixmaps_dir, value);
+ }
+ else
+ return g_strdup (value);
+}
+
+
+GdkFont *
+load_font (GbWidgetSetArgData * data,
+ const gchar * property_name,
+ gchar ** xlfd_fontname)
+{
+ GdkFont *font;
+ gchar *value = load_get_value (data, property_name);
+ *xlfd_fontname = value;
+ if (value)
+ {
+ font = gdk_font_load (value);
+ if (font == NULL)
+ g_warning ("Couldn't load font: %s", value);
+ return font;
+ }
+ return NULL;
+}
+
+
+time_t
+load_date (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+ time_t result = value ? load_parse_date (data, value) : 0;
+
+ if (data->status == GLADE_STATUS_INVALID_VALUE)
+ {
+ g_warning ("Invalid date value: %s", value);
+ data->status = GLADE_STATUS_OK;
+ result = 0;
+ }
+
+ return result;
+}
+
+
+/* This parses a date in the RFC1123 format (an update of RFC822),
+ e.g. 'Sun, 06 Nov 1994 08:49:37 GMT'. */
+time_t
+load_parse_date (GbWidgetSetArgData * data,
+ const gchar * value)
+{
+ struct tm t;
+ gchar day[4], month[4];
+ gint matched, i;
+ time_t time;
+
+ if (!value || !value[0])
+ return 0;
+
+ /* Terminate the strings to be careful. */
+ day[0] = '\0';
+ month[0] = '\0';
+
+ MSG1 ("Trying to match date: %s", value);
+ matched = sscanf (value, "%3s, %2d %3s %4d %2d:%2d:%2d GMT",
+ &day[0], &t.tm_mday, &month[0], &t.tm_year,
+ &t.tm_hour, &t.tm_min, &t.tm_sec);
+ if (matched != 7)
+ {
+ MSG1 ("ERROR parsing date, matched: %i", matched);
+ data->status = GLADE_STATUS_INVALID_VALUE;
+ return 0;
+ }
+
+ /* The tm_year field starts from 1900 so we have to subtract that. */
+ t.tm_year -= 1900;
+
+ /* Find the month. */
+ t.tm_mon = -1;
+ for (i = 0; i < 12; i++)
+ {
+ if (!strcmp (GladeMonthNames[i], month))
+ {
+ t.tm_mon = i;
+ break;
+ }
+ }
+
+ /* Find the day. */
+ t.tm_wday = -1;
+ for (i = 0; i < 7; i++)
+ {
+ if (!strcmp (GladeDayNames[i], day))
+ {
+ t.tm_wday = i;
+ break;
+ }
+ }
+
+ if (t.tm_mon == -1 || t.tm_wday == -1)
+ {
+ MSG ("ERROR parsing date");
+ data->status = GLADE_STATUS_INVALID_VALUE;
+ return 0;
+ }
+
+ t.tm_isdst = -1;
+ /* Note that we don't need to set t.tm_yday (or t.tm_wday really).
+ They are recomputed by mktime.
+ Note also that mktime works since we have already set the timezone to GMT
+ in load_project_file(). */
+ time = mktime (&t);
+ if (time == -1)
+ {
+ MSG ("ERROR parsing date");
+ data->status = GLADE_STATUS_INVALID_VALUE;
+ return 0;
+ }
+ return time;
+}
+
+
+gchar*
+load_icon (GbWidgetSetArgData * data,
+ const gchar * property_name)
+{
+ gchar *value = load_get_value (data, property_name);
+
+ if (glade_util_check_is_stock_id (value))
+ return value;
+ else
+ return load_pixmap_filename (data, property_name);
+}
+
+
+static void
+load_ensure_widgets_named (GtkWidget *widget,
+ GladeProject *project)
+{
+ glade_project_ensure_widgets_named (project, widget);
+}
+
+
+static void
+load_atk_properties (GtkWidget *widget,
+ GHashTable *all_widgets)
+{
+ GladeWidgetInfo * widget_info;
+
+ widget_info = gtk_object_get_data (GTK_OBJECT (widget), GladeWidgetInfoKey);
+ if (widget_info)
+ {
+ glade_atk_load_properties (widget, widget_info, all_widgets);
+
+ /* Clear the pointer, just to be safe. */
+ gtk_object_set_data (GTK_OBJECT (widget), GladeWidgetInfoKey, NULL);
+ }
+
+ /* Load the child widgets' properties recursively. */
+ gb_widget_children_foreach (widget, (GtkCallback) load_atk_properties,
+ all_widgets);
+}
diff --git a/tools/glade/glade/load.h b/tools/glade/glade/load.h
new file mode 100644
index 00000000..2de6b8f4
--- /dev/null
+++ b/tools/glade/glade/load.h
@@ -0,0 +1,85 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_LOAD_H
+#define GLADE_LOAD_H
+
+#include <time.h>
+
+#include "gbwidget.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+gboolean load_project_file (GladeProject *project);
+
+
+gchar* load_string (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gchar* load_text (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gint load_int (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gfloat load_float (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gboolean load_bool (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gchar* load_choice (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gchar* load_combo (GbWidgetSetArgData *data,
+ const gchar *property_name);
+GdkColor* load_color (GbWidgetSetArgData *data,
+ const gchar *property_name);
+GdkPixmap* load_bgpixmap (GbWidgetSetArgData *data,
+ const gchar *property_name,
+ gchar **filename);
+gpointer load_dialog (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gchar* load_filename (GbWidgetSetArgData *data,
+ const gchar *property_name);
+/* This will convert any relative filenames to absolute ones, based on the
+ project directory and/or pixmaps directory options. It should be freed
+ when no longer needed. */
+gchar* load_pixmap_filename (GbWidgetSetArgData *data,
+ const gchar *property_name);
+GdkFont* load_font (GbWidgetSetArgData *data,
+ const gchar *property_name,
+ gchar **xlfd_fontname);
+time_t load_date (GbWidgetSetArgData *data,
+ const gchar *property_name);
+gchar* load_icon (GbWidgetSetArgData *data,
+ const gchar *property_name);
+
+
+gboolean load_parse_bool (GbWidgetSetArgData *data,
+ const gchar *value);
+GdkColor* load_parse_color (GbWidgetSetArgData *data,
+ const gchar *value);
+time_t load_parse_date (GbWidgetSetArgData * data,
+ const gchar *value);
+
+gchar* load_get_value (GbWidgetSetArgData *data,
+ const gchar *property_name);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_LOAD_H */
diff --git a/tools/glade/glade/main.c b/tools/glade/glade/main.c
new file mode 100644
index 00000000..94a2331f
--- /dev/null
+++ b/tools/glade/glade/main.c
@@ -0,0 +1,608 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-2002 Damon Chaplin
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include <gtk/gtkmain.h>
+#include <gtk/gtkrc.h>
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#include <bonobo.h>
+#include <libgnomeui/gnome-window-icon.h>
+#endif
+
+#include "glade.h"
+#include "glade_palette.h"
+#include "glade_project.h"
+#include "glade_project_window.h"
+#include "property.h"
+#include "save.h"
+#include "tree.h"
+#include "utils.h"
+
+
+/* These are the arguments parsed from the command line. */
+static gchar *arg_filename = NULL; /* The XML file to load on start-up. */
+static int arg_write_source = 0; /* Set to write the source & exit. */
+static int arg_hide_palette = 0;
+static int arg_hide_property_editor = 0;
+static int arg_show_widget_tree = 0;
+static int arg_show_clipboard = 0;
+
+
+static void parse_command_line (int argc, char *argv[]);
+static guint final_setup_from_main_loop (gpointer data);
+static void write_source (void);
+static void usage (void);
+
+
+#ifdef USE_GNOME
+static poptContext pctx;
+
+static struct poptOption options[] = {
+ {
+ "write-source", 'w', POPT_ARG_NONE, &arg_write_source, 0,
+ N_("Write the source code and exit"), NULL
+ },
+ {
+ "hide-palette", '\0', POPT_ARG_NONE, &arg_hide_palette, 0,
+ N_("Start with the palette hidden"), NULL
+ },
+ {
+ "hide-property-editor", '\0', POPT_ARG_NONE, &arg_hide_property_editor, 0,
+ N_("Start with the property editor hidden"), NULL
+ },
+ {
+ "show-widget-tree", '\0', POPT_ARG_NONE, &arg_show_widget_tree, 0,
+ N_("Show the widget tree"), NULL
+ },
+ {
+ "show-clipboard", '\0', POPT_ARG_NONE, &arg_show_clipboard, 0,
+ N_("Show the clipboard"), NULL
+ },
+ {
+ NULL, '\0', 0, NULL, 0, NULL, NULL
+ }
+};
+
+static gint session_save_yourself_cb (GnomeClient *client, gint phase,
+ GnomeRestartStyle save_style,
+ gboolean shutdown,
+ GnomeInteractStyle interact_style,
+ gboolean fast,
+ gpointer client_data);
+static void session_die_cb (GnomeClient *client, gpointer client_data);
+#else
+static GOptionEntry options[] = {
+ {
+ "write-source", 'w', 0, G_OPTION_ARG_NONE, &arg_write_source,
+ N_("Write the source code and exit"), NULL
+ },
+ {
+ "hide-palette", '\0', 0, G_OPTION_ARG_NONE, &arg_hide_palette,
+ N_("Start with the palette hidden"), NULL
+ },
+ {
+ "hide-property-editor", '\0', 0, G_OPTION_ARG_NONE, &arg_hide_property_editor,
+ N_("Start with the property editor hidden"), NULL
+ },
+ {
+ "show-widget-tree", '\0', 0, G_OPTION_ARG_NONE, &arg_show_widget_tree,
+ N_("Show the widget tree"), NULL
+ },
+ {
+ "show-clipboard", '\0', 0, G_OPTION_ARG_NONE, &arg_show_clipboard,
+ N_("Show the clipboard"), NULL
+ },
+ { NULL }
+};
+#endif
+
+
+#ifdef USE_GNOME
+GnomeClient *GladeClient;
+#endif
+
+
+static void
+glade_log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ /* We just want to ignore this warning as it happens in normal circumstances
+ and just confuses users. */
+ if (!strcmp (message, "gtk_scrolled_window_add(): cannot add non scrollable widget use gtk_scrolled_window_add_with_viewport() instead"))
+ return;
+
+ g_log_default_handler (log_domain, log_level, message, user_data);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ gchar *home_dir, *rc_path, *modules, *modules_needed, *new_modules;
+#ifdef USE_GNOME
+ GnomeProgram *program;
+ char *icon;
+#endif
+
+ home_dir = NULL;
+ rc_path = NULL;
+
+ /* We need to ensure that gail is loaded, so that we can query accessibility
+ info. I can't see a GTK+ function to do that. For now we just add the
+ modules we need to the GTK_MODULES environment variable. It doesn't
+ matter if modules appear twice. */
+ modules = (char*) g_getenv ("GTK_MODULES");
+#ifdef USE_GNOME
+ modules_needed = "gail" G_SEARCHPATH_SEPARATOR_S "gail-gnome";
+#else
+ modules_needed = "gail";
+#endif
+ new_modules = g_strdup_printf ("GTK_MODULES=%s%s%s",
+ modules ? modules : "",
+ modules ? G_SEARCHPATH_SEPARATOR_S : "",
+ modules_needed);
+ putenv (new_modules);
+
+#ifdef USE_GNOME
+ /* Gnome sets the locale and parses rc files automatically. */
+ program = gnome_program_init ("glade-2", VERSION,
+ LIBGNOMEUI_MODULE,
+ argc, argv,
+ GNOME_PARAM_POPT_TABLE, options,
+ GNOME_PARAM_APP_DATADIR, GLADE_DATADIR,
+ NULL);
+ icon = gnome_program_locate_file (program, GNOME_FILE_DOMAIN_APP_PIXMAP,
+ "glade-2.png", TRUE, NULL);
+
+ if (icon)
+ gnome_window_icon_set_default_from_file (icon);
+ g_free (icon);
+
+ g_object_get (G_OBJECT (program),
+ GNOME_PARAM_POPT_CONTEXT, &pctx,
+ NULL);
+
+ /* Set up session management*/
+ GladeClient = gnome_master_client ();
+
+ g_signal_connect (GladeClient, "save_yourself",
+ G_CALLBACK (session_save_yourself_cb), (gpointer)argv[0]);
+ g_signal_connect (GladeClient, "die", G_CALLBACK (session_die_cb), NULL);
+
+#else
+
+ gtk_set_locale ();
+
+ /* For GTK 1.2, default GTK rc files are parsed automatically. */
+ home_dir = (gchar*) g_get_home_dir ();
+ if (home_dir)
+ {
+ rc_path = g_strdup_printf ("%s/.gladerc", home_dir);
+ gtk_rc_add_default_file (rc_path);
+ g_free (rc_path);
+ }
+ gtk_init_with_args (&argc, &argv, "file", options, NULL, NULL);
+#endif
+
+ /* Ignore Ctrl-C. */
+ /*signal (SIGINT, SIG_IGN);*/
+
+#ifdef ENABLE_NLS
+ bindtextdomain (GETTEXT_PACKAGE, GLADE_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+#endif
+
+ glade_app_init ();
+
+ parse_command_line (argc, argv);
+
+ /* If the --write-source option is passed, we just write the source and exit
+ without even entering the GTK+ main loop. */
+ if (arg_write_source)
+ write_source ();
+
+ /* We can't make any CORBA calls unless we're in the main loop.
+ So we delay loading of files until then. */
+ gtk_idle_add ((GtkFunction) final_setup_from_main_loop, NULL);
+
+ g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, glade_log_handler, NULL);
+
+#ifdef USE_GNOME
+ bonobo_main ();
+#else
+ gtk_main ();
+#endif
+ return 0;
+}
+
+
+/* This looks for a .glade file to load, after all the popt options have
+ been removed. */
+#ifdef USE_GNOME
+static void
+parse_command_line (int argc, char *argv[])
+{
+ const gchar **args;
+ gint i;
+
+ args = poptGetArgs (pctx);
+
+ for (i = 0; args && args[i]; i++)
+ {
+ if (arg_filename == NULL)
+ arg_filename = (gchar*) args[i];
+ else
+ usage ();
+ }
+
+ poptFreeContext (pctx);
+}
+
+#else
+static void
+parse_command_line (int argc, char *argv[])
+{
+ gint i;
+
+ /* GTK parses argc & argv and sets arguments to NULL if it has used them. */
+ for (i = 1; i < argc; i++)
+ {
+ if (!argv[i]) continue;
+ if (!strcmp (argv[i], "-w") || !strcmp (argv[i], "--write-source"))
+ arg_write_source = 1;
+ else if (!strcmp (argv[i], "--version"))
+ {
+ printf ("Glade (GTK+) %s\n", VERSION);
+ exit (0);
+ }
+ else if (arg_filename == NULL)
+ arg_filename = (gchar*) argv[i];
+ else
+ usage ();
+ }
+}
+#endif
+
+
+#ifdef USE_GNOME
+/* Returns the session file, in on-disk encoding (We are assuming that
+ gnome_client_get_config_prefix() returns on-disk encoded filenames). */
+static char*
+get_session_file (GnomeClient *client)
+{
+ const char *config_prefix;
+ char *prefix, *session_file;
+
+ /* Get the config prefix, copy it, and remove the '/' at each end. */
+ config_prefix = gnome_client_get_config_prefix (client);
+ prefix = g_strdup (config_prefix + 1);
+ prefix[strlen (prefix) - 1] = '\0';
+
+ /* Create the directory containing all the sessions, if necessary.
+ gnome-client.h suggests using ~/.gnome2/<app>.d/session/ to save session
+ files, so that is what we do. */
+ session_file = g_build_filename (gnome_user_dir_get(), "glade-2.d",
+ "sessions", prefix, "project.glade", NULL);
+ g_free (prefix);
+
+ return session_file;
+}
+#endif
+
+
+static void
+show_window (GtkWidget *window, gboolean show)
+{
+ if (show)
+ gtk_widget_show (window);
+ else
+ gtk_widget_hide (window);
+}
+
+
+/* This creates the main GUI windows and loads any XML file specified from the
+ command-line. We do this here because we can't make any Bonob calls until
+ the main loop is running. */
+static guint
+final_setup_from_main_loop (gpointer data)
+{
+ GladeProjectWindow *project_window;
+ gchar *directory, *pathname = NULL, *pathname_utf8 = NULL;
+#ifdef USE_GNOME
+ gchar *session_file = NULL, *session_file_utf8 = NULL;
+#endif
+ gboolean loaded_file = FALSE;
+ gboolean show_palette = TRUE, show_property_editor = TRUE;
+ gboolean show_widget_tree = FALSE, show_clipboard = FALSE;
+
+ project_window = glade_project_window_new ();
+
+ /* Load the window geometries. */
+ glade_load_settings (project_window,
+ glade_palette, &show_palette,
+ win_property, &show_property_editor,
+ win_tree, &show_widget_tree,
+ glade_clipboard, &show_clipboard);
+
+ /* Always show the main project window. */
+ gtk_widget_show (project_window->window);
+
+ /* Command-line args override the settings file. */
+ if (arg_hide_palette)
+ show_palette = FALSE;
+ if (arg_hide_property_editor)
+ show_property_editor = FALSE;
+ if (arg_show_widget_tree)
+ show_widget_tree = TRUE;
+ if (arg_show_clipboard)
+ show_clipboard = TRUE;
+
+ show_window (glade_palette, show_palette);
+ show_window (win_property, show_property_editor);
+ show_window (win_tree, show_widget_tree);
+ show_window (glade_clipboard, show_clipboard);
+
+ if (arg_filename)
+ {
+ directory = g_get_current_dir ();
+ pathname = glade_util_make_absolute_path (directory, arg_filename);
+ pathname_utf8 = g_filename_to_utf8 (pathname, -1, NULL, NULL, NULL);
+ g_free (directory);
+ }
+
+ /* First we check for a saved session, else we check for a normal project
+ file on the command-line. */
+#ifdef USE_GNOME
+ session_file = get_session_file (GladeClient);
+ session_file_utf8 = g_filename_to_utf8 (session_file, -1, NULL, NULL,
+ NULL);
+ if (g_file_test (session_file, G_FILE_TEST_EXISTS))
+ {
+ struct stat pathname_stat, session_file_stat;
+ int status1 = -1, status2 = -1;
+
+ /* Note that pathname may be NULL, if the project hasn't been
+ saved yet. NOTE: This could cause problems if the user explicitly
+ saves a session without saving the Glade project, and then keeps
+ using that session on startup. Glade will always think the project
+ is a new one, even if the user saves it at some point. (Sessions
+ shouldn't be used this way really.) */
+ if (pathname)
+ {
+ status1 = stat (pathname, &pathname_stat);
+ status2 = stat (session_file, &session_file_stat);
+ }
+
+ /* We only want to load the session file if it is newer than the
+ real project XML file. i.e. its mtime is greater. */
+ if (status1 == -1 || status2 == -1
+ || session_file_stat.st_mtime >= pathname_stat.st_mtime)
+ {
+ GladeSessionFile = session_file_utf8;
+ glade_project_window_open_project (project_window, pathname_utf8);
+ GladeSessionFile = NULL;
+ loaded_file = TRUE;
+ }
+ }
+ g_free (session_file);
+ g_free (session_file_utf8);
+#endif
+
+ if (!loaded_file && pathname_utf8)
+ {
+ glade_project_window_open_project (project_window, pathname_utf8);
+ }
+
+ g_free (pathname);
+ g_free (pathname_utf8);
+
+ /* For GNOME, we start with no current project, as the user needs to select
+ between GTK+ and GNOME when creating a project. For GTK+ we can just
+ create a GTK+ project. */
+#ifdef USE_GNOME
+ if (current_project == NULL)
+ gtk_widget_set_sensitive (GTK_BIN (glade_palette)->child, FALSE);
+#else
+ if (current_project == NULL)
+ glade_project_new ();
+#endif
+
+ glade_project_window_set_project (project_window, current_project);
+
+ glade_project_window_refresh_menu_items ();
+
+ return FALSE;
+}
+
+
+/* Outputs the source code for the project, for when the --write-source option
+ is used. This function will not return. It exits with 0 if OK, or 1 if
+ there was an error writing the source. */
+static void
+write_source (void)
+{
+ GladeProject *project;
+ gboolean status;
+ GladeError *error;
+ gchar *directory, *directory_utf8, *filename;
+
+ if (!arg_filename) {
+ g_printerr (_("glade: The XML file must be set for the '-w' or '--write-source' option.\n"));
+ exit (1);
+ }
+
+ directory = g_get_current_dir ();
+ directory_utf8 = g_filename_to_utf8 (directory, -1, NULL, NULL, NULL);
+ filename = glade_util_make_absolute_path (directory_utf8, arg_filename);
+ g_free (directory_utf8);
+ g_free (directory);
+
+ status = glade_project_open (filename, &project);
+ g_free (filename);
+
+ if (!status) {
+ g_printerr (_("glade: Error loading XML file.\n"));
+ /* The errors aren't freed, but it doesn't really matter. */
+ exit (1);
+ }
+
+ error = glade_project_write_source (project);
+ if (error) {
+ g_printerr (_("glade: Error writing source.\n"));
+ glade_error_free (error);
+ exit (1);
+ }
+
+ exit (0);
+}
+
+
+/* Display the available command-line options and exit. Used when an invalid
+ argument was passed in. */
+static void
+usage (void)
+{
+ fprintf (stderr, "Usage: glade [-w|--write-source] [<filename>]\n");
+ exit (0);
+}
+
+
+#if USE_GNOME
+static void
+glade_write_session_files (GnomeClient *client)
+{
+ GladeError* error;
+ char *session_file = NULL, *session_dir = NULL;
+ char *session_file_utf8 = NULL, *session_dir_utf8 = NULL;
+ gchar *argv[] = { "rm", "-r", NULL };
+
+ session_file = get_session_file (client);
+ session_dir = g_dirname (session_file);
+ session_file_utf8 = g_filename_to_utf8 (session_file, -1, NULL, NULL, NULL);
+ session_dir_utf8 = g_filename_to_utf8 (session_dir, -1, NULL, NULL, NULL);
+
+ error = glade_util_ensure_directory_exists (session_dir_utf8);
+ if (error)
+ {
+ fprintf (stderr, error->message);
+ glade_error_free (error);
+ goto out;
+ }
+
+ /* Set a global variable to the session file to save. */
+ GladeSessionFile = session_file_utf8;
+ error = save_project_file (current_project);
+ GladeSessionFile = NULL;
+ if (error)
+ {
+ fprintf (stderr, error->message);
+ glade_error_free (error);
+ }
+
+ /* Set the discard command, so the session files will be deleted when the
+ session is. It copies all the args, so we can free our copies.
+ Note that we use on-disk encoding here, as I assume that is what 'rm'
+ wants. */
+ argv[2] = session_dir;
+ gnome_client_set_discard_command (client, 3, argv);
+
+ out:
+
+ g_free (session_dir);
+ g_free (session_file);
+ g_free (session_dir_utf8);
+ g_free (session_file_utf8);
+}
+
+
+static gint
+session_save_yourself_cb (GnomeClient *client, gint phase,
+ GnomeRestartStyle save_style, gboolean shutdown,
+ GnomeInteractStyle interact_style, gboolean fast,
+ gpointer client_data)
+{
+ char *argv[10]; /* Make sure this has enough space for all possible args. */
+ int arg = 0;
+
+ /* FIXME: Hardcoded path just for testing. */
+#if 0
+ argv[arg++] = "/home/damon/cvs/glade-gtk2/glade/glade-2";
+#else
+ argv[arg++] = "glade-2";
+#endif
+
+ if (!glade_palette || !GTK_WIDGET_VISIBLE (glade_palette))
+ {
+ argv[arg++] = "--hide-palette";
+ }
+
+ if (!win_property || !GTK_WIDGET_VISIBLE (win_property))
+ {
+ argv[arg++] = "--hide-property-editor";
+ }
+
+ if (win_tree && GTK_WIDGET_VISIBLE (win_tree))
+ {
+ argv[arg++] = "--show-widget-tree";
+ }
+
+ if (glade_clipboard && GTK_WIDGET_VISIBLE (glade_clipboard))
+ {
+ argv[arg++] = "--show-clipboard";
+ }
+
+ /* Check if we need to save the project files. */
+ if (current_project && current_project->components)
+ {
+ /* We save the XML filename as an arg, but the saved session files will
+ be loaded instead. Though we need to know the XML filename for saving
+ the project later. */
+ if (current_project->xml_filename
+ && *current_project->xml_filename)
+ argv[arg++] = current_project->xml_filename;
+
+ glade_write_session_files (client);
+ }
+
+ gnome_client_set_restart_command (client, arg, argv);
+
+ return TRUE;
+}
+
+
+static void
+session_die_cb (GnomeClient *client, gpointer client_data)
+{
+ gtk_main_quit ();
+}
+#endif
diff --git a/tools/glade/glade/named_icons.c b/tools/glade/glade/named_icons.c
new file mode 100644
index 00000000..4735f83d
--- /dev/null
+++ b/tools/glade/glade/named_icons.c
@@ -0,0 +1,1026 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <gtk/gtk.h>
+
+const gchar * GladeNamedIcons[] =
+{
+ GTK_STOCK_DIALOG_AUTHENTICATION,
+ GTK_STOCK_DIALOG_INFO,
+ GTK_STOCK_DIALOG_WARNING,
+ GTK_STOCK_DIALOG_ERROR,
+ GTK_STOCK_DIALOG_QUESTION,
+ GTK_STOCK_DND,
+ GTK_STOCK_DND_MULTIPLE,
+ GTK_STOCK_ABOUT,
+ GTK_STOCK_ADD,
+ GTK_STOCK_APPLY,
+ GTK_STOCK_BOLD,
+ GTK_STOCK_CANCEL,
+ GTK_STOCK_CDROM,
+ GTK_STOCK_CLEAR,
+ GTK_STOCK_CLOSE,
+ GTK_STOCK_COLOR_PICKER,
+ GTK_STOCK_CONVERT,
+ GTK_STOCK_CONNECT,
+ GTK_STOCK_COPY,
+ GTK_STOCK_CUT,
+ GTK_STOCK_DELETE,
+ GTK_STOCK_DIRECTORY,
+ GTK_STOCK_DISCONNECT,
+ GTK_STOCK_EDIT,
+ GTK_STOCK_EXECUTE,
+ GTK_STOCK_FILE,
+ GTK_STOCK_FIND,
+ GTK_STOCK_FIND_AND_REPLACE,
+ GTK_STOCK_FLOPPY,
+ GTK_STOCK_FULLSCREEN,
+ GTK_STOCK_GOTO_BOTTOM,
+ GTK_STOCK_GOTO_FIRST,
+ GTK_STOCK_GOTO_LAST,
+ GTK_STOCK_GOTO_TOP,
+ GTK_STOCK_GO_BACK,
+ GTK_STOCK_GO_DOWN,
+ GTK_STOCK_GO_FORWARD,
+ GTK_STOCK_GO_UP,
+ GTK_STOCK_HARDDISK,
+ GTK_STOCK_HELP,
+ GTK_STOCK_HOME,
+ GTK_STOCK_INDEX,
+ GTK_STOCK_INDENT,
+ GTK_STOCK_INFO,
+ GTK_STOCK_UNINDENT,
+ GTK_STOCK_ITALIC,
+ GTK_STOCK_JUMP_TO,
+ GTK_STOCK_JUSTIFY_CENTER,
+ GTK_STOCK_JUSTIFY_FILL,
+ GTK_STOCK_JUSTIFY_LEFT,
+ GTK_STOCK_JUSTIFY_RIGHT,
+ GTK_STOCK_LEAVE_FULLSCREEN,
+ GTK_STOCK_MISSING_IMAGE,
+ GTK_STOCK_MEDIA_FORWARD,
+ GTK_STOCK_MEDIA_NEXT,
+ GTK_STOCK_MEDIA_PAUSE,
+ GTK_STOCK_MEDIA_PLAY,
+ GTK_STOCK_MEDIA_PREVIOUS,
+ GTK_STOCK_MEDIA_RECORD,
+ GTK_STOCK_MEDIA_REWIND,
+ GTK_STOCK_MEDIA_STOP,
+ GTK_STOCK_NETWORK,
+ GTK_STOCK_NEW,
+ GTK_STOCK_NO,
+ GTK_STOCK_OK,
+ GTK_STOCK_OPEN,
+ GTK_STOCK_PASTE,
+ GTK_STOCK_PREFERENCES,
+ GTK_STOCK_PRINT,
+ GTK_STOCK_PRINT_PREVIEW,
+ GTK_STOCK_PROPERTIES,
+ GTK_STOCK_QUIT,
+ GTK_STOCK_REDO,
+ GTK_STOCK_REFRESH,
+ GTK_STOCK_REMOVE,
+ GTK_STOCK_REVERT_TO_SAVED,
+ GTK_STOCK_SAVE,
+ GTK_STOCK_SAVE_AS,
+ GTK_STOCK_SELECT_COLOR,
+ GTK_STOCK_SELECT_FONT,
+ GTK_STOCK_SORT_ASCENDING,
+ GTK_STOCK_SORT_DESCENDING,
+ GTK_STOCK_SPELL_CHECK,
+ GTK_STOCK_STOP,
+ GTK_STOCK_STRIKETHROUGH,
+ GTK_STOCK_UNDELETE,
+ GTK_STOCK_UNDERLINE,
+ GTK_STOCK_UNDO,
+ GTK_STOCK_YES,
+ GTK_STOCK_ZOOM_100,
+ GTK_STOCK_ZOOM_FIT,
+ GTK_STOCK_ZOOM_IN,
+ GTK_STOCK_ZOOM_OUT,
+
+#ifdef USE_GNOME
+ "stock_chart",
+ "stock_chart-autoformat",
+ "stock_chart-data-in-columns",
+ "stock_chart-data-in-rows",
+ "stock_chart-edit-type",
+ "stock_chart-reorganize",
+ "stock_chart-toggle-axes",
+ "stock_chart-toggle-axes-title",
+ "stock_chart-toggle-hgrid",
+ "stock_chart-toggle-legend",
+ "stock_chart-toggle-title",
+ "stock_chart-toggle-vgrid",
+ "stock_glue",
+ "stock_gluepoint-down",
+ "stock_gluepoint-horizontal-center",
+ "stock_gluepoint-horizontal-left",
+ "stock_gluepoint-horizontal-right",
+ "stock_gluepoint-left",
+ "stock_gluepoint-relative",
+ "stock_gluepoint-right",
+ "stock_gluepoint-up",
+ "stock_gluepoint-vertical-bottom",
+ "stock_gluepoint-vertical-center",
+ "stock_gluepoint-vertical-top",
+ "stock_insert-chart",
+ "stock_compile",
+ "stock_error-next",
+ "stock_error-next-16",
+ "stock_error-previous",
+ "stock_error-previous-16",
+ "stock_macro-check-brackets",
+ "stock_macro-insert",
+ "stock_macro-insert-breakpoint",
+ "stock_macro-jump-back",
+ "stock_macro-objects",
+ "stock_macro-organizer",
+ "stock_macro-stop-after-command",
+ "stock_macro-stop-after-procedure",
+ "stock_macro-stop-watching",
+ "stock_macro-watch-variable",
+ "stock_record-macro",
+ "stock_run-macro",
+ "stock_script",
+ "stock_tools-macro",
+ "stock_add-decimal-place",
+ "stock_advanced-filter",
+ "stock_autofilter",
+ "stock_data-delete-link",
+ "stock_data-delete-query",
+ "stock_data-delete-record",
+ "stock_data-delete-sql-query",
+ "stock_data-delete-table",
+ "stock_data-edit-link",
+ "stock_data-edit-query",
+ "stock_data-edit-sql-query",
+ "stock_data-edit-table",
+ "stock_data-explorer",
+ "stock_data-first",
+ "stock_data-last",
+ "stock_data-link",
+ "stock_data-linked-table",
+ "stock_data-links",
+ "stock_data-new-link",
+ "stock_data-new-query",
+ "stock_data-new-record",
+ "stock_data-new-sql-query",
+ "stock_data-new-table",
+ "stock_data-next",
+ "stock_data-previous",
+ "stock_data-queries",
+ "stock_data-query",
+ "stock_data-query-rename",
+ "stock_data-save",
+ "stock_data-sources",
+ "stock_data-sources-delete",
+ "stock_data-sources-hand",
+ "stock_data-sources-modified",
+ "stock_data-sources-new",
+ "stock_data-table",
+ "stock_data-tables",
+ "stock_data-undo",
+ "stock_database",
+ "stock_delete-autofilter",
+ "stock_delete-decimal-place",
+ "stock_filter-data-by-criteria",
+ "stock_filter-navigator",
+ "stock_filters",
+ "stock_format-default",
+ "stock_format-percent",
+ "stock_format-scientific",
+ "stock_function-autopilot",
+ "stock_goal-seek",
+ "stock_insert-fields",
+ "stock_lock",
+ "stock_lock-broken",
+ "stock_lock-ok",
+ "stock_lock-open",
+ "stock_record-number",
+ "stock_signature",
+ "stock_signature-bad",
+ "stock_signature-ok",
+ "stock_sort-ascending",
+ "stock_sort-column-ascending",
+ "stock_sort-criteria",
+ "stock_sort-descending",
+ "stock_sort-row-ascending",
+ "stock_standard-filter",
+ "stock_sum",
+ "stock_update-data",
+ "stock_attach",
+ "stock_certificate",
+ "stock_my-documents",
+ "stock_new",
+ "stock_new-drawing",
+ "stock_new-formula",
+ "stock_new-html",
+ "stock_new-labels",
+ "stock_new-master-document",
+ "stock_new-presentation",
+ "stock_new-spreadsheet",
+ "stock_new-template",
+ "stock_new-text",
+ "stock_preview-four-pages",
+ "stock_preview-two-pages",
+ "stock_print-layout",
+ "stock_print-options",
+ "stock_print-resolution",
+ "stock_samples",
+ "stock_script",
+ "stock_scripts",
+ "stock_task",
+ "stock_task-assigned",
+ "stock_task-assigned-to",
+ "stock_task-recurring",
+ "stock_todo",
+ "stock_view-html-source",
+ "stock_smiley-1",
+ "stock_smiley-10",
+ "stock_smiley-11",
+ "stock_smiley-12",
+ "stock_smiley-13",
+ "stock_smiley-14",
+ "stock_smiley-15",
+ "stock_smiley-16",
+ "stock_smiley-17",
+ "stock_smiley-18",
+ "stock_smiley-19",
+ "stock_smiley-2",
+ "stock_smiley-20",
+ "stock_smiley-21",
+ "stock_smiley-22",
+ "stock_smiley-23",
+ "stock_smiley-24",
+ "stock_smiley-25",
+ "stock_smiley-26",
+ "stock_smiley-3",
+ "stock_smiley-4",
+ "stock_smiley-5",
+ "stock_smiley-6",
+ "stock_smiley-7",
+ "stock_smiley-8",
+ "stock_smiley-9",
+ "stock_form-activation-order",
+ "stock_form-add-field",
+ "stock_form-automatic-control-focus",
+ "stock_form-autopilots",
+ "stock_form-button",
+ "stock_form-checkbox",
+ "stock_form-combobox",
+ "stock_form-control-properties",
+ "stock_form-currency-field",
+ "stock_form-date-field",
+ "stock_form-design-mode",
+ "stock_form-file-selection",
+ "stock_form-formatted-field",
+ "stock_form-frame",
+ "stock_form-image-button",
+ "stock_form-image-control",
+ "stock_form-label",
+ "stock_form-letter-dialog",
+ "stock_form-line-horizontal",
+ "stock_form-line-vertical",
+ "stock_form-listbox",
+ "stock_form-navigator",
+ "stock_form-numerical-field",
+ "stock_form-open-in-design-mode",
+ "stock_form-pattern-field",
+ "stock_form-progressbar",
+ "stock_form-properties",
+ "stock_form-radio",
+ "stock_form-table-control",
+ "stock_form-text-box",
+ "stock_form-time-field",
+ "stock_insert-form",
+ "stock_macro-controls",
+ "stock_show-form-dialog",
+ "stock_show-hidden-controls",
+ "stock_view-fields",
+ "stock_3d-favourites",
+ "stock_about",
+ "stock_active",
+ "stock_alarm",
+ "stock_allow-effects",
+ "stock_anchor",
+ "stock_animation",
+ "stock_autocompletion",
+ "stock_autopilot",
+ "stock_autopilot-24",
+ "stock_bell",
+ "stock_book_blue",
+ "stock_book_green",
+ "stock_book_open",
+ "stock_book_red",
+ "stock_book_yellow",
+ "stock_briefcase",
+ "stock_calc-accept",
+ "stock_calc-cancel",
+ "stock_calendar",
+ "stock_calendar-and-tasks",
+ "stock_calendar-view-day",
+ "stock_calendar-view-list",
+ "stock_calendar-view-month",
+ "stock_calendar-view-week",
+ "stock_calendar-view-work-week",
+ "stock_calendar-view-year",
+ "stock_cell-phone",
+ "stock_check-filled",
+ "stock_close",
+ "stock_color",
+ "stock_copy",
+ "stock_creditcard",
+ "stock_cut",
+ "stock_default-folder",
+ "stock_delete",
+ "stock_dialog-error",
+ "stock_dialog-info",
+ "stock_dialog-question",
+ "stock_dialog-warning",
+ "stock_drag-mode",
+ "stock_edit",
+ "stock_equals",
+ "stock_example",
+ "stock_exit",
+ "stock_extended-help",
+ "stock_file-properties",
+ "stock_flip-horizontally",
+ "stock_flip-vertically",
+ "stock_folder",
+ "stock_folder-copy",
+ "stock_folder-move",
+ "stock_folder-properties",
+ "stock_format-page",
+ "stock_fullscreen",
+ "stock_help",
+ "stock_help-add-bookmark",
+ "stock_help-agent",
+ "stock_help-book",
+ "stock_help-book-open",
+ "stock_help-chat",
+ "stock_help-document",
+ "stock_help-pane-off",
+ "stock_help-pane-on",
+ "stock_home",
+ "stock_id",
+ "stock_init",
+ "stock_keyring",
+ "stock_landline-phone",
+ "stock_leave-fullscreen",
+ "stock_mark",
+ "stock_new",
+ "stock_new-24h-appointment",
+ "stock_new-appointment",
+ "stock_new-dir",
+ "stock_new-meeting",
+ "stock_news",
+ "stock_not",
+ "stock_notebook",
+ "stock_notes",
+ "stock_openoffice",
+ "stock_paste",
+ "stock_people",
+ "stock_person",
+ "stock_presentation-box",
+ "stock_presentation-styles",
+ "stock_properties",
+ "stock_redo",
+ "stock_refresh",
+ "stock_score-high",
+ "stock_score-higher",
+ "stock_score-highest",
+ "stock_score-low",
+ "stock_score-lower",
+ "stock_score-lowest",
+ "stock_score-normal",
+ "stock_scores",
+ "stock_search",
+ "stock_search-and-replace",
+ "stock_send-fax",
+ "stock_show-all",
+ "stock_stop",
+ "stock_styles",
+ "stock_summary",
+ "stock_test-mode",
+ "stock_timer",
+ "stock_timer_stopped",
+ "stock_timezone",
+ "stock_toggle-info",
+ "stock_toggle-preview",
+ "stock_toilet-paper",
+ "stock_trash_full",
+ "stock_undelete",
+ "stock_undo",
+ "stock_unknown",
+ "stock_view-details",
+ "stock_weather-cloudy",
+ "stock_weather-few-clouds",
+ "stock_weather-fog",
+ "stock_weather-night-clear",
+ "stock_weather-night-few-clouds",
+ "stock_weather-showers",
+ "stock_weather-snow",
+ "stock_weather-storm",
+ "stock_weather-sunny",
+ "stock_web-calendar",
+ "stock_web-support",
+ "stock_3d-color-picker",
+ "stock_3d-colors",
+ "stock_3d-custom-color",
+ "stock_3d-effects",
+ "stock_arrowstyle",
+ "stock_brightness",
+ "stock_bucketfill",
+ "stock_channel-blue",
+ "stock_channel-green",
+ "stock_channel-red",
+ "stock_contrast",
+ "stock_crop",
+ "stock_display-grid",
+ "stock_display-guides",
+ "stock_distort",
+ "stock_draw-arc",
+ "stock_draw-callouts",
+ "stock_draw-circle",
+ "stock_draw-circle-arc",
+ "stock_draw-circle-pie",
+ "stock_draw-circle-pie-unfilled",
+ "stock_draw-circle-segment",
+ "stock_draw-circle-segment-unfilled",
+ "stock_draw-circle-unfilled",
+ "stock_draw-cone",
+ "stock_draw-connector",
+ "stock_draw-connector-ends-with-arrow",
+ "stock_draw-connector-ends-with-circle",
+ "stock_draw-connector-starts-with-arrow",
+ "stock_draw-connector-starts-with-circle",
+ "stock_draw-connector-with-arrows",
+ "stock_draw-connector-with-circles",
+ "stock_draw-cube",
+ "stock_draw-curve",
+ "stock_draw-curve-filled",
+ "stock_draw-curved-connector",
+ "stock_draw-curved-connector-ends-with-arrow",
+ "stock_draw-curved-connector-ends-with-circle",
+ "stock_draw-curved-connector-starts-with-arrow",
+ "stock_draw-curved-connector-starts-with-circle",
+ "stock_draw-curved-connector-with-arrows",
+ "stock_draw-curved-connector-with-circles",
+ "stock_draw-cylinder",
+ "stock_draw-dimension-line",
+ "stock_draw-ellipse",
+ "stock_draw-ellipse-pie",
+ "stock_draw-ellipse-pie-unfilled",
+ "stock_draw-ellipse-segment",
+ "stock_draw-ellipse-segment-unfilled",
+ "stock_draw-ellipse-unfilled",
+ "stock_draw-freeform-line",
+ "stock_draw-freeform-line-filled",
+ "stock_draw-half-sphere",
+ "stock_draw-line",
+ "stock_draw-line-45",
+ "stock_draw-line-connector",
+ "stock_draw-line-connector-ends-with-arrow",
+ "stock_draw-line-connector-ends-with-circle",
+ "stock_draw-line-connector-starts-with-arrow",
+ "stock_draw-line-connector-starts-with-circle",
+ "stock_draw-line-connector-with-arrows",
+ "stock_draw-line-connector-with-circles",
+ "stock_draw-line-ends-with-arrow",
+ "stock_draw-line-starts-with-arrow",
+ "stock_draw-line-with-arrow-circle",
+ "stock_draw-line-with-arrow-square",
+ "stock_draw-line-with-arrows",
+ "stock_draw-line-with-circle-arrow",
+ "stock_draw-line-with-square-arrow",
+ "stock_draw-polygon",
+ "stock_draw-polygon-45",
+ "stock_draw-polygon-45-filled",
+ "stock_draw-polygon-filled",
+ "stock_draw-pyramid",
+ "stock_draw-rectangle",
+ "stock_draw-rectangle-unfilled",
+ "stock_draw-rounded-rectangle",
+ "stock_draw-rounded-rectangle-unfilled",
+ "stock_draw-rounded-square",
+ "stock_draw-rounded-square-unfilled",
+ "stock_draw-selection",
+ "stock_draw-shell",
+ "stock_draw-sphere",
+ "stock_draw-square",
+ "stock_draw-square-unfilled",
+ "stock_draw-straight-connector",
+ "stock_draw-straight-connector-ends-with-arrow",
+ "stock_draw-straight-connector-ends-with-circle",
+ "stock_draw-straight-connector-starts-with-arrow",
+ "stock_draw-straight-connector-starts-with-circle",
+ "stock_draw-straight-connector-with-arrows",
+ "stock_draw-straight-connector-with-circles",
+ "stock_draw-torus",
+ "stock_draw-vertical-callouts",
+ "stock_edit-points",
+ "stock_filters-aging",
+ "stock_filters-charcoal",
+ "stock_filters-invert",
+ "stock_filters-pixelize",
+ "stock_filters-pop-art",
+ "stock_filters-posterize",
+ "stock_filters-relief",
+ "stock_filters-remove-noise",
+ "stock_filters-sharpen",
+ "stock_filters-smooth",
+ "stock_filters-solarize",
+ "stock_flip",
+ "stock_gamma",
+ "stock_gradient",
+ "stock_graphic-styles",
+ "stock_graphics-align-bottom",
+ "stock_graphics-align-center",
+ "stock_graphics-align-centered",
+ "stock_graphics-align-left",
+ "stock_graphics-align-right",
+ "stock_graphics-align-top",
+ "stock_guides",
+ "stock_imagemap-editor",
+ "stock_insert_image",
+ "stock_linepen",
+ "stock_modify-layout",
+ "stock_node-add",
+ "stock_node-close-path",
+ "stock_node-convert",
+ "stock_node-corner",
+ "stock_node-corner-to-smooth",
+ "stock_node-curve-split",
+ "stock_node-delete",
+ "stock_node-mark-for-deletion",
+ "stock_node-move",
+ "stock_node-smooth-to-symmetrical",
+ "stock_placeholder-graphic",
+ "stock_placeholder-line-contour",
+ "stock_placeholder-picture",
+ "stock_placeholder-text",
+ "stock_quickmask",
+ "stock_rotate",
+ "stock_rotate-3d",
+ "stock_rotation-mode",
+ "stock_shadow",
+ "stock_show-draw-functions",
+ "stock_toggle-graphics",
+ "stock_transform-circle-perspective",
+ "stock_transform-circle-slant",
+ "stock_transparency",
+ "stock_wallpaper-center",
+ "stock_wallpaper-fill",
+ "stock_wallpaper-scale",
+ "stock_wallpaper-tile",
+ "stock_bluetooth",
+ "stock_export",
+ "stock_insert-file",
+ "stock_network-printer",
+ "stock_open",
+ "stock_open-read-only",
+ "stock_opensave",
+ "stock_print",
+ "stock_print-driver",
+ "stock_print-duplex",
+ "stock_print-duplex-no-tumble",
+ "stock_print-duplex-tumble",
+ "stock_print-non-duplex",
+ "stock_print-preview",
+ "stock_print-preview-print",
+ "stock_print-setup",
+ "stock_printers",
+ "stock_reload",
+ "stock_save",
+ "stock_save-as",
+ "stock_save-pdf",
+ "stock_save-template",
+ "stock_save_as",
+ "stock_up-one-dir",
+ "stock_3dsound",
+ "stock_effects-sound",
+ "stock_headphones",
+ "stock_insert-video-plugin",
+ "stock_line_in",
+ "stock_media-fwd",
+ "stock_media-next",
+ "stock_media-pause",
+ "stock_media-play",
+ "stock_media-prev",
+ "stock_media-rec",
+ "stock_media-rew",
+ "stock_media-shuffle",
+ "stock_media-stop",
+ "stock_mic",
+ "stock_midi",
+ "stock_music-library",
+ "stock_playlist",
+ "stock_repeat",
+ "stock_shuffle",
+ "stock_smart-playlist",
+ "stock_sound",
+ "stock_volume",
+ "stock_volume-0",
+ "stock_volume-max",
+ "stock_volume-med",
+ "stock_volume-min",
+ "stock_volume-mute",
+ "stock_bottom",
+ "stock_down",
+ "stock_down-with-subpoints",
+ "stock_first",
+ "stock_first-page",
+ "stock_last",
+ "stock_last-page",
+ "stock_left",
+ "stock_left-with-subpoints",
+ "stock_live-mode",
+ "stock_navigate-next",
+ "stock_navigate-prev",
+ "stock_navigator",
+ "stock_navigator-all-or-sel-toggle",
+ "stock_navigator-database-ranges",
+ "stock_navigator-drag-mode",
+ "stock_navigator-edit-entry",
+ "stock_navigator-foonote-body-toggle",
+ "stock_navigator-footer-body-toggle",
+ "stock_navigator-header-body-toggle",
+ "stock_navigator-headings",
+ "stock_navigator-indexes",
+ "stock_navigator-insert-as-copy",
+ "stock_navigator-insert-as-link",
+ "stock_navigator-insert-index",
+ "stock_navigator-insert-linked",
+ "stock_navigator-levels",
+ "stock_navigator-list-box-toggle",
+ "stock_navigator-master-toggle",
+ "stock_navigator-next-object",
+ "stock_navigator-open-toolbar",
+ "stock_navigator-previous-object",
+ "stock_navigator-range-names",
+ "stock_navigator-references",
+ "stock_navigator-reminder",
+ "stock_navigator-scenarios",
+ "stock_navigator-sections",
+ "stock_navigator-shift-down",
+ "stock_navigator-shift-left",
+ "stock_navigator-shift-right",
+ "stock_navigator-shift-up",
+ "stock_navigator-table-formula",
+ "stock_navigator-text",
+ "stock_navigator-update-entry",
+ "stock_navigator-wrong-table-formula",
+ "stock_new-tab",
+ "stock_next",
+ "stock_next-page",
+ "stock_previous",
+ "stock_previous-page",
+ "stock_right",
+ "stock_right-with-subpoints",
+ "stock_top",
+ "stock_undo-history",
+ "stock_up",
+ "stock_up-with-subpoints",
+ "stock_zoom",
+ "stock_zoom-1",
+ "stock_zoom-in",
+ "stock_zoom-next",
+ "stock_zoom-object",
+ "stock_zoom-optimal",
+ "stock_zoom-out",
+ "stock_zoom-page",
+ "stock_zoom-page-width",
+ "stock_zoom-previous",
+ "stock_zoom-shift",
+ "stock_addressbook",
+ "stock_appointment-reminder",
+ "stock_appointment-reminder-excl",
+ "stock_channel",
+ "stock_connect",
+ "stock_connect-to-url",
+ "stock_contact",
+ "stock_contact-list",
+ "stock_directory-server",
+ "stock_disconnect",
+ "stock_exchange-connector",
+ "stock_groupwise-connector",
+ "stock_hand-signed",
+ "stock_hyperlink",
+ "stock_hyperlink-internet-search",
+ "stock_hyperlink-target",
+ "stock_hyperlink-toolbar",
+ "stock_inbox",
+ "stock_insert-url",
+ "stock_internet",
+ "stock_link",
+ "stock_mail",
+ "stock_mail-accounts",
+ "stock_mail-compose",
+ "stock_mail-copy",
+ "stock_mail-druid",
+ "stock_mail-druid-account",
+ "stock_mail-filters-apply",
+ "stock_mail-flag-for-followup",
+ "stock_mail-flag-for-followup-done",
+ "stock_mail-forward",
+ "stock_mail-handling",
+ "stock_mail-hide-deleted",
+ "stock_mail-hide-read",
+ "stock_mail-hide-selected",
+ "stock_mail-import",
+ "stock_mail-merge",
+ "stock_mail-move",
+ "stock_mail-open",
+ "stock_mail-open-multiple",
+ "stock_mail-priority-high",
+ "stock_mail-receive",
+ "stock_mail-replied",
+ "stock_mail-reply",
+ "stock_mail-reply-to-all",
+ "stock_mail-send",
+ "stock_mail-send-receive",
+ "stock_mail-unread",
+ "stock_mail-unread-multiple",
+ "stock_message-display",
+ "stock_not-spam",
+ "stock_online-layout",
+ "stock_outbox",
+ "stock_post-message",
+ "stock_proxy",
+ "stock_sent-mail",
+ "stock_shared-by-me",
+ "stock_shared-to-me",
+ "stock_spam",
+ "stock_video-conferencing",
+ "stock_3d-3d-attributes-only",
+ "stock_3d-all-attributes",
+ "stock_3d-geometry",
+ "stock_3d-light",
+ "stock_3d-light-off",
+ "stock_3d-light-on",
+ "stock_3d-material",
+ "stock_3d-normals-double-sided",
+ "stock_3d-normals-double-sided-closed-body",
+ "stock_3d-normals-flat",
+ "stock_3d-normals-flip-illumination",
+ "stock_3d-normals-object-specific",
+ "stock_3d-normals-spherical",
+ "stock_3d-perspective",
+ "stock_3d-shading",
+ "stock_3d-texture",
+ "stock_3d-texture-and-shading",
+ "stock_3d-texture-object-specific",
+ "stock_3d-texture-only",
+ "stock_3d-texture-parallel",
+ "stock_3d-texture-spherical",
+ "stock_add-bookmark",
+ "stock_auto-contour",
+ "stock_bookmark",
+ "stock_bring-backward",
+ "stock_bring-forward",
+ "stock_create-with-attributes",
+ "stock_delete-bookmark",
+ "stock_edit-bookmark",
+ "stock_effects",
+ "stock_effects-more-options",
+ "stock_effects-object",
+ "stock_effects-object-colorize",
+ "stock_effects-object-hide",
+ "stock_effects-play-in-full",
+ "stock_effects-preview",
+ "stock_enter-group",
+ "stock_exit-group",
+ "stock_file-with-objects",
+ "stock_format-object",
+ "stock_formula-cursor",
+ "stock_frame",
+ "stock_group",
+ "stock_handles-big",
+ "stock_handles-simple",
+ "stock_insert-applet",
+ "stock_insert-floating-frame",
+ "stock_insert-gluepoint",
+ "stock_insert-math-object",
+ "stock_insert-note",
+ "stock_insert-ole-object",
+ "stock_insert-plugin",
+ "stock_insert-rule",
+ "stock_insert-single-column-text-frame",
+ "stock_insert-slide",
+ "stock_insert-sound-plugin",
+ "stock_insert-text-frame",
+ "stock_insert_graphic",
+ "stock_insert_special_character",
+ "stock_interaction",
+ "stock_new-bcard",
+ "stock_new-window",
+ "stock_object-behind",
+ "stock_object-infront",
+ "stock_pin",
+ "stock_position-size",
+ "stock_reverse-order",
+ "stock_slide-design",
+ "stock_slide-duplicate",
+ "stock_slide-expand",
+ "stock_slide-reherse-timings",
+ "stock_slide-show",
+ "stock_slide-showhide",
+ "stock_snap-grid",
+ "stock_snap-guides",
+ "stock_snap-margins",
+ "stock_snap-object",
+ "stock_snap-object-points",
+ "stock_symbol-selection",
+ "stock_to-3d",
+ "stock_to-3d-rotation-object",
+ "stock_to-bottom",
+ "stock_to-curve",
+ "stock_to-polygon",
+ "stock_to-top",
+ "stock_ungroup",
+ "stock_unlink",
+ "stock_view-function-selection",
+ "stock_alignment",
+ "stock_alignment-bottom",
+ "stock_alignment-centered",
+ "stock_alignment-centered-vertically",
+ "stock_alignment-left",
+ "stock_alignment-right",
+ "stock_alignment-top",
+ "stock_cell-align-bottom",
+ "stock_cell-align-center",
+ "stock_cell-align-top",
+ "stock_choose-themes",
+ "stock_datapilot",
+ "stock_delete-column",
+ "stock_delete-row",
+ "stock_exchange-columns",
+ "stock_exchange-rows",
+ "stock_group-cells",
+ "stock_insert-cells",
+ "stock_insert-cells-down",
+ "stock_insert-cells-right",
+ "stock_insert-columns",
+ "stock_insert-names-define",
+ "stock_insert-rows",
+ "stock_insert-table",
+ "stock_select-cell",
+ "stock_select-column",
+ "stock_select-row",
+ "stock_select-table",
+ "stock_sort-table-column-ascending",
+ "stock_sort-table-row-ascending",
+ "stock_table-align-bottom",
+ "stock_table-align-center",
+ "stock_table-align-top",
+ "stock_table-borders",
+ "stock_table-combine",
+ "stock_table-fit-height",
+ "stock_table-fit-width",
+ "stock_table-fixed",
+ "stock_table-fixed-proportional",
+ "stock_table-line-color",
+ "stock_table-line-style",
+ "stock_table-optimize",
+ "stock_table-same-height",
+ "stock_table-same-width",
+ "stock_table-split",
+ "stock_table-variable",
+ "stock_table_borders",
+ "stock_table_fill",
+ "stock_ungroup-cells",
+ "stock_autoformat",
+ "stock_autospellcheck",
+ "stock_autotext",
+ "stock_chart-scale-text",
+ "stock_decrease-font",
+ "stock_directcursor",
+ "stock_draw-text",
+ "stock_draw-text-animation",
+ "stock_draw-text-frame",
+ "stock_draw-vertical-text",
+ "stock_draw-vertical-text-frame",
+ "stock_edit-contour",
+ "stock_edit-headers-and-footers",
+ "stock_effects-text",
+ "stock_euro",
+ "stock_font",
+ "stock_font-formatting-toggle",
+ "stock_font-size",
+ "stock_fontwork",
+ "stock_fontwork-2dshadow",
+ "stock_fontwork-3dshadow",
+ "stock_fontwork-adaptation-off",
+ "stock_fontwork-adaptation-rotate",
+ "stock_fontwork-adaptation-slant-h",
+ "stock_fontwork-adaptation-slant-v",
+ "stock_fontwork-adaptation-straight",
+ "stock_fontwork-align-fill",
+ "stock_fontwork-noshadow",
+ "stock_fontwork-preview-spline",
+ "stock_fontwork-reverse-text-flow",
+ "stock_fontwork-shadow-angle",
+ "stock_fontwork-shadow-length",
+ "stock_fontwork-shadow-x-offset",
+ "stock_fontwork-shadow-y-offset",
+ "stock_fontwork-spline-distance",
+ "stock_fontwork-spline-indent",
+ "stock_fontwork-text-border",
+ "stock_format-character",
+ "stock_format-numbering-bullets",
+ "stock_format-paragraph",
+ "stock_increase-font",
+ "stock_insert-caption",
+ "stock_insert-cross-reference",
+ "stock_insert-fields-author",
+ "stock_insert-fields-subject",
+ "stock_insert-fields-title",
+ "stock_insert-footer",
+ "stock_insert-header",
+ "stock_insert_endnote",
+ "stock_insert_footnote",
+ "stock_insert_index_marker",
+ "stock_insert_section",
+ "stock_line-spacing-1",
+ "stock_line-spacing-1.5",
+ "stock_line-spacing-2",
+ "stock_list-insert-unnumbered",
+ "stock_list_bullet",
+ "stock_list_enum",
+ "stock_list_enum-off",
+ "stock_list_enum-restart",
+ "stock_nonprinting-chars",
+ "stock_page-number",
+ "stock_page-total-number",
+ "stock_paragraph-spacing-decrease",
+ "stock_paragraph-spacing-increase",
+ "stock_select-all",
+ "stock_spellcheck",
+ "stock_styles-character-styles",
+ "stock_styles-fill-format-mode",
+ "stock_styles-frame-styles",
+ "stock_styles-new-style-from-selection",
+ "stock_styles-numbering-styles",
+ "stock_styles-page-styles",
+ "stock_styles-paragraph-styles",
+ "stock_styles-update-style",
+ "stock_subscript",
+ "stock_superscript",
+ "stock_text-direction-ltr",
+ "stock_text-direction-ttb",
+ "stock_text-double-click-to-edit",
+ "stock_text-monospaced",
+ "stock_text-outline",
+ "stock_text-quickedit",
+ "stock_text-select-text-only",
+ "stock_text-shadow",
+ "stock_text-spacing",
+ "stock_text-strikethrough",
+ "stock_text_bold",
+ "stock_text_center",
+ "stock_text_color_background",
+ "stock_text_color_foreground",
+ "stock_text_color_hilight",
+ "stock_text_indent",
+ "stock_text_italic",
+ "stock_text_justify",
+ "stock_text_left",
+ "stock_text_right",
+ "stock_text_underlined",
+ "stock_text_underlined-double",
+ "stock_text_unindent",
+ "stock_thesaurus",
+ "stock_to-background",
+ "stock_to-foreground",
+ "stock_tools-hyphenation",
+ "stock_update-fields",
+ "stock_view-field-shadings",
+ "stock_wrap-around",
+ "stock_wrap-behind",
+ "stock_wrap-contour",
+ "stock_wrap-interrupt",
+ "stock_wrap-left",
+ "stock_wrap-optimal",
+ "stock_wrap-right"
+#endif
+};
+
+int GladeNamedIconsSize = G_N_ELEMENTS (GladeNamedIcons);
diff --git a/tools/glade/glade/palette.c b/tools/glade/glade/palette.c
new file mode 100644
index 00000000..89738c44
--- /dev/null
+++ b/tools/glade/glade/palette.c
@@ -0,0 +1,156 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <gtk/gtkmenu.h>
+
+#include "gladeconfig.h"
+
+#include "glade.h"
+#include "gbwidget.h"
+#include "glade_gtk12lib.h"
+#include "palette.h"
+#include "glade_palette.h"
+#include "glade_project.h"
+#include "glade_project_window.h"
+
+
+static void on_palette_select_item (GladePalette *palette,
+ gchar *item_name);
+static void palette_finish_new_component (GtkWidget *component,
+ GbWidgetNewData *data);
+
+static GdkColormap *colormap;
+
+
+void
+palette_init ()
+{
+ glade_palette = glade_palette_new ();
+ gtk_window_move (GTK_WINDOW (glade_palette), 0, 250);
+ gtk_window_set_type_hint (GTK_WINDOW (glade_palette),
+ GDK_WINDOW_TYPE_HINT_UTILITY);
+ gtk_window_set_wmclass (GTK_WINDOW (glade_palette), "palette", "Glade");
+ gtk_window_add_accel_group (GTK_WINDOW (glade_palette),
+ glade_get_global_accel_group ());
+
+ gtk_signal_connect (GTK_OBJECT (glade_palette), "delete_event",
+ GTK_SIGNAL_FUNC (palette_hide), NULL);
+
+ gtk_signal_connect (GTK_OBJECT (glade_palette), "hide",
+ GTK_SIGNAL_FUNC (glade_project_window_uncheck_palette_menu_item),
+ NULL);
+
+ gtk_window_set_title (GTK_WINDOW (glade_palette), _("Palette"));
+ gtk_container_set_border_width (GTK_CONTAINER (glade_palette), 0);
+ colormap = gtk_widget_get_colormap (glade_palette);
+
+ gtk_signal_connect (GTK_OBJECT (glade_palette), "select_item",
+ GTK_SIGNAL_FUNC (on_palette_select_item), NULL);
+}
+
+
+void
+palette_add_gbwidget (GbWidget *gbwidget,
+ gchar *section,
+ gchar *name)
+{
+ gboolean show_section;
+
+ show_section = (!strcmp (section, "NotShown")) ? FALSE : TRUE;
+
+ /* Create the widget's pixmap, if it has one. */
+ if (gbwidget->pixmap_struct && !gbwidget->gdkpixmap)
+ gbwidget->gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &(gbwidget->mask), NULL, gbwidget->pixmap_struct);
+
+ if (show_section)
+ glade_palette_add_widget (GLADE_PALETTE (glade_palette),
+ _(section), name,
+ gbwidget->gdkpixmap, gbwidget->mask,
+ gbwidget->tooltip);
+
+}
+
+
+void
+palette_show (GtkWidget * widget,
+ gpointer data)
+{
+ gtk_widget_show (glade_palette);
+ /* This maps the window, which also de-iconifies it according to ICCCM. */
+ gdk_window_show (GTK_WIDGET (glade_palette)->window);
+ gdk_window_raise (GTK_WIDGET (glade_palette)->window);
+}
+
+
+gint
+palette_hide (GtkWidget * widget,
+ gpointer data)
+{
+ gtk_widget_hide (glade_palette);
+ return TRUE;
+}
+
+
+static void
+on_palette_select_item (GladePalette *palette,
+ gchar *class_name)
+{
+ GtkType type;
+
+ /* Ignore the selector. */
+ if (class_name == NULL)
+ return;
+
+ /* If we don't have a project open, just reset the selection. Hopefully
+ we'll make the palette insensitive in that case so this won't happen. */
+ if (current_project == NULL)
+ {
+ glade_palette_reset_selection (GLADE_PALETTE (glade_palette), FALSE);
+ return;
+ }
+
+ /* See if a toplevel item was selected - a window, dialog or menu.
+ If it was, we create a new component and reset the palette. */
+ type = g_type_from_name (class_name);
+#if 0
+ g_print ("Class Name: %s Type: %li\n", class_name, type);
+#endif
+
+ /* We just return if the type isn't found (e.g. for the custom widget). */
+ if (type == 0)
+ return;
+
+ if (gtk_type_is_a (type, gtk_window_get_type ())
+ || gtk_type_is_a (type, gtk_menu_get_type ()))
+ {
+ gb_widget_new_full (class_name, TRUE, NULL, NULL, 0, 0,
+ palette_finish_new_component, GB_CREATING, NULL);
+ glade_palette_reset_selection (GLADE_PALETTE (glade_palette), FALSE);
+ }
+}
+
+
+static void
+palette_finish_new_component (GtkWidget *component, GbWidgetNewData *data)
+{
+ glade_project_add_component (data->project, component);
+ glade_project_show_component (data->project, component);
+ gb_widget_show_properties (component);
+}
diff --git a/tools/glade/glade/palette.h b/tools/glade/glade/palette.h
new file mode 100644
index 00000000..63d5a28f
--- /dev/null
+++ b/tools/glade/glade/palette.h
@@ -0,0 +1,41 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADEPALETTE_H
+#define GLADEPALETTE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "glade.h"
+
+void palette_init (void);
+void palette_add_gbwidget (GbWidget *gbwidget,
+ gchar *section,
+ gchar *name);
+void palette_show (GtkWidget *widget,
+ gpointer data);
+gint palette_hide (GtkWidget *widget,
+ gpointer data);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADEPALETTE_H */
diff --git a/tools/glade/glade/property.c b/tools/glade/glade/property.c
new file mode 100644
index 00000000..5c21d5ec
--- /dev/null
+++ b/tools/glade/glade/property.c
@@ -0,0 +1,5672 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "gladeconfig.h"
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#endif
+
+#include "editor.h"
+#include "glade_atk.h"
+#include "glade_keys_dialog.h"
+#include "glade_project.h"
+#include "glade_project_window.h"
+#include "utils.h"
+#include "gbwidget.h"
+#include "property.h"
+#include "load.h"
+#include "save.h"
+
+/* These are the standard widget attribute names */
+const gchar *GbName = "GtkWidget::name";
+const gchar *GbClass = "GtkWidget::class";
+const gchar *GbWidth = "GtkWidget::width_request";
+const gchar *GbHeight = "GtkWidget::height_request";
+const gchar *GbVisible = "GtkWidget::visible";
+const gchar *GbSensitive = "GtkWidget::sensitive";
+const gchar *GbTooltip = "GtkWidget::tooltip";
+const gchar *GbCanDefault = "GtkWidget::can_default";
+const gchar *GbHasDefault = "GtkWidget::has_default";
+const gchar *GbCanFocus = "GtkWidget::can_focus";
+const gchar *GbHasFocus = "GtkWidget::has_focus";
+const gchar *GbEvents = "GtkWidget::events";
+const gchar *GbExtEvents = "GtkWidget::extension_events";
+
+/* This is just a button to show the accelerators dialog. */
+const gchar *GbAccelerators = "GtkWidget::accelerators";
+
+/* Language-Specific properties. */
+/* C-specific properties. */
+const gchar *GbCSourceFile = "GtkWidget::c_source_file";
+const gchar *GbCPublic = "GtkWidget::c_public";
+
+/* C++-specific properties. */
+const gchar *GbCxxSeparateFile = "GtkWidget::cxx_separate_file";
+const gchar *GbCxxSeparateClass = "GtkWidget::cxx_separate_class";
+const gchar *GbCxxVisibility = "GtkWidget::cxx_visibility";
+
+/* Visibility choices data */
+const gchar *GbCxxVisibilityChoices[] =
+{N_("private"), N_("protected"), N_("public"), NULL};
+const gint GbCxxVisibilityValues[] =
+{ 0, 1, 2
+};
+const gchar *GbCxxVisibilitySymbols[] =
+{
+ "private",
+ "protected",
+ "public"
+};
+
+/* Widget style properties. */
+const gchar *GbStylePropagate = "GtkWidget::style_propagate";
+const gchar *GbStyleName = "GtkWidget::style_name";
+const gchar *GbStyleFont = "GtkWidget::style_font";
+
+/* Signals page */
+const gchar *GbSignalName = "GtkWidget::signal_name";
+const gchar *GbSignalHandler = "GtkWidget::signal_handler";
+const gchar *GbSignalObject = "GtkWidget::signal_object";
+const gchar *GbSignalAfter = "GtkWidget::signal_after";
+const gchar *GbSignalData = "GtkWidget::signal_data";
+
+/* Accelerators page */
+const gchar *GbAccelKey = "GtkWidget::accelerator_key";
+const gchar *GbAccelSignal = "GtkWidget::accelerator_signal";
+
+
+const gchar *GbStateTabLabels[] =
+{ N_("Normal"), N_("Active"), N_("Prelight"),
+ N_("Selected"), N_("Insens") };
+
+/* Keys in object data hash used to store color, bg pixmap & filename */
+const gchar *GbColorKey = "GbColor";
+const gchar *GbBgPixmapKey = "GbBgPixmap";
+const gchar *GbBgFilenameKey = "GbBgFilename";
+const gchar *GbValueWidgetKey = "GbValue";
+const gchar *GbDialogValueKey = "GbDialogValue";
+const gchar *GbFilenameValueKey = "GbFilenameValue";
+const gchar *GbFontKey = "GbFont";
+const gchar *GbFontSpecKey = "GbFontSpec";
+const gchar *GladeStockIDKey = "GladeStockID";
+
+/* Extension mode choices data */
+const gchar *GbExtensionModeChoices[] =
+{"None", "All", "Cursor", NULL};
+const gint GbExtensionModeValues[] =
+{
+ GDK_EXTENSION_EVENTS_NONE,
+ GDK_EXTENSION_EVENTS_ALL,
+ GDK_EXTENSION_EVENTS_CURSOR
+};
+const gchar *GbExtensionModeSymbols[] =
+{
+ "GDK_EXTENSION_EVENTS_NONE",
+ "GDK_EXTENSION_EVENTS_ALL",
+ "GDK_EXTENSION_EVENTS_CURSOR"
+};
+
+/*
+ * Private variables
+ */
+
+/* Hashtables of all the label & value widgets on the various property pages */
+static GHashTable *gb_property_labels = NULL;
+static GHashTable *gb_property_values = NULL;
+static GHashTable *gb_property_buttons = NULL;
+
+/* Major components of the property window */
+#define GB_PAGE_WIDGET 0
+#define GB_PAGE_SIGNALS 3
+#define GB_PAGE_ATK 4
+GtkWidget *win_property = NULL;
+static GtkWidget *main_notebook = NULL;
+static GtkWidget *property_widget_notebook;
+static gint property_language = GLADE_LANGUAGE_C;
+static GtkWidget **lang_specific_properties;
+static GtkWidget *special_child_property_notebook;
+static GtkWidget *apply_button = NULL;
+#ifdef GLADE_STYLE_SUPPORT
+static GtkWidget *styles_notebook;
+#endif
+
+static GtkTooltips *tooltips;
+
+/* The widget whose properties are currently shown (or NULL) */
+static GtkWidget *property_widget = NULL;
+
+/* This is used when typing over a widget in the interface to set its label. */
+static gboolean typing_over_widget = FALSE;
+
+static GtkStyle *invalid_style;
+
+/* The current table & row used when creating properties */
+static GtkWidget *property_table;
+static gint property_table_row;
+
+/* This is used when automatically applying properties as they are changed.
+ It is on most of the time, except when changes are being made to property
+ values which we don't want to result in a callback. */
+static gboolean auto_apply;
+
+/* Color selection dialog */
+static GtkColorSelectionDialog *colorsel = NULL;
+static GtkWidget *color_value = NULL;
+
+/* File selection dialog */
+static GtkWidget *filesel = NULL;
+static GtkWidget *filename_value = NULL;
+
+/* Font selection fialog */
+static GtkFontSelectionDialog *fontsel = NULL;
+
+/* Widgets in Accelerators dialog. */
+#define ACCEL_MODIFIERS_COL 0
+#define ACCEL_KEY_COL 1
+#define ACCEL_SIGNAL_COL 2
+static GtkWidget *accel_dialog = NULL;
+static GtkWidget *accel_clist;
+static GtkWidget *accel_control_button;
+static GtkWidget *accel_shift_button;
+static GtkWidget *accel_alt_button;
+
+/* Widgets on Signals page */
+#define SIGNAL_NAME_COL 0
+#define SIGNAL_HANDLER_COL 1
+#define SIGNAL_DATA_COL 2
+#define SIGNAL_AFTER_COL 3
+#define SIGNAL_OBJECT_COL 4
+static GtkWidget *signal_clist;
+/* This holds the last modification time of the GladeSignals currently being
+ edited. */
+static GMemChunk *signal_mem_chunk;
+
+/* Clipboard used for copying/pasting colors - could possibly use GTK clipbd? */
+#define GB_COLOR_CLIPBD_EMPTY 1
+#define GB_COLOR_CLIPBD_COLOR 2
+#define GB_COLOR_CLIPBD_BGPIXMAP 3
+#define GB_COLOR_CLIPBD_STATE 4
+
+#ifdef GLADE_STYLE_SUPPORT
+static gint clipbd_state = GB_COLOR_CLIPBD_EMPTY;
+static GdkColor clipbd_colors[GB_NUM_STYLE_COLORS];
+static GdkPixmap *clipbd_bgpixmap;
+static gchar *clipbd_bgfilename;
+static GtkWidget *selected_style_widget = NULL;
+#endif
+
+
+/* The list of GTK+ stock items. */
+static GSList *stock_items = NULL;
+static GHashTable *stock_nsizes_hash = NULL;
+static GHashTable *stock_sizes_hash = NULL;
+
+/* Keys used in the GtkCombo value for stock items/icons. */
+static const gchar *GladeIconSizeKey = "GladeIconSizeKey";
+static const gchar *GladeNeedLabelKey = "GladeNeedLabelKey";
+
+
+static const gchar *GladeIsStringPropertyKey = "GladeIsStringPropertyKey";
+static const gchar *GladeShowTranslationPropertiesKey = "GladeShowTranslationPropertiesKey";
+
+/*
+ * Private functions
+ */
+
+static GtkWidget *create_widget_property_page ();
+static GtkWidget *create_standard_property_page ();
+static GtkWidget *create_special_child_properties ();
+static void create_language_specific_properties (GtkWidget *vbox);
+#ifdef GLADE_STYLE_SUPPORT
+static GtkWidget *create_style_property_page ();
+static GtkWidget *create_style_page (const gchar * state);
+#endif
+static GtkWidget *create_signals_property_page ();
+
+static const gchar* property_add (const gchar * property_name,
+ const gchar * label_string,
+ GtkWidget * value,
+ GtkWidget * dialog_button,
+ const gchar * tooltip);
+
+static void on_bool_property_toggle (GtkWidget * value,
+ gpointer data);
+
+static GtkWidget *create_color_preview ();
+static gboolean show_color_in_preview (GtkWidget * preview,
+ GdkColor *color);
+static void on_color_draw (GtkWidget * widget,
+ gpointer data);
+static void on_color_expose_event (GtkWidget * widget,
+ GdkEvent * event,
+ gpointer data);
+static void on_color_select (GtkWidget * widget,
+ gpointer data);
+
+static void show_pixmap_in_drawing_area (GtkWidget * drawing_area,
+ GdkPixmap * gdkpixmap);
+
+static gint expose_pixmap (GtkWidget * drawing_area,
+ GdkEventExpose * event,
+ gpointer data);
+
+static void show_events_dialog (GtkWidget * widget,
+ gpointer value);
+static void on_events_dialog_response (GtkWidget * widget,
+ gint response_id,
+ GtkWidget * clist);
+
+static void show_keys_dialog (GtkWidget * widget,
+ gpointer value);
+static void on_keys_clist_select (GtkWidget * widget,
+ gint row,
+ gint column,
+ GdkEventButton * bevent,
+ gpointer data);
+static void on_keys_dialog_response (GtkWidget * widget,
+ gint response_id,
+ gpointer data);
+
+static void show_signals_dialog (GtkWidget * widget,
+ gpointer value);
+static void on_signals_clist_select (GtkWidget * widget,
+ gint row,
+ gint column,
+ GdkEventButton * bevent,
+ gpointer data);
+static void on_signals_dialog_response (GtkWidget * widget,
+ gint response_id,
+ GtkWidget * clist);
+
+static void show_accelerators_dialog (GtkWidget * widget,
+ gpointer value);
+static void create_accelerators_dialog ();
+static void on_accelerator_add (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_accelerator_update (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_accelerator_delete (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_accelerator_clear (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_accelerator_select (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data);
+
+static void on_signal_add (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_signal_update (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_signal_delete (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_signal_clear (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_signal_select (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data);
+
+#ifdef GLADE_STYLE_SUPPORT
+static void on_style_copy (GtkWidget * widget,
+ gpointer data);
+static void on_style_copy_all (GtkWidget * widget,
+ gpointer data);
+static void on_style_paste (GtkWidget * widget,
+ gpointer data);
+#endif
+
+/* Currently unused - its all auto-applied
+ static void on_apply (GtkWidget *widget,
+ gpointer data);
+ */
+static void on_property_changed (GtkWidget * widget,
+ GtkWidget * property);
+static gboolean on_property_focus_out (GtkWidget * widget,
+ GdkEventFocus *event,
+ GtkWidget * property);
+
+static void set_pixmap (GtkWidget * drawing_area,
+ GdkPixmap * gdkpixmap,
+ const gchar * filename);
+
+static void show_colorsel_dialog (GtkWidget * widget,
+ gpointer data);
+static void on_colorsel_dialog_ok (GtkWidget * widget,
+ gpointer data);
+static gint close_dialog_event (GtkWidget * widget,
+ GdkEvent * event,
+ GtkWidget * dialog);
+static void close_dialog (GtkWidget * widget,
+ GtkWidget * dialog);
+
+static void show_filesel_dialog (GtkWidget * widget,
+ gpointer data);
+static void on_filesel_response (GtkWidget * widget,
+ gint response_id,
+ gpointer data);
+
+static void show_font_dialog (GtkWidget * widget,
+ gpointer data);
+#if 0
+static gint get_font_size_from_spec (const gchar * spec);
+#endif
+static gchar *get_font_name_from_spec (const gchar * spec);
+static void on_font_dialog_apply (GtkWidget * widget,
+ GtkFontSelectionDialog * fontsel);
+static void on_font_dialog_ok (GtkWidget * widget,
+ GtkFontSelectionDialog * fontsel);
+
+#ifdef GLADE_STYLE_SUPPORT
+static void show_style_dialog (GtkWidget * widget,
+ gpointer value);
+static gint add_style_to_clist (const gchar * key,
+ gpointer data,
+ GtkWidget * clist);
+static void on_style_clist_select (GtkWidget * widget,
+ gint row,
+ gint column,
+ GdkEventButton * bevent,
+ gpointer data);
+static void on_style_dialog_new (GtkWidget * widget,
+ GtkWidget * clist);
+static gint create_new_style (GtkWidget * widget,
+ const gchar * name,
+ GbStyle * base_gbstyle);
+static void on_style_dialog_ok (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_style_dialog_copy (GtkWidget * widget,
+ GtkWidget * clist);
+static void on_style_dialog_rename (GtkWidget * widget,
+ GtkWidget * clist);
+static gint rename_style (GtkWidget * widget,
+ const gchar * name,
+ GbStyle * gbstyle);
+static void on_style_dialog_delete (GtkWidget * widget,
+ GtkWidget * clist);
+#endif
+
+static void on_toggle_set_width (GtkWidget * widget, gpointer value);
+static void on_toggle_set_height (GtkWidget * widget, gpointer value);
+
+const gchar *GbEventMaskSymbols[GB_EVENT_MASKS_COUNT] =
+{
+ "GDK_EXPOSURE_MASK",
+ "GDK_POINTER_MOTION_MASK",
+ "GDK_POINTER_MOTION_HINT_MASK",
+ "GDK_BUTTON_MOTION_MASK",
+ "GDK_BUTTON1_MOTION_MASK",
+ "GDK_BUTTON2_MOTION_MASK",
+ "GDK_BUTTON3_MOTION_MASK",
+ "GDK_BUTTON_PRESS_MASK",
+ "GDK_BUTTON_RELEASE_MASK",
+ "GDK_KEY_PRESS_MASK",
+ "GDK_KEY_RELEASE_MASK",
+ "GDK_ENTER_NOTIFY_MASK",
+ "GDK_LEAVE_NOTIFY_MASK",
+ "GDK_FOCUS_CHANGE_MASK",
+ "GDK_STRUCTURE_MASK",
+ "GDK_PROPERTY_CHANGE_MASK",
+ "GDK_VISIBILITY_NOTIFY_MASK",
+ "GDK_PROXIMITY_IN_MASK",
+ "GDK_PROXIMITY_OUT_MASK",
+};
+
+
+const gint GbEventMaskValues[GB_EVENT_MASKS_COUNT] =
+{
+ GDK_EXPOSURE_MASK,
+ GDK_POINTER_MOTION_MASK,
+ GDK_POINTER_MOTION_HINT_MASK,
+ GDK_BUTTON_MOTION_MASK,
+ GDK_BUTTON1_MOTION_MASK,
+ GDK_BUTTON2_MOTION_MASK,
+ GDK_BUTTON3_MOTION_MASK,
+ GDK_BUTTON_PRESS_MASK,
+ GDK_BUTTON_RELEASE_MASK,
+ GDK_KEY_PRESS_MASK,
+ GDK_KEY_RELEASE_MASK,
+ GDK_ENTER_NOTIFY_MASK,
+ GDK_LEAVE_NOTIFY_MASK,
+ GDK_FOCUS_CHANGE_MASK,
+ GDK_STRUCTURE_MASK,
+ GDK_PROPERTY_CHANGE_MASK,
+ GDK_VISIBILITY_NOTIFY_MASK,
+ GDK_PROXIMITY_IN_MASK,
+ GDK_PROXIMITY_OUT_MASK
+};
+
+
+static const gchar *GbEventMaskDescriptions[GB_EVENT_MASKS_COUNT] =
+{
+ N_("When the window needs redrawing"),
+ N_("When the mouse moves"),
+ N_("Mouse movement hints"),
+ N_("Mouse movement with any button pressed"),
+ N_("Mouse movement with button 1 pressed"),
+ N_("Mouse movement with button 2 pressed"),
+ N_("Mouse movement with button 3 pressed"),
+ N_("Any mouse button pressed"),
+ N_("Any mouse button released"),
+ N_("Any key pressed"),
+ N_("Any key released"),
+ N_("When the mouse enters the window"),
+ N_("When the mouse leaves the window"),
+ N_("Any change in input focus"),
+ N_("Any change in window structure"),
+ N_("Any change in X Windows property"),
+ N_("Any change in visibility"),
+ N_("For cursors in XInput-aware programs"),
+ N_("For cursors in XInput-aware programs")
+};
+
+/*
+ * Create the properties window
+ */
+
+
+static void
+create_stock_items (void)
+{
+ GSList *elem;
+
+ stock_items = gtk_stock_list_ids ();
+ stock_items = g_slist_sort (stock_items, glade_util_compare_stock_labels);
+
+ /* We also keep data about which icon sizes are available for each stock
+ item, in a GHashTable. The key is the stock_id. */
+ stock_nsizes_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ stock_sizes_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (elem = stock_items; elem; elem = elem->next)
+ {
+ gchar *stock_id;
+ GtkIconSet *icon_set;
+ GtkIconSize *sizes;
+ gint n_sizes;
+#if 0
+ gint i;
+#endif
+
+ stock_id = elem->data;
+ icon_set = gtk_icon_factory_lookup_default (stock_id);
+ if (icon_set)
+ {
+ gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
+
+#if 0
+ g_print ("Stock ID %s Icon Set: %p Sizes:", stock_id, icon_set);
+ for (i = 0; i < n_sizes; i++)
+ g_print (" %i", sizes[i]);
+ g_print ("\n");
+#endif
+
+ /* Note that we use the stock_id as the keys, without copying it,
+ so they are only valid while stock_items exists. */
+ g_hash_table_insert (stock_nsizes_hash, stock_id,
+ GINT_TO_POINTER (n_sizes));
+ g_hash_table_insert (stock_sizes_hash, stock_id, sizes);
+ }
+ }
+}
+
+
+static gboolean
+propagate_key_press_to_main_notebook (GtkWidget *notebook,
+ GdkEventKey *event,
+ gpointer data)
+{
+
+ if (event->state & GDK_CONTROL_MASK)
+ {
+ if (event->keyval == GDK_Page_Up)
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (main_notebook),
+ "change_current_page", -1);
+ return TRUE;
+ }
+ else if (event->keyval == GDK_Page_Down)
+ {
+ gtk_signal_emit_by_name (GTK_OBJECT (main_notebook),
+ "change_current_page", 1);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+void
+property_init ()
+{
+ GtkWidget *vbox1, *label, *child, *page;
+
+ /* Create hash table for widgets containing property values */
+ gb_property_labels = g_hash_table_new (g_str_hash, g_str_equal);
+ gb_property_values = g_hash_table_new (g_str_hash, g_str_equal);
+ gb_property_buttons = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* Create the mem chunk for storing signal last modification times. */
+ signal_mem_chunk = g_mem_chunk_create (time_t, 16, G_ALLOC_ONLY);
+
+ /* Create property window */
+ win_property = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_move (GTK_WINDOW (win_property), 300, 0);
+ gtk_window_set_default_size (GTK_WINDOW (win_property), 260, -1);
+ gtk_widget_set_name (win_property, "GladeObjectInspector");
+ gtk_window_set_wmclass (GTK_WINDOW (win_property),
+ "object_inspector", "Glade");
+ gtk_widget_realize (win_property);
+ gtk_window_add_accel_group (GTK_WINDOW (win_property),
+ glade_get_global_accel_group ());
+
+ gtk_signal_connect (GTK_OBJECT (win_property), "delete_event",
+ GTK_SIGNAL_FUNC (property_hide), NULL);
+
+ gtk_signal_connect_after (GTK_OBJECT (win_property), "hide",
+ GTK_SIGNAL_FUNC (glade_project_window_uncheck_property_editor_menu_item),
+ NULL);
+
+ gtk_window_set_title (GTK_WINDOW (win_property), _("Properties"));
+ gtk_container_set_border_width (GTK_CONTAINER (win_property), 0);
+
+ tooltips = gtk_tooltips_new ();
+
+ vbox1 = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (win_property), vbox1);
+ gtk_widget_show (vbox1);
+
+ /* Create main notebook for different categories of widget properties */
+ main_notebook = gtk_notebook_new ();
+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (main_notebook), GTK_POS_TOP);
+ gtk_notebook_set_tab_vborder (GTK_NOTEBOOK (main_notebook), 0);
+ gtk_box_pack_start (GTK_BOX (vbox1), main_notebook, TRUE, TRUE, 0);
+ gtk_widget_show (main_notebook);
+
+ /* Create the pages of the main notebook */
+ /* NOTE: If you add/remove pages you need to change the GB_PAGE_SIGNALS
+ value at the top of this file */
+ label = gtk_label_new (_("Widget"));
+ gtk_widget_show (label);
+ child = create_widget_property_page ();
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_notebook), child, label);
+
+ label = gtk_label_new (_("Packing"));
+ gtk_widget_show (label);
+ child = create_special_child_properties ();
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_notebook), child, label);
+
+ label = gtk_label_new (_("Common"));
+ gtk_widget_show (label);
+ child = create_standard_property_page ();
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_notebook), child, label);
+
+#ifdef GLADE_STYLE_SUPPORT
+ label = gtk_label_new (_("Style"));
+ gtk_widget_show (label);
+ child = create_style_property_page ();
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_notebook), child, label);
+#endif
+
+ label = gtk_label_new (_("Signals"));
+ gtk_widget_show (label);
+ child = create_signals_property_page ();
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_notebook), child, label);
+
+ /* Create style to use when a property value is invalid - it's not used
+ at present. */
+ invalid_style = gtk_style_new ();
+ invalid_style->fg[GTK_STATE_NORMAL].red = 65535;
+ invalid_style->fg[GTK_STATE_NORMAL].green = 0;
+ invalid_style->fg[GTK_STATE_NORMAL].blue = 0;
+
+ create_accelerators_dialog ();
+
+ create_stock_items ();
+
+ /* Create the ATK properties page. */
+ glade_atk_create_property_page (GTK_NOTEBOOK (main_notebook));
+
+ /* Make sure Ctrl+PgUp/Down switch the main notebook page. */
+ page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (main_notebook),
+ GB_PAGE_ATK);
+ gtk_signal_connect (GTK_OBJECT (GTK_BIN (page)->child),
+ "key_press_event",
+ GTK_SIGNAL_FUNC (propagate_key_press_to_main_notebook), NULL);
+}
+
+
+void
+property_show (GtkWidget * widget,
+ gpointer data)
+{
+ gtk_widget_show (win_property);
+ /* This maps the window, which also de-iconifies it according to ICCCM. */
+ gdk_window_show (GTK_WIDGET (win_property)->window);
+ gdk_window_raise (GTK_WIDGET (win_property)->window);
+ property_set_widget (NULL);
+}
+
+gint
+property_hide (GtkWidget * widget,
+ gpointer data)
+{
+ gtk_widget_hide (win_property);
+ return TRUE;
+}
+
+
+GtkWidget *
+property_get_widget ()
+{
+ return property_widget;
+}
+
+
+void
+property_update_title (void)
+{
+ gchar buffer[128];
+ gchar *name;
+
+ if (property_widget)
+ {
+ strcpy (buffer, _("Properties: "));
+ name = (char*) gtk_widget_get_name (property_widget);
+ strncat (buffer, name, 120 - strlen (buffer));
+ gtk_window_set_title (GTK_WINDOW (win_property), buffer);
+ }
+ else
+ {
+ gtk_window_set_title (GTK_WINDOW (win_property),
+ _("Properties: <none>"));
+ }
+}
+
+
+void
+property_set_widget (GtkWidget * widget)
+{
+ gchar buffer[128];
+ gchar *name;
+
+ if (widget)
+ {
+ strcpy (buffer, _("Properties: "));
+ name = (char*) gtk_widget_get_name (widget);
+ strncat (buffer, name, 120 - strlen (buffer));
+ gtk_window_set_title (GTK_WINDOW (win_property), buffer);
+ gtk_widget_set_sensitive (main_notebook, TRUE);
+ if (apply_button)
+ gtk_widget_set_sensitive (apply_button, TRUE);
+ property_widget = widget;
+ }
+ else
+ {
+ gtk_window_set_title (GTK_WINDOW (win_property), _("Properties: <none>"));
+ property_hide_gbwidget_page ();
+ gtk_widget_set_sensitive (main_notebook, FALSE);
+ if (apply_button)
+ gtk_widget_set_sensitive (apply_button, FALSE);
+ /* Need to clear the property widget before clearing the name property,
+ since auto-apply may be on, and hence we may clear the name of the
+ currently shown widget. */
+ property_widget = NULL;
+ property_set_string (GbName, NULL);
+ property_set_string (GbClass, NULL);
+ /* Make now-empty property window display properly */
+ gtk_widget_queue_resize (win_property);
+ }
+
+ typing_over_widget = FALSE;
+ glade_atk_update_relation_dialogs ();
+}
+
+
+static GtkWidget *
+create_widget_property_page ()
+{
+ GtkWidget *page, *table, *vbox, *entry;
+
+ page = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show (page);
+ gtk_signal_connect (GTK_OBJECT (page),
+ "key_press_event",
+ GTK_SIGNAL_FUNC (propagate_key_press_to_main_notebook), NULL);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (page), vbox);
+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (GTK_BIN (page)->child),
+ GTK_SHADOW_NONE);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (2, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
+
+ property_set_table_position (table, 0);
+ property_add_string (GbName, _("Name:"),
+ _("The name of the widget"));
+ property_add_string (GbClass, _("Class:"),
+ _("The class of the widget"));
+ entry = property_get_value_widget (GbClass);
+ gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE);
+
+ /* Add language-specific options to a notebook at the bottom. */
+ create_language_specific_properties (vbox);
+
+ gtk_widget_show (table);
+
+ property_widget_notebook = gtk_notebook_new ();
+ gtk_widget_show (property_widget_notebook);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (property_widget_notebook),
+ FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (property_widget_notebook),
+ FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), property_widget_notebook,
+ FALSE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (property_widget_notebook),
+ "key_press_event",
+ GTK_SIGNAL_FUNC (propagate_key_press_to_main_notebook), NULL);
+
+ return page;
+}
+
+
+static GtkWidget *
+create_standard_property_page ()
+{
+ GtkWidget *page;
+
+ page = gtk_table_new (9, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (page), 1);
+
+ property_set_table_position (page, 0);
+ property_add_optional_int_range (GbWidth, _("Width:"),
+ _("The requested width of the widget (usually used to set the minimum width)"),
+ 0, 10000, 1, 10, 1, on_toggle_set_width);
+ property_add_optional_int_range (GbHeight, _("Height:"),
+ _("The requested height of the widget (usually used to set the minimum height)"),
+ 0, 10000, 1, 10, 1, on_toggle_set_height);
+
+ property_add_bool (GbVisible, _("Visible:"),
+ _("If the widget is initially visible"));
+ property_add_bool (GbSensitive, _("Sensitive:"),
+ _("If the widget responds to input"));
+ property_add_string (GbTooltip, _("Tooltip:"),
+ _("The tooltip to display if the mouse lingers over the widget"));
+
+ property_add_bool (GbCanDefault, _("Can Default:"),
+ _("If the widget can be the default action in a dialog"));
+ property_add_bool (GbHasDefault, _("Has Default:"),
+ _("If the widget is the default action in the dialog"));
+ property_add_bool (GbCanFocus, _("Can Focus:"),
+ _("If the widget can accept the input focus"));
+ property_add_bool (GbHasFocus, _("Has Focus:"),
+ _("If the widget has the input focus"));
+
+ property_add_dialog (GbEvents, _("Events:"),
+ _("The X events that the widget receives"),
+ FALSE, show_events_dialog);
+ property_add_choice (GbExtEvents, _("Ext.Events:"),
+ _("The X Extension events mode"),
+ GbExtensionModeChoices);
+
+ property_add_command (GbAccelerators, _("Accelerators:"),
+ _("Defines the signals to emit when keys are pressed"),
+ _("Edit..."),
+ GTK_SIGNAL_FUNC (show_accelerators_dialog));
+
+ gtk_widget_show (page);
+ return page;
+}
+
+
+#ifdef GLADE_STYLE_SUPPORT
+static GtkWidget *
+create_style_property_page ()
+{
+ GtkWidget *page, *table, *label, *child, *hbox, *button;
+ int i;
+
+ page = gtk_vbox_new (FALSE, 0);
+
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_box_pack_start (GTK_BOX (page), table, FALSE, TRUE, 0);
+
+ property_set_table_position (table, 0);
+ property_add_bool (GbStylePropagate, _("Propagate:"),
+ _("Set True to propagate the style to the widget's children"));
+ property_add_dialog (GbStyleName, _("Named Style:"),
+ _("The name of the style, which can be shared by several widgets"),
+ FALSE, show_style_dialog);
+ property_add_font (GbStyleFont, _("Font:"),
+ _("The font to use for any text in the widget"));
+
+ /* Create notebook for 5 states */
+ styles_notebook = gtk_notebook_new ();
+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (styles_notebook), GTK_POS_TOP);
+ gtk_box_pack_start (GTK_BOX (page), styles_notebook, FALSE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (styles_notebook), 0);
+
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ label = gtk_label_new (_(GbStateTabLabels[i]));
+ gtk_widget_show (label);
+ child = create_style_page (GbStateNames[i]);
+ gtk_notebook_append_page (GTK_NOTEBOOK (styles_notebook), child, label);
+ }
+ gtk_widget_show (styles_notebook);
+
+ /* Add/Update/Delete buttons at bottom */
+ hbox = gtk_hbox_new (TRUE, 5);
+ button = gtk_button_new_with_label (_("Copy"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_copy), NULL);
+
+ button = gtk_button_new_with_label (_("Copy All"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_copy_all), NULL);
+
+ button = gtk_button_new_with_label (_("Paste"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_paste), NULL);
+
+ gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, TRUE, 3);
+ gtk_widget_show (hbox);
+
+ gtk_widget_show (table);
+ gtk_widget_show (page);
+ return page;
+}
+
+
+static GtkWidget *
+create_style_page (const gchar * state)
+{
+ GtkWidget *page, *table;
+ int i;
+ gchar buffer[128];
+ gchar *labels[] =
+ {N_("Foreground:"), N_("Background:"), N_("Text:"), N_("Base:") };
+ gchar *tooltips[] =
+ {N_("Foreground color"), N_("Background color"), N_("Text color"),
+ N_("Base color") };
+
+ page = gtk_vbox_new (FALSE, 0);
+
+ /* Add the seven colours for this state */
+ table = gtk_table_new (8, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_box_pack_start (GTK_BOX (page), table, TRUE, TRUE, 0);
+ property_set_table_position (table, 0);
+ for (i = 0; i < GB_NUM_STYLE_COLORS; i++)
+ {
+ sprintf (buffer, "GtkStyle::%s[%s]", GbColorNames[i], state);
+ property_add_color (buffer, _(labels[i]), _(tooltips[i]));
+ }
+
+ /* Add the background pixmap */
+ sprintf (buffer, "GtkStyle::%s[%s]", GbBgPixmapName, state);
+ property_add_bgpixmap (buffer, _("Back. Pixmap:"),
+ _("The graphic to use as the background of the widget"));
+
+ gtk_widget_show (table);
+ gtk_widget_show (page);
+ return page;
+}
+#endif
+
+
+static GtkWidget *
+create_special_child_properties ()
+{
+ GtkWidget *page;
+
+ page = gtk_vbox_new (FALSE, 0);
+
+ special_child_property_notebook = gtk_notebook_new ();
+ gtk_widget_show (special_child_property_notebook);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (special_child_property_notebook),
+ FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (special_child_property_notebook),
+ FALSE);
+ gtk_box_pack_start (GTK_BOX (page), special_child_property_notebook,
+ TRUE, TRUE, 0);
+ gtk_widget_show (page);
+ gtk_signal_connect (GTK_OBJECT (special_child_property_notebook),
+ "key_press_event",
+ GTK_SIGNAL_FUNC (propagate_key_press_to_main_notebook), NULL);
+ return page;
+}
+
+
+static void
+create_language_specific_properties (GtkWidget *vbox)
+{
+ GtkWidget *table;
+ gint i;
+
+ lang_specific_properties = g_new (GtkWidget*, GladeNumLanguages);
+ for (i = 0; i < GladeNumLanguages; i++)
+ lang_specific_properties[i] = NULL;
+
+ /* Create table for C-specific properties. */
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ if (property_language == GLADE_LANGUAGE_C)
+ gtk_widget_show (table);
+ lang_specific_properties[GLADE_LANGUAGE_C] = table;
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+ property_set_table_position (table, 0);
+ property_add_filename (GbCSourceFile, _("Source File:"),
+ _("The file to write source code into"));
+ property_add_bool (GbCPublic, _("Public:"),
+ _("If the widget is added to the component's data structure"));
+
+ /* Create table for C++-specific properties. */
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ if (property_language == GLADE_LANGUAGE_CPP)
+ gtk_widget_show (table);
+ lang_specific_properties[GLADE_LANGUAGE_CPP] = table;
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+ property_set_table_position (table, 0);
+ property_add_bool (GbCxxSeparateClass, _("Separate Class:"),
+ _("Put this widget's subtree in a separate class"));
+ property_add_bool (GbCxxSeparateFile, _("Separate File:"),
+ _("Put this widget in a separate source file"));
+ property_add_choice (GbCxxVisibility, _("Visibility:"),
+ _("Visibility of widgets. Public widgets are exported to a global map."),
+ GbCxxVisibilityChoices);
+
+ /* Create table for Ada95-specific properties. */
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ if (property_language == GLADE_LANGUAGE_ADA95)
+ gtk_widget_show (table);
+ lang_specific_properties[GLADE_LANGUAGE_ADA95] = table;
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+ property_set_table_position (table, 0);
+ /* No properties yet. */
+
+
+ /* Create table for Perl-specific properties. */
+#if 0
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ if (property_language == GLADE_LANGUAGE_PERL)
+ gtk_widget_show (table);
+ lang_specific_properties[GLADE_LANGUAGE_PERL] = table;
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+ property_set_table_position (table, 0);
+ /* No properties yet. */
+#endif
+}
+
+
+
+gint
+property_add_gbwidget_page (GtkWidget * page)
+{
+ gtk_notebook_append_page (GTK_NOTEBOOK (property_widget_notebook), page,
+ NULL);
+ return g_list_length (GTK_NOTEBOOK (property_widget_notebook)->children) - 1;
+}
+
+
+void
+property_hide_gbwidget_page ()
+{
+ gtk_widget_hide (property_widget_notebook);
+}
+
+
+void
+property_show_gbwidget_page (gint page)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (property_widget_notebook), page);
+ gtk_widget_show (property_widget_notebook);
+}
+
+
+gint
+property_add_child_packing_page (GtkWidget * page)
+{
+ gtk_notebook_append_page (GTK_NOTEBOOK (special_child_property_notebook),
+ page, NULL);
+ return g_list_length (GTK_NOTEBOOK (special_child_property_notebook)->children) - 1;
+}
+
+
+void
+property_hide_child_packing_page ()
+{
+ gtk_widget_hide (special_child_property_notebook);
+}
+
+
+void
+property_show_child_packing_page (gint page)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (special_child_property_notebook), page);
+ gtk_widget_show (special_child_property_notebook);
+}
+
+
+void
+property_show_lang_specific_page (GladeLanguageType language)
+{
+ gint i;
+
+ property_language = language;
+ if (win_property == NULL)
+ return;
+
+ for (i = 0; i < GladeNumLanguages; i++)
+ {
+ if (lang_specific_properties[i])
+ {
+ /* FIXME: show the C language properties when we support them. */
+ if (i == language && i != GLADE_LANGUAGE_C)
+ gtk_widget_show (lang_specific_properties[i]);
+ else
+ gtk_widget_hide (lang_specific_properties[i]);
+ }
+ }
+}
+
+
+#ifdef GLADE_STYLE_SUPPORT
+static void
+on_style_copy (GtkWidget * widget, gpointer data)
+{
+ GdkColor *color;
+
+ if (!selected_style_widget)
+ {
+ glade_util_show_message_box (_("You need to select a color or background to copy"));
+ return;
+ }
+ if ((color = gtk_object_get_data (GTK_OBJECT (selected_style_widget),
+ GbColorKey)))
+ {
+ clipbd_colors[0] = *color;
+ clipbd_state = GB_COLOR_CLIPBD_COLOR;
+ }
+ else if (GTK_IS_DRAWING_AREA (selected_style_widget))
+ {
+ clipbd_bgpixmap = gtk_object_get_data (GTK_OBJECT (selected_style_widget),
+ GbBgPixmapKey);
+ clipbd_bgfilename = gtk_object_get_data (GTK_OBJECT (selected_style_widget),
+ GbBgFilenameKey);
+ clipbd_state = GB_COLOR_CLIPBD_BGPIXMAP;
+ }
+ else
+ {
+ g_warning (_("Invalid selection in on_style_copy()"));
+ }
+}
+
+
+static void
+on_style_copy_all (GtkWidget * widget, gpointer data)
+{
+ gint page, i;
+ GdkColor *color;
+ gchar buffer[128];
+
+ /* Find out which state is currently displayed */
+ page = gtk_notebook_get_current_page (GTK_NOTEBOOK (styles_notebook));
+
+ for (i = 0; i < GB_NUM_STYLE_COLORS; i++)
+ {
+ sprintf (buffer, "GtkStyle::%s[%s]", GbColorNames[i],
+ GbStateNames[page]);
+ color = property_get_color (buffer, NULL, NULL);
+ clipbd_colors[i] = *color;
+ }
+ sprintf (buffer, "GtkStyle::%s[%s]", GbBgPixmapName, GbStateNames[page]);
+ clipbd_bgpixmap = property_get_bgpixmap (buffer, NULL, NULL,
+ &clipbd_bgfilename);
+
+ clipbd_state = GB_COLOR_CLIPBD_STATE;
+}
+
+
+static void
+on_style_paste (GtkWidget * widget, gpointer data)
+{
+ gchar buffer[128];
+ gint page, i;
+ GtkWidget *value, *preview, *drawing_area, *changed_value = NULL;
+ gboolean bgpixmap_changed;
+ gchar *filename;
+
+ switch (clipbd_state)
+ {
+ case GB_COLOR_CLIPBD_EMPTY:
+ glade_util_show_message_box (_("You need to copy a color or background pixmap first"));
+ break;
+ case GB_COLOR_CLIPBD_COLOR:
+ if (!selected_style_widget
+ || !GTK_IS_DRAWING_AREA (selected_style_widget))
+ {
+ glade_util_show_message_box (_("You need to select a color to paste into"));
+ return;
+ }
+ show_color_in_preview (selected_style_widget, &clipbd_colors[0]);
+ value = selected_style_widget->parent;
+ on_property_changed (value, value);
+ break;
+ case GB_COLOR_CLIPBD_BGPIXMAP:
+ if (!selected_style_widget || !GTK_IS_DRAWING_AREA (selected_style_widget))
+ {
+ glade_util_show_message_box (_("You need to select a background pixmap to paste into"));
+ return;
+ }
+ set_pixmap (selected_style_widget, clipbd_bgpixmap, clipbd_bgfilename);
+ value = selected_style_widget->parent;
+ on_property_changed (value, value);
+ break;
+ case GB_COLOR_CLIPBD_STATE:
+ page = gtk_notebook_get_current_page (GTK_NOTEBOOK (styles_notebook));
+
+ /* We need to find one color or background pixmap which has changed so
+ we can call on_property_changed with it, thus recreating the style.
+ We don't want to call on_property_changed multiple times. */
+ for (i = 0; i < GB_NUM_STYLE_COLORS; i++)
+ {
+ sprintf (buffer, "GtkStyle::%s[%s]", GbColorNames[i],
+ GbStateNames[page]);
+ value = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ buffer);
+ g_return_if_fail (value != NULL);
+ preview = GTK_BIN (value)->child;
+ g_return_if_fail (GTK_IS_DRAWING_AREA (preview));
+ if (show_color_in_preview (preview, &clipbd_colors[i]))
+ changed_value = value;
+ }
+
+ sprintf (buffer, "GtkStyle::%s[%s]", GbBgPixmapName, GbStateNames[page]);
+ value = (GtkWidget *) g_hash_table_lookup (gb_property_values, buffer);
+ g_return_if_fail (value != NULL);
+ drawing_area = GTK_BIN (value)->child;
+ g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
+ filename = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgFilenameKey);
+ bgpixmap_changed = FALSE;
+ if (filename)
+ {
+ if (!clipbd_bgfilename || strcmp (filename, clipbd_bgfilename))
+ bgpixmap_changed = TRUE;
+ }
+ else
+ {
+ if (clipbd_bgfilename)
+ bgpixmap_changed = TRUE;
+ }
+ if (bgpixmap_changed)
+ {
+ property_set_bgpixmap (buffer, clipbd_bgpixmap, clipbd_bgfilename);
+ changed_value = value;
+ }
+
+ if (changed_value)
+ on_property_changed (changed_value, changed_value);
+
+ break;
+ }
+}
+#endif
+
+
+/*
+ * Color selection dialog
+ */
+
+static void
+show_colorsel_dialog (GtkWidget * widget, gpointer data)
+{
+ GdkColor *color;
+ gdouble rgb[4];
+ GtkWidget *transient_parent ;
+
+ /* Create the dialog if it doesn't exist yet */
+ if (!colorsel)
+ {
+ colorsel = GTK_COLOR_SELECTION_DIALOG (gtk_color_selection_dialog_new (_("Color Selection Dialog")));
+ /* Hide the Help button since it is not used */
+ gtk_widget_hide (GTK_WIDGET (colorsel->help_button));
+ gtk_signal_connect (GTK_OBJECT (colorsel), "delete_event",
+ GTK_SIGNAL_FUNC (close_dialog_event), colorsel);
+ gtk_signal_connect (GTK_OBJECT (colorsel->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (close_dialog), colorsel);
+ gtk_signal_connect (GTK_OBJECT (colorsel->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (on_colorsel_dialog_ok), NULL);
+ gtk_signal_connect (GTK_OBJECT (colorsel), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscCloses));
+ gtk_window_set_wmclass (GTK_WINDOW (colorsel), "color_selection", "Glade");
+ }
+
+ color_value = GTK_WIDGET (data);
+ g_return_if_fail (GTK_IS_FRAME (color_value));
+
+ color = gtk_object_get_data (GTK_OBJECT (GTK_BIN (color_value)->child),
+ GbColorKey);
+ g_return_if_fail (color != NULL);
+
+ rgb[0] = ((gdouble) color->red) / 0xFFFF;
+ rgb[1] = ((gdouble) color->green) / 0xFFFF;
+ rgb[2] = ((gdouble) color->blue) / 0xFFFF;
+
+ gtk_color_selection_set_color (GTK_COLOR_SELECTION (colorsel->colorsel),
+ rgb);
+ gtk_widget_show (GTK_WIDGET (colorsel));
+ transient_parent = glade_util_get_toplevel (widget);
+ if (GTK_IS_WINDOW (transient_parent))
+ gtk_window_set_transient_for (GTK_WINDOW (colorsel),
+ GTK_WINDOW (transient_parent));
+ /* This maps the window, which also de-iconifies it according to ICCCM. */
+ gdk_window_show (GTK_WIDGET (colorsel)->window);
+ gdk_window_raise (GTK_WIDGET (colorsel)->window);
+}
+
+
+static void
+on_colorsel_dialog_ok (GtkWidget * widget, gpointer data)
+{
+ GdkColor color;
+ gdouble rgb[4];
+ GtkWidget *preview = GTK_BIN (color_value)->child;
+
+ gtk_color_selection_get_color (GTK_COLOR_SELECTION (colorsel->colorsel),
+ rgb);
+
+ color.red = (gushort) 0xFFFF * rgb[0];
+ color.green = (gushort) 0xFFFF * rgb[1];
+ color.blue = (gushort) 0xFFFF * rgb[2];
+
+ show_color_in_preview (preview, &color);
+ close_dialog (widget, GTK_WIDGET (colorsel));
+ on_property_changed (color_value, color_value);
+}
+
+
+static gint
+close_dialog_event (GtkWidget * widget, GdkEvent * event, GtkWidget * dialog)
+{
+ close_dialog (widget, dialog);
+ return TRUE;
+}
+
+
+static void
+close_dialog (GtkWidget * widget, GtkWidget * dialog)
+{
+ glade_util_close_window (dialog);
+}
+
+
+/*
+ * File selection dialog
+ */
+#define GLADE_RESPONSE_CLEAR 1
+
+static void
+show_filesel_dialog (GtkWidget * widget, gpointer data)
+{
+ gchar *filename;
+ /* value can be an Entry or Combo (for filename properties) or a Frame (for
+ background pixmaps) */
+ filename_value = GTK_WIDGET (data);
+
+ /* Create the dialog if it doesn't exist yet */
+ if (!filesel)
+ {
+ filesel = gtk_file_chooser_dialog_new (_("Select File"),
+ GTK_WINDOW (win_property),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_CLEAR, GLADE_RESPONSE_CLEAR,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (filesel),
+ GTK_RESPONSE_OK);
+
+ g_signal_connect (filesel, "response",
+ GTK_SIGNAL_FUNC (on_filesel_response), NULL);
+ g_signal_connect (filesel, "delete_event",
+ G_CALLBACK (gtk_true), NULL);
+ }
+
+ /* set to current file, if there is one */
+ if (GTK_IS_ENTRY (filename_value) || GTK_IS_COMBO (filename_value))
+ {
+ filename = gtk_object_get_data (GTK_OBJECT (filename_value),
+ GbFilenameValueKey);
+ }
+ else
+ {
+ filename = gtk_object_get_data (GTK_OBJECT (GTK_BIN (filename_value)->child),
+ GbBgFilenameKey);
+ }
+ if (filename != NULL)
+ {
+ MSG1 ("Setting filename to: %s", filename);
+ glade_util_set_file_selection_filename (GTK_WIDGET (filesel), filename);
+ }
+
+ gtk_window_present (GTK_WINDOW (filesel));
+}
+
+
+static void
+on_filesel_response (GtkWidget * widget, gint response_id, gpointer data)
+{
+ GdkPixmap *gdkpixmap = NULL, *old_gdkpixmap;
+ gchar *filename, *old_filename;
+ GtkWidget *drawing_area;
+
+ if (response_id != GTK_RESPONSE_OK && response_id != GLADE_RESPONSE_CLEAR)
+ {
+ close_dialog (widget, GTK_WIDGET (filesel));
+ return;
+ }
+
+ if (response_id == GLADE_RESPONSE_CLEAR)
+ filename = NULL;
+ else
+ filename = glade_util_get_file_selection_filename (GTK_WIDGET (filesel));
+
+ /* For pixmaps we just show the file basename */
+ if (GTK_IS_ENTRY (filename_value) || GTK_IS_COMBO (filename_value))
+ {
+ gtk_object_set_data_full (GTK_OBJECT (filename_value),
+ GbFilenameValueKey,
+ g_strdup (filename), filename ? g_free : NULL);
+ if (GTK_IS_ENTRY (filename_value))
+ {
+ gtk_entry_set_text (GTK_ENTRY (filename_value),
+ filename ? g_basename (filename) : "");
+ on_property_changed (filename_value, filename_value);
+ }
+ else
+ {
+ /* For combos we don't have to call on_property_changed() since
+ the property should already have a signal connected to the
+ GtkEntry changed signal, so the popup list can be used. */
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (filename_value)->entry),
+ filename ? g_basename (filename) : "");
+ }
+ close_dialog (widget, GTK_WIDGET (filesel));
+ g_free (filename);
+ return;
+ }
+
+ drawing_area = GTK_BIN (filename_value)->child;
+
+ /* For background pixmaps we show them in the property value widget */
+ if (filename)
+ {
+ gdkpixmap = gdk_pixmap_create_from_xpm (drawing_area->window, NULL,
+ &drawing_area->style->bg[GTK_STATE_NORMAL],
+ filename);
+ if (!gdkpixmap)
+ {
+ glade_util_show_message_box (_("Couldn't create pixmap from file\n"),
+ GTK_WIDGET (filesel));
+ g_free (filename);
+ return;
+ }
+ }
+
+ old_gdkpixmap = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgPixmapKey);
+ if (old_gdkpixmap)
+ gdk_pixmap_unref (old_gdkpixmap);
+ old_filename = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgFilenameKey);
+ g_free (old_filename);
+
+ gtk_object_set_data (GTK_OBJECT (drawing_area), GbBgPixmapKey, gdkpixmap);
+ gtk_object_set_data (GTK_OBJECT (drawing_area), GbBgFilenameKey,
+ g_strdup (filename));
+
+ close_dialog (widget, GTK_WIDGET (filesel));
+ show_pixmap_in_drawing_area (drawing_area, gdkpixmap);
+ gtk_widget_queue_draw (drawing_area);
+ on_property_changed (filename_value, filename_value);
+
+ g_free (filename);
+}
+
+
+/*
+
+ */
+
+
+static GtkWidget *
+create_signals_property_page ()
+{
+ GtkWidget *page, *table, *hbox, *button, *scrolled_win;
+ gchar *signal_titles[5];
+ GList *handler_list = NULL;
+
+ page = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (page);
+
+ /* List of current signal handlers - Signal/Handler/Data/Options */
+ signal_titles[0] = _("Signal");
+ signal_titles[1] = _("Handler");
+ signal_titles[2] = _("Data");
+ signal_titles[3] = _("After");
+ signal_titles[4] = _("Object");
+ signal_clist = gtk_clist_new_with_titles (5, signal_titles);
+ gtk_clist_set_column_width (GTK_CLIST (signal_clist), 0, 150);
+ gtk_clist_set_column_width (GTK_CLIST (signal_clist), 1, 150);
+ gtk_clist_set_column_width (GTK_CLIST (signal_clist), 2, 80);
+ gtk_clist_set_column_width (GTK_CLIST (signal_clist), 3, 50);
+ gtk_clist_set_column_width (GTK_CLIST (signal_clist), 4, 80);
+ gtk_widget_show (signal_clist);
+ gtk_signal_connect (GTK_OBJECT (signal_clist), "select_row",
+ GTK_SIGNAL_FUNC (on_signal_select), NULL);
+
+ /* Hide the Data column. */
+ gtk_clist_set_column_visibility (GTK_CLIST (signal_clist), 2, FALSE);
+#if 0
+ gtk_clist_set_column_visibility (GTK_CLIST (signal_clist), 4, FALSE);
+#endif
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ /* This is only here to set a minimum size for the property editor. */
+ gtk_widget_set_usize (scrolled_win, 230, -1);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), signal_clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (page), scrolled_win, TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_win);
+
+ /* Mod, Key & Signal fields */
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_widget_show (table);
+ property_set_table_position (table, 0);
+ property_add_dialog (GbSignalName, _("Signal:"),
+ _("The signal to add a handler for"), TRUE,
+ show_signals_dialog);
+
+ /* FIXME: These are copied in gbsource.c, and should be language-specific,
+ i.e. we may need to change them when the project option changes. */
+ handler_list = g_list_append (handler_list, "gtk_widget_show");
+ handler_list = g_list_append (handler_list, "gtk_widget_hide");
+ handler_list = g_list_append (handler_list, "gtk_widget_grab_focus");
+ handler_list = g_list_append (handler_list, "gtk_widget_destroy");
+ handler_list = g_list_append (handler_list, "gtk_window_activate_default");
+ handler_list = g_list_append (handler_list, "gtk_true");
+ handler_list = g_list_append (handler_list, "gtk_false");
+ handler_list = g_list_append (handler_list, "gtk_main_quit");
+ property_add_combo (GbSignalHandler, _("Handler:"),
+ _("The function to handle the signal"), handler_list);
+ g_list_free (handler_list);
+
+ property_add_string (GbSignalData, _("Data:"),
+ _("The data passed to the handler"));
+ property_add_string (GbSignalObject, _("Object:"),
+ _("The object which receives the signal"));
+ property_add_bool (GbSignalAfter, _("After:"),
+ _("If the handler runs after the class function"));
+
+ /* Hide the data & object properties since they make signals too complicated.
+ But we'll leave them in for a while so we don't break old apps. */
+ property_set_visible (GbSignalData, FALSE);
+#if 0
+ property_set_visible (GbSignalObject, FALSE);
+#endif
+
+ gtk_box_pack_start (GTK_BOX (page), table, FALSE, TRUE, 5);
+
+ /* Add/Update/Delete buttons at bottom */
+ hbox = gtk_hbox_new (TRUE, 2);
+ button = gtk_button_new_with_label (_("Add"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_signal_add), signal_clist);
+
+ button = gtk_button_new_with_label (_("Update"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_signal_update), signal_clist);
+
+ button = gtk_button_new_with_label (_("Delete"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_signal_delete), signal_clist);
+
+ button = gtk_button_new_with_label (_("Clear"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_signal_clear), signal_clist);
+
+ gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, TRUE, 5);
+ gtk_widget_show (hbox);
+
+ return page;
+}
+
+
+static void
+show_accelerators_dialog (GtkWidget * widget,
+ gpointer value)
+{
+ GtkWidget *transient_parent = glade_util_get_toplevel (widget);
+ if (!accel_dialog)
+ create_accelerators_dialog ();
+
+ if (GTK_IS_WINDOW (transient_parent))
+ gtk_window_set_transient_for (GTK_WINDOW (accel_dialog),
+ GTK_WINDOW (transient_parent));
+
+ gtk_widget_show (accel_dialog);
+ if (GTK_WIDGET_REALIZED (accel_dialog))
+ {
+ gdk_window_show (accel_dialog->window);
+ gdk_window_raise (accel_dialog->window);
+ }
+}
+
+
+static void
+on_accelerators_dialog_response (GtkWidget * widget, gint response_id,
+ gpointer data)
+{
+ gtk_widget_hide (widget);
+}
+
+
+static void
+create_accelerators_dialog ()
+{
+ GtkWidget *vbox, *vbox2;
+ gchar *accel_titles[3];
+ GtkWidget *hbox, *label, *button, *table, *scrolled_win;
+ int row;
+
+ accel_dialog = gtk_dialog_new_with_buttons (_("Accelerators"), NULL, 0,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (accel_dialog), GTK_RESPONSE_CLOSE);
+ gtk_window_set_wmclass (GTK_WINDOW (accel_dialog), "accelerators", "Glade");
+
+ vbox = GTK_DIALOG (accel_dialog)->vbox;
+
+ vbox2 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox2);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
+
+ /* List of current accelerators - Mods/Keys/Signals */
+ accel_titles[0] = _("Mod");
+ accel_titles[1] = _("Key");
+ accel_titles[2] = _("Signal to emit");
+ accel_clist = gtk_clist_new_with_titles (3, accel_titles);
+ gtk_clist_set_column_width (GTK_CLIST (accel_clist), 0, 30);
+ gtk_clist_set_column_width (GTK_CLIST (accel_clist), 1, 100);
+ gtk_clist_set_column_width (GTK_CLIST (accel_clist), 2, 120);
+ gtk_widget_show (accel_clist);
+ gtk_signal_connect (GTK_OBJECT (accel_clist), "select_row",
+ GTK_SIGNAL_FUNC (on_accelerator_select), NULL);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), accel_clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (vbox2), scrolled_win, TRUE, TRUE, 0);
+ gtk_widget_set_usize (scrolled_win, 320, 120);
+ gtk_widget_show (scrolled_win);
+
+ /* Mod, Key & Signal fields */
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_widget_show (table);
+ row = 0;
+ label = gtk_label_new (_("Modifiers:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1,
+ GTK_FILL, 0, 1, 1);
+
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox);
+ accel_control_button = gtk_check_button_new_with_label (_("Ctrl"));
+ gtk_widget_show (accel_control_button);
+ gtk_box_pack_start (GTK_BOX (hbox), accel_control_button, TRUE, TRUE, 0);
+ accel_shift_button = gtk_check_button_new_with_label (_("Shift"));
+ gtk_widget_show (accel_shift_button);
+ gtk_box_pack_start (GTK_BOX (hbox), accel_shift_button, TRUE, TRUE, 0);
+ accel_alt_button = gtk_check_button_new_with_label (_("Alt"));
+ gtk_widget_show (accel_alt_button);
+ gtk_box_pack_start (GTK_BOX (hbox), accel_alt_button, TRUE, TRUE, 0);
+ gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, row, row + 1,
+ GTK_EXPAND | GTK_FILL, 0, 1, 1);
+
+ property_set_table_position (table, ++row);
+ property_add_dialog (GbAccelKey, _("Key:"),
+ _("The accelerator key"), TRUE, show_keys_dialog);
+ property_add_dialog (GbAccelSignal, _("Signal:"),
+ _("The signal to emit when the accelerator is pressed"),
+ TRUE, show_signals_dialog);
+ gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, TRUE, 5);
+
+ /* Add/Update/Delete buttons at bottom */
+ hbox = gtk_hbox_new (TRUE, 2);
+ /*button = gtk_button_new_with_label (_("Add"));*/
+ button = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_accelerator_add), accel_clist);
+
+ /*button = gtk_button_new_with_label (_("Update"));*/
+ button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_accelerator_update), accel_clist);
+
+ /*button = gtk_button_new_with_label (_("Delete"));*/
+ button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_accelerator_delete), accel_clist);
+
+ /*button = gtk_button_new_with_label (_("Clear"));*/
+ button = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_accelerator_clear), accel_clist);
+
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 5);
+ gtk_widget_show (hbox);
+
+ gtk_signal_connect (GTK_OBJECT (accel_dialog), "response",
+ GTK_SIGNAL_FUNC (on_accelerators_dialog_response),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (accel_dialog), "delete_event",
+ GTK_SIGNAL_FUNC (gtk_true),
+ NULL);
+}
+
+
+static void
+on_color_draw (GtkWidget * widget, gpointer data)
+{
+#ifdef GLADE_STYLE_SUPPORT
+ if (widget == selected_style_widget)
+ {
+ gdk_draw_rectangle (widget->window, widget->style->black_gc, FALSE, 0, 0,
+ widget->allocation.width - 1,
+ widget->allocation.height - 1);
+ gdk_draw_rectangle (widget->window, widget->style->white_gc, FALSE, 1, 1,
+ widget->allocation.width - 3,
+ widget->allocation.height - 3);
+ gdk_draw_rectangle (widget->window, widget->style->black_gc, FALSE, 2, 2,
+ widget->allocation.width - 5,
+ widget->allocation.height - 5);
+ }
+#endif
+}
+
+
+static void
+on_color_expose_event (GtkWidget * widget, GdkEvent * event, gpointer data)
+{
+ GdkColor *color = gtk_object_get_data (GTK_OBJECT (widget), GbColorKey);
+ g_return_if_fail (color != NULL);
+ gdk_window_set_background (widget->window, color);
+ gdk_window_clear (widget->window);
+ on_color_draw (widget, data);
+}
+
+
+static void
+on_color_select (GtkWidget * widget, gpointer data)
+{
+#ifdef GLADE_STYLE_SUPPORT
+ if (selected_style_widget == widget)
+ return;
+ if (selected_style_widget && selected_style_widget != widget)
+ gtk_widget_queue_draw (selected_style_widget);
+ selected_style_widget = widget;
+#endif
+ gtk_widget_queue_draw (widget);
+}
+
+
+/*
+ * Creating property widgets
+ */
+
+void
+property_set_table_position (GtkWidget * table, gint row)
+{
+ property_table = table;
+ property_table_row = row;
+}
+
+
+GtkWidget*
+property_get_table_position (gint *row)
+{
+ *row = property_table_row;
+ return property_table;
+}
+
+
+static void
+run_text_property_dialog (const gchar *property_name)
+{
+ GtkWidget *dialog;
+ GtkWidget *vbox5;
+ GtkWidget *vbox6;
+ GtkWidget *vbox7;
+ GtkWidget *frame2;
+ GtkWidget *alignment2;
+ GtkWidget *scrolledwindow8;
+ GtkWidget *property_text;
+ GtkWidget *label7;
+ GtkWidget *hbox3;
+ GtkWidget *translatable_checkbutton;
+ GtkWidget *context_prefix;
+ GtkWidget *frame3;
+ GtkWidget *alignment3;
+ GtkWidget *scrolledwindow9;
+ GtkWidget *comments;
+ GtkWidget *label8;
+ GtkWidget *hbuttonbox1;
+ GtkWidget *button1;
+ GtkWidget *button2;
+ GtkWidget *value, *textview;
+ gchar *text, *comments_text;
+ GtkTextBuffer *value_text_buffer = NULL, *text_buffer, *comments_text_buffer;
+ GtkTextIter start, end;
+ gboolean translatable, context;
+ gboolean free_text;
+ gboolean show_translation_properties = FALSE;
+
+ value = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+
+ if (g_object_get_data (G_OBJECT (value), GladeShowTranslationPropertiesKey))
+ show_translation_properties = TRUE;
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Text Property"));
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300);
+ gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ vbox5 = GTK_DIALOG (dialog)->vbox;
+ gtk_widget_show (vbox5);
+
+ vbox6 = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox6);
+ gtk_box_pack_start (GTK_BOX (vbox5), vbox6, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox6), 2);
+
+ vbox7 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox7);
+ gtk_box_pack_start (GTK_BOX (vbox6), vbox7, TRUE, TRUE, 0);
+
+ frame2 = gtk_frame_new (NULL);
+ gtk_widget_show (frame2);
+ gtk_box_pack_start (GTK_BOX (vbox7), frame2, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_NONE);
+
+ alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment2);
+ gtk_container_add (GTK_CONTAINER (frame2), alignment2);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment2), 2, 0, 12, 0);
+
+ scrolledwindow8 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow8);
+ gtk_container_add (GTK_CONTAINER (alignment2), scrolledwindow8);
+ gtk_widget_set_size_request (scrolledwindow8, 400, 200);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_SHADOW_IN);
+
+ property_text = gtk_text_view_new ();
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (property_text), GTK_WRAP_WORD);
+ gtk_widget_show (property_text);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow8), property_text);
+
+ label7 = gtk_label_new_with_mnemonic (_("<b>_Text:</b>"));
+ gtk_widget_show (label7);
+ gtk_frame_set_label_widget (GTK_FRAME (frame2), label7);
+ gtk_label_set_use_markup (GTK_LABEL (label7), TRUE);
+
+ hbox3 = gtk_hbox_new (FALSE, 12);
+ if (show_translation_properties)
+ gtk_widget_show (hbox3);
+ gtk_box_pack_start (GTK_BOX (vbox6), hbox3, FALSE, TRUE, 0);
+
+ translatable_checkbutton = gtk_check_button_new_with_mnemonic (_("T_ranslatable"));
+ gtk_widget_show (translatable_checkbutton);
+ gtk_box_pack_start (GTK_BOX (hbox3), translatable_checkbutton, FALSE, FALSE, 0);
+
+ context_prefix = gtk_check_button_new_with_mnemonic (_("Has Context _Prefix"));
+ gtk_widget_show (context_prefix);
+ gtk_box_pack_start (GTK_BOX (hbox3), context_prefix, FALSE, FALSE, 0);
+
+ frame3 = gtk_frame_new (NULL);
+ if (show_translation_properties)
+ gtk_widget_show (frame3);
+ gtk_box_pack_start (GTK_BOX (vbox6), frame3, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_NONE);
+
+ alignment3 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment3);
+ gtk_container_add (GTK_CONTAINER (frame3), alignment3);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment3), 2, 0, 12, 0);
+
+ scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow9);
+ gtk_container_add (GTK_CONTAINER (alignment3), scrolledwindow9);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_SHADOW_IN);
+
+ comments = gtk_text_view_new ();
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (comments), GTK_WRAP_WORD);
+ gtk_widget_show (comments);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow9), comments);
+
+ label8 = gtk_label_new_with_mnemonic (_("<b>Co_mments For Translators:</b>"));
+ gtk_widget_show (label8);
+ gtk_frame_set_label_widget (GTK_FRAME (frame3), label8);
+ gtk_label_set_use_markup (GTK_LABEL (label8), TRUE);
+
+ hbuttonbox1 = GTK_DIALOG (dialog)->action_area;
+ gtk_widget_show (hbuttonbox1);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_END);
+
+ button1 = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (button1);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button1, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
+
+ button2 = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (button2);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button2, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label7), property_text);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label8), comments);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+
+ /* Set the fields according to the data stored in the widget. */
+ if (GTK_IS_SCROLLED_WINDOW (value))
+ {
+ textview = GTK_BIN (value)->child;
+ value_text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+ gtk_text_buffer_get_bounds (value_text_buffer, &start, &end);
+ text = gtk_text_buffer_get_text (value_text_buffer, &start, &end, TRUE);
+ free_text = TRUE;
+ }
+ else
+ {
+ text = (gchar*) gtk_entry_get_text (GTK_ENTRY (value));
+ free_text = FALSE;
+ }
+
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (property_text));
+ gtk_text_buffer_set_text (text_buffer, text ? text : "", -1);
+ if (free_text)
+ g_free (text);
+
+ glade_util_get_translation_properties (value, property_name, &translatable,
+ &comments_text, &context);
+
+ comments_text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (comments));
+ gtk_text_buffer_set_text (comments_text_buffer,
+ comments_text ? comments_text : "", -1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (translatable_checkbutton),
+ translatable);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (context_prefix),
+ context);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+ {
+ /* Copy the 3 extra settings to the widget data. */
+ gtk_text_buffer_get_bounds (comments_text_buffer, &start, &end);
+ text = gtk_text_buffer_get_text (comments_text_buffer, &start, &end,
+ TRUE);
+ if (text && text[0] == '\0')
+ {
+ g_free (text);
+ text = NULL;
+ }
+
+ translatable = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (translatable_checkbutton));
+ context = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (context_prefix));
+
+ if (show_translation_properties)
+ glade_util_set_translation_properties (value, property_name,
+ translatable, text, context);
+ g_free (text);
+
+ /* Copy the main text back to the widget in the property editor.
+ Do this last since it will result in the "changed" callbacks being
+ called and we want to be in a good state for that. */
+ gtk_text_buffer_get_bounds (text_buffer, &start, &end);
+ text = gtk_text_buffer_get_text (text_buffer, &start, &end, TRUE);
+ if (GTK_IS_SCROLLED_WINDOW (value))
+ {
+ gtk_text_buffer_set_text (value_text_buffer, text ? text : "", -1);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (value), text);
+ }
+
+ /* We have to call this, since if the text doesn't change it
+ doesn't emit the "changed" signal. */
+ on_property_changed (value, value);
+
+ g_free (text);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+
+static void
+property_edit_string (GtkWidget *button, const gchar *property_name)
+{
+ run_text_property_dialog (property_name);
+}
+
+
+void
+property_add_string (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value = gtk_entry_new ();
+ GtkWidget *dialog_button = gtk_button_new_with_label ("...");
+ gtk_widget_set_usize (value, 80, -1);
+ property_name = property_add (property_name, label, value, dialog_button,
+ tooltip);
+ gtk_signal_connect (GTK_OBJECT (value), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (property_edit_string),
+ (gpointer) property_name);
+
+ /* Flag that it is a string property, so we can distinguish it from dialogs
+ etc. in property_set_string(). */
+ g_object_set_data (G_OBJECT (value), GladeIsStringPropertyKey, "TRUE");
+}
+
+
+static void
+property_edit_text (GtkWidget *button, const gchar *property_name)
+{
+ run_text_property_dialog (property_name);
+}
+
+
+void
+property_add_text (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ gint visible_lines)
+{
+ GtkWidget *value, *text, *dialog_button;
+ GtkTextBuffer *buffer;
+ gint line_height;
+ PangoFontMetrics *metrics;
+ PangoContext *context;
+ gint ascent, descent;
+
+ value = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (value),
+ GTK_SHADOW_IN);
+ buffer = gtk_text_buffer_new (NULL);
+ text = gtk_text_view_new_with_buffer (buffer);
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_WORD);
+ gtk_widget_show (text);
+ gtk_container_add (GTK_CONTAINER (value), text);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (value),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ context = gtk_widget_get_pango_context (text);
+ metrics = pango_context_get_metrics (context,
+ text->style->font_desc,
+ pango_context_get_language (context));
+ ascent = pango_font_metrics_get_ascent (metrics);
+ descent = pango_font_metrics_get_descent (metrics);
+ line_height = PANGO_PIXELS (ascent + descent);
+
+ /* We add extra for the text's border height, hscrollbar height etc. */
+ gtk_widget_set_usize (value, 80, visible_lines * line_height + 24);
+ dialog_button = gtk_button_new_with_label ("...");
+ property_name = property_add (property_name, label, value, dialog_button,
+ tooltip);
+ g_signal_connect (G_OBJECT (buffer), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (property_edit_text),
+ (gpointer) property_name);
+ g_object_unref (G_OBJECT (buffer));
+}
+
+
+void
+property_add_int (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value = gtk_entry_new ();
+ gtk_widget_set_usize (value, 80, -1);
+ property_add (property_name, label, value, NULL, tooltip);
+ gtk_signal_connect (GTK_OBJECT (value), "activate",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ gtk_signal_connect (GTK_OBJECT (value), "focus_out_event",
+ GTK_SIGNAL_FUNC (on_property_focus_out), value);
+}
+
+
+void
+property_add_int_range (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ gint min,
+ gint max,
+ gint step_increment,
+ gint page_increment,
+ gint climb_rate)
+{
+ GtkObject *adjustment = gtk_adjustment_new (min, min, max, step_increment,
+ page_increment, page_increment);
+ GtkWidget *value = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment),
+ climb_rate, 0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (value), TRUE);
+ gtk_widget_set_usize (value, 80, -1);
+ gtk_signal_connect (GTK_OBJECT (value), "value_changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+void
+property_add_optional_int_range (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ gint min,
+ gint max,
+ gint step_increment,
+ gint page_increment,
+ gint climb_rate,
+ GtkCallback callback)
+{
+ GtkObject *adjustment = gtk_adjustment_new (min, min, max, step_increment,
+ page_increment, page_increment);
+ GtkWidget *value = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment),
+ climb_rate, 0);
+ GtkWidget *dialog_button = gtk_check_button_new ();
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (value), TRUE);
+#if 0
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (dialog_button), FALSE);
+ gtk_widget_set_usize (dialog_button, 16, -1);
+#endif
+ gtk_widget_set_usize (value, 50, -1);
+ gtk_signal_connect (GTK_OBJECT (value), "value_changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "toggled",
+ GTK_SIGNAL_FUNC (callback), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+void
+property_add_float (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value = gtk_entry_new ();
+ gtk_widget_set_usize (value, 80, -1);
+ property_add (property_name, label, value, NULL, tooltip);
+ gtk_signal_connect (GTK_OBJECT (value), "activate",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ gtk_signal_connect (GTK_OBJECT (value), "focus_out_event",
+ GTK_SIGNAL_FUNC (on_property_focus_out), value);
+}
+
+
+void
+property_add_float_range (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ gfloat min,
+ gfloat max,
+ gfloat step_increment,
+ gfloat page_increment,
+ gfloat climb_rate,
+ gint decimal_digits)
+{
+ GtkObject *adjustment = gtk_adjustment_new (min, min, max, step_increment,
+ page_increment, page_increment);
+ GtkWidget *value = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment),
+ climb_rate, decimal_digits);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (value), TRUE);
+ gtk_widget_set_usize (value, 80, -1);
+ gtk_signal_connect (GTK_OBJECT (value), "value_changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+static void
+on_bool_property_toggle (GtkWidget * value, gpointer data)
+{
+ guint active = GTK_TOGGLE_BUTTON (value)->active;
+ GtkWidget *label = GTK_BIN (value)->child;
+ gtk_label_set_text (GTK_LABEL (label), active ? _("Yes") : _("No"));
+ on_property_changed (value, value);
+}
+
+
+void
+property_add_bool (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value = gtk_toggle_button_new_with_label (_("No"));
+ GTK_WIDGET_UNSET_FLAGS (value, GTK_CAN_DEFAULT);
+ gtk_signal_connect (GTK_OBJECT (value), "toggled",
+ GTK_SIGNAL_FUNC (on_bool_property_toggle), NULL);
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+void
+property_add_choice (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ const gchar ** choices)
+{
+ GtkWidget *value = gtk_option_menu_new ();
+ GtkWidget *menu = gtk_menu_new ();
+ gint i = 0;
+
+ GTK_WIDGET_UNSET_FLAGS (value, GTK_CAN_DEFAULT);
+
+ while (choices[i])
+ {
+ GtkWidget *menuitem = gtk_menu_item_new_with_label (choices[i]);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+ gtk_widget_show (menuitem);
+ i++;
+ }
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (value), menu);
+ gtk_signal_connect_after (GTK_OBJECT (menu), "selection_done",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+void
+property_add_combo (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ GList * choices)
+{
+ GtkWidget *value = gtk_combo_new ();
+ gtk_widget_set_usize (GTK_COMBO (value)->entry, 60, -1);
+ gtk_widget_set_usize (value, 80, -1);
+ if (choices)
+ gtk_combo_set_popdown_strings (GTK_COMBO (value), choices);
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (value)->entry), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+void
+property_add_color (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value, *preview, *dialog_button;
+ value = gtk_frame_new (NULL);
+ preview = create_color_preview ();
+ gtk_widget_set_events (preview, gtk_widget_get_events (preview)
+ | GDK_BUTTON_PRESS_MASK);
+ gtk_signal_connect_after (GTK_OBJECT (preview), "expose_event",
+ GTK_SIGNAL_FUNC (on_color_expose_event), value);
+ gtk_signal_connect (GTK_OBJECT (preview), "button_press_event",
+ GTK_SIGNAL_FUNC (on_color_select), value);
+
+ gtk_container_add (GTK_CONTAINER (value), preview);
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (show_colorsel_dialog), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+void
+property_add_bgpixmap (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value, *drawing_area, *dialog_button;
+ value = gtk_frame_new (NULL);
+ drawing_area = gtk_drawing_area_new ();
+ gtk_widget_set_events (drawing_area, gtk_widget_get_events (drawing_area)
+ | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK);
+ gtk_widget_set_size_request (drawing_area, 100, 20);
+ gtk_widget_show (drawing_area);
+ gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
+ GTK_SIGNAL_FUNC (expose_pixmap), NULL);
+ gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
+ GTK_SIGNAL_FUNC (on_color_select), value);
+ gtk_container_add (GTK_CONTAINER (value), drawing_area);
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (show_filesel_dialog), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+void
+property_add_dialog (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ gboolean editable,
+ GtkCallback callback)
+{
+ GtkWidget *value, *dialog_button;
+ value = gtk_entry_new ();
+ gtk_widget_set_usize (value, 80, -1);
+ gtk_editable_set_editable (GTK_EDITABLE (value), editable);
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (callback), value);
+ gtk_signal_connect (GTK_OBJECT (value), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+void
+property_add_filename (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value, *dialog_button;
+ value = gtk_entry_new ();
+ gtk_widget_set_usize (value, 80, -1);
+ gtk_editable_set_editable (GTK_EDITABLE (value), FALSE);
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (show_filesel_dialog), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+void
+property_add_filename_with_combo (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ GList * choices)
+{
+ GtkWidget *value, *dialog_button;
+ value = gtk_combo_new ();
+ gtk_widget_set_usize (GTK_COMBO (value)->entry, 60, -1);
+ gtk_widget_set_usize (value, 80, -1);
+ if (choices)
+ gtk_combo_set_popdown_strings (GTK_COMBO (value), choices);
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (value)->entry), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (show_filesel_dialog), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+
+void
+property_add_font (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip)
+{
+ GtkWidget *value, *dialog_button;
+ value = gtk_entry_new ();
+ gtk_widget_set_usize (value, 80, -1);
+ gtk_editable_set_editable (GTK_EDITABLE (value), FALSE);
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (show_font_dialog), value);
+ gtk_signal_connect (GTK_OBJECT (value), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+void
+property_add_command (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ const gchar * command,
+ GtkSignalFunc callback)
+{
+ GtkWidget *value;
+ value = gtk_button_new_with_label (command);
+ if (callback)
+ {
+ gtk_signal_connect (GTK_OBJECT (value), "clicked",
+ GTK_SIGNAL_FUNC (callback), value);
+ }
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+/* This adds all the stock items to the combo's popup list. It uses the
+ smallest icon size available. It hides items that don't have an icon of the
+ given size, or don't have a label if need_label is TRUE. */
+static void
+fill_stock_combo (GtkWidget *combo,
+ gboolean need_label,
+ GtkIconSize icon_size)
+{
+ GtkWidget *list, *listitem;
+ GSList *elem;
+
+ list = GTK_COMBO (combo)->list;
+
+ /* Add a 'None' item at the top of the list. */
+ listitem = gtk_list_item_new_with_label (_("None"));
+ gtk_widget_show (listitem);
+ gtk_container_add (GTK_CONTAINER (list), listitem);
+ gtk_combo_set_item_string (GTK_COMBO (combo), GTK_ITEM (listitem), "");
+
+ for (elem = stock_items; elem; elem = elem->next)
+ {
+ GtkStockItem item;
+ GtkWidget *hbox, *image, *label;
+ GtkIconSize *sizes;
+ gint n_sizes, i, use_icon_size;
+ gchar *stock_id, *label_text;
+ gboolean show_item;
+
+ stock_id = elem->data;
+
+#if 0
+ g_print ("Stock ID: %s\n", stock_id);
+#endif
+
+ n_sizes = GPOINTER_TO_INT (g_hash_table_lookup (stock_nsizes_hash,
+ stock_id));
+ sizes = g_hash_table_lookup (stock_sizes_hash, stock_id);
+ if (n_sizes <= 0)
+ continue;
+
+ /* If we accept any icons size, then get the icon closest to
+ GTK_ICON_SIZE_MENU to display in the list. If we only accept a
+ particular size, then check the stock item has that size. */
+ use_icon_size = GTK_ICON_SIZE_INVALID;
+
+ show_item = (icon_size == GLADE_ICON_SIZE_ANY) ? TRUE : FALSE;
+
+ for (i = 0; i < n_sizes; i++)
+ {
+ if (sizes[i] == icon_size)
+ show_item = TRUE;
+
+ if (sizes[i] != GTK_ICON_SIZE_INVALID
+ && (use_icon_size == GTK_ICON_SIZE_INVALID
+ || sizes[i] < use_icon_size))
+ use_icon_size = sizes[i];
+ }
+
+ if (use_icon_size == GTK_ICON_SIZE_INVALID)
+ {
+#if 0
+ g_print ("Skipping: %s\n", stock_id);
+#endif
+ continue;
+ }
+
+ if (gtk_stock_lookup (stock_id, &item))
+ {
+ label_text = item.label;
+ }
+ else
+ {
+ if (need_label)
+ show_item = FALSE;
+ label_text = stock_id;
+ }
+
+ listitem = gtk_list_item_new ();
+ gtk_object_set_data (GTK_OBJECT (listitem), GladeStockIDKey, stock_id);
+ if (show_item)
+ gtk_widget_show (listitem);
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (listitem), hbox);
+ gtk_widget_show (hbox);
+
+ image = gtk_image_new_from_stock (stock_id, use_icon_size);
+ if (image)
+ {
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ }
+
+ label = gtk_type_new (GTK_TYPE_ACCEL_LABEL);
+ gtk_label_set_text_with_mnemonic (GTK_LABEL (label), label_text);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ gtk_combo_set_item_string (GTK_COMBO (combo), GTK_ITEM (listitem),
+ stock_id);
+
+ gtk_container_add (GTK_CONTAINER (list), listitem);
+ }
+}
+
+
+/* This shows the appropriate stock items in the popup list. If need_label
+ is TRUE, it only shows items which have stock labels. If icon_size is
+ not GLADE_ICON_SIZE_ANY, it only shows items that have icons of the given
+ size. */
+static void
+show_stock_items (GtkWidget *combo)
+{
+ gboolean need_label;
+ GtkIconSize icon_size;
+ GtkWidget *list;
+ GList *elem;
+ gboolean gnome_support;
+
+ need_label = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (combo),
+ GladeNeedLabelKey));
+ icon_size = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (combo),
+ GladeIconSizeKey));
+
+ list = GTK_COMBO (combo)->list;
+
+ gnome_support = glade_project_get_gnome_support (current_project);
+
+ for (elem = GTK_LIST (list)->children; elem; elem = elem->next)
+ {
+ GtkWidget *listitem;
+ gchar *stock_id;
+ gboolean show_item;
+ GtkStockItem item;
+
+ listitem = elem->data;
+
+ /* Fetch the stock id from the item. */
+ stock_id = gtk_object_get_data (GTK_OBJECT (listitem), GladeStockIDKey);
+ if (!stock_id)
+ continue;
+
+ show_item = TRUE;
+ if (need_label && !gtk_stock_lookup (stock_id, &item))
+ show_item = FALSE;
+
+ /* Only show GTK+ stock items in GTK+ projects. */
+ if (!gnome_support && (strncmp (stock_id, "gtk-", 4) != 0))
+ show_item = FALSE;
+
+ if (show_item && icon_size != GLADE_ICON_SIZE_ANY)
+ {
+ GtkIconSize *sizes;
+ gint n_sizes, i;
+
+ n_sizes = GPOINTER_TO_INT (g_hash_table_lookup (stock_nsizes_hash,
+ stock_id));
+ sizes = g_hash_table_lookup (stock_sizes_hash, stock_id);
+
+ show_item = FALSE;
+ for (i = 0; i < n_sizes; i++)
+ {
+ if (sizes[i] == icon_size)
+ {
+ show_item = TRUE;
+ }
+ }
+ }
+
+ if (show_item)
+ gtk_widget_show (listitem);
+ else
+ gtk_widget_hide (listitem);
+ }
+}
+
+
+/* A stock item is a GTK+ stock item that has a label and an icon with the
+ given size. Any stock items that don't have labels or don't have an icon
+ with the given size are not displayed in the popup list.
+ You can change the icon size dynamically, e.g. based on another property.
+ The popup list will be recreated, and if the stock item currently used does
+ not have the given icon size, the stock item will be set to 'None'.
+ Using GLADE_ICON_SIZE_ANY means any icon size is OK. */
+void
+property_add_stock_item (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ GtkIconSize icon_size)
+{
+ GtkWidget *value;
+
+ value = gtk_combo_new ();
+ gtk_widget_set_usize (GTK_COMBO (value)->entry, 60, -1);
+ gtk_widget_set_usize (value, 80, -1);
+
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (value)->entry), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+
+ fill_stock_combo (value, TRUE, icon_size);
+ gtk_object_set_data (GTK_OBJECT (value), GladeNeedLabelKey,
+ GINT_TO_POINTER (TRUE));
+ gtk_object_set_data (GTK_OBJECT (value), GladeIconSizeKey,
+ GINT_TO_POINTER (icon_size));
+
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+extern const gint GladeNamedIconsSize;
+extern const gchar *GladeNamedIcons[];
+
+void
+property_add_named_icon (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip)
+{
+ GtkWidget *value, *list, *listitem, *hbox, *image, *label_widget;
+ gint i;
+
+ value = gtk_combo_new ();
+ list = GTK_COMBO (value)->list;
+ gtk_widget_set_usize (GTK_COMBO (value)->entry, 60, -1);
+ gtk_widget_set_usize (value, 80, -1);
+
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (value)->entry), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+
+ for (i = 0; i < GladeNamedIconsSize; i++)
+ {
+ listitem = gtk_list_item_new ();
+ gtk_widget_show (listitem);
+
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (listitem), hbox);
+ gtk_widget_show (hbox);
+
+ image = gtk_image_new_from_icon_name (GladeNamedIcons[i],
+ GTK_ICON_SIZE_MENU);
+ if (image)
+ {
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ }
+
+ label_widget = gtk_label_new (GladeNamedIcons[i]);
+ gtk_widget_show (label_widget);
+ gtk_box_pack_start (GTK_BOX (hbox), label_widget, FALSE, FALSE, 0);
+
+ gtk_combo_set_item_string (GTK_COMBO (value), GTK_ITEM (listitem),
+ GladeNamedIcons[i]);
+
+ gtk_container_add (GTK_CONTAINER (list), listitem);
+ }
+
+ property_add (property_name, label, value, NULL, tooltip);
+}
+
+
+/* An icon is a GTK+ stock icon with the given icon size, or a user-specified
+ icon. It will show a GtkCombo, with a '...' button beside it for opening
+ a file selection dialog, so the user can specify an icon file.
+ As with stock item, you can change the icon size dynamically, and the popup
+ list of stock icons will be recreated. */
+void
+property_add_icon (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ GtkIconSize icon_size)
+{
+ GtkWidget *value, *dialog_button;
+
+ value = gtk_combo_new ();
+ gtk_widget_set_usize (GTK_COMBO (value)->entry, 60, -1);
+ gtk_widget_set_usize (value, 80, -1);
+
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (value)->entry), "changed",
+ GTK_SIGNAL_FUNC (on_property_changed), value);
+
+ fill_stock_combo (value, FALSE, icon_size);
+ gtk_object_set_data (GTK_OBJECT (value), GladeNeedLabelKey,
+ GINT_TO_POINTER (FALSE));
+ gtk_object_set_data (GTK_OBJECT (value), GladeIconSizeKey,
+ GINT_TO_POINTER (icon_size));
+
+ dialog_button = gtk_button_new_with_label ("...");
+ gtk_signal_connect (GTK_OBJECT (dialog_button), "clicked",
+ GTK_SIGNAL_FUNC (show_filesel_dialog), value);
+
+ property_add (property_name, label, value, dialog_button, tooltip);
+}
+
+
+static const gchar*
+property_add (const gchar * property_name,
+ const gchar * label_string,
+ GtkWidget * value,
+ GtkWidget * dialog_button,
+ const gchar * tooltip)
+{
+ GtkWidget *label, *eventbox;
+ gchar *property_name_copy;
+ gint xpad = 0, ypad = 0;
+
+ if (glade_debug_properties)
+ g_print ("Property: %s\n", property_name);
+
+#if 0
+ if (GTK_IS_OPTION_MENU (value))
+ xpad = ypad = 0;
+#endif
+
+ label = gtk_label_new (label_string);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.3);
+ /*gtk_misc_set_padding(GTK_MISC(label), 0, 5); */
+ gtk_widget_show (label);
+
+ /* We put the label in the event box so we can set a tooltip. */
+ eventbox = gtk_event_box_new ();
+ gtk_widget_set_usize (eventbox, 100, -1);
+ gtk_widget_show (eventbox);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+
+ gtk_widget_show (value);
+ if (tooltip)
+ gtk_tooltips_set_tip (tooltips, eventbox, tooltip, NULL);
+
+ gtk_table_attach (GTK_TABLE (property_table), eventbox, 0, 1,
+ property_table_row, property_table_row + 1,
+ GTK_FILL, GTK_FILL, 1, 1);
+ if (dialog_button)
+ {
+ GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
+ gtk_table_attach (GTK_TABLE (property_table), hbox, 1, 3,
+ property_table_row, property_table_row + 1,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+ /* Empty checkbuttons are placed before the value widget. */
+ if (GTK_IS_CHECK_BUTTON (dialog_button)
+ && GTK_BIN (dialog_button)->child == NULL)
+ {
+ gtk_box_pack_start (GTK_BOX (hbox), dialog_button, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), value, TRUE, TRUE, 0);
+ }
+ else
+ {
+ gtk_box_pack_start (GTK_BOX (hbox), value, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), dialog_button, FALSE, FALSE, 0);
+ }
+ gtk_widget_show (dialog_button);
+ gtk_widget_show (hbox);
+ }
+ else
+ {
+ gtk_table_attach (GTK_TABLE (property_table), value, 1, 3,
+ property_table_row, property_table_row + 1,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+ }
+ property_table_row++;
+
+ /* Insert property label & value widgets into hash tables */
+ property_name_copy = g_strdup (property_name);
+ g_hash_table_insert (gb_property_labels, property_name_copy, label);
+ g_hash_table_insert (gb_property_values, property_name_copy, value);
+ if (dialog_button)
+ g_hash_table_insert (gb_property_buttons,
+ property_name_copy,
+ dialog_button);
+
+ return property_name_copy;
+}
+
+
+/*
+ * Functions for getting/setting properties.
+ * NOTE: should also specify whether set properties are copied and
+ * if values returned by get should be freed.
+ * For widgets which use a GtkEntry: string value set is copied,
+ * & don't free string returned by get (it is the actual entry text).
+ *
+ * NOTE: property_get_*() functions also set the apply flag.
+ * This is used to enable the automatic applying of
+ * properties as they are changed in the property editor. It is set
+ * to TRUE if the property widget matches the to_apply widget.
+ */
+
+
+static void
+copy_translation_properties (const gchar *property_name,
+ GtkWidget *from_widget, GtkWidget *to_widget)
+{
+ /* Just return if either widget is NULL. This can happen for the fields on
+ the signals page, which aren't translated at all. */
+ if (from_widget == NULL || to_widget == NULL)
+ return;
+
+ /* Copy the translator comments string, and translatable & context flags
+ from one widget to the other. */
+ glade_util_copy_translation_properties (from_widget, property_name,
+ to_widget, property_name);
+}
+
+
+gchar *
+property_get_string (const gchar * property_name,
+ GtkWidget *actual_widget,
+ GtkWidget * to_apply,
+ gboolean * apply_retval)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ gboolean apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+
+ if (apply_retval)
+ *apply_retval = apply;
+
+ g_return_val_if_fail (widget != NULL, "");
+
+ /* Copy the extra data from the property value to the actual widget. */
+ if (apply)
+ copy_translation_properties (property_name, widget, actual_widget);
+
+ return ((char*) gtk_entry_get_text (GTK_ENTRY (widget)));
+}
+
+
+void
+property_set_string (const gchar * property_name,
+ const gchar * value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ GtkWidget *button;
+ g_return_if_fail (widget != NULL);
+ gtk_entry_set_text (GTK_ENTRY (widget), value ? value : "");
+
+ /* Make sure the '...' button is not visible, only for string properties. */
+ if (g_object_get_data (G_OBJECT (widget), GladeIsStringPropertyKey))
+ {
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+ gtk_widget_hide (button);
+ }
+}
+
+
+void
+property_set_translatable_string (const gchar * property_name,
+ const gchar * value,
+ GtkWidget *actual_widget)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ GtkWidget *button;
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (actual_widget != NULL);
+ gtk_entry_set_text (GTK_ENTRY (widget), value ? value : "");
+
+ /* Make sure the '...' button is visible. */
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+ gtk_widget_show (button);
+
+ copy_translation_properties (property_name, actual_widget, widget);
+
+ /* Set a special flag in the property value widget so we do show the
+ translatable properties in the dialog. */
+ g_object_set_data (G_OBJECT (widget), GladeShowTranslationPropertiesKey, "TRUE");
+}
+
+
+/* Note: returned string must be freed with g_free() */
+gchar *
+property_get_text (const gchar * property_name,
+ GtkWidget *actual_widget,
+ GtkWidget * to_apply,
+ gboolean * apply_retval)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ gboolean apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ GtkWidget *text = GTK_BIN (widget)->child;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+
+ if (apply_retval)
+ *apply_retval = apply;
+
+ g_return_val_if_fail (text != NULL, g_strdup (""));
+ g_return_val_if_fail (GTK_IS_TEXT_VIEW (text), g_strdup (""));
+
+ /* Copy the extra data from the property value to the actual widget. */
+ if (apply)
+ copy_translation_properties (property_name, widget, actual_widget);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+ return (gtk_text_buffer_get_text (buffer, &start, &end, TRUE));
+}
+
+
+void
+property_set_text (const gchar * property_name,
+ const gchar * value)
+{
+ GtkWidget *text;
+ GtkTextBuffer *buffer;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+
+ text = GTK_BIN (widget)->child;
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_set_text (buffer, value ? value : "", -1);
+
+ /* Set a special flag in the property value widget so we don't show the
+ translatable properties in the dialog. */
+ g_object_set_data (G_OBJECT (widget), GladeShowTranslationPropertiesKey, NULL);
+}
+
+
+void
+property_set_translatable_text (const gchar * property_name,
+ const gchar * value,
+ GtkWidget * actual_widget)
+{
+ GtkWidget *text;
+ GtkTextBuffer *buffer;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (actual_widget != NULL);
+
+ text = GTK_BIN (widget)->child;
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_set_text (buffer, value ? value : "", -1);
+
+ copy_translation_properties (property_name, actual_widget, widget);
+
+ /* Set a special flag in the property value widget so we do show the
+ translatable properties in the dialog. */
+ g_object_set_data (G_OBJECT (widget), GladeShowTranslationPropertiesKey, "TRUE");
+}
+
+
+gint
+property_get_int (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ gchar *text;
+ gint value = 0;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, 0);
+ if (GTK_IS_SPIN_BUTTON (widget))
+ {
+ return gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
+ }
+ else
+ {
+ text = (char*) gtk_entry_get_text (GTK_ENTRY (widget));
+ sscanf (text, "%i", &value);
+ return value;
+ }
+}
+
+
+gint
+property_get_optional_int (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply,
+ gboolean * is_set)
+{
+ gchar *text;
+ gint value = 0;
+ GtkWidget *widget, *button;
+
+ widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, 0);
+
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+ g_return_val_if_fail (button != NULL, 0);
+
+ if (is_set)
+ *is_set = GTK_TOGGLE_BUTTON (button)->active ? TRUE : FALSE;
+
+ if (GTK_IS_SPIN_BUTTON (widget))
+ {
+ return gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
+ }
+ else
+ {
+ text = (char*) gtk_entry_get_text (GTK_ENTRY (widget));
+ sscanf (text, "%i", &value);
+ return value;
+ }
+}
+
+
+void
+property_set_int (const gchar * property_name,
+ gint value)
+{
+ gchar buffer[128];
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ if (GTK_IS_SPIN_BUTTON (widget))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
+ }
+ else
+ {
+ sprintf (buffer, "%i", value);
+ gtk_entry_set_text (GTK_ENTRY (widget), buffer);
+ }
+}
+
+
+void
+property_set_optional_int (const gchar * property_name,
+ gint value,
+ gboolean is_set)
+{
+ gchar buffer[128];
+ GtkWidget *widget, *button;
+
+ widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+ g_return_if_fail (button != NULL);
+
+ if (GTK_IS_SPIN_BUTTON (widget))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
+ }
+ else
+ {
+ sprintf (buffer, "%i", value);
+ gtk_entry_set_text (GTK_ENTRY (widget), buffer);
+ }
+
+ gtk_widget_set_sensitive (widget, is_set);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), is_set);
+}
+
+
+gfloat
+property_get_float (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ gchar *text;
+ gfloat value = 0;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, 0);
+ if (GTK_IS_SPIN_BUTTON (widget))
+ {
+ return gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
+ }
+ else
+ {
+ text = (char*) gtk_entry_get_text (GTK_ENTRY (widget));
+ sscanf (text, "%f", &value);
+ return value;
+ }
+}
+
+
+void
+property_set_float (const gchar * property_name,
+ gfloat value)
+{
+ gchar buffer[128];
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ if (GTK_IS_SPIN_BUTTON (widget))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
+ }
+ else
+ {
+ sprintf (buffer, "%g", value);
+ gtk_entry_set_text (GTK_ENTRY (widget), buffer);
+ }
+}
+
+
+gboolean
+property_get_bool (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, FALSE);
+ return (GTK_TOGGLE_BUTTON (widget)->active ? TRUE : FALSE);
+}
+
+
+void
+property_set_bool (const gchar * property_name,
+ gint value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
+}
+
+
+gchar *
+property_get_choice (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ GtkWidget *label;
+ gchar *label_text;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, NULL);
+ label = GTK_BIN (widget)->child;
+ if (!label)
+ {
+ GtkWidget *menuitem = gtk_menu_get_active (GTK_MENU (GTK_OPTION_MENU (widget)->menu));
+ if (menuitem)
+ label = GTK_BIN (menuitem)->child;
+ }
+ if (!label || !GTK_IS_LABEL (label))
+ {
+ g_warning ("Couldn't find option menu label");
+ return NULL;
+ }
+ label_text = (gchar*) gtk_label_get_text (GTK_LABEL (label));
+ return label_text;
+}
+
+
+void
+property_set_choice (const gchar * property_name,
+ gint value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ gtk_option_menu_set_history (GTK_OPTION_MENU (widget), value);
+}
+
+
+gchar *
+property_get_combo (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, "");
+ return ((char*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (widget)->entry)));
+}
+
+
+void
+property_set_combo (const gchar * property_name,
+ const gchar * value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (widget)->entry), value ? value : "");
+}
+
+
+void
+property_set_combo_strings (const gchar * property_name,
+ GList * choices)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ if (choices)
+ gtk_combo_set_popdown_strings (GTK_COMBO (widget), choices);
+ else
+ gtk_list_clear_items (GTK_LIST (GTK_COMBO (widget)->list), 0, -1);
+}
+
+
+GdkColor *
+property_get_color (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ GdkColor *color;
+ GtkWidget *preview;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, NULL);
+ preview = GTK_BIN (widget)->child;
+ g_return_val_if_fail (GTK_IS_DRAWING_AREA (preview), NULL);
+ color = gtk_object_get_data (GTK_OBJECT (preview), GbColorKey);
+ g_return_val_if_fail (color != NULL, NULL);
+ return color;
+}
+
+
+void
+property_set_color (const gchar * property_name,
+ GdkColor * value)
+{
+ GtkWidget *preview;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ preview = GTK_BIN (widget)->child;
+ g_return_if_fail (GTK_IS_DRAWING_AREA (preview));
+ show_color_in_preview (preview, value);
+}
+
+
+GdkPixmap *
+property_get_bgpixmap (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply,
+ gchar ** filename)
+{
+ GtkWidget *drawing_area;
+ GdkPixmap *gdkpixmap;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, NULL);
+ drawing_area = GTK_BIN (widget)->child;
+ g_return_val_if_fail (GTK_IS_DRAWING_AREA (drawing_area), NULL);
+
+ gdkpixmap = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgPixmapKey);
+ *filename = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgFilenameKey);
+ return gdkpixmap;
+}
+
+
+void
+property_set_bgpixmap (const gchar * property_name,
+ GdkPixmap * gdkpixmap,
+ const gchar * filename)
+{
+ GtkWidget *drawing_area;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ drawing_area = GTK_BIN (widget)->child;
+ g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
+
+ set_pixmap (drawing_area, gdkpixmap, filename);
+}
+
+
+static void
+set_pixmap (GtkWidget * drawing_area, GdkPixmap * gdkpixmap,
+ const gchar * filename)
+{
+ GdkPixmap *old_gdkpixmap;
+ gchar *old_filename, *filename_copy;
+
+ /* free/unref any existing values */
+ old_gdkpixmap = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgPixmapKey);
+ if (old_gdkpixmap)
+ gdk_pixmap_unref (old_gdkpixmap);
+ old_filename = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgFilenameKey);
+ g_free (old_filename);
+
+ gtk_object_set_data (GTK_OBJECT (drawing_area), GbBgPixmapKey, gdkpixmap);
+ filename_copy = filename ? g_strdup (filename) : NULL;
+ gtk_object_set_data (GTK_OBJECT (drawing_area), GbBgFilenameKey, filename_copy);
+
+ if (gdkpixmap)
+ gdk_pixmap_ref (gdkpixmap);
+
+ show_pixmap_in_drawing_area (drawing_area, gdkpixmap);
+}
+
+
+gpointer
+property_get_dialog (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ gpointer dialog_value;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, NULL);
+ dialog_value = gtk_object_get_data (GTK_OBJECT (widget), GbDialogValueKey);
+ if (dialog_value)
+ return dialog_value;
+ else
+ return ((char*) gtk_entry_get_text (GTK_ENTRY (widget)));
+}
+
+
+void
+property_set_dialog (const gchar * property_name,
+ const gchar * string,
+ gconstpointer value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ if (value)
+ gtk_object_set_data (GTK_OBJECT (widget), GbDialogValueKey,
+ (gpointer) value);
+ gtk_entry_set_text (GTK_ENTRY (widget), string ? string : "");
+}
+
+
+gchar *
+property_get_filename (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, "");
+ return gtk_object_get_data (GTK_OBJECT (widget), GbFilenameValueKey);
+}
+
+
+void
+property_set_filename (const gchar * property_name,
+ const gchar * value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ gtk_object_set_data_full (GTK_OBJECT (widget), GbFilenameValueKey,
+ g_strdup (value), value ? g_free : NULL);
+
+ if (GTK_IS_ENTRY (widget))
+ gtk_entry_set_text (GTK_ENTRY (widget), value ? g_basename (value) : "");
+ else if (GTK_IS_COMBO (widget))
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (widget)->entry),
+ value ? g_basename (value) : "");
+ else
+ g_warning ("Invalid filename property");
+}
+
+
+GdkFont *
+property_get_font (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply,
+ gchar ** xlfd_fontname)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, NULL);
+ *xlfd_fontname = gtk_object_get_data (GTK_OBJECT (widget), GbFontSpecKey);
+ return (gtk_object_get_data (GTK_OBJECT (widget), GbFontKey));
+}
+
+
+void
+property_set_font (const gchar * property_name,
+ GdkFont * font,
+ const gchar * xlfd_fontname)
+{
+ GdkFont *old_font;
+ gchar *old_xlfd_fontname;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+
+ old_font = gtk_object_get_data (GTK_OBJECT (widget), GbFontKey);
+ if (old_font)
+ gdk_font_unref (old_font);
+ if (font)
+ gdk_font_ref (font);
+ gtk_object_set_data (GTK_OBJECT (widget), GbFontKey, font);
+ old_xlfd_fontname = gtk_object_get_data (GTK_OBJECT (widget), GbFontSpecKey);
+ g_free (old_xlfd_fontname);
+ gtk_object_set_data (GTK_OBJECT (widget), GbFontSpecKey, g_strdup (xlfd_fontname));
+ gtk_entry_set_text (GTK_ENTRY (widget), get_font_name_from_spec (xlfd_fontname));
+}
+
+
+/* This searches through a GtkCombo's popup list to find the listitem whose
+ text matches the text in the GtkEntry. If it finds it, it returns the
+ stock_id stored in the listitem's data, else it returns NULL. */
+#if 0
+static gchar*
+find_stock_id (GtkCombo *value)
+{
+ gchar *text;
+ GList *elem;
+
+ text = (gchar*) gtk_entry_get_text (GTK_ENTRY (value->entry));
+
+ for (elem = GTK_LIST (value->list)->children; elem; elem = elem->next)
+ {
+ GtkWidget *listitem = elem->data;
+ gchar *item_text = glade_util_gtk_combo_func (GTK_LIST_ITEM (listitem));
+ if (!strcmp (item_text, text))
+ return gtk_object_get_data (GTK_OBJECT (listitem), GladeStockIDKey);
+ }
+
+ return NULL;
+}
+#endif
+
+
+gchar*
+property_get_stock_item (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ gchar *stock_id;
+
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, 0);
+
+ /* We want to return the stock_id corresponding to the currently selected
+ item. */
+ stock_id = (gchar*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (widget)->entry));
+ return (*stock_id) ? stock_id : NULL;
+}
+
+
+/* This searches through a GtkCombo's popup list to find the listitem whose
+ stock_id matches the given stock_id. */
+#if 0
+static GtkWidget*
+find_stock_item (GtkCombo *value, const gchar *stock_id)
+{
+ GList *elem;
+
+ if (!stock_id || !stock_id[0])
+ return NULL;
+
+ for (elem = GTK_LIST (value->list)->children; elem; elem = elem->next)
+ {
+ GtkWidget *listitem = elem->data;
+ gchar *elem_stock_id;
+
+ elem_stock_id = gtk_object_get_data (GTK_OBJECT (listitem),
+ GladeStockIDKey);
+ if (elem_stock_id && !strcmp (stock_id, elem_stock_id))
+ return listitem;
+ }
+
+ return NULL;
+}
+#endif
+
+
+void
+property_set_stock_item (const gchar *property_name,
+ const gchar *stock_id)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (widget)->entry),
+ stock_id ? stock_id : "");
+}
+
+
+void
+property_set_stock_item_icon_size (const gchar *property_name,
+ GtkIconSize icon_size)
+{
+ GtkWidget *value;
+
+ value = property_get_value_widget (property_name);
+
+ gtk_object_set_data (GTK_OBJECT (value), GladeIconSizeKey,
+ GINT_TO_POINTER (icon_size));
+
+ show_stock_items (value);
+}
+
+
+gchar*
+property_get_icon (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ gchar *text, *filename;
+
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, 0);
+
+ /* If the field is empty, return NULL. */
+ text = (gchar*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (widget)->entry));
+ if (!*text)
+ return NULL;
+
+ /* Check if the text in the entry matches the basename of any filename
+ set. If it does, return the entire filename. Otherwise return the
+ entry contents. */
+ filename = gtk_object_get_data (GTK_OBJECT (widget), GbFilenameValueKey);
+ if (filename)
+ {
+ const gchar *basename = g_basename (filename);
+ if (!strcmp (basename, text))
+ return filename;
+ }
+
+ return text;
+}
+
+
+void
+property_set_icon (const gchar *property_name,
+ const gchar *icon)
+{
+ const gchar *value = NULL;
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+
+ /* We need to determine whether icon is a stock id or a filename. */
+ if (glade_util_check_is_stock_id (icon))
+ {
+ value = icon;
+ gtk_object_remove_data (GTK_OBJECT (widget), GbFilenameValueKey);
+ }
+ else
+ {
+ value = icon ? g_basename (icon) : "";
+ gtk_object_set_data_full (GTK_OBJECT (widget), GbFilenameValueKey,
+ g_strdup (icon), icon ? g_free : NULL);
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (widget)->entry),
+ value ? value : "");
+
+ show_stock_items (widget);
+}
+
+
+void
+property_set_icon_size (const gchar *property_name,
+ GtkIconSize icon_size)
+{
+ GtkWidget *value;
+
+ value = property_get_value_widget (property_name);
+
+ gtk_object_set_data (GTK_OBJECT (value), GladeIconSizeKey,
+ GINT_TO_POINTER (icon_size));
+
+ show_stock_items (value);
+}
+
+
+void
+property_set_icon_filesel (const gchar *property_name,
+ gboolean filesel)
+{
+ GtkWidget *button;
+
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+
+ if (filesel)
+ gtk_widget_show (button);
+ else
+ gtk_widget_hide (button);
+}
+
+
+gchar *
+property_get_named_icon (const gchar * property_name,
+ GtkWidget * to_apply,
+ gboolean * apply)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ if (apply)
+ *apply = (!to_apply || to_apply == widget) ? TRUE : FALSE;
+ g_return_val_if_fail (widget != NULL, "");
+ return ((char*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (widget)->entry)));
+}
+
+
+void
+property_set_named_icon (const gchar * property_name,
+ const gchar * value)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (widget)->entry), value ? value : "");
+}
+
+/*
+ * For getting the widgets used to display properties.
+ */
+GtkWidget*
+property_get_value_widget (const gchar *property_name)
+{
+ return (GtkWidget *) g_hash_table_lookup (gb_property_values, property_name);
+}
+
+
+/*
+ * Setting properties sensitive/insensitive
+ */
+void
+property_set_sensitive (const gchar * property_name, gboolean sensitive)
+{
+ property_set_sensitive_full (property_name, sensitive, sensitive, TRUE);
+}
+
+void
+property_set_sensitive_full (const gchar * property_name,
+ gboolean label_sensitive,
+ gboolean value_sensitive,
+ gboolean button_visible)
+{
+ GtkWidget *value, *label, *button;
+
+ value = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (value != NULL);
+ gtk_widget_set_sensitive (value, value_sensitive);
+
+ label = (GtkWidget *) g_hash_table_lookup (gb_property_labels,
+ property_name);
+ if (label)
+ gtk_widget_set_sensitive (label, label_sensitive);
+
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+ if (button)
+ {
+ if (button_visible)
+ {
+ gtk_widget_show (button);
+ if (GTK_IS_TOGGLE_BUTTON (button))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ value_sensitive);
+ else
+ gtk_widget_set_sensitive (button, value_sensitive);
+ }
+ else
+ gtk_widget_hide (button);
+ }
+}
+
+
+void
+property_set_visible (const gchar * property_name,
+ gboolean visible)
+{
+ GtkWidget *value, *label, *button;
+
+ value = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (value != NULL);
+ if (visible)
+ gtk_widget_show (value);
+ else
+ gtk_widget_hide (value);
+
+
+ label = (GtkWidget *) g_hash_table_lookup (gb_property_labels,
+ property_name);
+ if (label)
+ {
+ if (visible)
+ gtk_widget_show (label);
+ else
+ gtk_widget_hide (label);
+ }
+
+ button = (GtkWidget *) g_hash_table_lookup (gb_property_buttons,
+ property_name);
+ if (button)
+ {
+ if (visible)
+ gtk_widget_show (button);
+ else
+ gtk_widget_hide (button);
+ }
+
+ /* Hide the parent of the value/button if it isn't the main table.
+ We need this since sometimes the table doesn't resize properly, and we
+ are left with a blank row. */
+ if (value->parent && !GTK_IS_TABLE (value->parent))
+ {
+ if (visible)
+ gtk_widget_show (value->parent);
+ else
+ gtk_widget_hide (value->parent);
+ }
+}
+
+
+/*
+ * Setting properties valid/invalid
+ */
+void
+property_set_valid (const gchar * property_name, gboolean valid)
+{
+ GtkWidget *widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (widget != NULL);
+
+ if (valid)
+ gtk_widget_set_style (widget, gtk_widget_get_default_style ());
+ else
+ gtk_widget_set_style (widget, invalid_style);
+}
+
+
+/*
+ * Color previews - for showing style colors
+ */
+
+static GtkWidget *
+create_color_preview ()
+{
+ GtkWidget *preview;
+ GdkColormap *colormap;
+ GdkColor *color;
+
+ preview = gtk_drawing_area_new ();
+ gtk_widget_show (preview);
+
+ color = g_new (GdkColor, 1);
+ color->red = color->green = color->blue = 0xFFFF;
+ gtk_object_set_data (GTK_OBJECT (preview), GbColorKey, color);
+
+ /* Allocate the color. */
+ colormap = gtk_widget_get_colormap (preview);
+ if (!gdk_color_alloc (colormap, color))
+ {
+ g_warning ("Couldn't allocate white color");
+ }
+
+ return preview;
+}
+
+
+/* Returns TRUE if the color has changed. */
+static gboolean
+show_color_in_preview (GtkWidget * preview, GdkColor *new_color)
+{
+ GdkColormap *colormap;
+ GdkColor *color;
+ gulong pixel;
+
+ color = gtk_object_get_data (GTK_OBJECT (preview), GbColorKey);
+ g_return_val_if_fail (color != NULL, FALSE);
+
+ /* If it is the same, return FALSE. */
+ if (color->red == new_color->red
+ && color->green == new_color->green
+ && color->blue == new_color->blue)
+ return FALSE;
+
+ /* Allocate the color. */
+ colormap = gtk_widget_get_colormap (preview);
+ if (!gdk_color_alloc (colormap, new_color))
+ {
+ /* If we can't allocate the colour, keep the old one. */
+ g_warning ("Couldn't allocate color");
+ return FALSE;
+ }
+
+ /* Free the old color. */
+ pixel = color->pixel;
+ gdk_colors_free (colormap, &pixel, 1, 0);
+
+ *color = *new_color;
+
+ /* The drawing area doesn't get a window until the notebook page is shown! */
+ if (preview->window)
+ {
+ gdk_window_set_background (preview->window, color);
+ gdk_window_clear (preview->window);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Pixmap values (displayed as background of drawing area)
+ */
+static void
+show_pixmap_in_drawing_area (GtkWidget * drawing_area, GdkPixmap * gdkpixmap)
+{
+ g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
+ /* The drawing area doesn't get a window until the notebook page is shown! */
+ if (drawing_area->window == NULL)
+ return;
+ if (gdkpixmap)
+ {
+ gdk_window_set_back_pixmap (drawing_area->window, gdkpixmap, FALSE);
+ }
+ else
+ {
+ gdk_window_set_background (drawing_area->window,
+ &drawing_area->style->bg[GTK_STATE_NORMAL]);
+ }
+ gdk_window_clear (drawing_area->window);
+}
+
+
+static gint
+expose_pixmap (GtkWidget * drawing_area, GdkEventExpose * event, gpointer data)
+{
+ GdkPixmap *gdkpixmap;
+
+ g_return_val_if_fail (GTK_IS_DRAWING_AREA (drawing_area), FALSE);
+
+ gdkpixmap = gtk_object_get_data (GTK_OBJECT (drawing_area), GbBgPixmapKey);
+ show_pixmap_in_drawing_area (drawing_area, gdkpixmap);
+ on_color_draw (drawing_area, NULL);
+
+ return FALSE;
+}
+
+
+/*
+ * The Events dialog, used for selecting which X events to receive.
+ */
+
+static void
+show_events_dialog (GtkWidget * widget, gpointer value)
+{
+ GtkWidget *dialog, *clist, *scrolled_win;
+ GtkWindow *transient_parent;
+ gchar *titles[2];
+ const gchar *row[2];
+ int i;
+ gchar *event_mask_string;
+ gint event_mask_value;
+
+ transient_parent = (GtkWindow*) glade_util_get_toplevel (widget);
+ dialog = gtk_dialog_new_with_buttons (_("Select X Events"),
+ transient_parent, 0,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "select_events", "Glade");
+
+ titles[0] = _("Event Mask");
+ titles[1] = _("Description");
+ clist = gtk_clist_new_with_titles (2, titles);
+ gtk_clist_column_titles_passive (GTK_CLIST (clist));
+ gtk_clist_set_column_width (GTK_CLIST (clist), 0, 230);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 1, 100);
+ gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_MULTIPLE);
+ gtk_widget_set_usize (clist, 500, 350);
+ gtk_widget_show (clist);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scrolled_win,
+ TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_win);
+
+ /* Insert events & descriptions */
+ gtk_clist_freeze (GTK_CLIST (clist));
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ row[0] = GbEventMaskSymbols[i];
+ row[1] = _(GbEventMaskDescriptions[i]);
+ gtk_clist_append (GTK_CLIST (clist), (gchar**)row);
+ }
+
+ /* Select rows according to current mask setting */
+ event_mask_string = (char*) gtk_entry_get_text (GTK_ENTRY (value));
+ event_mask_value = property_events_string_to_value (event_mask_string);
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ if (event_mask_value & GbEventMaskValues[i])
+ {
+ gtk_clist_select_row (GTK_CLIST (clist), i, 0);
+ }
+ }
+ gtk_clist_thaw (GTK_CLIST (clist));
+
+ /* Save pointer to value to use when OK pressed */
+ gtk_object_set_data (GTK_OBJECT (clist), GbValueWidgetKey, value);
+
+ gtk_signal_connect (GTK_OBJECT (dialog), "response",
+ GTK_SIGNAL_FUNC (on_events_dialog_response),
+ clist);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+}
+
+
+static void
+on_events_dialog_response (GtkWidget * widget, gint response_id,
+ GtkWidget * clist)
+{
+ gint row, mask_value = 0;
+ GtkWidget *dialog, *value;
+ GList *selection = GTK_CLIST (clist)->selection;
+
+ dialog = gtk_widget_get_toplevel (clist);
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ while (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ mask_value |= GbEventMaskValues[row];
+ selection = selection->next;
+ }
+
+ value = gtk_object_get_data (GTK_OBJECT (clist), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+ gtk_entry_set_text (GTK_ENTRY (value),
+ property_events_value_to_string (mask_value));
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+
+/* Converts the events gint to a string of 0s and 1s for displaying */
+gchar *
+property_events_value_to_string (gint event_mask)
+{
+ static gchar buf[GB_EVENT_MASKS_COUNT + 2];
+ int i;
+
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ if (event_mask & GbEventMaskValues[i])
+ buf[GB_EVENT_MASKS_COUNT - i - 1] = '1';
+ else
+ buf[GB_EVENT_MASKS_COUNT - i - 1] = '0';
+ }
+ buf[GB_EVENT_MASKS_COUNT] = '0';
+ buf[GB_EVENT_MASKS_COUNT + 1] = '\0';
+ return buf;
+}
+
+
+/* Converts the string of 0s and 1s back to a gint event mask */
+gint
+property_events_string_to_value (const gchar * event_string)
+{
+ gint i, value = 0;
+
+ if (strlen (event_string) < GB_EVENT_MASKS_COUNT)
+ return 0;
+ for (i = 0; i < GB_EVENT_MASKS_COUNT; i++)
+ {
+ if (event_string[GB_EVENT_MASKS_COUNT - i - 1] == '1')
+ value |= GbEventMaskValues[i];
+ }
+ return value;
+}
+
+
+/*
+ * The Accelerators page
+ */
+
+static void
+on_accelerator_add (GtkWidget * widget, GtkWidget * clist)
+{
+ gchar modifiers[4];
+ gchar *row[3];
+ gchar *key, *signal;
+
+ key = property_get_string (GbAccelKey, NULL, NULL, NULL);
+ if (strlen (key) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the accelerator key"),
+ widget);
+ return;
+ }
+ signal = property_get_string (GbAccelSignal, NULL, NULL, NULL);
+ if (strlen (signal) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the signal to emit"),
+ widget);
+ return;
+ }
+
+ modifiers[0] = modifiers[1] = modifiers[2] = ' ';
+ modifiers[3] = '\0';
+ if (GTK_TOGGLE_BUTTON (accel_control_button)->active)
+ modifiers[0] = 'C';
+ if (GTK_TOGGLE_BUTTON (accel_shift_button)->active)
+ modifiers[1] = 'S';
+ if (GTK_TOGGLE_BUTTON (accel_alt_button)->active)
+ modifiers[2] = 'A';
+
+ row[ACCEL_MODIFIERS_COL] = modifiers;
+ row[ACCEL_KEY_COL] = key;
+ row[ACCEL_SIGNAL_COL] = signal;
+ gtk_clist_append (GTK_CLIST (clist), row);
+
+ /* clear the key & signal fields */
+ property_set_string (GbAccelKey, "");
+ property_set_string (GbAccelSignal, "");
+
+ on_property_changed (clist, clist);
+}
+
+
+static void
+on_accelerator_update (GtkWidget * widget, GtkWidget * clist)
+{
+ gchar modifiers[4];
+ gchar *key, *signal;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gint row;
+
+ if (!selection)
+ return;
+ row = GPOINTER_TO_INT (selection->data);
+
+ key = property_get_string (GbAccelKey, NULL, NULL, NULL);
+ if (strlen (key) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the accelerator key"),
+ widget);
+ return;
+ }
+ signal = property_get_string (GbAccelSignal, NULL, NULL, NULL);
+ if (strlen (signal) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the signal to emit"),
+ widget);
+ return;
+ }
+
+ modifiers[0] = modifiers[1] = modifiers[2] = ' ';
+ modifiers[3] = '\0';
+ if (GTK_TOGGLE_BUTTON (accel_control_button)->active)
+ modifiers[0] = 'C';
+ if (GTK_TOGGLE_BUTTON (accel_shift_button)->active)
+ modifiers[1] = 'S';
+ if (GTK_TOGGLE_BUTTON (accel_alt_button)->active)
+ modifiers[2] = 'A';
+
+ gtk_clist_set_text (GTK_CLIST (clist), row, ACCEL_MODIFIERS_COL, modifiers);
+ gtk_clist_set_text (GTK_CLIST (clist), row, ACCEL_KEY_COL, key);
+ gtk_clist_set_text (GTK_CLIST (clist), row, ACCEL_SIGNAL_COL, signal);
+
+ on_property_changed (clist, clist);
+}
+
+
+static void
+on_accelerator_delete (GtkWidget * widget, GtkWidget * clist)
+{
+ GList *selection = GTK_CLIST (clist)->selection;
+ gint row;
+
+ if (!selection)
+ return;
+ row = GPOINTER_TO_INT (selection->data);
+ gtk_clist_remove (GTK_CLIST (clist), row);
+ /* clear the key & signal fields */
+ property_set_string (GbAccelKey, "");
+ property_set_string (GbAccelSignal, "");
+
+ on_property_changed (clist, clist);
+}
+
+
+static void
+on_accelerator_clear (GtkWidget * widget, GtkWidget * clist)
+{
+ property_set_string (GbAccelKey, "");
+ property_set_string (GbAccelSignal, "");
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (accel_control_button), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (accel_shift_button), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (accel_alt_button), FALSE);
+}
+
+
+static void
+on_accelerator_select (GtkWidget * clist, gint row, gint column,
+ GdkEventButton * event, gpointer user_data)
+{
+ gchar *modifiers, *key, *signal;
+ gint len;
+
+ gtk_clist_get_text (GTK_CLIST (clist), row, ACCEL_MODIFIERS_COL, &modifiers);
+ gtk_clist_get_text (GTK_CLIST (clist), row, ACCEL_KEY_COL, &key);
+ gtk_clist_get_text (GTK_CLIST (clist), row, ACCEL_SIGNAL_COL, &signal);
+
+ len = strlen (modifiers);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (accel_control_button),
+ len >= 1 && modifiers[0] != ' ');
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (accel_shift_button),
+ len >= 2 && modifiers[1] != ' ');
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (accel_alt_button),
+ len >= 3 && modifiers[2] != ' ');
+
+ property_set_string (GbAccelKey, key);
+ property_set_string (GbAccelSignal, signal);
+}
+
+
+void
+property_clear_accelerators ()
+{
+ gtk_clist_clear (GTK_CLIST (accel_clist));
+ /* clear the key & signal fields */
+ property_set_string (GbAccelKey, "");
+ property_set_string (GbAccelSignal, "");
+}
+
+
+void
+property_add_accelerator (GladeAccelerator * accel)
+{
+ gchar modifiers[4];
+ gchar *row[3];
+
+ modifiers[0] = modifiers[1] = modifiers[2] = ' ';
+ modifiers[3] = '\0';
+ if (accel->modifiers & GDK_CONTROL_MASK)
+ modifiers[0] = 'C';
+ if (accel->modifiers & GDK_SHIFT_MASK)
+ modifiers[1] = 'S';
+ /* The Alt key uses GDK_MOD1_MASK */
+ if (accel->modifiers & GDK_MOD1_MASK)
+ modifiers[2] = 'A';
+
+ row[ACCEL_MODIFIERS_COL] = modifiers;
+ row[ACCEL_KEY_COL] = accel->key;
+ row[ACCEL_SIGNAL_COL] = accel->signal;
+ gtk_clist_append (GTK_CLIST (accel_clist), row);
+}
+
+
+gboolean
+property_is_accel_clist (GtkWidget * widget)
+{
+ return (widget == accel_clist) ? TRUE : FALSE;
+}
+
+
+GList *
+property_get_accelerators ()
+{
+ gint row, len;
+ GList *accelerators = NULL;
+ GladeAccelerator *accel;
+ gchar *modifiers, *key, *signal;
+
+ for (row = 0; row < GTK_CLIST (accel_clist)->rows; row++)
+ {
+ accel = g_new (GladeAccelerator, 1);
+
+ gtk_clist_get_text (GTK_CLIST (accel_clist), row,
+ ACCEL_MODIFIERS_COL, &modifiers);
+ gtk_clist_get_text (GTK_CLIST (accel_clist), row,
+ ACCEL_KEY_COL, &key);
+ gtk_clist_get_text (GTK_CLIST (accel_clist), row,
+ ACCEL_SIGNAL_COL, &signal);
+
+ len = strlen (modifiers);
+ accel->modifiers = 0;
+ if (len >= 1 && modifiers[0] != ' ')
+ accel->modifiers |= GDK_CONTROL_MASK;
+ if (len >= 2 && modifiers[1] != ' ')
+ accel->modifiers |= GDK_SHIFT_MASK;
+ if (len >= 3 && modifiers[2] != ' ')
+ accel->modifiers |= GDK_MOD1_MASK;
+
+ accel->key = g_strdup (key);
+ accel->signal = g_strdup (signal);
+ accelerators = g_list_append (accelerators, accel);
+ }
+ return accelerators;
+}
+
+
+/*
+ * The Accelerator Keys dialog for selecting an accelerator key.
+ */
+
+static void
+show_keys_dialog (GtkWidget * widget, gpointer value)
+{
+ GladeKeysDialog *dialog;
+ GtkWidget *transient_parent;
+
+ dialog = GLADE_KEYS_DIALOG (glade_keys_dialog_new ());
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ transient_parent = glade_util_get_toplevel (widget);
+ if (GTK_IS_WINDOW (transient_parent))
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ GTK_WINDOW (transient_parent));
+ /* Save pointer to value to use when OK pressed */
+ gtk_object_set_data (GTK_OBJECT (dialog), GbValueWidgetKey, value);
+ gtk_signal_connect (GTK_OBJECT (dialog->clist), "select_row",
+ GTK_SIGNAL_FUNC (on_keys_clist_select), dialog);
+ gtk_signal_connect (GTK_OBJECT (dialog), "response",
+ GTK_SIGNAL_FUNC (on_keys_dialog_response),
+ NULL);
+ gtk_widget_show (GTK_WIDGET (dialog));
+}
+
+
+static void
+on_keys_dialog_response (GtkWidget * widget, gint response_id, gpointer data)
+{
+ GladeKeysDialog *dialog;
+ GtkWidget *value;
+ gchar *key_symbol;
+
+ dialog = (GladeKeysDialog*) widget;
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ key_symbol = glade_keys_dialog_get_key_symbol (dialog);
+ if (key_symbol)
+ {
+ value = gtk_object_get_data (GTK_OBJECT (dialog), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+ gtk_entry_set_text (GTK_ENTRY (value), key_symbol);
+ }
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+
+static void
+on_keys_clist_select (GtkWidget * widget, gint row, gint column,
+ GdkEventButton * bevent, gpointer data)
+{
+ if (bevent && bevent->type == GDK_2BUTTON_PRESS)
+ on_keys_dialog_response (GTK_WIDGET (data), GTK_RESPONSE_OK, NULL);
+}
+
+
+/*
+ * The Signals page
+ */
+
+static void
+on_signal_add (GtkWidget * widget, GtkWidget * clist)
+{
+ gchar *row_data[5];
+ gchar *signal, *handler, *object, *data;
+ gboolean after;
+ gint row;
+ time_t *last_mod_time;
+
+ signal = property_get_string (GbSignalName, NULL, NULL, NULL);
+ if (strlen (signal) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the signal name"),
+ widget);
+ return;
+ }
+ handler = property_get_combo (GbSignalHandler, NULL, NULL);
+ if (strlen (handler) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the handler for the signal"), widget);
+ return;
+ }
+ object = property_get_string (GbSignalObject, NULL, NULL, NULL);
+ after = property_get_bool (GbSignalAfter, NULL, NULL);
+ data = property_get_string (GbSignalData, NULL, NULL, NULL);
+
+ row_data[SIGNAL_NAME_COL] = signal;
+ row_data[SIGNAL_HANDLER_COL] = handler;
+ row_data[SIGNAL_OBJECT_COL] = object;
+ row_data[SIGNAL_AFTER_COL] = after ? "Y" : "";
+ row_data[SIGNAL_DATA_COL] = data;
+ row = gtk_clist_append (GTK_CLIST (clist), row_data);
+
+ /* Set the last modification time to the current time. */
+ last_mod_time = g_chunk_new (time_t, signal_mem_chunk);
+ *last_mod_time = time (NULL);
+ if (*last_mod_time == (time_t) -1)
+ g_warning ("Error getting current time");
+ gtk_clist_set_row_data (GTK_CLIST (signal_clist), row, last_mod_time);
+
+ /* clear the fields */
+ property_set_string (GbSignalName, "");
+ property_set_combo (GbSignalHandler, "");
+ property_set_string (GbSignalObject, "");
+ property_set_string (GbSignalData, "");
+ property_set_bool (GbSignalAfter, FALSE);
+
+ on_property_changed (clist, clist);
+}
+
+
+static void
+on_signal_update (GtkWidget * widget, GtkWidget * clist)
+{
+ gchar *signal, *handler, *object, *data;
+ gchar *old_signal, *old_handler, *old_data;
+ gboolean after;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gint row;
+ time_t *last_mod_time;
+
+ if (!selection)
+ return;
+ row = GPOINTER_TO_INT (selection->data);
+
+ signal = property_get_string (GbSignalName, NULL, NULL, NULL);
+ if (strlen (signal) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the signal name"),
+ widget);
+ return;
+ }
+ handler = property_get_combo (GbSignalHandler, NULL, NULL);
+ if (strlen (handler) == 0)
+ {
+ glade_util_show_message_box (_("You need to set the handler for the signal"), widget);
+ return;
+ }
+ object = property_get_string (GbSignalObject, NULL, NULL, NULL);
+ after = property_get_bool (GbSignalAfter, NULL, NULL);
+ data = property_get_string (GbSignalData, NULL, NULL, NULL);
+
+ /* We update the last_mod_time if the signal, handler or data have changed.*/
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_NAME_COL, &old_signal);
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_HANDLER_COL, &old_handler);
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_DATA_COL, &old_data);
+ if (strcmp (signal, old_signal) || strcmp (handler, old_handler)
+ || strcmp (data, old_data))
+ {
+ last_mod_time = (time_t*) gtk_clist_get_row_data (GTK_CLIST (signal_clist), row);
+ *last_mod_time = time (NULL);
+ if (*last_mod_time == (time_t) -1)
+ g_warning ("Error getting current time");
+ }
+
+ gtk_clist_set_text (GTK_CLIST (clist), row, SIGNAL_NAME_COL, signal);
+ gtk_clist_set_text (GTK_CLIST (clist), row, SIGNAL_HANDLER_COL, handler);
+ gtk_clist_set_text (GTK_CLIST (clist), row, SIGNAL_OBJECT_COL, object);
+ gtk_clist_set_text (GTK_CLIST (clist), row, SIGNAL_AFTER_COL,
+ after ? "Y" : "");
+ gtk_clist_set_text (GTK_CLIST (clist), row, SIGNAL_DATA_COL, data);
+
+ on_property_changed (clist, clist);
+}
+
+
+static void
+on_signal_delete (GtkWidget * widget, GtkWidget * clist)
+{
+ GList *selection = GTK_CLIST (clist)->selection;
+ gint row;
+
+ if (!selection)
+ return;
+ row = GPOINTER_TO_INT (selection->data);
+ gtk_clist_remove (GTK_CLIST (clist), row);
+ /* clear the key & signal fields */
+ property_set_string (GbSignalName, "");
+ property_set_combo (GbSignalHandler, "");
+ property_set_string (GbSignalObject, "");
+ property_set_string (GbSignalData, "");
+
+ on_property_changed (clist, clist);
+}
+
+
+static void
+on_signal_clear (GtkWidget * widget, GtkWidget * clist)
+{
+ property_set_string (GbSignalName, "");
+ property_set_combo (GbSignalHandler, "");
+ property_set_string (GbSignalObject, "");
+ property_set_string (GbSignalData, "");
+ property_set_bool (GbSignalAfter, FALSE);
+}
+
+
+static void
+on_signal_select (GtkWidget * clist,
+ gint row,
+ gint column,
+ GdkEventButton * event,
+ gpointer user_data)
+{
+ gchar *signal, *handler, *object, *after, *data;
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_NAME_COL, &signal);
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_HANDLER_COL, &handler);
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_OBJECT_COL, &object);
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_AFTER_COL, &after);
+ gtk_clist_get_text (GTK_CLIST (clist), row, SIGNAL_DATA_COL, &data);
+ property_set_string (GbSignalName, signal);
+ property_set_combo (GbSignalHandler, handler);
+ property_set_string (GbSignalObject, object);
+ if (!strcmp (after, "Y"))
+ property_set_bool (GbSignalAfter, TRUE);
+ else
+ property_set_bool (GbSignalAfter, FALSE);
+ property_set_string (GbSignalData, data);
+}
+
+
+void
+property_clear_signals ()
+{
+ gtk_clist_clear (GTK_CLIST (signal_clist));
+ /* clear the fields */
+ property_set_string (GbSignalName, "");
+ property_set_combo (GbSignalHandler, "");
+ property_set_string (GbSignalObject, "");
+ property_set_string (GbSignalData, "");
+
+ g_mem_chunk_reset (signal_mem_chunk);
+}
+
+
+void
+property_add_signal (GladeSignal * signal)
+{
+ gchar *row_data[5];
+ time_t *last_mod_time;
+ gint row;
+
+ row_data[SIGNAL_NAME_COL] = signal->name ? signal->name : "";
+ row_data[SIGNAL_HANDLER_COL] = signal->handler ? signal->handler : "";
+ row_data[SIGNAL_OBJECT_COL] = signal->object ? signal->object : "";
+ row_data[SIGNAL_AFTER_COL] = signal->after ? "Y" : "";
+ row_data[SIGNAL_DATA_COL] = signal->data ? signal->data : "";
+ row = gtk_clist_append (GTK_CLIST (signal_clist), row_data);
+
+ last_mod_time = g_chunk_new (time_t, signal_mem_chunk);
+ *last_mod_time = signal->last_modification_time;
+ gtk_clist_set_row_data (GTK_CLIST (signal_clist), row, last_mod_time);
+}
+
+
+gboolean
+property_is_signal_clist (GtkWidget * widget)
+{
+ return (widget == signal_clist) ? TRUE : FALSE;
+}
+
+
+GList *
+property_get_signals ()
+{
+ gint row;
+ GList *signals = NULL;
+ GladeSignal *signal;
+ gchar *name, *handler, *object, *after, *data;
+ time_t *time;
+
+ for (row = 0; row < GTK_CLIST (signal_clist)->rows; row++)
+ {
+ signal = g_new (GladeSignal, 1);
+
+ gtk_clist_get_text (GTK_CLIST (signal_clist), row,
+ SIGNAL_NAME_COL, &name);
+ gtk_clist_get_text (GTK_CLIST (signal_clist), row,
+ SIGNAL_HANDLER_COL, &handler);
+ gtk_clist_get_text (GTK_CLIST (signal_clist), row,
+ SIGNAL_OBJECT_COL, &object);
+ gtk_clist_get_text (GTK_CLIST (signal_clist), row,
+ SIGNAL_AFTER_COL, &after);
+ gtk_clist_get_text (GTK_CLIST (signal_clist), row,
+ SIGNAL_DATA_COL, &data);
+ time = gtk_clist_get_row_data (GTK_CLIST (signal_clist), row);
+
+ signal->name = strlen (name) > 0 ? g_strdup (name) : NULL;
+ signal->handler = strlen (handler) > 0 ? g_strdup (handler) : NULL;
+ signal->object = strlen (object) > 0 ? g_strdup (object) : NULL;
+ signal->after = !strcmp (after, "Y") ? TRUE : FALSE;
+ signal->data = strlen (data) > 0 ? g_strdup (data) : NULL;
+ signal->last_modification_time = *time;
+ signals = g_list_append (signals, signal);
+ }
+ return signals;
+}
+
+
+/*
+ * The Signals dialog box for selecting a signal to handle.
+ */
+
+static void
+add_signals_for_type (GType type, GtkWidget *clist, GdkColor *inactive_fg, GdkColor *inactive_bg, gchar *current_signal, gboolean show_actions_only)
+{
+ guint *signals;
+ guint nsignals;
+ gchar *name;
+ gint i;
+ gint row;
+ GList *items, *elem;
+ GSignalQuery query_info;
+
+ signals = g_signal_list_ids (type, &nsignals);
+
+ row = GTK_CLIST (clist)->rows;
+ if (nsignals)
+ {
+ items = NULL;
+ for (i = 0; i < nsignals; i++)
+ {
+ g_signal_query (signals[i], &query_info);
+
+ if (!show_actions_only
+ || query_info.signal_flags & G_SIGNAL_ACTION)
+ {
+ name = g_strdup (query_info.signal_name);
+ g_strdelimit (name, NULL, '_');
+ items = g_list_prepend (items, name);
+ }
+ }
+
+ if (items)
+ {
+ items = g_list_sort (items, (GCompareFunc)strcmp);
+
+ /* This groups the signals by class, e.g. 'GtkButton signals'. */
+ name = g_strdup_printf (_("%s signals"), gtk_type_name (type));
+ gtk_clist_append (GTK_CLIST (clist), &name);
+ g_free (name);
+ gtk_clist_set_foreground (GTK_CLIST (clist), row, inactive_fg);
+ gtk_clist_set_background (GTK_CLIST (clist), row, inactive_bg);
+ /* Set this so we know when a row containing a class name is
+ selected. See on_signals_clist_select(). */
+ gtk_clist_set_row_data (GTK_CLIST (clist), row, "ClassName");
+ row++;
+
+ elem = items;
+ while (elem)
+ {
+ name = elem->data;
+ gtk_clist_append (GTK_CLIST (clist), &name);
+ gtk_clist_set_shift (GTK_CLIST (clist), row, 0, 0, 10);
+ if (!strcmp (current_signal, name))
+ {
+ gtk_clist_select_row (GTK_CLIST (clist), row, 0);
+ }
+ row++;
+ g_free (name);
+ elem = elem->next;
+ }
+ g_list_free (items);
+ }
+ }
+
+ g_free (signals);
+}
+
+static void
+show_signals_dialog (GtkWidget * widget, gpointer value)
+{
+ GtkWidget *dialog, *clist, *scrolled_win;
+ GtkWindow *transient_parent;
+ gchar *titles[1];
+ GType type;
+ GdkColor *inactive_fg, *inactive_bg;
+ GType *interfaces;
+ guint n_interfaces = 0;
+ gchar *current_signal;
+ gint i;
+ gboolean show_actions_only = FALSE;
+
+ if (!property_widget)
+ return;
+
+ /* For keyboard accelerators we only show ACTION signals, since they are
+ the only signals that can be used. */
+ if (property_get_value_widget (GbAccelSignal) == value)
+ {
+ g_print ("Showing ACTION signals only\n");
+ show_actions_only = TRUE;
+ }
+
+ transient_parent = (GtkWindow*) glade_util_get_toplevel (widget);
+ dialog = gtk_dialog_new_with_buttons (_("Select Signal"),
+ transient_parent, 0,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "select_signal", "Glade");
+
+ titles[0] = _("Signals");
+ clist = gtk_clist_new_with_titles (1, titles);
+ gtk_clist_column_titles_passive (GTK_CLIST (clist));
+ gtk_widget_set_usize (clist, 240, 260);
+ gtk_widget_show (clist);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scrolled_win,
+ TRUE, TRUE, 0);
+ gtk_widget_show(scrolled_win);
+
+ /* Insert list of signals. */
+ gtk_clist_freeze (GTK_CLIST (clist));
+
+ current_signal = (char*) gtk_entry_get_text (GTK_ENTRY (value));
+
+ /* For custom widgets we only allow standard widget signals to be set. */
+ if (GLADE_IS_CUSTOM_WIDGET (property_widget))
+ type = gtk_widget_get_type ();
+ else
+ type = GTK_OBJECT_TYPE (property_widget);
+
+ inactive_fg = &widget->style->fg[GTK_STATE_INSENSITIVE];
+ inactive_bg = &widget->style->bg[GTK_STATE_INSENSITIVE];
+
+ interfaces = g_type_interfaces (type, &n_interfaces);
+ for (i = 0; i < n_interfaces; i++)
+ {
+ add_signals_for_type (interfaces[i], clist, inactive_fg, inactive_bg, current_signal, show_actions_only);
+ }
+ g_free (interfaces);
+
+ while (type)
+ {
+ add_signals_for_type (type, clist, inactive_fg, inactive_bg, current_signal, show_actions_only);
+ type = gtk_type_parent (type);
+ }
+
+ gtk_clist_thaw (GTK_CLIST (clist));
+ gtk_signal_connect (GTK_OBJECT (clist), "select_row",
+ GTK_SIGNAL_FUNC (on_signals_clist_select), clist);
+
+ /* Save pointer to value to use when OK pressed */
+ gtk_object_set_data (GTK_OBJECT (clist), GbValueWidgetKey, value);
+
+ gtk_signal_connect (GTK_OBJECT (dialog), "response",
+ GTK_SIGNAL_FUNC (on_signals_dialog_response),
+ clist);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+}
+
+
+static void
+on_signals_dialog_response (GtkWidget * widget, gint response_id,
+ GtkWidget * clist)
+{
+ gint row, page;
+ GtkWidget *dialog, *value, *handler;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gchar *name, *handler_text;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ if (response_id != GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ return;
+ }
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ value = gtk_object_get_data (GTK_OBJECT (clist), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+ gtk_clist_get_text (GTK_CLIST (clist), row, 0, &name);
+ gtk_entry_set_text (GTK_ENTRY (value), name);
+
+ /* If we're on the Signals page, and the current handler is empty,
+ insert an initial value of "on_<widget name>_<signal name>",
+ with '-' in widget name changed to '_' */
+ page = gtk_notebook_get_current_page (GTK_NOTEBOOK (main_notebook));
+ if (page == GB_PAGE_SIGNALS)
+ {
+ handler = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ GbSignalHandler);
+ g_return_if_fail (handler != NULL);
+ handler_text = (char*) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (handler)->entry));
+
+ if (strlen (handler_text) == 0)
+ {
+ gchar buf[128];
+ gchar *widget_name;
+ widget_name = g_strdup (gtk_widget_get_name (property_widget));
+ if (widget_name
+ && strlen (widget_name) + strlen (name) + 5 < 128)
+ {
+ g_strdelimit (widget_name, "-", '_');
+ sprintf (buf, "on_%s_%s", widget_name, name);
+ gtk_entry_set_text (GTK_ENTRY ( GTK_COMBO (handler)->entry),
+ buf);
+ gtk_editable_select_region (GTK_EDITABLE ( GTK_COMBO (handler)->entry), 0, -1);
+ }
+ g_free (widget_name);
+ gtk_widget_grab_focus (handler);
+ }
+ }
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+
+static void
+on_signals_clist_select (GtkWidget * widget, gint row, gint column,
+ GdkEventButton * bevent, gpointer data)
+{
+ /* Don't allow selection of widget class names */
+ if (gtk_clist_get_row_data (GTK_CLIST (widget), row))
+ gtk_clist_unselect_row (GTK_CLIST (widget), row, 0);
+ if (bevent && bevent->type == GDK_2BUTTON_PRESS)
+ {
+ on_signals_dialog_response (widget, GTK_RESPONSE_OK, widget);
+ }
+}
+
+
+/*
+ void
+ on_apply(GtkWidget *widget, gpointer data)
+ {
+ if (!property_widget) return;
+ gb_widget_apply_properties(property_widget, NULL);
+ }
+ */
+
+void
+property_set_auto_apply (gboolean value)
+{
+ auto_apply = value;
+}
+
+
+/* This is just used for debugging */
+#ifdef GLADE_DEBUG
+static void
+find_hash_value (const gchar * key, gpointer data, gpointer property)
+{
+ if (data == property)
+ MSG1 (" applying property: %s", key);
+}
+#endif
+
+static void
+on_property_changed (GtkWidget * widget, GtkWidget * property)
+{
+ if (property_widget && auto_apply)
+ {
+#ifdef GLADE_DEBUG
+ g_hash_table_foreach (gb_property_values, (GHFunc) find_hash_value,
+ property);
+#endif
+ gb_widget_apply_properties (property_widget, property);
+ }
+}
+
+
+static gboolean
+on_property_focus_out (GtkWidget * widget, GdkEventFocus *event,
+ GtkWidget * property)
+{
+ MSG ("In on_property_focus_out");
+ on_property_changed (widget, property);
+ return FALSE;
+}
+
+
+/*
+ * Adjustments - handles adding/showing/applying of all 6 properties
+ */
+void
+property_add_adjustment (const gchar * Values[], gint label_type)
+{
+ const gchar *default_labels[] =
+ {N_("Value:"), N_("Min:"), N_("Max:"), N_("Step Inc:"),
+ N_("Page Inc:"), N_("Page Size:")};
+ const gchar *horz_labels[] =
+ {N_("H Value:"), N_("H Min:"), N_("H Max:"), N_("H Step Inc:"),
+ N_("H Page Inc:"), N_("H Page Size:")};
+ const gchar *vert_labels[] =
+ {N_("V Value:"), N_("V Min:"), N_("V Max:"), N_("V Step Inc:"),
+ N_("V Page Inc:"), N_("V Page Size:")};
+ const gchar *tips[] =
+ {
+ N_("The initial value"),
+ N_("The minimum value"),
+ N_("The maximum value"),
+ N_("The step increment"),
+ N_("The page increment"),
+ N_("The page size"),
+ };
+ const gchar **labels;
+ gint i;
+
+ if (label_type == GB_ADJUST_H_LABELS)
+ labels = horz_labels;
+ else if (label_type == GB_ADJUST_V_LABELS)
+ labels = vert_labels;
+ else
+ labels = default_labels;
+
+ for (i = 0; i < 6; i++)
+ {
+ if (Values[i])
+ {
+ property_add_float (Values[i], _(labels[i]), _(tips[i]));
+ }
+ }
+}
+
+
+/*
+ * The Font dialog
+ */
+
+/* This is the default GTK font spec., from gtkstyle.c */
+#define GB_DEFAULT_XLFD_FONTNAME \
+ "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*"
+
+static void
+show_font_dialog (GtkWidget * widget, gpointer value)
+{
+ gchar *current_xlfd_fontname;
+ GtkWidget *transient_parent;
+
+ /* Create the dialog if it doesn't exist yet */
+ if (!fontsel)
+ {
+ fontsel = GTK_FONT_SELECTION_DIALOG (gtk_font_selection_dialog_new (NULL));
+
+ /* The OK/Apply/Cancel button */
+ gtk_signal_connect (GTK_OBJECT (fontsel), "delete_event",
+ GTK_SIGNAL_FUNC (close_dialog_event), fontsel);
+ gtk_signal_connect (GTK_OBJECT (fontsel->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (on_font_dialog_ok), fontsel);
+ gtk_widget_show (fontsel->apply_button);
+ gtk_signal_connect (GTK_OBJECT (fontsel->apply_button), "clicked",
+ GTK_SIGNAL_FUNC (on_font_dialog_apply), fontsel);
+ gtk_signal_connect (GTK_OBJECT (fontsel->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (close_dialog), fontsel);
+ gtk_window_set_wmclass (GTK_WINDOW (fontsel), "font_selection", "Glade");
+ gtk_signal_connect (GTK_OBJECT (fontsel), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscCloses));
+ }
+
+ /* Select font according to current setting */
+ current_xlfd_fontname = gtk_object_get_data (GTK_OBJECT (value), GbFontSpecKey);
+ if (!current_xlfd_fontname || current_xlfd_fontname[0] == '\0')
+ current_xlfd_fontname = GB_DEFAULT_XLFD_FONTNAME;
+
+ gtk_font_selection_dialog_set_font_name (fontsel, current_xlfd_fontname);
+
+ /* Save pointer to value to use when OK/Apply pressed */
+ gtk_object_set_data (GTK_OBJECT (fontsel), GbValueWidgetKey, value);
+
+ gtk_widget_show (GTK_WIDGET (fontsel));
+ transient_parent = glade_util_get_toplevel (widget);
+ if (GTK_IS_WINDOW (transient_parent))
+ gtk_window_set_transient_for (GTK_WINDOW (fontsel),
+ GTK_WINDOW (transient_parent));
+ /* This maps the window, which also de-iconifies it according to ICCCM. */
+ gdk_window_show (GTK_WIDGET (fontsel)->window);
+ gdk_window_raise (GTK_WIDGET (fontsel)->window);
+}
+
+
+/* FIXME: This isn't used at present */
+#if 0
+static gint
+get_font_size_from_spec (const gchar * spec)
+{
+ gint i, size = -1;
+
+ for (i = 0; i < 8; i++)
+ {
+ spec = strchr (spec, '-');
+ if (spec == NULL)
+ return -1;
+ spec++;
+ }
+ sscanf (spec, "%i", &size);
+ return size;
+}
+#endif
+
+/* Note: this only works with standard X font specs, e.g.
+ -adobe-courier-bold-i-normal--0-0-75-75-m-0-iso8859-1
+ It copies the first two fields, changing '-' to ' ' and capitalising the
+ first characters of words - after a '-', ' ' or '&'.
+ Note: returns pointer to static buffer, so copy it if you want to keep it */
+static gchar *
+get_font_name_from_spec (const gchar * spec)
+{
+ static gchar buf[128];
+ gint i, dashes_found = 0;
+ gboolean word_start = TRUE;
+ gchar ch;
+
+ if (spec == NULL)
+ return "";
+
+ for (i = 0; i < 127; i++)
+ {
+ ch = spec[i + 1];
+ if (ch == '\0')
+ break;
+ if (ch == '-')
+ {
+ dashes_found++;
+ if (dashes_found == 2)
+ break;
+ ch = ' ';
+ }
+ if (word_start)
+ ch = toupper (ch);
+ word_start = (ch == ' ' || ch == '&');
+ buf[i] = ch;
+ }
+ buf[i] = '\0';
+ return buf;
+}
+
+
+static void
+on_font_dialog_apply (GtkWidget * widget, GtkFontSelectionDialog * fontsel)
+{
+ GtkWidget *value;
+ GdkFont *font, *old_font;
+ gchar *xlfd_fontname, *old_xlfd_fontname;
+
+ value = gtk_object_get_data (GTK_OBJECT (fontsel), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+
+ /* Try to create the font, if the font spec has changed */
+ xlfd_fontname = gtk_font_selection_dialog_get_font_name (fontsel);
+ font = gtk_font_selection_dialog_get_font (fontsel);
+ old_xlfd_fontname = gtk_object_get_data (GTK_OBJECT (value), GbFontSpecKey);
+
+ if (!old_xlfd_fontname
+ || (xlfd_fontname && strcmp (xlfd_fontname, old_xlfd_fontname)))
+ {
+ if (font == NULL)
+ {
+ glade_util_show_message_box (_("The requested font is not available."), widget);
+ return;
+ }
+
+ old_font = gtk_object_get_data (GTK_OBJECT (value), GbFontKey);
+ if (old_font)
+ gdk_font_unref (old_font);
+ gdk_font_ref (font);
+ gtk_object_set_data (GTK_OBJECT (value), GbFontKey, font);
+ g_free (old_xlfd_fontname);
+ gtk_object_set_data (GTK_OBJECT (value), GbFontSpecKey, g_strdup (xlfd_fontname));
+ gtk_entry_set_text (GTK_ENTRY (value), get_font_name_from_spec (xlfd_fontname));
+ }
+}
+
+
+static void
+on_font_dialog_ok (GtkWidget * widget, GtkFontSelectionDialog * fontsel)
+{
+ on_font_dialog_apply (widget, fontsel);
+ close_dialog (widget, GTK_WIDGET (fontsel));
+}
+
+
+/*
+ * The Style dialog, for selecting a style to use/copy for a widget.
+ */
+
+#ifdef GLADE_STYLE_SUPPORT
+static void
+show_style_dialog (GtkWidget * widget, gpointer value)
+{
+ GtkWidget *dialog;
+ GtkWidget *hbox, *clist, *vbbox, *button, *scrolled_win;
+ GtkWidget *transient_parent;
+ int i;
+ gchar *current_style;
+ gchar *titles[1];
+ gchar *text;
+ gchar *row[1];
+
+ dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 3);
+
+ gtk_signal_connect_object (GTK_OBJECT (dialog), "delete_event",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (dialog));
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Select Named Style"));
+ gtk_window_set_wmclass (GTK_WINDOW (dialog), "select_named_style", "Glade");
+ transient_parent = glade_util_get_toplevel (transient_for);
+ if (GTK_IS_WINDOW (transient_parent))
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ GTK_WINDOW (transient_parent));
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_add (GTK_CONTAINER (dialog), hbox);
+ gtk_widget_show (hbox);
+
+ titles[0] = _("Styles");
+ clist = gtk_clist_new_with_titles (1, titles);
+ gtk_clist_column_titles_passive (GTK_CLIST (clist));
+ gtk_widget_set_usize (clist, 200, 200);
+ gtk_widget_show (clist);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (hbox), scrolled_win, TRUE, TRUE, 0);
+ gtk_widget_show(scrolled_win);
+
+ /* Insert styles */
+ gtk_clist_freeze (GTK_CLIST (clist));
+
+ /* Add unnamed style first */
+ row[0] = GB_STYLE_UNNAMED;
+ gtk_clist_append (GTK_CLIST (clist), row);
+ g_hash_table_foreach (gb_style_hash, (GHFunc) add_style_to_clist, clist);
+
+ current_style = gtk_entry_get_text (GTK_ENTRY (value));
+ if (strlen (current_style) == 0)
+ {
+ gtk_clist_select_row (GTK_CLIST (clist), 0, 0);
+ }
+ else
+ {
+ for (i = 1; i < GTK_CLIST (clist)->rows; i++)
+ {
+ gtk_clist_get_text (GTK_CLIST (clist), i, 0, &text);
+ if (!strcmp (current_style, text))
+ {
+ gtk_clist_select_row (GTK_CLIST (clist), i, 0);
+ }
+ }
+ }
+
+ gtk_clist_thaw (GTK_CLIST (clist));
+ gtk_signal_connect (GTK_OBJECT (clist), "select_row",
+ GTK_SIGNAL_FUNC (on_style_clist_select), clist);
+
+ /* Save pointer to value to use when a button is pressed */
+ gtk_object_set_data (GTK_OBJECT (clist), GbValueWidgetKey, value);
+
+ /* Create all the buttons */
+ vbbox = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (vbbox), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (vbbox), 2);
+ gtk_widget_show (vbbox);
+ gtk_box_pack_start (GTK_BOX (hbox), vbbox, FALSE, TRUE, 0);
+
+ button = gtk_button_new_with_label (_("New"));
+ gtk_box_pack_start (GTK_BOX (vbbox), button, FALSE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_dialog_new), clist);
+
+ button = gtk_button_new_with_label (_("Rename"));
+ gtk_box_pack_start (GTK_BOX (vbbox), button, FALSE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_dialog_rename), clist);
+ gtk_object_set_data (GTK_OBJECT (clist), "rename_button", button);
+ gtk_widget_set_sensitive (button, FALSE);
+
+
+ button = gtk_button_new_with_label (_("Delete"));
+ gtk_box_pack_start (GTK_BOX (vbbox), button, FALSE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_dialog_delete), clist);
+ gtk_object_set_data (GTK_OBJECT (clist), "delete_button", button);
+ gtk_widget_set_sensitive (button, FALSE);
+
+ button = gtk_button_new_with_label (_("Copy"));
+ gtk_box_pack_start (GTK_BOX (vbbox), button, FALSE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_dialog_copy), clist);
+ gtk_object_set_data (GTK_OBJECT (clist), "copy_button", button);
+ gtk_widget_set_sensitive (button, FALSE);
+
+ button = gtk_button_new_with_label (_("Cancel"));
+ gtk_box_pack_start (GTK_BOX (vbbox), button, TRUE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_show (button);
+ gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (dialog));
+ gtk_widget_show (GTK_WIDGET (dialog));
+ gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event",
+ GTK_SIGNAL_FUNC (on_key_press),
+ GINT_TO_POINTER (PROP_CLOSE_DESTROYS));
+
+ button = gtk_button_new_with_label (_("OK"));
+ gtk_box_pack_start (GTK_BOX (vbbox), button, FALSE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default (button);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_style_dialog_ok), clist);
+
+}
+
+
+static gint
+add_style_to_clist (const gchar * key, gpointer data, GtkWidget * clist)
+{
+ gint i;
+ gchar *text;
+ const gchar *row[1];
+ row[0] = key;
+
+ /* Leave unnamed style at top */
+ for (i = 1; i < GTK_CLIST (clist)->rows; i++)
+ {
+ gtk_clist_get_text (GTK_CLIST (clist), i, 0, &text);
+ if (strcmp (key, text) < 0)
+ {
+ gtk_clist_insert (GTK_CLIST (clist), i, (gchar**) row);
+ return i;
+ }
+ }
+ return gtk_clist_append (GTK_CLIST (clist), (gchar**) row);
+}
+
+
+static void
+on_style_clist_select (GtkWidget * widget, gint row, gint column,
+ GdkEventButton * bevent, gpointer data)
+{
+ gchar *text = NULL;
+ GtkWidget *copy_button, *rename_button, *delete_button;
+ gboolean copy_sensitive = TRUE;
+ gboolean rename_sensitive = TRUE;
+ gboolean delete_sensitive = TRUE;
+
+ if (bevent && bevent->type == GDK_2BUTTON_PRESS)
+ {
+ on_style_dialog_ok (widget, widget);
+ return;
+ }
+
+ copy_button = gtk_object_get_data (GTK_OBJECT (widget), "copy_button");
+ g_return_if_fail (copy_button != NULL);
+ rename_button = gtk_object_get_data (GTK_OBJECT (widget), "rename_button");
+ g_return_if_fail (rename_button != NULL);
+ delete_button = gtk_object_get_data (GTK_OBJECT (widget), "delete_button");
+ g_return_if_fail (delete_button != NULL);
+
+ /* If unnamed style selected, make copy, rename & delete buttons insensitive,
+ else if default style selected, make rename & delete insensitive. */
+ gtk_clist_get_text (GTK_CLIST (widget), row, 0, &text);
+ /* Added this check since it SEGVed once here. */
+ g_return_if_fail (text != NULL);
+ if (!strcmp (text, GB_STYLE_UNNAMED))
+ {
+ copy_sensitive = FALSE;
+ rename_sensitive = FALSE;
+ delete_sensitive = FALSE;
+ }
+ else if (!strcmp (text, GB_STYLE_DEFAULT))
+ {
+ rename_sensitive = FALSE;
+ delete_sensitive = FALSE;
+ }
+ gtk_widget_set_sensitive (copy_button, copy_sensitive);
+ gtk_widget_set_sensitive (rename_button, rename_sensitive);
+ gtk_widget_set_sensitive (delete_button, delete_sensitive);
+}
+
+
+static void
+on_style_dialog_new (GtkWidget * widget, GtkWidget * clist)
+{
+ GList *selection = GTK_CLIST (clist)->selection;
+ gint row;
+ gchar *text;
+ GladeWidgetData *wdata;
+ GbStyle *base_gbstyle = NULL;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ gtk_clist_get_text (GTK_CLIST (clist), row, 0, &text);
+ if (!strcmp (text, GB_STYLE_UNNAMED))
+ {
+ if (property_widget)
+ {
+ wdata = gtk_object_get_data (GTK_OBJECT (property_widget),
+ GB_WIDGET_DATA_KEY);
+ if (wdata)
+ base_gbstyle = wdata->gbstyle;
+ }
+ }
+ else
+ {
+ base_gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, text);
+ g_return_if_fail (base_gbstyle != NULL);
+ }
+ }
+
+ glade_util_show_entry_dialog (_("New Style:"), NULL, clist,
+ (GbEntryDialogFunc) create_new_style,
+ base_gbstyle);
+}
+
+
+static gint
+create_new_style (GtkWidget * widget, const gchar * name, GbStyle * base_gbstyle)
+{
+ GbStyle *gbstyle, *existing_gbstyle;
+ gint row;
+
+ if (strlen (name) == 0)
+ {
+ glade_util_show_message_box (_("Invalid style name"));
+ return FALSE;
+ }
+
+ /* Make sure name is unique */
+ existing_gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, name);
+ if (existing_gbstyle)
+ {
+ glade_util_show_message_box (_("That style name is already in use"));
+ return FALSE;
+ }
+
+ if (!base_gbstyle)
+ base_gbstyle = gb_widget_default_gb_style;
+ g_return_val_if_fail (base_gbstyle != NULL, TRUE);
+
+ gbstyle = gb_widget_copy_gb_style (base_gbstyle);
+ g_free (gbstyle->name);
+ gbstyle->name = g_strdup (name);
+ g_hash_table_insert (gb_style_hash, gbstyle->name, gbstyle);
+
+ /* Add style to clist */
+ row = add_style_to_clist (name, NULL, widget);
+ gtk_clist_select_row (GTK_CLIST (widget), row, 0);
+
+ return TRUE;
+}
+
+
+static void
+on_style_dialog_copy (GtkWidget * widget, GtkWidget * clist)
+{
+ GladeWidgetData *wdata;
+ gint row, i;
+ GtkWidget *value;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gchar *text;
+ GbStyle *gbstyle, *other_gbstyle;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ value = gtk_object_get_data (GTK_OBJECT (clist), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+
+ gtk_clist_get_text (GTK_CLIST (clist), row, 0, &text);
+ if (!strcmp (text, GB_STYLE_UNNAMED))
+ return;
+ other_gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, text);
+ g_return_if_fail (other_gbstyle != NULL);
+
+ if (property_widget)
+ {
+ wdata = gtk_object_get_data (GTK_OBJECT (property_widget),
+ GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+ gbstyle = wdata->gbstyle;
+
+ /* If widget is using an unnamed GbStyle, just use the selected GbStyle.
+ else copy the selected GbStyle to the current one. */
+ if (wdata->flags & GB_STYLE_IS_UNNAMED)
+ {
+ gb_widget_set_gb_style (widget, other_gbstyle);
+ }
+ else
+ {
+ g_free (gbstyle->xlfd_fontname);
+ gbstyle->xlfd_fontname = g_strdup (other_gbstyle->xlfd_fontname);
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ g_free (gbstyle->bg_pixmap_filenames[i]);
+ gbstyle->bg_pixmap_filenames[i]
+ = g_strdup (other_gbstyle->bg_pixmap_filenames[i]);
+ }
+ gtk_style_unref (gbstyle->style);
+ gbstyle->style = other_gbstyle->style;
+ gtk_style_ref (gbstyle->style);
+ gb_widget_update_gb_styles (gbstyle, gbstyle);
+ }
+
+ editor_refresh_widget (property_widget);
+ property_set_auto_apply (FALSE);
+ gb_widget_show_style (property_widget);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ gtk_widget_destroy (gtk_widget_get_toplevel (clist));
+}
+
+
+static void
+on_style_dialog_rename (GtkWidget * widget, GtkWidget * clist)
+{
+ gint row;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gchar *text;
+ GbStyle *gbstyle;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ gtk_clist_get_text (GTK_CLIST (clist), row, 0, &text);
+ if (!strcmp (text, GB_STYLE_UNNAMED) || (!strcmp (text, GB_STYLE_DEFAULT)))
+ return;
+ gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, text);
+ g_return_if_fail (gbstyle != NULL);
+ glade_util_show_entry_dialog (_("Rename Style To:"), text, clist,
+ (GbEntryDialogFunc) rename_style, gbstyle);
+ }
+}
+
+
+static gint
+rename_style (GtkWidget * clist, const gchar * name, GbStyle * gbstyle)
+{
+ GbStyle *existing_gbstyle;
+ gchar *text, *old_name;
+ gint i, row;
+
+ if (strlen (name) == 0)
+ {
+ glade_util_show_message_box (_("Invalid style name"));
+ return FALSE;
+ }
+
+ /* Make sure name is unique */
+ existing_gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, text);
+ if (existing_gbstyle == gbstyle)
+ return TRUE;
+ if (existing_gbstyle)
+ {
+ glade_util_show_message_box (_("That style name is already in use"));
+ return FALSE;
+ }
+
+ old_name = gbstyle->name;
+ gbstyle->name = g_strdup (name);
+
+ /* Delete old entry in style hash & insert new one */
+ g_hash_table_remove (gb_style_hash, old_name);
+ g_hash_table_insert (gb_style_hash, gbstyle->name, gbstyle);
+
+ /* Update name in clist */
+ for (i = 0; i < GTK_CLIST (clist)->rows; i++)
+ {
+ gtk_clist_get_text (GTK_CLIST (clist), i, 0, &text);
+ if (!strcmp (text, old_name))
+ {
+ gtk_clist_remove (GTK_CLIST (clist), i);
+ break;
+ }
+ }
+ row = add_style_to_clist (name, NULL, clist);
+ gtk_clist_select_row (GTK_CLIST (clist), row, 0);
+
+ g_free (old_name);
+
+ return TRUE;
+}
+
+
+static void
+on_style_dialog_delete (GtkWidget * widget, GtkWidget * clist)
+{
+ gint row;
+ GtkWidget *value;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gchar *text;
+ GbStyle *gbstyle;
+ gboolean reshow = FALSE;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ value = gtk_object_get_data (GTK_OBJECT (clist), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+
+ gtk_clist_get_text (GTK_CLIST (clist), row, 0, &text);
+ if (!strcmp (text, GB_STYLE_UNNAMED) || (!strcmp (text, GB_STYLE_DEFAULT)))
+ return;
+
+ gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, text);
+ g_return_if_fail (gbstyle != NULL);
+
+ gtk_clist_remove (GTK_CLIST (clist), row);
+
+ if (property_widget && property_widget->style == gbstyle->style)
+ {
+ reshow = TRUE;
+ }
+
+ /* Make all widgets which are using the style use the default instead */
+ gb_widget_update_gb_styles (gbstyle, gb_widget_default_gb_style);
+ gb_widget_destroy_gb_style (gbstyle, TRUE);
+
+ if (reshow)
+ {
+ property_set_auto_apply (FALSE);
+ gb_widget_show_style (property_widget);
+ property_set_auto_apply (TRUE);
+ }
+ }
+}
+
+
+static void
+on_style_dialog_ok (GtkWidget * widget, GtkWidget * clist)
+{
+ GladeWidgetData *wdata;
+ gint row;
+ GtkWidget *value;
+ GList *selection = GTK_CLIST (clist)->selection;
+ gchar *text;
+ GbStyle *gbstyle;
+
+ if (selection)
+ {
+ row = GPOINTER_TO_INT (selection->data);
+ value = gtk_object_get_data (GTK_OBJECT (clist), GbValueWidgetKey);
+ g_return_if_fail (value != NULL);
+
+ gtk_clist_get_text (GTK_CLIST (clist), row, 0, &text);
+
+ if (property_widget)
+ {
+ wdata = gtk_object_get_data (GTK_OBJECT (property_widget),
+ GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ /* If <none> is selected, just set the unnamed style flag, so if any
+ changes are made to the style a new GbStyle is created. */
+ if (!strcmp (text, GB_STYLE_UNNAMED))
+ {
+ if (!(wdata->flags & GB_STYLE_IS_UNNAMED))
+ {
+ wdata->flags |= GB_STYLE_IS_UNNAMED;
+ property_set_auto_apply (FALSE);
+ gb_widget_show_style (property_widget);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ else
+ {
+ gbstyle = (GbStyle *) g_hash_table_lookup (gb_style_hash, text);
+ g_return_if_fail (gbstyle != NULL);
+ wdata->flags &= ~GB_STYLE_IS_UNNAMED;
+
+ gb_widget_set_gb_style (property_widget, gbstyle);
+ editor_refresh_widget (property_widget);
+ property_set_auto_apply (FALSE);
+ gb_widget_show_style (property_widget);
+ property_set_auto_apply (TRUE);
+ }
+ }
+ }
+ gtk_widget_destroy (gtk_widget_get_toplevel (clist));
+}
+#endif
+
+
+/* Experimental code. */
+void
+property_redirect_key_press (GdkEventKey *event)
+{
+ GtkWidget *value_widget;
+ GdkEventKey tmp_event;
+ gchar *property_name = NULL;
+
+ if (property_widget == NULL)
+ return;
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (main_notebook), GB_PAGE_WIDGET);
+
+ /* Make sure subclasses are tested first.
+ FIXME: Shouldn't really be using copies of the strings here. */
+ if (GTK_IS_ACCEL_LABEL (property_widget))
+ property_name = "AccelLabel|GtkLabel::label";
+ else if (GTK_IS_LABEL (property_widget))
+ property_name = "GtkLabel::label";
+ else if (GTK_IS_RADIO_BUTTON (property_widget))
+ property_name = "RadioButton|GtkButton::label";
+ else if (GTK_IS_CHECK_BUTTON (property_widget))
+ property_name = "CheckButton|GtkButton::label";
+ else if (GTK_IS_TOGGLE_BUTTON (property_widget))
+ property_name = "ToggleButton|GtkButton::label";
+ else if (GTK_IS_BUTTON (property_widget))
+ property_name = "GtkButton::label";
+
+ if (property_name == NULL)
+ return;
+
+ value_widget = (GtkWidget *) g_hash_table_lookup (gb_property_values,
+ property_name);
+ g_return_if_fail (value_widget != NULL);
+
+ if (GTK_IS_SCROLLED_WINDOW (value_widget))
+ value_widget = GTK_BIN (value_widget)->child;
+
+ if (!GTK_WIDGET_IS_SENSITIVE (value_widget))
+ return;
+
+ /* If this is the first key-press, we delete the current text. */
+ if (!typing_over_widget)
+ {
+ if (GTK_IS_ENTRY (value_widget))
+ {
+ gtk_entry_set_text (GTK_ENTRY (value_widget), "");
+ }
+ else if (GTK_IS_TEXT_VIEW (value_widget))
+ {
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (value_widget));
+ gtk_text_buffer_set_text (buffer, "", 0);
+ }
+ else
+ {
+ g_warning ("Can't redirect key press - property isn't a GtkEntry or GtkTextView");
+ return;
+ }
+
+ typing_over_widget = TRUE;
+ }
+
+ tmp_event = *event;
+ tmp_event.send_event = TRUE;
+
+ gtk_widget_event (value_widget, (GdkEvent *)&tmp_event);
+}
+
+
+gboolean
+property_is_typing_over_widget (void)
+{
+ return typing_over_widget;
+}
+
+
+/*
+ * Callbacks for the buttons to reset the widget width & height.
+ * We set the values to 0, which will result in the widget being resized to
+ * the default width/height. This then results in the property being updated
+ * to show the default size.
+ */
+
+static void
+update_position_property (GtkWidget * widget, gpointer value, gint flag)
+{
+ GladeWidgetData *wdata;
+ gboolean value_set;
+ gint w, h;
+
+ if (property_widget == NULL)
+ return;
+ wdata = gtk_object_get_data (GTK_OBJECT (property_widget),
+ GB_WIDGET_DATA_KEY);
+ g_return_if_fail (wdata != NULL);
+
+ value_set = GTK_TOGGLE_BUTTON (widget)->active ? TRUE : FALSE;
+ gtk_widget_set_sensitive (GTK_WIDGET (value), value_set);
+ if (value_set)
+ wdata->flags |= flag;
+ else
+ wdata->flags &= ~flag;
+
+ /* X & Y flags can only be changed for windows, and we don't need to update
+ those, so we only have to worry about the width & height flags changing.*/
+ if (flag == GLADE_WIDTH_SET || flag == GLADE_HEIGHT_SET)
+ {
+ w = wdata->flags & GLADE_WIDTH_SET ? wdata->width : -1;
+ h = wdata->flags & GLADE_HEIGHT_SET ? wdata->height : -1;
+
+ gb_widget_set_usize (property_widget, w, h);
+ }
+}
+
+
+static void
+on_toggle_set_width (GtkWidget * widget, gpointer value)
+{
+ update_position_property (widget, value, GLADE_WIDTH_SET);
+}
+
+
+static void
+on_toggle_set_height (GtkWidget * widget, gpointer value)
+{
+ update_position_property (widget, value, GLADE_HEIGHT_SET);
+}
diff --git a/tools/glade/glade/property.h b/tools/glade/glade/property.h
new file mode 100644
index 00000000..431c4e78
--- /dev/null
+++ b/tools/glade/glade/property.h
@@ -0,0 +1,424 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_PROPERTY_H
+#define GLADE_PROPERTY_H
+
+#include "gbwidget.h"
+#include "glade_project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Currently the property editor creates the standard widget properties itself.
+ Eventually I want to rewrite it so that all properties are added elsewhere.
+ I also want to change it to use only 2 notebook pages - properties and
+ signals. The styles and accelerators properties will move to dialog boxes.
+ It should also handle setting properties of multiple selected widgets at
+ once - only showing the properies which are common to all the selected
+ widgets. Though this requires supporting an 'unset' value for each type
+ of property, to be used when the properties of the different widgets differ.
+*/
+
+extern GtkWidget *win_property;
+
+/* These are the standard widget property names */
+extern const gchar* GbName;
+extern const gchar* GbClass;
+extern const gchar* GbWidth;
+extern const gchar* GbHeight;
+extern const gchar* GbVisible;
+extern const gchar* GbSensitive;
+extern const gchar* GbTooltip;
+extern const gchar* GbCanDefault;
+extern const gchar* GbHasDefault;
+extern const gchar* GbCanFocus;
+extern const gchar* GbHasFocus;
+extern const gchar* GbEvents;
+extern const gchar* GbExtEvents;
+
+/* Event masks */
+#define GB_EVENT_MASKS_COUNT 19
+extern const gchar* GbEventMaskSymbols [GB_EVENT_MASKS_COUNT];
+extern const gint GbEventMaskValues [GB_EVENT_MASKS_COUNT];
+
+/* X Extension mode choices data, for updating the choice property */
+extern const gchar* GbExtensionModeChoices[];
+extern const gint GbExtensionModeValues[];
+extern const gchar* GbExtensionModeSymbols[];
+
+/* Language-Specific properties. */
+/* C-specific properties. */
+extern const gchar* GbCSourceFile;
+extern const gchar* GbCPublic;
+
+/* C++-specific properties. */
+extern const gchar* GbCxxSeparateFile;
+extern const gchar* GbCxxUseHeap;
+extern const gchar* GbCxxSeparateClass;
+extern const gchar* GbCxxVisibility;
+
+extern const gchar* GbCxxVisibilityChoices[];
+extern const gint GbCxxVisibilityValues[];
+extern const gchar* GbCxxVisibilitySymbols[];
+
+/* Style properties */
+extern const gchar* GbStylePropagate;
+extern const gchar* GbStyleName;
+extern const gchar* GbStyleFont;
+
+/* Signals page */
+extern const gchar* GbSignalName;
+extern const gchar* GbSignalHandler;
+extern const gchar* GbSignalObject;
+extern const gchar* GbSignalAfter;
+extern const gchar* GbSignalData;
+
+/* Accelerators page */
+extern const gchar* GbAccelKey;
+extern const gchar* GbAccelSignal;
+
+
+void property_init (void);
+
+/* Showing/hiding the property editor window. */
+void property_show (GtkWidget *widget,
+ gpointer data);
+gint property_hide (GtkWidget *widget,
+ gpointer data);
+
+/* Getting/setting the widget whose properties are being edited. */
+GtkWidget* property_get_widget (void);
+void property_set_widget (GtkWidget *widget);
+
+/* Updates the window title, i.e. if the widget's name has been changed. */
+void property_update_title (void);
+
+/* Adding property pages specific to a particular widget class. */
+gint property_add_gbwidget_page (GtkWidget *page);
+void property_hide_gbwidget_page (void);
+void property_show_gbwidget_page (gint page);
+
+/* Adding property pages for child packing properties. */
+gint property_add_child_packing_page (GtkWidget *page);
+void property_hide_child_packing_page (void);
+void property_show_child_packing_page (gint page);
+
+/* Shows the properties specific to the project's source language - C, C++ */
+void property_show_lang_specific_page (GladeLanguageType language);
+
+
+/* When adding properties, we first set the table to add the properties to,
+ and the row to start at. The properties can then simply be added using the
+ property_add_int() and similar functions below. The row is automatically
+ incremented as new properties are added. */
+GtkWidget* property_get_table_position (gint *row);
+void property_set_table_position (GtkWidget *table,
+ gint row);
+
+
+/* Note: Unless stated otherwise, values passed to property_set_XXX() will
+ not be changed (and copied if needed), and you should copy values returned
+ from property_get_XXX() calls if you need them (or ref pixmaps/bitmaps). */
+void property_add_string (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+gchar* property_get_string (const gchar *property_name,
+ GtkWidget *actual_widget,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_string (const gchar *property_name,
+ const gchar *value);
+void property_set_translatable_string (const gchar *property_name,
+ const gchar *value,
+ GtkWidget *widget);
+
+void property_add_text (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ gint visible_lines);
+/* Note: string returned from property_get_text must be freed with g_free() */
+gchar* property_get_text (const gchar *property_name,
+ GtkWidget *actual_widget,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_text (const gchar *property_name,
+ const gchar *value);
+void property_set_translatable_text (const gchar *property_name,
+ const gchar *value,
+ GtkWidget *widget);
+
+void property_add_int (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+void property_add_int_range (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ gint min,
+ gint max,
+ gint step_increment,
+ gint page_increment,
+ gint climb_rate);
+void property_add_optional_int_range (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ gint min,
+ gint max,
+ gint step_increment,
+ gint page_increment,
+ gint climb_rate,
+ GtkCallback callback);
+gint property_get_int (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+gint property_get_optional_int (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply,
+ gboolean *is_set);
+void property_set_int (const gchar *property_name,
+ gint value);
+void property_set_optional_int (const gchar *property_name,
+ gint value,
+ gboolean is_set);
+
+void property_add_float (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+void property_add_float_range (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ gfloat min,
+ gfloat max,
+ gfloat step_increment,
+ gfloat page_increment,
+ gfloat climb_rate,
+ gint decimal_digits);
+gfloat property_get_float (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_float (const gchar *property_name,
+ gfloat value);
+
+void property_add_bool (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+gboolean property_get_bool (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+/* property_set_bool() takes an int so we can pass it GTK values which aren't
+ really gbooleans and we can also use results of ANDing bit masks etc. */
+void property_set_bool (const gchar *property_name,
+ gint value);
+
+void property_add_choice (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar **choices);
+gchar* property_get_choice (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_choice (const gchar *property_name,
+ gint value);
+
+void property_add_combo (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ GList *choices);
+gchar* property_get_combo (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_combo (const gchar *property_name,
+ const gchar *value);
+void property_set_combo_strings (const gchar *property_name,
+ GList *choices);
+
+void property_add_color (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+GdkColor* property_get_color (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_color (const gchar *property_name,
+ GdkColor *value);
+
+void property_add_bgpixmap (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+GdkPixmap* property_get_bgpixmap (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply,
+ gchar **filename);
+void property_set_bgpixmap (const gchar *property_name,
+ GdkPixmap *gdkpixmap,
+ const gchar *filename);
+
+/* A dialog property is an Entry with a button on the right of it which, when
+ clicked, calls the callback given in the property_add_dialog() function.
+ This callback should show an appropriate dialog box for editing the
+ property. Then, the dialog should change the text in the Entry.
+ If the property value can't be completely represented using text, the value
+ should be placed in the Entry's object data hash under GbDialogValueKey,
+ (In this case the the Entry should not be editable, as set in
+ property_add_dialog) */
+void property_add_dialog (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ gboolean editable,
+ GtkCallback callback);
+gpointer property_get_dialog (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_dialog (const gchar *property_name,
+ const gchar *string,
+ gconstpointer value);
+
+void property_add_filename (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+void property_add_filename_with_combo (const gchar * property_name,
+ const gchar * label,
+ const gchar * tooltip,
+ GList * choices);
+gchar* property_get_filename (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_filename (const gchar *property_name,
+ const gchar *value);
+
+void property_add_font (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+GdkFont* property_get_font (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply,
+ gchar **xlfd_fontname);
+void property_set_font (const gchar *property_name,
+ GdkFont *font,
+ const gchar *xlfd_fontname);
+
+void property_add_command (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *command,
+ GtkSignalFunc callback);
+
+/* A stock item is a GTK+ stock item that has a label and an icon with the
+ given size. Any stock items that don't have labels or don't have an icon
+ with the given size are not displayed in the popup list.
+ You can change the icon size dynamically, e.g. based on another property.
+ The popup list will be recreated, and if the stock item currently used does
+ not have the given icon size, the stock item will be set to 'None'.
+ Using GLADE_ICON_SIZE_ANY means any icon size is OK. */
+#define GLADE_ICON_SIZE_ANY 255
+
+void property_add_stock_item (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ GtkIconSize icon_size);
+gchar* property_get_stock_item (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_stock_item (const gchar *property_name,
+ const gchar *stock_id);
+void property_set_stock_item_icon_size (const gchar *property_name,
+ GtkIconSize icon_size);
+
+
+/* An icon is a GTK+ stock icon with the given icon size, or a user-specified
+ icon. It will show a GtkCombo, with a '...' button beside it for opening
+ a file selection dialog, so the user can specify an icon file.
+ As with stock item, you can change the icon size dynamically, and the popup
+ list of stock icons will be recreated. The file selection can be shown or
+ hidden with property_set_icon_filesel(). */
+void property_add_icon (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip,
+ GtkIconSize icon_size);
+gchar* property_get_icon (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_icon (const gchar *property_name,
+ const gchar *icon);
+void property_set_icon_size (const gchar *property_name,
+ GtkIconSize icon_size);
+void property_set_icon_filesel (const gchar *property_name,
+ gboolean filesel);
+
+void property_add_named_icon (const gchar *property_name,
+ const gchar *label,
+ const gchar *tooltip);
+gchar* property_get_named_icon (const gchar *property_name,
+ GtkWidget *to_apply,
+ gboolean *apply);
+void property_set_named_icon (const gchar *property_name,
+ const gchar *icon_name);
+
+
+#define GB_ADJUST_DEFAULT_LABELS 1
+#define GB_ADJUST_H_LABELS 2
+#define GB_ADJUST_V_LABELS 3
+void property_add_adjustment (const gchar *Values[],
+ gint label_type);
+
+/* Returns the widget used for displaying a property value. */
+GtkWidget* property_get_value_widget (const gchar *property_name);
+
+void property_set_sensitive (const gchar *property_name,
+ gboolean sensitive);
+void property_set_sensitive_full (const gchar *property_name,
+ gboolean label_sensitive,
+ gboolean value_sensitive,
+ gboolean button_visible);
+void property_set_visible (const gchar *property_name,
+ gboolean visible);
+
+/* This isn't currently used. It changes the style so that text is shown in
+ red to indicate an invalid property value. */
+void property_set_valid (const gchar *property_name,
+ gboolean valid);
+
+gchar* property_events_value_to_string (gint event_mask);
+gint property_events_string_to_value (const gchar *event_string);
+
+/* Turn on/off auto-apply which applies changes as they are made in the
+ property editor. You may need to turn this off if you are updating
+ properties, otherwise the properties will be applied again. */
+void property_set_auto_apply (gboolean value);
+
+
+void property_clear_accelerators (void);
+void property_add_accelerator (GladeAccelerator *accel);
+gboolean property_is_accel_clist (GtkWidget *widget);
+GList* property_get_accelerators (void);
+
+void property_clear_signals (void);
+void property_add_signal (GladeSignal *signal);
+gboolean property_is_signal_clist (GtkWidget *widget);
+GList* property_get_signals (void);
+
+
+/* This is to allow a widget's label to be typed in while the mouse hovers
+ over the widget. I'm not sure how well this will work yet. */
+void property_redirect_key_press (GdkEventKey *event);
+gboolean property_is_typing_over_widget (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_PROPERTY_H */
diff --git a/tools/glade/glade/save.c b/tools/glade/glade/save.c
new file mode 100644
index 00000000..ea9f8eee
--- /dev/null
+++ b/tools/glade/glade/save.c
@@ -0,0 +1,1039 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <errno.h>
+#include <locale.h>
+
+#include "glade_project.h"
+#include "gbwidget.h"
+#include "save.h"
+#include "utils.h"
+
+/* This is set if we are saving a session. A bit of a hack. */
+char *GladeSessionFile = NULL;
+
+
+/* The stuff to output at the start of XML files. */
+static gchar *GLADE_XML_BEGIN =
+ "<?xml version=\"1.0\" standalone=\"no\"?> <!--*- mode: xml -*-->\n"
+ "<!DOCTYPE glade-interface SYSTEM \"http://glade.gnome.org/glade-2.0.dtd\">\n\n";
+
+static gchar *GLADE_PROJECT_XML_BEGIN =
+ "<?xml version=\"1.0\" standalone=\"no\"?> <!--*- mode: xml -*-->\n"
+ "<!DOCTYPE glade-project SYSTEM \"http://glade.gnome.org/glade-project-2.0.dtd\">\n\n";
+
+
+/* An internal struct to pass data to the save_component() and
+ save_named_style_callback() callbacks. */
+typedef struct _GladeSaveCallbackData GladeSaveCallbackData;
+struct _GladeSaveCallbackData
+{
+ GbWidgetGetArgData *data;
+ FILE *fp;
+};
+
+/* An internal struct to pass data to the save_requires_tags_cb(). */
+typedef struct _GladeSaveRequiresData GladeSaveRequiresData;
+struct _GladeSaveRequiresData
+{
+ /* We only support these 4 libs so we just have flags for each of them. */
+ gboolean require_gnome;
+ gboolean require_gnome_canvas;
+ gboolean require_gnomedb;
+ gboolean require_bonobo;
+};
+
+
+static GladeError* save_project_file_internal (GladeProject *project);
+static GladeError* save_xml_file_internal (GladeProject *project);
+
+static void save_requires_tags (FILE *fp, GladeProject *project);
+static void save_component (GtkWidget * item,
+ GladeSaveCallbackData * save_data);
+
+#ifdef GLADE_STYLE_SUPPORT
+static void save_named_style_callback (const gchar * name,
+ GbStyle * gbstyle,
+ GladeSaveCallbackData * save_data);
+static void save_named_style (const gchar * name,
+ GbStyle * gbstyle,
+ GbWidgetGetArgData * data,
+ FILE *fp);
+#endif
+
+static void save_buffer_flush (GbWidgetGetArgData * data,
+ FILE *fp);
+
+static void save_translatable_strings (GbWidgetGetArgData * data);
+
+
+/* We need this to make sure that numbers are output in a portable syntax,
+ instead of using the current locale. This code is from glibc info docs. */
+GladeError*
+save_project_file (GladeProject *project)
+{
+ gchar *old_locale, *saved_locale;
+ GladeError *error;
+
+ old_locale = setlocale (LC_NUMERIC, NULL);
+ saved_locale = g_strdup (old_locale);
+ setlocale (LC_NUMERIC, "C");
+
+ error = save_project_file_internal (project);
+
+ if (!error)
+ error = save_xml_file_internal (project);
+
+ setlocale (LC_NUMERIC, saved_locale);
+ g_free (saved_locale);
+ return error;
+}
+
+
+/* Backup the file, to <filename>.bak, if it exists. */
+static GladeError*
+backup_file (const gchar *filename)
+{
+ gchar *backup_filename;
+ GladeError *error = NULL;
+ int status;
+
+ if (!glade_util_file_exists (filename))
+ return NULL;
+
+ backup_filename = g_strdup_printf ("%s.bak", filename);
+#if defined (__EMX__) || defined (_WIN32)
+ /* for OS/2 rename dosn't work if the dest. file exist ! remove it! */
+ status = remove (backup_filename);
+#endif
+ status = rename (filename, backup_filename);
+
+ if (status == -1)
+ {
+ error = glade_error_new_system (_("Couldn't rename file:\n %s\nto:\n %s\n"), filename, backup_filename);
+ }
+
+ g_free (backup_filename);
+ return error;
+}
+
+
+/* The main function to output the XML. It creates and initializes the
+ GbWidgetGetArgData, opens the file, outputs the project options, the
+ named styles, and then each component (window/dialog) in the interface. */
+static GladeError*
+save_project_file_internal (GladeProject *project)
+{
+ gchar *xml_filename, *filename;
+ GladeError *error;
+ FILE *fp;
+
+ if (GladeSessionFile)
+ xml_filename = GladeSessionFile;
+ else
+ xml_filename = glade_project_get_xml_filename (project);
+
+ filename = g_strdup_printf ("%sp", xml_filename);
+
+ if (!GladeSessionFile)
+ {
+ error = backup_file (filename);
+ if (error)
+ goto out;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ goto out;
+ }
+
+ fprintf (fp, "%s", GLADE_PROJECT_XML_BEGIN);
+
+ error = glade_project_save_options (project, fp);
+
+ fclose (fp);
+
+ out:
+
+ g_free (filename);
+
+ return error;
+}
+
+
+/* The main function to output the XML. It creates and initializes the
+ GbWidgetGetArgData, opens the file, outputs the project options, the
+ named styles, and then each component (window/dialog) in the interface. */
+static GladeError*
+save_xml_file_internal (GladeProject *project)
+{
+ GbWidgetGetArgData data = { 0 };
+ GladeSaveCallbackData save_data;
+ gchar *filename;
+ FILE *fp;
+
+ MSG ("Saving project");
+
+ data.project = project;
+ data.action = GB_SAVING;
+ data.copying_to_clipboard = FALSE;
+ data.error = NULL;
+
+ if (GladeSessionFile)
+ filename = GladeSessionFile;
+ else
+ filename = glade_project_get_xml_filename (project);
+
+ if (!GladeSessionFile)
+ {
+ data.error = backup_file (filename);
+ if (data.error)
+ return data.error;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ return glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+
+ /* Initialize the output buffer. */
+ data.buffer = g_string_sized_new (1024);
+ data.indent = 0;
+
+ /* See if we need the translatable strings file output. */
+ data.save_translatable_strings = FALSE;
+ data.translatable_strings = NULL;
+ if (!GladeSessionFile)
+ {
+ data.save_translatable_strings = glade_project_get_output_translatable_strings (data.project);
+ if (data.save_translatable_strings)
+ data.translatable_strings = g_string_sized_new (1024);
+ }
+
+ /* Output the XML version info and our root element '<glade-interface>'. */
+ fprintf (fp, "%s", GLADE_XML_BEGIN);
+ fprintf (fp, "<glade-interface>\n");
+
+ /* Output the requires tags. */
+ save_requires_tags (fp, project);
+
+ /* Set up the struct to pass data to the callbacks. */
+ save_data.data = &data;
+ save_data.fp = fp;
+
+#ifdef GLADE_STYLE_SUPPORT
+ if (!data.error)
+ {
+ /* Save default gbstyle first. */
+ MSG ("Saving styles");
+ save_named_style (gb_widget_default_gb_style->name,
+ gb_widget_default_gb_style, &data, fp);
+ /* Now save all the other named styles. */
+ g_hash_table_foreach (gb_style_hash, (GHFunc) save_named_style_callback,
+ &save_data);
+ }
+#endif
+
+ if (!data.error)
+ {
+ MSG ("Saving components");
+ glade_project_foreach_component (data.project,
+ (GtkCallback) save_component,
+ &save_data);
+ }
+
+ /* Finish the root element. */
+ if (!data.error)
+ {
+ fprintf (fp, "\n</glade-interface>\n");
+ }
+
+ /* Save the translatable strings file, if needed. */
+ if (!data.error)
+ {
+ if (data.save_translatable_strings)
+ save_translatable_strings (&data);
+ }
+
+ /* Free any memory used while saving. */
+ g_string_free (data.buffer, TRUE);
+ if (data.translatable_strings)
+ g_string_free (data.translatable_strings, TRUE);
+
+ fclose (fp);
+
+ return data.error;
+}
+
+
+static void
+save_requires_tags_cb (GtkWidget *widget,
+ GladeSaveRequiresData * requires_data)
+{
+ const char *type_name;
+
+ type_name = g_type_name (G_OBJECT_TYPE (widget));
+
+ /* We assume that any classes starting with GnomeDB require the GnomeDB
+ support etc. Note that GNOME apps will probably require Bonobo for the
+ BonoboDock widgets used in GnomeApp. */
+ if (!strncmp (type_name, "GnomeDb", 7))
+ requires_data->require_gnomedb = TRUE;
+ else if (!strncmp (type_name, "GnomeCanvas", 11))
+ requires_data->require_gnome_canvas = TRUE;
+ else if (!strncmp (type_name, "Gnome", 5))
+ requires_data->require_gnome = TRUE;
+ else if (!strncmp (type_name, "Bonobo", 6))
+ requires_data->require_bonobo = TRUE;
+
+ /* Recursively check all children. */
+ gb_widget_children_foreach (widget, (GtkCallback) save_requires_tags_cb,
+ requires_data);
+}
+
+static void
+save_requires_tags (FILE *fp, GladeProject *project)
+{
+ GladeSaveRequiresData requires_data;
+
+ /* Assume we don't need any of them until we find one of their widgets. */
+ requires_data.require_gnome = FALSE;
+ requires_data.require_gnome_canvas = FALSE;
+ requires_data.require_gnomedb = FALSE;
+ requires_data.require_bonobo = FALSE;
+
+ glade_project_foreach_component (project,
+ (GtkCallback) save_requires_tags_cb,
+ &requires_data);
+
+ /* Require "gnome", as provided in libgnomeui/glade/glade-gnome.c.
+ We now require GNOME for all GNOME projects, since even if they don't
+ contain GNOME widgets they may use stock GNOME items. */
+ if (requires_data.require_gnome
+ || glade_project_get_gnome_support (project))
+ fprintf (fp, "<requires lib=\"gnome\"/>\n");
+ /* Require "canvas", as provided in libgnomecanvas/glade/glade-canvas.c. */
+ if (requires_data.require_gnome_canvas)
+ fprintf (fp, "<requires lib=\"canvas\"/>\n");
+ /* Require "gnomedb", as provided in libgnomedb/glade/glade-gnomedb.c. */
+ if (requires_data.require_gnomedb)
+ fprintf (fp, "<requires lib=\"gnomedb\"/>\n");
+ /* Require "bonobo", as provided in libbonoboui/glade/glade-bonobo.c. */
+ if (requires_data.require_bonobo)
+ fprintf (fp, "<requires lib=\"bonobo\"/>\n");
+}
+
+/* This is called when iterating over the components in a project, to output
+ each component. It simply calls gb_widget_save() to recursively save the
+ XML for the component into the buffer, and it then flushes the buffer to
+ the output file. */
+static void
+save_component (GtkWidget * component,
+ GladeSaveCallbackData * save_data)
+{
+ /* If an error has occurred, we return. */
+ if (save_data->data->error)
+ return;
+
+ gb_widget_save (component, save_data->data);
+ save_buffer_flush (save_data->data, save_data->fp);
+}
+
+
+/* This is called when iterating over the GHashTable of named styles.
+ If the style isn't the default style it is output here. The default
+ style is output first, since for all other styles we only output the
+ differences from the default. */
+#ifdef GLADE_STYLE_SUPPORT
+static void
+save_named_style_callback (const gchar * name,
+ GbStyle * gbstyle,
+ GladeSaveCallbackData * save_data)
+{
+ /* If an error has occurred, or this is the default GbStyle, we return. */
+ if (save_data->data->error || gbstyle == gb_widget_default_gb_style)
+ {
+ return;
+ }
+
+ save_named_style (name, gbstyle, save_data->data, save_data->fp);
+}
+
+
+/* Outputs a named style. */
+static void
+save_named_style (const gchar * name,
+ GbStyle * gbstyle,
+ GbWidgetGetArgData * data,
+ FILE *fp)
+{
+ gboolean save_all = FALSE;
+
+ MSG1 ("Saving style: %s", name);
+ /* If this is the default style, only save it if it is different to the
+ GTK default style, and if it is make sure we save everything. */
+ if (gbstyle == gb_widget_default_gb_style)
+ {
+ if (gbstyle->style == gtk_widget_get_default_style ())
+ return;
+ else
+ save_all = TRUE;
+ }
+ gb_widget_save_style (gbstyle, data, save_all);
+ save_buffer_flush (data, fp);
+}
+#endif
+
+
+/* Adds a start tag, e.g. "<widget>", to the output buffer. */
+void
+save_start_tag (GbWidgetGetArgData * data, const gchar * tag_name)
+{
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append_c (data->buffer, '<');
+ g_string_append (data->buffer, tag_name);
+ g_string_append (data->buffer, ">\n");
+ data->indent++;
+}
+
+
+/* Adds an end tag, e.g. "</widget>", to the output buffer. */
+void
+save_end_tag (GbWidgetGetArgData * data, const gchar * tag_name)
+{
+ data->indent--;
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append (data->buffer, "</");
+ g_string_append (data->buffer, tag_name);
+ g_string_append (data->buffer, ">\n");
+}
+
+
+/* Adds a <widget> start tag to the output buffer, with the given class_name
+ and id, if they are not NULL. */
+void
+save_widget_start_tag (GbWidgetGetArgData * data, const gchar * class_name,
+ const gchar *id)
+{
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append (data->buffer, "<widget");
+
+ if (class_name)
+ {
+ g_string_append (data->buffer, " class=\"");
+ save_buffer_add_string (data->buffer, class_name);
+ g_string_append_c (data->buffer, '"');
+ }
+
+ if (id)
+ {
+ g_string_append (data->buffer, " id=\"");
+ save_buffer_add_string (data->buffer, id);
+ g_string_append_c (data->buffer, '"');
+ }
+
+ g_string_append (data->buffer, ">\n");
+ data->indent++;
+}
+
+
+/* Adds a <child> start tag to the output buffer, with the given child_name
+ if it is not NULL. */
+void
+save_child_start_tag (GbWidgetGetArgData * data, const gchar * child_name)
+{
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append (data->buffer, "<child");
+
+ if (child_name)
+ {
+ g_string_append (data->buffer, " internal-child=\"");
+ save_buffer_add_string (data->buffer, child_name);
+ g_string_append_c (data->buffer, '"');
+ }
+
+ g_string_append (data->buffer, ">\n");
+ data->indent++;
+}
+
+
+/* Adds a <placeholder/> tag to the output buffer. */
+void
+save_placeholder (GbWidgetGetArgData * data)
+{
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append (data->buffer, "<placeholder/>\n");
+}
+
+
+/* Starts a new line in the output buffer (without indenting). */
+void
+save_newline (GbWidgetGetArgData * data)
+{
+ g_string_append_c (data->buffer, '\n');
+}
+
+
+/* These functions are called to save different types of widget properties.
+ They all convert the property to a string representation and call
+ save_string() to output it. The tag_name is usually the long name of the
+ property, e.g. "GtkLabel::justify", so we cut out the first part and output
+ <justify>...</justify>. */
+
+static void
+save_string_internal (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value,
+ gboolean translatable,
+ const gchar *translator_comments,
+ gboolean has_context_prefix)
+{
+ gchar *tag_name_start;
+
+ if (tag_value == NULL)
+ return;
+
+ tag_name_start = glade_util_find_start_of_tag_name (tag_name);
+ save_buffer_add_indent (data->buffer, data->indent);
+
+ g_string_append (data->buffer, "<property");
+
+ if (data->agent)
+ {
+ g_string_append (data->buffer, " agent=\"");
+ save_buffer_add_string (data->buffer, data->agent);
+ g_string_append_c (data->buffer, '"');
+ }
+
+ g_string_append (data->buffer, " name=\"");
+ save_buffer_add_string (data->buffer, tag_name_start);
+ g_string_append_c (data->buffer, '"');
+
+ if (translatable)
+ {
+ g_string_append (data->buffer, " translatable=\"yes\"");
+
+ if (has_context_prefix)
+ g_string_append (data->buffer, " context=\"yes\"");
+
+ if (translator_comments && *translator_comments)
+ {
+ g_string_append (data->buffer, " comments=\"");
+ save_buffer_add_string (data->buffer, translator_comments);
+ g_string_append_c (data->buffer, '"');
+ }
+ }
+
+ g_string_append_c (data->buffer, '>');
+ save_buffer_add_string (data->buffer, tag_value);
+ g_string_append (data->buffer, "</property>\n");
+}
+
+void
+save_string (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string_internal (data, tag_name, tag_value, FALSE, NULL, FALSE);
+}
+
+
+void
+save_translatable_string_internal (GbWidgetGetArgData * data,
+ const gchar * tag_name,
+ const gchar * tag_value)
+{
+ gboolean translatable, context;
+ gchar *comments;
+
+ glade_util_get_translation_properties (data->widget, tag_name, &translatable,
+ &comments, &context);
+ save_string_internal (data, tag_name, tag_value, translatable,
+ comments, context);
+}
+
+
+void
+save_translatable_string (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_translatable_string_internal (data, tag_name, tag_value);
+ if (data->save_translatable_strings)
+ save_add_translatable_string (data, tag_value);
+}
+
+
+void
+save_text (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+void
+save_translatable_text (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_translatable_string (data, tag_name, tag_value);
+}
+
+
+/* This is like save_translatable_text() except it splits the text into lines
+ when adding to the translatable strings file. This is used for option menu
+ items and combo items. */
+void
+save_translatable_text_in_lines (GbWidgetGetArgData * data,
+ const gchar * tag_name,
+ const gchar * tag_value)
+{
+ /* FIXME: This probably won't work if other apps just try to translate the
+ entire string. */
+ save_translatable_string_internal (data, tag_name, tag_value);
+
+ if (data->save_translatable_strings && tag_value)
+ {
+ gchar *items, *pos, *items_end;
+
+ items = pos = g_strdup (tag_value);
+ items_end = &items[strlen (items)];
+
+ while (pos < items_end)
+ {
+ gchar *item_end = strchr (pos, '\n');
+ if (item_end == NULL)
+ item_end = items_end;
+ *item_end = '\0';
+
+ save_add_translatable_string (data, pos);
+
+ pos = item_end + 1;
+ }
+
+ g_free (items);
+ }
+}
+
+
+void
+save_int (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gint tag_value)
+{
+ gchar buf[32];
+ sprintf (buf, "%i", tag_value);
+ save_string (data, tag_name, buf);
+}
+
+
+void
+save_float (GbWidgetGetArgData * data, const gchar * tag_name,
+ gfloat tag_value)
+{
+ gchar buf[32];
+ sprintf (buf, "%.12g", tag_value);
+ save_string (data, tag_name, buf);
+}
+
+
+void
+save_bool (GbWidgetGetArgData * data, const gchar * tag_name, gint tag_value)
+{
+ save_string (data, tag_name, tag_value ? "True" : "False");
+}
+
+
+void
+save_choice (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+void
+save_combo (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+/* Colors are now saved as '#rrrrggggbbbb', where rgb are 0-65535.
+ We use gdk_color_parse() when loading, so color names can be used as well.*/
+void
+save_color (GbWidgetGetArgData * data, const gchar * tag_name,
+ GdkColor * tag_value)
+{
+ gchar buf[32];
+
+ sprintf (buf, "#%04x%04x%04x", tag_value->red, tag_value->green,
+ tag_value->blue);
+ save_string (data, tag_name, buf);
+}
+
+
+void
+save_bgpixmap (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+void
+save_dialog (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+/* FIXME: I think this is broken. It should save it relative to the XML file.*/
+void
+save_filename (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+void
+save_pixmap_filename (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ if (data->copying_to_clipboard)
+ {
+ /* When saving to the clipboard, we just save the full path.
+ This means it will still work if we paste into other projects. */
+ save_string (data, tag_name, tag_value);
+ }
+ else
+ {
+ /* When saving the XML file, we save only the basename of the pixmap
+ files, since they should all be in the pixmaps directory. */
+ gchar *pixmaps_dir, *filename;
+
+ pixmaps_dir = glade_project_get_pixmaps_directory (data->project);
+ g_return_if_fail (pixmaps_dir != NULL);
+ g_return_if_fail (pixmaps_dir[0] != '\0');
+
+ if (tag_value == NULL || tag_value[0] == '\0')
+ {
+ filename = NULL;
+ }
+ else
+ {
+ filename = (gchar*) g_basename (tag_value);
+ }
+
+ save_string (data, tag_name, filename);
+ }
+}
+
+
+void
+save_font (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ save_string (data, tag_name, tag_value);
+}
+
+
+/* This saves a date in the RFC1123 format (an update of RFC822),
+ e.g. 'Sun, 06 Nov 1994 08:49:37 GMT'. */
+static void
+format_date (char *buffer,
+ time_t tag_value)
+{
+ time_t time;
+ struct tm *t;
+
+ time = tag_value;
+ t = gmtime (&time);
+ sprintf (buffer, "%s, %02d %s %04d %02d:%02d:%02d GMT",
+ GladeDayNames[t->tm_wday], t->tm_mday, GladeMonthNames[t->tm_mon],
+ t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec);
+}
+
+
+/* This saves a date in the RFC1123 format (an update of RFC822),
+ e.g. 'Sun, 06 Nov 1994 08:49:37 GMT'. */
+void
+save_date (GbWidgetGetArgData * data, const gchar * tag_name,
+ time_t tag_value)
+{
+ gchar buffer[32];
+
+ format_date (buffer, tag_value);
+ save_string (data, tag_name, buffer);
+}
+
+
+void
+save_icon (GbWidgetGetArgData * data, const gchar * tag_name,
+ const gchar * tag_value)
+{
+ /* If it is a stock icon we can save it as an oridnary string.
+ If it isn't, we need to save it as a pixmap filename, i.e. get rid of
+ the path and just save the basename. */
+ if (glade_util_check_is_stock_id (tag_value))
+ save_string (data, tag_name, tag_value);
+ else
+ save_pixmap_filename (data, tag_name, tag_value);
+}
+
+
+/* Adds a string to the output buffer, converting special characters to
+ entities, e.g. "<" is output as "&lt;". */
+void
+save_buffer_add_string (GString * buffer, const gchar * string)
+{
+ gchar ch;
+
+ while ((ch = *string++))
+ {
+ if (ch == '<')
+ g_string_append (buffer, "&lt;");
+ else if (ch == '>')
+ g_string_append (buffer, "&gt;");
+ else if (ch == '&')
+ g_string_append (buffer, "&amp;");
+ else if (ch == '"')
+ g_string_append (buffer, "&quot;");
+ else
+ g_string_append_c (buffer, ch);
+ }
+}
+
+
+/* Outputs the contents of the buffer to the file and resets the buffer. */
+static void
+save_buffer_flush (GbWidgetGetArgData * data,
+ FILE *fp)
+{
+ gint bytes_written;
+
+ bytes_written = fwrite (data->buffer->str, sizeof (gchar), data->buffer->len,
+ fp);
+ if (bytes_written != data->buffer->len)
+ {
+ MSG2 ("Bytes: %i Written: %i", data->buffer->len, bytes_written);
+ data->error = glade_error_new_system (_("Error writing XML file\n"));
+ }
+
+ /* Reset the output buffer. */
+ g_string_truncate (data->buffer, 0);
+ data->indent = 0;
+}
+
+
+/* Outputs tabs & spaces to indent the line according to the current
+ indentation level. Tabs are used to cut down on the file size a bit. */
+void
+save_buffer_add_indent (GString *buffer, gint indent)
+{
+ gint i, ntabs, nspaces;
+
+ ntabs = (indent * 2) / 8;
+ nspaces = (indent * 2) % 8;
+
+ for (i = 0; i < ntabs; i++)
+ g_string_append_c (buffer, '\t');
+
+ for (i = 0; i < nspaces; i++)
+ g_string_append_c (buffer, ' ');
+}
+
+
+/*
+ * Translatable string functions.
+ */
+
+/* This adds a translatable string to the buffer, wrapping it in the N_()
+ macro so xgettext can find it. */
+void
+save_add_translatable_string (GbWidgetGetArgData * data,
+ const gchar * string)
+{
+ GString *buffer;
+ gchar escape_buffer[16];
+ const gchar *p;
+
+ /* If it is an empty string don't bother outputting it. */
+ if (!string || string[0] == '\0')
+ return;
+
+ buffer = data->translatable_strings;
+ g_string_append (buffer, "gchar *s = N_(\"");
+
+ /* Step through each character of the given string, adding it to our GString
+ buffer, converting it so that it is valid in a literal C string. */
+ for (p = string; *p; p++)
+ {
+ switch (*p)
+ {
+ case '\n':
+ g_string_append (buffer, "\\n\"\n \"");
+ break;
+ case '\r':
+ g_string_append (buffer, "\\r");
+ break;
+ case '\t':
+ g_string_append (buffer, "\\t");
+ break;
+ case '\\':
+ g_string_append (buffer, "\\\\");
+ break;
+ case '"':
+ g_string_append (buffer, "\\\"");
+ break;
+ default:
+ if (isprint ((unsigned char) *p))
+ {
+ g_string_append_c (buffer, *p);
+ }
+ else
+ {
+ sprintf (escape_buffer, "\\%02o", (guchar) *p);
+ g_string_append (buffer, escape_buffer);
+ }
+ break;
+ }
+ }
+
+ g_string_append (buffer, "\");\n");
+}
+
+
+/* This outputs the file containing all the translatable strings. */
+static void
+save_translatable_strings (GbWidgetGetArgData * data)
+{
+ gchar *filename;
+ FILE *fp;
+
+ filename = glade_project_get_translatable_strings_file (data->project);
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ return;
+ }
+
+ fprintf (fp,
+ _("/*\n"
+ " * Translatable strings file generated by Glade.\n"
+ " * Add this file to your project's POTFILES.in.\n"
+ " * DO NOT compile it as part of your application.\n"
+ " */\n"
+ "\n"));
+
+ fprintf (fp, "%s", data->translatable_strings->str);
+
+ fclose (fp);
+}
+
+
+void
+save_signal (GbWidgetGetArgData *data,
+ gchar *signal_name,
+ gchar *handler,
+ gboolean after,
+ gchar *object,
+ time_t last_modification_time)
+{
+ /* Don't save signals without names or handlers. */
+ if (!signal_name || !signal_name[0] || ! handler || !handler[0])
+ return;
+
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append (data->buffer, "<signal name=\"");
+ save_buffer_add_string (data->buffer, signal_name);
+ g_string_append (data->buffer, "\" handler=\"");
+ save_buffer_add_string (data->buffer, handler);
+ g_string_append (data->buffer, "\"");
+
+ if (after)
+ g_string_append (data->buffer, " after=\"yes\"");
+
+ if (object)
+ {
+ g_string_append (data->buffer, " object=\"");
+ save_buffer_add_string (data->buffer, object);
+ g_string_append (data->buffer, "\"");
+ }
+
+ if (last_modification_time != 0)
+ {
+ gchar buffer[32];
+
+ format_date (buffer, last_modification_time);
+
+ g_string_append (data->buffer, " last_modification_time=\"");
+ save_buffer_add_string (data->buffer, buffer);
+ g_string_append (data->buffer, "\"");
+ }
+
+ g_string_append (data->buffer, "/>\n");
+}
+
+
+void
+save_accelerator (GbWidgetGetArgData *data,
+ guint8 modifiers,
+ gchar *key,
+ gchar *signal)
+{
+ gchar *modifiers_string;
+
+ /* Don't save accelerators without signals or keys. */
+ if (!key || !key[0] || !signal || !signal[0])
+ return;
+
+ save_buffer_add_indent (data->buffer, data->indent);
+ g_string_append (data->buffer, "<accelerator key=\"");
+ save_buffer_add_string (data->buffer, key);
+ g_string_append (data->buffer, "\"");
+
+ modifiers_string = glade_util_create_modifiers_string (modifiers);
+ g_string_append (data->buffer, " modifiers=\"");
+ save_buffer_add_string (data->buffer, modifiers_string);
+ g_string_append (data->buffer, "\"");
+
+ g_string_append (data->buffer, " signal=\"");
+ save_buffer_add_string (data->buffer, signal);
+ g_string_append (data->buffer, "\"");
+
+ g_string_append (data->buffer, "/>\n");
+}
+
+
diff --git a/tools/glade/glade/save.h b/tools/glade/glade/save.h
new file mode 100644
index 00000000..fd347b59
--- /dev/null
+++ b/tools/glade/glade/save.h
@@ -0,0 +1,156 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_SAVE_H
+#define GLADE_SAVE_H
+
+#include <time.h>
+
+#include "gbwidget.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* This is set if we are saving a session. A bit of a hack. */
+extern char *GladeSessionFile;
+
+
+/* This is the main function called by glade_project_save() to save the XML. */
+GladeError* save_project_file (GladeProject *project);
+
+
+/* Adds a start tag with no attributes, e.g. "<packing>", to begin a new
+ section. It is placed on its own line, and the indentation level is
+ incremented. The tag_name parameter should not include the '<' and '>'. */
+void save_start_tag (GbWidgetGetArgData *data,
+ const gchar *tag_name);
+
+/* These are for the <widget> and <child> start tags. */
+void save_widget_start_tag (GbWidgetGetArgData *data,
+ const gchar *class_name,
+ const gchar *id);
+void save_child_start_tag (GbWidgetGetArgData *data,
+ const gchar *child_name);
+
+/* Adds an end tag, e.g. "</widget>", to end a section.
+ It is placed on its own line, after decrementing the indentation level.
+ The tag_name parameter should not include the '</' and '>'. */
+void save_end_tag (GbWidgetGetArgData *data,
+ const gchar *tag_name);
+
+/* Adds a <placeholder/> tag to the output buffer. */
+void save_placeholder (GbWidgetGetArgData *data);
+
+/* Starts a new line in the output buffer (without indenting). */
+void save_newline (GbWidgetGetArgData *data);
+
+/* Adds a translatable string to be output in the translatable strings file. */
+void save_add_translatable_string(GbWidgetGetArgData *data,
+ const gchar *string);
+
+
+/* These functions are called to save different types of widget properties.
+ They all convert the property to a string representation and call
+ save_string() to output it. The tag_name is usually the long name of the
+ property, e.g. "GtkLabel::justify", so we cut out the first part and output
+ <justify>...</justify>. */
+
+void save_string (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_translatable_string (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_text (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_translatable_text (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+ void save_translatable_text_in_lines (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_int (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ gint tag_value);
+void save_float (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ gfloat tag_value);
+void save_bool (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ gint tag_value);
+void save_choice (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_combo (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_color (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ GdkColor *tag_value);
+void save_bgpixmap (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_dialog (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_filename (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_pixmap_filename (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_font (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+void save_date (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ time_t tag_value);
+void save_icon (GbWidgetGetArgData *data,
+ const gchar *tag_name,
+ const gchar *tag_value);
+
+
+void save_signal (GbWidgetGetArgData *data,
+ gchar *signal_name,
+ gchar *handler,
+ gboolean after,
+ gchar *object,
+ time_t last_modification_time);
+void save_accelerator (GbWidgetGetArgData *data,
+ guint8 modifiers,
+ gchar *key,
+ gchar *signal);
+
+/* Outputs tabs & spaces to indent the line according to the current
+ indentation level. Tabs are used to cut down on the file size a bit. */
+void save_buffer_add_indent (GString *buffer,
+ gint indent);
+
+/* Adds the string to the buffer, converting special XML characters like '<'
+ to entities like '%lt;'. */
+void save_buffer_add_string (GString *buffer,
+ const gchar *string);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_SAVE_H */
diff --git a/tools/glade/glade/source.c b/tools/glade/glade/source.c
new file mode 100644
index 00000000..af2a05c4
--- /dev/null
+++ b/tools/glade/glade/source.c
@@ -0,0 +1,2818 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <ctype.h>
+#include <locale.h>
+
+#include <gtk/gtkmenu.h>
+
+#include "gladeconfig.h"
+
+#include "gbwidget.h"
+#include "glade_project.h"
+#include "source.h"
+#include "utils.h"
+#ifdef HAVE_OS2_H
+#include "source_os2.h"
+#endif
+
+/* Turn this on to add -DG_DISABLE_DEPRECATED etc. flags in generated code,
+ so we can check if Glade is generating any deprecated code. */
+#if 0
+#define GLADE_ADD_DISABLE_DEPRECATED_FLAGS
+#endif
+
+/* An internal struct to pass data to the source_write_component() callback. */
+typedef struct _GladeSourceCallbackData GladeSourceCallbackData;
+struct _GladeSourceCallbackData
+{
+ GbWidgetWriteSourceData *write_source_data;
+ FILE *interface_h_fp;
+ FILE *interface_c_fp;
+ FILE *callback_h_fp;
+ FILE *callback_c_fp;
+};
+
+
+static GladeError* source_write_internal (GladeProject * project);
+
+static void source_write_interface_and_callbacks (GbWidgetWriteSourceData * data);
+static void source_begin_interface_and_callbacks_files (GbWidgetWriteSourceData * data,
+ FILE **interface_h_fp,
+ FILE **interface_c_fp,
+ FILE **callback_h_fp,
+ FILE **callback_c_fp);
+static void source_output_interface_and_callbacks_source (GbWidgetWriteSourceData * data,
+ FILE *interface_h_fp,
+ FILE *interface_c_fp,
+ FILE *callback_h_fp,
+ FILE *callback_c_fp);
+static void source_write_component (GtkWidget * component,
+ GladeSourceCallbackData * source_data);
+
+static void source_write_interface_h_preamble (GbWidgetWriteSourceData * data,
+ FILE *fp);
+static void source_write_interface_c_preamble (GbWidgetWriteSourceData * data,
+ FILE *fp);
+static void source_write_callback_h_preamble (GbWidgetWriteSourceData * data,
+ FILE *fp);
+static void source_write_callback_c_preamble (GbWidgetWriteSourceData * data,
+ FILE *fp);
+static void source_write_preamble (gchar *project_name,
+ FILE * fp);
+
+static void source_write_main_c (GbWidgetWriteSourceData * data);
+static void source_write_component_create (GtkWidget * component,
+ GbWidgetWriteSourceData * data);
+
+static void source_write_build_files (GbWidgetWriteSourceData * data);
+static void source_write_autogen_sh (GbWidgetWriteSourceData * data);
+
+static void source_write_gtk_build_files (GbWidgetWriteSourceData * data);
+static void source_write_gtk_configure_in (GbWidgetWriteSourceData * data);
+static void source_write_gtk_makefile_am (GbWidgetWriteSourceData * data);
+static void source_write_gtk_makefile_am_pixmaps_targets (GbWidgetWriteSourceData * data,
+ gchar * directory,
+ FILE * fp);
+
+static void source_write_gnome_build_files (GbWidgetWriteSourceData * data);
+static void source_write_gnome_configure_in (GbWidgetWriteSourceData * data);
+static void source_write_gnome_makefile_am (GbWidgetWriteSourceData * data);
+static void source_write_gnome_makefile_am_pixmaps_targets (GbWidgetWriteSourceData * data,
+ gchar * directory,
+ FILE * fp);
+
+static void source_write_common_build_files (GbWidgetWriteSourceData * data);
+static void source_write_toplevel_makefile_am (GbWidgetWriteSourceData * data);
+static void source_write_extra_dist (GbWidgetWriteSourceData * data,
+ const gchar *directory,
+ FILE *fp);
+static GladeError* source_create_file_if_not_exist (const gchar *directory,
+ const gchar *filename,
+ const gchar *contents);
+static void source_write_po_files (GbWidgetWriteSourceData * data);
+#if 0
+static void source_write_acconfig_h (GbWidgetWriteSourceData * data);
+#endif
+static void source_write_support_files (GbWidgetWriteSourceData * data);
+
+static void source_write_gtk_create_pixmap_functions (GbWidgetWriteSourceData * data,
+ FILE *fp);
+static void source_write_gnome_create_pixmap_functions (GbWidgetWriteSourceData * data,
+ FILE *fp);
+
+static gchar* source_is_valid_source_filename (const gchar * filename);
+static GladeError* source_backup_file_if_exists (const gchar * filename);
+
+static gchar * source_make_string_internal (const gchar * text,
+ gboolean translatable,
+ gboolean is_static,
+ gboolean context);
+static void source_reset_code_buffers (GbWidgetWriteSourceData * data);
+static void source_destroy_standard_widgets_callback (gchar * key,
+ GtkWidget * widget,
+ gpointer data);
+static void source_free_hash_keys_callback (gchar * key,
+ gpointer value,
+ gpointer data);
+static gchar* source_get_source_subdirectory (GbWidgetWriteSourceData * data);
+static void source_write_no_editing_warning (FILE *fp);
+static void source_write_include_files (FILE *fp);
+
+
+/* We need this so that numbers are written in C syntax rather than the
+ current locale, which may use ',' instead of '.' and then the code
+ will not compile. This code is from glibc info docs. */
+GladeError*
+source_write (GladeProject *project)
+{
+ gchar *old_locale, *saved_locale;
+ GladeError *error;
+
+ old_locale = setlocale (LC_NUMERIC, NULL);
+ saved_locale = g_strdup (old_locale);
+ setlocale (LC_NUMERIC, "C");
+ error = source_write_internal (project);
+ setlocale (LC_NUMERIC, saved_locale);
+ g_free (saved_locale);
+ return error;
+}
+
+
+static GladeError*
+source_write_internal (GladeProject * project)
+{
+ GbWidgetWriteSourceData data;
+ gchar *source_directory, *interface_source_file, *interface_header_file;
+ gchar *callback_source_file, *callback_header_file, *msg;
+ gchar *support_source_file, *support_header_file;
+ gint i;
+
+ source_directory = glade_project_get_source_directory (project);
+ glade_project_get_source_files (project,
+ &interface_source_file,
+ &interface_header_file,
+ &callback_source_file,
+ &callback_header_file);
+
+ /* Check that any source filenames that we are going to use are valid. */
+ if ((msg = source_is_valid_source_filename (interface_source_file)))
+ return glade_error_new_general (GLADE_STATUS_ERROR, _("Invalid interface source filename: %s\n%s\n"), interface_source_file, msg);
+ if ((msg = source_is_valid_source_filename (interface_header_file)))
+ return glade_error_new_general (GLADE_STATUS_ERROR, _("Invalid interface header filename: %s\n%s\n"), interface_header_file, msg);
+
+ if ((msg = source_is_valid_source_filename (callback_source_file)))
+ return glade_error_new_general (GLADE_STATUS_ERROR, _("Invalid callbacks source filename: %s\n%s\n"), callback_source_file, msg);
+ if ((msg = source_is_valid_source_filename (callback_header_file)))
+ return glade_error_new_general (GLADE_STATUS_ERROR, _("Invalid callbacks header filename: %s\n%s\n"), callback_source_file, msg);
+
+ if (glade_project_get_output_support_files (project)) {
+ support_source_file = glade_project_get_support_source_file (project);
+ support_header_file = glade_project_get_support_header_file (project);
+ if ((msg = source_is_valid_source_filename (support_source_file)))
+ return glade_error_new_general (GLADE_STATUS_ERROR, _("Invalid support source filename: %s\n%s\n"), support_source_file, msg);
+ if ((msg = source_is_valid_source_filename (support_header_file)))
+ return glade_error_new_general (GLADE_STATUS_ERROR, _("Invalid support header filename: %s\n%s\n"), support_header_file, msg);
+ }
+
+ /* Initialize the GbWidgetWriteSourceData fields.
+ Note that the error is set to NULL. If anything sets it we know there is
+ an error. */
+ data.project = project;
+ data.error = NULL;
+ data.project_name = glade_project_get_name (project);
+ data.program_name = glade_project_get_program_name (project);
+ data.interface_c_filename = glade_util_make_absolute_path (source_directory,
+ interface_source_file);
+ data.interface_h_filename = glade_util_make_absolute_path (source_directory,
+ interface_header_file);
+ data.callback_c_filename = glade_util_make_absolute_path (source_directory,
+ callback_source_file);
+ data.callback_h_filename = glade_util_make_absolute_path (source_directory,
+ callback_header_file);
+ data.set_widget_names = glade_project_get_use_widget_names (project);
+ data.use_gettext = glade_project_get_gettext_support (project);
+ data.use_component_struct = FALSE;
+ data.creating_callback_files = FALSE;
+ data.standard_widgets = g_hash_table_new (g_str_hash, g_str_equal);
+ data.handlers_output = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* Create the empty source code buffers. */
+ for (i = 0; i < GLADE_NUM_SOURCE_BUFFERS; i++)
+ data.source_buffers[i] = g_string_sized_new (1024);
+
+ /* If the callback.c file doesn't exists, we need to output all signal
+ handlers & callbacks. If it exists, we only write handlers & callbacks
+ that have been added/changed since the last time the interface.c file
+ was written. */
+ if (!glade_util_file_exists (data.callback_c_filename))
+ {
+ data.creating_callback_files = TRUE;
+ }
+ else
+ {
+ data.error = glade_util_file_last_mod_time (data.interface_c_filename,
+ &data.last_write_time);
+
+ /* If the interface.c file doesn't exist, we have no way of knowing
+ which callbacks need to be output, so we set the last_write_time
+ to the current time, i.e. we don't output any callbacks. */
+ if (data.error && data.error->status == GLADE_STATUS_SYSTEM_ERROR
+ && data.error->system_errno == ENOENT)
+ {
+ data.last_write_time = time (NULL);
+ glade_error_free (data.error);
+ data.error = NULL;
+ }
+ }
+
+ /* Make sure the project & source directories exist. */
+ if (!data.error)
+ data.error = glade_util_ensure_directory_exists (glade_project_get_directory (data.project));
+
+ if (!data.error)
+ data.error = glade_util_ensure_directory_exists (glade_project_get_source_directory (data.project));
+
+ /* Now call the main functions to write the source code and support files. */
+ if (!data.error)
+ source_write_build_files (&data);
+ if (!data.error)
+ source_write_support_files (&data);
+ if (!data.error)
+ source_write_main_c (&data);
+ if (!data.error)
+ source_write_interface_and_callbacks (&data);
+
+ /* Now free everything. */
+ for (i = 0; i < GLADE_NUM_SOURCE_BUFFERS; i++)
+ g_string_free (data.source_buffers[i], TRUE);
+
+ g_hash_table_foreach (data.standard_widgets,
+ (GHFunc) source_destroy_standard_widgets_callback,
+ NULL);
+ g_hash_table_destroy (data.standard_widgets);
+
+ g_hash_table_foreach (data.handlers_output,
+ (GHFunc) source_free_hash_keys_callback, NULL);
+ g_hash_table_destroy (data.handlers_output);
+
+ g_free (data.interface_c_filename);
+ g_free (data.interface_h_filename);
+ g_free (data.callback_c_filename);
+ g_free (data.callback_h_filename);
+
+ return data.error;
+}
+
+
+/*************************************************************************
+ * Main source files - interface.[hc] & callbacks.[hc]
+ *************************************************************************/
+
+static void
+source_write_interface_and_callbacks (GbWidgetWriteSourceData * data)
+{
+ FILE *interface_h_fp = NULL, *interface_c_fp = NULL;
+ FILE *callback_h_fp = NULL, *callback_c_fp = NULL;
+
+ /* Backup the two main files, if the backup option is selected.
+ We don't backup the signals files since we only ever append to them. */
+ if (glade_project_get_backup_source_files (data->project))
+ {
+ data->error = source_backup_file_if_exists (data->interface_c_filename);
+ if (data->error)
+ return;
+
+ data->error = source_backup_file_if_exists (data->interface_h_filename);
+ if (data->error)
+ return;
+ }
+
+ /* Open all the files and add the standard license and #include stuff.
+ Note that if an error occurs, data->error is set, and we simply drop
+ through to close any files which were opened below. */
+ source_begin_interface_and_callbacks_files (data,
+ &interface_h_fp,
+ &interface_c_fp,
+ &callback_h_fp,
+ &callback_c_fp);
+
+ if (!data->error)
+ {
+ source_output_interface_and_callbacks_source (data,
+ interface_h_fp,
+ interface_c_fp,
+ callback_h_fp,
+ callback_c_fp);
+ }
+
+ /* Now close any files which were opened. */
+ if (interface_h_fp)
+ fclose (interface_h_fp);
+ if (interface_c_fp)
+ fclose (interface_c_fp);
+ if (callback_h_fp)
+ fclose (callback_h_fp);
+ if (callback_c_fp)
+ fclose (callback_c_fp);
+}
+
+
+/* Creates the interface.h & interface.c files, and created callbacks.h
+ & callback.c or opens them for appending as appropriate. */
+static void
+source_begin_interface_and_callbacks_files (GbWidgetWriteSourceData * data,
+ FILE **interface_h_fp,
+ FILE **interface_c_fp,
+ FILE **callback_h_fp,
+ FILE **callback_c_fp)
+{
+ /* Create the interface.h file and output the standard license. */
+ *interface_h_fp = glade_util_fopen (data->interface_h_filename, "w");
+ if (*interface_h_fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ data->interface_h_filename);
+ return;
+ }
+
+ source_write_interface_h_preamble (data, *interface_h_fp);
+ if (data->error)
+ return;
+
+
+ /* Create the interface.c file and output the standard license and #include
+ lines. */
+ *interface_c_fp = glade_util_fopen (data->interface_c_filename, "w");
+ if (*interface_c_fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ data->interface_c_filename);
+ return;
+ }
+
+ source_write_interface_c_preamble (data, *interface_c_fp);
+ if (data->error)
+ return;
+
+
+ /* If the callback.[hc] files are being created from scratch, create them
+ and and output the standard license and #include stuff, else just open
+ them for appending. */
+ if (data->creating_callback_files)
+ {
+ *callback_h_fp = glade_util_fopen (data->callback_h_filename, "w");
+ if (*callback_h_fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ data->callback_h_filename);
+ return;
+ }
+
+ source_write_callback_h_preamble (data, *callback_h_fp);
+ if (data->error)
+ return;
+
+
+ *callback_c_fp = glade_util_fopen (data->callback_c_filename, "w");
+ if (*callback_c_fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ data->callback_c_filename);
+ return;
+ }
+
+ source_write_callback_c_preamble (data, *callback_c_fp);
+ if (data->error)
+ return;
+ }
+ else
+ {
+ *callback_h_fp = glade_util_fopen (data->callback_h_filename, "a");
+ if (*callback_h_fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't append to file:\n %s\n"),
+ data->callback_h_filename);
+ return;
+ }
+
+ *callback_c_fp = glade_util_fopen (data->callback_c_filename, "a");
+ if (*callback_c_fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't append to file:\n %s\n"),
+ data->callback_c_filename);
+ return;
+ }
+ }
+}
+
+
+static void
+source_output_interface_and_callbacks_source (GbWidgetWriteSourceData * data,
+ FILE *interface_h_fp,
+ FILE *interface_c_fp,
+ FILE *callback_h_fp,
+ FILE *callback_c_fp)
+{
+ GladeSourceCallbackData source_data;
+
+ /* This outputs the code to create the components and the signal handler
+ prototypes. */
+ source_data.write_source_data = data;
+ source_data.interface_h_fp = interface_h_fp;
+ source_data.interface_c_fp = interface_c_fp;
+ source_data.callback_h_fp = callback_h_fp;
+ source_data.callback_c_fp = callback_c_fp;
+
+ /* Iterate through the project components outputting the source code and
+ declarations. */
+ glade_project_foreach_component (data->project,
+ (GtkCallback) source_write_component,
+ &source_data);
+}
+
+
+/* This outputs the source code for one component (a window, dialog or popup
+ menu). */
+static void
+source_write_component (GtkWidget * component,
+ GladeSourceCallbackData * source_data)
+{
+ GbWidgetWriteSourceData * data;
+ FILE *interface_h_fp, *interface_c_fp;
+ FILE *callback_h_fp, *callback_c_fp;
+
+ /* Get the data out of the callback data struct. */
+ data = source_data->write_source_data;
+ interface_h_fp = source_data->interface_h_fp;
+ interface_c_fp = source_data->interface_c_fp;
+ callback_h_fp = source_data->callback_h_fp;
+ callback_c_fp = source_data->callback_c_fp;
+
+ /* Reset the GbWidgetWriteSourceData, ready to begin a new component. */
+ data->component = component;
+ data->component_name = source_create_valid_identifier (gtk_widget_get_name (component));
+ data->parent = NULL;
+ data->need_tooltips = FALSE;
+ data->need_accel_group = FALSE;
+ data->create_widget = TRUE;
+ data->write_children = TRUE;
+ data->focus_widget = NULL;
+ data->default_widget = NULL;
+
+ /* Clear all the code from the previous component. */
+ source_reset_code_buffers (data);
+
+ /* Recursively write the source for all the widgets in the component. */
+ gb_widget_write_source (component, data);
+
+ /*
+ * Output interface.h
+ */
+
+ /* Output the declaration of the function to create the component in the
+ header file. */
+ fprintf (interface_h_fp, "GtkWidget* create_%s (void);\n",
+ data->component_name);
+
+
+ /*
+ * Output interface.c
+ */
+
+ /* Output any GnomeUIInfo structs. */
+ fprintf (interface_c_fp, "%s", data->source_buffers[GLADE_UIINFO]->str);
+
+ fprintf (interface_c_fp,
+ "GtkWidget*\n"
+ "create_%s (void)\n"
+ "{\n",
+ data->component_name);
+
+ /* Output the declarations of all the widgets and any temporary variables
+ needed at the start of the function. */
+ fprintf (interface_c_fp, "%s",
+ data->source_buffers[GLADE_DECLARATIONS]->str);
+
+ /* Output a declaration of accel_group and tooltips if they are needed by
+ the component. */
+ if (data->need_accel_group)
+ fprintf (interface_c_fp, " GtkAccelGroup *accel_group;\n");
+// if (data->need_tooltips)
+// fprintf (interface_c_fp, " GtkTooltips *tooltips;\n");
+
+ /* Output a blank line between the declarations and the source. */
+ fprintf (interface_c_fp, "\n");
+
+ /* Create the tooltips object if needed. */
+// if (data->need_tooltips)
+// fprintf (interface_c_fp, " tooltips = gtk_tooltips_new ();\n\n");
+
+ /* Create the accel group if needed. */
+ if (data->need_accel_group)
+ fprintf (interface_c_fp, " accel_group = gtk_accel_group_new ();\n\n");
+
+ /* Output the source code to create the widgets in the component. */
+ fprintf (interface_c_fp, "%s", data->source_buffers[GLADE_SOURCE]->str);
+
+ /* Output the source code to connect the signal handlers. */
+ if (data->source_buffers[GLADE_SIGNAL_CONNECTIONS]->len > 0)
+ fprintf (interface_c_fp, "%s\n",
+ data->source_buffers[GLADE_SIGNAL_CONNECTIONS]->str);
+
+ /* Output the source code to setup the accelerator keys. */
+ if (data->source_buffers[GLADE_ACCELERATORS]->len > 0)
+ fprintf (interface_c_fp, "%s\n",
+ data->source_buffers[GLADE_ACCELERATORS]->str);
+
+ /* Output the source code to set ATK properties. */
+ if (data->source_buffers[GLADE_ATK_SOURCE]->len > 0)
+ fprintf (interface_c_fp, "%s\n",
+ data->source_buffers[GLADE_ATK_SOURCE]->str);
+
+ /* Output the source code to set the pointers to the widgets. */
+ if (data->source_buffers[GLADE_OBJECT_HOOKUP]->len > 0)
+ {
+ fprintf (interface_c_fp,
+ " /* Store pointers to all widgets, for use by lookup_widget(). */\n");
+ fprintf (interface_c_fp, "%s",
+ data->source_buffers[GLADE_OBJECT_HOOKUP]->str);
+ }
+
+ /* Store a pointer to the tooltips object, if we used one, so that it can
+ be accessed in callbacks. */
+// if (data->need_tooltips)
+// {
+// fprintf (interface_c_fp,
+// " GLADE_HOOKUP_OBJECT_NO_REF (%s, tooltips, \"tooltips\");\n",
+// data->component_name);
+// }
+
+ fprintf (interface_c_fp, "\n");
+
+ /* Set the focus widget, if there is one. */
+ if (data->focus_widget)
+ {
+ fprintf (interface_c_fp, " gtk_widget_grab_focus (%s);\n",
+ data->focus_widget);
+ g_free (data->focus_widget);
+ data->focus_widget = NULL;
+ }
+
+ /* Set the default widget, if there is one. */
+ if (data->default_widget)
+ {
+ fprintf (interface_c_fp, " gtk_widget_grab_default (%s);\n",
+ data->default_widget);
+ g_free (data->default_widget);
+ data->default_widget = NULL;
+ }
+
+ /* Add the accel group to the component. */
+ if (data->need_accel_group)
+ {
+ if (GTK_IS_MENU (data->component))
+ fprintf (interface_c_fp,
+ " gtk_menu_set_accel_group (GTK_MENU (%s), accel_group);\n\n",
+ data->component_name);
+ else
+ fprintf (interface_c_fp,
+ " gtk_window_add_accel_group (GTK_WINDOW (%s), accel_group);\n\n",
+ data->component_name);
+ }
+
+ /* Return the toplevel widget and finish the function. */
+ fprintf (interface_c_fp, " return %s;\n}\n\n", data->component_name);
+
+ /*
+ * Output callbacks.h
+ */
+
+ /* Output the signal handler declarations. */
+ fprintf (callback_h_fp, "%s",
+ data->source_buffers[GLADE_CALLBACK_DECLARATIONS]->str);
+
+ /*
+ * Output callbacks.c
+ */
+
+ /* Output the signal handler functions. */
+ fprintf (callback_c_fp, "%s",
+ data->source_buffers[GLADE_CALLBACK_SOURCE]->str);
+
+
+ g_free (data->component_name);
+ data->component_name = NULL;
+}
+
+
+/* Outputs the license and and other code needed at the top of the interface.h
+ header file, before any function declarations are output. */
+static void
+source_write_interface_h_preamble (GbWidgetWriteSourceData * data, FILE *fp)
+{
+ source_write_no_editing_warning (fp);
+ source_write_preamble (data->project_name, fp);
+}
+
+static void
+source_write_include_files (FILE *fp)
+{
+ fprintf (fp,
+ "#ifdef HAVE_CONFIG_H\n"
+ "# include <config.h>\n"
+ "#endif\n"
+ "\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <unistd.h>\n"
+ "#include <string.h>\n"
+ "#include <stdio.h>\n"
+ "\n");
+}
+
+/* Outputs the license and any include files needed at the top of the
+ interface.c source file, before code for the components is output. */
+static void
+source_write_interface_c_preamble (GbWidgetWriteSourceData * data, FILE *fp)
+{
+ source_write_no_editing_warning (fp);
+ source_write_preamble (data->project_name, fp);
+
+ source_write_include_files (fp);
+
+ if (glade_project_get_gnome_support (data->project))
+ {
+ fprintf (fp, "#include <bonobo.h>\n");
+ fprintf (fp, "#include <gnome.h>\n");
+
+ if (glade_project_get_gnome_db_support (data->project))
+ {
+ fprintf (fp, "#include <libgnomedb/libgnomedb.h>\n");
+ }
+ }
+ else
+ {
+ fprintf (fp,
+ "#include <gdk/gdkkeysyms.h>\n"
+ "#include <gtk/gtk.h>\n");
+ }
+
+ fprintf (fp,
+ "\n"
+ "#include \"%s\"\n"
+ "#include \"%s\"\n"
+ "#include \"%s\"\n\n",
+ g_basename (data->callback_h_filename),
+ g_basename (data->interface_h_filename),
+ glade_project_get_support_header_file (data->project));
+
+ fprintf (fp,
+ "#define GLADE_HOOKUP_OBJECT(component,widget,name) \\\n"
+ " g_object_set_data_full (G_OBJECT (component), name, \\\n"
+ " g_object_ref(G_OBJECT(widget)), (GDestroyNotify) g_object_unref)\n\n");
+
+ fprintf (fp,
+ "#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \\\n"
+ " g_object_set_data (G_OBJECT (component), name, widget)\n\n");
+}
+
+
+/* Outputs the license and and other code needed at the top of the callback.h
+ header file, before any signal handler and callback function declarations
+ are output. */
+static void
+source_write_callback_h_preamble (GbWidgetWriteSourceData * data, FILE *fp)
+{
+ source_write_preamble (data->project_name, fp);
+
+ if (glade_project_get_gnome_support (data->project))
+ fprintf (fp, "#include <gnome.h>\n\n");
+ else
+ fprintf (fp, "#include <gtk/gtk.h>\n\n");
+
+ if (glade_project_get_gnome_db_support (data->project))
+ fprintf (fp, "#include <libgnomedb/libgnomedb.h>\n");
+}
+
+
+/* Outputs the license and any include files needed at the top of the
+ callback.c source file, before code for the signal handlers and callback
+ functions is output. */
+static void
+source_write_callback_c_preamble (GbWidgetWriteSourceData * data, FILE *fp)
+{
+ source_write_preamble (data->project_name, fp);
+
+ fprintf (fp,
+ "#ifdef HAVE_CONFIG_H\n"
+ "# include <config.h>\n"
+ "#endif\n"
+ "\n");
+
+ if (glade_project_get_gnome_support (data->project))
+ fprintf (fp, "#include <gnome.h>\n");
+ else
+ fprintf (fp, "#include <gtk/gtk.h>\n");
+
+ fprintf (fp,
+ "\n"
+ "#include \"%s\"\n"
+ "#include \"%s\"\n"
+ "#include \"%s\"\n\n",
+ g_basename (data->callback_h_filename),
+ g_basename (data->interface_h_filename),
+ glade_project_get_support_header_file (data->project));
+}
+
+
+/* Output a license at the top of a source or header file.
+ Note this will eventually be editable in the user interface, with an option
+ to include a few standard licenses, e.g. GPL, which are then edited by the
+ user. FIXME: I've taken this out until we support it fully. */
+static void
+source_write_preamble (gchar *project_name, FILE * fp)
+{
+#if 0
+ fprintf (fp,
+ "/* Note: You are free to use whatever license you want.\n"
+ " Eventually you will be able to edit it within Glade. */\n"
+ "\n"
+ "/* %s\n"
+ " * Copyright (C) <YEAR> <AUTHORS>\n"
+ " *\n"
+ " * This program is free software; you can redistribute it and/or modify\n"
+ " * it under the terms of the GNU General Public License as published by\n"
+ " * the Free Software Foundation; either version 2 of the License, or\n"
+ " * (at your option) any later version.\n"
+ " *\n"
+ " * This program is distributed in the hope that it will be useful,\n"
+ " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ " * GNU General Public License for more details.\n"
+ " *\n"
+ " * You should have received a copy of the GNU General Public License\n"
+ " * along with this program; if not, write to the Free Software\n"
+ " * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"
+ "*/\n\n", project_name);
+#endif
+}
+
+
+/*************************************************************************
+ * main.c file.
+ *************************************************************************/
+
+void
+source_write_main_c (GbWidgetWriteSourceData * data)
+{
+ gchar *directory, *source_directory, *filename;
+ FILE *fp;
+
+ /* See if the main.c file is wanted. */
+ if (!glade_project_get_output_main_file (data->project))
+ return;
+
+ directory = glade_project_get_directory (data->project);
+ source_directory = glade_project_get_source_directory (data->project);
+
+ filename = glade_util_make_absolute_path (source_directory, "main.c");
+
+ /* Return if it already exists. */
+ if (glade_util_file_exists (filename))
+ {
+ g_free (filename);
+ return;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ source_write_preamble (data->project_name, fp);
+
+ fprintf (fp,
+ "/*\n"
+ " * Initial main.c file generated by Glade. Edit as required.\n"
+ " * Glade will not overwrite this file.\n"
+ " */\n\n");
+
+ fprintf (fp,
+ "#ifdef HAVE_CONFIG_H\n"
+ "# include <config.h>\n"
+ "#endif\n\n");
+
+ if (glade_project_get_gnome_support (data->project))
+ {
+ fprintf (fp, "#include <gnome.h>\n\n");
+ }
+ else
+ {
+ fprintf (fp, "#include <gtk/gtk.h>\n\n");
+ }
+
+ /* Include the interface.h header to get declarations of the functions to
+ create the components, and support.h so we include libintl.h if needed. */
+ fprintf (fp,
+ "#include \"%s\"\n"
+ "#include \"%s\"\n\n",
+ g_basename (data->interface_h_filename),
+ glade_project_get_support_header_file (data->project));
+
+ fprintf (fp,
+ "int\n"
+ "main (int argc, char *argv[])\n"
+ "{\n");
+
+ source_reset_code_buffers (data);
+
+ /* This outputs code in main() to create one of each component, just so that
+ the user sees something after first building the project. */
+ glade_project_foreach_component (data->project,
+ (GtkCallback) source_write_component_create,
+ data);
+ fprintf (fp, "%s\n", data->source_buffers[GLADE_DECLARATIONS]->str);
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp,
+ "#ifdef ENABLE_NLS\n"
+ " bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);\n"
+ " bind_textdomain_codeset (GETTEXT_PACKAGE, \"UTF-8\");\n"
+ " textdomain (GETTEXT_PACKAGE);\n"
+ "#endif\n"
+ "\n");
+ }
+
+ /* Note that we don't mark the project name as translatable.
+ I'm not entirely certain we should do that. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+ fprintf (fp,
+ " gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,\n"
+ " argc, argv,\n"
+ " GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR,\n"
+ " NULL);\n");
+ }
+ else
+ {
+ fprintf (fp,
+ " gtk_set_locale ();\n"
+ " gtk_init (&argc, &argv);\n"
+ "\n");
+
+ fprintf (fp,
+ " add_pixmap_directory (PACKAGE_DATA_DIR \"/\" PACKAGE \"/pixmaps\");\n");
+ }
+
+ fprintf (fp,
+ "\n"
+ " /*\n"
+ " * The following code was added by Glade to create one of each component\n"
+ " * (except popup menus), just so that you see something after building\n"
+ " * the project. Delete any components that you don't want shown initially.\n"
+ " */\n");
+ fprintf (fp, "%s", data->source_buffers[GLADE_SOURCE]->str);
+ fprintf (fp, "\n gtk_main ();\n return 0;\n}\n\n");
+
+ fclose (fp);
+
+ g_free (filename);
+}
+
+
+static void
+source_write_component_create (GtkWidget * component,
+ GbWidgetWriteSourceData * data)
+{
+ gchar *component_name;
+
+ /* Don't output code to show popup menus. */
+ if (GTK_IS_MENU (component))
+ return;
+
+ component_name = (gchar*) gtk_widget_get_name (component);
+ component_name = source_create_valid_identifier (component_name);
+ source_add_decl (data, " GtkWidget *%s;\n", component_name);
+ source_add (data,
+ " %s = create_%s ();\n"
+ " gtk_widget_show (%s);\n",
+ component_name, component_name, component_name);
+ g_free (component_name);
+}
+
+
+/*************************************************************************
+ * Build Files.
+ *************************************************************************/
+
+static void
+source_write_build_files (GbWidgetWriteSourceData * data)
+{
+ /* If the build files aren't wanted, return. */
+ if (!glade_project_get_output_build_files (data->project))
+ return;
+
+ /* Write the support files - Makefile.am, configure.in, etc. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+ source_write_gnome_build_files (data);
+ }
+ else
+ {
+ source_write_gtk_build_files (data);
+ }
+ if (data->error)
+ return;
+
+ source_write_common_build_files (data);
+ if (data->error)
+ return;
+
+#ifdef HAVE_OS2_H
+ source_write_os2_files(data);
+#endif
+}
+
+
+/*
+ * GTK+ build files.
+ */
+
+static void
+source_write_gtk_build_files (GbWidgetWriteSourceData * data)
+{
+ source_write_autogen_sh (data);
+ if (data->error)
+ return;
+
+ source_write_gtk_configure_in (data);
+ if (data->error)
+ return;
+
+ source_write_gtk_makefile_am (data);
+}
+
+
+/* Copies the generic autogen.sh script which runs aclocal, automake
+ & autoconf to create the Makefiles etc. */
+static void
+source_write_autogen_sh (GbWidgetWriteSourceData * data)
+{
+ static const gchar *data_dir = GLADE_DATADIR "/glade-2";
+ gchar *project_dir, *srcbuffer, *destbuffer;
+ const gchar *filename = "autogen.sh";
+ gint old_umask;
+
+ srcbuffer = g_malloc (strlen (data_dir) + 128);
+ project_dir = glade_project_get_directory (data->project);
+ destbuffer = g_malloc (strlen (project_dir) + 128);
+
+ sprintf (srcbuffer, "%s/gtk/%s", data_dir, filename);
+ sprintf (destbuffer, "%s/%s", project_dir, filename);
+
+ if (!glade_util_file_exists (destbuffer))
+ {
+ data->error = glade_util_copy_file (srcbuffer, destbuffer);
+ }
+
+ /* We need to make the script executable, but we try to honour any umask. */
+#ifndef _WIN32
+ old_umask = umask (0666);
+ chmod (destbuffer, 0777 & ~old_umask);
+ umask (old_umask);
+#endif
+
+ g_free (srcbuffer);
+ g_free (destbuffer);
+}
+
+
+static void
+source_write_gtk_configure_in (GbWidgetWriteSourceData * data)
+{
+ FILE *fp;
+ gchar *filename, *alt_filename, *source_subdir;
+
+ filename = glade_util_make_absolute_path (glade_project_get_directory (data->project), "configure.in");
+ alt_filename = glade_util_make_absolute_path (glade_project_get_directory (data->project), "configure.ac");
+
+ /* FIXME: If configure.in exists, just leave it, for now. */
+ if (glade_util_file_exists (filename)
+ || glade_util_file_exists (alt_filename))
+ {
+ g_free (filename);
+ g_free (alt_filename);
+ return;
+ }
+
+ g_free (alt_filename);
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ /* FIXME: Using AC_INIT(configure.in) is not really correct - we should be
+ using a file unique to the project. */
+ fprintf (fp,
+ "dnl Process this file with autoconf to produce a configure script.\n"
+ "\n"
+ "AC_INIT(configure.in)\n"
+ "AM_INIT_AUTOMAKE(%s, 0.1)\n"
+ "AM_CONFIG_HEADER(config.h)\n"
+ "AM_MAINTAINER_MODE\n"
+ "\n"
+ "AC_ISC_POSIX\n"
+ "AC_PROG_CC\n"
+ "AM_PROG_CC_STDC\n"
+ "AC_HEADER_STDC\n"
+ "\n",
+ data->program_name);
+
+ fprintf (fp,
+ "pkg_modules=\"gtk+-2.0 >= 2.0.0\"\n"
+ "PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])\n"
+ "AC_SUBST(PACKAGE_CFLAGS)\n"
+ "AC_SUBST(PACKAGE_LIBS)\n"
+ "\n");
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp,
+ "GETTEXT_PACKAGE=%s\n"
+ "AC_SUBST(GETTEXT_PACKAGE)\n"
+ "AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,\"$GETTEXT_PACKAGE\", [Gettext package.])\n\n",
+ data->program_name);
+ fprintf (fp,
+ "dnl Add the languages which your application supports here.\n"
+ "ALL_LINGUAS=\"\"\n"
+ "AM_GLIB_GNU_GETTEXT\n"
+ "\n");
+ }
+
+ fprintf (fp,
+ "AC_OUTPUT([\n"
+ "Makefile\n");
+
+ source_subdir = source_get_source_subdirectory (data);
+ if (source_subdir)
+ {
+ fprintf (fp, "%s/Makefile\n", source_subdir);
+ g_free (source_subdir);
+ }
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp,
+ "po/Makefile.in\n");
+ }
+
+ fprintf (fp, "])\n\n");
+
+ fclose (fp);
+
+ g_free (filename);
+}
+
+
+static void
+source_write_gtk_makefile_am (GbWidgetWriteSourceData * data)
+{
+ FILE *fp;
+ gchar *directory, *source_directory, *filename, *program_name_as_target;
+ gboolean is_toplevel;
+
+ directory = glade_project_get_directory (data->project);
+ source_directory = glade_project_get_source_directory (data->project);
+
+ filename = glade_util_make_absolute_path (source_directory, "Makefile.am");
+
+ /* FIXME: If Makefile.am exists, just leave it, for now. */
+ if (glade_util_file_exists (filename))
+ {
+ g_free (filename);
+ return;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ fprintf (fp,
+ "## Process this file with automake to produce Makefile.in\n\n");
+
+ /* If the project directory is the source directory, we need to output
+ SUBDIRS here. */
+ is_toplevel = glade_util_directories_equivalent (directory,
+ source_directory);
+ if (is_toplevel)
+ {
+ fprintf (fp, "SUBDIRS =");
+
+ if (glade_project_get_gettext_support (data->project))
+ fprintf (fp, " po");
+
+ fprintf (fp, "\n\n");
+ }
+
+ fprintf (fp,
+ "INCLUDES = \\\n"
+ "\t-DPACKAGE_DATA_DIR=\\\"\"$(datadir)\"\\\" \\\n"
+ "\t-DPACKAGE_LOCALE_DIR=\\\"\"$(prefix)/$(DATADIRNAME)/locale\"\\\" \\\n"
+#ifdef GLADE_ADD_DISABLE_DEPRECATED_FLAGS
+ "\t-DG_DISABLE_DEPRECATED \\\n"
+ "\t-DGDK_DISABLE_DEPRECATED \\\n"
+ "\t-DGTK_DISABLE_DEPRECATED \\\n"
+#endif
+ "\t@PACKAGE_CFLAGS@\n"
+ "\n");
+
+ program_name_as_target = g_strdup (data->program_name);
+ g_strdelimit (program_name_as_target, "-", '_');
+
+ fprintf (fp,
+ "bin_PROGRAMS = %s\n"
+ "\n",
+ data->program_name);
+
+ fprintf (fp,
+ "%s_SOURCES = \\\n",
+ program_name_as_target);
+
+ if (glade_project_get_output_main_file (data->project))
+ fprintf (fp, "\tmain.c \\\n");
+
+ if (glade_project_get_output_support_files (data->project))
+ {
+ fprintf (fp, "\t%s %s \\\n",
+ glade_project_get_support_source_file (data->project),
+ glade_project_get_support_header_file (data->project));
+ }
+
+ fprintf (fp,
+ "\t%s %s \\\n"
+ "\t%s %s\n\n",
+ g_basename (data->interface_c_filename),
+ g_basename (data->interface_h_filename),
+ g_basename (data->callback_c_filename),
+ g_basename (data->callback_h_filename));
+
+ fprintf (fp,
+ "%s_LDADD = @PACKAGE_LIBS@",
+ program_name_as_target);
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp, " $(INTLLIBS)");
+ }
+
+ fprintf (fp, "\n\n");
+
+ if (is_toplevel)
+ source_write_extra_dist (data, source_directory, fp);
+
+ source_write_gtk_makefile_am_pixmaps_targets (data, source_directory, fp);
+
+ fclose (fp);
+
+ g_free (program_name_as_target);
+ g_free (filename);
+}
+
+
+/* This outputs targets to install pixmaps and to include them in the
+ distribution, if the pixmaps are in a subdirectory of the given directory.
+*/
+static void
+source_write_gtk_makefile_am_pixmaps_targets (GbWidgetWriteSourceData * data,
+ gchar * directory,
+ FILE * fp)
+{
+ gchar *pixmaps_directory, *subdir;
+ gint subdir_len;
+
+ pixmaps_directory = glade_project_get_pixmaps_directory (data->project);
+
+ if (!glade_util_directory_contains_file (directory, pixmaps_directory))
+ return;
+
+ subdir = glade_util_make_relative_path (directory, pixmaps_directory);
+ subdir_len = strlen (subdir);
+ if (subdir_len > 0 && subdir[subdir_len - 1] == G_DIR_SEPARATOR)
+ subdir[subdir_len - 1] = '\0';
+
+ /* When installing we simply copy anything in the pixmaps directory into
+ $(datadir)/pixmaps, if the pixmaps directory exists.
+ FIXME: The @$(NORMAL_INSTALL) line comes from the GNU Makefile
+ conventions, in the GNU coding standards info pages (under Releases).
+ Using DESTDIR also allows installation into 'staging areas'.
+ To comply fully the install commands should install to a particular file,
+ rather than a directory, and we should probably also have an uninstall
+ command. Kepp this in sync with source_write_gnome_makefile_am_... */
+ fprintf (fp,
+ "install-data-local:\n"
+ "\t@$(NORMAL_INSTALL)\n"
+ "\tif test -d $(srcdir)/%s; then \\\n"
+ "\t $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/pixmaps; \\\n"
+ "\t for pixmap in $(srcdir)/%s/*; do \\\n"
+ "\t if test -f $$pixmap; then \\\n"
+ "\t $(INSTALL_DATA) $$pixmap $(DESTDIR)$(pkgdatadir)/pixmaps; \\\n"
+ "\t fi \\\n"
+ "\t done \\\n"
+ "\tfi\n"
+ "\n",
+ subdir, subdir);
+
+ /* When building the distribution we simply copy anything in the pixmaps
+ directory into $(distdir)/subdir, if the pixmaps directory exists. */
+ fprintf (fp,
+ "dist-hook:\n"
+ "\tif test -d %s; then \\\n"
+ "\t mkdir $(distdir)/%s; \\\n"
+ "\t for pixmap in %s/*; do \\\n"
+ "\t if test -f $$pixmap; then \\\n"
+ "\t cp -p $$pixmap $(distdir)/%s; \\\n"
+ "\t fi \\\n"
+ "\t done \\\n"
+ "\tfi\n"
+ "\n",
+ subdir, subdir, subdir, subdir);
+
+ g_free (subdir);
+}
+
+
+/*
+ * Gnome build files.
+ */
+
+static void
+source_write_gnome_build_files (GbWidgetWriteSourceData * data)
+{
+ source_write_autogen_sh (data);
+ if (data->error)
+ return;
+
+ source_write_gnome_configure_in (data);
+ if (data->error)
+ return;
+
+ source_write_gnome_makefile_am (data);
+ if (data->error)
+ return;
+}
+
+
+static void
+source_write_gnome_configure_in (GbWidgetWriteSourceData * data)
+{
+ FILE *fp;
+ gchar *filename, *alt_filename, *source_subdir;
+
+ filename = glade_util_make_absolute_path (glade_project_get_directory (data->project), "configure.in");
+ alt_filename = glade_util_make_absolute_path (glade_project_get_directory (data->project), "configure.ac");
+
+ /* FIXME: If configure.in exists, just leave it, for now. */
+ if (glade_util_file_exists (filename)
+ || glade_util_file_exists (alt_filename))
+ {
+ g_free (filename);
+ g_free (alt_filename);
+ return;
+ }
+
+ g_free (alt_filename);
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ /* FIXME: Using AC_INIT(configure.in) is not really correct - we should be
+ using a file unique to the project. */
+ fprintf (fp,
+ "dnl Process this file with autoconf to produce a configure script.\n"
+ "\n"
+ "AC_INIT(configure.in)\n"
+ "AM_INIT_AUTOMAKE(%s, 0.1)\n"
+ "AM_MAINTAINER_MODE\n"
+ "AM_CONFIG_HEADER(config.h)\n"
+ "\n"
+ "AC_ISC_POSIX\n"
+ "AC_PROG_CC\n"
+ "AM_PROG_CC_STDC\n"
+ "AC_HEADER_STDC\n"
+ "\n",
+ data->program_name);
+
+ if (glade_project_get_gnome_db_support (data->project))
+ fprintf (fp, "pkg_modules=\"libgnomedb\"\n");
+ else
+ fprintf (fp, "pkg_modules=\"libgnomeui-2.0\"\n");
+
+ fprintf (fp,
+ "PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])\n"
+ "AC_SUBST(PACKAGE_CFLAGS)\n"
+ "AC_SUBST(PACKAGE_LIBS)\n"
+ "\n");
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp,
+ "GETTEXT_PACKAGE=%s\n"
+ "AC_SUBST(GETTEXT_PACKAGE)\n"
+ "AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,\"$GETTEXT_PACKAGE\", [Gettext package.])\n\n",
+ data->program_name);
+ fprintf (fp,
+ "dnl Add the languages which your application supports here.\n"
+ "ALL_LINGUAS=\"\"\n"
+ "AM_GLIB_GNU_GETTEXT\n"
+ "\n");
+ }
+
+ fprintf (fp,
+ "AC_OUTPUT([\n"
+ "Makefile\n");
+
+ source_subdir = source_get_source_subdirectory (data);
+ if (source_subdir)
+ {
+ fprintf (fp, "%s/Makefile\n", source_subdir);
+ g_free (source_subdir);
+ }
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp,
+ "po/Makefile.in\n");
+ }
+
+ fprintf (fp, "])\n\n");
+
+ fclose (fp);
+
+ g_free (filename);
+}
+
+
+static void
+source_write_gnome_makefile_am (GbWidgetWriteSourceData * data)
+{
+ FILE *fp;
+ gchar *directory, *source_directory, *filename, *program_name_as_target;
+ gboolean is_toplevel;
+
+ directory = glade_project_get_directory (data->project);
+ source_directory = glade_project_get_source_directory (data->project);
+
+ filename = glade_util_make_absolute_path (source_directory, "Makefile.am");
+
+ /* FIXME: If Makefile.am exists, just leave it, for now. */
+ if (glade_util_file_exists (filename))
+ {
+ g_free (filename);
+ return;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ fprintf (fp,
+ "## Process this file with automake to produce Makefile.in\n\n");
+
+ /* If the project directory is the source directory, we need to output
+ SUBDIRS here. */
+ is_toplevel = glade_util_directories_equivalent (directory,
+ source_directory);
+ if (is_toplevel)
+ {
+ if (glade_project_get_gettext_support (data->project))
+ fprintf (fp, "SUBDIRS = po\n\n");
+ }
+
+ fprintf (fp,
+ "INCLUDES = \\\n"
+ "\t-DPACKAGE_DATA_DIR=\\\"\"$(datadir)\"\\\" \\\n"
+ "\t-DPACKAGE_LOCALE_DIR=\\\"\"$(prefix)/$(DATADIRNAME)/locale\"\\\" \\\n"
+#ifdef GLADE_ADD_DISABLE_DEPRECATED_FLAGS
+ "\t-DG_DISABLE_DEPRECATED \\\n"
+ "\t-DGDK_DISABLE_DEPRECATED \\\n"
+ "\t-DGTK_DISABLE_DEPRECATED \\\n"
+ "\t-DGNOME_DISABLE_DEPRECATED \\\n"
+#endif
+ "\t@PACKAGE_CFLAGS@\n"
+ "\n");
+
+ program_name_as_target = g_strdup (data->program_name);
+ g_strdelimit (program_name_as_target, "-", '_');
+
+ fprintf (fp,
+ "bin_PROGRAMS = %s\n"
+ "\n",
+ data->program_name);
+
+ fprintf (fp,
+ "%s_SOURCES = \\\n",
+ program_name_as_target);
+
+ if (glade_project_get_output_main_file (data->project))
+ fprintf (fp, "\tmain.c \\\n");
+
+ if (glade_project_get_output_support_files (data->project))
+ {
+ fprintf (fp, "\t%s %s \\\n",
+ glade_project_get_support_source_file (data->project),
+ glade_project_get_support_header_file (data->project));
+ }
+
+ fprintf (fp,
+ "\t%s %s \\\n"
+ "\t%s %s\n\n",
+ g_basename (data->interface_c_filename),
+ g_basename (data->interface_h_filename),
+ g_basename (data->callback_c_filename),
+ g_basename (data->callback_h_filename));
+
+ fprintf (fp,
+ "%s_LDADD = @PACKAGE_LIBS@",
+ program_name_as_target);
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp, " $(INTLLIBS)");
+ }
+
+ fprintf (fp, "\n\n");
+
+ if (is_toplevel)
+ source_write_extra_dist (data, source_directory, fp);
+
+ source_write_gnome_makefile_am_pixmaps_targets (data, source_directory, fp);
+
+ fclose (fp);
+
+ g_free (program_name_as_target);
+ g_free (filename);
+}
+
+
+/* This outputs targets to install pixmaps and to include them in the
+ distribution, if the pixmaps are in a subdirectory of the given directory.
+*/
+static void
+source_write_gnome_makefile_am_pixmaps_targets (GbWidgetWriteSourceData * data,
+ gchar * directory,
+ FILE * fp)
+{
+ gchar *pixmaps_directory, *subdir;
+ gint subdir_len;
+
+ pixmaps_directory = glade_project_get_pixmaps_directory (data->project);
+
+ if (!glade_util_directory_contains_file (directory, pixmaps_directory))
+ return;
+
+ subdir = glade_util_make_relative_path (directory, pixmaps_directory);
+ subdir_len = strlen (subdir);
+ if (subdir_len > 0 && subdir[subdir_len - 1] == G_DIR_SEPARATOR)
+ subdir[subdir_len - 1] = '\0';
+
+ /* When installing we simply copy anything in the pixmaps directory into
+ $(datadir)/pixmaps, if the pixmaps directory exists. */
+ fprintf (fp,
+ "install-data-local:\n"
+ "\t@$(NORMAL_INSTALL)\n"
+ "\tif test -d $(srcdir)/%s; then \\\n"
+ "\t $(mkinstalldirs) $(DESTDIR)$(datadir)/pixmaps/$(PACKAGE); \\\n"
+ "\t for pixmap in $(srcdir)/%s/*; do \\\n"
+ "\t if test -f $$pixmap; then \\\n"
+ "\t $(INSTALL_DATA) $$pixmap $(DESTDIR)$(datadir)/pixmaps/$(PACKAGE); \\\n"
+ "\t fi \\\n"
+ "\t done \\\n"
+ "\tfi\n"
+ "\n",
+ subdir, subdir);
+
+ /* When building the distribution we simply copy anything in the pixmaps
+ directory into $(distdir)/subdir, if the pixmaps directory exists. */
+ fprintf (fp,
+ "dist-hook:\n"
+ "\tif test -d %s; then \\\n"
+ "\t mkdir $(distdir)/%s; \\\n"
+ "\t for pixmap in %s/*; do \\\n"
+ "\t if test -f $$pixmap; then \\\n"
+ "\t cp -p $$pixmap $(distdir)/%s; \\\n"
+ "\t fi \\\n"
+ "\t done \\\n"
+ "\tfi\n"
+ "\n",
+ subdir, subdir, subdir, subdir);
+
+ g_free (subdir);
+}
+
+
+/*
+ * Common build files.
+ */
+
+/* This creates the standard files that automake expects you to have,
+ i.e. NEWS, README, AUTHORS, ChangeLog.
+ If they already exist, they are left as they are. */
+static void
+source_write_common_build_files (GbWidgetWriteSourceData * data)
+{
+ gchar *directory;
+
+ directory = glade_project_get_directory (data->project);
+
+ source_write_toplevel_makefile_am (data);
+ if (data->error)
+ return;
+
+ data->error = source_create_file_if_not_exist (directory, "NEWS", NULL);
+ if (data->error)
+ return;
+
+ data->error = source_create_file_if_not_exist (directory, "README", NULL);
+ if (data->error)
+ return;
+
+ data->error = source_create_file_if_not_exist (directory, "AUTHORS", NULL);
+ if (data->error)
+ return;
+
+ data->error = source_create_file_if_not_exist (directory, "ChangeLog", NULL);
+ if (data->error)
+ return;
+
+ data->error = source_create_file_if_not_exist (directory, "stamp-h.in",
+ "timestamp\n");
+ if (data->error)
+ return;
+
+ source_write_po_files (data);
+ if (data->error)
+ return;
+
+#if 0
+ source_write_acconfig_h (data);
+#endif
+}
+
+
+/* This writes the toplevel Makefile.am, if the source directory is a
+ subdirectory of the project directory, and the Makefile.am doesn't already
+ exist. */
+static void
+source_write_toplevel_makefile_am (GbWidgetWriteSourceData * data)
+{
+ FILE *fp;
+ gchar *directory, *source_subdir, *filename;
+
+ directory = glade_project_get_directory (data->project);
+
+ /* If the source directory isn't a subdirectory of the project directory,
+ just return. */
+ source_subdir = source_get_source_subdirectory (data);
+ if (!source_subdir)
+ return;
+
+ filename = glade_util_make_absolute_path (directory, "Makefile.am");
+
+ /* FIXME: If Makefile.am exists, just leave it, for now. */
+ if (glade_util_file_exists (filename))
+ {
+ g_free (source_subdir);
+ g_free (filename);
+ return;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (source_subdir);
+ g_free (filename);
+ return;
+ }
+
+ fprintf (fp,
+ "## Process this file with automake to produce Makefile.in\n"
+ "\n"
+ "SUBDIRS = %s",
+ source_subdir);
+
+ if (glade_project_get_gettext_support (data->project))
+ fprintf (fp, " po");
+
+ fprintf (fp, "\n\n");
+
+ source_write_extra_dist (data, directory, fp);
+
+ if (glade_project_get_gnome_support (data->project))
+ source_write_gnome_makefile_am_pixmaps_targets (data, directory, fp);
+ else
+ source_write_gtk_makefile_am_pixmaps_targets (data, directory, fp);
+
+ fclose (fp);
+
+ g_free (source_subdir);
+ g_free (filename);
+}
+
+
+static void
+source_write_extra_dist (GbWidgetWriteSourceData * data,
+ const gchar *directory,
+ FILE *fp)
+{
+ gchar *xml_filename;
+
+ xml_filename = glade_project_get_xml_filename (data->project);
+
+ xml_filename = glade_util_make_relative_path (directory, xml_filename);
+
+ fprintf (fp,
+ "EXTRA_DIST = \\\n"
+ "\tautogen.sh \\\n"
+ "\t%s \\\n"
+ "\t%sp\n\n",
+ xml_filename, xml_filename);
+
+ g_free (xml_filename);
+}
+
+
+/* This creates an empty file in the given directory if it doesn't already
+ exist. It is used to create the empty NEWS, README, AUTHORS & ChangeLog. */
+static GladeError*
+source_create_file_if_not_exist (const gchar *directory,
+ const gchar *filename,
+ const gchar *contents)
+{
+ gchar *pathname;
+ FILE *fp;
+ GladeError *error = NULL;
+ gint bytes_written;
+
+ pathname = glade_util_make_absolute_path (directory, filename);
+
+ if (!glade_util_file_exists (pathname))
+ {
+ fp = glade_util_fopen (pathname, "w");
+ if (fp)
+ {
+ if (contents)
+ {
+ gint contents_len;
+
+ contents_len = strlen (contents);
+ bytes_written = fwrite (contents, 1, contents_len, fp);
+ if (bytes_written != contents_len)
+ {
+ error = glade_error_new_system (_("Error writing to file:\n %s\n"), pathname);
+ }
+ }
+
+ fclose (fp);
+ }
+ else
+ {
+ error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ pathname);
+ }
+ }
+ g_free (pathname);
+ return error;
+}
+
+
+/* This creates the initial po/POTFILES.in & po/ChangeLog if they don't exist.
+ If we don't create a ChangeLog the 'make dist' fails. */
+static void
+source_write_po_files (GbWidgetWriteSourceData * data)
+{
+ gchar *dirname = NULL, *filename = NULL, *prefix, *separator;
+ gint prefix_len;
+ FILE *fp;
+
+ /* Returns if gettext support isn't wanted. */
+ if (!glade_project_get_gettext_support (data->project))
+ return;
+
+ dirname = glade_util_make_absolute_path (glade_project_get_directory (data->project), "po");
+
+ /* Create the po directory if it doesn't exist. */
+ data->error = glade_util_ensure_directory_exists (dirname);
+ if (data->error)
+ {
+ g_free (dirname);
+ return;
+ }
+
+ /* Create ChangeLog if it doesn't exist. */
+ data->error = source_create_file_if_not_exist (dirname, "ChangeLog", NULL);
+ if (data->error)
+ {
+ g_free (dirname);
+ return;
+ }
+
+ /* FIXME: If POTFILES.in exists, just leave it, for now. */
+ filename = glade_util_make_absolute_path (dirname, "POTFILES.in");
+ if (glade_util_file_exists (filename))
+ {
+ g_free (dirname);
+ g_free (filename);
+ return;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (dirname);
+ g_free (filename);
+ return;
+ }
+
+ /* We need the relative path from the project directory to the source
+ directory, to prefix each source file. */
+ prefix = glade_util_make_relative_path (glade_project_get_directory (data->project), glade_project_get_source_directory (data->project));
+
+ /* See if we need a directory separator after the prefix. */
+ prefix_len = strlen (prefix);
+ if (prefix_len == 0 || prefix[prefix_len - 1] == G_DIR_SEPARATOR)
+ separator = "";
+ else
+ separator = G_DIR_SEPARATOR_S;
+
+ fprintf (fp, "# List of source files containing translatable strings.\n\n");
+
+ /* Add the main.c file if we are outputting it. */
+ if (glade_project_get_output_main_file (data->project))
+ fprintf (fp, "%s%s%s\n", prefix, separator, "main.c");
+
+ /* Add the interface.c & callbacks.c files. */
+ fprintf (fp,
+ "%s%s%s\n"
+ "%s%s%s\n",
+ prefix, separator, g_basename (data->interface_c_filename),
+ prefix, separator, g_basename (data->callback_c_filename));
+
+ /* Add the support.c file if we are outputting it. */
+ if (glade_project_get_output_support_files (data->project))
+ fprintf (fp, "%s%s%s\n", prefix, separator,
+ glade_project_get_support_source_file (data->project));
+
+ g_free (prefix);
+
+ fclose (fp);
+
+ g_free (dirname);
+ g_free (filename);
+}
+
+
+#if 0
+static void
+source_write_acconfig_h (GbWidgetWriteSourceData * data)
+{
+ FILE *fp;
+ gchar *filename;
+
+ filename = glade_util_make_absolute_path (glade_project_get_directory (data->project), "acconfig.h");
+
+ /* FIXME: If acconfig.h exists, just leave it, for now. */
+ if (glade_util_file_exists (filename))
+ {
+ g_free (filename);
+ return;
+ }
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ /* If we aren't using gettext or Gnome some of these may not be necessary,
+ but I don't think they cause problems. */
+ fprintf (fp,
+ "#undef ENABLE_NLS\n"
+ "#undef HAVE_CATGETS\n"
+ "#undef HAVE_GETTEXT\n"
+ "#undef GETTEXT_PACKAGE\n"
+ "#undef HAVE_LC_MESSAGES\n"
+ "#undef HAVE_STPCPY\n"
+ "#undef HAVE_LIBSM\n");
+ fclose (fp);
+
+ g_free (filename);
+}
+#endif
+
+
+/*************************************************************************
+ * Support Files.
+ *************************************************************************/
+
+/* We copy a file containing support functions into the project, and a
+ corresponding header.
+ Note that we do overwrite these, in case an old version is currently
+ being used. */
+static void
+source_write_support_files (GbWidgetWriteSourceData * data)
+{
+ gchar *filename;
+ FILE *fp;
+
+ /* If the support files aren't wanted, just return. */
+ if (!glade_project_get_output_support_files (data->project))
+ return;
+
+ /* Create the support header file first. */
+ filename = glade_util_make_absolute_path (glade_project_get_source_directory (data->project), glade_project_get_support_header_file (data->project));
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ source_write_no_editing_warning (fp);
+ source_write_preamble (data->project_name, fp);
+
+ if (glade_project_get_gnome_support (data->project))
+ {
+ fprintf (fp,
+ "#ifdef HAVE_CONFIG_H\n"
+ "# include <config.h>\n"
+ "#endif\n"
+ "\n"
+ "#include <gnome.h>\n\n");
+
+ if (glade_project_get_gettext_support (data->project))
+ {
+ /* bonobo-i18n.h doesn't include the Q_ macro so we add it here. */
+ fprintf (fp,
+ "#undef Q_\n"
+ "#ifdef ENABLE_NLS\n"
+ "# define Q_(String) g_strip_context ((String), gettext (String))\n"
+ "#else\n"
+ "# define Q_(String) g_strip_context ((String), (String))\n"
+ "#endif\n\n\n");
+ }
+ }
+ else
+ {
+ fprintf (fp,
+ "#ifdef HAVE_CONFIG_H\n"
+ "# include <config.h>\n"
+ "#endif\n"
+ "\n"
+ "#include <gtk/gtk.h>\n\n");
+
+ /* For GTK+ apps that want gettext support, we define the standard
+ macros here. */
+ if (glade_project_get_gettext_support (data->project))
+ {
+ fprintf (fp,
+ "/*\n"
+ " * Standard gettext macros.\n"
+ " */\n"
+ "#ifdef ENABLE_NLS\n"
+ "# include <libintl.h>\n"
+ "# undef _\n"
+ "# define _(String) dgettext (PACKAGE, String)\n"
+ "# define Q_(String) g_strip_context ((String), gettext (String))\n"
+ "# ifdef gettext_noop\n"
+ "# define N_(String) gettext_noop (String)\n"
+ "# else\n"
+ "# define N_(String) (String)\n"
+ "# endif\n"
+ "#else\n"
+ "# define textdomain(String) (String)\n"
+ "# define gettext(String) (String)\n"
+ "# define dgettext(Domain,Message) (Message)\n"
+ "# define dcgettext(Domain,Message,Type) (Message)\n"
+ "# define bindtextdomain(Domain,Directory) (Domain)\n"
+ "# define _(String) (String)\n"
+ "# define Q_(String) g_strip_context ((String), (String))\n"
+ "# define N_(String) (String)\n"
+ "#endif\n\n\n");
+ }
+ }
+
+ fprintf (fp,
+ "/*\n"
+ " * Public Functions.\n"
+ " */\n"
+ "\n");
+
+ if (!data->use_component_struct)
+ {
+ fprintf (fp,
+ "/*\n"
+ " * This function returns a widget in a component created by Glade.\n"
+ " * Call it with the toplevel widget in the component (i.e. a window/dialog),\n"
+ " * or alternatively any widget in the component, and the name of the widget\n"
+ " * you want returned.\n"
+ " */\n"
+ "GtkWidget* lookup_widget (GtkWidget *widget,\n"
+ " const gchar *widget_name);\n"
+ "\n"
+ "\n");
+ }
+
+ /* Gnome has its own function for looking for pixmaps, so we don't need this
+ one. */
+ if (!glade_project_get_gnome_support (data->project))
+ {
+ fprintf (fp,
+ "/* Use this function to set the directory containing installed pixmaps. */\n"
+ "void add_pixmap_directory (const gchar *directory);\n"
+ "\n");
+ }
+
+ fprintf (fp,
+ "\n"
+ "/*\n"
+ " * Private Functions.\n"
+ " */\n"
+ "\n");
+
+ fprintf (fp,
+ "/* This is used to create the pixmaps used in the interface. */\n"
+ "GtkWidget* create_pixmap (GtkWidget *widget,\n"
+ " const gchar *filename);\n"
+ "\n");
+
+ fprintf (fp,
+ "/* This is used to create the pixbufs used in the interface. */\n"
+ "GdkPixbuf* create_pixbuf (const gchar *filename);\n"
+ "\n");
+
+ fprintf (fp,
+ "/* This is used to set ATK action descriptions. */\n"
+ "void glade_set_atk_action_description (AtkAction *action,\n"
+ " const gchar *action_name,\n"
+ " const gchar *description);\n"
+ "\n");
+
+ fclose (fp);
+
+ g_free (filename);
+
+
+ /* Now create the support source file. */
+ filename = glade_util_make_absolute_path (glade_project_get_source_directory (data->project), glade_project_get_support_source_file (data->project));
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ {
+ data->error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ filename);
+ g_free (filename);
+ return;
+ }
+
+ source_write_no_editing_warning (fp);
+ source_write_preamble (data->project_name, fp);
+ source_write_include_files (fp);
+
+ if (glade_project_get_gnome_support (data->project))
+ fprintf (fp, "#include <gnome.h>\n\n");
+ else
+ fprintf (fp, "#include <gtk/gtk.h>\n\n");
+
+ fprintf (fp, "#include \"%s\"\n\n",
+ glade_project_get_support_header_file (data->project));
+
+ /* Write a function to get a widget from the component's hash. */
+ if (!data->use_component_struct)
+ {
+ fprintf (fp,
+ "GtkWidget*\n"
+ "lookup_widget (GtkWidget *widget,\n"
+ " const gchar *widget_name)\n"
+ "{\n"
+ " GtkWidget *parent, *found_widget;\n"
+ "\n"
+ " for (;;)\n"
+ " {\n"
+ " if (GTK_IS_MENU (widget))\n"
+ " parent = gtk_menu_get_attach_widget (GTK_MENU (widget));\n"
+ " else\n"
+ " parent = gtk_widget_get_parent (widget);\n"
+ " if (!parent)\n"
+ " parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), \"GladeParentKey\");\n"
+ " if (parent == NULL)\n"
+ " break;\n"
+ " widget = parent;\n"
+ " }\n"
+ "\n"
+ " found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),\n"
+ " widget_name);\n"
+ " if (!found_widget)\n"
+ " g_warning (\"Widget not found: %%s\", widget_name);\n"
+ " return found_widget;\n"
+ "}\n\n");
+ }
+
+ if (glade_project_get_gnome_support (data->project))
+ {
+ source_write_gnome_create_pixmap_functions (data, fp);
+ }
+ else
+ {
+ source_write_gtk_create_pixmap_functions (data, fp);
+ }
+
+ /* Output the support function to set AtkAction descriptions. */
+ fprintf (fp,
+ "/* This is used to set ATK action descriptions. */\n"
+ "void\n"
+ "glade_set_atk_action_description (AtkAction *action,\n"
+ " const gchar *action_name,\n"
+ " const gchar *description)\n"
+ "{\n"
+ " gint n_actions, i;\n"
+ "\n"
+ " n_actions = atk_action_get_n_actions (action);\n"
+ " for (i = 0; i < n_actions; i++)\n"
+ " {\n"
+ " if (!strcmp (atk_action_get_name (action, i), action_name))\n"
+ " atk_action_set_description (action, i, description);\n"
+ " }\n"
+ "}\n\n");
+
+ fclose (fp);
+
+ g_free (filename);
+}
+
+
+static void
+source_write_gtk_create_pixmap_functions (GbWidgetWriteSourceData * data,
+ FILE *fp)
+{
+ /*
+ * Write a function used to set the installed pixmaps directory.
+ */
+ fprintf (fp,
+ "static GList *pixmaps_directories = NULL;\n"
+ "\n"
+ "/* Use this function to set the directory containing installed pixmaps. */\n"
+ "void\n"
+ "add_pixmap_directory (const gchar *directory)\n"
+ "{\n"
+ " pixmaps_directories = g_list_prepend (pixmaps_directories,\n"
+ " g_strdup (directory));\n"
+ "}\n\n");
+
+ /*
+ * Write a function used to find pixmap files. It returns the full pathname
+ * of the found pixmap file, or NULL if it wasn't found.
+ */
+ fprintf (fp,
+ "/* This is an internally used function to find pixmap files. */\n"
+ "static gchar*\n"
+ "find_pixmap_file (const gchar *filename)\n"
+ "{\n"
+ " GList *elem;\n"
+ "\n");
+
+ fprintf (fp,
+ " /* We step through each of the pixmaps directory to find it. */\n"
+ " elem = pixmaps_directories;\n"
+ " while (elem)\n"
+ " {\n"
+ " gchar *pathname = g_strdup_printf (\"%%s%%s%%s\", (gchar*)elem->data,\n"
+ " G_DIR_SEPARATOR_S, filename);\n"
+ " if (g_file_test (pathname, G_FILE_TEST_EXISTS))\n"
+ " return pathname;\n"
+ " g_free (pathname);\n"
+ " elem = elem->next;\n"
+ " }\n"
+ " return NULL;\n"
+ "}\n\n");
+
+
+
+ /*
+ * Write a function used for creating GtkImage widgets from pixmap files.
+ * It will return an unset GtkImage if the pixmap file isn't found, so the
+ * application will still run. Though it will output a warning if the
+ * pixmap filename was set but wasn't found.
+ */
+ fprintf (fp,
+ "/* This is an internally used function to create pixmaps. */\n"
+ "GtkWidget*\n"
+ "create_pixmap (GtkWidget *widget,\n"
+ " const gchar *filename)\n"
+ "{\n"
+ " gchar *pathname = NULL;\n"
+ " GtkWidget *pixmap;\n"
+ "\n");
+
+ /* The developer may not have finished the interface yet, so we handle
+ the filename not being set. */
+ fprintf (fp,
+ " if (!filename || !filename[0])\n"
+ " return gtk_image_new ();\n"
+ "\n");
+
+ fprintf (fp,
+ " pathname = find_pixmap_file (filename);\n"
+ "\n");
+
+ fprintf (fp,
+ " if (!pathname)\n"
+ " {\n"
+ " g_warning (%s, filename);\n"
+ " return gtk_image_new ();\n"
+ " }\n"
+ "\n",
+ source_make_string ("Couldn't find pixmap file: %s",
+ data->use_gettext));
+
+ fprintf (fp,
+ " pixmap = gtk_image_new_from_file (pathname);\n"
+ " g_free (pathname);\n"
+ " return pixmap;\n"
+ "}\n\n");
+
+
+
+ /*
+ * Write a function used for creating GdkPixbufs from pixmap files.
+ * It will return NULL if the pixmap file isn't found, so any calls to this
+ * function may need to handle that. It will output a warning if the
+ * pixmap filename was set but wasn't found.
+ */
+ fprintf (fp,
+ "/* This is an internally used function to create pixmaps. */\n"
+ "GdkPixbuf*\n"
+ "create_pixbuf (const gchar *filename)\n"
+ "{\n"
+ " gchar *pathname = NULL;\n"
+ " GdkPixbuf *pixbuf;\n"
+ " GError *error = NULL;\n"
+ "\n");
+
+ /* The developer may not have finished the interface yet, so we handle
+ the filename not being set. */
+ fprintf (fp,
+ " if (!filename || !filename[0])\n"
+ " return NULL;\n"
+ "\n");
+
+ fprintf (fp,
+ " pathname = find_pixmap_file (filename);\n"
+ "\n");
+
+ fprintf (fp,
+ " if (!pathname)\n"
+ " {\n"
+ " g_warning (%s, filename);\n"
+ " return NULL;\n"
+ " }\n"
+ "\n",
+ source_make_string ("Couldn't find pixmap file: %s",
+ data->use_gettext));
+
+ fprintf (fp,
+ " pixbuf = gdk_pixbuf_new_from_file (pathname, &error);\n"
+ " if (!pixbuf)\n"
+ " {\n"
+ " fprintf (stderr, \"Failed to load pixbuf file: %%s: %%s\\n\",\n"
+ " pathname, error->message);\n"
+ " g_error_free (error);\n"
+ " }\n"
+ " g_free (pathname);\n"
+ " return pixbuf;\n"
+ "}\n\n");
+}
+
+
+static void
+source_write_gnome_create_pixmap_functions (GbWidgetWriteSourceData * data,
+ FILE *fp)
+{
+ /*
+ * Write a function used for creating GtkImage widgets from pixmap files.
+ * It will return an unset GtkImage if the pixmap file isn't found, so the
+ * application will still run. Though it will output a warning if the
+ * pixmap filename was set but wasn't found.
+ */
+ fprintf (fp,
+ "/* This is an internally used function to create pixmaps. */\n"
+ "GtkWidget*\n"
+ "create_pixmap (GtkWidget *widget,\n"
+ " const gchar *filename)\n"
+ "{\n"
+ " GtkWidget *pixmap;\n"
+ " gchar *pathname;\n"
+ "\n");
+
+ /* The developer may not have finished the interface yet, so we handle
+ the filename not being set. */
+ fprintf (fp,
+ " if (!filename || !filename[0])\n"
+ " return gtk_image_new ();\n"
+ "\n");
+
+ fprintf (fp,
+ " pathname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP,\n"
+ " filename, TRUE, NULL);\n"
+ " if (!pathname)\n"
+ " {\n"
+ " g_warning (%s, filename);\n"
+ " return gtk_image_new ();\n"
+ " }\n"
+ "\n",
+ source_make_string ("Couldn't find pixmap file: %s",
+ data->use_gettext));
+
+ fprintf (fp,
+ " pixmap = gtk_image_new_from_file (pathname);\n"
+ " g_free (pathname);\n"
+ " return pixmap;\n"
+ "}\n"
+ "\n");
+
+
+ /*
+ * Write a function used for creating GdkPixbufs from pixmap files.
+ * It will return NULL if the pixmap file isn't found, so any calls to this
+ * function may need to handle that. It will output a warning if the
+ * pixmap filename was set but wasn't found.
+ */
+ fprintf (fp,
+ "/* This is an internally used function to create pixmaps. */\n"
+ "GdkPixbuf*\n"
+ "create_pixbuf (const gchar *filename)\n"
+ "{\n"
+ " gchar *pathname = NULL;\n"
+ " GdkPixbuf *pixbuf;\n"
+ " GError *error = NULL;\n"
+ "\n");
+
+ /* The developer may not have finished the interface yet, so we handle
+ the filename not being set. */
+ fprintf (fp,
+ " if (!filename || !filename[0])\n"
+ " return NULL;\n"
+ "\n");
+
+ fprintf (fp,
+ " pathname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP,\n"
+ " filename, TRUE, NULL);\n"
+ "\n");
+
+ fprintf (fp,
+ " if (!pathname)\n"
+ " {\n"
+ " g_warning (%s, filename);\n"
+ " return NULL;\n"
+ " }\n"
+ "\n",
+ source_make_string ("Couldn't find pixmap file: %s",
+ data->use_gettext));
+
+ fprintf (fp,
+ " pixbuf = gdk_pixbuf_new_from_file (pathname, &error);\n"
+ " if (!pixbuf)\n"
+ " {\n"
+ " fprintf (stderr, \"Failed to load pixbuf file: %%s: %%s\\n\",\n"
+ " pathname, error->message);\n"
+ " g_error_free (error);\n"
+ " }\n"
+ " g_free (pathname);\n"
+ " return pixbuf;\n"
+ "}\n\n");
+}
+
+
+/*************************************************************************
+ * Public Functions.
+ *************************************************************************/
+
+/* Adds some source code to one of the buffers, using printf-like format
+ and arguments. */
+void
+source_add_to_buffer (GbWidgetWriteSourceData * data,
+ GladeSourceBuffer buffer,
+ const gchar *fmt,
+ ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ source_add_to_buffer_v (data, buffer, fmt, args);
+ va_end (args);
+}
+
+
+/* A va_list implementation of the above. */
+void
+source_add_to_buffer_v (GbWidgetWriteSourceData * data,
+ GladeSourceBuffer buffer,
+ const gchar *fmt,
+ va_list args)
+{
+ gchar *buf;
+
+ buf = g_strdup_vprintf (fmt, args);
+ g_string_append (data->source_buffers[buffer], buf);
+ g_free (buf);
+}
+
+
+/* Convenience functions to add to the 2 main source buffers, containing
+ the code which creates the widgets and the declarations of the widgets. */
+void
+source_add (GbWidgetWriteSourceData * data, const gchar * fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ source_add_to_buffer_v (data, GLADE_SOURCE, fmt, args);
+ va_end (args);
+}
+
+
+void
+source_add_translator_comments (GbWidgetWriteSourceData *data,
+ gboolean translatable,
+ const gchar *comments)
+{
+ /* If the property isn't being translated we don't bother outputting the
+ translator comments. */
+ if (!translatable || !comments || comments[0] == '\0')
+ return;
+
+ /* We simply output it in a C comment.
+ FIXME: If the comments contain an end of comment marker it won't
+ compile. */
+ source_add (data, " /* %s */\n", comments);
+}
+
+
+void
+source_add_translator_comments_to_buffer (GbWidgetWriteSourceData *data,
+ GladeSourceBuffer buffer,
+ gboolean translatable,
+ const gchar *comments)
+{
+ /* If the property isn't being translated we don't bother outputting the
+ translator comments. */
+ if (!translatable || !comments || comments[0] == '\0')
+ return;
+
+ /* We simply output it in a C comment.
+ FIXME: If the comments contain an end of comment marker it won't
+ compile. */
+ source_add_to_buffer (data, buffer, " /* %s */\n", comments);
+}
+
+
+void
+source_add_decl (GbWidgetWriteSourceData * data, const gchar * fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ source_add_to_buffer_v (data, GLADE_DECLARATIONS, fmt, args);
+ va_end (args);
+}
+
+
+/* This ensures that a temporary variable is declared, by adding the given
+ declaration if it has not already been added. */
+void
+source_ensure_decl (GbWidgetWriteSourceData *data,
+ const gchar *decl)
+{
+ if (!glade_util_strstr (data->source_buffers[GLADE_DECLARATIONS]->str, decl))
+ source_add_decl (data, decl);
+}
+
+
+/* This creates a valid C identifier from a given string (usually the name of
+ a widget or a signal handler function name). Currently all we do is convert
+ any illegal characters to underscores.
+ The returned string should be freed when no longer needed. */
+gchar *
+source_create_valid_identifier (const gchar * name)
+{
+ gint name_len, i, j;
+ gchar *identifier;
+
+ name_len = strlen (name);
+ /* allocate extra space for _ prefix if the identifier starts with
+ a number */
+ identifier = g_malloc (name_len + 2);
+ j = 1;
+
+ /* The first character of an identifier must be in [a-zA-Z_] */
+ if ((name[0] >= 'a' && name[0] <= 'z')
+ || (name[0] >= 'A' && name[0] <= 'Z')
+ || name[0] == '_')
+ identifier[0] = name[0];
+ else
+ {
+ if (name[0] >= '0' && name[0] <= '9')
+ {
+ /* prepend the _ instead of overwriting, so you'll still have
+ unique names */
+ identifier[0] = '_';
+ identifier[1] = name[0];
+ j++;
+ }
+ else
+ identifier[0] = '_';
+ }
+
+ /* The remaining characters must be in [a-zA-Z0-9_] */
+ for (i = 1; i < name_len; i++, j++)
+ {
+ if ((name[i] >= 'a' && name[i] <= 'z')
+ || (name[i] >= 'A' && name[i] <= 'Z')
+ || (name[i] >= '0' && name[i] <= '9')
+ || name[i] == '_')
+ identifier[j] = name[i];
+ else
+ identifier[j] = '_';
+ }
+
+ identifier[j] = '\0';
+
+ return identifier;
+}
+
+
+/* This converts a string so that it can be output as part of the C source
+ * code. It converts non-printable characters to escape codes.
+ * Note that it uses one dynamically allocated buffer, so the result is only
+ * valid until the next call to the function.
+ *
+ * FIXME: There is a limit to the length of literal strings in ANSI C - ~500
+ * chars. What should we do when that is exceeded?
+ */
+gchar *
+source_make_string (const gchar * text,
+ gboolean translatable)
+{
+ return source_make_string_internal (text, translatable, FALSE, FALSE);
+}
+
+
+gchar *
+source_make_string_full (const gchar * text,
+ gboolean translatable,
+ gboolean context)
+{
+ return source_make_string_internal (text, translatable, FALSE, context);
+}
+
+
+gchar *
+source_make_static_string (const gchar * text,
+ gboolean translatable)
+{
+ return source_make_string_internal (text, translatable, TRUE, FALSE);
+}
+
+
+/* This converts a string so that it can be output as part of the C source
+ * code. It converts non-printable characters to escape codes.
+ * If is_static is TRUE it uses "N_" to mark translatable strings.
+ * Note that it uses one dynamically allocated buffer, so the result is only
+ * valid until the next call to the function.
+ */
+static gchar *
+source_make_string_internal (const gchar * text,
+ gboolean translatable,
+ gboolean is_static,
+ gboolean context)
+{
+ static GString *buffer = NULL;
+
+ gchar escape_buffer[16];
+ const gchar *p;
+
+ /* If the text is empty, we return an empty string without the _ macro. */
+ if (!text || text[0] == '\0')
+ return "\"\"";
+
+ /* Create the buffer if it hasn't already been created. */
+ if (buffer == NULL)
+ {
+ buffer = g_string_sized_new (1024);
+ }
+
+ /* Clear any previous string. */
+ g_string_truncate (buffer, 0);
+
+ /* Output the C code to start the string. */
+ if (translatable)
+ {
+ /* Static "N_" overrides any context setting, though they shouldn't
+ really both be passed in as TRUE anyway. */
+ if (is_static)
+ g_string_append (buffer, "N_(\"");
+ else if (context)
+ g_string_append (buffer, "Q_(\"");
+ else
+ g_string_append (buffer, "_(\"");
+ }
+ else
+ {
+ g_string_append (buffer, "\"");
+ }
+
+ /* Step through each character of the given string, adding it to our GString
+ buffer, converting it so that it is valid in a literal C string. */
+ for (p = text; *p; p++)
+ {
+ switch (*p)
+ {
+ case '\n':
+ g_string_append (buffer, "\\n");
+ break;
+ case '\r':
+ g_string_append (buffer, "\\r");
+ break;
+ case '\t':
+ g_string_append (buffer, "\\t");
+ break;
+ case '\\':
+ g_string_append (buffer, "\\\\");
+ break;
+ case '"':
+ g_string_append (buffer, "\\\"");
+ break;
+ default:
+ if (isprint (*p))
+ {
+ g_string_append_c (buffer, *p);
+ }
+ else
+ {
+ sprintf (escape_buffer, "\\%02o", (guchar) *p);
+ g_string_append (buffer, escape_buffer);
+ }
+ break;
+ }
+ }
+
+ /* Output the C code to end the string. */
+ g_string_append (buffer, translatable ? "\")" : "\"");
+
+ return buffer->str;
+}
+
+
+/* This outputs code to create a GtkImage widget with the given identifier,
+ and using the given filename (only the basename is used). If filename NULL
+ or "" an empty GtkImage is created. */
+void
+source_create_pixmap (GbWidgetWriteSourceData * data,
+ const gchar * identifier,
+ const gchar * filename)
+{
+ gboolean empty_filename = FALSE;
+
+ if (!filename || filename[0] == '\0')
+ empty_filename = TRUE;
+
+ /* We use the basename of the pixmap file. The create_pixmap() support
+ function is responsible for finding the pixmap.
+ If it can't find the pixmap, it outputs a warning messages and returns
+ a simple dummy pixmap, so that the app can continue without crashing. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+ /* FIXME: Should convert filename to a valid C string? */
+ if (!empty_filename)
+ source_add (data, " %s = create_pixmap (%s, \"%s/%s\");\n",
+ identifier, data->component_name,
+ data->program_name, g_basename (filename));
+ else
+ source_add (data, " %s = create_pixmap (%s, NULL);\n",
+ identifier, data->component_name);
+ }
+ else
+ {
+ if (!empty_filename)
+ source_add (data, " %s = create_pixmap (%s, \"%s\");\n",
+ identifier, data->component_name, g_basename (filename));
+ else
+ source_add (data, " %s = create_pixmap (%s, NULL);\n",
+ identifier, data->component_name);
+ }
+}
+
+
+/* This outputs code to create a GdkPixbuf with the given identifier,
+ and using the given filename (only the basename is used). filename must not
+ be NULL or "". */
+void
+source_create_pixbuf (GbWidgetWriteSourceData * data,
+ const gchar * identifier,
+ const gchar * filename)
+{
+ g_return_if_fail (filename && filename[0]);
+
+ /* We use the basename of the pixmap file. The create_pixmap() support
+ function is responsible for finding the pixmap.
+ If it can't find the pixmap, it outputs a warning messages and returns
+ a simple dummy pixmap, so that the app can continue without crashing. */
+ if (glade_project_get_gnome_support (data->project))
+ {
+ /* FIXME: Should convert filename to a valid C string? */
+ source_add (data, " %s = create_pixbuf (\"%s/%s\");\n",
+ identifier, data->program_name, g_basename (filename));
+ }
+ else
+ {
+ source_add (data, " %s = create_pixbuf (\"%s\");\n",
+ identifier, g_basename (filename));
+ }
+}
+
+
+/*************************************************************************
+ * Utility Functions.
+ *************************************************************************/
+
+/* This empties all the source code buffers, but doesn't free them. */
+static void
+source_reset_code_buffers (GbWidgetWriteSourceData * data)
+{
+ gint i;
+
+ for (i = 0; i < GLADE_NUM_SOURCE_BUFFERS; i++)
+ g_string_truncate (data->source_buffers[i], 0);
+}
+
+
+/* A callback used to free the 'standard widgets' (widgets we use to determine
+ default property values) when iterating over their GHashTable. */
+static void
+source_destroy_standard_widgets_callback (gchar * key, GtkWidget * widget,
+ gpointer data)
+{
+ gtk_widget_destroy (widget);
+}
+
+
+/* A callback used to free GHashTable keys when iterating over them */
+static void
+source_free_hash_keys_callback (gchar * key, gpointer value, gpointer data)
+{
+ g_free (key);
+}
+
+
+/* Checks if the given file is a valid source filename, i.e. not NULL and
+ not absolute. If not it returns an appropriate error message. */
+static gchar*
+source_is_valid_source_filename (const gchar * filename)
+{
+ if (filename == NULL || filename[0] == '\0')
+ return _("The filename must be set in the Project Options dialog.");
+
+ if (g_path_is_absolute (filename))
+ return _("The filename must be a simple relative filename.\n"
+ "Use the Project Options dialog to set it.");
+
+ return NULL;
+}
+
+
+/* Checks if the given file exists, and if so renames it to file.bak. */
+static GladeError*
+source_backup_file_if_exists (const gchar * filename)
+{
+ GladeError *error = NULL;
+ gchar *backup_filename;
+ int status;
+
+ if (glade_util_file_exists (filename))
+ {
+ backup_filename = g_strdup_printf ("%s.bak", filename);
+#if defined (__EMX__) || defined (_WIN32)
+ remove (backup_filename);
+#endif
+ status = rename (filename, backup_filename);
+
+ if (status == -1)
+ {
+ error = glade_error_new_system (_("Couldn't rename file:\n %s\nto:\n %s\n"), filename, backup_filename);
+ }
+ g_free (backup_filename);
+ }
+ return error;
+}
+
+
+/* This returns the relative path from the project directory to the source
+ directory, or NULL if the source directory is the project directory.
+ The returned string will not have any trailing '/', and should be freed
+ when no longer needed. */
+static gchar*
+source_get_source_subdirectory (GbWidgetWriteSourceData * data)
+{
+ gchar *directory, *source_directory, *subdir;
+ gint subdir_len;
+
+ directory = glade_project_get_directory (data->project);
+ source_directory = glade_project_get_source_directory (data->project);
+
+ /* Check if the source directory is a subdirectory of the project directory.
+ */
+ if (!glade_util_directory_contains_file (directory, source_directory))
+ return NULL;
+
+ subdir = glade_util_make_relative_path (directory, source_directory);
+ subdir_len = strlen (subdir);
+ if (subdir_len > 0 && subdir[subdir_len - 1] == G_DIR_SEPARATOR)
+ subdir[subdir_len - 1] = '\0';
+
+ return subdir;
+}
+
+
+/* Outputs a warning to the given file, telling the user not to edit the file
+ since it is generated by Glade. */
+static void
+source_write_no_editing_warning (FILE *fp)
+{
+ /*
+ * Output a 3-line comment like this one, makes it easy for translators.
+ * Actually I've turned translation off now, as UTF-8 may cause problems
+ * in the C code. See bug #95435.
+ */
+ fprintf (fp, "/*\n * %s\n */\n\n",
+ "DO NOT EDIT THIS FILE - it is generated by Glade.");
+}
diff --git a/tools/glade/glade/source.h b/tools/glade/glade/source.h
new file mode 100644
index 00000000..69f76338
--- /dev/null
+++ b/tools/glade/glade/source.h
@@ -0,0 +1,113 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_SOURCE_H
+#define GLADE_SOURCE_H
+
+#include "gbwidget.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* This is the main function for writing C source output for an application,
+ and is called from glade_project_write_c_source().
+ If an error occurs, a GladeError is returned which should be freed with
+ glade_error_free() when no longer needed. */
+GladeError* source_write (GladeProject *project);
+
+
+/* Adds some source code to one of the buffers, using printf-like format
+ and arguments. */
+void source_add_to_buffer (GbWidgetWriteSourceData *data,
+ GladeSourceBuffer buffer,
+ const gchar *fmt,
+ ...) G_GNUC_PRINTF (3, 4);
+
+/* A va_list implementation of the above. */
+void source_add_to_buffer_v (GbWidgetWriteSourceData *data,
+ GladeSourceBuffer buffer,
+ const gchar *fmt,
+ va_list args);
+
+/* Convenience functions to add to the 2 main source buffers, containing
+ the code which creates the widgets and the declarations of the widgets. */
+void source_add (GbWidgetWriteSourceData *data,
+ const gchar *fmt,
+ ...) G_GNUC_PRINTF (2, 3);
+void source_add_decl (GbWidgetWriteSourceData *data,
+ const gchar *fmt,
+ ...) G_GNUC_PRINTF (2, 3);
+
+/* This ensures that a temporary variable is declared, by adding the given
+ declaration if it has not already been added. */
+void source_ensure_decl (GbWidgetWriteSourceData *data,
+ const gchar *decl);
+
+/* This outputs the comments string as a C comment if translatable is set.
+ It is intended to be used for comments to be picked up by gettext. */
+void source_add_translator_comments (GbWidgetWriteSourceData *data,
+ gboolean translatable,
+ const gchar *comments);
+void source_add_translator_comments_to_buffer (GbWidgetWriteSourceData *data,
+ GladeSourceBuffer buffer,
+ gboolean translatable,
+ const gchar *comments);
+
+/* This creates a valid C identifier from a given string (usually the name of
+ a widget). The returned string should be freed when no longer needed. */
+gchar* source_create_valid_identifier (const gchar *name);
+
+/* This creates a string literal to place into the source code, using the
+ given text, and includes the quotation marks, e.g. "Hello World".
+ If translatable is TRUE, it also uses the gettext macro,
+ e.g. _("Hello World"). The returned string is only valid until the next
+ call to the function (since the same buffer is used). */
+gchar* source_make_string (const gchar *text,
+ gboolean translatable);
+
+/* This is like source_make_string, but if context is set it uses the Q_
+ macro which will call g_strip_context() from the translated string. */
+gchar * source_make_string_full (const gchar *text,
+ gboolean translatable,
+ gboolean context);
+
+/* This is similar to source_make_string, but when using gettext it uses "N_"
+ so it should be used when strings are used in structs. */
+gchar* source_make_static_string (const gchar *text,
+ gboolean translatable);
+
+/* This outputs code to create a GtkImage widget with the given identifier,
+ and using the given filename (only the basename is used). If filename NULL
+ or "" an empty GtkImage is created. */
+void source_create_pixmap (GbWidgetWriteSourceData * data,
+ const gchar * identifier,
+ const gchar * filename);
+
+/* This outputs code to create a GdkPixbuf with the given identifier,
+ and using the given filename (only the basename is used). filename must not
+ be NULL or "". */
+void source_create_pixbuf (GbWidgetWriteSourceData * data,
+ const gchar * identifier,
+ const gchar * filename);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_SOURCE_H */
diff --git a/tools/glade/glade/source_os2.c b/tools/glade/glade/source_os2.c
new file mode 100644
index 00000000..fa988a27
--- /dev/null
+++ b/tools/glade/glade/source_os2.c
@@ -0,0 +1,116 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#include <locale.h>
+
+#include "gladeconfig.h"
+
+#include "gbwidget.h"
+#include "glade_project.h"
+#include "source.h"
+#include "utils.h"
+#ifdef HAVE_OS2_H
+
+extern FILE * create_file_if_not_exist (gchar *filename,
+ GladeStatusCode *status);
+
+static void source_write_makefile_simple (gchar *makefilename)
+{
+ FILE *fp;
+
+ if (glade_util_file_exists (makefilename))
+ return;
+
+ fp = glade_util_fopen (makefilename, "wt");
+ if (fp == NULL)
+ return;
+
+ fprintf (fp,"#\n");
+ fprintf (fp,"# This is an example makefile for OS/2\n");
+ fprintf (fp,"#\n");
+ fprintf (fp,"CC=gcc\n");
+ fprintf (fp,"GTKLIBS=-L$(X11ROOT)/XFree86/lib -lgtk -lgdk -lglib\n");
+#ifdef USE_GNOME
+ fprintf (fp,"GNOMELIBS=-lgnome -lgnomeui -lgdk_imlib\n");
+ fprintf (fp,"PACK=-DPACKAGE=\\\"gladtst\\\" -DVERSION=\\\"0.0.1\\\"\n");
+#endif
+ fprintf (fp,"DIRS=-DPACKAGE_DATA_DIR=\\\".\\\" -DPACKAGE_SOURCE_DIR=\\\".\\\"\n");
+ fprintf (fp,"OBJS=main.o support.o interface.o callbacks.o\n");
+ fprintf (fp,"CFLAGS=-Zmtd -D__ST_MT_ERRNO__ -I. -I$(X11ROOT)/XFree86/include");
+ fprintf (fp," $(DIRS)");
+#ifdef USE_GNOME
+ fprintf (fp," $(PACK)");
+#endif
+ fprintf (fp," \n");
+ fprintf (fp,"\n");
+ fprintf (fp,"all: gladetst.exe\n");
+ fprintf (fp,"\n");
+ fprintf (fp,"%%.o : %%.c\n");
+ fprintf (fp,"\t$(CC) $(CFLAGS) -c $<\n");
+ fprintf (fp,"\n");
+ fprintf (fp,"gladetst.exe: $(OBJS)\n");
+ fprintf (fp,"\t$(CC) -Zmtd -o $@ $(OBJS) $(GTKLIBS)");
+#ifdef USE_GNOME
+ fprintf (fp," $(GNOMELIBS)");
+#endif
+ fprintf (fp," gladetst.def\n");
+ fclose (fp);
+}
+
+static void source_write_os2_def_file (gchar *filename)
+{
+ FILE *fp;
+
+ if (glade_util_file_exists (filename))
+ return;
+
+ fp = glade_util_fopen (filename, "w");
+ if (fp == NULL)
+ return;
+
+ fprintf (fp,"NAME gladetst WINDOWCOMPAT\n");
+ fprintf (fp,"HEAPSIZE 0x10000\n");
+ fprintf (fp,"STACKSIZE 0x10000\n");
+ fclose (fp);
+}
+
+void source_write_os2_files(GbWidgetWriteSourceData * data)
+{
+ gchar *directory;
+ gchar *filename;
+
+ directory = glade_project_get_source_directory (data->project);
+
+ filename = glade_util_make_absolute_path (directory, "makefile.os2");
+ source_write_makefile_simple (filename);
+ g_free (filename);
+
+ filename = glade_util_make_absolute_path (directory, "gladetst.def");
+ source_write_os2_def_file (filename);
+ g_free (filename);
+}
+#endif
diff --git a/tools/glade/glade/source_os2.h b/tools/glade/glade/source_os2.h
new file mode 100644
index 00000000..c93f0145
--- /dev/null
+++ b/tools/glade/glade/source_os2.h
@@ -0,0 +1,33 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_SOURCE_OS2_H
+#define GLADE_SOURCE_OS2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+void source_write_os2_files (GbWidgetWriteSourceData * data);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_SOURCE_OS2_H */
diff --git a/tools/glade/glade/styles.c b/tools/glade/glade/styles.c
new file mode 100644
index 00000000..4f74064f
--- /dev/null
+++ b/tools/glade/glade/styles.c
@@ -0,0 +1,208 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef GLADE_STYLE_SUPPORT
+
+#include "gladeconfig.h"
+
+#include "glade_project.h"
+#include "styles.h"
+#include "gbwidget.h"
+
+
+gchar *GbStateNames[] =
+{"NORMAL", "ACTIVE", "PRELIGHT",
+ "SELECTED", "INSENSITIVE"};
+gchar *GbColorNames[] =
+{"fg", "bg", "text", "base"};
+gchar *GbBgPixmapName = "bg_pixmap";
+
+/* The style data hash stores named GbStyles with the name as the key.
+ Note that the GbStyle name field is also used as the key so be careful when
+ freeing or updating it. */
+GHashTable *gb_style_hash = NULL;
+
+/* The default style of created widgets. We need to use a separate default
+ style for the widgets created so that the Glade UI doesn't change. */
+GbStyle *gb_widget_default_gb_style;
+
+
+struct GbUpdateStyleData
+ {
+ GbStyle *old_gbstyle;
+ GbStyle *new_gbstyle;
+ };
+
+static void update_style (GtkWidget * component,
+ struct GbUpdateStyleData *data);
+
+/*************************************************************************
+ * Functions for creating/copying/destroying GbStyleData structs
+ *************************************************************************/
+
+static void
+reset_gb_styles_callback (gchar * key, GbStyle * gbstyle, gpointer data)
+{
+ gb_widget_destroy_gb_style (gbstyle, FALSE);
+}
+
+void
+gb_widget_reset_gb_styles ()
+{
+ if (gb_style_hash)
+ {
+ g_hash_table_foreach (gb_style_hash, (GHFunc) reset_gb_styles_callback,
+ NULL);
+ g_hash_table_destroy (gb_style_hash);
+ }
+
+
+ /* Create new GbStyle hash */
+ gb_style_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* Create default GbStyle */
+ gb_widget_default_gb_style = gb_widget_new_gb_style ();
+ gb_widget_default_gb_style->name = g_strdup (GB_STYLE_DEFAULT);
+ gb_widget_default_gb_style->xlfd_fontname = g_strdup (GB_DEFAULT_XLFD_FONTNAME);
+ gb_widget_default_gb_style->style = gtk_widget_get_default_style ();
+ g_hash_table_insert (gb_style_hash, gb_widget_default_gb_style->name,
+ gb_widget_default_gb_style);
+}
+
+
+GbStyle *
+gb_widget_new_gb_style ()
+{
+ gint i;
+ GbStyle *gbstyle = g_new (GbStyle, 1);
+ gbstyle->name = NULL;
+ gbstyle->xlfd_fontname = NULL;
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ gbstyle->bg_pixmap_filenames[i] = NULL;
+ }
+ gbstyle->style = NULL;
+ gbstyle->ref_count = 0;
+ return gbstyle;
+}
+
+
+GbStyle *
+gb_widget_copy_gb_style (GbStyle * gbstyle)
+{
+ gint i;
+ GbStyle *gbstyle_copy = g_new (GbStyle, 1);
+ gbstyle_copy->name = g_strdup (gbstyle->name);
+ gbstyle_copy->xlfd_fontname = g_strdup (gbstyle->xlfd_fontname);
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ gbstyle_copy->bg_pixmap_filenames[i]
+ = g_strdup (gbstyle->bg_pixmap_filenames[i]);
+ }
+ gbstyle_copy->style = gbstyle->style;
+ gtk_style_ref (gbstyle_copy->style);
+ gbstyle_copy->ref_count = 0;
+ return gbstyle_copy;
+}
+
+
+void
+gb_widget_ref_gb_style (GbStyle * gbstyle)
+{
+ gbstyle->ref_count++;
+}
+
+
+void
+gb_widget_unref_gb_style (GbStyle * gbstyle)
+{
+ gbstyle->ref_count--;
+ /* Don't destroy named GbStyles - let user do that explicitly. */
+ if (gbstyle->ref_count <= 0 && gbstyle->name == NULL)
+ {
+ gb_widget_destroy_gb_style (gbstyle, TRUE);
+ }
+}
+
+
+void
+gb_widget_destroy_gb_style (GbStyle * gbstyle, gboolean remove_from_hash)
+{
+ gint i;
+
+ MSG1 ("Destroying gbstyle:%s", gbstyle->name);
+
+ /* Remove the GbStyle from the hash */
+ if (remove_from_hash && gbstyle->name)
+ g_hash_table_remove (gb_style_hash, gbstyle->name);
+
+ /* Now free all the memory used */
+ g_free (gbstyle->name);
+ g_free (gbstyle->xlfd_fontname);
+ for (i = 0; i < GB_NUM_STYLE_STATES; i++)
+ {
+ g_free (gbstyle->bg_pixmap_filenames[i]);
+ }
+ if (gbstyle->style)
+ gtk_style_unref (gbstyle->style);
+ g_free (gbstyle);
+}
+
+
+
+/* This steps through all widgets in all components and updates the GbStyle
+ and GtkStyles as appropriate. */
+void
+gb_widget_update_gb_styles (GbStyle * old_gbstyle, GbStyle * new_gbstyle)
+{
+ struct GbUpdateStyleData data;
+ data.old_gbstyle = old_gbstyle;
+ data.new_gbstyle = new_gbstyle;
+ glade_project_foreach_component (current_project,
+ (GtkCallback) update_style, &data);
+}
+
+
+static void
+update_style (GtkWidget * widget, struct GbUpdateStyleData *data)
+{
+#if 0
+ GladeWidgetData *wdata;
+
+ wdata = gtk_object_get_data (GTK_OBJECT (widget), GB_WIDGET_DATA_KEY);
+
+ if (wdata && wdata->gbstyle == data->old_gbstyle)
+ {
+ wdata->gbstyle = data->new_gbstyle;
+ if (widget->style != wdata->gbstyle->style)
+ {
+ gtk_widget_set_style (widget, wdata->gbstyle->style);
+ gtk_widget_queue_resize (widget);
+ gtk_widget_queue_draw (widget);
+ }
+ }
+ if (GTK_IS_CONTAINER (widget))
+ {
+ gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) update_style,
+ data);
+ }
+#endif
+}
+
+
+#endif
diff --git a/tools/glade/glade/styles.h b/tools/glade/glade/styles.h
new file mode 100644
index 00000000..050a651c
--- /dev/null
+++ b/tools/glade/glade/styles.h
@@ -0,0 +1,85 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_STYLES_H
+#define GLADE_STYLES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#ifdef GLADE_STYLE_SUPPORT
+
+
+#define GB_NUM_STYLE_STATES 5
+extern gchar* GbStateNames[];
+#define GB_NUM_STYLE_COLORS 4
+extern gchar* GbColorNames[];
+extern gchar* GbBgPixmapName;
+
+#define GB_STYLE_UNNAMED "<none>"
+#define GB_STYLE_DEFAULT "Default"
+
+/* This is the default GTK font spec., from gtkstyle.c */
+#define GB_DEFAULT_XLFD_FONTNAME \
+ "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*"
+
+/* This contains all extra info needed to recreate a style.
+ NOTE: A GtkStyle may be used by more than one GbStyle. */
+typedef struct _GbStyle GbStyle;
+struct _GbStyle
+{
+ gchar *name;
+ gchar *xlfd_fontname;
+ gchar *bg_pixmap_filenames[GB_NUM_STYLE_STATES];
+ GtkStyle *style;
+ gint ref_count;
+};
+
+
+/* The style data hash stores named GbStyles with the name as the key.
+ Note that the GbStyle name field is also used as the key so be careful when
+ freeing or updating it. */
+extern GHashTable *gb_style_hash;
+
+/* The default GbStyle of created widgets. We need to use a separate default
+ style for the widgets created so that the Glade UI doesn't change.
+ Remember to push the GtkStyle before creating any gbwidgets. */
+extern GbStyle *gb_widget_default_gb_style;
+
+/* Functions for handling GbStyles. */
+void gb_widget_reset_gb_styles (void);
+GbStyle* gb_widget_new_gb_style (void);
+GbStyle* gb_widget_copy_gb_style (GbStyle *gbstyle);
+void gb_widget_ref_gb_style (GbStyle *gbstyle);
+void gb_widget_unref_gb_style (GbStyle *gbstyle);
+void gb_widget_destroy_gb_style (GbStyle *gbstyle,
+ gboolean remove_from_hash);
+
+void gb_widget_set_gb_style (GtkWidget *widget,
+ GbStyle *gbstyle);
+void gb_widget_update_gb_styles (GbStyle *old_gbstyle,
+ GbStyle *new_gbstyle);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_STYLES_H */
diff --git a/tools/glade/glade/tree.c b/tools/glade/glade/tree.c
new file mode 100644
index 00000000..8f643e35
--- /dev/null
+++ b/tools/glade/glade/tree.c
@@ -0,0 +1,471 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <string.h>
+
+#include <gtk/gtkcellrendererpixbuf.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtktreeselection.h>
+#include <gtk/gtktreestore.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkwindow.h>
+
+
+#include "gbwidget.h"
+#include "editor.h"
+#include "tree.h"
+#include "utils.h"
+#include "glade_project_window.h"
+
+/* This key is used to store a pointer from each widget to its corresponding
+ node in the widget tree. */
+#define GLADE_TREE_NODE_KEY "GLADE_TREE_NODE_KEY"
+
+enum {
+ COLUMN_ICON,
+ COLUMN_TEXT,
+ COLUMN_OBJECT
+};
+
+GtkWidget *win_tree = NULL;
+static GtkWidget *widget_tree = NULL;
+static GtkTreeStore *tree_store = NULL;
+static GtkTreeSelection *tree_selection = NULL;
+
+
+static void tree_on_selection_changed (GtkTreeSelection *selection,
+ gpointer data);
+static gint tree_on_button_press (GtkWidget * tree,
+ GdkEventButton * event,
+ gpointer widget);
+
+
+
+/* This creates the widget tree window, with just the root tree. */
+void
+tree_init ()
+{
+ GtkWidget *scrolled_win;
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *icon_rend, *text_rend;
+
+ win_tree = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_move (GTK_WINDOW (win_tree), 530, 0);
+ gtk_widget_set_name (win_tree, "GladeWidgetTree");
+ gtk_signal_connect (GTK_OBJECT (win_tree), "delete_event",
+ GTK_SIGNAL_FUNC (tree_hide), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (win_tree), "hide",
+ GTK_SIGNAL_FUNC (glade_project_window_uncheck_widget_tree_menu_item),
+ NULL);
+ gtk_window_set_title (GTK_WINDOW (win_tree), _("Widget Tree"));
+ gtk_container_set_border_width (GTK_CONTAINER (win_tree), 0);
+ gtk_window_set_wmclass (GTK_WINDOW (win_tree), "widget_tree", "Glade");
+ gtk_window_add_accel_group (GTK_WINDOW (win_tree),
+ glade_get_global_accel_group ());
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (win_tree), scrolled_win);
+ gtk_widget_show (scrolled_win);
+
+ tree_store = gtk_tree_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING,
+ G_TYPE_POINTER);
+ widget_tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget_tree), FALSE);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), widget_tree);
+ gtk_widget_set_usize (widget_tree, 250, 320);
+ gtk_widget_show (widget_tree);
+
+ tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget_tree));
+ gtk_tree_selection_set_mode (GTK_TREE_SELECTION (tree_selection),
+ GTK_SELECTION_SINGLE);
+
+ col = gtk_tree_view_column_new ();
+
+ icon_rend = gtk_cell_renderer_pixbuf_new ();
+ text_rend = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (col, icon_rend, FALSE);
+ gtk_tree_view_column_pack_start (col, text_rend, TRUE);
+ gtk_tree_view_column_set_attributes (col, icon_rend,
+ "pixbuf", COLUMN_ICON,
+ NULL);
+ gtk_tree_view_column_set_attributes (col, text_rend,
+ "text", COLUMN_TEXT,
+ NULL);
+ gtk_tree_view_column_set_resizable (col, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (widget_tree), col);
+
+ gtk_signal_connect (GTK_OBJECT (widget_tree), "button_press_event",
+ GTK_SIGNAL_FUNC (tree_on_button_press), NULL);
+ g_signal_connect (G_OBJECT (tree_selection), "changed",
+ GTK_SIGNAL_FUNC (tree_on_selection_changed), NULL);
+}
+
+/* This shows the widget tree window. */
+void
+tree_show (GtkWidget * widget, gpointer data)
+{
+ gtk_widget_show (win_tree);
+ gdk_window_show (GTK_WIDGET (win_tree)->window);
+ gdk_window_raise (GTK_WIDGET (win_tree)->window);
+}
+
+/* This hides the widget tree window. */
+gint
+tree_hide (GtkWidget * widget, gpointer data)
+{
+ gtk_widget_hide (win_tree);
+ return TRUE;
+}
+
+
+/* This adds a widget to the tree (if it is a widget that we are interested in,
+ * i.e. a GbWidget). The widget must have already been added to the interface,
+ * so we can determine its parent. It also recursively adds any children. */
+void
+tree_add_widget (GtkWidget * widget)
+{
+ /* We only add it to the tree if it is a GbWidget and it hasn't already been
+ added. */
+ if (GB_IS_GB_WIDGET (widget))
+ {
+ if (!gtk_object_get_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY))
+ {
+ GbWidget *gbwidget;
+ GtkWidget *parent;
+ GNode *parent_node = NULL;
+ GtkTreeIter iter, tmp_iter = { 0 }, *parent_iter = NULL;
+
+ gbwidget = gb_widget_lookup (widget);
+ g_return_if_fail (gbwidget != NULL);
+
+ parent = glade_util_get_parent (widget);
+ if (parent)
+ parent_node = gtk_object_get_data (GTK_OBJECT (parent),
+ GLADE_TREE_NODE_KEY);
+ if (parent_node)
+ {
+ /* I'm not sure if this is a bad hack. */
+ tmp_iter.stamp = tree_store->stamp;
+ tmp_iter.user_data = parent_node;
+ parent_iter = &tmp_iter;
+ }
+
+ /* Create the pixbuf for the icon, if necessary. */
+ if (gbwidget->pixbuf == NULL && gbwidget->pixmap_struct)
+ {
+ gbwidget->pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**) gbwidget->pixmap_struct);
+ }
+
+ gtk_tree_store_append (tree_store, &iter, parent_iter);
+ gtk_tree_store_set (tree_store, &iter,
+ COLUMN_ICON, gbwidget->pixbuf,
+ COLUMN_TEXT, gtk_widget_get_name (widget),
+ COLUMN_OBJECT, widget,
+ -1);
+
+ /* Save a pointer to the GNode inside the widget. */
+ gtk_object_set_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY,
+ iter.user_data);
+ }
+ else
+ {
+ /* Update the name if necessary. This is needed because we may have
+ added this widget before (if it was created by its parent
+ automatically), but we have only just loaded its name. */
+ tree_rename_widget (widget, gtk_widget_get_name (widget));
+ }
+ }
+
+ /* Now add any children. */
+ gb_widget_children_foreach (widget, (GtkCallback) tree_add_widget, NULL);
+}
+
+
+/* Recursively removes any pointers to tree GNodes in the widgets. */
+void
+tree_remove_widget_cb (GtkWidget * widget)
+{
+#if 0
+ g_print ("Removing node key from widget: %s\n", gtk_widget_get_name (widget));
+#endif
+ gtk_object_remove_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY);
+ gb_widget_children_foreach (widget, (GtkCallback) tree_remove_widget_cb,
+ NULL);
+}
+
+
+void
+tree_remove_widget (GtkWidget * widget)
+{
+ GNode *node;
+ GtkTreeIter iter = { 0 };
+
+#if 0
+ g_print ("In tree_remove_widget: %s\n", gtk_widget_get_name (widget));
+#endif
+
+ node = gtk_object_get_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY);
+ if (node == NULL)
+ return;
+
+ /* I'm not sure if this is a bad hack. */
+ iter.stamp = tree_store->stamp;
+ iter.user_data = node;
+
+#if 0
+ g_print ("Removing widget: %s\n", gtk_widget_get_name (widget));
+#endif
+
+ gtk_object_remove_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY);
+
+ /* Remove the GNode's stored in any child widgets, as these GNodes are also
+ about to be removed. */
+ gb_widget_children_foreach (widget, (GtkCallback) tree_remove_widget_cb,
+ NULL);
+
+ gtk_tree_store_remove (tree_store, &iter);
+}
+
+
+void
+tree_clear (void)
+{
+ gtk_tree_store_clear (tree_store);
+}
+
+
+void
+tree_freeze (void)
+{
+#if 0
+ /* I don't think GtkTreeView has a corresponding function. */
+ gtk_clist_freeze (GTK_CLIST (widget_tree));
+#endif
+}
+
+
+void
+tree_thaw (void)
+{
+#if 0
+ /* I don't think GtkTreeView has a corresponding function. */
+ gtk_clist_thaw (GTK_CLIST (widget_tree));
+#endif
+}
+
+
+void
+tree_rename_widget (GtkWidget * widget, const gchar * name)
+{
+ GNode *node;
+ GtkTreeIter iter = { 0 };
+ gchar *old_name;
+
+ node = gtk_object_get_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY);
+ if (node == NULL)
+ return;
+
+ /* I'm not sure if this is a bad hack. */
+ iter.stamp = tree_store->stamp;
+ iter.user_data = node;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (tree_store), &iter,
+ COLUMN_TEXT, &old_name, -1);
+
+ /* Only update it if the name has really changed. */
+ if (strcmp (old_name, name))
+ {
+#if 0
+ g_print ("Changing name from: %s to: %s\n", old_name, name);
+#endif
+ gtk_tree_store_set (tree_store, &iter, COLUMN_TEXT, name, -1);
+ }
+}
+
+
+/* This is used when inserting an alignment or event box above a widget. */
+void
+tree_insert_widget_parent (GtkWidget * parent, GtkWidget * widget)
+{
+ /* Remove the widget if it is currently in the tree. */
+ tree_remove_widget (widget);
+
+ /* Now add the parent. Since widgets are added recursively, the widget
+ will get added back as well. */
+ tree_add_widget (parent);
+}
+
+
+/* Selects a node and makes sure it is visible on the tree */
+static void
+tree_select_iter (GtkTreeIter *iter)
+{
+ GtkTreePath *path;
+ GList *ancestors = NULL, *elem;
+
+ /* Make sure all ancestors are expanded. This makes the GUI easier to use,
+ but is also necessary to be able to select the widget in the GtkTreeView.
+ We have to expand the rows from the top down, so first we step up the
+ tree pushing them onto a list. */
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
+ for (;;)
+ {
+ if (!gtk_tree_path_up (path))
+ break;
+
+ ancestors = g_list_prepend (ancestors, path);
+ path = gtk_tree_path_copy (path);
+ }
+ gtk_tree_path_free (path);
+
+ for (elem = ancestors; elem; elem = elem->next)
+ {
+ GtkTreePath *tmp_path = elem->data;
+
+ if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget_tree), tmp_path))
+ gtk_tree_view_expand_row (GTK_TREE_VIEW (widget_tree), tmp_path,
+ FALSE);
+ gtk_tree_path_free (tmp_path);
+ }
+ g_list_free (ancestors);
+
+ /* Select the row. */
+ gtk_tree_selection_select_iter (tree_selection, iter);
+
+ /* Make sure the row is visible. */
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (widget_tree), path, NULL,
+ TRUE, 0, 0);
+ gtk_tree_path_free (path);
+}
+
+
+static void
+tree_get_selection_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GList **selection)
+{
+ GObject *object;
+
+ gtk_tree_model_get (model, iter, COLUMN_OBJECT, &object, -1);
+ if (object)
+ *selection = g_list_prepend (*selection, object);
+}
+
+
+/* Returns a list of selected widgets. g_list_free() it. */
+static GList*
+tree_get_selection (void)
+{
+ GList *selection = NULL;
+
+ /* Create a GList of all the widgets selected in the tree. */
+ gtk_tree_selection_selected_foreach (tree_selection,
+ (GtkTreeSelectionForeachFunc) tree_get_selection_cb,
+ &selection);
+ return selection;
+}
+
+
+void
+tree_select_widget (GtkWidget * widget, gboolean select)
+{
+ GNode *node;
+ GtkTreeIter iter = { 0 };
+ GList *selection;
+ gboolean selected = FALSE;
+
+ if (!GB_IS_GB_WIDGET (widget))
+ return;
+
+ node = gtk_object_get_data (GTK_OBJECT (widget), GLADE_TREE_NODE_KEY);
+ if (node == NULL)
+ return;
+
+ /* I'm not sure if this is a bad hack. */
+ iter.stamp = tree_store->stamp;
+ iter.user_data = node;
+
+ /* Check if the item is currently selected. */
+ selection = tree_get_selection ();
+ if (g_list_find (selection, widget))
+ selected = TRUE;
+ g_list_free (selection);
+
+ if (select && !selected)
+ tree_select_iter (&iter);
+ else if (!select && selected)
+ gtk_tree_selection_unselect_iter (tree_selection, &iter);
+}
+
+
+/* We set the widget selection in the GUI to match the selection in the tree.
+ */
+static void
+tree_on_selection_changed (GtkTreeSelection *selection, gpointer data)
+{
+ /* Note that we may get callbacks as widgets are selected or deselected in
+ the GUI, but we will check if the tree needs updating and it shouldn't
+ so we won't get into infinite loops. */
+ editor_set_selection (tree_get_selection ());
+}
+
+
+/* This is called when a button is pressed in the tree. If it was the
+ right mouse button we show the popup menu for the widget. */
+static gint
+tree_on_button_press (GtkWidget *tree,
+ GdkEventButton *event,
+ gpointer data)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ if (event->button != 3
+ || event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (tree)))
+ return FALSE;
+
+ if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree),
+ event->x, event->y,
+ &path, NULL, NULL, NULL))
+ return FALSE;
+
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &iter, path))
+ {
+ GtkWidget *widget;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (tree_store), &iter,
+ COLUMN_OBJECT, &widget,
+ -1);
+
+ if (widget)
+ gb_widget_show_popup_menu (GTK_WIDGET (widget), event);
+
+ gtk_tree_path_free (path);
+ }
+
+ return TRUE;
+}
+
+
diff --git a/tools/glade/glade/tree.h b/tools/glade/glade/tree.h
new file mode 100644
index 00000000..fefbd0ff
--- /dev/null
+++ b/tools/glade/glade/tree.h
@@ -0,0 +1,70 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLADE_TREE_H
+#define GLADE_TREE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern GtkWidget *win_tree;
+
+/* This creates the widget tree and window, but doesn't show it. It needs
+ to be called before any widgets are added to the interface, so they can
+ be added to the tree. */
+void tree_init (void);
+
+/* These show or hide the widget tree window. */
+void tree_show (GtkWidget *widget,
+ gpointer data);
+gint tree_hide (GtkWidget *widget,
+ gpointer data);
+
+/* These are for adding/selecting/renaming/removing widgets. The widget must
+ already have been added to the interface before calling tree_add_widget(),
+ since we need to be able to determine its parent so we know where to add it
+ in th widget tree. */
+void tree_add_widget (GtkWidget *widget);
+void tree_select_widget (GtkWidget *widget,
+ gboolean select);
+void tree_rename_widget (GtkWidget *widget,
+ const gchar *name);
+void tree_remove_widget (GtkWidget *widget);
+
+/* These are for inserting widgets into the existing tree, and
+ are used when adding/removing event boxes or alignment widgets. */
+void tree_insert_widget_parent (GtkWidget *parent,
+ GtkWidget *widget);
+
+/* This clears the entire widget tree, and is used when another project is
+ about to be created or opened. */
+void tree_clear (void);
+
+/* These are called when making major changes to the widget tree (i.e. when
+ loading an entire interface), to make the updates more efficient. */
+void tree_freeze (void);
+void tree_thaw (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_TREE_H */
diff --git a/tools/glade/glade/utils.c b/tools/glade/glade/utils.c
new file mode 100644
index 00000000..56b5beb2
--- /dev/null
+++ b/tools/glade/glade/utils.c
@@ -0,0 +1,2327 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gladeconfig.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <dirent.h>
+#include <errno.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#ifdef USE_GNOME
+#include <gnome.h>
+#include <bonobo.h>
+#endif
+
+#include "gb.h"
+#include "gbwidget.h"
+#include "glade_project_window.h"
+#include "utils.h"
+
+
+gchar *GladeDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+gchar *GladeMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+typedef void (*GladeDialogCallback) (GtkDialog *dialog, gpointer data);
+
+#define READ_BUFFER_SIZE 4096
+
+static void on_entry_dialog_ok (GtkWidget * widget,
+ gpointer data);
+static void on_entry_dialog_destroy (GtkWidget * widget,
+ gpointer data);
+static gboolean check_components_match (const gchar *base,
+ const gchar *path,
+ gint root_pos,
+ gint len);
+
+static GtkWidget* glade_util_find_table_accelerator_target (GtkWidget *parent,
+ GtkWidget *child);
+static GtkWidget* glade_util_find_box_accelerator_target (GtkWidget *parent,
+ GtkWidget *child);
+static GtkWidget* glade_util_find_fixed_accelerator_target (GtkWidget *parent,
+ GtkWidget *child);
+static GtkWidget* glade_util_find_layout_accelerator_target (GtkWidget *parent,
+ GtkWidget *child);
+
+typedef struct _GladeLayoutCallbackData GladeLayoutCallbackData;
+struct _GladeLayoutCallbackData
+{
+ gint x, y, best_distance;
+ GtkWidget *child, *best_target;
+};
+
+typedef struct _GladeFindWidgetData GladeFindWidgetData;
+struct _GladeFindWidgetData
+{
+ gchar *name;
+ GtkWidget *found_widget;
+};
+
+static void glade_util_find_layout_acclererator_target_cb (GtkWidget *widget,
+ GladeLayoutCallbackData *data);
+
+static GtkWidget* glade_util_find_focus_child (GtkWidget *widget);
+
+static void glade_util_find_widget_recursive (GtkWidget *widget,
+ GladeFindWidgetData *data);
+
+
+/* This shows a simple dialog box with a label and an 'OK' button.
+ Example usage:
+ glade_util_show_message_box ("Error saving file", NULL);
+*/
+void
+glade_util_show_message_box (const gchar *message,
+ GtkWidget *transient_widget)
+{
+ GtkWidget *dialog;
+ GtkWindow *transient_parent;
+
+ transient_parent = (GtkWindow *)glade_util_get_toplevel (transient_widget);
+ dialog = gtk_message_dialog_new (transient_parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s", message);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+
+/* This shows a dialog box with a message and an Entry for entering a value.
+ * When the OK button is pressed the handler of the specified widget will
+ * be called with the value and the given data.
+ * NOTE: The dialog is automatically destroyed when any button is clicked.
+
+ Example usage:
+ glade_util_show_entry_dialog ("Name:", "default", widget, on_dialog_ok,
+ "NewName", NULL);
+
+ void
+ on_dialog_ok(GtkWidget *widget, gchar *value, gpointer data)
+ {
+ ...
+
+*/
+void
+glade_util_show_entry_dialog (const gchar *message,
+ const gchar *initial_value,
+ GtkWidget *widget,
+ GbEntryDialogFunc signal_handler,
+ gpointer data,
+ GtkWidget *transient_widget)
+{
+ GtkWidget *dialog, *hbox, *label, *entry, *button, *toplevel;
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+
+ /* FIXME: Passing a function as a gpointer isn't compatable with ANSI. */
+ gtk_object_set_data (GTK_OBJECT (dialog), "handler", signal_handler);
+ gtk_object_set_data (GTK_OBJECT (dialog), "widget", widget);
+ gtk_widget_ref (widget);
+
+ hbox = gtk_hbox_new (FALSE, 10);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 20);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
+ TRUE, TRUE, 0);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (message);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ gtk_widget_show (label);
+
+ entry = glade_util_entry_new (GTK_OBJECT (dialog));
+ if (initial_value)
+ gtk_entry_set_text (GTK_ENTRY (entry), initial_value);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+ gtk_widget_show (entry);
+ gtk_widget_grab_focus (entry);
+ gtk_object_set_data (GTK_OBJECT (dialog), "entry", entry);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button,
+ FALSE, TRUE, 20);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_show (button);
+ gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (dialog));
+
+ button = gtk_button_new_from_stock (GTK_STOCK_OK);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button,
+ FALSE, TRUE, 20);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default (button);
+ gtk_widget_show (button);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (on_entry_dialog_ok),
+ data);
+
+ gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event",
+ GTK_SIGNAL_FUNC (glade_util_check_key_is_esc),
+ GINT_TO_POINTER (GladeEscDestroys));
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (on_entry_dialog_destroy), widget);
+
+ if (transient_widget)
+ {
+ toplevel = glade_util_get_toplevel (transient_widget);
+ if (toplevel && GTK_IS_WINDOW (toplevel) && GTK_WIDGET_MAPPED (toplevel))
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ GTK_WINDOW (toplevel));
+ }
+
+ gtk_widget_show (dialog);
+}
+
+
+static void
+on_entry_dialog_destroy (GtkWidget * widget, gpointer data)
+{
+ gtk_widget_unref (GTK_WIDGET (data));
+}
+
+
+static void
+on_entry_dialog_ok (GtkWidget * widget, gpointer data)
+{
+ GtkWidget *dialog = gtk_widget_get_toplevel (widget);
+ GbEntryDialogFunc handler;
+ GtkWidget *entry;
+ gchar *text;
+ gboolean close = TRUE;
+
+ /* FIXME: ANSI forbids casting function pointer to data pointer. */
+ handler = (GbEntryDialogFunc) (gtk_object_get_data (GTK_OBJECT (dialog),
+ "handler"));
+ widget = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dialog), "widget"));
+ entry = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dialog), "entry"));
+ g_return_if_fail (entry != NULL);
+ text = (gchar*) gtk_entry_get_text (GTK_ENTRY (entry));
+
+ if (handler)
+ close = (*handler) (widget, text, data);
+ if (close)
+ gtk_widget_destroy (dialog);
+}
+
+static void
+on_dialog_response (GtkDialog *dialog, gint response, gpointer ok_handler_data)
+{
+ GladeDialogCallback ok_handler;
+
+ if (response == GTK_RESPONSE_OK)
+ {
+ ok_handler = (GladeDialogCallback) g_object_get_data (G_OBJECT (dialog), "ok_handler");
+ ok_handler (dialog, ok_handler_data);
+ }
+ else
+ {
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ }
+}
+
+/* This creates a dialog with OK & Cancel buttons, usable in plain GTK or
+ Gnome, and returns a vbox which the caller can place widgets in.
+ If transient_for is non-NULL, the window it is in is used to set the
+ transient for relationship, so the dialog will always be above the widget.
+ (This only works with GTK 1.1.6+).
+ The callback will be called when the OK button is pressed. */
+GtkWidget*
+glade_util_create_dialog (const gchar *title,
+ GtkWidget *transient_for,
+ GtkSignalFunc ok_handler,
+ gpointer ok_handler_data,
+ GtkWidget **vbox)
+{
+ GtkWidget *dialog;
+ GtkWindow *transient_parent;
+
+ transient_parent = (GtkWindow *)glade_util_get_toplevel (transient_for);
+ dialog = gtk_dialog_new_with_buttons (title, transient_parent,
+ 0,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+ g_object_set_data (G_OBJECT (dialog), "ok_handler", ok_handler);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (on_dialog_response),
+ ok_handler_data);
+
+ *vbox = GTK_DIALOG (dialog)->vbox;
+
+ return dialog;
+}
+
+
+gint glade_util_check_key_is_esc (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
+{
+ g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+
+ if (event->keyval == GDK_Escape)
+ {
+ GladeEscAction action = GPOINTER_TO_INT (data);
+
+ if (action == GladeEscCloses)
+ {
+ glade_util_close_window (widget);
+ return TRUE;
+ }
+ else if (action == GladeEscDestroys)
+ {
+ gtk_widget_destroy (widget);
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ else
+ return FALSE;
+}
+
+/* This returns a new entry ready to insert in a dialog.
+ The entry is set up so that <Return> will invoke the default action. The
+ returned widget must be added to a container in the dialog. */
+extern GtkWidget *
+glade_util_entry_new (GtkObject *dialog)
+{
+ GtkWidget *entry;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (dialog), NULL);
+
+ entry = gtk_entry_new ();
+ g_return_val_if_fail (entry != NULL, NULL);
+
+ /* Make <Return> in entry field invoke dialog default */
+ gtk_signal_connect_object (GTK_OBJECT (entry), "activate",
+ GTK_SIGNAL_FUNC (gtk_window_activate_default),
+ GTK_OBJECT (dialog));
+
+ return entry;
+}
+
+
+/* This returns a new spinbutton ready to insert in a dialog.
+ A pointer to the spin button is added as object data to the dialog. The
+ spinbutton is set up so that <Return> will invoke the default action. The
+ returned widget must be added to a container in the dialog. */
+GtkWidget *
+glade_util_spin_button_new (GtkObject *dialog,
+ const gchar *key,
+ GtkAdjustment *adjustment,
+ gfloat climb_rate,
+ guint digits)
+{
+ GtkWidget *spinbutton;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (dialog), NULL);
+ g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL);
+
+ spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), climb_rate,
+ digits);
+ g_return_val_if_fail (spinbutton != NULL, NULL);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
+
+ /* save pointer to entry so we can find it easily in the OK handler */
+ gtk_object_set_data (GTK_OBJECT (dialog), key, spinbutton);
+ /* Make <Return> in entry field invoke dialog default */
+ gtk_signal_connect_object (GTK_OBJECT (spinbutton), "activate",
+ GTK_SIGNAL_FUNC (gtk_window_activate_default),
+ GTK_OBJECT (dialog));
+
+ return spinbutton;
+}
+
+/* This returns the index of the given gint with the given array of gints.
+ If the value is not found it outputs a warning and returns -1.
+ This function is intended to be used for finding the index when using
+ properties which are choices. */
+gint
+glade_util_int_array_index (const gint array[],
+ gint array_size,
+ gint value)
+{
+ gint i;
+
+ for (i = 0; i < array_size; i++)
+ {
+ if (array[i] == value)
+ return i;
+ }
+ return -1;
+}
+
+
+/* This returns the index of the given string with the given array of strings.
+ If the value is not found it outputs a warning and returns -1.
+ This function is intended to be used for finding the index when using
+ properties which are choices. */
+gint
+glade_util_string_array_index (const gchar *array[],
+ gint array_size,
+ const gchar *value)
+{
+ gint i;
+
+ for (i = 0; i < array_size; i++)
+ {
+ if (array[i] && !strcmp (array[i], value))
+ return i;
+ }
+ return -1;
+}
+
+
+/* This returns TRUE if the two strings are equivalent. Note that NULL is
+ considered equivalent to the empty string. */
+gboolean
+glade_util_strings_equivalent (const gchar *string1,
+ const gchar *string2)
+{
+ if (string1 && string1[0] == '\0')
+ string1 = NULL;
+ if (string2 && string2[0] == '\0')
+ string2 = NULL;
+
+ if (string1 == NULL)
+ {
+ if (string2 == NULL)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else if (string2 == NULL)
+ return FALSE;
+ else if (!strcmp (string1, string2))
+ return TRUE;
+ return FALSE;
+}
+
+
+/* This returns a copy of the given string, or NULL if the string is NULL
+ or empty, i.e. "". */
+gchar*
+glade_util_copy_string (const gchar *string)
+{
+ if (string == NULL || string[0] == '\0')
+ return NULL;
+ return g_strdup (string);
+}
+
+
+/* Returns TRUE if string contains substring. Returns FALSE if substring is
+ not found or is NULL. */
+gboolean
+glade_util_strstr (const gchar * string,
+ const gchar * substring)
+{
+ gchar first_char;
+ gint string_len, substring_len, i, j;
+ gboolean found;
+
+ if (!string || !substring)
+ return FALSE;
+
+ first_char = substring[0];
+ string_len = strlen (string);
+ substring_len = strlen (substring);
+
+ if (string_len < substring_len)
+ return FALSE;
+ for (i = 0; i <= string_len - substring_len; i++)
+ {
+ if (string[i] == first_char)
+ {
+ found = TRUE;
+ for (j = 1; j < substring_len; j++)
+ {
+ if (string[i + j] != substring[j])
+ {
+ found = FALSE;
+ break;
+ }
+ }
+ if (found == TRUE)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/* This looks for '::' in a property name and returns a pointer to the next
+ character. If '::' is not found it returns the argument. */
+gchar *
+glade_util_find_start_of_tag_name (const gchar * tag_name)
+{
+ register const gchar *pos = tag_name;
+
+ while (*pos && (*pos != ':' || *(pos + 1) != ':'))
+ pos++;
+ return (gchar*) (*pos ? pos + 2 : tag_name);
+}
+
+
+/* This creates a string representing the modifiers flags, e.g.
+ "GDK_CONTROL_MASK | GDK_SHIFT_MASK". It is used for saving the XML, and
+ also for writing the source code. It uses a static buffer which is
+ overwritten for each call. */
+gchar*
+glade_util_create_modifiers_string (guint8 modifier_flags)
+{
+ static gchar modifiers[128];
+
+ modifiers[0] = '\0';
+ if (modifier_flags == 0)
+ {
+ strcat (modifiers, "0");
+ return modifiers;
+ }
+
+ if (modifier_flags & GDK_CONTROL_MASK)
+ {
+ strcat (modifiers, "GDK_CONTROL_MASK");
+ }
+ if (modifier_flags & GDK_SHIFT_MASK)
+ {
+ if (modifiers[0] != '\0')
+ strcat (modifiers, " | ");
+ strcat (modifiers, "GDK_SHIFT_MASK");
+ }
+ if (modifier_flags & GDK_MOD1_MASK)
+ {
+ if (modifiers[0] != '\0')
+ strcat (modifiers, " | ");
+ strcat (modifiers, "GDK_MOD1_MASK");
+ }
+ return modifiers;
+}
+
+
+/* This creates a GtkPixmap widget, using a colormap and xpm data from an
+ '#include'd pixmap file. */
+GtkWidget*
+glade_util_create_pixmap_using_colormap (GdkColormap *colormap,
+ gchar **xpm_data)
+{
+ GtkWidget *pixmap;
+ GdkPixmap *gdkpixmap;
+ GdkBitmap *mask;
+
+ gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
+ NULL, (gchar**) xpm_data);
+ pixmap = gtk_pixmap_new (gdkpixmap, mask);
+
+ /* The GtkPixmap assumes the reference count, so we can unref them. */
+ gdk_pixmap_unref (gdkpixmap);
+ gdk_bitmap_unref (mask);
+
+ return pixmap;
+}
+
+
+/* This returns TRUE if the widget is a toplevel project component,
+ i.e. a window, dialog or popup menu. */
+gboolean
+glade_util_is_component (GtkWidget *widget)
+{
+ if (widget->parent == NULL)
+ return TRUE;
+
+ /* Note that menus may have submenus, so we make sure that this is the
+ toplevel menu. */
+ if (GTK_IS_MENU (widget)
+ && gtk_menu_get_attach_widget (GTK_MENU (widget)) == NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/* This returns the toplevel window/dialog/menu that contains the given
+ widget. It even walks up menus, which gtk_widget_get_toplevel() does not. */
+GtkWidget*
+glade_util_get_toplevel (GtkWidget *widget)
+{
+ GtkWidget *parent;
+
+ if (widget == NULL)
+ return NULL;
+
+ for (;;)
+ {
+ if (GTK_IS_MENU (widget))
+ parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ else
+ parent = widget->parent;
+ if (parent == NULL)
+ break;
+ widget = parent;
+ }
+
+ return widget;
+}
+
+
+/* This returns the closes ancestor of the given widget which is a GbWidget. */
+GtkWidget*
+glade_util_get_parent (GtkWidget *widget)
+{
+ GtkWidget *parent;
+
+ for (;;)
+ {
+ if (GTK_IS_MENU (widget))
+ parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ else
+ parent = widget->parent;
+
+ /* There is no way to move up from the combo popup list window to the
+ combo, so we added a special pointer. */
+ if (!parent)
+ parent = gtk_object_get_data (GTK_OBJECT (widget), GladeParentKey);
+
+ if (parent == NULL)
+ break;
+
+ if (GB_IS_GB_WIDGET (parent))
+ return parent;
+
+ widget = parent;
+ }
+
+ return widget;
+}
+
+
+/* This is used when setting up keyboard accelerators resulting from underlined
+ keys in labels. It returns the default mnemonic widget to use. */
+GtkWidget*
+glade_util_find_default_accelerator_target (GtkWidget *label)
+{
+ GtkWidget *parent, *child, *target = NULL;
+
+ g_return_val_if_fail (GTK_IS_LABEL (label), NULL);
+
+ /* Now try to find the widget to the right of the label. We can do this
+ fairly easily for tables, boxes, and fixed containers. But the packer
+ container may be more difficult. */
+ parent = label->parent;
+ child = label;
+ while (parent)
+ {
+ if (GTK_IS_TABLE (parent))
+ target = glade_util_find_table_accelerator_target (parent, child);
+ else if (GTK_IS_HBOX (parent))
+ target = glade_util_find_box_accelerator_target (parent, child);
+ else if (GTK_IS_FIXED (parent))
+ target = glade_util_find_fixed_accelerator_target (parent, child);
+ else if (GTK_IS_LAYOUT (parent))
+ target = glade_util_find_layout_accelerator_target (parent, child);
+
+ if (target)
+ {
+ return target;
+ }
+
+ child = parent;
+ parent = parent->parent;
+ }
+
+ return NULL;
+}
+
+
+/* This tries to find a named widget in a component. */
+GtkWidget*
+glade_util_find_widget (GtkWidget *widget, gchar *name)
+{
+ GladeFindWidgetData data;
+
+ data.name = name;
+ data.found_widget = NULL;
+
+ glade_util_find_widget_recursive (widget, &data);
+
+ return data.found_widget;
+}
+
+
+static void
+glade_util_find_widget_recursive (GtkWidget *widget,
+ GladeFindWidgetData *data)
+{
+ if (!data->found_widget && widget->name
+ && !strcmp (widget->name, data->name))
+ {
+ data->found_widget = widget;
+ }
+
+ if (GTK_IS_CONTAINER (widget))
+ {
+ gtk_container_forall (GTK_CONTAINER (widget),
+ (GtkCallback) glade_util_find_widget_recursive,
+ data);
+ }
+}
+
+
+/* This tries to find the widget on the right of the given child. */
+static GtkWidget*
+glade_util_find_table_accelerator_target (GtkWidget *parent, GtkWidget *child)
+{
+ GtkTableChild *tchild, *tchild2;
+ GList *children;
+
+ tchild = glade_util_find_table_child (GTK_TABLE (parent), child);
+ g_return_val_if_fail (tchild != NULL, NULL);
+
+ children = GTK_TABLE (parent)->children;
+ while (children)
+ {
+ tchild2 = (GtkTableChild*) children->data;
+
+ if (tchild2->widget != tchild->widget
+ && tchild2->left_attach == tchild->right_attach
+ && tchild2->top_attach < tchild->bottom_attach
+ && tchild2->bottom_attach > tchild->top_attach)
+ {
+ return glade_util_find_focus_child (tchild2->widget);
+ }
+ children = children->next;
+ }
+ return NULL;
+}
+
+
+/* This tries to find the widget on the right of the given child. */
+static GtkWidget*
+glade_util_find_box_accelerator_target (GtkWidget *parent, GtkWidget *child)
+{
+ GtkBoxChild *bchild, *bchild2;
+ GList *children, *elem;
+ gint pos;
+
+ pos = glade_util_get_box_pos (GTK_BOX (parent), child);
+ g_return_val_if_fail (pos != -1, NULL);
+
+ children = GTK_BOX (parent)->children;
+ elem = g_list_nth (children, pos);
+ bchild = (GtkBoxChild*) elem->data;
+
+ /* If the child has PACK_START set, try to find the next child also with
+ PACK_START set. If that can't be found, try to find the last child with
+ PACK_END set, since that will be nearest the middle.
+ If the child has PACK_END set, find the previous child with PACK_END. */
+ if (bchild->pack == GTK_PACK_START)
+ {
+ while (elem->next)
+ {
+ elem = elem->next;
+ bchild2 = (GtkBoxChild*) elem->data;
+ if (bchild2->pack == GTK_PACK_START)
+ return glade_util_find_focus_child (bchild2->widget);
+ }
+ /* We couldn't find another child with PACK_START, so we drop through
+ to the second loop with elem containing the last list element. */
+ }
+ else
+ {
+ elem = elem->prev;
+ }
+
+ /* Step back through the list trying to find a child with PACK_END set. */
+ while (elem)
+ {
+ bchild2 = (GtkBoxChild*) elem->data;
+ if (bchild2->pack != GTK_PACK_END)
+ return glade_util_find_focus_child (bchild2->widget);
+ elem = elem->prev;
+ }
+ return NULL;
+}
+
+
+/* This tries to find the widget on the right of the given child. */
+static GtkWidget*
+glade_util_find_fixed_accelerator_target (GtkWidget *parent, GtkWidget *child)
+{
+ GtkFixedChild *fchild, *fchild2;
+ GtkWidget *best_target = NULL;
+ gint distance, best_distance = -1;
+ GList *children;
+
+ fchild = glade_util_find_fixed_child (GTK_FIXED (parent), child);
+ g_return_val_if_fail (fchild != NULL, NULL);
+
+ children = GTK_BOX (parent)->children;
+ while (children)
+ {
+ fchild2 = (GtkFixedChild*) children->data;
+
+ /* We allow a few pixels difference in the y coordinate.
+ The x coordinate must be greater than the given child label. */
+ if (fchild2->widget != fchild->widget
+ && abs (fchild2->y - fchild->y) < 5
+ && fchild2->x > fchild->x)
+ {
+ distance = fchild2->x - fchild->x;
+
+ if (best_distance == -1 || distance < best_distance)
+ {
+ best_distance = distance;
+ best_target = fchild2->widget;
+ }
+ }
+
+ children = children->next;
+ }
+
+ return glade_util_find_focus_child (best_target);
+}
+
+
+/* This tries to find the widget on the right of the given child. */
+static GtkWidget*
+glade_util_find_layout_accelerator_target (GtkWidget *parent, GtkWidget *child)
+{
+ GladeLayoutCallbackData data;
+
+ data.best_distance = -1;
+ data.best_target = NULL;
+ data.child = child;
+ data.x = child->allocation.x;
+ data.y = child->allocation.y;
+ gtk_container_forall (GTK_CONTAINER (parent),
+ (GtkCallback)glade_util_find_layout_acclererator_target_cb,
+ &data);
+ return glade_util_find_focus_child (data.best_target);
+}
+
+static void
+glade_util_find_layout_acclererator_target_cb (GtkWidget *widget,
+ GladeLayoutCallbackData *data)
+{
+ gint distance;
+
+ /* We allow a few pixels difference in the y coordinate.
+ The x coordinate must be greater than the given child label. */
+ if (widget != data->child
+ && abs (widget->allocation.y - data->y) < 5
+ && widget->allocation.x > data->x)
+ {
+ distance = widget->allocation.x - data->x;
+
+ if (data->best_distance == -1 || distance < data->best_distance)
+ {
+ data->best_distance = distance;
+ data->best_target = widget;
+ }
+ }
+}
+
+
+/* This tries to find a widget which can accept the input focus, within the
+ given widget and its descendants. Note that this will only work if the
+ child is a GbWidget, since gb_label_write_source() assumes there is a
+ variable declared corresponding to the widget. */
+static GtkWidget*
+glade_util_find_focus_child (GtkWidget *widget)
+{
+ if (widget == NULL)
+ return NULL;
+
+ if (GTK_WIDGET_CAN_FOCUS (widget))
+ return widget;
+
+ if (GTK_IS_COMBO (widget))
+ return GTK_COMBO (widget)->entry;
+
+#ifdef USE_GNOME
+ if (GNOME_IS_FILE_ENTRY (widget))
+ return gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (widget));
+#endif
+
+ return NULL;
+}
+
+
+gint
+glade_util_get_box_pos (GtkBox * box,
+ GtkWidget * widget)
+{
+ GList *children;
+ GtkBoxChild *child;
+ guint pos = 0;
+
+ children = box->children;
+ while (children)
+ {
+ child = children->data;
+ if (widget == child->widget)
+ return pos;
+ pos++;
+ children = children->next;
+ }
+ g_warning (_("Widget not found in box"));
+ return -1;
+}
+
+
+GtkTableChild *
+glade_util_find_table_child (GtkTable * table,
+ GtkWidget * widget)
+{
+ GList *children;
+ GtkTableChild *child;
+
+ children = table->children;
+ while (children)
+ {
+ child = children->data;
+ if (widget == child->widget)
+ return child;
+ children = children->next;
+ }
+ g_warning (_("Widget not found in table"));
+ return NULL;
+}
+
+
+GtkBoxChild *
+glade_util_find_box_child (GtkBox * box,
+ GtkWidget * widget)
+{
+ GList *children;
+ GtkBoxChild *child;
+
+ children = box->children;
+ while (children)
+ {
+ child = children->data;
+ if (widget == child->widget)
+ return child;
+ children = children->next;
+ }
+ g_warning (_("Widget not found in box"));
+ return NULL;
+}
+
+
+GtkFixedChild*
+glade_util_find_fixed_child (GtkFixed *fixed,
+ GtkWidget *widget)
+{
+ GList *children;
+ GtkFixedChild *child;
+
+ children = fixed->children;
+ while (children)
+ {
+ child = children->data;
+ if (widget == child->widget)
+ return child;
+ children = children->next;
+ }
+ g_warning (_("Widget not found in fixed container"));
+ return NULL;
+}
+
+
+#if GLADE_SUPPORTS_GTK_PACKER
+GtkPackerChild *
+glade_util_find_packer_child (GtkPacker * packer,
+ GtkWidget * widget)
+{
+ GList *children;
+ GtkPackerChild *child;
+
+ children = packer->children;
+ while (children)
+ {
+ child = children->data;
+ if (widget == child->widget)
+ return child;
+ children = children->next;
+ }
+ g_warning (_("Widget not found in packer"));
+ return NULL;
+}
+#endif
+
+
+/* This returns the GtkLabel's text, including the underline characters.
+ We don't really need it now for GTK+ 2.0. Free the returned string. */
+gchar*
+glade_util_get_label_text (GtkWidget *label)
+{
+ char *result;
+
+ /* Hopefully this will work in GTK+ 2.0. */
+ result = (gchar*) gtk_label_get_label (GTK_LABEL (label));
+
+#if 0
+ g_print ("Label text: %s\n", result);
+#endif
+
+ /* We strdup it just to remain compatable with the old version. */
+ return g_strdup (result);
+
+#if 0
+ /* This is the old GTK+ 1.2 version, for reference. */
+ GdkWChar *label_wc, *label_with_underscores;
+ gchar *label_text, *label_pattern, *result;
+ gint len, i, j;
+ gboolean in_pattern;
+
+ g_return_val_if_fail (GTK_IS_LABEL (label), NULL);
+
+ /* We assume that the multi-byte and wide char versions of the text match. */
+ label_text = GTK_LABEL (label)->label;
+ label_wc = GTK_LABEL (label)->label_wc;
+ label_pattern = GTK_LABEL (label)->pattern;
+ /* The maximum space we need is 2 * the string length, i.e. when all letters
+ are underlined. */
+ len = strlen (label_text);
+ label_with_underscores = g_new (GdkWChar, len * 2 + 1);
+
+ /* We are careful in case the pattern is shorter than the label text. */
+ in_pattern = label_pattern ? TRUE : FALSE;
+ for (i = 0, j = 0; i < len; i++)
+ {
+ if (in_pattern && label_pattern[i])
+ {
+ if (label_pattern[i] == '_')
+ label_with_underscores[j++] = '_';
+ }
+ else
+ in_pattern = FALSE;
+ label_with_underscores[j++] = label_wc[i];
+
+ if (label_wc[i] == '_')
+ label_with_underscores[j++] = '_';
+ }
+ label_with_underscores[j] = '\0';
+
+ /* Now convert it to multi-byte. */
+ result = gdk_wcstombs (label_with_underscores);
+ g_free (label_with_underscores);
+
+ return result;
+#endif
+}
+
+
+/* This should be hooked up to the delete_event of windows which you want
+ to hide, so that if they are shown again they appear in the same place.
+ This stops the window manager asking the user to position the window each
+ time it is shown, which is quite annoying. */
+gint
+glade_util_close_window_on_delete (GtkWidget * widget,
+ GdkEvent * event,
+ gpointer data)
+{
+ glade_util_close_window (widget);
+ return TRUE;
+}
+
+
+gint
+glade_util_close_window (GtkWidget * widget)
+{
+ gint x, y;
+ gboolean set_position = FALSE;
+
+ /* remember position of window for when it is used again */
+ if (widget->window)
+ {
+ gdk_window_get_root_origin (widget->window, &x, &y);
+ set_position = TRUE;
+ }
+
+ gtk_widget_hide (widget);
+
+ if (set_position)
+ gtk_widget_set_uposition (widget, x, y);
+
+ return TRUE;
+}
+
+
+/* Returns TRUE if the given file exists. filename must be UTF-8. */
+gboolean
+glade_util_file_exists (const gchar *filename)
+{
+ int status;
+ struct stat filestat;
+ gchar *on_disk_filename;
+
+ on_disk_filename = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL);
+ status = stat (on_disk_filename, &filestat);
+ g_free (on_disk_filename);
+
+ if (status == -1 && errno == ENOENT)
+ return FALSE;
+ return TRUE;
+}
+
+
+/* Returns the last modification time of the given file, or 0 if it doesn't
+ exist, or -1 on error. filename must be UTF-8. */
+GladeError*
+glade_util_file_last_mod_time (const gchar *filename, time_t *last_mod_time)
+{
+ int status;
+ struct stat filestat;
+ gchar *on_disk_filename;
+
+ on_disk_filename = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL);
+ status = stat (on_disk_filename, &filestat);
+ g_free (on_disk_filename);
+
+ if (status == -1)
+ {
+ return glade_error_new_system (_("Couldn't access file:\n %s\n"),
+ filename);
+ }
+
+ *last_mod_time = filestat.st_mtime;
+ return NULL;
+}
+
+
+/* This copies a file from src to dest, and returns a GladeError if an error
+ occurs. src & dest must be UTF-8. */
+GladeError*
+glade_util_copy_file (const gchar *src,
+ const gchar *dest)
+{
+ FILE *input_fp, *output_fp;
+ gchar buffer[READ_BUFFER_SIZE];
+ gint bytes_read, bytes_written;
+ GladeError *error = NULL;
+
+ input_fp = glade_util_fopen (src, "r");
+ if (input_fp == NULL)
+ {
+ return glade_error_new_system (_("Couldn't open file:\n %s\n"), src);
+ }
+
+ output_fp = glade_util_fopen (dest, "w");
+ if (output_fp == NULL)
+ {
+ error = glade_error_new_system (_("Couldn't create file:\n %s\n"),
+ dest);
+ fclose (input_fp);
+ return error;
+ }
+
+ for (;;)
+ {
+ bytes_read = fread (buffer, 1, READ_BUFFER_SIZE, input_fp);
+ if (bytes_read != READ_BUFFER_SIZE && ferror (input_fp))
+ {
+ error = glade_error_new_system (_("Error reading from file:\n %s\n"),
+ src);
+ break;
+ }
+
+ if (bytes_read)
+ {
+ bytes_written = fwrite (buffer, 1, bytes_read, output_fp);
+ if (bytes_read != bytes_written)
+ {
+ error = glade_error_new_system (_("Error writing to file:\n %s\n"),
+ dest);
+ break;
+ }
+ }
+
+ if (bytes_read != READ_BUFFER_SIZE && feof (input_fp))
+ {
+ break;
+ }
+ }
+
+ fclose (input_fp);
+ fclose (output_fp);
+
+ return error;
+}
+
+
+/* Creates a directory if it doesn't already exist. directory must be an
+ absolute path, in UTF-8. */
+GladeError*
+glade_util_ensure_directory_exists (const gchar *directory)
+{
+ GladeError *error = NULL;
+ struct stat filestat;
+ gchar *on_disk_directory;
+
+ g_return_val_if_fail (g_path_is_absolute (directory), NULL);
+
+ on_disk_directory = g_filename_from_utf8 (directory, -1, NULL, NULL, NULL);
+ if (stat (on_disk_directory, &filestat) != 0)
+ {
+ /* If the directory doesn't exist, try to create it. */
+ if (errno == ENOENT)
+ {
+ gchar *parent_dir;
+
+ /* First make sure the parent directory exists. */
+ parent_dir = glade_util_parent_directory (directory);
+ if (parent_dir)
+ {
+ error = glade_util_ensure_directory_exists (parent_dir);
+ g_free (parent_dir);
+ }
+
+ if (!error)
+ {
+#ifdef _WIN32
+ if (mkdir (on_disk_directory) != 0)
+#else
+ if (mkdir (on_disk_directory, 0777) != 0)
+#endif
+ {
+#ifndef _WIN32
+/* This happens under WIN32 when stat is confused by the filename, but this is
+ harmless, since we know that the directory exists after all. */
+ error = glade_error_new_system (_("Couldn't create directory:\n %s\n"), directory);
+#endif
+ }
+ }
+ }
+ else
+ {
+ error = glade_error_new_system (_("Couldn't access directory:\n %s\n"), directory);
+ }
+ }
+#ifndef _WIN32
+ /* If the directory does exist, check it is a directory. */
+ else if (!S_ISDIR (filestat.st_mode))
+ {
+ error = glade_error_new_general (GLADE_STATUS_INVALID_DIRECTORY,
+ _("Invalid directory:\n %s\n"),
+ directory);
+ }
+#endif
+
+ g_free (on_disk_directory);
+
+ return error;
+}
+
+
+/* Adds a filename onto a directory to make a complete pathname.
+ The directory may or may not end in '/'. file must be a simple filename.
+ Free the returned string when no longer needed. */
+gchar*
+glade_util_make_path (const gchar *dir,
+ const gchar *file)
+{
+ gint dir_len;
+
+ g_return_val_if_fail (dir != NULL, NULL);
+ g_return_val_if_fail (file != NULL, NULL);
+
+ dir_len = strlen (dir);
+ g_return_val_if_fail (dir_len > 0, NULL);
+
+ if (dir[dir_len - 1] == G_DIR_SEPARATOR)
+ return g_strdup_printf ("%s%s", dir, file);
+ else
+ return g_strdup_printf ("%s%c%s", dir, G_DIR_SEPARATOR, file);
+}
+
+
+/* This turns a relative pathname into an absolute one based on the given
+ base directory (which MUST be absolute).
+ e.g. "/home/damon" + "../dave/test" -> "/home/dave/test"
+ The returned path should be freed when no longer needed. */
+gchar*
+glade_util_make_absolute_path (const gchar *dir, const gchar *file)
+{
+ gint dir_pos, file_pos, len, root_pos = 0;
+ gchar *path;
+
+ g_return_val_if_fail (dir != NULL, NULL);
+
+ if (file == NULL || file[0] == '\0')
+ return g_strdup (dir);
+
+ if (g_path_is_absolute (file))
+ return g_strdup (file);
+
+ /* For windows if dir has a drive set, e.g. "C:\", we never delete that. */
+#ifdef NATIVE_WIN32
+ if (isalpha (dir[0]) && dir[1] == ':' && dir[2] == G_DIR_SEPARATOR)
+ root_pos = 2;
+#endif
+
+ /* Start at last character in dir. */
+ dir_pos = strlen (dir) - 1;
+
+ /* First we make sure we skip any '/' at the end of dir. */
+ if (dir_pos > root_pos && dir[dir_pos] == G_DIR_SEPARATOR)
+ dir_pos--;
+
+ /* Now for each '..' in file, we step back one component in dir, and
+ forward one component in file. */
+ file_pos = 0;
+ for (;;)
+ {
+ /* Skip './' */
+ if (file[file_pos] == '.' && file[file_pos + 1] == G_DIR_SEPARATOR)
+ file_pos += 2;
+
+ else if (file[file_pos] == '.' && file[file_pos + 1] == '.'
+ && (file[file_pos + 2] == G_DIR_SEPARATOR
+ || file[file_pos + 2] == '\0'))
+ {
+ while (dir_pos > root_pos && dir[dir_pos] != G_DIR_SEPARATOR)
+ dir_pos--;
+ if (dir_pos > root_pos)
+ dir_pos--;
+
+ if (file[file_pos + 2] == G_DIR_SEPARATOR)
+ file_pos += 3;
+ else
+ file_pos += 2;
+ }
+
+ else
+ break;
+ }
+
+ /* Now concatenate the parts of dir and file together. */
+ if (dir_pos > root_pos)
+ dir_pos++;
+ len = dir_pos + 1 + (strlen (file) - file_pos) + 1;
+ path = g_malloc (len);
+ strncpy (path, dir, dir_pos);
+ path[dir_pos] = G_DIR_SEPARATOR;
+ strcpy (path + dir_pos + 1, file + file_pos);
+ return path;
+}
+
+
+/* This turns an absolute pathname into an relative one based on the given
+ base directory. Both arguments must be absolute paths, and should be in
+ canonical form, i.e. not containing '..', '.' or multiple '/'s together.
+ The returned value may or may not end with a '/', depending on the
+ arguments.
+ e.g. "/home/damon" + "/home/damon/pixmaps" -> "pixmaps"
+ "/home/damon" + "/home/damon/pixmaps/" -> "pixmaps/"
+ "/home/damon/project" + "/home/damon/test/pic.xpm" -> "../test/pic.xpm"
+ "/home/damon/project" + "/home/damon/project" -> ""
+ "/home/damon/project" + "/home/damon" -> "../"
+ The returned path should be freed when no longer needed. */
+gchar*
+glade_util_make_relative_path (const gchar *base, const gchar *path)
+{
+ gchar *relative_path;
+ gint pos, num_parents = 0, len, path_len, i, root_pos = 0;
+ gboolean match = FALSE;
+
+ if (path == NULL)
+ return g_strdup ("");
+
+ /* For windows if base has a drive set, e.g. "C:\", then path must start with
+ the same drive or we just return path. */
+#ifdef NATIVE_WIN32
+ if (isalpha (base[0]) && base[1] == ':' && base[2] == G_DIR_SEPARATOR)
+ {
+ root_pos = 2;
+ if (!isalpha (path[0]) || path[1] != ':' || path[2] != G_DIR_SEPARATOR
+ || base[0] != path[0])
+ return g_strdup (path);
+ }
+#endif
+
+ /* We step up each component of base_dir until we find a match with the
+ start of file. */
+ pos = strlen (base) - 1;
+ for (;;)
+ {
+ /* Skip trailing '/'s. */
+ if (pos > root_pos && base[pos] == G_DIR_SEPARATOR)
+ pos--;
+
+ match = check_components_match (base, path, root_pos, pos + 1);
+ if (match)
+ break;
+
+ /* They didn't match, so we move up one component and try again. */
+ num_parents++;
+ while (pos && base[pos] != G_DIR_SEPARATOR)
+ pos--;
+ }
+
+ /* If we match some components, build the relative path, else just return
+ path. */
+ if (match)
+ {
+ path_len = strlen (path);
+ /* Skip over the '/', but special case for root directory. */
+ if (pos == root_pos)
+ pos++;
+ else
+ pos += 2;
+ len = (num_parents * 3) + 1;
+ if (path_len > pos)
+ len += path_len - pos;
+ relative_path = g_malloc (len);
+ /* Add a '../' for each parent directory needed. */
+ for (i = 0; i < num_parents; i++)
+ {
+ relative_path[i * 3] = '.';
+ relative_path[i * 3 + 1] = '.';
+ relative_path[i * 3 + 2] = G_DIR_SEPARATOR;
+ }
+ /* Add on the end of path, skipping the '/' after the component. */
+ if (path_len > pos)
+ strcpy (relative_path + num_parents * 3, path + pos);
+ relative_path[len - 1] = '\0';
+
+ return relative_path;
+ }
+ else
+ return g_strdup (path);
+}
+
+
+/* This checks that the leading directory components of base match those in
+ path up to the given length. */
+static gboolean
+check_components_match (const gchar *base,
+ const gchar *path,
+ gint root_pos,
+ gint len)
+{
+ if (strncmp (base, path, len))
+ return FALSE;
+
+ /* We also need to check that it is a complete component in path, i.e.
+ "/home/damon" should NOT match "/home/damon2". But root dir is a
+ special case. "/" matches "/home". */
+ if (len == root_pos + 1 || path[len] == '\0' || path[len] == G_DIR_SEPARATOR)
+ return TRUE;
+ return FALSE;
+}
+
+
+/* Returns TRUE if file is in dir. Both paths must be absolute. file can
+ be a directory, and both can end in '/' or not. Note that we assume
+ that both are in proper form, i.e. there are no instances of '//', '.',
+ or '..' in either. */
+gboolean
+glade_util_directory_contains_file (const gchar *dir,
+ const gchar *file)
+{
+ gint dir_len, file_len;
+ gchar *next_dir_separator;
+
+ g_return_val_if_fail (g_path_is_absolute (dir), FALSE);
+ g_return_val_if_fail (g_path_is_absolute (file), FALSE);
+
+ dir_len = strlen (dir);
+ file_len = strlen (file);
+
+ /* First check that file matches dir up until dir finishes. */
+ if (strncmp (dir, file, dir_len))
+ return FALSE;
+
+ /* If dir doesn't end in a '/', then we also need to check that the next
+ character in file is a '/'. */
+ if (dir[dir_len - 1] != G_DIR_SEPARATOR)
+ {
+ if (file[dir_len] != G_DIR_SEPARATOR)
+ return FALSE;
+ dir_len++;
+ }
+
+ /* If file is equivalent to dir we return FALSE. */
+ if (dir_len == file_len)
+ return FALSE;
+
+ /* Now we need to check that file is not in a subdirectory, i.e. there are
+ no more '/'s in file except possibly for the last character. */
+ next_dir_separator = strchr (file + dir_len, G_DIR_SEPARATOR);
+ if (next_dir_separator && next_dir_separator < file + file_len - 1)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/* Returns TRUE if the 2 directories are equivalent. Both must be absolute
+ paths, and may or may not end in '/'. */
+gboolean
+glade_util_directories_equivalent (const gchar *dir1,
+ const gchar *dir2)
+{
+ gint dir1_len, dir2_len;
+
+ g_return_val_if_fail (g_path_is_absolute (dir1), FALSE);
+ g_return_val_if_fail (g_path_is_absolute (dir2), FALSE);
+
+ /* Find the length of both directories and decrement it if they end in a
+ '/'. */
+ dir1_len = strlen (dir1);
+ dir2_len = strlen (dir2);
+
+ if (dir1[dir1_len - 1] == G_DIR_SEPARATOR)
+ dir1_len--;
+ if (dir2[dir2_len - 1] == G_DIR_SEPARATOR)
+ dir2_len--;
+
+ /* Now both lengths must be equal and the directories must match up to
+ that point. */
+ if (dir1_len != dir2_len)
+ return FALSE;
+
+ if (strncmp (dir1, dir2, dir1_len))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/* This is similar to GLib's dirname, but it makes sure the dirname ends with
+ a G_DIR_SEPARATOR. The returned string should be freed later. */
+gchar*
+glade_util_dirname (const gchar *file_name)
+{
+ register gchar *base;
+ register guint len;
+
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ base = strrchr (file_name, G_DIR_SEPARATOR);
+ if (!base)
+ return g_strdup ("." G_DIR_SEPARATOR_S);
+ while (base > file_name && *base == G_DIR_SEPARATOR)
+ base--;
+ len = (guint) 1 + base - file_name;
+
+ base = g_new (gchar, len + 2);
+ g_memmove (base, file_name, len);
+ if (len > 1)
+ base[len++] = G_DIR_SEPARATOR;
+ base[len] = 0;
+
+ return base;
+}
+
+
+/* This returns the parent directory of the given directory, which may or may
+ not end in a G_DIR_SEPARATOR. If there is no parent directory, NULL is
+ returned. The returned string should be freed. dir MUST be absolute. */
+gchar*
+glade_util_parent_directory (const gchar *dir)
+{
+ gchar *skipped_root, *parent_dir;
+ gint pos;
+
+ g_return_val_if_fail (g_path_is_absolute (dir), NULL);
+
+ /* We handle the root dir specially here, and return NULL. */
+ skipped_root = (gchar*) g_path_skip_root ((gchar*) dir);
+ if (*skipped_root == '\0')
+ return NULL;
+
+ /* Ignore any G_DIR_SEPARATOR at the end of dir (just by skipping the last
+ char), and step back to the previous G_DIR_SEPARATOR. */
+ pos = strlen (dir) - 2;
+ while (pos >= 0 && dir[pos] != G_DIR_SEPARATOR)
+ pos--;
+
+ /* This shouldn't really happen, since we dealt with the root dir above,
+ but just in case. */
+ if (pos < 0)
+ return NULL;
+
+ /* Check if the parent directory is the root directory. If it is, we just
+ want to return the root directory, i.e. "/" or "C:\". */
+ if (pos <= skipped_root - dir)
+ pos = skipped_root - dir;
+
+ parent_dir = g_malloc (pos + 1);
+ strncpy (parent_dir, dir, pos);
+ parent_dir[pos] = '\0';
+
+ return parent_dir;
+}
+
+
+/* This searches the $HOME/Projects directory to find the default directory to
+ use for the next project, e.g. $HOME/Projects/project1. The returned
+ directory should be freed when no longer needed. */
+GladeError*
+glade_util_get_next_free_project_directory (gchar **project_directory_return,
+ gint *project_num_return)
+{
+ GladeError *error = NULL;
+ gchar *projects_dir, *project_string, *subdir;
+ const gchar *home_dir;
+ DIR *directory;
+ struct dirent *entry;
+ gint project_num, max_project_num, project_string_len;
+ gint num_matched, chars_matched;
+
+ home_dir = g_get_home_dir ();
+ if (home_dir)
+ {
+ projects_dir = glade_util_make_absolute_path (home_dir, _("Projects"));
+ }
+ else
+ {
+#ifdef _WIN32
+ projects_dir = g_strdup ("C:\\Projects");
+#else
+ /* Just use the root directory. Though it probably won't be writable. */
+ projects_dir = g_strdup (G_DIR_SEPARATOR_S);
+#endif
+ }
+
+ /* Step through the 'Projects' directory, if it exists, to find
+ subdirectories named 'projectXX', and get the highest number used so
+ far. */
+ max_project_num = 0;
+ directory = opendir (projects_dir);
+ project_string = _("project");
+ project_string_len = strlen (project_string);
+ if (directory == NULL)
+ {
+ if (errno != ENOENT)
+ {
+ error = glade_error_new_system (_("Couldn't open directory:\n %s\n"),
+ projects_dir);
+ g_free (projects_dir);
+ return error;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ entry = readdir (directory);
+
+ if (entry == NULL)
+ break;
+
+ if (!strncmp (entry->d_name, project_string, project_string_len))
+ {
+ /* Now see if it has a number on the end. */
+ num_matched = sscanf (entry->d_name + project_string_len,
+ "%i%n", &project_num, &chars_matched);
+ if (num_matched >= 1
+ && chars_matched == strlen (entry->d_name) - project_string_len)
+ {
+ max_project_num = MAX (max_project_num, project_num);
+ }
+ }
+ }
+
+ closedir (directory);
+ }
+
+ max_project_num++;
+ *project_num_return = max_project_num;
+ subdir = g_strdup_printf ("%s%i", project_string, max_project_num);
+ *project_directory_return = glade_util_make_absolute_path (projects_dir,
+ subdir);
+ g_free (subdir);
+ g_free (projects_dir);
+
+ return NULL;
+}
+
+
+/* This will hold the last "TZ=XXX" string we used with putenv(). After we
+ call putenv() again to set a new TZ string, we can free the previous one.
+ As far as I know, no libc implementations actually free the memory used in
+ the environment variables (how could they know if it is a static string or
+ a malloc'ed string?), so we have to free it ourselves. */
+static char* saved_tz = NULL;
+
+
+/* Sets the TZ environment variable to the given value, e.g. "UTC", returning
+ the old setting.
+ NOTE: You must call glade_util_reset_timezone() some time later to restore
+ the original TZ. Pass glade_util_reset_timezone() the string that
+ glade_util_set_timezone() returns. */
+gchar*
+glade_util_set_timezone (const gchar *tz)
+{
+ char *old_tz, *old_tz_copy = NULL, *new_tz;
+
+ /* Get the old TZ setting and save a copy of it to return. */
+ old_tz = getenv ("TZ");
+ if (old_tz)
+ {
+ old_tz_copy = g_malloc (strlen (old_tz) + 4);
+ strcpy (old_tz_copy, "TZ=");
+ strcpy (old_tz_copy + 3, old_tz);
+ }
+
+ /* Create the new TZ string. */
+ new_tz = g_malloc (strlen (tz) + 4);
+ strcpy (new_tz, "TZ=");
+ strcpy (new_tz + 3, tz);
+
+ /* Add the new TZ to the environment. */
+ putenv (new_tz);
+ tzset ();
+
+ /* Free any previous TZ environment string we have used. */
+ if (saved_tz)
+ g_free (saved_tz);
+
+ /* Save a pointer to the TZ string we just set, so we can free it later. */
+ saved_tz = new_tz;
+
+ return old_tz_copy; /* This will be zero if the TZ env var was not set */
+}
+
+
+void
+glade_util_reset_timezone (gchar *tz)
+{
+ /* restore the original TZ setting. */
+ if (tz)
+ putenv (tz);
+ else
+ putenv ("TZ"); /* Delete from environment */
+
+ tzset ();
+
+ /* Free any previous TZ environment string we have used. */
+ if (saved_tz)
+ g_free (saved_tz);
+
+ /* Save a pointer to the TZ string we just set, so we can free it later.
+ (This can possibly be NULL if there was no TZ to restore.) */
+ saved_tz = tz;
+}
+
+
+gboolean
+glade_util_check_is_stock_id (const gchar *stock_id)
+{
+ static GHashTable *stock_hash = NULL;
+
+ gboolean retval = FALSE;
+
+ /* Create a hash of stock ids, so future calls will be fast. */
+ if (!stock_hash)
+ {
+ GSList *stock_items, *elem;
+
+ stock_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ stock_items = gtk_stock_list_ids ();
+ for (elem = stock_items; elem; elem = elem->next)
+ {
+ /* We just use the stock id for the key and the data, as we don't
+ need to store anything. We should free the keys at some point,
+ but we need them until Glade exits. */
+ g_hash_table_insert (stock_hash, elem->data, elem->data);
+ }
+
+ g_slist_free (stock_items);
+ }
+
+ if (stock_id && g_hash_table_lookup (stock_hash, stock_id))
+ retval = TRUE;
+
+#if 0
+ g_print ("glade_util_check_is_stock_id: %s -> %i\n",
+ stock_id ? stock_id : "", retval);
+#endif
+
+ return retval;
+}
+
+
+static gint
+compare_uline_labels (const gchar *labela, const gchar *labelb)
+{
+ for (;;) {
+ gunichar c1, c2;
+
+ if (*labela == '\0')
+ return (*labelb == '\0') ? 0 : -1;
+ if (*labelb == '\0')
+ return 1;
+
+ c1 = g_utf8_get_char (labela);
+ if (c1 == '_')
+ {
+ labela = g_utf8_next_char (labela);
+ c1 = g_utf8_get_char (labela);
+ }
+
+ c2 = g_utf8_get_char (labelb);
+ if (c2 == '_')
+ {
+ labelb = g_utf8_next_char (labelb);
+ c2 = g_utf8_get_char (labelb);
+ }
+
+ if (c1 < c2)
+ return -1;
+ if (c1 > c2)
+ return 1;
+
+ labela = g_utf8_next_char (labela);
+ labelb = g_utf8_next_char (labelb);
+ }
+
+ /* Shouldn't be reached. */
+ return 0;
+}
+
+
+/* This is a GCompareFunc for comparing the labels of 2 stock items, ignoring
+ any '_' characters. It isn't particularly efficient. */
+gint
+glade_util_compare_stock_labels (gconstpointer a, gconstpointer b)
+{
+ const gchar *stock_ida = a, *stock_idb = b;
+ GtkStockItem itema, itemb;
+ gboolean founda, foundb;
+ gint retval;
+
+ founda = gtk_stock_lookup (stock_ida, &itema);
+ foundb = gtk_stock_lookup (stock_idb, &itemb);
+
+ if (founda)
+ {
+ if (!foundb)
+ retval = -1;
+ else
+ /* FIXME: Not ideal for UTF-8. */
+ retval = compare_uline_labels (itema.label, itemb.label);
+ }
+ else
+ {
+ if (!foundb)
+ retval = 0;
+ else
+ retval = 1;
+ }
+
+ return retval;
+}
+
+
+/* These are pinched from gtkcombo.c */
+gpointer /* GtkListItem * */
+glade_util_gtk_combo_find (GtkCombo * combo)
+{
+ gchar *text;
+ gchar *ltext;
+ GList *clist;
+ int (*string_compare) (const char *, const char *);
+
+ if (combo->case_sensitive)
+ string_compare = strcmp;
+ else
+ string_compare = g_strcasecmp;
+
+ text = (gchar*) gtk_entry_get_text (GTK_ENTRY (combo->entry));
+ clist = GTK_LIST (combo->list)->children;
+
+ while (clist && clist->data)
+ {
+ ltext = glade_util_gtk_combo_func (GTK_LIST_ITEM (clist->data));
+ if (!ltext)
+ continue;
+ if (!(*string_compare) (ltext, text))
+ return (GtkListItem *) clist->data;
+ clist = clist->next;
+ }
+
+ return NULL;
+}
+
+gchar *
+glade_util_gtk_combo_func (gpointer data)
+{
+ GtkListItem * listitem = data;
+
+ /* I needed to pinch this as well - Damon. */
+ static const gchar *gtk_combo_string_key = "gtk-combo-string-value";
+
+ GtkWidget *label;
+ gchar *ltext = NULL;
+
+ ltext = (gchar *) gtk_object_get_data (GTK_OBJECT (listitem),
+ gtk_combo_string_key);
+ if (!ltext)
+ {
+ label = GTK_BIN (listitem)->child;
+ if (!label || !GTK_IS_LABEL (label))
+ return NULL;
+ ltext = (gchar*) gtk_label_get_text (GTK_LABEL (label));
+ }
+ return ltext;
+}
+
+/**
+ * glade_enum_from_string
+ * @type: the GType for this enum type.
+ * @string: the string representation of the enum value.
+ *
+ * This helper routine is designed to be used by widget build routines to
+ * convert the string representations of enumeration values found in the
+ * XML descriptions to the integer values that can be used to configure
+ * the widget.
+ *
+ * Returns: the integer value for this enumeration, or 0 if it couldn't be
+ * found.
+ */
+gint
+glade_enum_from_string (GType type, const char *string)
+{
+ GEnumClass *eclass;
+ GEnumValue *ev;
+ gchar *endptr;
+ gint ret = 0;
+
+ ret = strtoul(string, &endptr, 0);
+ if (endptr != string) /* parsed a number */
+ return ret;
+
+ eclass = g_type_class_ref(type);
+ ev = g_enum_get_value_by_name(eclass, string);
+ if (!ev) ev = g_enum_get_value_by_nick(eclass, string);
+ if (ev) ret = ev->value;
+
+ g_type_class_unref(eclass);
+
+ return ret;
+}
+
+/**
+ * glade_string_from_enum
+ * @type: the GType for this enum type.
+ * @value: the value of the enum
+ *
+ * This helper routine is designed to be used by widget build routines to
+ * convert the string representations of enumeration values found in the
+ * XML descriptions to the integer values that can be used to configure
+ * the widget.
+ *
+ * Returns: the string value for this enumeration
+ */
+const char *
+glade_string_from_enum (GType type, gint value)
+{
+ GEnumClass *eclass;
+ GEnumValue *ev;
+
+ eclass = g_type_class_ref(type);
+
+ ev = g_enum_get_value (eclass, value);
+
+ g_type_class_unref(eclass);
+
+ return ev ? ev->value_name : "0";
+}
+
+
+/**
+ * glade_util_flags_from_string
+ * @type: the GType for this flags type.
+ * @string: the string representation of the flags value.
+ *
+ * This helper routine is designed to be used by widget build routines
+ * to convert the string representations of flags values found in the
+ * XML descriptions to the integer values that can be used to
+ * configure the widget. The string is composed of string names or
+ * nicknames for various flags separated by '|'.
+ *
+ * Returns: the integer value for this flags string
+ */
+guint
+glade_util_flags_from_string (GType type, const char *string)
+{
+ GFlagsClass *fclass;
+ gchar *endptr, *prevptr;
+ guint i, j, ret = 0;
+ char *flagstr;
+
+ ret = strtoul(string, &endptr, 0);
+ if (endptr != string) /* parsed a number */
+ return ret;
+
+ fclass = g_type_class_ref(type);
+
+
+ flagstr = g_strdup (string);
+ for (ret = i = j = 0; ; i++) {
+ gboolean eos;
+
+ eos = flagstr [i] == '\0';
+
+ if (eos || flagstr [i] == '|') {
+ GFlagsValue *fv;
+ const char *flag;
+ gunichar ch;
+
+ flag = &flagstr [j];
+ endptr = &flagstr [i];
+
+ if (!eos) {
+ flagstr [i++] = '\0';
+ j = i;
+ }
+
+ /* trim spaces */
+ for (;;)
+ {
+ ch = g_utf8_get_char (flag);
+ if (!g_unichar_isspace (ch))
+ break;
+ flag = g_utf8_next_char (flag);
+ }
+
+ while (endptr > flag)
+ {
+ prevptr = g_utf8_prev_char (endptr);
+ ch = g_utf8_get_char (prevptr);
+ if (!g_unichar_isspace (ch))
+ break;
+ endptr = prevptr;
+ }
+
+ if (endptr > flag)
+ {
+ *endptr = '\0';
+ fv = g_flags_get_value_by_name (fclass, flag);
+
+ if (!fv)
+ fv = g_flags_get_value_by_nick (fclass, flag);
+
+ if (fv)
+ ret |= fv->value;
+ else
+ g_warning ("Unknown flag: '%s'", flag);
+ }
+
+ if (eos)
+ break;
+ }
+ }
+
+ g_free (flagstr);
+
+ g_type_class_unref(fclass);
+
+ return ret;
+}
+
+/**
+ * glade_util_string_from_flags
+ * @type: the GType for this flags type.
+ * @flags: the value of the flags
+ *
+ * This helper routine is designed to be used by widget build routines
+ * to convert the flags values into the string representations in the
+ * XML descriptions.
+ * The string is composed of string names or
+ * nicknames for various flags separated by '|'.
+ *
+ * Returns: the string representation of these flags. Must be freed.
+ */
+gchar *
+glade_util_string_from_flags (GType type, guint flags)
+{
+ GFlagsClass *flags_class;
+ GString *string;
+ char *ret;
+
+ flags_class = g_type_class_ref (type);
+
+ string = g_string_new ("");
+
+ if (flags_class->n_values)
+ {
+ GFlagsValue *fval;
+
+ for (fval = flags_class->values; fval->value_name; fval++)
+ {
+ /* We have to be careful as some flags include 0 values, e.g.
+ BonoboDockItemBehavior uses 0 for BONOBO_DOCK_ITEM_BEH_NORMAL.
+ If a 0 value is available, we only output it if the entire
+ flags value is 0, otherwise we check if the bit-flag is set. */
+ if ((fval->value == 0 && flags == 0)
+ || (fval->value && (fval->value & flags) == fval->value))
+ {
+ if (string->len)
+ g_string_append_c (string, '|');
+ g_string_append (string, fval->value_name);
+ }
+ }
+ }
+
+ ret = string->str;
+ g_string_free (string, FALSE);
+
+ g_type_class_unref (flags_class);
+
+ return ret;
+}
+
+
+/* Returns TRUE if the widget should have a border width property.
+ Containers normally do, but Bonobo controls don't.
+ Also, GtkDialog widgets and their action area hbuttonboxes don't, as they
+ use style properties. */
+gboolean
+glade_util_uses_border_width (GtkWidget *widget)
+{
+ char *child_name = gb_widget_get_child_name (widget);
+
+#ifdef USE_GNOME
+ if (BONOBO_IS_WIDGET (widget))
+ return FALSE;
+#endif
+
+ /* The GtkDialog vbox has its border width set from a style property, so
+ we shouldn't show the property in Glade. */
+ if (GTK_IS_VBOX (widget) && widget->parent && GTK_IS_DIALOG (widget->parent))
+ return FALSE;
+
+ if (child_name && !strcmp (child_name, GladeChildDialogActionArea))
+ return FALSE;
+
+ if (GTK_IS_CONTAINER (widget))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/* Converts a filename from UTF-8 to on-disk encoding, and sets it in a
+ GtkFileSelection. */
+void
+glade_util_set_file_selection_filename (GtkWidget *filesel,
+ const gchar *filename_utf8)
+{
+ gchar *on_disk_filename;
+
+ on_disk_filename = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL,
+ NULL);
+
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filesel),
+ on_disk_filename);
+ g_free (on_disk_filename);
+}
+
+
+/* Gets the selected file in a GtkFileSelection, converts it to UTF-8 and
+ returns it. Note that the returned string must be freed. */
+gchar*
+glade_util_get_file_selection_filename (GtkWidget *filesel)
+{
+ const gchar *on_disk_filename;
+ gchar *filename;
+
+ on_disk_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filesel));
+ filename = g_filename_to_utf8 (on_disk_filename, -1, NULL, NULL, NULL);
+ return filename;
+}
+
+
+/* Like fopen but takes a UTF-8 filename and converts to on-disk encoding. */
+FILE*
+glade_util_fopen (const gchar *filename_utf8, const gchar *mode)
+{
+ gchar *on_disk_filename;
+ FILE *fp;
+
+ on_disk_filename = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL,
+ NULL);
+ fp = fopen (on_disk_filename, mode);
+ g_free (on_disk_filename);
+ return fp;
+}
+
+
+/**
+ * glade_util_uri_list_parse:
+ * @uri_list: the text/urilist, must be NULL terminated.
+ *
+ * Extracts a list of file names from a standard text/uri-list,
+ * such as one you would get on a drop operation.
+ * This is mostly stolen from gnome-vfs-uri.c.
+ *
+ * Returns a GList of gchars.
+ **/
+GList *
+glade_util_uri_list_parse (const gchar *uri_list)
+{
+ const gchar *p, *q;
+ GList *result = NULL;
+
+ g_return_val_if_fail (uri_list != NULL, NULL);
+
+ p = uri_list;
+
+ /* We don't actually try to validate the URI according to RFC
+ * 2396, or even check for allowed characters - we just ignore
+ * comments and trim whitespace off the ends. We also
+ * allow LF delimination as well as the specified CRLF.
+ */
+ while (p)
+ {
+ if (*p != '#')
+ {
+ gchar *retval;
+ gchar *path;
+
+ while (g_ascii_isspace (*p))
+ p++;
+
+ q = p;
+ while ((*q != '\0') && (*q != '\n') && (*q != '\r'))
+ q++;
+
+ if (q > p)
+ {
+ q--;
+ while (q > p && g_ascii_isspace (*q))
+ q--;
+
+ retval = g_new (gchar, q - p + 2);
+ memcpy (retval, p, q - p + 1);
+ retval[q - p + 1] = '\0';
+
+ path = g_filename_from_uri (retval, NULL, NULL);
+ if (!path)
+ {
+ g_free (retval);
+ continue;
+ }
+
+ result = g_list_prepend (result, path);
+
+ g_free (retval);
+ }
+ }
+ p = strchr (p, '\n');
+ if (p)
+ p++;
+ }
+
+ return g_list_reverse (result);
+}
+
+
+void
+glade_util_get_translation_properties (GtkWidget *widget,
+ const gchar *property_name,
+ gboolean *translatable,
+ gchar **comments,
+ gboolean *context)
+{
+ gchar buffer[1024];
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ sprintf (buffer, "%s:::comments", property_name);
+ *comments = g_object_get_data (G_OBJECT (widget), buffer);
+
+ /* This defaults to TRUE if no object data is set. */
+ sprintf (buffer, "%s:::not_translatable", property_name);
+ *translatable = g_object_get_data (G_OBJECT (widget), buffer) ? FALSE : TRUE;
+
+ /* This defaults to FALSE if no object data is set. */
+ sprintf (buffer, "%s:::context", property_name);
+ *context = g_object_get_data (G_OBJECT (widget), buffer) ? TRUE : FALSE;
+}
+
+
+void
+glade_util_set_translation_properties (GtkWidget *widget,
+ const gchar *property_name,
+ gboolean translatable,
+ const gchar *comments,
+ gboolean context)
+{
+ gchar buffer[1024];
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ sprintf (buffer, "%s:::comments", property_name);
+ g_object_set_data_full (G_OBJECT (widget), buffer,
+ g_strdup (comments), comments ? g_free : NULL);
+
+ sprintf (buffer, "%s:::not_translatable", property_name);
+ g_object_set_data (G_OBJECT (widget), buffer, translatable ? NULL : "N");
+
+ sprintf (buffer, "%s:::context", property_name);
+ g_object_set_data (G_OBJECT (widget), buffer, context ? "Y" : NULL);
+}
+
+
+/* Copies the extra translation properties stored inside the widget data. */
+void
+glade_util_copy_translation_properties (GtkWidget *from_widget,
+ const gchar *from_property_name,
+ GtkWidget *to_widget,
+ const gchar *to_property_name)
+{
+ gchar *comments;
+ gboolean translatable, context;
+
+ g_return_if_fail (GTK_IS_WIDGET (from_widget));
+ g_return_if_fail (GTK_IS_WIDGET (to_widget));
+
+ /* Copy the translator comments string, and translatable & context flags
+ from one widget to the other. */
+ glade_util_get_translation_properties (from_widget, from_property_name,
+ &translatable, &comments, &context);
+ glade_util_set_translation_properties (to_widget, to_property_name,
+ translatable, comments, context);
+}
+
diff --git a/tools/glade/glade/utils.h b/tools/glade/glade/utils.h
new file mode 100644
index 00000000..0a591142
--- /dev/null
+++ b/tools/glade/glade/utils.h
@@ -0,0 +1,386 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef GLADE_UTILS_H
+#define GLADE_UTILS_H
+
+#include <stdio.h>
+
+#include <gtk/gtkbox.h>
+#include <gtk/gtkcombo.h>
+#include <gtk/gtkfixed.h>
+#include <gtk/gtklistitem.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktoolbar.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkobject.h>
+
+#include "gbwidget.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Days of the week, 'Sun' ... 'Sat'. */
+extern gchar *GladeDayNames[];
+/* Months of the year, 'Jan' ... 'Dec'. */
+extern gchar *GladeMonthNames[];
+
+
+/* This shows a simple dialog box with a label and an 'OK' button.
+ If transient_widget is not NULL, then its toplevel window is found and used
+ to set the transient_for property (this also works for menu widgets).
+
+ Example usage:
+ glade_util_show_message_box ("Error saving file", NULL);
+ */
+void glade_util_show_message_box (const gchar *message,
+ GtkWidget *transient_widget);
+
+
+/* This creates a dialog box with a message and a number of buttons.
+ * Signal handlers can be supplied for any of the buttons.
+ * NOTE: The dialog is automatically destroyed when any button is clicked.
+ * default_button specifies the default button, numbered from 1..
+ * data is passed to the signal handler.
+
+ Example usage:
+ gchar *buttons[] = { "Yes", "No", "Cancel" };
+ GtkSignalFunc signal_handlers[] = { on_yes, on_no, NULL };
+ glade_util_show_dialog ("Do you want to save the current project?",
+ 3, buttons, 3, signal_handlers, NULL);
+ */
+GtkWidget* glade_util_create_dialog_with_buttons (const gchar *message,
+ gint nbuttons,
+ const gchar *buttons[],
+ gint default_button,
+ GtkSignalFunc signal_handlers[],
+ gpointer data,
+ GtkWidget *transient_widget);
+
+
+/* This shows a dialog box with a message and an Entry for entering a value.
+ * When the OK button is pressed the handler of the specified widget will
+ * be called with the value and the given data.
+ * NOTE: The dialog is automatically destroyed when any button is clicked.
+
+ Example usage:
+ glade_util_show_entry_dialog ("Name:", "default", widget, on_dialog_ok,
+ "NewName");
+
+ void
+ on_dialog_ok(GtkWidget *widget, gchar *value, gpointer data)
+ {
+ ...
+ */
+typedef gint (*GbEntryDialogFunc) (GtkWidget *widget,
+ gchar *value,
+ gpointer data);
+
+void glade_util_show_entry_dialog(const gchar *message,
+ const gchar *initial_value,
+ GtkWidget *widget,
+ GbEntryDialogFunc signal_handler,
+ gpointer data,
+ GtkWidget *transient_widget);
+
+
+/* This creates a dialog with OK & Cancel buttons, usable in plain GTK or
+ Gnome, and returns a vbox which the caller can place widgets in.
+ If transient_for is non-NULL, the window it is in is used to set the
+ transient for relationship, so the dialog will always be above the widget.
+ The callback will be called when the OK button is pressed. */
+GtkWidget* glade_util_create_dialog (const gchar *title,
+ GtkWidget *transient_for,
+ GtkSignalFunc ok_handler,
+ gpointer ok_handler_data,
+ GtkWidget **vbox);
+
+
+typedef enum
+{
+ GladeEscCloses,
+ GladeEscDestroys
+} GladeEscAction;
+
+
+/* This event handler performs the selected GladeEscAction when Esc is
+ pressed in a dialog.
+ It is not necessary for GnomeDialogs. */
+gint glade_util_check_key_is_esc (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data);
+
+
+/* This returns a new entry ready to insert in a dialog.
+ The entry is set up so that <Return> will invoke the default action. The
+ returned widget must be added to a container in the dialog. */
+extern GtkWidget *
+glade_util_entry_new (GtkObject *dialog);
+
+
+/* This returns a new spinbutton ready to insert in a dialog.
+ A pointer to the spin button is added as object data to the dialog. The
+ spinbutton is set up so that <Return> will invoke the default action. The
+ returned widget must be added to a container in the dialog. */
+extern GtkWidget *
+glade_util_spin_button_new (GtkObject *dialog,
+ const gchar *key,
+ GtkAdjustment *adjustment,
+ gfloat climb_rate,
+ guint digits);
+
+
+/* This returns the index of the given gint with the given array of gints.
+ If the value is not found it outputs a warning and returns -1.
+ This function is intended to be used for finding the index when using
+ properties which are choices. */
+gint glade_util_int_array_index (const gint array[],
+ gint array_size,
+ gint value);
+
+/* This returns the index of the given string with the given array of strings.
+ If the value is not found it outputs a warning and returns -1.
+ This function is intended to be used for finding the index when using
+ properties which are choices. */
+gint glade_util_string_array_index (const gchar *array[],
+ gint array_size,
+ const gchar *value);
+
+/* This returns TRUE if the two strings are equivalent. Note that NULL is
+ considered equivalent to the empty string. */
+gboolean glade_util_strings_equivalent (const gchar *string1,
+ const gchar *string2);
+/* This returns a copy of the given string, or NULL if the string is NULL
+ or empty, i.e. "". */
+gchar* glade_util_copy_string (const gchar *string);
+/* Returns TRUE if string contains substring. Returns FALSE if substring is
+ not found or is NULL. */
+gboolean glade_util_strstr (const gchar *string,
+ const gchar *substring);
+
+gchar* glade_util_find_start_of_tag_name (const gchar * tag_name);
+
+gchar* glade_util_create_modifiers_string (guint8 modifier_flags);
+
+/* parse a string in the form of "GTK_ANCHOR_NE|GTK_ANCHOR_SW" */
+guint glade_util_flags_from_string (GType type, const char *string);
+gchar* glade_util_string_from_flags (GType type, guint flags);
+
+const char *glade_string_from_enum (GType type, gint value);
+
+gint glade_enum_from_string (GType type, const char *string);
+
+
+/* This creates a GtkPixmap widget, using a colormap and xpm data from an
+ '#include'd pixmap file. */
+GtkWidget* glade_util_create_pixmap_using_colormap (GdkColormap *colormap,
+ gchar **xpm_data);
+
+/* This returns TRUE if the widget is a toplevel project component,
+ i.e. a window, dialog or popup menu. */
+gboolean glade_util_is_component (GtkWidget *widget);
+
+/* This returns the toplevel widget containing the given widget. It is similar
+ to gtk_widget_get_toplevel() but is also walks up menus. */
+GtkWidget* glade_util_get_toplevel (GtkWidget *widget);
+
+/* This returns the closest ancestor of the given widget which is a GbWidget.*/
+GtkWidget* glade_util_get_parent (GtkWidget *widget);
+
+/* This tries to find a named widget in a component. It returns the widget or
+ NULL if it wasn't found. */
+GtkWidget* glade_util_find_widget (GtkWidget *widget, gchar *name);
+
+
+/* This is used when setting up keyboard accelerators resulting from underlined
+ keys in labels. It returns the mnemonic widget to use. */
+GtkWidget* glade_util_find_default_accelerator_target (GtkWidget *label);
+
+/* Returns the index of a widget in a box. Note that the box packing
+ property means that widgets may not be displayed in this order. */
+gint glade_util_get_box_pos (GtkBox *box,
+ GtkWidget *widget);
+
+/* Returns the structure corresponding to the given widget in a table. */
+GtkTableChild* glade_util_find_table_child (GtkTable *table,
+ GtkWidget *widget);
+GtkBoxChild* glade_util_find_box_child (GtkBox *box,
+ GtkWidget *widget);
+GtkFixedChild* glade_util_find_fixed_child (GtkFixed *fixed,
+ GtkWidget *widget);
+#if GLADE_SUPPORTS_GTK_PACKER
+GtkPackerChild* glade_util_find_packer_child (GtkPacker *packer,
+ GtkWidget *widget);
+#endif
+
+/* This returns the GtkLabel's text, including the underline characters.
+ It is needed since GtkLabel doesn't provide the opposite function to
+ gtk_label_parse_uline(). The returned string should be freed after use. */
+gchar* glade_util_get_label_text (GtkWidget *label);
+
+/* These close the given window, so that if it is shown again it appears in
+ the same place. */
+gint glade_util_close_window_on_delete (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data);
+gint glade_util_close_window (GtkWidget *widget);
+
+
+
+/*
+ * File Utility Functions.
+ */
+
+/* Returns TRUE if the given file exists. filename must be UTF-8. */
+gboolean glade_util_file_exists (const gchar *filename);
+
+/* Returns the last modification time of the given file, or 0 if it doesn't
+ exist, or -1 on error. filename must be UTF-8. */
+GladeError* glade_util_file_last_mod_time (const gchar *filename,
+ time_t *last_mod_time);
+
+/* This copies a file from src to dest, and returns a GladeError if an error
+ occurs. src & dest must be UTF-8. */
+GladeError* glade_util_copy_file (const gchar *src,
+ const gchar *dest);
+
+/* Creates a directory if it doesn't already exist. */
+GladeError* glade_util_ensure_directory_exists (const gchar *directory);
+
+/*
+ * Filename Utility Functions.
+ */
+
+/* Adds a filename onto a directory to make a complete pathname.
+ The directory may or may not end in '/'. file must be a simple filename.
+ Free the returned string when no longer needed. */
+gchar* glade_util_make_path (const gchar *dir,
+ const gchar *file);
+
+/* This turns a relative pathname into an absolute one based on the given
+ base directory (which MUST be absolute).
+ e.g. "/home/damon" + "../dave/test" -> "/home/dave/test"
+ The returned path should be freed when no longer needed. */
+gchar* glade_util_make_absolute_path (const gchar *dir,
+ const gchar *file);
+
+/* This turns an absolute pathname into an relative one based on the given
+ base directory. Both arguments must be absolute paths, and should be in
+ canonical form, i.e. not containing '..', '.' or multiple '/'s together.
+ The returned value may or may not end with a '/', depending on the
+ arguments. The returned path should be freed when no longer needed. */
+gchar* glade_util_make_relative_path (const gchar *base_dir,
+ const gchar *file);
+
+/* Returns TRUE if file is in dir. Both paths must be absolute. file can
+ be a directory, and both can end in '/' or not. Note that we assume
+ that both are in proper form, i.e. there are no instances of '//', '.',
+ or '..' in either. */
+gboolean glade_util_directory_contains_file (const gchar *dir,
+ const gchar *file);
+
+/* Returns TRUE if the 2 directories are equivalent. Both must be absolute
+ paths, and may or may not end in '/'. */
+gboolean glade_util_directories_equivalent (const gchar *dir1,
+ const gchar *dir2);
+
+
+/* This is similar to GLib's dirname, but it makes sure the dirname ends with
+ a G_DIR_SEPARATOR. */
+gchar* glade_util_dirname (const gchar *file_name);
+
+/* This returns the parent directory of the given directory, which may or may
+ not end in a G_DIR_SEPARATOR. The returned string should be freed. */
+gchar* glade_util_parent_directory (const gchar *dir);
+
+
+/* This searches the $HOME/Projects directory to find the default directory to
+ use for the next project, e.g. $HOME/Projects/project1. The returned
+ directory should be freed when no longer needed. */
+GladeError* glade_util_get_next_free_project_directory (gchar **project_directory_return,
+ gint *project_num_return);
+
+
+/* Sets the TZ environment variable to the given value, e.g. "UTC", returning
+ the old setting.
+ NOTE: You must call glade_util_reset_timezone() some time later to restore
+ the original TZ. Pass glade_util_reset_timezone() the string that
+ glade_util_set_timezone() returns. */
+gchar* glade_util_set_timezone (const gchar *tz);
+void glade_util_reset_timezone (gchar *tz);
+
+
+gboolean glade_util_check_is_stock_id (const gchar *stock_id);
+
+/* This is a GCompareFunc for comparing the labels of 2 stock items, ignoring
+ any '_' characters. It isn't particularly efficient. */
+gint glade_util_compare_stock_labels (gconstpointer a,
+ gconstpointer b);
+
+
+/* FIXME: These are pinched from gtkcombo.c. Get rid of them. */
+/* GtkListItem *glade_util_gtk_combo_find (GtkCombo *combo);*/
+/*gchar *glade_util_gtk_combo_func (GtkListItem *listitem);*/
+gpointer glade_util_gtk_combo_find (GtkCombo *combo);
+gchar *glade_util_gtk_combo_func (gpointer listitem);
+
+/* Returns TRUE if we need to support a 'Border Width' property for a widget.*/
+gboolean glade_util_uses_border_width (GtkWidget *widget);
+
+/* Converts a filename from UTF-8 to on-disk encoding, and sets it in a
+ GtkFileSelection. */
+void glade_util_set_file_selection_filename(GtkWidget *filesel,
+ const gchar *filename_utf8);
+/* Gets the selected file in a GtkFileSelection, converts it to UTF-8 and
+ returns it. Note that the returned string must be freed. */
+gchar* glade_util_get_file_selection_filename(GtkWidget *filesel);
+
+/* Like fopen but takes a UTF-8 filename and converts to on-disk encoding. */
+FILE* glade_util_fopen (const gchar *filename_utf8,
+ const gchar *mode);
+
+/* Gets a list of file names from a text/uri-list */
+GList *glade_util_uri_list_parse (const gchar *uri_list);
+
+/* Gets the extra translation properties stored inside the widget data. */
+void glade_util_get_translation_properties (GtkWidget *widget,
+ const gchar *property_name,
+ gboolean *translatable,
+ gchar **comments,
+ gboolean *context);
+
+/* Sets the extra translation properties stored inside the widget data. */
+void glade_util_set_translation_properties (GtkWidget *widget,
+ const gchar *property_name,
+ gboolean translatable,
+ const gchar *comments,
+ gboolean context);
+
+/* Copies the extra translation properties stored inside the widget data. */
+void glade_util_copy_translation_properties(GtkWidget *from_widget,
+ const gchar *from_property_name,
+ GtkWidget *to_widget,
+ const gchar *to_property_name);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLADE_UTILS_H */