Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Marecki <hippiecoder@gmail.com>2010-10-28 03:51:25 +0400
committerMichael Hutchinson <mhutchinson@novell.com>2010-10-28 10:03:05 +0400
commit2778758acfe2a7132b9550a5f5ffca1d1126f8c9 (patch)
treef38581ceb8f88493b6e9f754bf6e1a8850fead79 /main/src/addins/MonoDevelop.GtkCore2
parent7b44f72cb54224ba9889720891bcf83ef09df953 (diff)
Import MonoDevelop.GtkCore2
Diffstat (limited to 'main/src/addins/MonoDevelop.GtkCore2')
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/AssemblyInfo.cs9
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/ChangeLog2935
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/ChangeLog.stetic6477
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/Makefile.am112
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/ChangeLog4
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/GtkCommands.cs45
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs186
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ChangeLog18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs79
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs64
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs81
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs40
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs93
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs143
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs206
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs316
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ChangeLog101
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ClassUtils.cs64
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs360
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs307
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs71
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs105
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs104
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs743
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs635
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs613
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs260
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs211
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs77
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs201
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs145
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ChangeLog83
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs42
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs177
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs52
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs179
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs156
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs140
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs88
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ChangeLog68
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/Counters.cs38
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkCoreService.cs43
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkDesignInfo.cs676
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ObjectsDocument.cs301
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ProjectResourceProvider.cs89
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ReferenceManager.cs291
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs172
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetParser.cs226
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.addin.xml210
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.csproj223
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.sln32
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.xbuild.csproj232
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/README14
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/addin-project.xml7
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/build/debug/Mono.TextEditor.dll.config18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Core.dll.config4
-rwxr-xr-xmain/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exebin0 -> 11264 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe.config16
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/build/debug/libstetic2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/build/debug/libsteticui2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/changes.patch6455
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/gtk-gui/ChangeLog50
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs40
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs183
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/gtk-gui/generated.cs82
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/gtk-gui/gui.stetic231
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/gui.glade710
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/ChangeLog5
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/actiongroup.pngbin0 -> 274 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/dialog.pngbin0 -> 671 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo-orig.pngbin0 -> 31621 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo.pngbin0 -> 21915 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/gtkx.pngbin0 -> 4683 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/image-x-generic.pngbin0 -> 558 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/widget.pngbin0 -> 337 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/icons/window.pngbin0 -> 321 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ChangeLog1793
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ClassDescriptor.cs344
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/Clipboard.cs91
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/CommandDescriptor.cs152
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/CustomWidget.cs27
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/DND.cs630
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/EnumDescriptor.cs86
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ErrorWidget.cs111
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/GeneratorContext.cs546
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeException.cs59
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeUtils.cs773
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/IDesignArea.cs39
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/IEditableObject.cs18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/IProject.cs33
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/IPropertyEditor.cs23
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/IRadioGroupManager.cs21
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/IResourceProvider.cs72
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ImageInfo.cs215
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemDescriptor.cs158
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroup.cs78
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroupCollection.cs42
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/Makefile.am269
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/NoGuiDispatchAttribute.cs9
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectReader.cs38
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapper.cs482
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapperEventHandler.cs20
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWriter.cs38
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ParamSpec.cs225
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/Placeholder.cs149
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/ProjectIconFactory.cs335
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyDescriptor.cs310
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorAttribute.cs36
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorCell.cs302
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/RadioGroupManager.cs212
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/Registry.cs370
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/Set.cs51
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/SignalDescriptor.cs70
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelDialog.cs39
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelWindow.cs57
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/TranslatableAttribute.cs8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedClassDescriptor.cs221
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedPropertyDescriptor.cs321
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedSignalDescriptor.cs59
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetLibrary.cs163
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetUtils.cs393
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/bin/Release/libstetic2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Accelerator.cs196
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionGroupEditor.cs577
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionItem.cs209
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenu.cs650
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuBar.cs555
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuItem.cs588
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolItem.cs371
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolbar.cs542
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Boolean.cs67
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/CellRendererComboBox.cs111
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ChangeLog16
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Char.cs45
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Color.cs54
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/DateTimeEditor.cs72
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconDialog.cs284
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconFactoryDialog.cs95
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Enumeration.cs87
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Flags.cs174
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FlagsSelectorDialog.cs79
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FloatRange.cs47
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/GroupPicker.cs175
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconList.cs205
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorItem.cs285
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenu.cs56
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenuItem.cs59
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Identifier.cs78
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Image.cs265
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageFile.cs10
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageSelector.cs177
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IntRange.cs120
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/NonContainerWarningDialog.cs51
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/OptIntRange.cs90
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconList.cs29
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconSelectorItem.cs21
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ResponseId.cs100
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectIconDialog.cs179
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectImageDialog.cs314
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconList.cs27
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconSelectorItem.cs134
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockItem.cs200
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/String.cs44
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StringArray.cs99
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Text.cs14
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextBox.cs51
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditor.cs83
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditorDialog.cs70
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIcon.cs162
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIconList.cs1018
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TimeSpanEditor.cs67
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Translatable.cs233
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TreeViewCellContainer.cs82
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/WidgetSelector.cs98
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.csproj471
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.csproj471
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/stetic.glade2107
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/ActionDiffAdaptor.cs273
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/DiffGenerator.cs319
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/IDiffAdaptor.cs31
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/UndoManager.cs315
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/XmlDiffAdaptor.cs230
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/AboutDialog.cs75
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Action.cs504
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionGroup.cs425
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionToolbarWrapper.cs294
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionTree.cs351
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Bin.cs388
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Box.cs276
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Button.cs339
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ButtonBox.cs161
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ChangeLog12
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/CheckButton.cs90
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ColorButton.cs37
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBox.cs122
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBoxEntry.cs32
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Container.cs1456
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Custom.cs123
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Dialog.cs183
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Entry.cs15
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Expander.cs80
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Fixed.cs91
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontButton.cs22
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontSelectionDialog.cs19
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Frame.cs92
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScale.cs18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScrollbar.cs18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/IconView.cs39
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Image.cs80
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ImageMenuItem.cs62
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Label.cs49
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuBar.cs261
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuItem.cs110
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MessageDialog.cs141
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Misc.cs35
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Notebook.cs269
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Object.cs49
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/OptionMenu.cs79
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Paned.cs73
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioActionGroupManager.cs144
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioButton.cs80
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioMenuItem.cs75
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioToolButton.cs80
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Range.cs24
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Scale.cs24
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ScrolledWindow.cs112
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Signal.cs60
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalChangedEventHandler.cs19
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalCollection.cs89
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalEventHandler.cs19
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SpinButton.cs12
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Table.cs520
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TextView.cs62
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToggleToolButton.cs12
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToolButton.cs147
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Toolbar.cs178
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TreeView.cs21
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScale.cs18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScrollbar.cs18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Viewport.cs28
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Widget.cs1094
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetEventHandler.cs33
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetNameChangedHandler.cs25
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Window.cs223
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/objects.xml2274
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/COPIED1
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/accellabel.pngbin0 -> 489 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/actiongroup.pngbin0 -> 274 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-check-label.pngbin0 -> 626 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-menu.pngbin0 -> 381 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/alignment.pngbin0 -> 213 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/arrow.pngbin0 -> 378 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-expand.pngbin0 -> 338 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-fill.pngbin0 -> 357 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/button.pngbin0 -> 374 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/calendar.pngbin0 -> 478 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-h.pngbin0 -> 332 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-v.pngbin0 -> 341 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-h.pngbin0 -> 296 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-v.pngbin0 -> 332 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/checkbutton.pngbin0 -> 360 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorbutton.pngbin0 -> 1136 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselection.pngbin0 -> 1136 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselectiondialog.pngbin0 -> 1136 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/combo.pngbin0 -> 456 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/comboentry.pngbin0 -> 529 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/custom.pngbin0 -> 212 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dec-border.pngbin0 -> 363 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dialog.pngbin0 -> 671 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/drawingarea.pngbin0 -> 926 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/entry.pngbin0 -> 606 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/eventbox.pngbin0 -> 565 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/expander.pngbin0 -> 536 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fileselection.pngbin0 -> 1230 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fixed.pngbin0 -> 122 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontbutton.pngbin0 -> 774 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselection.pngbin0 -> 774 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselectiondialog.pngbin0 -> 605 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/frame.pngbin0 -> 307 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe-not.pngbin0 -> 795 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe.pngbin0 -> 715 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/handlebox.pngbin0 -> 339 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbox.pngbin0 -> 397 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbuttonbox.pngbin0 -> 274 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hpaned.pngbin0 -> 655 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscale.pngbin0 -> 255 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscrollbar.pngbin0 -> 324 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hseparator.pngbin0 -> 315 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/iconview.pngbin0 -> 590 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/image.pngbin0 -> 594 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/inc-border.pngbin0 -> 370 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/label.pngbin0 -> 420 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menu.pngbin0 -> 284 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menubar.pngbin0 -> 593 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/messagedialog.pngbin0 -> 726 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/missing.pngbin0 -> 357 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/notebook.pngbin0 -> 752 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/optionmenu.pngbin0 -> 501 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/progressbar.pngbin0 -> 194 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/radiobutton.pngbin0 -> 560 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-check-label.pngbin0 -> 593 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-menu.pngbin0 -> 324 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/scrolledwindow.pngbin0 -> 667 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/spinbutton.pngbin0 -> 523 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/statusbar.pngbin0 -> 199 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/table.pngbin0 -> 499 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/textview.pngbin0 -> 592 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/togglebutton.pngbin0 -> 612 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/toolbar.pngbin0 -> 788 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/treeview.pngbin0 -> 556 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbox.pngbin0 -> 373 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbuttonbox.pngbin0 -> 268 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/viewport.pngbin0 -> 204 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vpaned.pngbin0 -> 787 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscale.pngbin0 -> 279 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscrollbar.pngbin0 -> 362 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vseparator.pngbin0 -> 327 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/widget.pngbin0 -> 337 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/window.pngbin0 -> 321 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionComponent.cs75
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupComponent.cs58
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesigner.cs278
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesignerBackend.cs45
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupEditSession.cs355
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupToolbar.cs275
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Application.cs584
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackend.cs653
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackendController.cs105
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyResolver.cs242
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyWidgetLibrary.cs141
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilClassDescriptor.cs382
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilPropertyDescriptor.cs127
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilSignalDescriptor.cs88
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilWidgetLibrary.cs368
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ChangeLog431
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerationResult.cs26
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerator.cs432
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGeneratorPartialClass.cs143
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Component.cs112
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentEventHandler.cs67
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentSignalEventHandler.cs27
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentType.cs94
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContainerUndoRedoManager.cs18
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContextMenu.cs174
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Designer.cs44
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Glade.cs63
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Grid.cs347
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSink.cs142
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSinkProvider.cs30
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/IProjectDesignInfo.cs22
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/LibraryCache.cs793
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Makefile.am107
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonFunction.cs20
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonLayout.cs36
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameFlags.cs30
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameType.cs22
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ObjectManager.cs19
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Preview.cs227
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Theme.cs41
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Palette.cs46
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/PaletteBackend.cs409
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/PluggableWidget.cs154
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Project.cs870
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectBackend.cs1237
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectViewBackend.cs345
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyEditor.cs64
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyGrid.cs275
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyTree.cs565
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Shadow.cs116
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditor.cs90
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditorBackend.cs481
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/UndoQueue.cs282
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/UserInterface.cs34
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetActionBar.cs251
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetComponent.cs122
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesigner.cs423
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesignerBackend.cs961
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetEditSession.cs368
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetFactory.cs136
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetInfoEventHandler.cs41
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTree.cs28
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTreeBackend.cs118
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTree.cs92
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTreeCombo.cs213
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/Preview.cs109
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/WindowsTheme.cs201
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/action.pngbin0 -> 319 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libstetic2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libsteticui2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.csproj172
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.csproj188
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.dll.config8
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/libsteticui/missing.pngbin0 -> 357 bytes
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/monodevelop-slim.sln146
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroup.xft.xml66
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroupPartial.xft.xml62
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/ChangeLog4
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/Dialog.xft.xml126
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/DialogPartial.xft.xml122
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/DrawingArea.xft.xml171
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/Widget.xft.xml76
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/WidgetPartial.xft.xml72
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/Window.xft.xml75
-rw-r--r--main/src/addins/MonoDevelop.GtkCore2/templates/WindowPartial.xft.xml71
407 files changed, 77817 insertions, 0 deletions
diff --git a/main/src/addins/MonoDevelop.GtkCore2/AssemblyInfo.cs b/main/src/addins/MonoDevelop.GtkCore2/AssemblyInfo.cs
new file mode 100644
index 0000000000..8769752524
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/AssemblyInfo.cs
@@ -0,0 +1,9 @@
+// Autogenerated from MonoDevelop.GtkCore.addin.xml
+
+using System.Reflection;
+
+[assembly: AssemblyProduct ("MonoDevelop")]
+[assembly: AssemblyTitle ("GTK# Visual Designer")]
+[assembly: AssemblyDescription ("Provides support for visual design of GTK# windows, dialogs and widgets.")]
+[assembly: AssemblyVersion ("2.4")]
+[assembly: AssemblyCopyright ("X11")]
diff --git a/main/src/addins/MonoDevelop.GtkCore2/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/ChangeLog
new file mode 100644
index 0000000000..8235e70571
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/ChangeLog
@@ -0,0 +1,2935 @@
+2010-10-04 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-09-30 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gtk-gui/gui.stetic:
+
+2010-09-22 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+ Implements ReloadDesigner commands.
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore2.addin.xml:
+ * MonoDevelop.GtkCore.Commands/GtkCommands.cs:
+ * MonoDevelop.GtkCore.Commands/GladeCommands.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+
+
+2010-09-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-09-20 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore2.addin.xml:
+
+2010-09-17 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-09-17 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+ Reorganizing project pad menu items.
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore2.addin.xml:
+
+2010-09-15 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gtk-gui/gui.stetic:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore2.addin.xml:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+
+
+2010-08-30 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-08-27 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore2.addin.xml:
+ * MonoDevelop.GtkCore2.xbuild.csproj:
+
+2010-08-17 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore.addin.xml:
+
+2010-08-16 Krzysztof Marecki <freefirma@gmail.com>
+
+ * MonoDevelop.GtkCore.addin.xml:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * MonoDevelop.GtkCore.addin.xml:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore.addin.xml:
+
+2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore.addin.xml: Add GuiFolderBuilderNode extension
+
+2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
+
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-07-27 Krzysztof Marecki <freefirma@gmail.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ Remove autoCommit argument
+
+2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore.addin.xml:
+
+2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
+ Fixes fo better file grouping in the project pad
+
+
+2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+ Draw action group icon
+ * gtk-gui/gui.stetic:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+
+2010-06-22 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+
+
+2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * MonoDevelop.GtkCore.addin.xml:
+
+2010-06-15 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+ Changes in the project pad for displaying grouped component files
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
+
+
+2010-06-09 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gtk-gui/gui.stetic:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Add gtkx files to project
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gtk-gui/gui.stetic:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+
+2010-06-02 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore2.csproj:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ Move generated partial class for components from gtk-gui.
+
+2010-04-29 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track
+ AddFilesToProject API.
+
+2010-04-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs:
+ ViewContent widgets are now destroyed by the workspace
+ window.
+
+
+2010-04-27 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: call
+ destroy on the container vbox during
+
+2010-04-26 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs: Found better work
+ around for the "gnome-sharp" reference issue.
+
+2010-04-26 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs: Fixed 'Bug 599335 -
+ Error CS0433: The imported type `Gtk.DeleteEventArgs' is
+ defined multiple times (CS0433)'.
+
+2010-03-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added
+ null check.
+
+2010-03-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * AssemblyInfo.cs:
+ * MonoDevelop.GtkCore.addin.xml: Bumped MD version.
+
+2010-03-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Use the
+ stock Visual Design layout as layout for stetic.
+
+2010-03-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Fix
+ race in SteticApp initialization.
+
+2010-03-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * gtk-gui/gui.stetic:
+ * MonoDevelop.GtkCore.csproj:
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs:
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs:
+ * MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs:
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs:
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs:
+ * MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
+ * MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Merged MD.Projects into MD.Core, and MD.Projects.Gui,
+ MD.Core.Gui and MD.Components into MD.Ide.
+
+2010-02-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs:
+ Track api changes.
+
+2010-02-09 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs:
+ Track API changes for lazy loading images.
+
+2010-01-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Track api
+ changes.
+
+2010-01-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gtk-gui/generated.cs:
+ * gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs:
+ Flush.
+
+2010-01-26 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ Track DisplayBinding API.
+
+2010-01-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.csproj:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Format
+ generated files using the MD formatter to ensure that the
+ generated text is the same for al platforms and
+ environments.
+
+ * gtk-gui/gui.stetic: Use global:: for type references in
+ generated code.
+
+2009-12-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Implement SupportsItem.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: When
+ adding a stock gtk widget to a window there is no need to
+ update the references. Fixes bug #565492.
+
+ * gtk-gui/generated.cs:
+ * gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs:
+ Flush.
+
+2009-12-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Introduced the ConfigurationSelector class to all methods
+ that previously took a configuration name as string. This
+ eliminates the ambiguity between solution configuration
+ names and project configuration names.
+
+2009-11-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders\WindowsFolder.cs:
+ Implemented Equals/GetHashCode. Fixes bug #549902 - MD
+ crashes when adding a new gtk form.
+
+2009-10-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * AssemblyInfo.cs:
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2009-10-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gtk-gui/generated.cs:
+ * MonoDevelop.GtkCore.csproj:
+ * gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs:
+ Flush.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Use
+ typed collection instead of ArrayList.
+
+2009-10-16 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs:
+ Handled icon loading failures.
+
+2009-10-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * AssemblyInfo.cs:
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2009-09-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Route
+ commands to the text editor view. Fixes bug #536740 -
+ Expression evaluator unnecessarily in context menu.
+
+2009-09-09 Christian Hergert <chris@dronelabs.com>
+
+ * libstetic/editor/Accelerator.cs:
+ * libstetic/editor/GroupPicker.cs:
+ * libstetic/editor/TextEditor.cs:
+ * libstetic/editor/SelectImageDialog.cs:
+ * libstetic/editor/NonContainerWarningDialog.cs:
+ * libstetic/editor/TextEditorDialog.cs:
+ * libstetic/editor/EditIconDialog.cs:
+ * libstetic/editor/IconSelectorMenu.cs:
+ * libstetic/editor/Image.cs:
+ * libstetic/editor/ActionGroupEditor.cs:
+ * libstetic/editor/StringArray.cs:
+ * libstetic/editor/EditIconFactoryDialog.cs:
+ * libstetic/editor/SelectIconDialog.cs:
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs:
+ * MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs:
+ * MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fixes to
+ make windows and dialogs Transient to either their parent
+ window/dialog or the MD root window (when applicable).
+
+2009-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: Use real
+ resource Ids instead of file names. Fixes bug #528309 -
+ Button Icons are not displayed.
+
+2009-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs: Store the
+ GuiBuilderProject on which the ChangedEvent was subscribed,
+ and use that reference when unsubscribing on Dispose. This
+ is required because the GuiBuilderProject bound to a project
+ may change. Fixes bug #525421 - Removing gtk-sharp reference
+ from a project causes it to not function properly.
+
+2009-08-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Don't use the text editor
+ display binding id as reference for registering the designer
+ view. Use DefaultDisplayBinding instead. Removed unused
+ supportedFormats attribute.
+
+2009-08-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gtk-gui/gui.stetic: Update gtk# dependency.
+
+2009-08-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.csproj: Updated dependencies. We now
+ depend on gtk# 2.12.8, Mono 2.4, and Mono.Addins 0.4.
+
+2009-08-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ Added support for saving and restoring the status of the
+ designer, including the undo queue. This allows implenting
+ ISupportsProjectReload.
+
+2009-08-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/FolderNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/GuiBuilderProjectNodeBuilder.cs:
+ Remove unused files.
+
+2009-08-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Use the
+ new AssemblyContext class to query and resolve assemblies.
+
+2009-08-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.csproj:
+ * MonoDevelop.GtkCore/Counters.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added
+ some performance counters.
+
+2009-07-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs:
+ Track api changes.
+
+2009-07-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: No more
+ missing IntPtr constructor exceptions.
+
+2009-06-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Use the
+ new DesktopService instead of PlatformService.
+
+2009-06-15 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track
+ assembly lookup APIs.
+
+2009-06-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore\ProjectResourceProvider.cs:
+ GetMimeTypeForUri doesn't really support uris.
+
+2009-06-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ GetGtkAssemblyVersion is expected to return the version and
+ token, not only the version.
+
+2009-05-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore\ReferenceManager.cs: Don't get the
+ package version from the gtk# package. Instead, get it from
+ the first version numbers of the gtk-sharp assembly. That's
+ necessary because in windows there is no gtk# package.
+
+2009-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ Workaround for what seems to be a mcs bug. Looks like it
+ can't properly resolve the implicit conversion of null to
+ string.
+
+2009-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore\GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder\GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder\GuiBuilderProject.cs: Use the
+ new FilePath class for handling file and directory paths.
+
+2009-05-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't
+ create a new drop target list. Use the one defined by
+ Stetic.
+
+2009-04-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.csproj: Don't require a specific gtk#
+ version.
+
+2009-04-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: gui designer is now before
+ the text editor (wrong text editor id).
+
+2009-04-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ Track API changes.
+
+2009-04-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ Track API changes.
+
+2009-04-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs: Remove vte-sharp
+ from the gnome libs list, since it now has its own package.
+
+2009-04-27 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Track
+ API changes.
+
+2009-04-23 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs:
+ Removed unused namespace.
+
+2009-04-20 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ Renamed PixbufService to ImageService.
+
+2009-04-20 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ Track API changes.
+
+2009-04-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs: Moved
+ SystemAssemblyService and related classes to the namespace
+ MonoDevelop.Core.Assemblies.
+
+2009-04-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * AssemblyInfo.cs:
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2009-04-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Add
+ support for multiple target runtimes.
+
+2009-03-17 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ Track API changes.
+
+2009-03-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: When the stetic files
+ are generated for the first time, ensure that their write
+ date is < the write date of the .stetic file, otherwise they
+ won't be regenerated when building. Fixes bug #483970 -
+ [Regression] Default C# Gtk# app no longer builds.
+
+2009-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gtk-gui/gui.stetic: Flush.
+
+2009-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Don't try to generate files when not building inside the
+ IDE.
+
+2009-02-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: In
+ ForceCodeGenerationOnBuild, force a rebuild of the project
+ too. Fixes bug #472683.
+
+2009-02-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.csproj: Flush.
+
+2009-02-26 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/ProjectResourcesProvider.cs: lookup mime
+ type and use more specific ResourceInfo ctor. [Fixes #475820]
+
+2009-02-26 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/WidgetDesignerBackend.cs: implement Delete key
+ support. [Fixes #470637]
+
+2009-02-26 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Added
+ explicit "Misc" category for localization.
+
+2009-02-26 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Worked on
+ propertygrid localization.
+
+2009-02-25 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/ApplicationBackend.cs: Reload the registry libraries
+ in LoadLibraries, since adding a library doesn't necessarily refresh
+ an out-of-date previously registered library.
+ * libsteticui/CecilWidgetLibrary.cs: enhance NeedsReload check to
+ use a cache refresh and the new change notification so that the
+ library stays 'dirty' until it's reloaded.
+ * libsteticui/LibraryCache.cs: add change notification for cache items.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: do an update
+ of the steticapp libs even if the list hasn't changed in case the
+ contents of any of them have changed.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: check for
+ 'dirty' references when regenerating code. [Fixes #472683]
+
+2009-02-24 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: only touch the design file
+ when forcing rebuilds.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: don't regen
+ if design file and generated files have equal timestamps to avoid
+ regenerations on fresh checkouts. [#478894]
+
+2009-02-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
+ Track merge of the project pad context menu.
+
+2009-02-18 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/ScrolledWindow.cs: when the child viewport itself
+ is being replaced, don't try to remove the viewport from itself.
+ * libstetic/wrapper/Viewport.cs: add case for when placeholders are
+ being replaced by scrollable widgets to insert the new child directly
+ into the parent scrolled window. [Fixes #404861]
+
+2009-02-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Fix
+ crash when the project's gtk# is not installed.
+
+2009-02-17 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.csproj: Set correct resource name for
+ DrawingArea template.
+
+2009-02-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Track api
+ changes.
+
+2009-02-13 Michael Hutchinson <mhutchinson@novell.com>
+
+ * Makefile.am: Fix build. Looks like the makefiles can't cope
+ with resources with IDs.
+
+2009-02-13 Mike Kestner <mkestner@novell.com>
+
+ * Makefile.am: add template resource
+ * MonoDevelop.GtkCore.addin.xml: ditto.
+ * templates/DrawingArea.xft.xml: new DrawingArea subclass template
+ with stubs for OnExposeEvent, OnButtonPressEvent, OnSizeRequested,
+ OnSizeAllocated, and ctor. Helps speed up the development of custom
+ drawn widgets. [Fixes #472665]
+
+2009-02-11 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/Registry.cs: account for reloading of the coreLib,
+ since this can happen when dogfooding MD. [Fixes #365983]
+
+2009-02-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.csproj: Remove a local-copy ref.
+
+2009-02-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mds:
+ * MonoDevelop.GtkCore.mdp:
+ * MonoDevelop.GtkCore.csproj: Migrated to MSBuild file format.
+
+2009-02-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * gtk-gui/gui.stetic:
+ * gtk-gui/generated.cs:
+ * MonoDevelop.GtkCore.mdp:
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs:
+ * gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs:
+ Added option for enabling/disabling auto-switch of the GUI
+ builder layout. Disabled from now on by default.
+
+2009-02-04 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/objects.xml: explicit default values for Table
+ NRows and NCols values so they don't default to 1. Fixes #471242.
+
+2009-02-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * AssemblyInfo.cs:
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2009-02-02 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/PropertyDescriptor.cs: null guard the ValueToString
+ formatting for string arrays.
+
+2009-02-02 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/PropertyDescriptor.cs: handle empty string lists
+ * libstetic/wrapper/ComboBox.cs: some more null guarding for Items.
+ [Fixes #471244]
+
+2009-01-30 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Propagate a
+ policy parent SolutionItem through project/file creation so that
+ policies can always be resolved correctly.
+
+2009-01-26 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.mdp:
+ * libsteticui/libsteticui.mdp: Flush project format changes.
+
+2009-01-26 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/ActionTree.cs: guard against removing unsaved
+ actions. [Fixes #443472]
+
+2009-01-22 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/editor/StringArray.cs: display "(Collection)" in the
+ label instead of a joined list on \n which displays garbage chars.
+ This approach is consistent with another very popular IDE. ;-)
+ * libstetic/wrapper/objects.xml: use Editor.StringArray for the Items
+ property of ComboBox.
+ * libstetic/wrapper/ComboBox.cs: switch Items to a string[]. Luckily
+ this is backwards compat since we currently saved string[] as a newline
+ join of the member strings. [Fixes #405396]
+
+2009-01-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Don't serialize the GtkDesignInfo
+ element when it is empty.
+
+2009-01-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added missing
+ nullref check.
+
+2009-01-13 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: adds a
+ FileAddedToProject handler which scans the file for classes and
+ checks the deleted-designs cache for matches to restore to the
+ project.
+
+2009-01-13 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/ProjectBackend.cs (RemoveWidget): export the widget
+ to a deleted-designs dir for later recovery if necessary. Should
+ also decide on some cleanup mechanism to remove old designs and
+ automate recovery in the move case if possible. Or we can wait for
+ 1wpf which should solve the move case more cleanly.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: reenable
+ OnFileRemovedFromProject handler. Revamp to use a ParseDocument of
+ the removed file to scan for removed classes to kill.
+ [Fixes #366392]
+
+2009-01-09 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/Project.cs: forward isInternal to the backend in
+ AddWidgetLibrary.
+
+2009-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/LibraryCache.cs: Don't ignore internal classes when
+ looking for widgets. If a widget is internal, set the "internal" flag
+ to true. Don't abort AddObjects if there is an assembly resolution
+ error.
+
+2009-01-08 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/LibraryCache.cs : delay cache directory creation until
+ files are going to be written to it.
+
+2009-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: Don't try to resolve full assembly
+ paths.
+
+2008-12-18 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/editor/Flags.cs : fix cs0030 under new mcs.
+ * libstetic/editor/FlagsSelectionDialog.cs : fix cs0030 under new mcs.
+ * libstetic/editor/ResponseId.cs : fix cs0030 under new mcs.
+
+2008-12-13 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/Container.cs: generate tooltips based on the target
+ version, using the new Tooltip API for >= 2.12. Fixes #372015.
+
+2008-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetParser.cs: Properly search for subclasses of
+ Gtk.Widget.
+
+2008-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp:
+ * libsteticui/libsteticui.mdp: All projects now require fx 3.5.
+
+2008-12-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Remove the mono
+ version number comment from the generated files.
+
+2008-12-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs: Track API changes.
+
+2008-12-09 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs: Use an
+ Alignment as the concrete Bin instead of custom InvisibleFrame.
+
+2008-12-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Don't require a specific version of
+ Mono.Addins.
+
+2008-12-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetParser.cs: Optimized GetToolboxItems.
+
+2008-12-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetParser.cs:
+ * MonoDevelop.GtkCore/ObjectsDocument.cs: Getting the list of widgets is
+ an expensive operation. It shouldn't be a property.
+
+2008-12-02 Michael Hutchinson <mhutchinson@novell.com>
+
+ * Makefile.am:
+ * AssemblyInfo.cs:
+ * MonoDevelop.GtkCore.mdp: Add AssemblyInfo.cs files that are
+ autogenerated from the addin manifests.
+
+2008-12-01 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/objects.xml: move ToggleButton ahead of CheckButton
+ and add ToggleButton signal item group to CheckButton. Remove toggled
+ signal from RadioButton since it inherits it from CheckButton.
+ [Fixes #450237]
+
+2008-11-25 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: refactor the default and
+ supported version checks into the ReferenceManager, with all the other
+ package and assembly code.
+ * MonoDevelop.GtkCore/ReferenceManager.cs: refactored default and
+ supported version properties.
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: use new api.
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: use new api.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: use new api.
+
+2008-11-23 Mike Kestner <mkestner@novell.com>
+
+ * *: I've typed lib/stetic/libstetic(ui) a few too many times.
+
+2008-11-18 Mike Kestner <mkestner@novell.com>
+
+ * */Makefile.am: break the gnome/gconf-sharp dependencies.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: set up
+ callbacks to the PlatformService for MIME resolution and showing
+ urls.
+
+2008-11-11 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: use the
+ new ForceUpdate method on the ProjectDom returned by GetParserContext
+ to ensure a fully updated database.
+
+2008-11-11 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: null guarding for
+ all the things that can possibly go wrong with the parse in
+ GetClass.
+
+2008-11-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Create the
+ formInfos list when the project is loaded. This is necessary since
+ the list is destroyed when the project is unloaded. Fixes bug #Bug
+ 431723 - Cannot build GTK applications with sln format.
+
+2008-11-06 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ revert the context menu changes. Don't show them if the project has no
+ gtk-sharp ref, only add the templates to the dialog, per Lluis.
+
+2008-11-06 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ show Add Widget|Window|Dialog|ActionGroup template items in the context
+ menu and Add File dialog even when the project has no Gtk# reference.
+
+2008-11-05 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: needed to revert
+ the >= to <= change from the 440435 fix since the refmgr is now
+ reporting TargetGtkVersion without Version=. oops.
+
+2008-11-05 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs: strip Version= out of
+ TargetGtkVersion.
+
+2008-11-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2008-10-30 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ switch to a x.y TargetGtkVersion obtained by parsing the gtk-sharp
+ reference version. Invert the version comparison in the toolboxitem
+ filter. We want toolbox items that are less than the project target
+ version, not greater. Fixes #440435.
+
+2008-10-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Don't notify the
+ file has changed unless the changes are saved to disk. Fixes bug
+ #430497 - Widget names created in Stetic not available for
+ autocomplete.
+
+2008-10-29 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs (ShowPage): only
+ regenerate the dummy structure when switching to the source page.
+
+2008-10-28 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/ReferenceManager.cs: switch default updating
+ to use the current assembly StoredReference version. Avoids problems
+ when the stored version has no corresponding installed package.
+ Fixes #436246.
+
+2008-10-27 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: don't store
+ configuration on Project Save. Avoids a crash due to file availability
+ when saving config while loading and it's extraneous since we store
+ the config on app exit and it contains no project specific props.
+
+2008-10-22 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs (HasDesignedObjects): guard
+ against null projects.
+
+2008-10-21 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs (HasDesignedObjects): don't
+ instantiate just to get the SteticFile. Avoids project file garbage.
+ [Fixes #436201]
+
+2008-10-21 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: guard against null
+ documents returned from parse. I think this is related to the old
+ ErrorsDuringCompile check that was commented with the new parser port.
+ [Fixes #436998]
+
+2008-10-05 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: fixed TODO.
+
+2008-10-03 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding:
+ rework GetWindow method. now uses the ParsedDocument for a requested
+ file to check if any of its types have a GuiBuilderWindow.
+ The existing method of walking the project windows list and using
+ the ProjectDom database to lookup their file locations is susceptible
+ to timing problems due to imcomplete parse databases. This method is
+ probably slightly more efficient as well.
+
+2008-10-01 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/ProjectResourceProvider.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track API.
+
+2008-09-23 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: bandaid to
+ avoid exceptions when removing non-existent buttons. Fixes #377414.
+
+2008-09-23 Mike Kestner <mkestner@novell.com>
+
+ * lib/stetic/libsteticui/CecilWidgetLibrary.cs: don't hold assembly
+ reference beyond load operation. Recreate it on each load so we are
+ always accessing the current assembly instance. Only access cache
+ using filename. Ensure Class description lookups cause spew to
+ console.
+ * lib/stetic/libsteticui/LibraryCache.cs: enhance the path lookup
+ logic in Refresh to avoid some churn on named lookups.
+ * lib/stetic/libsteticui/ProjectBackend.cs: reload library if
+ necessary before getting component types. Fixes #427334.
+
+2008-09-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated projects.
+
+2008-09-15 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCode.GuiBuilder/GtkProjectServiceExtension.cs:
+ add the project stetic file to any generation warnings produced.
+ Fixes #373244.
+
+2008-09-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.mdp, lib/libstetic.mdp, lib/gtk-gui/generated.cs,
+ gtk-gui/generated.cs: Updated generated code.
+
+2008-09-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore/WidgetParser.cs: Track api changes.
+
+2008-09-11 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Changes caused by
+ interface changes.
+
+2008-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: Moved
+ the extensible tree view to its own directory.
+
+2008-08-27 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDesciptionTemplate.cs: perform a
+ project save after the file insertions and updates. This seems
+ suboptimal, since it would probably be better to mark the project
+ dirty and let the user save the project, but until we switch to
+ one-widget-per-design-file, we probably need to save the project
+ automatically to avoid problems.
+ Fixes #385712.
+
+2008-08-27 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Restrict to DotNetProjects and verify ProjectFolders are for DNPs.
+ Fixes #412448.
+
+2008-08-22 Mike Kestner <mkestner@novell.com>
+
+ Fixes bug #413275 and delays more GtkDesignInfo-related project file
+ churn.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: init the refmgr on startup.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Remove targetVersion field and
+ associated prop. Move reference updating logic to Ref Manager. Target
+ Version is now exclusively tracked via reference version by the
+ ReferenceManager.
+ * MonoDevelop.GtkCore/ReferenceManager.cs: new class to encapsulate all
+ reference management behaviors, from responding to user add removes to
+ automated updates for designer projects.
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: only show feature
+ for projects which support refactoring, since it advertises designer
+ support and that's not available without refactoring yet. Use refmgr
+ for version updates.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionsPanel.cs: use refmgr
+ for version info and suppress gettext options if no designed objects
+ exist.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: use refmgr for
+ target version.
+
+2008-08-20 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs: Remove
+ the "resources folder" feature. Resources are now shown in the
+ solution tree like any other files. For a detailed explanation see
+ "Bug 381430 - [PATCH] Display resource files in main project tree".
+
+2008-08-19 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: revert a silly
+ change that was causing explicit paths to be inserted into gui.stetic
+ files for gac references. [Fixes #412960]
+
+2008-08-19 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: fixed issue in
+ GetSourceCodeFile.
+
+2008-08-19 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: fixed some
+ possible nullrefs.
+
+2008-08-19 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp: re-set project
+ references (fix some libstetic.dll not found issue, localcopy ==
+ true was missing).
+
+2008-08-18 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: make HasDesignedObjects
+ and SupportsDesigner static so that we can defer a few more instance
+ creation scenarios.
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs:
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
+ Update to new static API.
+
+2008-08-08 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Add a null
+ check.
+
+2008-08-04 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: fixed possible
+ null references in the unload method.
+
+2008-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Fix crash when looking for
+ designed objects in a project that doesn't support it.
+
+2008-07-31 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fixed some
+ issues.
+
+2008-07-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Translated
+ old code to new dom.
+
+2008-07-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/ObjectsDocument.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Changes for converted
+ refactoring infrastructure.
+
+2008-07-27 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/WidgetParser.cs,
+ MonoDevelop.GtkCore/ObjectsDocument.cs,
+ MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ClassUtils.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Worked on code
+ completion/new dom.
+
+2008-07-24 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: get paths
+ for gac references to simplify the lookup in stetic.
+
+2008-07-23 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ Use HasDesignedObjects not SupportsDesigner.
+
+2008-07-23 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: delay creation of guifolder
+ until GuiBuilderProject is accessed. Refactor Bind into a Project
+ property to gather all the connect/disconnects together. Add new
+ HasDesignedObjects prop for when SupportsDesigner doesn't cut it.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs: use new
+ HasDesignedObjects prop.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs:
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: don't
+ need to update the folder for these options any more.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs: get
+ GuiBuilderProject from design info directly.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: kill
+ BeforeCompile handler and GetGuiBuilderProject method. Use new
+ HasDesignedObjects to control code generation.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: kill
+ GenerateSteticCode field. It was always set to true. Use new
+ HasDesignedObjects prop to control generation.
+
+2008-07-22 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Connect to project file
+ events and trigger objects.xml updates. Translate a confirm button
+ label. Require AddAttribute refactoring.
+ * MonoDevelop.GtkCore/ObjectsDocument.cs: new class reinstating some
+ old document updating code and adding some new. Inserts ToolBoxItem
+ and Category attrs into sources for a first-time "upgrade" to enable
+ the attr-sync feature now controlled by a root attribute on the
+ document.
+ * MonoDevelop.GtkCore/WidgetParser.cs: new class reinstating some
+ old parsing code and adding some new. This will become the home
+ for all source parsing in the addin. Refactoring to come...
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Add WidgetParser
+ prop. Remove Debug spew.
+
+2008-07-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs: Moved serialization engine to
+ MonoDevelop.Core. Use new syntax for specifying attribute scope.
+
+2008-07-15 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: add an updatingVersion
+ state to prevent warning when we are adjusting reference versions.
+
+2008-07-15 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: add a user confirmation for
+ disabling the designer on reference removal. Leave the stetic.gui
+ and objects.xml files on disk, though we still remove them from the
+ project.
+
+2008-07-14 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fixed possible
+ null reference.
+
+2008-07-10 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs (FromProject): return an
+ empty instance for non-DotNetProjects which will report false
+ on SupportsDesigner.
+
+2008-07-10 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Gutted. Moved everything
+ that took a Project parameter to GtkDesignInfo. Removed all the
+ enable/disable/get info methods replaced by GtkDesignInfo.FromProject.
+ Killed all the objects file updating. Moved designer support checks
+ to DesignInfo.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Add FromProject static
+ method to replace GtkCoreService.GetGtkInfo. Remove ExportedWidgets
+ and IsWidgetLibrary functionality. Enable and disable designer based
+ on presence of gtk-sharp reference on projects. Refactor/move code
+ generation to GuiBuilderProject from UpdateGtkFolder. Kill
+ GeneratePartialClasses since it's a simple project property access
+ and all users of GtkDesignInfo access it via the project. Moved
+ Refactory checks from GtkCoreService to encapsulate SupportsDesigner.
+ Fix Reference updating checks for Mono.Posix, since the
+ StoredReference returns a simple name for it.
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: switched to
+ FromProject api. Killed ExportedWidget handling.
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: removed widget
+ library checkbox. s/Gtk#/GTK# for consistency. Updated to new
+ DesignInfo API.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: removed
+ all the Exported Widgets and WidgetLibrary tab stuff, simplified to
+ a vbox and hand-written to remove glade taint.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ switched to new DesignInfo API.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ switched to new DesignInfo API. moved gui folder file generation
+ here instead of DesignInfo iterating over builder properties.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs:
+ Added category mangling for ToolboxItems so that they are placed
+ by project.
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
+ switched to new DesignInfo api.
+ * templates/Widget.xft.xml: add ToolboxItem attr.
+ * templates/WidgetPartial.xft.xml: add ToolboxItem attr.
+
+2008-06-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2008-05-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Explicitly set the resource ids
+ for gui.stetic and objects.xml, since msbuild uses different
+ default ids.
+
+2008-05-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Track api
+ changes.
+
+2008-05-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Merged the extension points for
+ project and solution option panels into a single extension point. A
+ single extension point will now be used for all kinds of items.
+ Extension conditions can be used to make panels visible only for
+ some specific item types.
+
+2008-05-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Replaced ICompilerResult/DefaultCompilerResult/CompilerResults by a
+ new BuildResult class, which has owner information at error level,
+ so it is possible to know which project generated an error when
+ building a solution. Updated Task and TaskService to use the new
+ owner information.
+
+2008-05-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore/ProjectResourceProvider.cs,
+ MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.mdp,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs,
+ MonoDevelop.GtkCore.mds, lib/libsteticui.mdp, lib/libstetic.mdp,
+ Makefile.am,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: New project
+ model changes.
+
+2008-05-20 Mike Kestner <mkestner@novell.com>
+
+ * templates/Widget.xft.xml:
+ * templates/WidgetPartial.xft.xml:
+ Mark the custom widgets Visible=false to conform to the Gtk convention
+ of widgets being shown explicitly. [Fixes #364985]
+
+2008-05-15 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Track API. Mark up
+ for property grid.
+
+2008-05-13 Mike Kestner <mkestner@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: use new
+ Stetic.ApplicationFactory api.
+
+2008-05-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Track API.
+
+2008-04-30 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, gtk-gui,
+ gtk-gui/generated.cs, gtk-gui/gui.stetic, Makefile.am,
+ icons/pad-widget-tree-16.png,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Implement
+ IOutlinedDocument instead of custom pad. Set GTK# version to 2.8.
+
+2008-03-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Removed unneeded dependency.
+
+2008-03-04 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: fixed bugfix (thanks
+ ankit)
+
+2008-03-04 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Fixed possible null
+ reference exception.
+
+2008-03-04 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Worked on gnome hig
+ compliant alerts.
+
+2008-03-01 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fixed null ref.
+
+2008-02-29 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Refactored content
+ interfaces
+
+2008-02-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.mdp: Set correct makefile ver for files.
+
+2008-02-27 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Worked on category
+ support for the toolbox service.
+
+2008-02-23 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp: Removed some unused glade
+ and gnome-sharp references (only the unused). But I'll continue to
+ remove glade, we need to lower the dependency tree a bit.
+
+2008-02-22 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Added IViewContent
+ switching logic (but should be done centrally using the secondaryview
+ paradigmn).
+
+2008-02-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Workaround for mono bug
+ #350432.
+
+2008-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Handle the delete
+ key in TreeViewPad, so it will work event if the shortcut is not
+ defined.
+
+2008-01-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am,
+ icons/pad-widget-tree-16.png: Added widget tree icon.
+
+2008-01-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Update MD version.
+
+2008-01-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Made internal
+ some classes that don't need to be public.
+
+2008-01-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Notify file changes
+ through the FileService.
+
+2008-01-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Stetic code must be
+ generated in the GUI thread. Should fix bug #349505.
+
+2008-01-15 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Feed default layout
+ name to Gettext for translation.
+
+2008-01-15 Michael Hutchinson <mhutchinson@novell.com>
+
+ * templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/ActionGroupPartial.xft.xml,
+ templates/Window.xft.xml, templates/ActionGroup.xft.xml,
+ templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Make template
+ categories translatable.
+
+2008-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Added null check on the
+ result of UpdateFile. Should fix bug #352194.
+
+2008-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: Handle
+ projects which don't support the GTK# designer. Window and widget
+ generation options are hidden, and code is never generated. Fixes bug
+ #350632.
+
+2007-12-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Don't update bindings if the
+ file has syntax errors. May fix bug #347590.
+
+2007-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump add-in versions.
+
+2007-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am: Update after build reorg.
+
+2007-12-06 Geoff Norton <gnorton@novell.com>
+
+ * Makefile.am: Only build the GtkCore addin if we have gnome-sharp
+ available.
+
+2007-12-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp, lib/libstetic.mdp,
+ Makefile.am: Directory reorganization.
+
+2007-11-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade, MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs: Removed
+ Gnome.FileEntry.
+
+2007-11-09 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: Track
+ LoggingService API changes.
+
+2007-11-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Use RootCombine
+ instead of CurrentOpenCombine when possible.
+
+2007-10-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2007-10-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Fix nullref. Happens
+ when removing a project from a solution while one of the windows of that
+ project is open.
+
+2007-10-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * templates/ActionGroup.xft.xml, templates/ActionGroupPartial.xft.xml,
+ templates/Dialog.xft.xml, templates/DialogPartial.xft.xml,
+ templates/Widget.xft.xml, templates/WidgetPartial.xft.xml,
+ templates/Window.xft.xml, templates/WindowPartial.xft.xml: Use tango
+ file icons. Removed obsolete icons.
+
+2007-10-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Track api changes. Added
+ Description property.
+
+2007-10-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.mdp, lib/libstetic.mdp: Project file names updated by
+ change in MD path functions.
+
+2007-10-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mds, Makefile.am: Added custom command for updating
+ the Stetic sources.
+
+2007-10-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Set a more meaningful category name for
+ addin commands.
+ * MonoDevelop.GtkCore.mdp, MonoDevelop.GtkCore.mds: Updated.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: If the current selection
+ can't be deleted, just ignore the delete command, so the default handler
+ will be executed. Fixes bug #325440.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.mdp: Fix required gtk# version.
+
+2007-10-12 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Applied changes that
+ were neccassary for to the new FileService.
+
+2007-10-11 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Changed calls for
+ the new StringParser.
+
+2007-10-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: In Bind(), don't subscribe the
+ NameChanged event at every call.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: The designer needs to
+ be explicitely destroyed.
+
+2007-10-03 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: No need to implement
+ IComparable; it's done in the base class now.
+
+2007-09-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Assign the selected
+ target gtk# version to the new project.
+
+2007-09-21 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Use ProjectReference.StoredReference
+ rather than ProjectReference.Reference, in order to refer to the actual
+ stored reference string rather than a temporarily bumped version.
+
+2007-09-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2007-09-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Implemented an
+ assembly resolver for the stetic app, so assembly widgets registered
+ with .pc files can be found.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs: If a widget dll belongs
+ to a package, store it as a package reference in the toolbox index.
+
+2007-09-19 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Allow setting TargetGtkVersion to
+ DefaultGtkVersion when current value is null.
+
+2007-09-19 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Don't touch GTK# assembly versions
+ when a target version is not set. Don't use gtkVersion=null to represent
+ default version.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Set TargetGtkVersion on new
+ projects. Bump default version to 2.8.
+
+2007-09-17 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp, lib/libstetic.mdp,
+ lib/Makefile.am, MonoDevelop.GtkCore.mds, Makefile.am: Use projects for
+ imported stetic libraries.
+
+2007-09-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Removed access to
+ Component object.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Remove unused method.
+
+2007-09-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs: Fix warnings.
+
+2007-09-13 Michael Hutchinson <mhutchinson@novell.com>
+
+ * lib/stetic, Makefile.am, lib/Makefile.am: Build stetic from
+ svn:externals.
+ * lib/libsteticui.dll.config, lib/libstetic.dll.config,
+ lib/libstetic.dll, lib/libsteticui.dll: Removed.
+
+2007-09-10 Michael Hutchinson <mhutchinson@novell.com>
+
+ * templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml,
+ templates/ActionGroupPartial.xft.xml, templates/ActionGroup.xft.xml,
+ templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Remove
+ deprecated FileOptions element from templates.
+
+2007-09-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Changed the way to
+ set the active designer (the api changed). Fixed some renaming issues.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Track api changes.
+
+2007-09-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * templates/Window.xft.xml: Oops, PartialTypeSupport should be set to
+ Disabled for non-partial window.
+
+2007-09-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Updated.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs: Use DotNetProject.UsePartialTypes
+ instead of custom setting.
+ * MonoDevelop.GtkCore/WidgetFileTemplatePartialClass.cs,
+ MonoDevelop.GtkCore/WidgetFileTemplateFullClass.cs: No longer needed.
+ * templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml,
+ templates/ActionGroupPartial.xft.xml, templates/ActionGroup.xft.xml,
+ templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Use
+ PartialTypes condition instead of custom file template.
+
+2007-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes fixes for bugs #82671, #82527, #82476, #81763 and #81238.
+
+2007-08-31 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs: Changes due to new
+ property infrastructure.
+
+2007-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs: By default use the project name
+ as category name for new custom widgets.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Don't show the full
+ name of widgets in the toolbar.
+
+2007-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: In FindClass, make
+ sure the getUserClass parameter is taken into account when the found
+ class is not a multi-part class. Fixes bug #82258.
+
+2007-08-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Removed the CommandService class.
+ Everything is done directly with CommandManager. Moved all extension
+ node types to MD.Components.
+
+2007-08-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.mdp, Makefile.am: Reorganized the extension point
+ hierarchy. Embedded all add-in manifests as resources.
+ * lib/libstetic.dll: Updated from stetic module.
+
+2007-08-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Improved error
+ reporting.
+
+2007-08-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Converted
+ DispatchService to a static class.
+
+2007-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fixed some
+ problems with the target gtk version. It was not assigned to the
+ stetic project. Also fixed some stock icon rendering issues in
+ Stetic.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes a nullref fix.
+
+2007-07-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Layout switch
+ delay is not needed anymore.
+
+2007-07-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Fix nullref
+ when gtk support is not enabled. Patch by Chris Howie.
+
+2007-07-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Don't try to use the CurrentNode property after adding the file,
+ since it may have changed. Should fix bug #82123.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+ Fixes bugs #81846 and #82144.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fix window
+ source file lookup.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Use the new methods
+ for checking clipboard operations on the current selection.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Include the
+ current project in the list of libraries to show in the toolbox.
+ Fixes bug #82125.
+
+2007-07-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated. Fixes bugs 81977,
+ 81810 and 82052.
+
+2007-07-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Properly rename
+ fields when the widget name is changed. Fixes bug #81976.
+
+2007-07-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Update the
+ properties pad when the focus is on the widget tree pad. Fixes bug
+ #81971.
+
+2007-07-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Added null
+ check.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Track api changes
+ in DesignerSupport. When adding a project reference to a widget
+ library, take into account that widgets may be implemented in a
+ library different from the one providing the widget list.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: In
+ GetDynamicItems, only return widgets provided by libraries
+ referenced by the project. Don't return widgets from libstetic
+ since those are already included by default in the toolbox.
+ Implemented IToolboxDefaultProvider.
+
+2007-07-03 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Changed a bit
+ because of the removal of custom collections in the Ide project.
+
+2007-06-30 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * gui.glade: Fixed capitalization.
+
+2007-06-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs: Don't show windows
+ in the toolbox.
+ * lib/libstetic.dll, lib/libsteticui.dll: Updated from Stetic module.
+
+2007-06-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+
+2007-06-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade, MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Allow selecting
+ the target GTK# version of the project.
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Implemented a
+ toolbox loader, which allows registering assemblies in the toolbox.
+ When a widget from a toolbox is dropped to a window, MD will now
+ add a reference to the required assembly.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll: One last update.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Set the import
+ file callback when editing project stock icons.
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: The GetResources
+ method only returns resource files now.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-06-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Default pad
+ placement is now specified in the xml file.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: In GetBaseType, use
+ Project.GetWidgetTypes to get all registered wiget types, including
+ base widget types (which were not provided by GetComponentTypes).
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes fix for bug #81785.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Don't include non-public
+ members to the objects.xml file.
+
+2007-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Fix feature message.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+ Includes fixes for bugs #81761, #81758 and #81762.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ (UpdateLibraries) Properly check for library changes.
+
+2007-05-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Fixes bugs #80783 and #81683.
+
+2007-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Added new dependency.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from svn. Fixes bug
+ #81590.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: When selecting an
+ image file in the widget designer, import the file into the
+ project.
+
+2007-05-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Added some delay
+ in the code that changes the workbench layout when selecting the
+ designer. Fixes bug #80963.
+
+2007-05-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPalettePad.cs: Removed old
+ palette pad.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Set the 'internal' flag for
+ widgets implemented by private classes.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from svn module.
+ Fixes bugs #80875, #81261, #81365.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: If the project
+ is a library, add itself as an internal widget library, so widgets
+ with internal visibility will be shown.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: When saving a window,
+ use the visibility of the class to set the visibility of the
+ component. Together with all changes done in stetic, fixes bug
+ #80875.
+
+2007-05-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Track api changes in
+ Stetic.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Delay
+ library updating until really necessary.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-05-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Copy the .addins.xml file to the output dir.
+
+2007-05-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Copy stetic dlls together with the assembly.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated.
+
+2007-05-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Reference shared assemblies
+ from the correct location.
+
+2007-05-04 Wade Berrier <wberrier@novell.com>
+ * lib/libstetic.dll.config:
+ * lib/libsteticui.dll.config:
+ Fix os attribute formats (mono-config.c separates oses by comma,
+ and ignores or includes the whole string.)
+
+2007-05-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am:
+ Migration to Mono.Addins.
+
+2007-04-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp,
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs, Makefile.am:
+ Implemented project feature for enabling gtk# support in new
+ projects.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: Use
+ Menu icon size in the project pad.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Show a
+ relative path in the window delete confirm dialog, since the
+ absolute path may take too much space.
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Add
+ Ok/Cancel buttons by default in new dialogs.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes fixes for bugs 81033, 81086, 81239, 81143, 81014 and
+ 81015.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Allow pasting when
+ a placeholder is selected. Fixes bug #81246.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.mdp, Makefile.am, icons/image-x-generic.png:
+ Show a "Stock Icons" node in the User Interface folder. It's easier
+ to discover than the context menu option.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.Commands/GladeCommands.cs: Added menu option
+ for opening the gtk# settings.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Don't crash if
+ the gtk-gui folder doesn't exist. Fixes bug #81152.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Hide the border
+ of the combined view notebook.
+
+2007-03-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated from stetic module. Fixes NRE crash.
+
+2007-03-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Fix null ref.
+
+2007-03-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Register a new toolbox loader. Removed
+ old properties pads.
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Added reference to
+ MonoDevelop.DesignerSupport.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from svn module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Integrate Stetic
+ widgets in the main toolbox.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Implement
+ ICustomPropertyPadProvider and return the Stetic property pad.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs: Renamed.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Fix warning.
+
+2007-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ Updated from Stetic module. Includes fix for bug #80864.
+
+2007-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from SVN. Fixes some
+ memory leaks and bug #79453.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Explicitely
+ destroy notebook children, since notebook doesnt do it because of a
+ gtk bug.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Some fixes in the
+ dispose code.
+
+2007-02-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Use
+ ProjectOperations.SaveProject to save projects.
+
+2007-02-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Change add-in versions to 0.13.
+
+2007-02-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fix nullref.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: Log
+ error message.
+ * Makefile.am, MonoDevelop.GtkCore.mdp: Synchronized MD project and
+ makefile.
+
+2007-02-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Avoid throwing
+ delayed events after the project has been disposed.
+
+2007-02-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added missing
+ null check.
+
+2007-02-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Ask for user
+ confirmation when reloading a designer only when the designer has
+ unsaved changes.
+
+2007-02-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Detect external
+ changes in the gui.stetic files, and reload it when it changes.
+ Take into account that the load of gui.stetic can fail. Added
+ several workarounds for this case.
+
+2007-02-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from SVN. Includes
+ fixes for bugs #80722, #79427 and #80127.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Store some
+ Stetic configuration in the MD properties.
+
+2007-02-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade, MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Added options
+ for enabling/disabling gtk support, and for gettext support.
+ * MonoDevelop.GtkCore.addin.xml: Change options panel name.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Make sure the
+ MD project is saved together with the stetic project, if necessary.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Avoid saving
+ the MD project twice.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs: If gtk
+ integration status changes for a project, refresh the tree.
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs: Null check.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added support for gettext and
+ gettext class options for generated code.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Added events for notifying
+ when the gtk integration status changes for a project.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * Makefile.am: distcheck fixes
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: When a designer
+ project is disposed, hide the designer view in the editor.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Factorized some code into GtkDesignInfo.
+
+2007-02-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Make sure the code generation
+ extension is executed before the last step.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Hide the add window commands when the project is not DotNet
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.dll, lib/libstetic.dll:
+ Updated.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Intercept calls
+ to the IPositionable interface, and show the editor page when
+ jumping to a line.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: When looking for
+ the window class, avoid returning the generated partial class.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Show the editor
+ page when jumping to a signal handler.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Warn the user if
+ the gtk-sharp-2 package can't be found. Some distros don't include
+ the .pc file in the gtk# package, only in the -devel package.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+
+2007-01-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll.config, lib/libsteticui.dll, lib/libstetic.dll,
+ lib/libsteticui.dll.config: Updated from Stetic module.
+
+2007-01-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Track api
+ changes in Document class.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated form Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Removed
+ implementation of all text editor interfaces. Now the view
+ overrides GetContent and calls editor.GetContent when a requested
+ interface is not found.
+
+2007-01-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Removed unused namespace.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Use the new base-type property
+ to describe custom widgets. When looking for properties and events,
+ look in the base classes as well as in the widget class.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * Makefile.am,
+ MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/ProjectSignalDescriptor.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/ProjectPropertyDescriptor.cs:
+ Removed unused files. All widget library functionality has been
+ moved to stetic.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Removed all
+ widget library management, which has been moved to Stetic.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Added some null checks.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Use the new way
+ of managing dependencies in projects.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml: The
+ window constructor now takes the window type.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Some gui
+ improvements and added some null checks.
+
+2007-01-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't crash if the
+ designer can't be loaded for some reason.
+
+2007-01-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore/WidgetFileTemplatePartialClass.cs,
+ MonoDevelop.GtkCore/WidgetFileTemplateFullClass.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs,
+ templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml,
+ templates/ActionGroupPartial.xft.xml,
+ templates/ActionGroup.xft.xml, templates/DialogPartial.xft.xml,
+ templates/Dialog.xft.xml: Implemented support for generating code
+ in partial classes.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Use the
+ correct method for saving the project.
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs: Refresh the user
+ interface folder when the gui project is reloaded.
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added support for partial
+ classes. In the GuiBuilderProject property, don't update the
+ gtk-gui folder since this call may change the contents of the
+ project, and weird things happen when called by the project pad to
+ fill the tree.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * Makefile.am: Added new files.
+ * MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs:
+ Make it work even when the assembly it references has been deleted
+ (maybe as a result of cleaning a project). In this case the widget
+ library is shown as empty.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added support
+ for Loading/Unloading a project, to optimize use of memory for
+ solutions with many gui projects. Implemented support for
+ generating code in partial classes.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Implemented
+ support for generating code in partial classes. Implemented support
+ for UNDO/REDO.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Generation of gui code is now done from the Build method of a
+ project service extension. Fixes some issues when building a
+ project which contains custom components.
+
+2006-12-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Track API changes in
+ FileService.
+
+2006-12-13 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Don't
+ generate stetic code if CurrentOpenCombine is null.
+
+2006-12-07 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated to it can be
+ built from MonoDevelop.
+
+2006-11-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Simplified the
+ code by using global events from the Ide, instead of combine
+ events.
+
+2006-10-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added RemoveExportedWidget method.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: track
+ API changes.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: If the name of a
+ widget changes and it is being exported, update it in the objects.xml
+ file. Fixes bug #79656.
+
+2006-09-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module. It provides a redesigned API
+ which will allow running designers in a separate process.
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs:
+ * MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs:
+ * MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPalettePad.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs:
+ Track api changes.
+
+ * MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs: Make sure
+ parse information is up to date before loading an assembly library.
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: Make sure this object
+ is always alive when remoted.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Added null check.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Not needed anymore.
+ * MonoDevelop.GtkCore.addin.xml: Removed build step. Code generation
+ is done now before compiling.
+
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectWidgetLibrary.cs:
+ * MonoDevelop.GtkCore.WidgetLibrary/CachedProjectWidgetLibrary.cs:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: ProjectWidgetLibrary is not used
+ anymore. All libraries are now handled by AssemblyReferenceWidgetLibrary.
+
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopWidgetActionBar.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopActionGroupToolbar.cs:
+ Moved to Stetic.
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-09-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track api changes.
+
+2006-09-19 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * .: Added svn:ignore for MonoDevelop.GtkCore.pidb
+
+2006-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from stetic module. Includes fix for bug #79247.
+
+2006-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from stetic module.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Save the project after editing the icons.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Set the
+ ResourceProvider for the main stetic project. Added null check.
+
+2006-08-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Fixed bug about
+ adding the wrong widget as action designer page.
+
+2006-08-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Only export properties which
+ return primitive types. Fixes bug #79195.
+ * lib/*: Updated from stetic module.
+ * MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs: Unsubscribe close
+ event when done.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Handle designer
+ commands in its own tab page.
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Explicitely dispose
+ custom widgets to avoid memory leaks.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Track api changes.
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-08-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade: Minor fix.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Track api
+ changes.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Stetic files don't need
+ to be added as resource to projects.
+ * MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs: Make it
+ work for action groups.
+ * lib/*: several fixes.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added method
+ for removing an action group.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Track API changes
+ in Stetic. Properly bound edit commands from the main menu.
+
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.addin.xml: Implemented Open and Delete
+ commands for global action groups.
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-08-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module. Includes fixes for
+ bugs #79043, #79044 and #79045
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Don't
+ crash if something goes wrong when binding a class.
+ Fixed nullref.
+
+2006-08-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ CreateContentForFile should not load the file, just create
+ the view.
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Add
+ support for IEncodedTextContent.
+
+2006-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ Set the resource provider before loading the project.
+ Fixes bug #78966.
+
+ * libs/*: Updated from Stetic module. Fixes several bugs:
+ 78938, 78916, 78909, 78956, and 78867.
+
+2006-07-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs:
+ Added null check.
+
+ * MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs:
+ Get the parser context using the assembly file name, not the full
+ assembly name.
+
+2006-07-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Factorized several
+ more or less duplicate methods into GuiBuilderProject, specially
+ methods for locating the class bound to a window. GuiBuilderProject
+ now will explicitelly update the parser database the first time it
+ needs to locate a class, so it will work even if the parser service
+ is busy parsing assemblies.
+
+2006-07-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated from stetic module. Fixes a bug
+ in the table wrapper which may cause an endless loop.
+
+2006-07-05 Matej Urbas <matej.urbas@gmail.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs: Updated to use
+ ReturnType as BaseTypes in IClass instances.
+
+2006-07-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Fixed automatic
+ layout switch policy.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Fix showing of
+ action group view.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Properly
+ bind actions when pressing "BindToField".
+
+ * MonoDevelop.GtkCore.addin.xml: Updated versions.
+
+2006-06-29 Michael Hutchinson <m.j.hutchinson@gmail.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Only display WidgetBuilderOptionPanel
+ for "DotNet" projects.
+
+2006-06-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Switch to the
+ designer workbench layout when selecting an action group file.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Support jumping
+ to signal hanlder when double-clicking it in the signals editor.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Removed debug code.
+
+ * templates/ActionGroup.xft.xml:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ Fix code generation of action groups.
+
+2006-06-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: If a member has a [Browsable(false)]
+ attribute, don't add it to the objects.xml file. Also don't add
+ read-only properties.
+ * lib/*: Updated from stetic module. Fixes bugs #78622 and #78620.
+ Adds an icon for expander and fixes a bug in ColorButton (fix by ml)
+
+2006-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll:
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopWidgetActionBar.cs:
+ Track changes in the api.
+
+2006-06-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Updated from stetic module. Several improvements.
+ Also fixes bug #78160.
+
+2006-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ Added DisplayName property.
+
+2006-05-29 David Makovský (Yakeen) <yakeen@sannyas-on.net>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: reverted interface changes - missing file change
+
+2006-05-29 David Makovský (Yakeen) <yakeen@sannyas-on.net>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: reverted interface changes
+
+2006-05-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Updated from stetic module. Adds support for toolbars.
+
+2006-05-23 David Makovský (Yakeen) <yakeen@sannyas-on.net>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: track api changes
+
+2006-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Commands/GladeCommands.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.addin.xml: Added commands for creating
+ an action group and editing the project icons.
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Show local
+ action groups as children of the window node.
+
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs: Moved
+ some event subscriptions to WindowsFolder.cs
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: Open the
+ corresponding file when clicking on local action groups.
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Added action group template.
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Added support for
+ action group file templates.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Notify changes in
+ local action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't show the actions
+ tab until there is at least one action group.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs: Don't show
+ properties or signals for global actions.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Added virtual method
+ OnActiveDocumentChanged, which is called when the view is brought to front.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Use the new MemberName
+ field when binding fields.
+
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopActionGroupToolbar.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Several minor fixes.
+
+ * lib/*: Updated.
+
+
+2006-05-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Initial support for the menu editor. Still very unstable!!
+
+ * lib/*: Updated from Stetic module.
+ * MonoDevelop.GtkCore.addin.xml: Register a node builder and and
+ display binding for action groups.
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs: Update
+ the folder when action groups change.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Fix nullref.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Factorized
+ some code into CodeBinder.cs
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Factorized some
+ code into CombinedDesignView.cs.
+
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: New node
+ builder for action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs: New display
+ binding for editing global action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopWidgetActionBar.cs: Moved from
+ GuiBuilderView.cs.
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopActionGroupToolbar.cs: A new
+ toolbar for the action group designer.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: A view for editing
+ global action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Moved here some code
+ from GuiBuilderEditSession.cs.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Moved here some
+ code from GuiBuilderView.cs.
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Added new files.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track api changes.
+
+2006-05-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated from Stetic module. Includes
+ a fix for bug #78307.
+
+2006-05-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Updated versions.
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-05-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module. Includes fixes for
+ bugs #78266, #78240 and #78276.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track changes
+ in the Stetic API.
+
+2006-04-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Don't
+ crash if a stetic project can't be loaded. Fixes bug #78169.
+ * lib/libstetic.dll: Updated from Stetic module. Fixes bug #78167.
+
+2006-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Updated from stetic module. Fixed construction of
+ scales and scrollbars.
+
+2006-04-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs: When
+ creating a widget from a widget design, remove the signals since
+ those signals reference handlers in the widget class, not the
+ widget container class.
+
+2006-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Fix nullref in some themes.
+
+2006-04-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Fix typo.
+ * libs/*: Fix for #78111, #78092 and #78090.
+
+2006-04-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: Save the project
+ after adding or removing a resource.
+
+2006-04-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated.
+
+2006-03-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Get open
+ combine events in the GUI thread.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Properly
+ delete signals for which there isn't a handler. Half fixed field
+ renaming.
+ * lib/*: Updated.
+
+2006-03-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/MonoDevelop.GtkCore.addin.xml: Fix ID and
+ description. Added stetic config files to add-in package.
+
+2006-03-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Updated references.
+
+2006-03-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ Don't crash if no parse info is available for the file
+ being edited. Should fix #77885.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't show
+ the bind to field button for the root container.
+ * lib/*: Updated.
+
+2006-03-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am: Use an unified format. Patch by Matze Braun.
+ * MonoDevelop.GtkCore.addin.xml: Updated add-in versions.
+
+2006-03-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore.mdp: Removed GladeFileDisplayBinding.
+ * lib/*: Updated.
+ * Makefile.am: Updated. Some files have been moved to Stetic.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Fixed
+ layout switching. Don't show the widget tree pad by default,
+ since it is already available as a combo in the designer.
+ * MonoDevelop.GtkCore.GuiBuilder/GladeFileDisplayBinding.cs: Removed.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs: use
+ the new property tree instead of the grid.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: The designer
+ toolbar has been moved to Stetic.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Changed
+ default placement.
+
+2006-03-19 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * .: Added Makefile.in and Makefile to svn:ignore.
+
+2006-03-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added support for using
+ resource images in the designer.
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Check if the objects.xml
+ file exists before loading it.
+ * MonoDevelop.GtkCore/GeneratorBuildStep.cs: Don't generate code
+ if the stetic file has not been modified since the last
+ generation.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: If Gtk
+ support is not enabled, don't enable it if no widgets have
+ been selected.
+ * lib/libstetic.dll: Updated.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Mapped some
+ commands.
+ * templates/Window.xft.xml: The constructor of Gtk.Window requires
+ the title of the window.
+
+2006-03-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Updated.
+ * MonoDevelop.GtkCore/GeneratorBuildStep.cs: When generating
+ code for a project that exports widgets, include the own
+ project library to the generation, since there can be
+ widgets that contain other widgets defined in the project.
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs:
+ removed some IdeApp dependencies.
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectWidgetLibrary.cs:
+ added method for getting the class information from
+ a project.
+ * CachedProjectWidgetLibrary.cs: New widget library class
+ which takes class information from a collection of
+ ProjectClassInfo objects.
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectPropertyDescriptor.cs:
+ Consider all properties runtime-properties, since they have
+ been created from class properties.
+ * lib/*: Updated.
+
+2006-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am: removed debug files.
+
+2006-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Propagate
+ project changes to the editor.
+
+2006-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ Initial implementation of the Stetic add-in.
diff --git a/main/src/addins/MonoDevelop.GtkCore2/ChangeLog.stetic b/main/src/addins/MonoDevelop.GtkCore2/ChangeLog.stetic
new file mode 100644
index 0000000000..cd6a44f1a0
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/ChangeLog.stetic
@@ -0,0 +1,6477 @@
+2008-11-18 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/editor/ActionMenuItem.cs: check for whitespace only Text
+ values before saving actions to stop people from doing silly things.
+ [Fixes #446281]
+
+2008-11-18 Mike Kestner <mkestner@novell.com>
+
+ * *: kill gnome dependency. Dynamically load GConf.Client object
+ to query for stetic theme. Dynamically load Gnome.Stock for icon
+ editors. Establish callbacks for MIME resolution and showing urls.
+
+2008-11-12 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/PropertyTree.cs: refine store column type declarations.
+ * libsteticui/SignalEditorBacked.cs: eliminate multiple refreshes on
+ selection changes. some changes to the store, simplifying to string
+ and bool columns, and using AppendValues for all row insertions. I
+ don't think most of the model changes are necessary, but this bug
+ fought me so hard I was trying everything and am too tired of it to
+ back down to a minimal patch.
+ * libsteticui/WidgetPropertyEditorBacked.cs: check the selection is
+ really changing before refreshing. [Fixes #431751]
+
+2008-10-29 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/editor/ActionMenuItem.cs (Select): don't clear and reshow
+ parent's submenu if it's the current item's menu. Fixes #430520.
+
+2008-10-27 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/AssemblyResolver.cs: use the app backend's name resolver
+ in the AssemblyNameRef resolve overload to avoid some dependency load
+ failures. I think this also fixes #436246. At least I can't repro it
+ with this fix in place.
+
+2008-09-15 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/ErrorWidget.cs: add Project filename to the generation
+ warning messages. Fixes #373244.
+
+2008-08-19 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/ActionTree.cs: use field references for uim
+ access. Use Action.Name for name in ui string if name isn't set.
+ * libstetic/wrapper/Widget.cs: make UIManagerName fixed and dependent
+ on action group presence. Adjust uim generation to field references.
+ * libsteticui/CodeGenerator.cs (GetFieldsToBind): add uimanager
+ field if needed.
+ * libsteticui/CodeGeneratorPartialClass.cs: add uimanager field if
+ needed.
+
+2008-08-19 Mike Krüger <mkrueger@novell.com>
+
+ * libsteticui/CecilClassDescriptor.cs: fixed some possible nullrefs.
+
+2008-08-18 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/Widget.cs: null guarding for ToString().
+
+2008-08-10 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/LibraryCache.cs: add browsable properties and events
+ to the toolbox item entries in the objects xml doc.
+
+2008-07-27 Mike Krüger <mkrueger@novell.com>
+
+
+
+2008-07-24 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs (Load): use Refresh to get
+ the cache info so it has a better resolver to work with if the
+ cache is dirty.
+
+2008-07-22 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/LibraryCache.cs: only perform attribute parsing if
+ there is no objects.xml resource. If an objects.xml resource exists,
+ it is the definitive source of exported capabilities.
+
+2008-07-22 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/CecilClassDescriptor.cs: some null guarding in prop
+ lookup method.
+
+2008-07-21 Mike Kestner <mkestner@novell.com>
+
+ Patch from David Makovsky and Jeremie Laval.
+ * libstetic/PropertyDescriptor.cs: use invariant culture for doubles.
+ * libsteticui/GladeUtils.cs: use invariant culture for doubles.
+
+2008-07-16 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs (LoadDependencies): always set
+ up dependencies to ensure we never return null.
+
+2008-07-16 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/ApplicationBackend.cs (RegisterLibrary): null guarding.
+
+2008-07-14 Mike Krüger <mkrueger@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: fixed possible null reference
+ exception.
+
+2008-07-11 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/ApplicationBackend.cs: removed some CWL spew. This
+ case is apparently expected for first-time builds.
+
+2008-07-01 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/AssemblyResolver.cs: make type resolver public.
+ * libsteticui/LibraryCache.cs: [ToolboxItem] and [Category] scanner
+ for identification of exported widgets from libraries.
+
+2008-06-25 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/Application.cs: use resolver.
+ * libsteticui/ApplicationBackend.cs: use resolver.
+ * libsteticui/AssemblyResolver.cs: integrate ImportContext. remove
+ usused method and field resolution methods.
+ * libsteticui/AssemblyWidgetLibrary.cs: refactor ImportContext.
+ use cached objects doc.
+ * libsteticui/CecilWidgetLibrary.cs: refactor to use cached docs
+ and assembly resolver.
+ * libsteticui/LibraryCache.cs: add document props for objects/gui.
+ add objects and gui resource extraction and caching. Refresh using
+ resolver if available.
+ * libsteticui/ProjectBackend.cs: ImportContext refactor to resolver.
+
+2008-06-19 Mike Kestner <mkestner@novell.com>
+
+ * configure.in: detect cecil and substitute the dll path.
+ * libsteticui/Makefile.am: build using installed dll.
+ * libsteticui/lib/Mono.Cecil.dll: remove
+
+2008-06-19 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/AssemblyWidgetLibrary.cs: refactor to use LibraryCache.
+ * libsteticui/CecilWidgetLibrary.cs: use singleton Cache. Refine
+ NeedsReload. Call Load (XmlDocument) conditionally.
+ * libsteticui/LibraryCache.cs: hide Load and expose a singleton Cache
+ field to share between AssemblyWidgetLibrary and CecilWidgetLibrary.
+ Remove Gtk reference checking, we will use explicit ToolboxItem attrs
+ instead. Make HasWidgets a check for an objects.xml file, since we
+ will be constructing one for attr-only assemblies.
+
+2008-06-18 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/WidgetLibrary.cs: refactor class addition logic from Load
+ into a protected AddClass method which subclasses can use to add
+ classes marked with [ToolboxItem].
+
+2008-06-18 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: remove timestamp code and reuse
+ cache currency logic. flatten out an unnecessary if branch in Load.
+
+2008-06-18 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/Application.cs: remove dead code
+
+2008-06-02 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/Object.cs: dispose guarding
+ * libstetic/wrapper/Widget.cs: dispose guarding
+
+2008-05-28 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/editor/ActionGroupEditor.cs: dispose guarding
+ * libstetic/editor/ActionMenuItem.cs: dispose guarding
+ * libsteticui/ActionGroupDesigner.cs: dispose guarding
+ * libsteticui/ActionGroupEditSession.cs: dispose guarding
+ * libsteticui/ActionGroupToolbar.cs: dispose guarding
+ * libsteticui/WidgetActionBar.cs: dispose guarding
+
+2008-05-21 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/ActionToolbarWrapper.cs: call FillMenu on Wrap
+ so that the actionTree is populated on the editor. Otherwise we
+ crash when inserting items. [Fixes #377672] Also fix what looks to
+ be a copy/paste error on a UIManagerItemType in the ActionTree.
+
+2008-05-20 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/LibraryCache.cs: do a recursive delete when revising
+ the cache directory.
+
+2008-05-15 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/Application.cs: remove redundant cache. Destroy widgets
+ on Dispose instead of Disposing them.
+
+2008-05-13 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/Application.cs: refactor to split out isolated backend
+ and inprocess backend cases. Dispose additions. Destroy handling for
+ the public accessors.
+ * libsteticui/ApplicationBackendController.cs: use IsolatedApplication.
+ * libsteticui/PluggableWidget.cs: IsolatedApplication handling and
+ dispose rework.
+ * libsteticui/Project.cs: ditto.
+ * stetic/Stetic.cs: use new ApplicationFactory.
+
+2008-05-13 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/AssemblyResolver.cs: update to JBs latest Linker version.
+ * libsteticui/CecilWidgetLibrary.cs: use new cache API.
+ * libsteticui/LibraryCache.cs: rewritten to use instances,
+ XmlSerialization of the index and keep the index in memory, and to add
+ HasWidgets capability. Should be able to remove the other cache from
+ Application now.
+
+2008-05-11 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/SignalsEditor.cs: some Disposal bulletproofing.
+
+2008-04-30 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/objects.xml: clamp Gtk.Misc.(X|Y)align to values
+ between 0.0 and 1.0.
+
+2008-02-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/ActionItem.cs: Properly handle drag event fired by
+ the widget selection box. Fixes bug #363865.
+
+2008-02-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilClassDescriptor.cs,
+ libsteticui/CecilWidgetLibrary.cs: Properly load icons from
+ resurces.
+
+2008-02-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ErrorWidget.cs: Always write the ErrorWidget by reusing the
+ xml that generated it, unless we are exporting to another format,
+ in which case we can't write the same xml, and we replace it by a
+ label. Fixes bug #362596.
+
+2008-02-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilClassDescriptor.cs: Don't create black boxes for
+ custom widgets which allow children. Fixes bug #361650.
+ * libsteticui/ContextMenu.cs: Dont show invisible commands.
+ * libstetic/wrapper/Frame.cs, libstetic/wrapper/Table.cs,
+ libstetic/wrapper/Paned.cs, libstetic/wrapper/Box.cs,
+ libstetic/wrapper/ScrolledWindow.cs, libstetic/wrapper/Expander.cs,
+ libstetic/wrapper/Notebook.cs: Don't add placeholders if they are
+ not allowed.
+ * libstetic/wrapper/Container.cs: Don't allow placeholders if a
+ container can't have children.
+ * libstetic/wrapper/objects.xml: Hide commands not allowed when
+ containers does not allow children.
+
+2008-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionComponent.cs, libstetic/wrapper/Action.cs: Added wrapper
+ properties for Label and StockId, since the notify event is not being
+ fired for Gtk.Action.
+ * libstetic/editor/ActionMenuItem.cs, libstetic/editor/ActionToolItem.cs:
+ Use new Action wrapper properties to access to the label and stock id.
+
+2008-02-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/SignalsEditorBackend.cs: TargetObject can't be set when no
+ project is selected.
+
+2008-01-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/PropertyTree.cs: Use a theme color for the property group
+ headers. Fixes bug #356244.
+
+2008-01-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Label.cs: Fix generation of MnemonicWidget property
+ assignment.
+ * libstetic/wrapper/objects.xml: The default way of
+ * libstetic/editor/WidgetSelector.cs: Sort the list of widgets. Hide
+ unselectable widgets.
+
+2008-01-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/GuiDispatchServerSink.cs, libsteticui/WidgetDesigner.cs,
+ libsteticui/Project.cs: Made events fired by the designer synchronous.
+ Fixes some criticals caused by events being fired in the wrong order.
+ * libstetic/wrapper/Frame.cs, libstetic/wrapper/CheckButton.cs,
+ libstetic/wrapper/Container.cs, libstetic/wrapper/ScrolledWindow.cs: Fix
+ some gtk warnings and criticals.
+
+2008-01-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetDesigner.cs: Fix typo.
+
+2008-01-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/ComboBox.cs: Fix bug #324925 - Glade import: Text combos
+ not correctly imported.
+
+2008-01-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/Boolean.cs: Improve rendering of checkbox.
+
+2008-01-11 Marek Safar <marek.safar@gmail.com>
+
+ * libstetic/editor/ActionMenu.cs, libstetic/editor/ActionMenuBar.cs,
+ libstetic/editor/ActionToolbar.cs, libstetic/undo/ActionDiffAdaptor.cs
+ libstetic/editor/ActionGroupEditor.cs: Build with the latest gmcs.
+
+2008-01-11 Marek Safar <marek.safar@gmail.com>
+
+ * libsteticui/ActionGroupToolbar.cs: Build with the latest gmcs.
+
+2008-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs: Don't fire load events when loading a
+ widget. Fixes part of bug #352065.
+ * libstetic/wrapper/Paned.cs: Fix bug in paned initialization. Fixes part of
+ bug #352065.
+ * libstetic/editor/IconSelectorItem.cs: Added null check. Fixes some
+ crashes.
+
+2007-12-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Container.cs: Call base method when attaching/detaching
+ designer, since Object has some logic in those methods.
+
+2007-12-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/ScrolledWindow.cs, libstetic/wrapper/objects.xml: Set
+ the correct default for ScrolledWindow.XscrollbarPolicy.
+
+2007-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/ActionMenuItem.cs: Don't try to remove the menu item
+ controls if they have not been added to the table.
+
+2007-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/libsteticui.mdp, libstetic/libstetic.mdp, stetic/stetic.mdp,
+ stetic.mds: Updated.
+ * libstetic/wrapper/objects.xml: In ScrolledWindow, ignore the default for
+ scrollbar policy. The default value returned by gtk is not correct.
+ Fixes bug #344196.
+ * libstetic/ErrorWidget.cs: Allow exporting projects with unknown widgets.
+ * stetic/UIManager.cs: Use gtk stock icons instead of gnome's.
+
+2007-10-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/PaletteBackend.cs: Moved defaultActionIcon to ActionComponent.
+ * libsteticui/ActionComponent.cs, libsteticui/ComponentType.cs,
+ libstetic/wrapper/Action.cs: Added a label property to the
+ ActionComponent. The label will be shown in the toolbox now. Also show
+ the default action icon if no icon is specified, instead of the missing
+ image icon.
+
+2007-10-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/ActionItem.cs: Ignore the SelectionDisposed event if the
+ action item has already been disposed.
+
+2007-10-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs: Remove undo annotations from the xml
+ document when saving.
+
+2007-10-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml: Set default value for ShowScrollbars
+ property.
+
+2007-10-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/ActionItem.cs: The selected object needs to be the action
+ because that's what is shown in the properties pad.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/TextView.cs, libstetic/wrapper/TreeView.cs: By default,
+ show TextView and TreeView widgets wrapped in a ScrolledWindow. Fixes
+ bug #324439.
+ * libstetic/wrapper/Widget.cs, libstetic/wrapper/Container.cs,
+ libstetic/wrapper/ScrolledWindow.cs, libstetic/wrapper/Viewport.cs,
+ libstetic/wrapper/objects.xml: Implemented new ShowScrollbars
+ pseudo-property for widgets. When set, the widget will be wrapped inside
+ a ScrolledWindow. This scrolled window will be bound to the widget, so
+ if the widget is deleted or moved, the ScrolledWindow will also be
+ deleted or moved.
+ * libstetic/wrapper/Table.cs, libstetic/wrapper/Paned.cs,
+ libstetic/wrapper/Box.cs, libstetic/wrapper/Notebook.cs: Methods for
+ adding widgets to a container other than Add() do not fire the child
+ Added event, so it has to be manually called.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/Clipboard.cs, libsteticui/Clipboard.cs: Moved to libstetic.
+ * libstetic/editor/ActionGroupEditor.cs, libstetic/editor/ActionItem.cs,
+ libstetic/editor/ActionMenuItem.cs, libstetic/editor/ActionToolItem.cs:
+ Factorized common code in ActionMenuItem and ActionToolItem into
+ ActionItem. Implemented IEditableObject.
+ * libstetic/editor/ActionMenu.cs: Improved support for keyboard. Return now
+ edits the selected item, and ctrl+right/left adds/removes submenus.
+ * libstetic/editor/ActionMenuBar.cs, libstetic/editor/ActionToolbar.cs: Keep
+ the selection when a node is deleted. Track other api changes.
+ * libstetic/IEditableObject.cs: New interface to be implemented by objects
+ which can handle clipboard operations.
+ * libstetic/libstetic.mdp, libstetic/Makefile.am,
+ libsteticui/libsteticui.mdp, libsteticui/Makefile.am: Updated.
+ * libstetic/Placeholder.cs, libstetic/wrapper/Widget.cs: Implemented
+ IEditableObject.
+ * libsteticui/ContextMenu.cs: Use the new IEditableObject interface to
+ implement the clipboard operations.
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetDesigner.cs,
+ libsteticui/WidgetEditSession.cs: Use IEditableObject to handle
+ clipboard operations.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs: Removed unneeded dispose and destroy
+ calls. The toolbar will be destroyed together with the parent.
+ * libsteticui/ActionGroupEditSession.cs: If the designer has not been
+ requested, it means it has not been added to a container, so it has to
+ be explicitely destroyed.
+ * libsteticui/WidgetActionBar.cs: Removed unneeded Dispose and Destroy calls
+ (Destroy already calls dispose).
+ * libsteticui/WidgetDesignerBackend.cs: Make sure base.Dispose is always
+ called. Handle exceptions thrown by the GConf query.
+ * libsteticui/ActionGroupDesignerBackend.cs: Remove references on dispose.
+ Helps tracking down leaks.
+ * libsteticui/PluggableWidget.cs: Don't try to create an image of the
+ designer if it is not visible. Don't explicitely destroy the child
+ designer. It will be destroyed by the subclass.
+ * libstetic/editor/ActionToolbar.cs, libstetic/editor/ActionGroupEditor.cs:
+ Properly destroy items.
+
+2007-10-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Action.cs: Avoid providing a null name in the Gtk.Action
+ constructor. Fixes crash in gtk+ 2.12.
+
+2007-10-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: Added missing null check.
+
+2007-09-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/AssemblyWidgetLibrary.cs,
+ libsteticui/CecilWidgetLibrary.cs, libsteticui/ApplicationBackend.cs,
+ libsteticui/Application.cs: Added a callback for resolving assembly
+ names.
+
+2007-09-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs, libsteticui/Designer.cs,
+ libsteticui/WidgetDesigner.cs: Added a property for getting the project
+ element being edited in the designer.
+ * libsteticui/ComponentEventHandler.cs: Added property for getting the new
+ name in the args for the name change event.
+
+2007-09-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/WidgetUtils.cs: Fix version comparison logic.
+
+2007-09-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs,
+ libsteticui/Project.cs: Properly propagate the widget name change event
+ when saving the contents of the designer.
+
+2007-09-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs: Removed unneeded code.
+
+2007-09-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs: When
+ creating the designer, about creating twice the window widget (once for
+ the source project and once for the project being edited). Removed some
+ debug code.
+
+2007-09-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs, libsteticui/ApplicationBackend.cs,
+ libsteticui/Designer.cs, libsteticui/Application.cs,
+ libsteticui/WidgetDesigner.cs: The Application.ActiveProject has been
+ replaced by Application.ActiveDesigner, which coveys more information
+ about what to show in the designer widgets.
+ * libsteticui/ProjectBackend.cs, libsteticui/Project.cs, libstetic/DND.cs:
+ Implemented lazy loading of windows. The project now only loads the xml,
+ and only creates the widgets when they have to be shown in the designer.
+ * libsteticui/WidgetEditSession.cs, libsteticui/WidgetTree.cs,
+ libsteticui/ProjectView.cs, libsteticui/ProjectViewBackend.cs: Renamed
+ ProjectView to WidgetTree. This widget now only displays the widget tree
+ of the currently active designer.
+ * libsteticui/libsteticui.mdp, libsteticui/Makefile.am: Added new files.
+ * libsteticui/PaletteBackend.cs: Hide the palette if there is no active
+ project.
+ * libstetic/IProject.cs, libstetic/ObjectWrapper.cs,
+ libstetic/wrapper/Widget.cs: Added notification methods to IProject, in
+ this way some common events can be forwarded to the project without
+ having to subscribe them on every widget.
+ * libstetic/wrapper/Button.cs, libstetic/wrapper/Object.cs,
+ libstetic/wrapper/Container.cs, libstetic/TypedPropertyDescriptor.cs:
+ Make sure change events are not fired when widgets are loaded from xml.
+ * libstetic/WidgetUtils.cs: Removed unused code.
+ * stetic/Stetic.cs, stetic/DesignerView.cs, stetic/stetic.glade,
+ stetic/Makefile.am, stetic/stetic.mdp, stetic/WindowListWidget.cs,
+ stetic/UIManager.cs: Added a new widget for displaying the list of all
+ windows in the project, since the project view now only displays the
+ widget tree of the active designer. Track other api changes.
+
+2007-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml: Added support for NodeView. Fixes bug
+ #81238.
+
+2007-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/ComboBox.cs: Comboboxes are now of type Text by default.
+ Fixes bug #81763.
+
+2007-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Notebook.cs: Workaround for GTK bug. ShowAll is not
+ propagated to tab labels. Fixes bug #82476.
+
+2007-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs: When reloading a project, reuse the same
+ icon factory instance, since it may be inherited from another project.
+ Fixes bug #82527.
+ * libsteticui/WidgetEditSession.cs: Removed unneeded assignement.
+ * libsteticui/CodeGenerator.cs, libsteticui/CodeGeneratorInternalClass.cs,
+ libsteticui/CodeGeneratorPartialClass.cs, libstetic/GeneratorContext.cs:
+ Fix crash when generating the icon factory (the root object was not set
+ in the GeneratorContext).
+ * libsteticui/Project.cs: Special handling of IconFactory is not needed.
+ * libstetic/editor/ActionToolItem.cs: In CreateControls, fix crash caused by
+ the icon property being set too early, when it might be null.
+ * libstetic/editor/ActionToolbar.cs: Added missing null check.
+
+2007-09-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml: FileChooserButton doesn't have a default
+ constructor, it requires the title and the action. Fixes bug #82671.
+
+2007-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs, libsteticui/Application.cs,
+ libsteticui/ApplicationBackendController.cs: When a library is unloaded
+ notify the application frontend. The frontend can then clear cached data
+ from the library.
+ * libstetic/wrapper/objects.xml: Update EventBox category to 'container'.
+ * libstetic/ClassDescriptor.cs: When no label is set for a widget, use the
+ class name, without namespace.
+
+2007-08-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Widget.cs: Added missing null check. Don't set the Name
+ property to unselectable widgets.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Button.cs, libstetic/wrapper/ButtonBox.cs: Don't
+ store the IsDialogButton property. The value can be determined on
+ the fly.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs: Assign the target gtk version to
+ the project being edited.
+ * libstetic/wrapper/IconView.cs, libstetic/wrapper/objects.xml,
+ libstetic/libstetic.mdp, libstetic/Makefile.am: Added wrapper for
+ IconView.
+ * libstetic/TypedPropertyDescriptor.cs: Added null check.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ImageInfo.cs, libstetic/editor/ThemedIcon.cs,
+ libstetic/editor/SelectImageDialog.cs,
+ libstetic/editor/StockIconSelectorItem.cs,
+ libstetic/editor/StockIconList.cs, libstetic/editor/StockItem.cs,
+ libstetic/editor/SelectIconDialog.cs,
+ libstetic/GeneratorContext.cs, libstetic/WidgetUtils.cs: Fixed
+ loading of theme and gtk stock icons.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetPropertyTreeBackend.cs: Added missing null check.
+
+2007-07-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: Added null check.
+ * libsteticui/PluggableWidget.cs: When updating the child widget, do
+ not add it to the notebook if it is already a child of the
+ notebook.
+ * libstetic/wrapper/pixmaps/comboentry.png,
+ libstetic/wrapper/pixmaps/iconview.png, libstetic/libstetic.mdp,
+ libstetic/Makefile.am: Added some missing icons.
+ * libstetic/wrapper/Widget.cs, libstetic/wrapper/objects.xml: Fixed
+ some issues with HasDefault. It can only be assigned when the
+ widget already has a parent.
+ * libstetic/TypedClassDescriptor.cs: Report icon loading errors.
+
+2007-07-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs: Make DeleteSelection work for
+ placeholders.
+ * libsteticui/WidgetEditSession.cs, libsteticui/Component.cs,
+ libsteticui/WidgetDesigner.cs, libsteticui/WidgetComponent.cs:
+ Moved all clipboard checking properties to WidgetDesigner.
+
+2007-07-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Project.cs: Fixes on ActionGroup management.
+
+2007-07-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupToolbar.cs: Notify group changes to the
+ frontend.
+ * libsteticui/ActionGroupEditSession.cs: Don't delay the creation of
+ the designer because when used in combination with the widget
+ designer, change events are subscribed since the begining
+
+2007-07-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs: Fix NRE (bug #82052).
+
+2007-07-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/ActionMenuItem.cs,
+ libstetic/editor/ActionToolItem.cs: Show menu items and tool
+ buttons insensitive when bound to an insensitive action. Fixes bug
+ #81810.
+
+2007-07-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectViewBackend.cs: Cosmetic fixes.
+
+2007-07-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: Return 2.4 target gtk version is
+ none is provided.
+ * libsteticui/ApplicationBackend.cs, libsteticui/Application.cs,
+ libsteticui/ComponentType.cs: Added Library property to
+ ComponentType.
+ * libsteticui/PluggableWidget.cs: The widget may be unrealized after
+ adding the notebook. Added a null check for this case. Fixes bug
+ #81977.
+
+2007-06-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs, libsteticui/Application.cs,
+ libsteticui/ComponentType.cs: When reading the component list of a
+ library, get the target version.
+ * libsteticui/ApplicationBackend.cs: Properly report an error when
+ dropping a widget of a class that doesn't exist.
+ * libstetic/WidgetLibrary.cs, libstetic/DND.cs: Added null check.
+
+2007-06-27 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * libstetic/WidgetLibrary.cs: Added handling of
+ an empty objects.xml file.
+
+2007-06-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: When looking for widgets in a
+ library, ignore those without a palette category.
+ * libsteticui/ApplicationBackend.cs: Added null check.
+ * libsteticui/Application.cs: Don't try to load widgets from an
+ assembly if we know that's not a widget library.
+ * libstetic/CustomWidget.cs: Add IntPtr constructor.
+ * libstetic/EnumDescriptor.cs: Fix problem with the enum loading code,
+ which was not working when loading Gtk.SelectionMode, because it
+ has two members with the same value.
+ * libstetic/wrapper/Container.cs: When dropping an object, look for
+ placeholders in all the child hierarchy, not only the direct
+ childs.
+
+2007-06-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs: Flickering fixes.
+ * libsteticui/WidgetDesigner.cs: In BeginComponentDrag, don't take a
+ callback when the component type is known.
+
+2007-06-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs,
+ libsteticui/WidgetDesigner.cs, libsteticui/PluggableWidget.cs,
+ libsteticui/Project.cs: Fixed flickering in widget designers caused
+ by project reloading. The new ProjectReloading event is fired
+ before the whole process reloading starts, and the designer takes a
+ 'screenshot' of the old desiger, which is shown in place of the
+ real designer during the reloading process.
+ * libsteticui/CecilWidgetLibrary.cs, libsteticui/Application.cs: Added
+ GetComponentTypes method, which returns a list of widgets
+ implemented in a library, without having to load it.
+ * libsteticui/ApplicationBackend.cs, libstetic/IProject.cs,
+ libstetic/ObjectWriter.cs, libstetic/ObjectWrapper.cs,
+ libstetic/wrapper/Container.cs, libstetic/DND.cs: Added support for
+ dragging widgets from a palette before loading the widget library
+ that implements them. When the widget is dropped, a callback is
+ called (which is supposed to load the library) and the new widget
+ is created.
+ * libstetic/wrapper/pixmaps/widget.png, libstetic/libstetic.mdp,
+ libstetic/Makefile.am: Added new image.
+
+2007-06-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml: Added some missing gtk 2.8 properties.
+
+2007-06-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/SignalsEditorBackend.cs,
+ libsteticui/WidgetPropertyTreeBackend.cs,
+ libsteticui/WidgetEditSession.cs, libsteticui/PropertyTree.cs,
+ libsteticui/WidgetActionBar.cs, libsteticui/ApplicationBackend.cs,
+ libsteticui/PaletteBackend.cs, libsteticui/Project.cs,
+ libstetic/IProject.cs, libstetic/ItemDescriptor.cs,
+ libstetic/ObjectWrapper.cs, libstetic/WidgetLibrary.cs,
+ libstetic/ErrorWidget.cs, libstetic/WidgetUtils.cs,
+ libstetic/ClassDescriptor.cs: Allow selecting the target the gtk#
+ version of a project.
+ * libstetic/wrapper/objects.xml: Added new widgets, properties and
+ events for gtk# 2.6.
+
+2007-06-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/lib/Mono.Cecil.dll: Updated from SVN, to keep in sync
+ with MD.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Project.cs: Make sure the project backend is loaded when
+ checking the CanGenerateCode property.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ImageInfo.cs: Load images from a path relative to the entry
+ assembly location.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Project.cs: Fix problem with reading empty action groups.
+
+2007-06-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/GeneratorContext.cs: IconLoader must be an internal class.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Action.cs: Generate initialization of the Active
+ and DrawAsRadio properties. They are not generated by default
+ because they belong to a Gtk.Action subclass. Fixes bug #81785.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/Project.cs: Added method
+ for getting all widget types included in a project.
+ * libstetic/wrapper/objects.xml: Gtk.Bin now inherits the properties of
+ Gtk.Container.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilClassDescriptor.cs: Added missing null check when
+ checking for base classes in FindEvent.
+
+2007-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/libsteticui.mdp, libsteticui/Makefile.am: Added reference
+ to glib.
+ * libsteticui/WidgetActionBar.cs, libstetic/CommandDescriptor.cs: Use
+ Menu size for command icons.
+ * libsteticui/WidgetTreeCombo.cs: Replaced the popup widget menu by a
+ popup widget tree view. Fixes bug #81762.
+
+2007-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Window.cs: Store the WindowPosition property in the
+ Window wrapper, since it may sometimes be changed by the embedder
+ widget.
+ * libstetic/wrapper/objects.xml: Added default value for Widget.Events
+ property.
+ * libstetic/wrapper/Dialog.cs: (Wrap) Don't initialize the HasSeparator
+ property if the provided instance is already initialized.
+
+2007-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/ActionMenuBar.cs, libstetic/editor/ActionMenu.cs:
+ When a menu bar loses the focus, reset the menu item selection
+ before hiding the submenus. Fixes bug #81761.
+
+2007-05-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/StockIconSelectorItem.cs,
+ libstetic/editor/IconSelectorItem.cs: Added IntPtr constructors. It
+ seems to crash without them in some contexts.
+
+2007-05-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs: When saving write to a temporary file
+ first, just in case something fails.
+
+2007-05-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilSignalDescriptor.cs,
+ libsteticui/CecilWidgetLibrary.cs: Properly handle generic event
+ handler types. Fixes bug #80783.
+
+2007-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs,
+ libsteticui/WidgetDesigner.cs, libsteticui/Project.cs,
+ libstetic/IProject.cs: Added ImagesRootPath, which is the root path
+ where to start looking for images. Added the ImportFileCallback
+ callback, called when an image file is referenced from the stetic
+ project.
+ * libstetic/ImageInfo.cs: Image files are now relative to
+ ImagesRootPath.
+ * libstetic/stetic.glade, libstetic/editor/SelectImageDialog.cs: Use
+ the new root image path to create relative paths to images.
+ * libstetic/editor/ImageSelector.cs: Make the clean button smaller.
+ * libstetic/WidgetUtils.cs: Added AbsoluteToRelative function.
+
+2007-05-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Notebook.cs, libstetic/wrapper/objects.xml: Added
+ CurrentPage property to Notebook.
+
+2007-05-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilSignalDescriptor.cs: Added missing null check.
+ * libsteticui/ProjectBackend.cs: Remove debug cwl.
+ * libstetic/wrapper/Container.cs: Don't show the main window if the
+ visible flag is not set. Fixes bug #81365.
+
+2007-05-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetActionBar.cs, libstetic/CommandDescriptor.cs: Fix
+ bug about widget commands without an icon not being properly shown.
+ * libstetic/wrapper/Notebook.cs: Implemented Swap methods.
+ * libstetic/libstetic.mdp: Updated.
+
+2007-05-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs,
+ libsteticui/PaletteBackend.cs, libsteticui/Project.cs: Added
+ support for internal widgets and internal widget libraries.
+ Internal widgets won't be shown in the palette unless the library
+ to which they belong is internal to the project.
+ * libsteticui/Component.cs, libsteticui/ActionGroupComponent.cs,
+ libsteticui/WidgetComponent.cs: Added properties for changing the
+ GeneratePublic flag.
+ * libstetic/ImageInfo.cs, libstetic/ProjectIconFactory.cs,
+ libstetic/GeneratorContext.cs: Added a GenerateLoadPixbuf method
+ which creates a pixbuf from a stock image name in safe way (it
+ won't crash if the image doesn't exist, but it will return a
+ 'missing image' icon).
+ * libstetic/wrapper/ActionGroup.cs: Allow generatic private action
+ groups.
+ * libstetic/ClassDescriptor.cs: Added support for internal widgets.
+
+2007-05-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs, libsteticui/ProjectBackend.cs,
+ libsteticui/WidgetInfoEventHandler.cs, libsteticui/Application.cs,
+ libsteticui/Project.cs, libsteticui/PluggableWidget.cs,
+ stetic/Stetic.cs, stetic/DesignerView.cs, stetic/UIManager.cs:
+ Implemented lazy loading of projects. Project widgets won't be
+ instantiated until necessary. The new WidgetInfo class allows
+ getting the list of toplevels in a project without having to
+ completely load it.
+ * libsteticui/CecilSignalDescriptor.cs,
+ libsteticui/CecilPropertyDescriptor.cs,
+ libsteticui/LibraryCache.cs, libsteticui/CecilClassDescriptor.cs,
+ libsteticui/CecilWidgetLibrary.cs: Store parsed information in a
+ cache file. When loading the library again stetic will check if the
+ library has changed, and it if has not it will load widget info
+ from the cache file.
+ * libsteticui/libsteticui.mdp, libsteticui/Makefile.am: Updated.
+ * libsteticui/ProjectView.cs, libsteticui/ProjectViewBackend.cs: Added
+ SelectionChanged event. Moved from the Project class, since project
+ doesn't have the concept of Selection anymore.
+ * libsteticui/WidgetDesigner.cs: Added clipboard check operations from
+ the Project class.
+ * libstetic/wrapper/Widget.cs: After reading the info of a widget,
+ store the oldName field, so it can properly track name changes.
+ * stetic/Makefile.am, stetic/stetic.mdp: Added new files.
+
+2007-05-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/ScrolledWindow.cs: Manually notify that a child has
+ been added, since the child added event is not being fired.
+ * libstetic/GladeUtils.cs: Normalize glade field names when loading.
+
+2007-05-02 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/WidgetFactory.cs: don't Destroy from Dispose override
+ since the circular ref GC mechanism can get to the child before the
+ parent.
+
+2007-05-01 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/wrapper/ActionToolbarWrapper.cs:
+ * libstetic/editor/ActionMenuItem.cs:
+ * libstetic/editor/IconSelectorMenuItem.cs:
+ * libstetic/editor/ActionMenu.cs: Call base.Dispose on GLib.Objects
+ after all other dispose actions are performed.
+
+2007-05-01 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/WidgetFactory.cs:
+ * libsteticui/ProjectView.cs:
+ * libsteticui/PaletteBackend.cs:
+ * libsteticui/SignalsEditor.cs:
+ * libsteticui/ActionGroupToolbar.cs:
+ * libsteticui/WidgetDesigner.cs:
+ * libsteticui/PluggableWidget.cs:
+ * stetic/DesignerView.cs: Call base.Dispose on GLib.Objects after
+ all other dispose actions are performed.
+
+2007-04-27 Mike Kestner <mkestner@novell.com>
+
+ * libstetic/editor/ActionToolbar.cs (FillMenu): can't Destroy
+ after Disposing the widgets. Just Destroy, as it disposes.
+
+2007-04-27 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/ObjectWrapper.cs: ContainerChildHashItem.Equals needs
+ to return avoid cast and return false if comparing to another type.
+
+2007-04-26 Mike Kestner <mkestner@novell.com>
+
+ * libsteticui/PaletteBackend.cs: ActionGroupBox.Dispose needs to
+ do its cleanup before invoking base.Dispose.
+
+2007-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/libsteticui.mdp, libstetic/libstetic.mdp: Updated.
+ * libstetic/wrapper/Box.cs, libstetic/wrapper/Table.cs: Set spacing to
+ 6 by default.
+ * libstetic/wrapper/ScrolledWindow.cs: Set scrolling to automatic by
+ default.
+ * libstetic/WidgetUtils.cs, libstetic/ClassDescriptor.cs,
+ libstetic/TypedClassDescriptor.cs: When looking for default values,
+ avoid initializing the test instance, make sure the get an instance
+ with all default values.
+
+2007-04-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CecilWidgetLibrary.cs: Performance improvements in the
+ method that resolves widget types.
+ * libstetic/wrapper/ButtonBox.cs: Don't automatically bind dialog
+ buttons with response type set to None.
+ * libstetic/PropertyDescriptor.cs: Set the hasDefault flag when a
+ default is explicitely set in the objects.xml file.
+ * libstetic/Makefile.am: Updated.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs: Don't allow cutting/copying top
+ level widgets. Fixes bug #81015.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs: When
+ selecting a widget, avoid setting the focus to the parent
+ container, since it may end changing the selection. Fixes bug
+ #81014.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml: Removed properties already inherited
+ from Gtk.Button.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/undo/XmlDiffAdaptor.cs: Don't crash if a child element
+ doesn't exist.
+ * libstetic/editor/StockItem.cs: Fix warning.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/ScrolledWindow.cs: Don't generate the viewport if
+ there isn't any child. Make scrollbars always visible in the
+ designer.
+ * libstetic/wrapper/objects.xml: Ignore the default for DrawIndicator,
+ since the default is 'false', but a default CheckButton has 'true'
+ as value.
+
+2007-03-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs,
+ libsteticui/CodeGeneratorPartialClass.cs,
+ libstetic/wrapper/Widget.cs, libstetic/wrapper/objects.xml: Support
+ generating private classes.
+ * libsteticui/ComponentType.cs, libstetic/ImageInfo.cs,
+ libstetic/wrapper/Action.cs, libstetic/wrapper/ImageMenuItem.cs,
+ libstetic/editor/StockItem.cs, libstetic/WidgetUtils.cs: Use the
+ new MissingIcon constant.
+ * libstetic/wrapper/ComboBox.cs: Made combo values translatable. Fixes
+ bug #81033.
+ * libstetic/HandleWindow.cs: Removed unused file.
+
+2007-03-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Container.cs: Fix null ref.
+ * libstetic/wrapper/Widget.cs: Use a wrapper property for CanFocus
+ since it may be changed by the designer.
+
+2007-03-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetDesignerBackend.cs: ResetSelection now sets the
+ focus to the fixed container.
+ * libsteticui/PropertyTree.cs: Dispose the edit session of a cell when
+ losing the focus.
+ * libsteticui/PaletteBackend.cs: Don't call SetActionGroups when
+ disposing, since it ends calling show().
+ * libstetic/wrapper/Container.cs: Use ResetSelection to remove the
+ focus from the current widget.
+ * libstetic/editor/TextEditor.cs: Don't fire the changed event at every
+ key press, only when pressing enter or losing the focus.
+ * libstetic/PropertyEditorCell.cs: When losing the focus, update the
+ property value.
+ * libstetic/wrapper/Widget.cs: Don't try to change widget event flags
+ if the widget is already realized.
+
+2007-03-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs: Added some null checks. Added
+ BeginComponentDrag, to allow using an external toolbox.
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetDesigner.cs,
+ libsteticui/Project.cs: Added method for getting all component
+ types accessible from a project. Added some null checks.
+ * libsteticui/WidgetEditSession.cs: Reload the project when the widget
+ libraries change.
+ * libsteticui/Application.cs: Fill ComponentType with category
+ information.
+ * libsteticui/PropertyTree.cs: Removed the horizontall scrollbar. Cell
+ size will always fit the available space. Allow changing the column
+ width by dragging the divider.
+ * libsteticui/PaletteBackend.cs: The library list of a project now
+ includes the core library.
+ * libsteticui/ActionGroupComponent.cs: Added null check.
+ * libsteticui/ComponentType.cs: Added category information. Allow
+ creating a ComponentType from an action.
+ * libsteticui/WidgetComponent.cs: Added some null checks.
+ * libstetic/editor/Enumeration.cs: Use a combo box entry with no frame
+ as selector. It takes less space.
+ * libstetic/editor/TextEditor.cs, libstetic/editor/Flags.cs,
+ libstetic/editor/String.cs, libstetic/editor/IntRange.cs,
+ libstetic/editor/Identifier.cs, libstetic/editor/OptIntRange.cs,
+ libstetic/editor/StringArray.cs: Removed frames from all editors.
+ Take less space.
+
+
+
+2007-02-24 Zach Lute <zach.lute@gmail.com>
+
+ * libstetic/ImageInfo.cs: Fixed an issue in which an image thumbnail
+ wouldn't be scaled if width and height were equal. Fixes bug #80927.
+
+2007-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ObjectReader.cs, libstetic/wrapper/Container.cs: Fixed
+ issues with internal children when importing a glade file.
+ * libstetic/GladeUtils.cs: Use invariant culture to parse floats.
+
+2007-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupEditSession.cs: Added null check.
+ * libstetic/wrapper/Action.cs: Don't set the type to Radio unless a
+ real group name is provided.
+ * libstetic/editor/ActionMenu.cs: Set AppPaintable, since we do some
+ custom painting in the Expose event. Also call the base
+ OnExposeEvent after painting the background. Fixes bug #80864.
+
+
+
+2007-02-19 Nate Hancock <nchancock@yahoo.com>
+
+ * libstetic/wrapper/object.xml: Gtk.ToggleButton now has base class
+ Gtk.Button instead of Gtk.Container.
+
+2007-02-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetFactory.cs, libsteticui/WidgetEditSession.cs:
+ Several fixes in the disposing code.
+ * libsteticui/ActionGroupToolbar.cs: Unsubscribe all events, since gtk#
+ seems to leak if not done. Replaced all anonymous methods, since
+ keep to many references in memory.
+ * libsteticui/ActionGroupDesignerBackend.cs: Removed the Dispose
+ method, since everything will be disposed when the backend is
+ destroyed.
+ * libsteticui/libsteticui.mdp, libstetic/libstetic.mdp,
+ stetic/stetic.mdp: Updated.
+ * libsteticui/WidgetDesigner.cs: Added some checks to avoid operating
+ on disposed designers.
+ * libsteticui/ActionGroupEditSession.cs: Delay the creation of the
+ action group designer until it is really required.
+ * libsteticui/PluggableWidget.cs: Explicitely destroy replaced
+ children.
+ * libstetic/undo/UndoManager.cs: Don't use an anonymous method since it
+ will hold a reference to the object to which the event is being
+ added, and we don't want this.
+ * libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs: Moved
+ tooltip generation code from Widget to Container. Reset the
+ generated widget code when starting code generation.
+ * libstetic/wrapper/MenuBar.cs: Dispose the attached ActionTreeNode
+ object when the palette item is disposed.
+ * libstetic/wrapper/ActionTree.cs: Recursively dispose node children.
+ * libstetic/editor/ActionGroupEditor.cs: Unsubscribe events when
+ disposing.
+
+2007-02-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Container.cs: Emit the content changed event when a
+ new child is added.
+ * libstetic/wrapper/Paned.cs: Add1 and Add2 does not fire the child
+ added event, so the parent has to be manually notified.
+
+2007-02-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/RadioGroupManager.cs: Implement the IRadioGroupManager
+ interface.
+ * libstetic/wrapper/Action.cs, libstetic/wrapper/objects.xml,
+ libstetic/wrapper/RadioActionGroupManager.cs: Implemented support
+ for radio groups in RadioAction objects.
+ * libstetic/wrapper/RadioToolButton.cs,
+ libstetic/wrapper/RadioButton.cs,
+ libstetic/wrapper/RadioMenuItem.cs: Implement the new
+ IRadioGroupManagerProvider interface.
+ * libstetic/IRadioGroupManager.cs: Added new interface for wrapping
+ group managers.
+ * libstetic/editor/GroupPicker.cs: Get the group manager from the
+ manager provider, instead of looking for a static method.
+ * libstetic/libstetic.mdp, libstetic/Makefile.am: Updated.
+
+2007-02-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs, libsteticui/Application.cs,
+ libstetic/stetic.glade, libstetic/wrapper/Container.cs,
+ libstetic/editor/NonContainerWarningDialog.cs,
+ libstetic/libstetic.mdp, libstetic/Makefile.am, stetic/Stetic.cs,
+ stetic/Configuration.cs: When dropping a non-container into a main
+ window, warn the user whether they really wanted that, or if they
+ instead wanted a container to be in place. Make this warning dialog
+ configurable.
+ * libsteticui/PropertyTree.cs: Removed unused code.
+
+2007-02-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/PropertyTree.cs: Refiltering the tree while it is being
+ edited has lots of issues, so filtering has been completely
+ removed. Now, the label of hidden properties are shown as disabled,
+ and the content blank.
+ * stetic/Makefile.am, stetic/stetic.mdp: Added missing resource.
+
+2007-02-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/libsteticui.mdp, libsteticui/Makefile.am,
+ libstetic/Makefile.am, stetic/Makefile.am: Flush.
+ * libsteticui/WidgetDesigner.cs: When disposing the active project,
+ reset the active project property.
+ * libstetic/GeneratorContext.cs: Added a code generation option for
+ specifying the Gettext class to use.
+
+2007-02-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/libsteticui.mdp, libsteticui/Makefile.am: Fixed
+ references.
+ * configure.in: Added missing modules.
+
+2007-02-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Makefile.am, libstetic/Makefile.am, stetic/Makefile.am:
+ Distcheck fixes.
+ * libstetic/GeneratorContext.cs: Don't generate gettext for empty
+ strings.
+ * configure.in: Add missing package.
+ * stetic/stetic.mdp, libsteticui/libsteticui.mdp,
+ libstetic/libstetic.mdp, stetic.mds: Added MonoDevelop projects.
+
+2007-02-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs: Clone the widget library list from
+ the master project since the list is cleared when the copy project
+ is closed.
+ * libstetic/ObjectWrapper.cs, libstetic/wrapper/Button.cs,
+ libstetic/PropertyDescriptor.cs, libstetic/WidgetUtils.cs: Properly
+ generate translatable properties.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/SelectImageDialog.cs,
+ libstetic/editor/StockIconSelectorItem.cs,
+ libstetic/editor/SelectIconDialog.cs, libstetic/WidgetUtils.cs,
+ libstetic/TypedClassDescriptor.cs,
+ libstetic/wrapper/pixmaps/missing.png: Looks like some themes don't
+ have icon for gtk-missing-image. Added a fallback to avoid crashes.
+ * stetic/UIManager.cs: Action fixes.
+
+2007-02-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * configure.in: More dependency removal.
+
+2007-02-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * autogen.sh: Removed gnome-common dependency.
+
+2007-01-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Clipboard.cs: Use the new PasteChild method, since
+ ReplaceChild is now protected.
+ * libsteticui/Glade.cs: Don't try to resolve references when loading a
+ glade file.
+ * libsteticui/libsteticui.dll.config, libstetic/libstetic.dll.config:
+ Added dlls maps for MacOSX
+ * libstetic/wrapper/Button.cs, libstetic/wrapper/CheckButton.cs: Set
+ UseUnderline = true by default.
+ * libstetic/wrapper/Container.cs: Made ReplaceChild protected. Make
+ sure widgets copied from clipboard are properly registered in the
+ undo system.
+ * libstetic/wrapper/Paned.cs, libstetic/wrapper/Box.cs,
+ libstetic/wrapper/Frame.cs, libstetic/wrapper/Fixed.cs,
+ libstetic/wrapper/ScrolledWindow.cs, libstetic/wrapper/Toolbar.cs,
+ libstetic/wrapper/Notebook.cs, libstetic/wrapper/Expander.cs: Made
+ ReplaceChild protected.
+ * libstetic/wrapper/ComboBoxEntry.cs: Fix code generation issue for
+ text combo box.
+ * libstetic/wrapper/objects.xml: Added UseUnderline property to
+ CheckButton.
+ * libstetic/DND.cs: Use the native format for copy/paste widgets.
+
+2007-01-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CodeGenerator.cs,
+ libsteticui/CodeGeneratorInternalClass.cs,
+ libsteticui/CodeGeneratorPartialClass.cs: Make sure the globla
+ Initialization is called from internal and partial classes.
+ * libstetic/editor/ActionMenuItem.cs,
+ libstetic/editor/ActionToolItem.cs: Fix compilation conflict with
+ recent gtk# versions.
+
+2007-01-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetDesigner.cs: Avoid disposing twice the designer.
+
+2007-01-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs, libsteticui/ProjectBackend.cs,
+ libsteticui/Application.cs: Fixed problem when updating project
+ libraries. Make sure referenced libraries are not unloaded when
+ they are still needed.
+ * libsteticui/CecilWidgetLibrary.cs: Null check.
+
+2007-01-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs, libsteticui/ProjectView.cs,
+ libsteticui/SignalsEditor.cs, libsteticui/PluggableWidget.cs: Some
+ protection to avoid dispatching some events after the object has
+ been disposed.
+ * libsteticui/ApplicationBackend.cs: Changed the way libraries are
+ loaded. If a library has dependencies, the dependencies are loaded
+ first.
+ * libsteticui/CecilSignalDescriptor.cs,
+ libsteticui/CecilPropertyDescriptor.cs,
+ libsteticui/AssemblyResolver.cs,
+ libsteticui/CecilClassDescriptor.cs,
+ libsteticui/CecilWidgetLibrary.cs: New classes which allow loading
+ a widget library using cecil.
+ * libsteticui/ProjectBackend.cs, libsteticui/Project.cs: Project
+ libraries are now stored in the project file. In this way it is
+ possible to generate code for projects which depend on other
+ libraries using the command line tool.
+ * libsteticui/GuiDispatchServerSink.cs: Removed debug message.
+ * libsteticui/CodeGenerator.cs: Avoid dependency on
+ TypeSignalDescriptor.
+ * libsteticui/WidgetTreeCombo.cs, stetic/Stetic.cs: Misc fixes.
+ * libsteticui/WidgetEditSession.cs, libsteticui/WidgetDesigner.cs: Some
+ protection to avoid dispatching some events after the object has
+ been disposed. Some fixes for the out-of-process mode.
+ * libsteticui/Application.cs: Implemented method which determines if an
+ assembly is a widget library or not. Other misc fixes.
+ * libsteticui/PaletteBackend.cs: Update the widget list when the
+ registry changes.
+ * libsteticui/Makefile.am: Updated. Added Cecil dependency.
+ * libsteticui/AssemblyWidgetLibrary.cs, libstetic/WidgetLibrary.cs:
+ Added GetLibraryDependencies method, which returns widget libraries
+ needed by the widgets of this library.
+ * libstetic/ItemGroup.cs, libstetic/Registry.cs: When looking for an
+ item group of a class, avoid returning a group which has not been
+ declared in the class, but inherited by a base class.
+ * libstetic/NoGuiDispatchAttribute.cs: Moved from libsteticui to
+ libstetic.
+ * libstetic/ObjectWrapper.cs: Added an extended data property where
+ class descriptors can store random information.
+ * libstetic/wrapper/Container.cs: Removed dependency on
+ TypeClassDescriptor.
+ * libstetic/wrapper/FontSelectionDialog.cs,
+ libstetic/wrapper/ComboBox.cs, libstetic/wrapper/ColorButton.cs:
+ Set the correct base class.
+ * libstetic/wrapper/ScrolledWindow.cs: Destory viewport after replacing
+ it.
+ * libstetic/wrapper/objects.xml, libstetic/ClassDescriptor.cs,
+ libstetic/TypedClassDescriptor.cs: Implemented support for
+ 'base-type' attribute, which means that a widget class inherits all
+ properties and events of the referenced type.
+ * libstetic/wrapper/TreeView.cs: New wrapper for TreeView.
+ * libstetic/Makefile.am: Updated.
+ * libstetic/AssemblyWidgetLibrary.cs: Moved to libsteticui.
+
+2007-01-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/EnumDescriptor.cs: Avoid importing enum values which have
+ not been declared in the xml file. Shoud fix bugs 80007 and 80471.
+ * libstetic/wrapper/objects.xml: Removed missing property.
+
+2007-01-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs: Fixed some warnings.
+ * libsteticui/WidgetDesignerBackend.cs,
+ libsteticui/WidgetEditSession.cs, libstetic/IDesignArea.cs,
+ libstetic/editor/ActionMenuItem.cs,
+ libstetic/editor/ActionToolItem.cs: Provide information about the
+ drag hot point when firing the drag event. Allow enabling/disabling
+ drag support.
+ * libsteticui/ProjectBackend.cs: Fix cast exception when changing
+ signals in actions.
+ * libsteticui/Clipboard.cs, libstetic/wrapper/Button.cs,
+ libstetic/wrapper/Frame.cs, libstetic/wrapper/ButtonBox.cs: User
+ the new ReplaceChild overload.
+ * libsteticui/WidgetDesigner.cs: Improve error message when the
+ designet can't be loaded.
+ * libsteticui/Makefile.am, configure.in, stetic/Makefile.am: Build
+ libstetic with mcs instead of gmcs, since that assembly may need to
+ be linked with widget libraries based on .net 1.1.
+ * libstetic/wrapper/pixmaps/fixed.png: New bitmap for Gtk.Fixed.
+ * libstetic/wrapper/Container.cs: Added protected methods for notifying
+ the add/remove child event, since some containers don't fire them.
+ Added ReplaceChild overload which will explicitely destroy the
+ replaced widget. Don't allow dragging top level widgets.
+ * libstetic/wrapper/Fixed.cs, libstetic/Makefile.am: Implemented
+ support for Gtk.Fixed.
+ * libstetic/wrapper/Window.cs: Don't generate code for the Type
+ property, since it's read-only.
+ * libstetic/wrapper/objects.xml: Implemented support for Gtk.Fixed.
+ Hide the Type property, since code for that property can't be
+ generated (it must be provided by the user in the window
+ constructor.
+ * libstetic/DND.cs: Added properties for getting the hot drag point
+ when dragging a widget.
+
+2007-01-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/UndoQueue.cs: Removed debug messages.
+
+2007-01-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ApplicationBackend.cs, libstetic/Registry.cs: Allow
+ grouping several changes in the registry in a single transaction.
+ * libsteticui/CodeGenerator.cs, libsteticui/Application.cs,
+ libsteticui/CodeGeneratorInternalClass.cs,
+ libsteticui/CodeGeneratorPartialClass.cs,
+ libsteticui/CodeGenerationResult.cs, libstetic/ObjectWrapper.cs,
+ libstetic/GeneratorContext.cs, libstetic/ErrorWidget.cs,
+ stetic/Stetic.cs: Added an option to allow generating code even
+ when not all referenced widgets are available. Added support for
+ warnings in the code generation methods, so the caller can get
+ information about what went wrong during the generation process.
+ * libsteticui/Makefile.am: Added CodeGenerationResult.
+ * libstetic/wrapper/Widget.cs: Clear the signal list when reloading a
+ widget. Fixed action group read code.
+ * libstetic/wrapper/Table.cs: Always return the children of the table
+ in the same order, to avoid unneeded changes in the diff files.
+
+2007-01-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ContainerUndoRedoManager.cs: Added missing file.
+
+2007-01-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs: When saving the designer session,
+ instead of deleting the old widget and adding the new one, update
+ the existing widget.
+ * libsteticui/Application.cs: Added some thread locking.
+ * libsteticui/Project.cs: When a widget name changed event is received,
+ update the corresponding component from the current thread, there
+ is no need to do it in the gui thread.
+ * libstetic/wrapper/Container.cs: Added null check for container child.
+
+2007-01-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs, libsteticui/WidgetDesigner.cs,
+ libsteticui/ActionGroupEditSession.cs: Added undo support for the
+ global action group designer.
+ * libsteticui/ApplicationBackend.cs: Catch errors when loading a
+ library to avoid aborting the whole update operation.
+ * libsteticui/ProjectBackend.cs,
+ libsteticui/CodeGeneratorInternalClass.cs,
+ libsteticui/PaletteBackend.cs, libsteticui/PropertyGrid.cs,
+ libstetic/undo/ActionDiffAdaptor.cs, stetic/Stetic.cs,
+ stetic/DesignerView.cs: Track api changes.
+ * libsteticui/CodeGenerator.cs: Include actions in the bind field list.
+ * libsteticui/ComponentEventHandler.cs, libsteticui/Project.cs: The
+ component removed event now provides the name of the removed
+ component, no the component reference. Needed since the component
+ is already removed, and providing an instance in this case is
+ problematic.
+ * libsteticui/ActionComponent.cs: Added property for gettion the group
+ of an action.
+ * libsteticui/Makefile.am: Added new file.
+ * libsteticui/UndoQueue.cs: Generalized the undo manager, so it can be
+ used for the action group editor.
+ * libstetic/undo/DiffGenerator.cs: Improved error message.
+ * libstetic/undo/UndoManager.cs: Make sure the UndoWriter works for
+ wrappers other than widgets. Don't include disposed or unregistered
+ wrappers into the undo event.
+ * libstetic/ObjectWrapper.cs: Factorized some undo properties and
+ methods into ObjectWrapper.
+ * libstetic/wrapper/Action.cs: More undo support.
+ * libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs: Removed
+ some methods and properties now implemented in ObjectWrapper.
+ * libstetic/wrapper/ActionGroup.cs: ActionGroup is now an ObjectWrapper
+ subclass. Added better support for Undo.
+ * libstetic/editor/ActionGroupEditor.cs: Use new new ObjectChanged
+ event.
+ * libstetic/GeneratorContext.cs: Made GenerateInstanceExpression
+ public.
+ * stetic/LibraryManagerDialog.cs: Fixed warning.
+
+2007-01-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CodeGenerator.cs: Don't generate variables for
+ unselectable widgets. Use CodeDom expressions instead of variable
+ names when possible. When using partial classes, avoid creating
+ unneeded local variables, use field references instead.
+ * libsteticui/WidgetTreeCombo.cs: Don't show unselectable widgets, but
+ show its children if they are selectable.
+ * libsteticui/CodeGeneratorInternalClass.cs: Use CodeDom expressions
+ instead of variable names when possible. Fixed some incorrect
+ variable names. Make sure the generated class names are valid.
+ * libsteticui/CodeGeneratorPartialClass.cs: Use CodeDom expressions
+ instead of variable names when possible.
+ * libstetic/RadioGroupManager.cs, libstetic/ObjectWrapper.cs,
+ libstetic/wrapper/Button.cs, libstetic/wrapper/Label.cs,
+ libstetic/wrapper/TextView.cs,
+ libstetic/wrapper/RadioToolButton.cs,
+ libstetic/wrapper/RadioButton.cs, libstetic/wrapper/Frame.cs,
+ libstetic/wrapper/ActionGroup.cs, libstetic/wrapper/Window.cs,
+ libstetic/wrapper/ComboBox.cs, libstetic/wrapper/ColorButton.cs,
+ libstetic/wrapper/Notebook.cs, libstetic/wrapper/ButtonBox.cs,
+ libstetic/wrapper/MenuBar.cs,
+ libstetic/wrapper/ActionToolbarWrapper.cs,
+ libstetic/wrapper/RadioMenuItem.cs, libstetic/wrapper/Expander.cs,
+ libstetic/wrapper/Bin.cs, libstetic/wrapper/CheckButton.cs,
+ libstetic/ErrorWidget.cs: Track api changes. Variable name in code
+ generation methods has been replaced by a CodeDom expression.
+ * libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs: Instead
+ of calling Show for each visible widget, call ShowAll on the top
+ level container child, and hide all invisible widgets. Track api
+ changes.
+ * libstetic/GeneratorContext.cs: Don't use variable names to reference
+ widget instances anymore, use CodeDom expressions instead. Needed
+ since widgets can be stored in variables and in fields.
+
+2006-12-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs,
+ libsteticui/WidgetDesigner.cs, libsteticui/Project.cs: Added new
+ Changed event.
+ * libsteticui/PaletteBackend.cs, libsteticui/UndoQueue.cs,
+ libstetic/undo/DiffGenerator.cs,
+ libstetic/undo/ActionDiffAdaptor.cs, libstetic/wrapper/Action.cs,
+ libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs,
+ libstetic/wrapper/ActionGroup.cs, libstetic/wrapper/MenuBar.cs,
+ libstetic/wrapper/ActionTree.cs,
+ libstetic/editor/ActionMenuItem.cs,
+ libstetic/editor/ActionMenuBar.cs, libstetic/editor/ActionMenu.cs,
+ libstetic/editor/ActionToolItem.cs,
+ libstetic/editor/ActionToolbar.cs: Improved support for Undo.
+ * libstetic/undo/UndoManager.cs: Removed debug code.
+ * libstetic/undo/XmlDiffAdaptor.cs: Fix support for name and id
+ properties when diffing.
+ * libstetic/wrapper/objects.xml: HasFocus property doesn't need to be
+ available at design time.
+ * libstetic/wrapper/ActionToolbarWrapper.cs: Implemented support for
+ Undo.
+
+2006-12-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ProjectBackend.cs, libsteticui/WidgetEditSession.cs,
+ libsteticui/WidgetDesigner.cs, libsteticui/Project.cs: Added new
+ Changed event.
+ * libsteticui/PaletteBackend.cs, libsteticui/UndoQueue.cs,
+ libstetic/undo/DiffGenerator.cs,
+ libstetic/undo/ActionDiffAdaptor.cs, libstetic/wrapper/Action.cs,
+ libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs,
+ libstetic/wrapper/ActionGroup.cs, libstetic/wrapper/MenuBar.cs,
+ libstetic/wrapper/ActionTree.cs,
+ libstetic/editor/ActionMenuItem.cs,
+ libstetic/editor/ActionMenuBar.cs, libstetic/editor/ActionMenu.cs,
+ libstetic/editor/ActionToolItem.cs,
+ libstetic/editor/ActionToolbar.cs: Improved support for Undo.
+ * libstetic/undo/UndoManager.cs: Removed debug code.
+ * libstetic/undo/XmlDiffAdaptor.cs: Fix support for name and id
+ properties when diffing.
+ * libstetic/wrapper/objects.xml: HasFocus property doesn't need to be
+ available at design time.
+ * libstetic/wrapper/ActionToolbarWrapper.cs: Implemented support for
+ Undo.
+
+2006-12-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/UndoQueue.cs: Added debug method.
+ * libstetic/UndoManager.cs: Moved to undo dir.
+ * libstetic/undo, libstetic/undo/IDiffAdaptor.cs,
+ libstetic/undo/DiffGenerator.cs, libstetic/undo/UndoManager.cs,
+ libstetic/undo/ActionDiffAdaptor.cs,
+ libstetic/undo/XmlDiffAdaptor.cs: Moved here UndoManager and added
+ some classes to generate undo diffs between objects and xml
+ representations.
+ * libstetic/wrapper/Button.cs, libstetic/wrapper/RadioToolButton.cs,
+ libstetic/wrapper/RadioButton.cs, libstetic/wrapper/OptionMenu.cs,
+ libstetic/wrapper/Image.cs, libstetic/wrapper/ImageMenuItem.cs,
+ libstetic/wrapper/RadioMenuItem.cs,
+ libstetic/wrapper/ToolButton.cs: Track api changes.
+ * libstetic/wrapper/Action.cs, libstetic/wrapper/ActionGroup.cs,
+ libstetic/wrapper/MenuBar.cs,
+ libstetic/wrapper/ActionToolbarWrapper.cs: Added support for
+ Undo/Redo.
+ * libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs: Moved
+ all diffing code to the DiffGenerator class.
+ * libstetic/Placeholder.cs: Changed the name of the undo id property.
+ * libstetic/editor/ActionMenuItem.cs: Made atomic some action property
+ changes.
+ * libstetic/editor/ActionMenuBar.cs, libstetic/editor/ActionMenu.cs:
+ Added methods for saving/restoring the selection of a menu and
+ toolbar.
+ * libstetic/TypedPropertyDescriptor.cs: Added null check.
+ * libstetic/Makefile.am: Updated.
+
+2006-12-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs: Added null check.
+ * libsteticui/ProjectBackend.cs: Always return the top level widgets in
+ the same order they were stored in the project file.
+ * libsteticui/WidgetEditSession.cs, libsteticui/Clipboard.cs,
+ libsteticui/WidgetDesigner.cs, libsteticui/UndoQueue.cs,
+ libstetic/UndoManager.cs, libstetic/ObjectWrapper.cs,
+ libstetic/Placeholder.cs, stetic/Stetic.cs, stetic/DesignerView.cs,
+ stetic/UIManager.cs: Added support for undo/redo.
+ * libsteticui/Application.cs: Minor fix.
+ * libsteticui/Glade.cs, libsteticui/ActionGroupEditSession.cs,
+ libstetic/wrapper/Button.cs, libstetic/wrapper/Action.cs,
+ libstetic/wrapper/Container.cs, libstetic/wrapper/Widget.cs,
+ libstetic/wrapper/RadioToolButton.cs,
+ libstetic/wrapper/RadioButton.cs, libstetic/wrapper/Frame.cs,
+ libstetic/wrapper/ActionGroup.cs, libstetic/wrapper/OptionMenu.cs,
+ libstetic/wrapper/Notebook.cs, libstetic/wrapper/Image.cs,
+ libstetic/wrapper/MenuItem.cs, libstetic/wrapper/ButtonBox.cs,
+ libstetic/wrapper/ImageMenuItem.cs, libstetic/wrapper/Table.cs,
+ libstetic/wrapper/MenuBar.cs, libstetic/wrapper/Dialog.cs,
+ libstetic/wrapper/ActionToolbarWrapper.cs,
+ libstetic/wrapper/RadioMenuItem.cs, libstetic/wrapper/Expander.cs,
+ libstetic/wrapper/CheckButton.cs, libstetic/wrapper/ToolButton.cs,
+ libstetic/GladeUtils.cs, libstetic/ErrorWidget.cs,
+ libstetic/WidgetUtils.cs: Track api changes.
+ * libsteticui/Makefile.am, libstetic/Makefile.am: Updated.
+ * libsteticui/Project.cs: Update the app library list after removing a
+ project.
+ * libstetic/ItemGroup.cs: Use an ordered dictionary to store
+ properties, so we always get them in the correct order.
+ * libstetic/CommandDescriptor.cs: Make sure the changes done by
+ commands are atomic.
+ * libstetic/ObjectReader.cs, libstetic/ObjectWriter.cs: New clases for
+ reading/writing objects
+ * libstetic/PropertyDescriptor.cs,
+ libstetic/TypedPropertyDescriptor.cs, libstetic/ClassDescriptor.cs,
+ libstetic/TypedClassDescriptor.cs: Added new method for
+ initializing and instance to its default values.
+
+2006-11-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/Flags.cs:
+ * libstetic/editor/ActionToolItem.cs:
+ Fix build. Patch by Michael Schurter.
+
+2006-09-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetEditSession.cs:
+ * libsteticui/Palette.cs:
+ * libsteticui/ProjectView.cs:
+ * libsteticui/SignalsEditor.cs:
+ * libsteticui/ApplicationBackend.cs: Reconnect the plug when the socket
+ is unrealized.
+
+ * libsteticui/WidgetDesignerBackend.cs: Added null check.
+
+ * libsteticui/WidgetDesigner.cs:
+ * libsteticui/ActionGroupEditSession.cs:
+ * libsteticui/PluggableWidget.cs:
+ * libsteticui/WidgetPropertyTree.cs:
+ * libsteticui/ActionGroupDesigner.cs:
+ * libstetic/Registry.cs:
+ * stetic/Stetic.cs:
+ * libsteticui/Application.cs: Fixed process restart workflow, to make
+ the process switch faster.
+
+ * libsteticui/GuiDispatchServerSink.cs:
+ * libsteticui/Component.cs:
+ * libsteticui/ApplicationBackendController.cs:
+ * libsteticui/Project.cs:
+ * libsteticui/ProjectBackend.cs: Misc bug fixes.
+
+ * libstetic/ItemDescriptor.cs: Made it serializable.
+ * libstetic/wrapper/Action.cs (CopyFrom): Clear the signals list before
+ adding the new signals.
+ * stetic/DesignerView.cs: Added getter for the root component.
+
+2006-09-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * stetic/UIManager.cs:
+ * stetic/Stetic.cs: Use the new API.
+
+ * stetic/stetic.glade:
+ * stetic/Configuration.cs:
+ * stetic/LibraryManagerDialog.cs: Implemented dialog for selecting
+ widget libraries.
+
+ * stetic/Makefile.am: Updated.
+
+2006-09-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs:
+ * libsteticui/ApplicationBackend.cs:
+ * libsteticui/WidgetDesignerBackend.cs:
+ * libsteticui/ProjectBackend.cs:
+ * libsteticui/SignalsEditorBackend.cs:
+ * libsteticui/WidgetPropertyTreeBackend.cs:
+ * libsteticui/WidgetEditSession.cs:
+ * libsteticui/Palette.cs:
+ * libsteticui/ComponentSignalEventHandler.cs:
+ * libsteticui/ProjectView.cs:
+ * libsteticui/ComponentEventHandler.cs:
+ * libsteticui/Component.cs:
+ * libsteticui/Application.cs:
+ * libsteticui/EmbedWindow.cs:
+ * libsteticui/PaletteBackend.cs:
+ * libsteticui/SignalsEditor.cs:
+ * libsteticui/ActionGroupComponent.cs:
+ * libsteticui/ApplicationBackendController.cs:
+ * libsteticui/ActionGroupDesignerBackend.cs:
+ * libsteticui/ActionComponent.cs:
+ * libsteticui/WidgetDesigner.cs:
+ * libsteticui/ActionGroupEditSession.cs:
+ * libsteticui/ComponentType.cs:
+ * libsteticui/Project.cs:
+ * libsteticui/WidgetComponent.cs:
+ * libsteticui/PluggableWidget.cs:
+ * libsteticui/WidgetPropertyTree.cs:
+ * libsteticui/ProjectViewBackend.cs:
+ * libstetic/IResourceProvider.cs:
+ Redesigned the API so it allows running the designer in a separate
+ process. This running mode is optional and not enabled by default
+ until all stability problems have been fixed.
+
+ * libsteticui/NoGuiDispatchAttribute.cs:
+ * libsteticui/GuiDispatchServerSinkProvider.cs:
+ * libsteticui/GuiDispatchServerSink.cs: A channel sink which ensures that
+ all incoming calls al dispatched in the GUI thread.
+
+ * libsteticui/ActionGroupToolbar.cs:
+ * libsteticui/WidgetActionBar.cs: Added the Bind to Field button
+ (moved from MD).
+
+ * libsteticui/CodeGenerator.cs: Added optional Gettext support.
+
+ * libsteticui/WidgetTreeCombo.cs:
+ * libsteticui/Clipboard.cs:
+ * libsteticui/Glade.cs:
+ * libsteticui/PropertyGrid.cs:
+ * libsteticui/UserInterface.cs:
+ * libsteticui/WidgetFactory.cs: Make classes internal.
+
+ * libsteticui/Makefile.am: Updated.
+
+2006-09-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/IProject.cs: Removed unused method.
+ * libstetic/ItemDescriptor.cs: Made some fields not serializable.
+ * libstetic/ObjectWrapper.cs: Allow binding a wrapper to a remote
+ frontend running in another process.
+
+ * libstetic/Registry.cs:
+ * libstetic/WidgetLibrary.cs: Implemented better support for library
+ reloading.
+
+ * libstetic/wrapper/Container.cs:
+ * libstetic/wrapper/Widget.cs:
+ * libstetic/wrapper/Action.cs: Track api changes, added some null checks.
+
+ * libstetic/wrapper/Signal.cs:
+ * libstetic/SignalDescriptor.cs:
+ * libstetic/TypedSignalDescriptor.cs:
+ * libstetic/wrapper/SignalCollection.cs: Made it serializable.
+
+ * libstetic/wrapper/ActionGroup.cs: Made it sealed. Added some helper
+ methods.
+ * libstetic/wrapper/objects.xml: Action properties are translatable.
+ * libstetic/editor/ThemedIcon.cs, ImageSelector.cs: Don't use
+ stock_symbol-selection stock
+ icon since it is not available in all themes.
+ * libstetic/editor/Identifier.cs: Fix warning.
+ * libstetic/TypedPropertyDescriptor.cs: Improved error reporting.
+ * libstetic/GeneratorContext.cs: Added support for Gettext.
+
+2006-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Container.cs: When changing the selected item,
+ disable the focus event for the correct widget. Fixes bug #79247.
+
+ * libstetic/editor/ThemedIcon.cs:
+ * libstetic/editor/ImageSelector.cs: Use "..." as label for the selector
+ button since the icon stock_symbol-selection is not present in some
+ themes.
+
+2006-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Project.cs: Avoid the normal widget clearing callback
+ when closing a project. It may avoid a crash seen by some users
+ but which is hard to reproduce. Initialize the icon factory
+ when closing the project.
+ * libstetic/CommandDescriptor.cs: Added null check.
+ * libstetic/wrapper/Widget.cs: Clear the selection if the selected
+ widget is destroyed.
+ * libstetic/wrapper/WidgetEventHandler.cs: Set the wrapper property
+ in the args constructor.
+ * libstetic/wrapper/Viewport.cs: Wrapper properties can't be initialized
+ in the constructor.
+ * libstetic/wrapper/objects.xml: Set the default value for Visible to
+ 'true' (in gtk, the default is false, but for stetic it is true).
+ * libstetic/editor/ActionMenuItem.cs: Added null check.
+ * libstetic/editor/SelectImageDialog.cs: Don't allow addin/removing
+ resources if there is no resource manager.
+
+2006-08-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs: Use Dispose instead of destroy
+ since it was generating some warnings.
+ * libsteticui/WidgetDesigner.cs: Dispose is enough.
+ * libsteticui/Project.cs: Don't add unselectable widgets to the tree.
+ Moved here some selection code from Widget.cs.
+ * libstetic/ItemGroup.cs: Make sure properties are returned in the
+ same order they are declared in objects.xml.
+ * libstetic/ObjectWrapper.cs: Don't nullify proj and signals on dispose,
+ it is causing some nullrefs.
+ * libstetic/wrapper/Container.cs: Changed a bit how selection works.
+ Everything is now controled by the project.
+ * libstetic/wrapper/Widget.cs: Make sure clicks for unselectable widgets
+ are intercepted.
+ * libstetic/wrapper/Notebook.cs: Track api changes.
+ * libstetic/wrapper/Table.cs: Destroy widgets removed from the table.
+ * libstetic/editor/ActionGroupEditor.cs: Implemented public Cut, Copy,
+ Paste and Delete methods.
+ * stetic/Stetic.cs:
+ * libstetic/TypedPropertyDescriptor.cs: Improved some error messages.
+
+2006-08-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupDesigner.cs:
+ * libsteticui/ActionGroupToolbar.cs:
+ * libsteticui/Palette.cs:
+ * libsteticui/WidgetDesigner.cs:
+ * libsteticui/Project.cs:
+ * libsteticui/WidgetActionBar.cs:
+ * libstetic/ObjectWrapper.cs:
+ * libstetic/editor/ActionMenuBar.cs:
+ * libstetic/editor/ActionMenu.cs:
+ * libstetic/editor/ActionGroupEditor.cs:
+ * stetic/Stetic.cs: Explicitely destroy custom widgets to avoid memory
+ leaks.
+
+2006-08-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/WidgetEventHandler.cs: Added WidgetWrapper property.
+
+ * libsteticui/PropertyGrid.cs:
+ * libsteticui/Palette.cs:
+ * libsteticui/ProjectView.cs:
+ * libsteticui/WidgetActionBar.cs:
+ * libsteticui/SignalsEditor.cs:
+ * stetic/Stetic.cs:
+ * stetic/UIManager.cs:
+ * libsteticui/WidgetPropertyTree.cs: Track changes in WidgetEventHandler.
+
+ * libsteticui/Project.cs: Factorized cleanup methods into Close().
+ Properly dispose actions.
+ * libstetic/wrapper/Action.cs: Properly read the action id.
+ * libstetic/wrapper/Container.cs: Disconnect container events when
+ disposing. Sync the table after reading it.
+ * libstetic/wrapper/Widget.cs: Properly track unwrapped children
+ and intercept clicks for them.
+ * libstetic/wrapper/Box.cs: Don't create drop faults if the widget is
+ not selectable.
+ * libstetic/wrapper/ActionGroup.cs: Implemented IDisposable.
+ * libstetic/wrapper/ButtonBox.cs: Destroy buttons being removed (this will
+ dispose the wrapper).
+ * libstetic/wrapper/objects.xml: Inherit IsTextCombo property.
+ * libstetic/editor/ActionMenuBar.cs: Show an "Empty" message when the widget
+ is not selected.
+ * libstetic/editor/StockIconSelectorItem.cs: Removed gnome stock icons since
+ they need some special initialization code. Still available in the stock
+ icon selection box.
+ * libstetic/editor/ActionToolItem.cs: Propagate to menu popup the key used
+ to show the menu.
+ * libstetic/PropertyDescriptor.cs: Store translation info in the object wrapper,
+ instead of a global hashtable. This avoids keeping a reference to the object
+ forever in the translation info hashtable.
+
+ * libstetic/wrapper/TextView.cs:
+ * libstetic/wrapper/Window.cs:
+ * libstetic/wrapper/Scale.cs:
+ * libstetic/wrapper/Range.cs:
+ * libstetic/wrapper/Dialog.cs:
+ * libstetic/wrapper/Toolbar.cs: Unsubscribe events on dispose.
+
+ * libstetic/editor/SelectIconDialog.cs:
+ * libstetic/stetic.glade: Added warning to stock selection icon, shown when
+ the selected icon needs special icon factories.
+
+2006-08-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupToolbar.cs: Fix exception.
+ * libsteticui/CodeGenerator.cs: Use CodeArgumentReferenceExpression
+ instead of CodeVariableReferenceExpression to reference parameters.
+ * libsteticui/WidgetDesigner.cs: Update the widget design size when
+ it changes.
+ * libstetic/ObjectWrapper.cs: Added setter for Loading.
+ * libstetic/wrapper/Container.cs: Don't fire ChildRemoved event
+ when loading.
+ * libstetic/wrapper/ActionGroup.cs: Added Remove method.
+
+ * libstetic/wrapper/ActionTree.cs:
+ * libstetic/wrapper/ActionToolbarWrapper.cs:
+ * libstetic/wrapper/MenuBar.cs: Don't fire change events when
+ creating the menu and toolbar.
+
+ * libstetic/wrapper/Widget.cs:
+ * libstetic/wrapper/Bin.cs: Implemented support for UIManagers
+ in custom widgets.
+
+ * libstetic/editor/Accelerator.cs: Fire change event when the
+ accelerator is set.
+ * stetic/UIManager.cs: Some UI improvements.
+
+2006-08-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/PropertyEditor.cs: Made the class internal.
+ * libsteticui/UserInterface.cs: Added new overload for
+ CreateActionGroupDesigner.
+ * stetic/Stetic.cs: Close the project before opening a new one.
+ * stetic/UIManager.cs: Fixed bug when opening recent files.
+ * libsteticui/ActionGroupDesigner.cs: New file.
+ * libsteticui/Project.cs: Set the modified flag when a widget
+ is added or removed from the project.
+ * stetic/Stetic.cs: Moved page creation code to DesignerView.cs.
+ * DesignerView.cs: New file.
+
+ * libstetic/wrapper/Custom.cs:
+ * libstetic/CustomWidget.cs: Make public again, since it is
+ being used by the MD addin.
+
+ * libsteticui/Makefile.am: Updated.
+
+2006-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/*:
+ * libstetic/*
+ * stetic/*: Added Catalog.GetString to all translatable strings.
+
+2006-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * stetic/Stetic.cs: If a file name is specified when starting
+ Stetic, load it. Warn the user when closing an unsaved project.
+ Implemented Close command. Read and save the main window position.
+ * stetic/stetic.glade: Added an status bar.
+ * stetic/UIManager.cs: Implemented "Recent Files" submenu.
+
+ * stetic/RecentFiles.cs:
+ * stetic/Configuration.cs: New files.
+
+ * stetic/Makefile.am: Updated.
+
+2006-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Shadow.cs:
+ * libsteticui/EmbedWindow.cs:
+ * libsteticui/Metacity: Moved from libstetic.
+
+ * libsteticui/WidgetFactory.cs: Don't allow dragging window
+ items.
+ * libsteticui/Glade.cs: Removed unused BeginGladeImport method.
+ * libsteticui/CodeGenerator.cs: Use GenerateCreationCode instead
+ of GenerateBuildCode to generate the code for the root window,
+ since it includes initialization code for properties which are
+ usually provided as constructor parameters.
+ * libsteticui/WidgetTreeCombo.cs: Fix warning.
+ * libsteticui/Project.cs: Added Close method. Removed some unused
+ code.
+ * libsteticui/PropertyTree.cs: Made CellRendererPropertyGroup internal.
+
+ * libsteticui/UserInterface.cs: Added method overload.
+ CreateActionGroupDesigner now creates the toolbar.
+
+ * libsteticui/ContextMenu.cs:
+ * libsteticui/Grid.cs: Made the class internal.
+
+ * libsteticui/WidgetDesigner.cs: Moved from libstetic. Renamed from
+ PreviewBox to WidgetDesigner.
+
+ * libsteticui/WidgetPropertyTree.cs:
+ * libsteticui/SignalsEditor.cs: Track api changes.
+
+ * libsteticui/Makefile.am: Updated.
+
+2006-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/CustomWidget.cs:
+ * libstetic/wrapper/Custom.cs: Made the class internal.
+
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/ButtonBox.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/HandleWindow.cs:
+ * libstetic/editor/Translatable.cs: Track api changes.
+
+ * libstetic/PreviewBox.cs:
+ * libstetic/EmbedWindow.cs:
+ * libstetic/Shadow.cs:
+ * libstetic/Metacity: Moved to libsteticui.
+
+ * libstetic/IDesignArea.cs: Moved here a delegate previously declared
+ in PreviewBox.
+ * libstetic/IProject.cs: Removed unused event.
+ * libstetic/ObjectWrapper.cs: Added public methods for attaching/detaching
+ designers.
+ * libstetic/wrapper/Container.cs: Removed unused code.
+ * libstetic/editor/TextBox.cs: Moved to Editors directory.
+ * libstetic/PropertyDescriptor.cs: Made TranslationInfo internal.
+ * libstetic/GeneratorContext.cs: Added initialization code for
+ top level widgets.
+
+ * libstetic/wrapper/ActionToolbarWrapper.cs:
+ * libstetic/wrapper/objects.xml: Support specifying a "Default" style for
+ the toolbar, which will cause the toolbar to take the style from the
+ gnome preferences.
+
+ * libstetic/Makefile.am: Updated.
+
+2006-08-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/DateTimeEditor.cs:
+ * libstetic/editor/TimeSpanEditor.cs:
+ * libstetic/PropertyEditorCell.cs:
+ * libstetic/Makefile.am: Added editors for DateTime and TimeSpan.
+
+2006-08-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetTreeCombo.cs: Don't show unselectable
+ widgets in the combo.
+
+ * libstetic/IProject.cs:
+ * libsteticui/Project.cs: Removed tooltips property. They are
+ now handlerd in a different way.
+
+ * libstetic/ObjectWrapper.cs:
+ * libstetic/wrapper/Container.cs:
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/Button.cs: Fixed some issues when reading
+ and writing buttons.
+
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/MenuItem.cs:
+ * libstetic/wrapper/OptionMenu.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/CheckButton.cs:
+ * libstetic/wrapper/Object.cs: Track api changes.
+
+ * libstetic/wrapper/objects.xml: Added initialization property
+ for windows. Use Entry.IsEditable instead of Editable, which is
+ obsolete.
+
+ * libstetic/editor/Flags.cs: Fix warnings.
+ * libstetic/wrapper/Widget.cs: Generate code for displaying
+ tooltips.
+
+ * libstetic/GeneratorContext.cs:
+ * libstetic/PropertyDescriptor.cs: Support code generation of
+ DateTime and TimeSpan.
+
+ * libstetic/DND.cs: Fixed several issues with insert bars in
+ boxes.
+
+ * libstetic/Makefile.am: Updated.
+
+2006-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ItemGroup.cs: Use a hashtable to store the items.
+
+ * libstetic/wrapper/Button.cs:
+ * libstetic/wrapper/Object.cs:
+ * libstetic/wrapper/Table.cs:
+ * libstetic/ObjectWrapper.cs: Avoid firing events while the objects
+ are loading.
+
+ * libstetic/wrapper/Container.cs: Don't validate names while the object
+ is being loaded.
+ * libstetic/ItemGroupCollection.cs: Added helper method for getting
+ an item.
+
+ * libstetic/WidgetUtils.cs: Avoid using SelectSingleNode since it's very
+ slow. Use the ChildNodes property instead. Merged ReadProperties and
+ ReadSignals in a single ReadMembers method, which is more efficient.
+
+2006-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Clipboard.cs: When copying a widget, store it as
+ xml, so if the widget is deleted the clipboard will still
+ have the data. Fixes bug #78938.
+
+ * libstetic/PreviewBox.cs:
+ * libstetic/EmbedWindow.cs: Avoid a crash when metacity is not
+ installed. Fixes bug #78916.
+
+ * libstetic/wrapper/Container.cs: Properly read internal children
+ when using Glade format.
+ * libstetic/wrapper/RadioButton.cs: Fix read code for radio buttons.
+ Fixes bug #78909.
+
+ * libstetic/wrapper/Dialog.cs:
+ * libstetic/wrapper/ButtonBox.cs: Added special code generation case
+ when the button box is the action area of a dialog. In this case
+ widgets are added using dialog.AddActionWidget(). Fixes bug #78956.
+
+ * libstetic/editor/Accelerator.cs: Capture the key combination using
+ a modal dialog, to avoid messing with the container accelerators.
+ Fixes bug #78867.
+
+2006-07-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/EnumDescriptor.cs: Don't throw an exception if the
+ CLR enum has more members than the enum declared in objects.xml.
+ A new backward compatible version of a library may introduce new
+ members which Stetic is unaware of.
+
+2006-07-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Table.cs: Don't try to automatically set
+ the horizontal expansion property of widgets which expand
+ more than one column, since we may have a different expand
+ value for each column, and changing it for every column may
+ end up in an infinite loop when syncing the table. The
+ same for rows and vertical expansion.
+
+2006-07-21 Alp Toker <alp@atoker.com>
+
+ * libsteticui/CodeGenerator.cs:
+ * libsteticui/PropertyTree.cs:
+ * libstetic/TypedPropertyDescriptor.cs:
+ * libstetic/WidgetUtils.cs: Trivial comment typofixes.
+
+2006-07-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetActionBar.cs: Assign the label of the command
+ to the button.
+ * libstetic/PreviewBox.cs: Added property for getting the current
+ selection.
+ * libstetic/wrapper/Action.cs: Use IconSet.RenderIcon to render
+ action icons.
+
+ * libstetic/wrapper/Image.cs:
+ * libstetic/wrapper/Label.cs: Changed base wrapper to Misc.
+
+ * libstetic/wrapper/objects.xml: Use the new identifier editor
+ for the widget name. Added alignment commands for Label and
+ for table child.
+ * libstetic/wrapper/Table.cs: Implemented Fill/Expand commands.
+ * libstetic/editor/ImageSelector.cs: Use a default size of 16
+ for thumbnail icons.
+ * libstetic/editor/StockItem.cs: Render icons using the icon set,
+ not the theme.
+ * libstetic/WidgetUtils.cs: In ParseWidgetName, limit numeric suffix
+ to 4 digits.
+ * libstetic/Makefile.am: Added Identifier.cs and Misc.cs.
+ * libstetic/TypedClassDescriptor.cs: If a wrapper is inherited
+ from a base class, ignore the CreateInstance method since it
+ is going to create an instance of the base class.
+
+
+2006-06-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ItemDescriptor.cs: Properly invoke method based checks
+ for item descriptors.
+ * libstetic/wrapper/Action.cs: Copy signals when cloning actions.
+ * libstetic/ErrorWidget.cs: Improve error message when generating code.
+
+ * libstetic/GeneratorContext.cs:
+ * libstetic/PropertyDescriptor.cs: Add support for string arrays.
+
+ * libstetic/wrapper/objects.xml:
+ * libstetic/wrapper/ComboBox.cs: Added property which when set generates
+ a text based combobox.
+
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/RadioGroupManager.cs: Fix bug when accessing to widget
+ variable names. Patch by Jasiu.
+
+2006-06-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/PropertyTree.cs: Don't show empty item groups.
+ * libsteticui/WidgetActionBar.cs: Call the virtual AddWidgetCommands
+ only once per widget.
+ * libstetic/editor/ActionToolbar.cs: Remove debug code.
+ * libstetic/wrapper/Widget.cs: When deleting a widget unselect it if
+ it is the current selection. Fixes bugs #78620 and 78622.
+ * libstetic/wrapper/ColorButton.cs: Don't generate the Alpha property
+ if the value is -1 (not set).
+
+ * libstetic/wrapper/objects.xml:
+ * libstetic/wrapper/pixmaps/expander.png: Added icon for the expander
+ widget by ml.
+
+
+2006-06-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/CommandDescriptor.cs:
+ * libsteticui/WidgetActionBar.cs: Add support for icon based
+ commands and for toogle commands.
+
+ * libstetic/ItemDescriptor.cs: invisible-if and disable-if elements
+ now support calling a method to get the check value.
+ * libstetic/WidgetLibrary.cs: Assign the widget library to
+ class descriptors.
+ * libstetic/wrapper/Container.cs: Implemented IncBorder and DecBorder
+ commands.
+ * libstetic/wrapper/Box.cs: Implemented BoxExpand and BoxFill toggle
+ commands.
+ * libstetic/wrapper/objects.xml: Added IncBorder and DecBorder commands
+ to containers. Added BoxExpand and BoxFill to box child.
+ * libstetic/editor/Accelerator.cs: Fixed. Added button for clearing
+ the accelerator.
+
+ * libstetic/editor/ActionToolbar.cs:
+ * libstetic/editor/ActionMenuBar.cs: Make sure the menu has some height
+ when there are no items, so it can be easily selected.
+
+ * libstetic/editor/ActionToolItem.cs: Don't allow editing separators.
+ * libstetic/PropertyEditorCell.cs: Paint text, not markup.
+ * libstetic/ClassDescriptor.cs: Added property which returns the widget
+ library that implements the class descriptor.
+ * libstetic/AssemblyWidgetLibrary.cs: Implemented GetResource method.
+
+2006-06-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Box.cs: In GladeChildren return children
+ based on the order of their positions. Fixes bug #78160.
+
+2006-05-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Palette.cs: Don't show the toolitems section,
+ since it's not being used right now. Show a default icon
+ for actions which don't have an icon.
+ * libsteticui/PropertyTree.cs: If the property tree only
+ has one group, allways expand it.
+ * libsteticui/Makefile.am: Added resource.
+ * libsteticui/WidgetPropertyTree.cs: There is no need to delay
+ the tree filling when the selection is null.
+ * libstetic/PreviewBox.cs: Minor fixes.
+ * libstetic/ImageInfo.cs: Added some image scaling methods.
+ * libstetic/ProjectIconFactory.cs: Added RenderIcon method.
+ * libstetic/wrapper/Action.cs: Added Accelerator property.
+ Other minor fixes.
+ * libstetic/wrapper/Widget.cs: Notify changes in the local
+ action groups. Register the accel group of the generated
+ UIManager.
+ * libstetic/wrapper/objects.xml: Disabled the old toolbar
+ model. Use the action based toolbar instead.
+ * libstetic/wrapper/ActionTree.cs: Added Changed event.
+ * libstetic/editor/ActionMenuItem.cs: Use the new icon
+ selection menu.
+ * libstetic/editor/StockItem.cs: Implemented a new editor
+ which uses the new icon selector menu.
+ * libstetic/PropertyDescriptor.cs: Added support for
+ specifying a default value for a property in the xml file.
+ * libstetic/Makefile.am: Updated.
+
+ * wrapper/ActionToolbarWrapper.cs:
+ * editor/ActionToolbar.cs:
+ * editor/ActionToolItem.cs: New toolbar designer.
+
+ * editor/IconSelectorItem.cs:
+ * editor/IconSelectorMenu.cs:
+ * editor/IconSelectorMenuItem.cs:
+ * editor/ProjectIconSelectorItem.cs:
+ * editor/StockIconSelectorItem.cs: New menu for selecting icons.
+
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/editor/ActionMenu.cs:
+ * libstetic/editor/ActionGroupEditor.cs:
+ * libstetic/editor/ActionMenuBar.cs:
+ * libstetic/wrapper/ActionGroup.cs: Several fixes.
+
+ * stetic/stetic.glade:
+ * stetic/UIManager.cs:
+ * stetic/Stetic.cs: Added a toolbar to the UI.
+
+
+2006-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetFactory.cs: Highlight the item on mouse over.
+ * libsteticui/ActionGroupToolbar.cs: Implemente a single group
+ mode, to be used when editing global action groups.
+ * libsteticui/CodeGenerator.cs: Generate code for actions and
+ icon factories.
+ * libsteticui/Palette.cs: Adjusted some margins. Update actions
+ when they change.
+ * libsteticui/ProjectView.cs: Clean the tree when no project
+ is selected.
+ * libsteticui/Makefile.am: Added UserInterface.cs.
+ * libsteticui/Project.cs: Added IconFactory property.
+ * libsteticui/SignalsEditor.cs: Added missing null check.
+ * libstetic/Metacity/ButtonLayout.cs:
+ * libsteticui/WidgetPropertyTree.cs: Minor fix.
+
+ * libstetic/IProject.cs: Added Modified and IconFactory properties.
+ * libstetic/PreviewBox.cs: Implemented UpdateObjectViewers.
+ * libstetic/stetic.glade: Added icon selector and icon factory editor.
+ * libstetic/RadioGroupManager.cs:
+
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/wrapper/ActionTree.cs:
+ * libstetic/wrapper/ActionGroup.cs:
+ * libstetic/wrapper/Action.cs: Implemented code generation. Avoid name
+ duplication inside action groups.
+ * libstetic/wrapper/Container.cs: Moved method ParseWidgetName into
+ WidgetUtils.
+ * libstetic/wrapper/Widget.cs: Added some methods for supporting code
+ action generation.
+ * libstetic/wrapper/ActionGroup.cs: Added memberName property.
+
+ * libstetic/editor/ImageSelector.cs:
+ * libstetic/editor/StockItem.cs:
+ * libstetic/GladeUtils.cs:
+ * libstetic/editor/TextEditorDialog.cs: Fix warning.
+
+ * libstetic/editor/ThemedIconList.cs: Factorized some code into the
+ new base class IconList.
+ * libstetic/editor/ActionMenuItem.cs: Added context menu. Added support
+ for separators. Use the new icon selector for selecting action items.
+ * libstetic/editor/SelectImageDialog.cs: Improved disabling of OK button when
+ nothing is selected.
+
+ * libstetic/editor/ActionGroupEditor.cs:
+ * libstetic/editor/ActionMenu.cs:
+ * libstetic/editor/ActionMenuBar.cs: Implemented some context menu commands.
+
+ * libstetic/GeneratorContext.cs: Support generating code for ActionGroups.
+ Make WidgetMap work for non-widget objects (e.g. Action).
+ * libstetic/WidgetUtils.cs: Moved from Container.cs.
+
+ * libstetic/Makefile.am: Updated. Added Mono.Unix reference.
+
+ * libstetic/editor/IconList.cs: Base class for two-column icon lists.
+ * libstetic/ProjectIconFactory.cs: Holds information about icons defined
+ in a project.
+ * libstetic/editor/ProjectIconList.cs: IconList subclass that shows
+ icons from a project icon factory.
+ * libstetic/editor/EditIconDialog.cs: Dialog for editing icons.
+ * libstetic/editor/StockIconList.cs: IconList subclass that shows
+ stock icons only.
+ * libstetic/editor/EditIconFactoryDialog.cs: Dialog for editing an
+ icon factory.
+ * libstetic/editor/SelectIconDialog.cs: Dialog for selecting an icon.
+
+ * libstetic/editor/TreeViewCellContainer.cs: Bridge widget to be used for
+ cell rederers with custom editors.
+ * libstetic/editor/CellRendererComboBox.cs: A combo cell renderer.
+
+ * stetic/Stetic.cs: Make sure Gtk is properly initialized before trying
+ to generate code.
+ * stetic/UIManager.cs: Added EditProjectIcons command.
+
+
+2006-05-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/ActionGroupToolbar.cs: Initialize the action group
+ editor after binding it.
+ * libstetic/PreviewBox.cs: Call OnDesignerAttach when attaching
+ a widget for editing.
+ * libstetic/wrapper/Widget.cs:
+ * libstetic/ObjectWrapper.cs: Moved basic code generation methods
+ here from Widget.cs, since generic objects may also need to
+ support it (for example, Gtk.Action).
+ Added OnDesignerAttach, which is called when a widget is attached
+ to a designer.
+ * libstetic/wrapper/Container.cs: Implement OnDesignerAttach.
+ * libstetic/wrapper/Action.cs: Implemented CopyTo in ActionCollection.
+ * libstetic/wrapper/Box.cs: Use Add insted of PackStart to add a widget
+ from drag-drop. Looks like PackStart does not fire the ChildAdded
+ event?
+ * libstetic/editor/ActionMenuItem.cs: Grab the keyboard focus after editing
+ is done.
+ * libstetic/editor/ActionMenuBar.cs: Show a dummy menu item when none is
+ defined, so the menubar has a proper height. Unselec any selected
+ item when the bar is unselected. Allow dropping actions from the
+ palette.
+ * libstetic/editor/ActionGroupEditor.cs: Sort action alphabetically.
+ * libstetic/editor/ActionMenu.cs: Destroy menu items when the menu
+ is disposed.
+ * libstetic/GeneratorContext.cs: In GenerateCreationCode, added the variable
+ for the new object to the statements collections after calling
+ GenerateObjectCreation, so statements needed for the object creation
+ are added before the declaration.
+ * libstetic/TypedClassDescriptor.cs: Lazily initialize the missingIcon
+ static variable.
+ * stetic/Stetic.cs: Show stetic help before standard gnome app help.
+
+ * libstetic/wrapper/ActionTree.cs:
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/wrapper/ActionGroup.cs: Added code generation support.
+
+ * libstetic/wrapper/HScale.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/ToolButton.cs:
+ * libstetic/wrapper/VScrollbar.cs:
+ * libstetic/wrapper/ComboBoxEntry.cs:
+ * libstetic/wrapper/ComboBox.cs:
+ * libstetic/wrapper/HScrollbar.cs:
+ * libstetic/wrapper/VScale.cs: Renamed GenerateWidgetCreation to
+ a more generic GenerateObjectCreation.
+
+ * libstetic/wrapper/objects.xml: Defined some initialization properties.
+
+2006-05-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/ActionMenuItem.cs:
+ * libstetic/wrapper/ActionMenu.cs: Moved to /editor
+ * libstetic/Makefile.am: Updated.
+
+2006-05-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Palette.cs: Show all action groups inside
+ an "Actions" section.
+ * libsteticui/Makefile.am: Updated.
+ * libsteticui/ActionGroupToolbar.cs: Toolbar for the ActionGroup
+ designer.
+ * libsteticui/Project.cs: Forwards events fired when changing action
+ signals.
+ * libsteticui/SignalsEditor.cs: Include the action name in generated
+ handlers.
+
+ * libstetic/IDesignArea.cs: Added some methods for getting the
+ current selection.
+ * libstetic/PreviewBox.cs: Implemented the new IDesignArea methods.
+ * libstetic/wrapper/Action.cs: Implemented clone and copy methods.
+ * libstetic/wrapper/ActionMenuItem.cs: Many fixes.
+ * libstetic/wrapper/Widget.cs: Allow more than one local action group.
+ Forward signal change events from the action groups.
+ * libstetic/wrapper/ActionGroup.cs: Added several events.
+ * libstetic/wrapper/ActionMenu.cs: Implemented keyboard support.
+ * libstetic/wrapper/objects.xml: Added name property to gtk.Action.
+ * libstetic/wrapper/MenuBar.cs: Moved ActionMenuBar to its own file.
+ * libstetic/WidgetUtils.cs: Added common GetDesignArea method.
+ * libstetic/Makefile.am: Updated.
+ * libstetic/editor/ActionGroupEditor.cs: Implemented an editor for
+ action groups.
+
+ * stetic/Stetic.cs: Added some support for the new action group editor.
+
+2006-05-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml: Ignore the default for the
+ Position property of BoxChild. The position always needs to
+ be set, even if it's 0. Fixes bug #78307.
+
+2006-05-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Palette.cs: Added support for drag&drop between
+ action groups. Temporarily disabled action group support.
+ * libsteticui/Project.cs: Create a global action group by
+ default.
+ * libstetic/IDesignArea.cs: Added MoveWidget method.
+ * libstetic/IProject.cs: Added ActionGroups property.
+ * libstetic/PreviewBox.cs: Update the preview window title when
+ the wrapped window title changes. Implemented IDesignArea.MoveWidget.
+ * libstetic/ObjectWrapper.cs: For Gtk.Container.ContainerChild objects,
+ store the object in the wrapper hashtable using a special container
+ objects which properly implements the GetHashCode and Equals methods.
+ This is needed since every call to the Gtk.Container indexer returns
+ a new instance of the container child.
+ * libstetic/wrapper/Action.cs: Implemented Read/Write methods. Added
+ some missing events. Improved ActionCollection.
+ * libstetic/wrapper/Container.cs: Fixed some issues with name conflict
+ checking. Checks can't be done in the ParentSet event, since when
+ it is fired the child is not yet shown as a child of the container.
+ Properly dispose container child wrappers.
+ * libstetic/wrapper/Widget.cs: Same as before. Implemented read/write
+ support for action groups, but it is disabled for now.
+ * libstetic/wrapper/Box.cs: In the ChildContentsChanged method, avoid
+ setting Expand and Fill properties if the values don't change.
+ This avoids firing some unneeded change events.
+ * libstetic/wrapper/ActionGroup.cs: Implemented.
+ * libstetic/wrapper/objects.xml: Added some 'min' values to properties.
+ * libstetic/wrapper/ActionTree.cs: Implemented read/write methods. Added
+ some events.
+ * libstetic/WidgetUtils.cs: Added support for reading/writing properties
+ of arbitrary objects, not only widgets.
+
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/wrapper/ActionMenu.cs:
+ * libstetic/wrapper/ActionMenuItem.cs: Support editing of menu items in
+ a menu bar. Bug fixes and improvements.
+
+2006-04-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetFactory.cs: Added PaletteItemFactory class,
+ as a base class for palette factories. Added InstanceWidgetFactory,
+ to support Action palette items.
+
+ * libsteticui/SignalsEditor.cs:
+ * libsteticui/CodeGenerator.cs: Track api changes in signal handling.
+
+ * libsteticui/Palette.cs: Add action groups to the palette.
+ * libsteticui/PropertyTree.cs: After editing a property,
+ notify the change to the wrapper.
+
+ * libsteticui/Project.cs: Added action group collection.
+ Track api changes in signal handling.
+ * libsteticui/WidgetPropertyTree.cs: Allow showing properties of any
+ kind of wrapper, not only widgets.
+ * libstetic/PreviewBox.cs: Implemented IDesignArea. Implemented a new
+ way of drawing the widget selection box.
+
+ * libstetic/wrapper/Widget.cs:
+ * libstetic/ObjectWrapper.cs: Moved signal properties and the notify
+ event from Widget to ObjectWrapper.
+
+ * libstetic/wrapper/SignalCollection.cs:
+ * libstetic/wrapper/Signal.cs:
+ * libstetic/wrapper/SignalEventHandler.cs:
+ * libstetic/wrapper/SignalChangedEventHandler.cs:
+ * libstetic/wrapper/Container.cs: Use the new selection box system,
+ based in IDesignArea.
+
+ * libstetic/wrapper/objects.xml: Added Action class.
+
+ * libstetic/DND.cs: Some minor changes to allow dragging widgets which
+ don't have a wrapper.
+
+ * libstetic/Makefile.am: Updated.
+
+ * libstetic/IDesignArea.cs: New class for providing some designer
+ services to widget wrappers.
+ * libstetic/ObjectWrapperEventHandler.cs: New handler for
+ ObjectWrapper events.
+ * libstetic/wrapper/Action.cs: Wrapper for Gtk.Action.
+ * libstetic/wrapper/ActionMenu.cs: Widget for editing a Menu.
+ * libstetic/wrapper/ActionMenuItem.cs: An action menu item editor.
+ * libstetic/wrapper/ActionGroup.cs: Wrapper for Gtk.ActionGruoup.
+ * libstetic/wrapper/ActionTree.cs: An action tree structure (menu or
+ toolbar).
+ * libstetic/wrapper/MenuBar.cs: Wrapper for Gtk.MenuBar.
+
+2006-04-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/PreviewBox.cs: When handling the case of metacity
+ not being installed, don't specifically check for
+ a DllNotFoundException, since the exception may be wrapped
+ in another exception.
+ * libstetic/EmbedWindow.cs: Don't crash if the metacity
+ libs can't be found.
+ * libstetic/wrapper/Table.cs: Fix hang when loading project
+ which contains a table (bug #78167).
+
+2006-04-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/VScale.cs:
+ * libstetic/wrapper/HScrollbar.cs:
+ * libstetic/wrapper/HScale.cs:
+ * libstetic/wrapper/VScrollbar.cs: Generate valid construction
+ expressions.
+
+2006-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/objects.xml:
+ * libstetic/wrapper/Notebook.cs: Disable "Insert Before" and
+ "Delete Page" commands when there are no pages in the notebook.
+ * stetic/Stetic.cs: Fix crash when deleting a widget.
+
+2006-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/wrapper/Widget.cs:
+ * libstetic/wrapper/Container.cs: When adding a widget to a container,
+ make sure the identifiers are not duplicated.
+ * libstetic/wrapper/Frame.cs: Fixed code generation for
+ the label widget.
+ * libstetic/wrapper/Expander.cs: Fix code generation. Fixes bug #78090.
+
+2006-04-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/editor/Boolean.cs: Fix nullref in some themes.
+
+2006-04-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetTreeCombo.cs: Don't show children
+ for widgets which don't allow children.
+ * libsteticui/ProjectView.cs: Allow deleting top level
+ widgets from the project view.
+ * libsteticui/ContextMenu.cs: Don't allow deleting or
+ cutting top level widgets.
+ * libstetic/CustomWidget.cs: Use EventBox as base class.
+ A gdk window is required to make child widgets selectable.
+ * libstetic/wrapper/Container.cs: Minor change in focus
+ handling. Don't allow deleting the only placeholder of a
+ top level container.
+ * libstetic/wrapper/Widget.cs: Avoid handling the FocusIn
+ event fired by an internal Select call.
+ * libstetic/wrapper/objects.xml: Removed some read-only
+ properties.
+ * libstetic/TypedPropertyDescriptor.cs: Provide defaults only
+ for primitive type properties.
+ * stetic/Stetic.cs: When deleting a top level widget, hide the
+ corresponding tab.
+
+2006-03-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/PropertyTree.cs: Changed the way instance
+ information is stored. The value is now stored in
+ the tree store instead of a hashtable.
+ * libstetic/wrapper/Table.cs: Added a flag to avoid
+ recursively notifying changes in properties.
+
+2006-03-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ImageInfo.cs: Don't crash if an icon is not
+ found in the current theme.
+
+2006-03-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/WidgetTreeCombo.cs: A combo that shows the
+ tree of widgets of a window.
+ * libsteticui/WidgetPropertyTree.cs:
+ * libsteticui/PropertyTree.cs: A TreeView based property
+ editor.
+ * libsteticui/WidgetActionBar.cs: A toolbar that shows
+ the tree of widgets on a combo and some commands
+ available for the selected widget.
+ * libsteticui/Project.cs: Replaced the Selected event by
+ SelectionChanged, which uses a standard signature
+ for event handlers.
+ * libsteticui/PropertyGrid.cs:
+ Track changes in the widget selected event.
+ * libsteticui/PropertyEditor.cs: Moved most of code to
+ PropertyEditorCell.
+ * libsteticui/Palette.cs: Show windows before widgets, since
+ windows are the first thing an user is going to create.
+ * libsteticui/ProjectView.cs: Track changes in the widget
+ selected event. Added WidgetActivated event.
+ * libsteticui/SignalsEditor.cs: Make columns resizable.
+ Track changes in the widget selected event.
+
+ * libsteticui/ContextMenu.cs: Show the Delete command for
+ placeholders. Delete placeholders through their container.
+
+ * libsteticui/Makefile.am: Updated.
+
+ * libstetic/PropertyEditorCell.cs: New file. Implements the base
+ class for property editors that need custom rendering.
+ * libstetic/IProject.cs: Added SelectionChanged event.
+ * libstetic/ItemDescriptor.cs: HasDependencies now returns true
+ if there are visibility dependencies, not only sensitivity.
+ * libstetic/stetic.glade: Added text editor dialog.
+
+ * libstetic/wrapper/Button.cs: Added null check.
+ * libstetic/wrapper/Container.cs: When the last placeholder of
+ a container is delete, delete the container.
+ * libstetic/wrapper/Paned.cs: Don't allow deleting placeholders.
+ * libstetic/wrapper/Box.cs: Removed AllowPlaceholders override,
+ now will always return true. Why was this override needed?
+ * libstetic/wrapper/Window.cs: Store the window icon in an ImageInfo
+ instance.
+ * libstetic/wrapper/objects.xml: Fixed some editor references.
+ Removed icons that don't exist. Moved scrollbar and separator
+ widgets to the "widget" palette category.
+ * libstetic/wrapper/Table.cs: Make sure placeholders can only be
+ deleted using the delete row/column commands.
+
+ * libstetic/editor/Color.cs:
+ * libstetic/editor/Boolean.cs:
+ * libstetic/editor/ImageSelector.cs:
+ * libstetic/editor/Enumeration.cs:
+ * libstetic/editor/Flags.cs:
+ * libstetic/editor/StockItem.cs:
+ * libstetic/editor/IntRange.cs:
+ * libstetic/editor/ResponseId.cs: Implemented as a PropertyEditorCell,
+ since it needs custom rendering.
+
+ * libstetic/editor/Text.cs: Implemented as a subclass of TextEditor.
+ * libstetic/editor/Image.cs: Make the editor visible.
+ * libstetic/editor/StringArray.cs: New implementation based on the
+ TextEditor dialog.
+
+ * libstetic/editor/TextEditorDialog.cs:
+ * libstetic/editor/TextEditor.cs: A new editor for strings.
+
+ * libstetic/DND.cs:
+ * libstetic/WidgetUtils.cs: Added some null checks.
+
+ * libstetic/TypedClassDescriptor.cs: Properly handle errors while
+ loading widget icons.
+ * libstetic/Makefile.am: Updated.
+
+ * stetic/stetic.glade:
+ * stetic/UIManager.cs:
+ * stetic/Stetic.cs: Implemented a new interface model. Design windows are
+ now embedded, instead of floating around. Using the new property tree.
+
+2006-03-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CodeGenerator.cs: Moved statements collection into
+ the GeneratorContext class.
+ * libsteticui/PropertyEditor.cs: Register new image editor.
+
+ * libstetic/IProject.cs:
+ * libsteticui/Project.cs: Added property for IResourceProvider.
+
+ * libstetic/ObjectWrapper.cs: Generate an error widget if something
+ fails while loading the project.
+ * libstetic/Registry.cs: In LookupItem, throw an exception if the
+ item can't be found.
+ * libstetic/wrapper/Button.cs: Use the new ImageInfo class for
+ storing the pixbuf.
+ * libstetic/wrapper/Label.cs: Generate specific code for setting
+ the MnemonicWidget property.
+ * libstetic/wrapper/TextView.cs: Don't allow placeholders in a
+ text view. Generate code for setting the text of the buffer.
+
+ * libstetic/wrapper/Widget.cs: The Visible property is the last
+ one to be set, in this way nothing is shown until everything
+ is built.
+ * libstetic/wrapper/Toolbar.cs: Put placeholders inside a ToolItem.
+ * libstetic/wrapper/Image.cs: Simplified the code by using an ImageInfo
+ object for storing the pixbuf.
+
+ * libstetic/wrapper/ComboBox.cs:
+ * libstetic/wrapper/ComboBoxEntry.cs: If some items have been
+ added at design time, generate a text combo box.
+
+ * libstetic/wrapper/RadioToolButton.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/Window.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/RadioMenuItem.cs:
+ * libstetic/wrapper/Bin.cs:
+ * libstetic/wrapper/Container.cs: Moved statements collection into
+ the GeneratorContext class.
+
+ * libstetic/wrapper/objects.xml: Added some min values. Removed the
+ Bin control from the palette. Track changes in Image and Button
+ image properties.
+ * libstetic/wrapper/CheckButton.cs: In the generated code, remove
+ the default label child widget if not needed.
+ * libstetic/wrapper/ToolButton.cs: Simplified the code by using a n
+ ImageInfo object for storing the pixbuf.
+ * libstetic/editor/ThemedIcon.cs: Fixed some compilation problems.
+ Moved ThemedIconList to its own file.
+ * libstetic/PropertyDescriptor.cs: Added support for type converters.
+ * libstetic/TypedPropertyDescriptor.cs: Implemented RuntimePropertyType.
+
+ * libstetic/GeneratorContext.cs: Added the statements collection that
+ will contain all generated code. Added EndGeneration, which
+ runs all post build generation methods.
+ * libstetic/ErrorWidget.cs: Added support for reporting load errors.
+
+ * libstetic/editor/FlagsSelectorDialog.cs:
+ * libstetic/editor/Flags.cs: When there are more than 5 flag values,
+ use a dialog to select them, since the checkbox list takes too
+ much space.
+
+ * libstetic/Makefile.am: Updated.
+
+2006-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/WidgetLibrary.cs: Made Dispose virtual.
+ * libstetic/wrapper/objects.xml: Declared initializer properties.
+ * libstetic/wrapper/Container.cs: Don't generate code for building
+ children if children are not allowed.
+ * libstetic/wrapper/Widget.cs: Support generating code for untyped
+ class descriptors.
+ * libstetic/TypedClassDescriptor.cs: When looking for a static
+ CreateInstance method, look for an overload that takes
+ a ClassDescriptor as parameter.
+ * libstetic/wrapper/Bin.cs: In CreateInstance, return the
+ CustomWidget instance only if the class is a Gtk.Bin.
+ Don't do it for subclasses of Bin.
+
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/RadioMenuItem.cs:
+ * libstetic/wrapper/RadioToolButton.cs: Track api changes.
+
+2006-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/SignalsEditor.cs: Add the name of the widget
+ to the handler name, to avoid collisions when mapping
+ the same event from different widgets.
+ * libstetic/wrapper/Notebook.cs: Added some specific generation
+ code.
+
+2006-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/CodeGenerator.cs: Generated class is not internal.
+ Generate a new Build overload, which takes a type instead of
+ an id as parameter. Other minor fixes.
+ * libsteticui/Palette.cs: Added methods for showing/hiding groups.
+ Added property for setting the widget libraries to show in
+ the palette.
+ * libsteticui/Clipboard.cs: Use the native format to make copies
+ of widgets.
+ * libsteticui/ProjectView.cs: Redraw the tree when widget names
+ change.
+ * libsteticui/Project.cs: Added method for getting a node.
+ * libstetic/PreviewBox.cs: Added some null checks.
+
+ * libstetic/wrapper/RadioToolButton.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/RadioMenuItem.cs:
+ * libstetic/RadioGroupManager.cs: Added support for code generation.
+
+ * libstetic/Registry.cs: Added getter for the core widget library.
+ * libstetic/wrapper/Container.cs: Generate code only for properties
+ available at run time.
+ * libstetic/wrapper/Widget.cs: Same as previous. Also use the wrapped
+ type name specified by the class descriptor, instead of using the
+ real type of the object, since it may be a design-time only object.
+ * libstetic/wrapper/Object.cs: Translate gtk property names to managed
+ names when firing the notify event.
+ * libstetic/wrapper/Custom.cs: Don't use GdkWindow.SetBackPixmap since
+ it seems to fail for some widget sizes.
+ * libstetic/wrapper/objects.xml: Specified a custom wrapper for Bin.
+ Added references to Gtk.Widget properties and signals.
+
+ * libstetic/PropertyDescriptor.cs: Added some methods for handling
+ property values at run-time.
+ * libstetic/TypedPropertyDescriptor.cs: Added support for run-time
+ properties.
+ * libstetic/GeneratorContext.cs: Added CodeNamespace property.
+
+ * libstetic/WidgetUtils.cs: Use XmlElement instead of XmlDocument
+ for exporting/importing widgets (its more generic). Implemented
+ Copy/Paste methods based on native format serialization.
+ Added some BuildWidget methods (which are not used right now).
+
+ * libstetic/ClassDescriptor.cs: Properly initialize the name of the
+ widget.
+ * libstetic/TypedClassDescriptor.cs: Moved name initialization to
+ base class.
+ * libstetic/Makefile.am: Updated.
+
+2006-02-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui/Glade.cs: Use the new api for reading/writing.
+ * libsteticui/Palette.cs: Update the palette when the
+ registry changes.
+ * libsteticui/ProjectView.cs: Update the project tree when
+ the project has been reloaded (due for example to a
+ registry change).
+ * libsteticui/Makefile.am: Updated.
+ * libsteticui/Project.cs: Make it aware of changes in the
+ registry. When the registry changes, reload the project.
+ Added Read/Write and Load/Save methods, based on the
+ native format. Added ProjectReloaded event, which is fired
+ after the project has been reloaded due to a registry change.
+ Other minor changes.
+ * libsteticui/SignalsEditor.cs: Refresh when the project is
+ reloaded. Addded SignalActivated, which is fired when double-
+ clicking an event.
+ * libsteticui/ContextMenu.cs: Get class descriptors from wrappers,
+ instead of looking up in the registry. Track some other api
+ changes.
+ * libsteticui/PropertyGrid.cs: Refresh when the project is
+ reloaded. Track some api changes.
+
+ * libstetic/ParamSpec.cs: Commented out some methods and
+ properties which depend on P/Invoke calls.
+ * libstetic/ItemGroup.cs: Delegate item creation to the
+ owner class.
+ * libstetic/wrapper/Button.cs:
+ * libstetic/wrapper/Container.cs: Replaced glade export/import
+ methods by Read/Write methods. Implemented code generation.
+ * libstetic/wrapper/Widget.cs: Select the widget when it gets
+ the focus. Changed InternalChildId by InternalChildProperty,
+ which has more useful information. Made Visible a wrapper
+ property for all widgets. Replaced glade export/import
+ methods by Read/Write methods. Implemented code generation.
+ * libstetic/wrapper/Window.cs: Implemented code generation.
+ * libstetic/wrapper/ComboBox.cs: Removed unneeded override.
+ * libstetic/wrapper/objects.xml: Added some init-properties
+ and wrapper attributes.
+ * libstetic/wrapper/Table.cs: Fixed bug when setting column
+ count.
+ * libstetic/wrapper/Dialog.cs: Track api changes. Don't throw
+ the buttons changed event while reading from xml.
+
+ * libstetic/wrapper/RadioMenuItem.cs:
+ * libstetic/wrapper/ImageMenuItem.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/MenuItem.cs:
+ * libstetic/wrapper/ButtonBox.cs:
+ * libstetic/wrapper/Box.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/CheckButton.cs:
+ * libstetic/wrapper/ToolButton.cs:
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/OptionMenu.cs:
+ * libstetic/editor/ResponseId.cs:
+ * libstetic/editor/Enumeration.cs:
+ * libstetic/editor/GroupPicker.cs:
+ * libstetic/editor/Flags.cs:
+ * libstetic/ItemDescriptor.cs:
+ * libstetic/wrapper/RadioToolButton.cs: Track api changes.
+
+ * libstetic/SignalDescriptor.cs: Moved all code that depends
+ on Type and Reflection to TypedSignalDescriptor. Added
+ ParameterDescriptor, which replaces ParameterInfo.
+ * libstetic/CommandDescriptor.cs: Made several changes to avoid
+ ClassDescriptor.WrapperType, which has been removed. Instead
+ of getting the method to call from the wrapped type, it gets
+ it from the type of the object when the command is invoked.
+ * libstetic/editor/Char.cs: Fix worng type check.
+ * libstetic/editor/Accelerator.cs: Removed glue P/Invokes.
+ * libstetic/Placeholder.cs: Looks loke GdkWindow.SetBackPixmap
+ doesn't work very well. Draw filled rectangle instead.
+ * libstetic/HandleWindow.cs: If the window is embedded in a
+ preview box, use the gdk window of that box, which has more room
+ for drawing the handles.
+ * libstetic/PropertyDescriptor.cs: Moved all code that depends
+ on Type and Reflection to TypedPropertyDescriptor.
+ Added StringToValue and ValueToString methods for parsing and
+ converting values to string.
+
+ * libstetic/GladeUtils.cs: Track api changes. Removed dependencies
+ to some ParamSpec properties that have been removed. The most
+ complex one to remove is the type of the glade property. Now it
+ is taken from the type of the corresponding class property.
+ * libstetic/EnumDescriptor.cs: Use the registry to lookup the type
+ of the enum. The registry will look in all available libraries.
+ * libstetic/ClassDescriptor.cs: Moved all code that depends
+ on Type and Reflection to TypedClassDescriptor.
+ * libstetic/Makefile.am: Updated.
+ * libstetic/ObjectWrapper.cs: Replaced glade export/import
+ methods by Read/Write methods with support for native format.
+ Added ClassDescriptor property. There is no need to lookup
+ for classes in the registry since it can be accessed most of
+ the time from wrappers.
+ * libstetic/Registry.cs: Added support for external widget
+ libraries.
+
+ * ErrorWidget.cs:
+ * EmbedWindow.cs:
+ * Shadow.cs:
+ * TypedClassDescriptor.cs:
+ * TypedPropertyDescriptor.cs:
+ * TypedSignalDescriptor.cs:
+ * WidgetLibrary.cs:
+ * Metacity/*:
+ * wrapper/Entry.cs:
+ * WidgetUtils.cs:
+ * GeneratorContext.cs:
+ * PreviewBox.cs:
+ * AssemblyWidgetLibrary.cs:
+ * WidgetLibrary.cs: New files.
+
+ * Makefile.am:
+ * configure.in: Removed glue directory from the build.
+
+ * stetic/Stetic.cs: Added support for code generation from
+ the command line.
+ * stetic/stetic.in: Added debug option.
+ * stetic/Makefile.am: Updated.
+ * stetic/Glade.cs: Moved to libsteticui.
+ * stetic/UIManager.cs: Added Load and Save commands.
+
+2006-02-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * stetic.pc.in: Add a reference to the new libsteticui dll.
+ * configure.in, Makefile.am: Add libsteticui dir.
+
+ * stetic/WidgetFactory.cs:
+ * stetic/Grid.cs:
+ * stetic/missing.png:
+ * stetic/PropertyGrid.cs:
+ * stetic/PropertyEditor.cs:
+ * stetic/Palette.cs:
+ * stetic/Clipboard.cs:
+ * stetic/ProjectView.cs:
+ * stetic/Makefile.am:
+ * stetic/Project.cs:
+ * stetic/SignalsEditor.cs:
+ * stetic/ContextMenu.cs:
+ Moved files to libsteticui.
+
+2006-02-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic/ItemGroup.cs: Converted to class. Added support for
+ Signal items.
+
+ * libstetic/wrapper/Container.cs: Added properties for storing
+ the width and height of the container (at design time).
+
+ * libstetic/wrapper/Widget.cs: Added support for signals.
+ Added some new events: NameChanged, WidgetChanged, SignalAdded,
+ SignalRemoved, SignalChanged.
+
+ * libstetic/wrapper/Window.cs: Don't show the window when it's
+ selected. That's something that the hosting application has to
+ decide. The selection change event in Project can be used for this.
+
+ * libstetic/wrapper/objects.xml: Added signals.
+
+ * libstetic/editor/ResponseId.cs:
+ * libstetic/editor/Translatable.cs:
+ * libstetic/editor/Char.cs:
+ * libstetic/editor/Color.cs:
+ * libstetic/editor/ThemedIcon.cs:
+ * libstetic/editor/Boolean.cs:
+ * libstetic/editor/Image.cs:
+ * libstetic/editor/FloatRange.cs:
+ * libstetic/editor/Text.cs:
+ * libstetic/editor/Accelerator.cs:
+ * libstetic/editor/Enumeration.cs:
+ * libstetic/editor/GroupPicker.cs:
+ * libstetic/editor/OptIntRange.cs:
+ * libstetic/editor/Flags.cs:
+ * libstetic/editor/StringArray.cs:
+ * libstetic/editor/String.cs:
+ * libstetic/editor/IntRange.cs:
+ Implement the new IPropertyEditor interface.
+
+ * libstetic/HandleWindow.cs: Use a wider focus rectangle.
+ Get the correct top level window when it's embedded in another window.
+
+ * libstetic/GladeUtils.cs: Added helper methods for exporting and
+ importing widgets. Read/Write signal information.
+
+ * libstetic/ClassDescriptor.cs: Added support for signals.
+
+ * stetic/Makefile.am:
+ * libstetic/Makefile.am: Updated.
+
+ * libstetic/Registry.cs: Added some helper methods for locating
+ groups.
+
+ * Makefile.am:
+ * configure.in: Set version to 0.1.0. Added .pc file.
+
+ * stetic/WidgetFactory.cs: Don't show the window when it's
+ created. The hosting app can do it by subscribing the
+ Project.WidgetAdded event.
+
+ * stetic/Glade.cs: Top level widgets don't need to be windows,
+ they can be containers.
+
+ * stetic/PropertyGrid.cs: Some big changes. This widget is not a Grid
+ anymore, but a VBox of grids. There is a grid for every ItemGroup, and
+ they are reused for all widgets that share the same ItemGroup. The
+ property grid is now much faster.
+
+ * stetic/Stetic.cs: Added the signals editor. Handle some events
+ previously handled in the widget code, but which I moved here to
+ make the code more generic.
+
+ * libstetic/IPropertyEditor.cs: New interface to be implemented
+ by all property editors.
+
+ * stetic/PropertyEditor.cs: Replaced all code that relied on reflection
+ to create and initialize property editors. All this is now done through
+ the new IPropertyEditor interface. Now it is also possible to reuse
+ the same PropertyEditor for different objects that share the same
+ property.
+
+ * stetic/Palette.cs:
+ * stetic/ProjectView.cs: Added support for changing the project to
+ which those widgets are bound.
+
+ * stetic/stetic.glade: Added the signals editor.
+
+ * stetic/Project.cs: Added several events which are needed to
+ integrate Stetic in an IDE.
+
+ * stetic.pc.in: Added.
+
+ * libstetic/SignalDescriptor.cs: New descriptor for signals.
+
+ * libstetic/wrapper/WidgetEventHandler.cs:
+ * libstetic/wrapper/WidgetNameChangedHandler.cs:
+ * libstetic/wrapper/SignalEventHandler.cs:
+ * libstetic/wrapper/SignalChangedEventHandler.cs
+
+ * libstetic/wrapper/SignalCollection.cs:
+ * libstetic/wrapper/Signal.cs: New class. Holds information
+ about signal handlers bound to a widgets.
+
+ * libstetic/ItemGroupCollection.cs: New collection class.
+
+ * stetic/SignalsEditor.cs: The new signals editor.
+
+2005-09-27 Dan Winship <danw@novell.com>
+
+ * libstetic/HandleWindow.cs (HandleEvent): hack around bgo 316871
+ (shaped windows block update events in gtk+ 2.8.0 - 2.8.3).
+
+2005-09-26 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/objects.xml: bring back ThemedIcon images and
+ buttons. Add <itemgroup ref="Gtk.Widget"> to a few classes that
+ were missing it.
+
+ * libstetic/editor/ThemedIcon.cs: Fix to work under Gtk# 2.4
+
+ * libstetic/wrapper/Button.cs: bring back ThemedIcon buttons
+
+ * libstetic/wrapper/Image.cs: bring back ThemedIcon images.
+
+ * libstetic/wrapper/Frame.cs: don't crash when importing a frame
+ with no label widget. If the LabelWidget changes, create a new
+ wrapper for it.
+
+ * libstetic/wrapper/Container.cs (GladeImport): don't crash when
+ importing a placeholder into a !AllowPlacerholders container.
+
+2005-09-26 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Dialog.cs (Buttons): make this a number rather
+ than having an enum of standard button choices; the HIG prefers
+ stronger labels than "OK"/"Yes", so we shouldn't be making it
+ easier to use bad labels than good ones.
+ (HelpButton): reorder the help button to be the first child so
+ that it won't ever get deleted when you decrement Buttons
+ (ButtonsChanged): keep the Buttons and HelpButton properties in
+ sync if the user manipulates the buttonbox contents by hand
+
+ * libstetic/wrapper/Button.cs (StockId): if the button's ReponseId
+ matches its old StockId (or is unset), update it to match it's new
+ StockId.
+ (IsDialogButton): replaces HasResponseId and is now settable
+ rather than being figured out automatically. Also, set
+ button.CanDefault when turning on IsDialogButton.
+ (ResponseIdForStockId): maps Gtk.Stock values to Gtk.ResponseType
+ values.
+
+ * libstetic/wrapper/ButtonBox.cs (NewButton): if the buttonbox is
+ a dialog's action_area, set IsDialogButton on new child buttons.
+ (AllowPlaceholders): false
+ (InsertBefore, InsertAfter): Reimplement using Secondary/non-
+ Secondary rather than PackType.
+ (ButtonBoxChild): add InDialog property
+
+ * libstetic/wrapper/Container.cs (ContextChildProps): for use in
+ context-menu ops; gets the child properties corresponding to the
+ ancestor of the widget that is a child of the container.
+
+ * libstetic/wrapper/Box.cs (AllowPlaceholders): only return false
+ if InternalChildId is unset. (Eg, we definitely want to allow
+ placeholders in a dialog box's internal vbox).
+ (InsertBefore, InsertAfter): use Container.ContextChildProps so
+ that this works regardless of what descendant widget was clicked
+ on.
+
+ * libstetic/wrapper/objects.xml (Gtk.ButtonBox): Change the
+ command labels to "Insert Button Before" and "Insert Button
+ After".
+ (Gtk.ButtonBox+ButtonBoxChild): Remove PackType, since the
+ interaction of PackType and Secondary is unnecessarily annoying.
+ Also add a new internal InDialog property and hide Secondary if
+ that's true (since we handle Help buttons specially and nothing
+ else should be secondary).
+ (Gtk.Button): s/HasResponseId/IsDialogButton/
+ (Gtk.Dialog): change the description of Buttons since it's now a
+ number, and give it a minimum value of "1".
+ (Gtk.ResponseType): add labels/descriptions for this enum
+ (Stetic.Wrapper.Dialog+StandardButtons): and kill this one
+
+ * libstetic/editor/ResponseId.cs: update this to use
+ EnumDescriptor
+
+2005-09-22 Dan Winship <danw@novell.com>
+
+ * libstetic/ClassDescriptor.cs: Handle <contextmenu ref="..." />
+
+ * libstetic/DND.cs (Cancel): fix a crash
+
+ * libstetic/Registry.cs (LookupContextMenu): look up a context
+ menu by class name.
+ (NewInstance): Look up a class and invoke NewInstance on it
+
+ * libstetic/wrapper/ButtonBox.cs: Wrapper for ButtonBox, that
+ automatically fills in dummy buttons as needed.
+
+ * libstetic/wrapper/objects.xml (Gtk.ButtonBox): use the new
+ ButtonBox wrapper. Add a "Size" property and a context menu.
+
+ * libstetic/wrapper/Container.cs (AllowPlaceholders): new virtual
+ property saying whether or not to allow arbitrary placeholders in
+ the container.
+ (Wrap, GladeImport, Delete): Don't add placeholders if
+ !AllowPlaceholders
+ (DragEnd): Remove the dragSource placeholder after a successful
+ drag if !AllowPlaceholders
+
+ * libstetic/wrapper/Box.cs (AllowPlaceholders): false
+ (InsertBefore, InsertAfter): If invoked on the box directly
+ (rather than via the submenu from one of its children), insert
+ before the first / after the last child.
+
+ * libstetic/wrapper/Button.cs: Remove CreateInstance method;
+ default to text-only buttons like Glade does.
+
+ * libstetic/wrapper/Dialog.cs (AddButton): Use
+ Registry.NewInstance.
+
+ * libstetic/wrapper/Notebook.cs (InsertPage): Use
+ Registry.NewInstance
+
+ * stetic/ContextMenu.cs: Fix up for bxc 75689 again, since it was
+ still broken before.
+
+2005-09-20 Dan Winship <danw@novell.com>
+
+ * libstetic/EnumDescriptor.cs: New descriptor class for English
+ (and later localized) enum value names and descriptions.
+
+ * libstetic/Registry.cs (Registry): Create EnumDescriptors before
+ ClassDescriptors.
+ (LookupEnum): return EnumDescriptors.
+
+ * libstetic/PropertyDescriptor.cs: throw an exception if an
+ enum-valued property has no EnumDescriptor in the registry.
+
+ * libstetic/editor/Enumeration.cs: simplify using EnumDescriptor.
+ Also set the combobox's tooltip to the description of the selected
+ enum value.
+
+ * libstetic/editor/Flags.cs: editor for flags values (vbox full of
+ checkbuttons, with tooltips).
+
+ * libstetic/wrapper/Widget.cs (Events): proxy this property, since
+ it can't be changed after the widget is realized.
+
+ * libstetic/wrapper/objects.xml: add <enum> nodes for all enum
+ types we use.
+
+ * stetic/PropertyEditor.cs (PropertyEditor): Use the Flags editor
+ for flags-valued enums
+
+2005-09-16 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Container.cs (ReplaceChild):
+ EmitContentsChanged() at the end, to fix a bug with the
+ Project tree being out of sync.
+
+ * configure.in: bump gtk-sharp dependency back up to 2.3.91. There
+ are too many post-1.9.5 fixes we need.
+
+ * libstetic/DND.cs:
+ * libstetic/HandleWindow.cs:
+ * libstetic/editor/Accelerator.cs:
+ * libstetic/editor/Translatable.cs: Revert 1.9.5 reversions
+
+2005-09-15 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Label.cs: remove the custom ctor
+
+ * libstetic/wrapper/Notebook.cs (InsertPage): use the Gtk.Label
+ ClassDescriptor's NewInstace to create labels, so they end up
+ fully-constructed.
+
+2005-09-14 Dan Winship <danw@novell.com>
+
+ * configure.in: drop gtk# dependency down to 1.9.5
+
+ * libstetic/Makefile.am (libstetic_dll_sources): remove
+ editor/ThemedIcon.cs and wrapper/AboutDialog.cs
+
+ * libstetic/DND.cs:
+ * libstetic/HandleWindow.cs: use gtk# 1.9.5-compatible
+ Gdk.WindowAttr fields
+
+ * libstetic/ItemGroup.cs (ItemGroup): deal with comment nodes in
+ objects.xml
+
+ * libstetic/editor/GroupPicker.cs: comment out use of
+ ComboBox.RowSeparatorFunc.
+
+ * libstetic/editor/Translatable.cs (ButtonPressed): use gtk#
+ 1.9.5-compatible Gtk.Menu.Popup call.
+
+ * libstetic/wrapper/objects.xml: comment out all 2.6 widgets and
+ properties
+
+ * libstetic/wrapper/Image.cs: comment out "themed icon" support
+
+ * libstetic/wrapper/Button.cs: comment out "themed icon" buttons
+ and the use of Button.Image
+
+ * stetic/UIManager.cs: Comment out Gtk.AboutDialog usage, use
+ Gnome.About instead.
+
+ * stetic/Clipboard.cs: Comment out support for plaintext cut+paste.
+
+ * stetic/Stetic.cs: Comment out Gtk.AboutDialog-related stuff.
+
+2005-08-18 Dan Winship <danw@novell.com>
+
+ * libstetic/Tooltips.cs: Hashtable/Gtk.Tooltips mix. (Gtk.Tooltips
+ is write-only, so we can't use it by itself.)
+
+ * libstetic/IProject.cs (Tooltips): new tooltips field
+
+ * stetic/Project.cs (Tooltips): implement
+
+ * libstetic/wrapper/objects.xml (Gtk.Widget): add Tooltip
+ property.
+
+ * libstetic/wrapper/Widget.cs (Tooltip): implement, using
+ proj.Tooltips.
+
+2005-08-17 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/objects.xml (Expander): Remove "Label",
+ "UseMarkup", and "UseUnderline" properties; we'll treat the label
+ as a child widget now, like Glade does. Also fix palette-category
+ to be "container".
+ (Frame): Remove the Label property, as with Expander. Also remove
+ the redundant and deprecated "Shadow" property.
+ (Notebook): Remove some deprecated properties
+
+ * libstetic/wrapper/Expander.cs (Wrap): create an ObjectWrapper
+ for the expander's LabelWidget
+ (ReplaceChild): deal with LabelWidget
+
+ * libstetic/wrapper/Frame.cs: Likewise
+
+ * libstetic/wrapper/Notebook.cs (Wrap): remove the dummy page that
+ will have been added by Container.Wrap.
+ (Select): don't crash if the passed-in wrapper is null
+
+2005-08-04 Dan Winship <danw@novell.com>
+
+ Support cut+paste of widgets, including interprocess cut+paste and
+ drag+drop. (For some reason, it is very slow when going
+ cross-process...)
+
+ * libstetic/GladeUtils.cs (ApplicationXGladeAtom): Gdk.Atom for
+ glade selections.
+ (XslImportTransform, XslExportTransform): do the import/export xsl
+ fixups.
+ (Copy): copy a glade representation of a widget into a
+ Gtk.SelectionData (in the same format that glade uses for its own
+ internal clipboard).
+ (Paste): generate a widget from a glade representation in a
+ Gtk.SelectionData.
+
+ * libstetic/DND.cs (targetList): add application/x-glade to the
+ supported target types.
+ (Drag): connect to the source's DragDataGet signal
+ (Drop): if asked to drop an out-of-proc widget, call
+ Gtk.Drag.GetData and return null.
+ (DragDataGet): Respond by calling GladeUtils.Copy
+ (FaultDragDrop, FaultDragDataReceived): update to be able to deal
+ with receiving an out-of-proc widget
+
+ * libstetic/ObjectWrapper.cs (Project): new public property to get
+ the wrapper's Project
+
+ * libstetic/wrapper/Container.cs (GladeExport): create
+ <placeholder> elements as appropriate.
+ (CreatePlaceholder): connect to DragDataReceived.
+ (PlaceholderDragDataReceived): Paste the received widget data into
+ place.
+ (GladeChildren): return AllChildren, not RealChildren, because we
+ want to include placeholders.
+ (ReplaceChild): make this public
+
+ * libstetic/wrapper/Button.cs (UseUnderline): wrap this; we can't
+ set it directly on the button when we have a special icon set.
+ (GladeImport): Remove a useless special case.
+ (GladeExport): Set the "label" property when the button has a
+ stock id.
+ (GladeChildren): return base.GladeChildren, not base.RealChildren.
+
+ * libstetic/wrapper/ScrolledWindow.cs (GladeChildren): don't need
+ to override any more.
+
+ * libstetic/wrapper/objects.xml (Gtk.Button): add UseStock as an
+ internal property.
+ (Gtk.ColorButton): Remove the "Color" property, since we have no
+ way to serialize it.
+ (Gtk.ColorSelection): Likewise for CurrentColor here.
+
+ * stetic/Clipboard.cs: new static class with some cut/paste helper
+ routines.
+
+ * stetic/ContextMenu.cs (DoCut, DoCopy, DoPaste, DoDelete): update
+ to use Clipboard
+
+ * stetic/Glade.cs: use GladeUtils.XslImportTransform and
+ XslExportTransform.
+
+ * stetic/Project.cs (Selection): don't crash when clearing the
+ selection
+
+ * stetic/UIManager.cs (Cut, Copy, Paste): Implement these for
+ widgets as well as text.
+
+2005-08-02 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (ParseEnum, ParseFlags, PropToString):
+ use Enum rather than obsolete EnumWrapper
+
+ * libstetic/editor/Translatable.cs (ButtonPressed): Use
+ non-obsolete Gtk.Menu.Popup().
+
+ * libstetic/wrapper/objects.xml: add "Stock" internal property to
+ Image so that stock images load correctly again. Fix
+ Gtk.Notebook's InsertBefore and InsertAfter commands.
+
+ * stetic/ContextMenu.cs (ContextMenu): work around another
+ anonymous delegates bug (75689)
+
+2005-07-21 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/*.cs: add a bunch of missing EmitNotify()
+ calls.
+
+2005-07-19 Dan Winship <danw@novell.com>
+
+ * stetic/UIManager.cs: subclass of Gtk.UIManager for Stetic. Not
+ horribly functional yet, though it does track Edit menu
+ sensitivity, for both widgets and text, and implements
+ Cut/Copy/Paste for text (but not widgets).
+
+ * stetic/stetic.glade: Replace the menubar with another Custom.
+
+ * stetic/Stetic.cs (Main): create a Stetic.UIManager. Set
+ SteticMain.MainWindow (to the window containing the PropertyGrid).
+ Move menu command implementations to UIManager.cs
+
+ * stetic/ContextMenu.cs: use ImageMenuItems for Cut/Copy/Paste.
+ Use the UIManager to implement them.
+
+ * stetic/Project.cs (SelectedHandler, Selection): pass the
+ Gtk.Widget, not its wrapper, since there won't be a wrapper in the
+ Placeholder case.
+
+ * stetic/ProjectView.cs (WidgetSelected):
+ * stetic/PropertyGrid.cs (Selected): update for prototype change
+
+2005-07-19 Dan Winship <danw@novell.com>
+
+ * libstetic/IProject.cs: rename IStetic to IProject
+
+ * libstetic/*.cs:
+ * libstetic/wrapper/*.cs:
+ * stetic/Project.cs: update
+
+2005-07-15 Dan Winship <danw@novell.com>
+
+ * libstetic/PropertyDescriptor.cs (Translatable, IsTranslated,
+ SetTranslated, TranslationContext, SetTranslationContext,
+ TranslationComment, SetTranslationComment): support for
+ translatable properties.
+
+ * libstetic/GladeUtils.cs: Reorg a bunch to handle
+ translatable-string-related attributes on import/export.
+ (SetPacking): do GladeOverride packing properties correctly.
+
+ * libstetic/EditorAttribute.cs: gone. We weren't really using it
+ anyway, and editors can get data from the PropertyDescriptor now.
+
+ * libstetic/TextBox.cs: a vertically-scrolling
+ fixed-number-of-lines TextView. Stolen from Stetic.Editor.Text,
+ now also used by Stetic.Editor.Translatable.
+
+ * libstetic/editor/Translatable.cs: base class for translatable
+ property editors. Adds an icon indicating whether or not the
+ property is marked for translation, with a pop-up menu allowing
+ you to toggle that and set a context or comment (which appear
+ inline in the property grid rather than only in a separate
+ window).
+
+ * libstetic/editor/String.cs: inherit from Translatable
+
+ * libstetic/editor/Text.cs: inherit from Translatable and use
+ TextBox.
+
+ * libstetic/editor/Enumeration.cs:
+ * libstetic/editor/GroupPicker.cs:
+ * libstetic/editor/StringArray.cs: update protytype to take a
+ PropertyDescriptor rather than a PropertyInfo.
+
+ * libstetic/wrapper/objects.xml: Mark all translatable string
+ properties with translatable="true". Also make more use of
+ <property ref=...> to simplify/correctify things.
+
+ * libstetic/wrapper/Container.cs (GladeSetInternalChild): Make
+ this look up the internal child using the properties on the
+ ClassDescriptor, since the "child" might really be a grandchild or
+ deeper descendant.
+ (GladeImportChild, GladeSetInternalChild): Update for
+ GladeUtils.SetPacking change.
+
+ * libstetic/wrapper/pixmaps/globe.png:
+ * libstetic/wrapper/pixmaps/globe-not.png: translated/not
+ translated icon
+
+ * stetic/stetic.glade: Remove the height_request and
+ width_request, because we only wanted to set initial defaults and
+ let it resize itself appropriately after that.
+
+ * stetic/PropertyEditor.cs (PropertyEditor): Pass
+ PropertyDescriptors, not PropertyInfos to editor constructors, and
+ add another new type (PropertyDescriptor, object).
+
+ * stetic/Glade.cs (Export): set the DOCTYPE after the xsl
+ transform, or else XslTransform will insist on adding lots of
+ redundant attributes we don't want.
+
+2005-07-13 Dan Winship <danw@novell.com>
+
+ * libstetic/ClassDescriptor.cs (ClassDescriptor) parse the
+ internal-children node of a class as an ItemGroup.
+ (InternalChildren): return it
+
+ * libstetic/wrapper/objects.xml: Add internal-children nodes to
+ Dialog and OptionMenu. Add info for AboutDialog, ColorSelection,
+ ColorSelectionDialog, FileChooserWidget, FileChooserButton,
+ FileChooserDialog, FontSelection, and FontSelectionDialog (several
+ of which also have internal-children). Move AutoSize from
+ ContainerChild to BoxChild and TableChild for now at least.
+
+ * libstetic/wrapper/Container.cs (Wrap): get the ClassDescriptor's
+ InternalChildren list and set InternalChildId and Name on the
+ container's internal children.
+
+ * libstetic/wrapper/Dialog.cs (Wrap):
+ * libstetic/wrapper/OptionMenu.cs (Wrap): Remove internal child
+ handling; it's done by Container now.
+
+ * libstetic/wrapper/AboutDialog.cs: wrap this, to make the
+ Website/WebsiteLabel behavior more interactively-sane, and to make
+ it not default to putting "Stetic" as the application name :).
+
+ * libstetic/wrapper/FontSelectionDialog.cs: wrapper to expose the
+ internal FontSelection widget.
+
+ * libstetic/editor/StringArray.cs: editor for string[] (for
+ AboutDialog)
+
+ * stetic/PropertyEditor.cs: add Stetic.Editor.StringArray to the
+ editors hashtable.
+
+ * stetic/Grid.cs (SizeAllocate): don't vertically center the label
+ wrt the editor if the editor is more than twice the line height
+ (eg, a multiline text box).
+
+ * stetic/Stetic.cs (Main): call Gtk.AboutDialog.SetUrlHook() here
+ rather than in About(), so that the UrlHook is set for
+ user-created about dialogs too.
+
+2005-07-12 Dan Winship <danw@novell.com>
+
+ * libstetic/ClassDescriptor.cs: fix some names with underscores to
+ use camelCase instead.
+ (ClassDescriptor): If a class has no wrapper typed specified, use
+ its parent's wrapper type. Allow a "cname" attribute, to override
+ the CName property, so we can use a different class at design time
+ than we do at runtime (eg, for MessageDialog). Remove the
+ never-necessary "commands" node and no-longer-necessary
+ "internal-properties" node. Count the number of "important"
+ itemgroups.
+ (NewInstance): move the widget-name-generation code here from
+ Widget, and apply it to every property on the object with the
+ init-with-name attribute.
+ (ImportantGroups): return the number of "important" itemgroups
+
+ * libstetic/GladeUtils.cs (ExtractWrapperProperties, GetProps):
+ update for ItemGroup being enumerable.
+ (ExportWidget): use the ClassDescriptor's CName, not the wrapped
+ type's name.
+
+ * libstetic/ItemDescriptor.cs (ItemDescriptor, IsInternal): note
+ when properties are internal.
+
+ * libstetic/ItemGroup.cs: make this IEnumerable, clean up a bit
+
+ * libstetic/PropertyDescriptor.cs (PropertyDescriptor,
+ InitWithName): note when properties have the init-with-name
+ attribute set.
+
+ * libstetic/wrapper/objects.xml: Move all internal-properties
+ properties to internal="true" properties in itemgroups. Set
+ init-with-name where appropriate. Remove now-redundant
+ wrapper="..." attributes. Remove <commands> node from Gtk.Label.
+ Fix Custom and GtkMessageDialog with cname attributes.
+
+ * libstetic/wrapper/Bin.cs: gone; Container can handle all of
+ this now.
+
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/ScrolledWindow.cs:
+ * libstetic/wrapper/Viewport.cs: inherit from Container now, since
+ Bin is gone
+
+ * libstetic/wrapper/CheckButton.cs (Wrap): Remove Label setting,
+ which now happens via init-with-name.
+
+ * libstetic/wrapper/Container.cs (Wrap): when initializing a
+ container, if it has no children, add a placeholder.
+
+ * libstetic/wrapper/Custom.cs: Remove references to C glue since
+ we can now do this entirely in C# via the "cname" property. Move
+ all of the properties into Stetic.Custom and remove
+ Stetic.Wrapper.Custom.
+
+ * libstetic/wrapper/Label.cs (Wrap): remove; LabelProp gets
+ initialized via init-with-name now
+
+ * libstetic/wrapper/MessageDialog.cs: create a new class
+ Stetic.MessageDialog that subclasses Gtk.Dialog (and update the
+ objects.xml entry to use that). The old solution of just creating
+ a special Gtk.Dialog in CreateInstance() doesn't work any more.
+
+ * libstetic/wrapper/RadioButton.cs (Wrap): remove the Label
+ setting, which now happens via init-with-name
+
+ * libstetic/wrapper/Widget.cs (Wrap): remove the Name setting,
+ which now happens in ClassDescriptor.
+
+ * libstetic/wrapper/Window.cs: inherit from Container, since Bin
+ is now gone, and remove Title setting, which now happens via
+ init-with-name
+
+ * stetic/PropertyEditor.cs: fix a bug in int properties with
+ neither a min nor a max specified.
+
+ * stetic/PropertyGrid.cs (AppendItemGroups): use
+ ClassDescriptor.ImportantGroups rather than assuming the first
+ ItemGroup should be expanded and the later ones shouldn't.
+
+ * glue/custom.c: no longer needed
+
+2005-07-11 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/objects.xml: add some missing properties
+
+2005-07-08 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Widget.cs (InsensitiveManager): track
+ realize/unrealize events and only create the intercepting window
+ when the underlying widget is realized, or else it will end up as
+ a child of the root window and we'll totally lose.
+
+2005-07-08 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/objects.xml: add <glade-transform> nodes with
+ XSL transformations to fix some oddities in the glade file format.
+ (GtkHButtonBox): set the "secondary" property on a Help button
+ child. Use Gtk.Box as a wrapper now, since we don't need a
+ ButtonBox wrapper any more.
+ (GtkButtonBox, GtkVButtonBox): use Gtk.Box as a wrapper.
+ (GtkMenuItem): a menuitem with no label should be a
+ SeparatorMenuItem.
+ (GtkTable): fix/break the non-standard "x_options" and "y_options"
+ (GtkWidget): remove/add the extraneous spaces in "events"
+
+ * libstetic/wrapper/ButtonBox.cs: gone
+
+ * libstetic/wrapper/Container.cs (GladeImport): Sync() at the end.
+
+ * libstetic/wrapper/Table.cs (GladeImportChild, GladeExportChild):
+ gone, handled by xsl now.
+ (GladeImport): gone, Container does the Sync() for us now.
+
+ * libstetic/GladeUtils.cs (ParseFlags): remove special case for
+ Widget.Events
+
+ * libstetic/Registry.cs: handle the <glade-transform> nodes.
+ (GladeImportXsl, GladeExportXsl): properties to return
+ XslTransforms for glade import and export.
+
+ * stetic/Glade.cs: use Registry.GladeImportXsl and GladeExportXsl.
+
+2005-07-08 Dan Winship <danw@novell.com>
+
+ Rework the glade import/export framework to pass XmlElements
+ directly to the wrapper import/export methods, rather than trying
+ to parse out the "relevant" parts into Hashtables, etc. This makes
+ it easier to handle a lot of the things that need special
+ handling now, and will make it easier to handle signal,
+ accelerator, and a11y import/export stuff later.
+
+ * libstetic/GladePropertyAttribute.cs: gone, entirely replaced by
+ XML attributes now
+
+ * libstetic/GladeUtils.cs: update to use XML.
+ (ParseProperty): handle gunichar properties.
+ (Wrap): don't need the LateImportHelper stuff now
+
+ * libstetic/ObjectWrapper.cs (GladeImport): update to use XML
+
+ * libstetic/PropertyDescriptor.cs: Update for removal of
+ GladePropertyAttribute. Handle glade-name and glade-override xml
+ attributes.
+
+ * libstetic/wrapper/objects.xml: Add glade-override="true" to
+ properties that should be read from/written to the wrapper rather
+ than the object during glade import/export. Move AutoSize from
+ Container to ContainerChild, where it belonged. Fix
+ Button.ResponseId to invisiblify correctly. Remove
+ palette-category="internal" since the Palette will now ignore
+ objects with no palette-category. Make Menu be wrapped by
+ Container rather than Widget, so its MenuItems will be added
+ correctly.
+
+ * libstetic/wrapper/Button.cs (GladeImport, GladeExport): update
+ (GladeImportChild): update, and remove the GladeImportComplete
+ stuff, since we can do it immediately after
+ base.GladeImportChild() now.
+ (StockId): Fix so this actually works :)
+
+ * libstetic/wrapper/ButtonBox.cs (GladeImportChild): update,
+ remove redundant setting of button.ResponseId.
+
+ * libstetic/wrapper/Container.cs: make non-abstract, since Menu
+ uses this as its wrapper now.
+ (GladeImport, GladeImportChild, GladeSetInternalChild,
+ GladeExport, GladeExportChild): Update. In particular, Container
+ now handles recursing into child widgets itself, which is nice
+ because it means all of a widget's children are imported when its
+ base.GladeImport() call returns, which lets us simplify a few
+ places that used to need the GladeImportComplete event.
+
+ * libstetic/wrapper/Image.cs (Wrap): Fix the case of wrapping a
+ Gtk.Image with no image specified
+ (IconSize): Remove GladePropertyAttribute
+
+ * libstetic/wrapper/Label.cs (MnemonicWidget): make this a string,
+ for now at least.
+
+ * libstetic/wrapper/OptionMenu.cs (GladeImport, etc):
+ * libstetic/wrapper/Table.cs (GladeImport, etc): update. Remove
+ GladeImportComplete hacks.
+
+ * libstetic/wrapper/Widget.cs (GladeImport, GladeExport): Make
+ these work with XML.
+ (Visible, HasDefault, Sensitive): Remove the
+ GladePropertyAttribute.
+
+ * libstetic/wrapper/Window.cs (Modal, TypeHint, Type): Remove
+ GladePropertyAttribute.
+
+ * libstetic/wrapper/Bin.cs (GladeImport):
+ * libstetic/wrapper/ComboBox.cs (GladeImport):
+ * libstetic/wrapper/CheckButton.cs (GladeImportChild):
+ * libstetic/wrapper/Expander.cs (GladeImportChild, GladeExportChild):
+ * libstetic/wrapper/Frame.cs (GladeImportChild, GladeExportChild):
+ * libstetic/wrapper/ImageMenuItem.cs (GladeImport):
+ * libstetic/wrapper/Notebook.cs (GladeImportChild, GladeExportChild):
+ * libstetic/wrapper/MenuItem.cs (GladeImportChild):
+ * libstetic/wrapper/RadioButton.cs (GladeImport, GladeExport):
+ * libstetic/wrapper/RadioMenuItem.cs (GladeImport, GladeExport):
+ * libstetic/wrapper/RadioToolButton.cs (GladeImport, GladeExport):
+ * libstetic/wrapper/ToolButton.cs (GladeImport): update
+
+ * libstetic/editor/FloatRange.cs:
+ * libstetic/editor/IntRange.cs:
+ * libstetic/editor/OptIntRange.cs: Make these take object args,
+ and substitute in a default min/max value if either is null.
+
+ * libstetic/ClassDescriptor.cs:
+ * libstetic/ItemDescriptor.cs: Use SelectNodes, not
+ GetElementsByTagName, which is recursive. (Oops.)
+
+ * libstetic/ParamSpec.cs (IsUnichar): add this, to test
+ G_IS_PARAM_SPEC_UNICHAR, since you can't otherwise distinguish
+ them from uint paramspecs.
+
+ * stetic/Glade.cs: update to pass XML to libstetic, and to not
+ recurse (since the wrappers do it themselves now).
+
+ * stetic/Palette.cs: ignore classes with no palette category
+ specified.
+
+ * stetic/PropertyEditor.cs: merge BasicEditor and RangeEditor
+ together, and update for the range editor changes to handle
+ implicit min/max.
+
+ * glue/paramspec.c (stetic_param_spec_is_unichar): glue for
+ ParamSpec.IsUnichar.
+
+2005-07-06 Dan Winship <danw@novell.com>
+
+ * libstetic/DND.cs (NewWindow):
+ * libstetic/HandleWindow.cs (HandleWindow): update for new
+ studlynamed WindowAttr fields.
+
+2005-07-01 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/objects.xml: new XML description of widgets,
+ replacing the Register() methods and a lot of miscellaneous
+ property attributes.
+
+ * libstetic/CommandAttribute.cs:
+ * libstetic/DescriptionAttribute.cs:
+ * libstetic/ObjectWrapperAttribute.cs:
+ * libstetic/ObjectWrapperType.cs:
+ * libstetic/RangeAttribute.cs: gone (replaced by XML attributes)
+
+ * libstetic/ItemGroup.cs: construct from XML
+
+ * libstetic/ItemDescriptor.cs: construct from XML
+ (EnabledFor, VisibleFor): take the widget as an argument rather
+ than the wrapper
+
+ * libstetic/PropertyDescriptor.cs: construct from XML, remove
+ slashed property names
+ (GetValue, SetValue): take the widget rather than the wrapper
+
+ * libstetic/CommandDescriptor.cs: construct from XML
+ (Enabled, Run): take the widget rather than the wrapper
+
+ * libstetic/Registry.cs: New static class that handles keeping
+ track of ObjectWrappers and ClassDescriptors.
+
+ * libstetic/ClassDescriptor.cs: new, describes a class. Takes on a
+ lot of functionality that used to be in static ObjectWrapper
+ methods. Also, having ItemGroups, etc stored on a ClassDescriptor
+ object means we don't need a ObjectWrapper subclass for each
+ wrapped class (unless the wrapper implements some special
+ functionality).
+
+ * libstetic/ObjectWrapper.cs: Remove a lot of static methods,
+ which are now handled by Registry and ClassDescriptor.
+
+ * libstetic/GladeUtils.cs: Misc updates for Registry/ObjectWrapper
+ changes
+
+ * libstetic/wrapper/*.cs: remove Register() and various other
+ no-longer-needed things
+
+ * libstetic/wrapper/Alignment.cs:
+ * libstetic/wrapper/Arrow.cs:
+ * libstetic/wrapper/Calendar.cs:
+ * libstetic/wrapper/CheckMenuItem.cs:
+ * libstetic/wrapper/DrawingArea.cs:
+ * libstetic/wrapper/Entry.cs:
+ * libstetic/wrapper/EventBox.cs:
+ * libstetic/wrapper/HBox.cs:
+ * libstetic/wrapper/HButtonBox.cs:
+ * libstetic/wrapper/HPaned.cs:
+ * libstetic/wrapper/HSeparator.cs:
+ * libstetic/wrapper/Menu.cs:
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/wrapper/Misc.cs:
+ * libstetic/wrapper/ProgressBar.cs:
+ * libstetic/wrapper/SeparatorMenuItem.cs:
+ * libstetic/wrapper/SeparatorToolItem.cs:
+ * libstetic/wrapper/Statusbar.cs:
+ * libstetic/wrapper/ToggleButton.cs:
+ * libstetic/wrapper/TreeView.cs:
+ * libstetic/wrapper/VBox.cs:
+ * libstetic/wrapper/VButtonBox.cs:
+ * libstetic/wrapper/VPaned.cs:
+ * libstetic/wrapper/VSeparator.cs: gone; these classes don't
+ need any special functionality beyond what can be specified in
+ objects.xml.
+
+ * stetic/Palette.cs: Use Registry.AllClasses to get the palette
+ contents.
+
+ * stetic/PropertyEditor.cs: use objects directly rather than via
+ their wrappers (particularly since PropertyDescriptor.Get/SetValue
+ now work directly on the objects).
+
+ * stetic/WidgetFactory.cs: take a ClassDescriptor instead of name,
+ icon, and wrapperType.
+
+ * stetic/ContextMenu.cs:
+ * stetic/Project.cs:
+ * stetic/PropertyGrid.cs: misc updates for other changes
+
+2005-06-28 Raja R Harinath <rharinath@novell.com>
+
+ Fix 'make distcheck'.
+ * stetic/Makefile.am (RESOURCE_FILES): Pick stetic.glade from
+ $(srcdir).
+ (stetic.exe): Prepend $(srcdir)/ to all source filenames.
+ (EXTRA_DIST): Add stetic.glade. Don't use $(RESOURCE_FILES).
+ Automake doesn't grok $(wildcard ..).
+ (dist-hook): New. Copy the png files here.
+ * libstetic/Makefile.am (libstetic.dll): Prepend $(srcdir)/ to all
+ source filenames.
+ (EXTRA_DIST): Don't list wrapper/pixmaps/*.png.
+ (dist-hook): New. Copy the png files here.
+
+2005-06-23 Dan Winship <danw@novell.com>
+
+ * libstetic/ItemDescriptor.cs (DisabledIf): Replaces DependsOn and
+ DependsInverselyOn; specifies that a property is disabled if
+ another property has any of the listed values. (Rather than only
+ being able to depend on boolean values like before).
+ (InvisibleIf): Likewise replaces VisibleIf and InvisibleIf.
+ (HasVisibility): Tests if an item has any visibility constraints,
+ a la HasDependencies.
+
+ * libstetic/editor/ThemedIcon.cs: new editor for selecting a
+ themed icon (which can be either a registered stock icon or one of
+ the broader set of theme-based icons).
+
+ * libstetic/wrapper/Button.cs: Redo this using an enum to select
+ the type of button (Stock, Text-only, Themed icon + Label,
+ Icon-from-file + Label, or Custom contents). Use
+ ItemDescriptor.InvisibleIf to cause irrelevant fields to be
+ hidden.
+ (Register): Rework for the above, plus for the
+ ToggleButton/CheckButton inheritance changes below.
+ (ThemedIcon): Use the ThemedIcon editor to select this.
+
+ * libstetic/wrapper/Image.cs: Handle the themed icon vs
+ icon-from-file distinction the same way Button does.
+
+ * libstetic/wrapper/CheckButton.cs: inherit from Container rather
+ than Button, since we're mostly not like Button.
+
+ * libstetic/wrapper/RadioButton.cs: inherit from CheckButton, not
+ Button.
+
+ * libstetic/wrapper/ToggleButton.cs: Simplify because it can
+ inherit more behavior from Button, now that CheckButton doesn't.
+
+ * libstetic/wrapper/Dialog.cs (AddButton): update for Button
+ changes
+
+ * libstetic/wrapper/ScrolledWindow.cs (AddWithViewport): Set the
+ ShadowType on the Viewport to None.
+
+ * libstetic/wrapper/Box.cs (BoxChild.Register):
+ * libstetic/wrapper/ButtonBox.cs (ButtonBoxChild.Register):
+ * libstetic/wrapper/FontButton.cs (Register):
+ * libstetic/wrapper/Scale.cs (Register):
+ * libstetic/wrapper/Table.cs (TableChild.Register): Update for
+ ItemDescriptor changes.
+
+ * stetic/PropertyGrid.cs: Add logic to allow property visibility
+ to change on the fly, rather than being assumed to be constant for
+ a given object.
+
+ * stetic/Grid.cs (OnSizeAllocated): if a widget is invisible,
+ don't allocate space for it. If an editor is invisible, hide its
+ label too.
+
+2005-06-12 Todd Berman <tberman@off.net>
+
+ * libstetic/wrapper/Frame.cs: Make the frame HIG-ified by default.
+ * TODO: Update TODO.
+
+2005-06-10 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Widget.cs (InsensitiveManager): new static
+ class to manage insensitive widgets (using a Gtk.Invisible and
+ InputOnly Gdk.Windows to intercept clicks on them).
+ (Sensitive): Inform the InsensitiveManager about the widget's
+ state.
+
+ * libstetic/HandleWindow.cs: Likewise, attach the HandleWindow to
+ a Gtk.Invisible, so we still get events on it even if the selected
+ widget is insensitive.
+
+ * TODO: Sensitive is handled properly now.
+
+2005-06-01 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/ScrolledWindow.cs (AddWithViewport): Create
+ and wrap the viewport first, rather than trying to wrap it after
+ adding it to the window, which may cause a warning trying to set
+ its .Events in Widget.Wrap().
+ (ReplaceChild): If oldChild is in a Viewport, remove it from that
+ as well as removing the viewport from the scrolled window.
+
+ * libstetic/wrapper/Container.cs (Select): connect to the
+ selection's "Destroyed" event (and disconnect from the old
+ selection's)
+ (SelectionDestroyed): Unselect the selection
+ (Delete): No longer need to do it here. (Now destroyed widgets get
+ properly unselected whether you delete them directly or delete one
+ of their ancestors.)
+
+ * stetic/Palette.cs: Fix this to not be a subclass of
+ ScrolledWindow; the caller can put it in a ScrolledWindow itself
+ if it wants to.
+
+ * stetic/Project.cs (Selection): don't try to unselect the
+ previous selection if it's been destroyed, or we'll get a warning.
+
+ * stetic/stetic.glade: Fill in the menu contents here, set up some
+ signal handlers.
+
+ * stetic/stetic-multi.glade: An alternate UI file, with multiple
+ windows like glade.
+
+ * stetic/Stetic.cs (Main): update for the .glade file changes.
+ (Cut, Copy, Paste, Delete): currently dummy methods
+ (Quit): implement
+ (About): implement
+
+2005-05-27 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Box.cs (DoSync, Drop): Properly handle
+ PackStart vs PackEnd (particularly in terms of creating all the
+ right drag faults).
+
+ * libstetic/DND.cs (AddFault): add some new overloads
+
+ * TODO: remove comments about PackStart/PackEnd
+
+2005-05-26 Dan Winship <danw@novell.com>
+
+ * stetic/Stetic.cs (Main): Load the UI from a glade file rather
+ than hardcoding it.
+
+ * stetic/stetic.glade: the UI, now editable in itself
+
+ * stetic/Glade.cs: Rename this class to GladeFiles, because C#'s
+ namespacing rules suck.
+
+ * stetic/Makefile.am: add stetic.glade as a resource
+
+ * libstetic/wrapper/Container.cs (LookupParent): don't return
+ Unselectable wrappers
+
+ * libstetic/wrapper/Custom.cs (Int1, Int2): Add RangeAttributes
+ to these so the property grid doesn't crash
+
+ * libstetic/wrapper/Paned.cs (ReplaceChild): Make this actually
+ work.
+
+ * libstetic/wrapper/ScrolledWindow.cs (ReplaceChild,
+ AddPlaceholder): when using a Viewport, create an (unselectable)
+ ObjectWrapper for it.
+ (RealChildren, GladeChildren): override to make the viewport show
+ up when glade-exporting, but not otherwise.
+
+ * libstetic/wrapper/Viewport.cs: new, wrapper for Gtk.Viewport.
+
+2005-05-26 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (ParseFlags, PropToString): Remove
+ special cases for TableChild options (now handled in Table.cs).
+ Use PropertyDescriptor.HasDefault.
+
+ * libstetic/IStetic.cs (Selection): Make this a Gtk.Widget, not a
+ Stetic.Wrapper.Widget, so we can keep more careful track of
+ Placeholder selections.
+
+ * libstetic/PropertyDescriptor.cs (HasDefault): new settable
+ property to say whether or not the property has a default value.
+ (See Scale.cs below).
+
+ * libstetic/wrapper/Bin.cs (GladeImport): at GladeImportComplete
+ time, if the bin is empty, add a Placeholder.
+
+ * libstetic/wrapper/Button.cs (GladeImport, GladeChildren): dtrt
+ with buttons that contain placeholders.
+ (FixupGladeChildren): set UseUnderline correctly.
+ (GladeExport): handle stock buttons correctly
+
+ * libstetic/wrapper/ButtonBox.cs (GladeImportChild): fix the
+ "Help" button case.
+
+ * libstetic/wrapper/Container.cs (LookupParent): was
+ Widget.ParentWrapper, but now can be used for Placeholders as
+ well.
+ (Select, UnSelect): update for selection changes
+
+ * libstetic/wrapper/Image.cs (GladeExport): don't export the
+ "filename" property when it's a stock image, or the "stock"
+ property when it's an image file.
+ (UseStock, Stock, Filename): misc other fixes
+
+ * libstetic/wrapper/OptionMenu.cs (GladeImport): juggle the Menu
+ at GladeImportComplete time to force a proper size request
+ (GladeImportChild): allow the menu to be specified as an internal
+ or non-internal child, since different versions of glade
+ apparently do different things.
+
+ * libstetic/wrapper/Scale.cs (Register): clear HasDefault on the
+ DrawValue and ValuePos properties, since the ParamSpecs are
+ registered with the wrong default values.
+
+ * libstetic/wrapper/Table.cs (GladeImportChild, GladeExportChild):
+ translate between the "normal" flag value representation
+ ("GTK_EXPAND|GTK_FILL") and TableChild's special representation
+ ("expand|fill") here rather than in GladeUtils.
+
+ * libstetic/wrapper/Widget.cs (ParentWrapper): use
+ Container.LookupParent().
+ (WidgetEvent): update for selection changes
+ (UnSelect): gone, handled by other things now
+
+ * stetic/ContextMenu.cs: Fix (again) so that only the top level
+ menu has submenus. Add icons to the widget labels.
+
+ * stetic/Glade.cs (Export): close the file when we're done.
+ (ExportWidget): Remove a no-longer-relevant FIXME about
+ Placeholders
+
+ * stetic/Project.cs (Selection, etc): update for IStetic change to
+ make Selection a Gtk.Widget. Unselect the previous selection
+ always. (Previously Placeholders weren't unselected properly.)
+
+ * stetic/PropertyGrid.cs: Add a "Widget Class" line (with icon)
+
+2005-05-24 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs: Fix up the parsing/unparsing to be
+ based on C# types rather than ParamSpec GTypes, so that it can be
+ used for C# wrapper properties. Update for PropertyDescriptor
+ GladeProperty changes.
+
+ * libstetic/PropertyDescriptor.cs (PropertyDescriptor): Allow the
+ "Foo" in a "Foo/Bar" property to be a wrapper property. Copy the
+ ParamSpec and GladeAttribute from a property to its glade proxy.
+ (GladeProperty): don't return null; if the property has no
+ GladeProperty proxy, return the property itself.
+ (GladeName): don't peek into GladeProperty. (Make the caller do
+ it).
+ (GladeGetValue, GladeSetValue): gone; just use GetValue/SetValue
+ on the GladeProperty.
+
+ * libstetic/RadioGroupManager.cs (GladeGroupName): return the
+ glade "group" property value for a radio group item.
+
+ * libstetic/editor/GroupPicker.cs (Dispose): Changed from
+ OnDestroyed() to work around a gtk# refcounting bug at the moment.
+
+ * libstetic/wrapper/Button.cs (ConstructChild): build Unselectable
+ wrappers for the contents, so they can be glade-serialized
+ correctly.
+ (GladeChildren): include or skip the child wrappers as
+ appropriate.
+ (HasResponseId): fix
+
+ * libstetic/wrapper/Calendar.cs (DisplayOptions): proxies
+ Gtk.Calendar.DisplayOptions, with a GladeProperty attribute.
+ (Register): Change properties to, "DisplayOptions/ShowHeading",
+ etc, so that DisplayOptions is treated as the glade property.
+ (GladeImport): no longer needed
+
+ * libstetic/wrapper/Container.cs (GladeChildren): new virtual
+ property to get a list of children for glade export purposes
+
+ * libstetic/wrapper/Custom.cs:
+ s/ObjectManager.RegisterType/GType.Register/
+ (Int1, Int2): make these ints now that GladeUtils can deal with
+ that.
+
+ * libstetic/wrapper/MenuItem.cs (Label): store the label text
+ separately from the Label itself, since OptionMenu will steal the
+ Label of the selected MenuItem, so our Label will sometimes be
+ unexpectedly null.
+ (UseUnderline): remove glade proxy now that GladeUtils can
+ directly deal with the property being a bool.
+
+ * libstetic/wrapper/OptionMenu.cs (Items, FlattenMenu): Remove.
+ Make the contents be a menu, not just a list of labels.
+ (Wrap): mark the menu wrapper with the InternalChildId "menu"
+ (GladeImport): don't need FlattenMenu any more, but have to set
+ Active property after the menu is built.
+ (GladeChildren): return the menu.
+
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/RadioMenuItem.cs:
+ * libstetic/wrapper/RadioToolButton.cs (GladeImport): Re-set
+ "Active" after setting the group.
+ (GladeExport): Use GroupManager.GladeGroupName() to get the right
+ group
+
+ * libstetic/wrapper/Widget.cs (Unselectable): new property.
+ (FindWrapper): skip wrappers marked Unselectable.
+
+ * stetic/Glade.cs (ExportWidget): use GladeChildren rather than
+ RealChildren.
+
+2005-05-04 Dan Winship <danw@novell.com>
+
+ * configure.in: require gtk-sharp 2.5
+
+ * libstetic/editor/GroupPicker.cs: use ComboBox.RowSeparatorFunc
+ to add a separator to the menu
+
+ * libstetic/wrapper/Toolbar.cs (Tooltips): Remove; this is a real
+ property in gtk 2.6
+
+ * libstetic/wrapper/ToggleToolButton.cs (Active): Likewise
+
+2005-04-28 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (PropToString): switch based on the type
+ of value, not on prop.PropertyType, since they might not match
+ (eg, if UseUnderlying is set).
+ (GetProps): skip props that aren't visible on a given wrapper
+
+ * glue/custom.c: define the last_modification_time property to
+ avoid warnings on glade import
+
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/Frame.cs (GladeExportChild): implement
+
+ * libstetic/wrapper/Paned.cs: Remove MaxPosition/MinPosition from
+ the Pane Properties; they're not writable.
+
+2005-04-26 Dan Winship <danw@novell.com>
+
+ * glue/Makefile.am (pkglib_LTLIBRARIES): install libsteticglue.la
+
+ * libstetic/Makefile.am (pkglib_DATA): install libstetic.dll and
+ libstetic.dll.config
+ (libstetic.dll): update to non-warned-about mcs option syntax
+ (CLEANFILES, EXTRA_DIST): update
+
+ * libstetic/libstetic.dll.config: remove unused mapping
+
+ * libstetic/wrapper/pixmaps/Makefile.am: remove unused Makefile
+
+ * stetic/Makefile.am (pkglib_DATA, bin_DATA): install stetic and
+ stetic.exe
+ (stetic.exe): update to non-warned-about mcs option syntax
+ (CLEANFILES, EXTRA_DIST): update
+ (run, trace, mdb, gdb): targets to run the uninstalled stetic.exe
+
+ * stetic/stetic.in: redo this for installation
+
+ * stetic/stetic.exe.config: remove this; stetic.exe doesn't
+ DllImport anything of its own
+
+ * configure.in: remove unused GACUTIL checks
+
+2005-04-20 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/CheckMenuItem.cs:
+ * libstetic/wrapper/ImageMenuItem.cs:
+ * libstetic/wrapper/MenuBar.cs:
+ * libstetic/wrapper/MenuItem.cs:
+ * libstetic/wrapper/RadioMenuItem.cs:
+ * libstetic/wrapper/SeparatorMenuItem.cs: wrap these enough to be
+ able to glade-import menus, but not really well enough to be able
+ to edit them happily.
+
+ * libstetic/Makefile.am (libstetic.dll): Change the rule to write
+ all the args out to a response file and then use that.
+
+ * libstetic/editor/Accelerator.cs: PropertyGrid editor for
+ accelerators. Loosely based on EggCellRendererKeys.
+
+ * glue/misc.c (stetic_keycode_is_modifier): for
+ Stetic.Editor.Accelerator
+
+ * glue/Makefile.am (libsteticglue_la_SOURCES): add misc.c
+
+2005-04-19 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (ParseProperty, PropToString): do the
+ value<->string conversion here rather than calling out to C glue.
+ Later on, this will let us get rid of some per-widget hacks, but
+ for now it just does exactly what the C code did.
+
+ * libstetic/wrapper/Container.cs (GladeExportChild): fix the
+ tagging of internal-children, which has apparently been broken for
+ a while.
+
+ * glue/value.c: gone
+
+2005-04-13 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/*.cs: change a bunch of fields that are only
+ used via reflection to be "internal" rather than "private", so
+ that mcs won't warn about their apparent unusedness.
+
+ * libstetic/PropertyDescriptor.cs: remove an unused field
+
+ * stetic/Glade.cs: remove an unused DllImport
+
+2005-04-11 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/HBox.cs:
+ * libstetic/wrapper/HPaned.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/OptionMenu.cs:
+ * libstetic/wrapper/VBox.cs:
+ * libstetic/wrapper/VPaned.cs: s/.Children//
+
+ * libstetic/wrapper/Container.cs (FindInternalChild): use
+ AllChildren
+ (RealChildren): use AllChildren. kill RealChildEnumerator.
+
+ * libstetic/wrapper/Widget.cs (InterceptClicks, FindWrapper): use
+ AllChildren, kill ChildEnumerator
+
+ * stetic/Grid.cs (ForAll): use new signature
+
+2005-04-11 Dan Winship <danw@novell.com>
+
+ * glue/custom.c (custom_new): new method
+
+ * libstetic/RadioGroupManager.cs (this[Gtk.Widget]): track the
+ Destroyed event on radio widgets and update everything
+ appropriately when a radio widget is destroyed.
+
+ * libstetic/wrapper/Widget.cs (Delete): UnSelect when Deleting.
+
+ * libstetic/wrapper/Container.cs (UnSelect): clear the Project
+ selection when unselecting.
+
+ * libstetic/wrapper/Custom.cs (Stetic.Custom.ctor()): call
+ custom_new()
+
+ * TODO: misc updates
+
+2005-04-07 Dan Winship <danw@novell.com>
+
+ * glue/custom.c:
+ * libstetic/wrapper/Custom.cs:
+ * libstetic/wrapper/pixmaps/custom.png: Add custom widgets (a bit
+ kludgy at the moment).
+
+ * libstetic/wrapper/Calendar.cs (GladeImport): handle "display_options"
+
+ * libstetic/wrapper/ComboBox.cs (Items): tag this properly for
+ glade import/export
+
+ * libstetic/wrapper/ScrolledWindow.cs (AddPlaceholder): override
+ this to add the placeholder in a viewport
+
+ * libstetic/wrapper/Widget.cs (ParentWrapper): fix to not get into
+ an infinite loop on toplevel windows.
+
+2005-04-07 Dan Winship <danw@novell.com>
+
+ Add Toolbar and its children, plus a bunch of things I had to fix
+ to get there.
+
+ * libstetic/DND.cs (Cancel): Returns the widget that was being
+ dragged, after removing it from the DragWindow, so we don't get
+ errors when you cancel a drag.
+
+ * libstetic/HandleWindow.cs (Dispose): disconnect from
+ selection.WidgetEvent.
+ (SelectionEvent): if the event occurred in the handle window,
+ always return true. Fixes the bug where widgets sometimes undrew
+ themselves when they were selected.
+
+ * libstetic/ObjectWrapperAttribute.cs (ObjectWrapperType): kill
+ this enum
+ (Type): make this a string
+
+ * libstetic/ObjectWrapperType.cs: new static class containing
+ constant strings for the predefined wrapper types (including the
+ new ToolbarItem type).
+
+ * libstetic/Placeholder.cs (OnDragDrop): remove this; Container
+ can handle the event itself.
+
+ * libstetic/PropertyDescriptor.cs: Fix this to be able to handle
+ the case of a subproperty of a wrapper type (eg,
+ ToolItem.IsImportant in Wrapper.Toolbar.ToolbarChild)
+
+ * libstetic/RadioGroupManager.cs: Move the group-handling code
+ from Wrapper.RadioButton here, and genericize it to be able to
+ work with RadioToolButtons and RadioMenuItems as well.
+
+ * libstetic/editor/GroupPicker.cs: update to use RadioGroupManager.
+
+ * libstetic/wrapper/Container.cs (PlaceholderDragDrop): connect to
+ this directly rather than having the Placeholder proxy it to us.
+ (CreateDragSource): new virtual method to create a Placeholder (or
+ not) specifically for when dragging something out of a container
+ (CreatePlaceholder): update signal-handling here
+ (RealChildren): make this virtual
+
+ * libstetic/wrapper/Toolbar.cs: Wrap this.
+ (RealChildren, ReplaceChild): Override these to handle "invisible"
+ ToolItem wrappers around non-ToolItem objects stuck into the
+ toolbar.
+ (DoSync, Drop): do DND autoexpanding. (At some point, we should
+ use the actual toolbar DND editing methods.)
+ (CreateDragSource, DragEnd): return a Gtk.Invisible rather than
+ adding a placeholder to the toolbar.
+ (ToolbarChild): wrap this, putting the three ToolItem properties
+ here, since it's where they really belong.
+
+ * libstetic/wrapper/RadioButton.cs: port to use RadioGroupManager
+
+ * libstetic/wrapper/Widget.cs (Wrap, InterceptClicks): recursively
+ set up event interception, so that widgets with internal embedded
+ widgets work correctly.
+ (ParentWrapper): Make this able to cope with non-wrapped widgets
+ in the hierarchy.
+
+ * libstetic/wrapper/RadioToolButton.cs:
+ * libstetic/wrapper/SeparatorToolItem.cs:
+ * libstetic/wrapper/ToggleToolButton.cs:
+ * libstetic/wrapper/ToolButton.cs: Wrap
+
+ * stetic/Palette.cs: update for ObjectWrapperType changes
+
+2005-04-05 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Widget.cs (ToString): override
+
+ * stetic/ContextMenu.cs (ContextMenu): Update for WidgetSite
+ removal; use the right context widget. Also, only include the
+ insensitive "name" label on the top-level menu.
+
+2005-04-04 Dan Winship <danw@novell.com>
+
+ * libstetic/PropertyDescriptor.cs (GladeName): fix for proxied
+ properties so that MnemonicWidget works right.
+
+ * libstetic/wrapper/Button.cs (ConstructChild): Fix so that stock
+ icons always UseUnderline
+
+ * libstetic/wrapper/Container.cs (FindInternalChild): No need to
+ recurse upward here any more. Also, return the wrapper rather than
+ the child.
+ (GladeSetInternalChild): don't create a wrapper here, since the
+ widget must already have one.
+ (Select): add a workaround for when you select a widget that isn't
+ mapped.
+
+ * libstetic/wrapper/OptionMenu.cs (Wrap): create a wrapper for the
+ menu.
+ (GladeSetInternalChild): override this, since the menu (which
+ glade considers to be an internal child of the optionmenu) is not
+ actually a real child.
+
+ * libstetic/wrapper/Widget.cs (FindWrapper): don't find widgets
+ that aren't mapped.
+ (HasDefault, HierarchyChanged): Fix the logic here; a widget
+ always has a "Toplevel", it's just that the Toplevel is not always
+ actually a toplevel widget.
+
+ * libstetic/wrapper/Window.cs (Select): Show() the window when it
+ is selected.
+
+2005-03-29 Dan Winship <danw@novell.com>
+
+ * libstetic/HandleWindow.cs (SelectionEvent): simplify for gdk#
+ changes
+
+ * libstetic/editor/Image.cs: Use reflection to get the list of
+ stock IDs rather than Gtk.Stock.ListIds, since the latter will
+ return 2.6-specific IDs if you have libgtk 2.6.
+ (Image): pack the combobox into a vbox so it won't expand
+ incorrectly.
+
+ * libstetic/wrapper/ButtonBox.cs (GladeImportChild): fix
+ ResponseId handling.
+
+ * libstetic/wrapper/Container.cs (Select, UnSelect): virtualize
+ (Delete): new method to delete a widget and replace it with a
+ Placeholder.
+
+ * libstetic/wrapper/Label.cs (Label (string)): pass "true" to Wrap
+ so it doesn't bash the passed-in label string
+
+ * libstetic/wrapper/Notebook.cs (GladeImportChild, InsertPage):
+ Remove FIXMEs.
+ (GladeExportChild): fix a leftover WidgetSiteism.
+ (Select): override this; if a tab is selected, switch to its page.
+ (ReplaceChild): allow tabs to be replaced, and don't muck things
+ up when pages get replaced
+
+ * libstetic/wrapper/Table.cs (Sync): fix to not get caught in
+ infinite loops again.
+
+ * libstetic/wrapper/Widget.cs (WidgetEvent): simply for gdk#
+ changes.
+ (FindWrapper): search all children (not just non-internal ones)
+ (Delete): new method to delete a widget (by calling
+ ParentWrapper.Delete)
+
+ * stetic/ContextMenu.cs (DoDelete): use Wrapper.Widget.Delete()
+
+2005-03-29 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetBox.cs:
+ * libstetic/WidgetSite.cs: GONE!
+
+ * libstetic/Placeholder.cs: inherit from DrawingArea rather than
+ WidgetBox now.
+ (NewWindow): Gone. The DrawingArea creates the window for us now.
+ (Mimic, UnMimic): kill; Wrapper.Container watches out for this now
+
+ * libstetic/HandleWindow.cs (SelectionEvent): intercept
+ ButtonPress and Motion events and signal to the parent container
+ when to start dragging.
+
+ * libstetic/DND.cs (SourceSet, SourceUnset, SourceButtonPress,
+ CanDrag): Remove "non-automatic" drag sources; HandleWindow
+ handles that now.
+ (AddFault, etc): update/rename stuff for WidgetSite removal
+
+ * libstetic/IStetic.cs (CreateWidgetSite, CreatePlaceholder): gone
+ (PopupContextMenu): new, to make the app pop up a context menu
+ (Selection): new read/write property to replace old Select() method
+
+ * libstetic/wrapper/Widget.cs (Wrap): add ButtonPressMask to the
+ widget eventmask, and connect to WidgetEvent and PopupMenu
+ (ParentWrapper): simplify for lack of WidgetSites
+ (WidgetEvent): intercept button presses and walk through the
+ widget's children to find the deepest wrapped widget that the
+ click was inside (since NoWindow widgets will no longer be able to
+ report their own clicks). Handle selection and context menus.
+
+ * libstetic/wrapper/Container.cs (GladeImportChild,
+ GladeExportChild): remove WidgetSite handling
+ (Add): replaces AddWidgetSite
+ (CreateWidgetSite, SiteButtonPress, SiteMotionNotify): gone
+ (CreatePlaceholder): create the Placeholder directly rather than
+ needing stetic.CreatePlaceholder.
+ (PlaceholderDrop, PlaceholderDragEnd): don't create a WidgetSite
+ (RealChildren): replaces Sites
+ (HandleWindowDrag): initiate drag and drop from here.
+ (ChildHExpandable, ChildVExpandable): checks the expandability of
+ a child (which might be a Placeholder, or not)
+
+ * libstetic/wrapper/*.cs: Update for WidgetSite removal, and
+ ChildHExpandable/ChildVExpandable.
+
+ * stetic/ContextMenu.cs (OnSelectionDone): be self-destroying
+
+ * stetic/Glade.cs (ExportWidget): no more WidgetSites
+
+ * stetic/Project.cs (Selection): change from method to property
+ (CreateWidgetSite, CreatePlaceholder): Kill
+ (PopupContextMenu): Implement
+ (AddWidget, ContentsChanged): s/foo.Sites/foo.RealChildren/
+
+2005-03-28 Dan Winship <danw@novell.com>
+
+ * libstetic/HandleWindow.cs: new class to implement selection handles.
+
+ * libstetic/WidgetBox.cs: Remove all handle-related code
+
+ * libstetic/IStetic.cs (Select): new, to tell the main program to
+ select a widget (rather than having the it listen for an event on
+ all toplevel windows).
+
+ * libstetic/wrapper/Widget.cs (Select, UnSelect): tell the parent
+ container (if any) to select this widget
+ (CreateWidgetSite, CreatePlaceholder): remove these; anything that
+ is a container needs to be subclassing Container, not Widget.
+
+ * libstetic/wrapper/Container.cs (CreateWidgetSite,
+ CreatePlaceholder): catch ButtonPressEvents
+ (SiteButtonPress, PlaceholderButtonPress): handle
+ selection/context menus
+ (Select, UnSelect): update handles, call stetic.Select()
+
+ * libstetic/wrapper/Notebook.cs: FIXME out a few bits for now...
+
+ * libstetic/wrapper/Table.cs (OnButtonPressEvent): remove this
+ code, which has been commented-out forever.
+
+ * libstetic/wrapper/Window.cs (SetFocus, Select): gone; selection
+ is handled at the Container level now.
+
+ * stetic/Project.cs (WindowFocusChanged): gone
+ (IStetic.Select): handle selection here
+ (SelectedHandler): change the WidgetBox arg to a Wrapper.Widget
+
+ * stetic/ProjectView.cs (WidgetSelected):
+ * stetic/PropertyGrid.cs (Selected): update signature
+
+2005-03-24 Dan Winship <danw@novell.com>
+
+ * libstetic/DND.cs: move the drag-and-drop "fault" code from
+ WidgetSite to here. Remove the DragBegin and DragEnd events since
+ nothing needs them any more.
+
+ * libstetic/WidgetSite.cs (AddFault, AddVFault, AddHFault,
+ ClearFaults, ShowFaults, HideFaults, OnDragMotion, OnDragLeave,
+ OnDragDrop): all moved into DND now.
+ (Internal): gone; does nothing WidgetBox.Internal doesn't do now
+
+ * libstetic/wrapper/Widget.cs (Drop): dummy virtual implementation
+ that just destroys the dropped widget
+
+ * libstetic/wrapper/Box.cs (Sync): s/site/DND/ for all the fault
+ stuff
+ (Drop): override to dtrt
+
+2005-03-24 Dan Winship <danw@novell.com>
+
+ More code migration out of WidgetSite
+
+ * libstetic/DND.cs (DragWidget): public accessor for dragWidget
+
+ * libstetic/Placeholder.cs (Mimic, UnMimic): makes a Placeholder
+ mimic the size and expandability of a given WidgetSite. (Replaces
+ the old "PseudoOccupied" mode of WidgetSite).
+
+ * libstetic/WidgetSite.cs (Contents): killed, was redundant with
+ "Child".
+ (ShapeChanged): gone, replaced by ChildContentsChanged on
+ Wrapper.Container.
+ (Occupancy, Empty): gone. pseudo-occupancy is now handled by
+ Placeholder; all WidgetSites are now always actually occupied.
+ (OnMotionNotifyEvent, OnDragDataDelete, OnDragEnd): handled by
+ Wrapper.Container now
+
+ * libstetic/wrapper/Button.cs: s/site.Contents/site.Child/
+
+ * libstetic/wrapper/Box.cs (DoSync): do autosizing here
+ (ReplaceChild): kill off the empty-placeholder-killing code for now
+
+ * libstetic/wrapper/Container.cs (Freeze, Thaw, Sync, DoSync):
+ move Freeze/Thaw here from Table, change the overridable method to
+ "DoSync" and make Sync check frozenness and then call DoSync.
+ (CreateWidgetSite): Set up DND on the site and if it contains a
+ container, connect to its ContentsChanged method (to replace the
+ old WidgetSite.ShapeChanged method).
+ (SiteMotionNotify, PlaceholderDragEnd): handle DND.
+ (ChildContentsChanged): Replaces SiteShapeChanged;
+
+ * stetic/Glade.cs:
+ * stetic/Project.cs:
+ * stetic/PropertyGrid.cs: s/site.Contents/site.Child/
+
+2005-03-23 Dan Winship <danw@novell.com>
+
+ Move IWidgetSite and WindowSite interfaces to
+ Stetic.Wrapper.Widget and Stetic.Wrapper.Window.
+
+ * libstetic/wrapper/Widget.cs (Wrapped): override to return a
+ Gtk.Widget, to get rid of lots of typecasting
+ (ParentWrapper): replacement for WidgetSite.ParentSite; returns
+ the wrapper for the wrapped widget's parent
+ (InternalChildId, Select): Moved here from WidgetSite.
+
+ * libstetic/wrapper/Window.cs (FocusChanged): moved here from
+ WindowSite.
+ (Select): override
+
+ * libstetic/WidgetSite.cs (ParentSite): gone; replaced by
+ Wrapper.Widget.ParentWrapper.
+ (Internal): replaces InternalChildId.
+ (Drop): call Select on the wrapper, not the site.
+ (Select, UnSelect, Delete): gone
+
+ * libstetic/IWidgetSite.cs:
+ * libstetic/WindowSite.cs: gone
+
+ * libstetic/wrapper/Button.cs (HasResponseId): use ParentWrapper
+ rather than ParentSite.
+
+ * libstetic/wrapper/Container.cs (GladeExportChild,
+ FindInternalChild): update for InternalChildId move from
+ WidgetSite to Wrapper.Widget.
+ (ChildWrapper): take a Wrapper.Widget instead of an IWidgetSite.
+ (PlaceholderDrop): call Select on the wrapper, not the site.
+
+ * libstetic/wrapper/Dialog.cs (Wrap): set InternalChildId on the
+ wrapper, not the site.
+
+ * stetic/ContextMenu.cs: Change all IWidgetSites to
+ Stetic.Wrapper.Widgets
+
+ * stetic/Project.cs (AddWindow): take a Stetic.Wrapper.Window
+ rather than a WindowSite.
+ (ProjectNode): add a "Wrapper" field
+
+ * stetic/ProjectView.cs (RowSelected, WidgetSelected): update to
+ use wrappers intead of sites.
+
+ * stetic/Glade.cs (Import):
+ * stetic/WidgetFactory.cs (WindowFactory.OnButtonPressEvent):
+ don't need to create a WindowSite for top-level windows any more.
+ Just pass the wrapper to Project.AddWindow instead.
+
+2005-03-23 Dan Winship <danw@novell.com>
+
+ Split apart placeholders and WidgetSites. This is an intermediate
+ step on the road to killing off WidgetSite, and several wrappers
+ are broken in this check-in because it doesn't make much sense to
+ fix them twice.
+
+ * libstetic/Placeholder.cs: New subclass of WidgetBox to represent
+ a placeholder (which can accept drops, but can't actually hold
+ widgets).
+
+ * libstetic/WidgetSite.cs: Mostly remove support for empty
+ WidgetSites (though not pseudo-occupied ones).
+
+ * libstetic/WidgetBox.cs: Move some stuff here from WidgetSite
+ that both WidgetSite and Placeholder will need. Move out some (but
+ not all) stuff that they don't both need.
+
+ * libstetic/WindowSite.cs (FocusChangedHandler, FocusChanged):
+ make the focus be a WidgetBox rather than an IWidgetSite
+
+ * libstetic/CommandDescriptor.cs:
+ * libstetic/ItemDescriptor.cs: Update commands to take a Widget
+ context rather than an IWidgetSite.
+
+ * libstetic/wrapper/Bin.cs:
+ * libstetic/wrapper/Box.cs:
+ * libstetic/wrapper/Dialog.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/Paned.cs:
+ * libstetic/wrapper/ScrolledWindow.cs:
+ * libstetic/wrapper/Table.cs:
+ * libstetic/wrapper/Window.cs: update for site/placeholder changes
+
+ * libstetic/wrapper/Widget.cs (CreateWidgetSite): Make this take a
+ widget to put in the WidgetSite.
+ (CreatePlaceholder): like the old CreateWidgetSite, but creates a
+ Placeholder.
+
+ * libstetic/wrapper/Container.cs: update for site/placeholder
+ changes
+ (ReplaceChild): new virtual method to replace one child widget
+ with another
+ (SiteEmpty): replace the site with a placeholder
+ (PlaceholderDrop): replace the placeholder with a WidgetSite
+ containing the dropped widget.
+
+ * libstetic/wrapper/Button.cs: update for site/placeholder changes
+ (Wrap): fix this so we don't get blank buttons
+ (ConstructChild): fix this to work around a maybe-bug in gtk
+ 2.4.12 and earlier.
+
+ * stetic/*.cs: Misc updates for WidgetSite/Placeholder changes
+
+2005-03-21 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Button.cs: Remove "UseStock" property and just
+ use a Stetic.Editor.Image to select either a stock icon or a file.
+ Also allow stock icon (or file) with non-stock label.
+ (GladeImportChild, FixupGladeChildren): import correctly
+
+ * libstetic/wrapper/ToggleButton.cs: likewise
+
+ * libstetic/wrapper/Dialog.cs (AddButton): update for Button changes
+
+ * libstetic/wrapper/Image.cs (File): This is equivalent to the
+ GladeProperty "pixbuf".
+
+ * libstetic/editor/Image.cs: fixes
+
+ * libstetic/GladeUtils.cs (ParseGladeProperty): don't try to parse
+ string properties, since they don't need to be (and might not
+ correspond to underlying properties anyway).
+
+2005-03-21 Dan Winship <danw@novell.com>
+
+ * glue/paramspec.c:
+ * libstetic/ParamSpec.cs: Simplify based on the latest version of
+ the patch in #70061.
+
+ * libstetic/ParamFlags.cs: gone; we never used this
+
+ * libstetic/libstetic.dll.config: add libgtk to the map
+
+2005-03-18 Dan Winship <danw@novell.com>
+
+ * libstetic/editor/Image.cs: editor that allows selecting a stock
+ image or a file
+
+ * libstetic/editor/ImageFile.cs: subclass of Stetic.Editor.Image
+ that only allows picking a file
+
+ * libstetic/editor/StockItem.cs: now a subclass of Image
+
+ * libstetic/editor/File.cs: gone
+
+ * libstetic/wrapper/Image.cs: Use ImageFile editor and fix things
+ up a bit.
+
+ * libstetic/wrapper/Window.cs (Icon): wrap, using the ImageFile editor
+
+2005-03-17 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetBox.cs (Internal): new property saying that the
+ box represents an internal object.
+ (ShapeHandles): if the box is Internal, don't add corner handles.
+
+ * libstetic/WidgetSite.cs (InternalChildId): set the "Internal"
+ property according to whether or not the child id is null, and
+ call DND.SourceUnset if marking something internal, so it can't be
+ dragged anywhere.
+
+ * libstetic/DND.cs (SourceUnset): new.
+ (SourceButtonPress, CanDrag): make sure that CanDrag always
+ returns false if the widget isn't a source.
+
+ * stetic/ContextMenu.cs (ContextMenu): disable Cut and Delete on
+ "Internal" widgetsites.
+
+ * libstetic/ItemDescriptor.cs (VisibleIf, InvisibleIf): mark a
+ property visible if/unless another property is set
+ (VisibleFor): Check if the property should be visible on a given
+ object.
+
+ * stetic/PropertyGrid.cs (AppendProperty): skip properties that
+ shouldn't be visible on this wrapper.
+
+ * libstetic/wrapper/Button.cs (Register): add a "ResponseId"
+ property, and a "HasResponseId" property saying whether or not it
+ should be visible.
+ (HasResponseId): Check if the button's site's parentsite has an
+ InternalChildId of "action_area"
+
+ * libstetic/editor/ResponseId.cs: ComboBoxEntry for dialog button
+ Response IDs.
+
+ * libstetic/wrapper/Dialog.cs (Register): add Buttons and
+ HelpButton properties.
+ (Wrap): set HasSeparator false. Give the internal children sane
+ names. Create a button by default.
+ (Buttons): Allow the user to pick default buttons via a menu
+ (HelpButton): Toggle a "Help" button on/off.
+
+ * libstetic/wrapper/Box.cs: Fix some minor autoexpand problems,
+ make it work right with buttonboxes.
+
+ * libstetic/wrapper/Widget.cs (HasDefault): instead of marking
+ this "LateImport", if it's set when the widget doesn't have a
+ Toplevel, connect to "HierarchyChanged". (That way things other
+ than glade import can set it at inappropriate times as well.)
+
+2005-03-15 Dan Winship <danw@novell.com>
+
+ * libstetic/editor/StockItem.cs: fix sorting again. (ignore "_")
+
+ * libstetic/wrapper/CheckButton.cs:
+ * libstetic/wrapper/Entry.cs:
+ * libstetic/wrapper/ProgressBar.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/Statusbar.cs: mark HExpandable
+
+ * libstetic/wrapper/DrawingArea.cs:
+ * libstetic/wrapper/TextView.cs:
+ * libstetic/wrapper/TreeView.cs: mark HExpandable and VExpandable
+
+2005-03-15 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetSite.cs (AddFault, AddHFault, AddVFault): Make
+ AddHFault and AddVFault take WidgetSites rather than coordinates,
+ and provide AddFault for fully-generic fault adding. For AddHFault
+ and AddVFault, make the fault windows fill the entire space
+ between the two widgets (or from the widget to the edge of its
+ parent) if the widgets are spread apart.
+ (OnDragMotion): Center the splitter inside its fault since the
+ fault may be very large now.
+
+ * libstetic/wrapper/Box.cs (Sync): update for that
+
+ * stetic/Project.cs (ContentsChanged): fix a crash when dragging a
+ widget from one position to another within the same container
+
+2005-03-14 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetSite.cs (FindFault): fix another autoexpand
+ buglet
+ (Drop): fix the focus in the autoexpand case
+
+ * libstetic/editor/StockItem.cs: sort the buttons by their Label,
+ not their StockId
+
+ * libstetic/wrapper/Box.cs (Wrap): Add 2 children to start out,
+ rather than 3.
+ (SiteOccupancyChanged): If a site is emptied, destroy it rather
+ than leaving an empty site behind (since you can still drag a new
+ widget there even without the empty site).
+
+2005-03-14 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetSite.cs: Make OccupancyChanged mean only
+ "Occupancy changed", and add a new ShapeChanged event for when
+ something else happens that may affect AutoSizing in its parent.
+ (ToString): override this for debug purposes
+
+ * libstetic/wrapper/Container.cs (CreateWidgetSite, SiteRemoved):
+ connect to/disconnect from ShapeChanged
+ (SiteShapeChanged): new virtual method
+ (SiteRemoved): call EmitContentsChanged()
+
+ * libstetic/wrapper/Box.cs (InsertBefore, InsertAfter, DropOn):
+ call EmitContentsChanged()
+ (SiteShapeChanged): connect to this, not OccupancyChanged
+
+ * libstetic/wrapper/Expander.cs: don't EmitContentsChanged when
+ toggling the expander, make HExpandable/VExpandable not depend on
+ whether or not the expander is expanded.
+
+ * libstetic/wrapper/Table.cs (Sync): EmitContentsChanged() iff we
+ added sites.
+ (SiteShapeChanged): connect to this, not OccupancyChanged
+
+ * stetic/Project.cs (AddWindow): take a WindowSite rather than a
+ Window, and connect to its FocusChanged event
+ (AddWidget): connect to the widget's Destroyed event
+ (WidgetDestroyed): remove the widget from the tree
+ (ContentsChanged): simplify using new gtk# api
+ (Selected): new event, emitted from the WindowSite.FocusChanged
+ handler
+
+ * stetic/ProjectView.cs (ProjectView): connect to the project's
+ "Selected" event.
+ (RowSelected): if not already syncing, grab the selection on the
+ widget corresponding to the row.
+ (WidgetSelected): if not already syncing, move the table selection
+ to the selected widget.
+
+ * stetic/Stetic.cs: pass Project to the PropertyGrid.
+ (Select, NoSelection): gone; the PropertyGrid snoops the Project
+ directly now.
+
+ * stetic/Glade.cs (Import):
+ * stetic/WidgetFactory.cs (WindowFactory): remove focus-handling
+ code; Project.AddWindow will deal with it now
+
+ * stetic/PropertyGrid.cs (PropertyGrid): take a Project and
+ connect to its Selected event and set the selection directly from
+ that.
+
+2005-03-11 Dan Winship <danw@novell.com>
+
+ First draft of Glade export.
+
+ * libstetic/GladeException.cs: simplify/fix
+
+ * libstetic/GladePropertyAttribute.cs: add "UseUnderlying", to
+ specify that export should use the underlying GObject property
+ rather than the stetic wrapper's version.
+
+ * libstetic/GladeUtils.cs (ExtractWrapperProperty): don't extract
+ properties with the "UseUnderlying" flag set.
+ (ParseGladeProperty): deal with the various new kinds of
+ PropertyDescriptor confusion.
+ (ExportWidget): base glade export method
+ (GetProps): utility method to fill in a Hashtable from a wrapper
+
+ * libstetic/ItemGroup.cs (ItemGroup): deal with '/'s in property
+ names.
+
+ * libstetic/ObjectWrapper.cs (WrappedType, NativeTypeName): make
+ these public so GladeUtils can use them.
+
+ * libstetic/ParamSpec.cs (ValueType, OwnerType): fix the return
+ type
+
+ * libstetic/PropertyDescriptor.cs (PropertyDescriptor): Allow
+ property names to have '/'s like "XOptions/XExpand", meaning that
+ the real property is XOptions, but it's being split up into other
+ properties (including XExpand) in stetic. For split properties
+ like that, and sub-properties like "Adjustment.Value", create a
+ PropertyDescriptor representing the intermediate property too.
+ (GladeProperty): returns the PropertyDescriptor to use for glade
+ export (when that's not the same as the PropertyDescriptor itself)
+ (GladeGetValue, GladeSetValue): renamed to not have "proxy" in the
+ name. Handle all getting/setting of properties for glade.
+
+ * libstetic/SiteContentEnumerator.cs: gone;
+ Stetic.Wrapper.Container.Sites handles this by itself now.
+
+ * libstetic/WidgetSite.cs (InternalChildId): property to mark a
+ WidgetSite as containing an "internal child" of the widget.
+
+ * glue/value.c: reorg a bunch
+ (stetic_g_value_child_property_to_string,
+ stetic_g_value_property_to_string, stetic_g_value_to_string): new
+ functions for glade export
+
+ * libstetic/wrapper/Widget.cs (GladeExport): implement
+
+ * libstetic/wrapper/Container.cs (GladeExportChild): implement
+ (FindInternalChild): make this less gross by expecting the
+ container's wrapper class to have set the InternalChildId on the
+ relevant WidgetSite.
+ (Sites): use Gtk.Container.Forall so that internal sites get
+ returned too.
+
+ * libstetic/wrapper/Button.cs (Label): set UseUnderlying
+
+ * libstetic/wrapper/Dialog.cs (Wrap): set InternalChildId on the
+ internal children.
+
+ * libstetic/wrapper/Image.cs (IconSize): set UseUnderlying
+
+ * libstetic/wrapper/Notebook.cs (GladeExportChild): do the inverse
+ of the GladeImportChild hackery to represent notebook tabs
+ correctly.
+
+ * libstetic/wrapper/RadioButton.cs (GladeExport): fake the "group"
+ property.
+
+ * libstetic/wrapper/Table.cs (TableChild): rewrite the property
+ names as, eg, "XOptions/XExpand", so they will be exported
+ correctly.
+
+ * stetic/Glade.cs (Export): Implement
+
+ * stetic/Project.cs (AddWidget, ContentsChanged): Use
+ Stetic.Wrapper.Container.Sites directly rather than using
+ SiteContentEnumerator.
+ (Toplevels): add an enumerator exposing this, for Glade.Export
+
+ * stetic/PropertyEditor.cs: Fix for PropertyDescriptor changes
+
+ * stetic/Stetic.cs: add an "Export" command to the menu.
+
+2005-03-11 Dan Winship <danw@novell.com>
+
+ * libstetic/ObjectWrapper.cs (Register, Create): if the wrapper
+ type doesn't have a CreateInstance method and the wrapped type
+ doesn't have a no-arg constructor, use g_object_new and the IntPtr
+ constructor.
+
+ * libstetic/wrapper/Alignment.cs:
+ * libstetic/wrapper/Arrow.cs:
+ * libstetic/wrapper/HBox.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/VBox.cs:
+ * libstetic/wrapper/Window.cs: remove no-longer-necessary
+ CreateInstance methods
+
+2005-03-08 Dan Winship <danw@novell.com>
+
+ * libstetic/GladePropertyAttribute.cs: new attribute to mark
+ properties that need special treatment for glade import/export (to
+ allow us to do the special treatment automatically rather than
+ needing custom GladeImport/GladeExport routines).
+ (GladeProperty): flags type for GladePropertyAttribute. Currently
+ defines Proxied (meaning that an alternate property is actually
+ used for glade import/export) and LateImport (meaning that on
+ import, the property shouldn't be set until the import has
+ completed).
+
+ * libstetic/PropertyDescriptor.cs: track glade-related info
+ (GladeFlags, GladeName): new accessors
+ (GladeProxyGetValue, GladeProxySetValue): getter/setter for glade
+ proxy properties
+
+ * libstetic/GladeUtils.cs (ImportWidget): replace CreateWidget and
+ SetProps with two new ImportWidget methods that also handle
+ [GladeProperty] properties.
+
+ * libstetic/ObjectWrapper.cs (GladeImport): if the GladeImport
+ invocation throws a TargetInvocationException, throw its
+ InnerException (presumably a GladeException) up to the caller.
+
+ * libstetic/wrapper/ComboBox.cs (Items): add
+ GladePropertyAttribute noting that this is glade's "items"
+ property.
+ (GladeImport): simplify
+
+ * libstetic/wrapper/Container.cs (GladeSetInternalChild): update.
+
+ * libstetic/wrapper/Entry.cs (InvisibleChar): add this, with a
+ GladePropertyAttribute marking GladeInvisibleChar as its proxy
+ (GladeInvisibleChar): get/set InvisibleChar as a string
+ (GladeImport): gone
+
+ * libstetic/wrapper/Label.cs (MnemonicWidget): add this, with a
+ GladePropertyAttribute marking GladeMnemonicWidget as its
+ LateImport proxy
+ (GladeMnemonicWidget): get/set MnemonicWidget as a string
+ (GladeImport): gone
+
+ * libstetic/wrapper/TextView.cs (Text): add a
+ GladePropertyAttribute noting that this is glade's "text"
+ property.
+ (GladeImport): gone
+
+ * libstetic/wrapper/Widget.cs (Visible, HasDefault): add
+ GladePropertyAttributes. (HasDefault is LateImport)
+ (GladeImport): simplified
+
+ * libstetic/wrapper/Window.cs (Modal, TypeHint, Type): add
+ GladePropertyAttributes
+ (GladeImport): gone
+
+2005-03-08 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetSite.cs (SetupFaults): Pass "false" to DND.DestSet,
+ not true, so that the whole widget isn't drop-on-able.
+ (AddHFault, AddVFault): don't create windows if we're not realized.
+
+ * libstetic/wrapper/Box.cs (Wrap): call box_ParentSet from here so
+ that the DropOn handler will be set up if the Parent is already
+ set when it's wrapped (ie, if it's an internal child)
+
+2005-03-08 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeException.cs: exception class for Glade import problems
+
+ * libstetic/GladeUtils.cs:
+ * libstetic/ObjectWrapper.cs:
+ * libstetic/wrapper/Container.cs: use GladeException
+
+ * libstetic/GladeUtils.cs (Hydrate): Call g_type_class_ref() and
+ pass the GObjectClass* to the glue methods rather than the GType*
+ (to save a bunch of lookups).
+
+ * glue/value.c (stetic_g_value_init_for_property,
+ stetic_g_value_init_for_child_property): Update for that
+
+ * stetic/Glade.cs: renamed from GladeImport.cs
+ (Import): renamed from Load. Use GladeException.
+
+ * libstetic/wrapper/Box.cs (Sync): Fix to not crash on empty boxes
+
+2005-03-08 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (ExtractProperty, CreateWidget,
+ SetProps, SetPacking): Make these all take a Hashtable of
+ propname->value rather than a pair of ArrayLists.
+
+ * libstetic/ObjectWrapper.cs (Wrap): make this public
+ (GladeImport): take a Hashtable rather than ArrayLists
+
+ * libstetic/wrapper/*.cs:
+ * stetic/GladeImport.cs: update for those
+
+2005-03-03 Todd Berman <tberman@off.net>
+
+ * stetic/Stetic.cs: Add a ShadowType.In to the widget TreeView.
+
+2005-03-03 Dan Winship <danw@novell.com>
+
+ * libstetic/DND.cs: static class to handle various
+ drag-and-drop-related stuff, so WidgetFactory doesn't need to
+ subclass WidgetSite, which is nice since they're not really very
+ related.
+ (SourceSet): wrapper for Gtk.Drag.SourceSet that can also set up
+ drag tracking for widgets that can't use SourceSet.
+ (DestSet, DestUnset): more wrappers
+ (CanDrag): for non automatic sources, checks if a
+ MotionNotifyEvent counts as a drag start
+ (Drag): starts a drag
+ (Drop): receives the dropped widget
+ (DragBegin, DragEnd): moved here from IStetic
+
+ * libstetic/WidgetSite.cs: remove static DND-related fields
+ (various): use DND methods rather than Gtk.Drag or IStetic ones
+ (OnButtonPressEvent): don't need to track click locations any
+ more; DND does it.
+ (OnMotionNotify): use DND.CanDrag and DND.Drag
+ (OnDragDrop): use DND.Drop
+ (OnDropEnd): don't need to call DragEnded() from here any more;
+ DND does it.
+
+ * libstetic/IStetic.cs:
+ * stetic/Project.cs: kill off the dnd-related events; they're on
+ DND now.
+
+ * stetic/WidgetFactory.cs: now a subclass of EventBox
+ (ctor): set AboveChild, call DND.SourceSet
+ (OnDragBegin): Call DND.Drag
+ (Drop): dead code since WidgetFactory isn't a drag destination any more.
+
+2005-03-02 Dan Winship <danw@novell.com>
+
+ "Autoexpand" for boxes (but not yet tables, and not 100% right
+ yet.)
+
+ * libstetic/WidgetSite.cs (AddHFault, AddVFault): allow the site
+ occupant to add "fault lines" inside the widget where it can split
+ apart to fit additional widgets
+ (ShowFaults, HideFaults): connected to the IStetic's DragBegin and
+ DragEnd signals, to show/hide the (invisible) fault line windows
+ as needed.
+ (OnDragMotion): if the user drags into a fault line, draw a
+ splitter.
+ (OnDragDrop): if the user dropped onto a fault line, emit the
+ "DropOn" event to let the child handle placing the widget.
+
+ * libstetic/WidgetBox.cs (NewWindow): make this protected so
+ WidgetSite can use it
+
+ * libstetic/IStetic.cs (DragBegin, DragEnd): new events, to
+ indicate that something somewhere is being dragged
+
+ * libstetic/wrapper/Container.cs (Sync): make this a virtual
+ method on Container
+ (ContainerChild.EmitNotify): Sync the parent
+
+ * libstetic/wrapper/Box.cs (Wrap): connect to the box's
+ SizeAllocated and ParentSet handlers
+ (Sync): add fault lines
+ (box_ParentSet): connect to the parent site's DropOn event
+ (box_SizeAllocated): Sync()
+ (DropOn): Insert the child in the right place
+
+ * libstetic/wrapper/Table.cs (Sync): add "override"
+ (TableChild.EmitNotify): don't need to call Sync from here;
+ Container does it
+
+ * stetic/Project.cs: implement the new IStetic bits
+
+ * stetic/WidgetFactory.cs (ctor): pass the project (IStetic) to
+ the WidgetSite ctor
+ (Drop): override this to get rid of the warning message when you
+ drag something from the palette but then cancel the drag
+
+ * TODO: update
+
+2005-02-28 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (HydrateProperties): Handle "adjustment"
+ properties, which glade serializes as 6 doubles separated by
+ spaces.
+
+ * libstetic/WidgetSite.cs (Selected): new event
+ (Focus): emit it
+
+ * libstetic/wrapper/ComboBox.cs (GladeImport): use CreateInstance
+ rather than calling down to base.GladeImport, so that we end up
+ with a text-only combobox. Handle the "items" property.
+ (Items): ignore trailing newlines
+
+ * libstetic/wrapper/Dialog.cs (Wrap): Put WidgetSites around the
+ VBox and ActionArea.
+
+ * libstetic/wrapper/Container.cs (FindInternalChild): make this a
+ little more complicated (read: grosser) to deal with the extra
+ WidgetSites inside a Dialog now.
+
+ * libstetic/wrapper/Expander.cs (GladeImport): Do the same label
+ widget hack as in Notebook and Frame
+
+ * libstetic/wrapper/Image.cs: if filename is "", use a "broken
+ image" image.
+
+ * libstetic/wrapper/Label.cs: add a new ctor that takes a string
+ and constructs a label with that string, and a wrapper around the
+ label.
+
+ * libstetic/wrapper/Notebook.cs: connect to the Selected event
+ on the label WidgetSites, and switch pages when a label is
+ selected.
+ (InsertPage): use the new Stetic.Wrapper.Label ctor
+
+ * libstetic/wrapper/OptionMenu.cs (Wrap): if the optionmenu has no
+ Menu, create one here rather than in FlattenMenu.
+
+ * libstetic/wrapper/Table.cs (GladeImportChild): if x_options or
+ y_options is unspecified, consider it to be "expand|fill", which
+ is glade's default value.
+ (SiteOccupancyChanged): don't adjust the cell's packing unless it
+ is set to AutoSize.
+
+ * libstetic/wrapper/Window.cs (Type): make this a shadow prop too
+
+2005-02-28 Dan Winship <danw@novell.com>
+
+ * libstetic/ObjectWrapperAttribute.cs: add a "Deprecated" flag
+
+ * libstetic/wrapper/OptionMenu.cs: New, wrap Gtk.OptionMenu, but
+ mark it with the "Deprecated" ObjectWrapperAttribute flag. Also,
+ since we don't have a menu editor yet, we just wrap it the same
+ way as ComboBox, with a multiline text entry to specify the menu
+ items.
+
+ * libstetic/wrapper/Menu.cs:
+ * libstetic/wrapper/MenuItem.cs: Wrap these just enough for
+ importing OptionMenus from glade
+
+ * libstetic/wrapper/Container.cs (GladeImportChild): if the
+ container does not accept arbitrary GtkWidget children (according
+ to Gtk.Container.ChildType()), then don't interpose a WidgetSite
+ between parent and child.
+
+ * stetic/Palette.cs (AddWidget): skip widgets with "Deprecated"
+ set on their ObjectWrapperAttribute. (Meaning that for now, they
+ can be imported, but not created by hand.)
+
+2005-02-27 Dan Winship <danw@novell.com>
+
+ * libstetic/GladeUtils.cs (ExtractProperty): utility to remove a
+ property from the propNames/propVals lists.
+ (HydrateProperties): add some debug messages here
+
+ * libstetic/wrapper/Label.cs (GladeImport): simplify using
+ ExtractProperty
+
+ * libstetic/wrapper/RadioButton.cs (GladeImport): handle "group"
+
+ * libstetic/wrapper/Table.cs (GladeImport): force a Sync after
+ import
+ (Sync): don't knock out conflicting sites if they're full (which
+ will happen temporarily during glade import, since table.Add(foo)
+ will always put it at 0,0).
+
+ * libstetic/wrapper/TextView.cs (GladeImport): handle "text"
+
+ * libstetic/wrapper/Widget.cs (GladeImport): extract "visible" and
+ "has_default"; fake out "visible", hold off on setting
+ "has_default" until the import is complete (since it requires a
+ parent window).
+
+ * libstetic/wrapper/Window.cs (Wrap): force TypeHint to "Normal"
+ so the WM doesn't do annoying things to us
+ (GladeImport): extract "modal" and "type_hint"
+ (TypeHint): add a shadow property for this
+
+ * stetic/GladeImport.cs (CreateWidget, AddChildren): merge these
+ together and reduce redundant code.
+
+2005-02-25 Dan Winship <danw@novell.com>
+
+ Reorganize the glade import code; put all the wacky exceptions
+ into the wrapper classes rather than adding more and more to
+ GladeImport itself.
+
+ * libstetic/ObjectWrapper.cs (GladeImport): static method to find
+ the wrapper type for a given class name and create a wrapper and
+ object based on glade data.
+ (Create): add a new overload using a className rather than a Type.
+
+ * libstetic/IStetic.cs: add GladeImportComplete event and
+ LookupWidgetById method.
+
+ * libstetic/GladeUtils.cs: utilities for GladeImport, etc
+
+ * libstetic/wrapper/Widget.cs (GladeImport): virtual method to
+ create widget from a glade description.
+
+ * libstetic/wrapper/Container.cs (GladeImportChild): virtual
+ method to add and pack a child widget from a glade file.
+ (AddPlaceholder): virtual method to add a placeholder
+ (GladeSetInternalChild): virtual method to set properties on an
+ internal child
+
+ * libstetic/wrapper/ButtonBox.cs (GladeImportChild): remove
+ "response_id" from the child's properties, and set the "secondary"
+ packing flag if the response_id is ResponseType.Help. This is not
+ a complete fix; we need to get the response_id back to the parent
+ Dialog somehow.
+
+ * libstetic/wrapper/Entry.cs (GladeImport): Handle the
+ "invisible_char" property.
+
+ * libstetic/wrapper/Frame.cs (GladeImportChild): handle the
+ special "label_item" child.
+
+ * libstetic/wrapper/Label.cs (GladeImport): Handle the
+ "mnemonic_widget" property.
+
+ * libstetic/wrapper/Notebook.cs (GladeImportChild): handle the
+ special "tab" child. (This is the only "new" exception so far; all
+ the others were previously handled in GladeImport.)
+
+ * stetic/Project.cs (LookupWidgetById, GladeImportComplete):
+ implement.
+
+ * stetic/GladeImport.cs: lots of code moved from here into
+ GladeUtils, ObjectWrapper, and various wrapper classes.
+
+2005-02-25 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Table.cs:
+ * libstetic/wrapper/Container.cs: move the "AutoSize" child
+ property from Table/TableChild to Container/ContainerChild. Also,
+ fix the previous fix.
+
+ * libstetic/wrapper/Box.cs: Add AutoSize child property and update
+ the SiteOccupancyChanged logic accordingly. Also remove the weird
+ code with the FIXME there, since I can't reproduce the bug anyway,
+ so either it's fixed or Todd's going to have to debug it himself.
+
+2005-02-25 Dan Winship <danw@novell.com>
+
+ * libstetic/ObjectWrapper.cs (Register): Fix the no-CreateInstance
+ case to use the *wrapped* type's ctor, not the wrapper type.
+
+ * libstetic/wrapper/Container.cs (Register): Make types whose
+ containerchild types are declared by a superclass work again.
+
+2005-02-25 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Icon.cs:
+ * libstetic/wrapper/Image.cs: Merge these two together, with a
+ bool property to switch between stock icon and pixmap behavior.
+ It's too messy to have two GtkImage wrappers.
+
+ * libstetic/ObjectWrapper.cs (Register, WrapperType): Simplify the
+ logic here for 1-1 mapping between gtk and stetic types.
+
+ * stetic/GladeImport.cs: Likewise
+
+2005-02-25 Dan Winship <danw@novell.com>
+
+ * stetic/Project.cs: implement IStetic
+
+ * stetic/GladeImport.cs: pass the Project down into CreateWidget
+ and AddChildren so they can eventually pass it to
+ ObjectWrapper.Create as an IStetic. One more FIXME down.
+
+ * stetic/Palette.cs: take a Project at construct time and pass it
+ on to WidgetFactories
+
+ * stetic/WidgetFactory.cs: take a Project at construct time and
+ pass that to new wrappers rather than implementing IStetic here.
+
+ * stetic/Stetic.cs: pass Project to the Palette
+
+ * libstetic/ObjectWrapper.cs (Create): swap the order of the
+ arguments
+
+ * libstetic/wrapper/Container.cs (ChildWrapper): update for
+ ObjectWrapper.Create change
+
+2005-02-24 Dan Winship <danw@novell.com>
+
+ * libstetic/ObjectWrapper.cs: remove the protected (IStetic,
+ object) constructor and replace it with a virtual Wrap method.
+ (Register): new method to register a wrapper type
+ (Create): new method to create a wrapper of a given type (with
+ either a provided widget or a fresh one).
+ (AddItemGroup): replaces RegisterWrapper. Adds a single ItemGroup
+ to the type.
+ (AddContextMenuItems): replaces RegisterContextMenu
+
+ * libstetic/ObjectWrapperAttribute.cs: remove the WrappedType
+ again; it's now a static property on the wrapper.
+
+ * libstetic/ItemGroup.cs (ItemGroup): fix this to not lose if
+ passed a wrapperType and a dotted property
+
+ * libstetic/wrapper/*.cs: update for the NWO:
+ * ObjectWrapperAttribute only takes 3 args again
+ * Add static WrappedType property to all wrappers
+ * Add static CreateInstance method to all wrappers that
+ need to do more than just "new Gtk.Foo ()"
+ * Replace static ctor with static Register method
+ using AddItemGroup/AddContextMenuItems
+ * Replace instance ctors with a Wrap override
+
+ * stetic/GladeImport.cs:
+ * stetic/Palette.cs:
+ * stetic/PropertyGrid.cs:
+ * stetic/WidgetFactory.cs: Update to match ObjectWrapper changes
+
+2005-02-24 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Dialog.cs:
+ * libstetic/wrapper/Window.cs (Modal): wrap this and don't set the
+ underlying window property
+
+ * libstetic/wrapper/Widget.cs (Visible): wrap this property and
+ don't set the underlying widget property for Window subclasses.
+
+ * stetic/GladeImport.cs (Load): set doc.PreserveWhitespace so that
+ things like '<property name="label"> </property>' (which is
+ used to indent HIG-style frames) import correctly. Don't crash if
+ CreateWidget returns null.
+ (CreateWidget): Add some debug messages, prevent a g_warning if
+ the glade file uses types we don't wrap.
+ (AddChildren): Add a hack to make "Help" buttons be packed with
+ the "secondary" property in ButtonBoxes, the same as glade does.
+ (HydrateProperties): Don't need to filter out Window.Visible any
+ more.
+
+2005-02-22 Dan Winship <danw@novell.com>
+
+ * stetic/PropertyGrid.cs: Kill ChildPropertyGrid and make the
+ child properties appear as just another property group in the main
+ Properties window.
+
+ * stetic/Stetic.cs (Main): clean this up a little, and reorganize
+ (palette on the left, project + properties on the right). Also
+ update for PropertyGrid changes.
+
+ * stetic/Palette.cs: fix up code style, make "Widgets" appear
+ before "Containers", remove some commented out code
+
+2005-02-22 Everaldo Canuto <everaldo_canuto@yahoo.com.br>
+
+ * stetic/Palette.cs: New palette GUI.
+
+2005-02-22 Todd Berman <tberman@off.net>
+
+ * libstetic/wrapper/Button.cs:
+ * libstetic/wrapper/ToggleButton.cs:
+ * libstetic/wrapper/VScale.cs:
+ * libstetic/wrapper/Label.cs:
+ * libstetic/wrapper/TextView.cs:
+ * libstetic/wrapper/Container.cs:
+ * libstetic/wrapper/Widget.cs:
+ * libstetic/wrapper/VSeparator.cs:
+ * libstetic/wrapper/Paned.cs:
+ * libstetic/wrapper/Icon.cs:
+ * libstetic/wrapper/Box.cs:
+ * libstetic/wrapper/ProgressBar.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/ComboBoxEntry.cs:
+ * libstetic/wrapper/EventBox.cs:
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/HPaned.cs:
+ * libstetic/wrapper/ScrolledWindow.cs:
+ * libstetic/wrapper/HBox.cs:
+ * libstetic/wrapper/SpinButton.cs:
+ * libstetic/wrapper/Window.cs:
+ * libstetic/wrapper/ComboBox.cs:
+ * libstetic/wrapper/ColorButton.cs:
+ * libstetic/wrapper/VPaned.cs:
+ * libstetic/wrapper/Alignment.cs:
+ * libstetic/wrapper/VBox.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/Image.cs:
+ * libstetic/wrapper/ButtonBox.cs:
+ * libstetic/wrapper/DrawingArea.cs:
+ * libstetic/wrapper/Scale.cs:
+ * libstetic/wrapper/Table.cs:
+ * libstetic/wrapper/Arrow.cs:
+ * libstetic/wrapper/TreeView.cs:
+ * libstetic/wrapper/Misc.cs:
+ * libstetic/wrapper/HScrollbar.cs:
+ * libstetic/wrapper/HButtonBox.cs:
+ * libstetic/wrapper/Range.cs:
+ * libstetic/wrapper/HScale.cs:
+ * libstetic/wrapper/Dialog.cs:
+ * libstetic/wrapper/Entry.cs:
+ * libstetic/wrapper/FontButton.cs:
+ * libstetic/wrapper/MessageDialog.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/HSeparator.cs:
+ * libstetic/wrapper/Bin.cs:
+ * libstetic/wrapper/Statusbar.cs:
+ * libstetic/wrapper/Calendar.cs:
+ * libstetic/wrapper/CheckButton.cs:
+ * libstetic/wrapper/VScrollbar.cs:
+ * libstetic/wrapper/VButtonBox.cs:
+
+ Move to a 3 param'd ctor, to provide initialized information
+ Add a Site property in Bin.
+ Add a 4th parameter to the ObjectWrapperAttributes to show which
+ gtk# type is wrapped.
+ Dummy TreeView wrapper.
+
+ * libstetic/ObjectWrapperAttribute.cs: New parameter to show which
+ gtk# type is wrapped.
+
+ * libstetic/Makefile.am: Add wrapper/TreeView.cs
+
+ * libstetic/ObjectWrapper.cs: Add LookupWrappedTypes, to return a
+ Type[] of the Stetic.Wrapper.* classes that wrap a given gtk# type.
+
+ * TODO: Update.
+
+ * stetic/WidgetFactory.cs: Make sure to hit wrappedObject.GType so
+ that GObject stuff is properly initialized.
+
+ * stetic/Stetic.cs: Change the GUI around a bit.
+
+ * stetic/Palette.cs: New palette GUI.
+
+ * stetic/Makefile.am: Add GladeImport.cs.
+
+ * stetic/Project.cs: Add Project.Clear ();
+
+ * stetic/GladeImport.cs: New file, used to provide glade file
+ importation.
+
+ * glue/Makefile.am: Add value.c
+ * glue/value.c: New glue file to help with interacting with GValues,
+ and used in the GladeImport process.
+
+2005-02-22 Dan Winship <danw@novell.com>
+
+ * TODO: New
+
+2005-02-22 Everaldo Canuto <everaldo_canuto@yahoo.com.br>
+
+ * libstetic/wrapper/pixmaps/alignment.png: new icon converted fron xpm.
+ * libstetic/wrapper/pixmaps/eventbox.png: new icon converted fron xpm.
+ * libstetic/wrapper/pixmaps/progressbar.png: new icon converted fron xpm.
+ * libstetic/wrapper/pixmaps/statusbar.png: new icon converted fron xpm.
+
+2005-02-19 Dan Winship <danw@novell.com>
+
+ * libstetic/WidgetBox.cs (PopupContextMenu): new event to mean
+ "pop up a context menu for some reason", which could be because of
+ a keypress or button press in either the widgetbox itself or its
+ child.
+ (InterceptButtonPress, OnButtonPressEvent): Handle this stuff here
+ rather than passing it off to WidgetSite.
+
+ * stetic/WidgetSite.cs:
+ * libstetic/WidgetSite.cs: move stetic/WidgetSite.cs to libstetic,
+ minus the very very small amount that depended on other things in
+ stetic/.
+
+ * libstetic/WindowSite.cs: split this out of WidgetSite.cs
+
+ * stetic/WidgetFactory.cs (CreateWidgetSite): connect to the
+ site's PopupContextMenu event.
+
+2005-02-18 Dan Winship <danw@novell.com>
+
+ * libstetic/TranslatableAttribute.cs: new attribute to mark a
+ string property of an attribute as being translatable.
+
+ * libstetic/ObjectWrapperAttribute.cs (Name): add
+ TranslatableAttribute to this property
+
+ * libstetic/CommandAttribute.cs: add a Description field, and mark
+ the Label and Description as Translatable.
+
+ * libstetic/CommandDescriptor.cs: extract description from
+ CommandAttribute and make it available via the Description field
+
+ * libstetic/DescriptionAttribute.cs: new attribute to give a
+ translatable label and description for a property.
+
+ * libstetic/PropertyDescriptor.cs: extract label and description
+ info from ParamSpecs or DescriptionAttributes, and make them
+ available via the Label and Description fields
+
+ * libstetic/wrapper/Box.cs:
+ * libstetic/wrapper/Button.cs:
+ * libstetic/wrapper/ComboBox.cs:
+ * libstetic/wrapper/Icon.cs:
+ * libstetic/wrapper/MessageDialog.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/Table.cs:
+ * libstetic/wrapper/TextView.cs: add descriptions to commands and
+ properties
+
+ * stetic/Grid.cs (AppendPair, Append): add overloads that take a
+ "description" arg, and set up tooltips.
+
+ * stetic/PropertyGrid.cs (AppendProperty, AppendCommand): Pass the
+ descriptions from the ItemDescriptors to the underlying Grid
+ methods
+
+2005-02-17 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Container.cs (RegisterWrapper): override the
+ base RegisterWrapper method and scan the type for a
+ Stetic.Wrapper.Container.ContainerChild subclass, and if found,
+ remember it as the class's child wrapper class.
+ (RegisterChildItems, ChildItemGroups): Gone now
+ (ChildWrapper): Creates a child property wrapper for a WidgetSite
+ (class ContainerChild): ObjectWrapper implementation for wrapping
+ Gtk.Container.ContainerChild
+ (CreateWidgetSite): Now an override of Widget's
+ (HExpandable, VExpandable): moved to Widget
+
+ * libstetic/wrapper/Widget.cs (CreateWidgetSite, HExpandable,
+ VExpandable): moved here from Container, with non-Container base
+ implementations.
+
+ * libstetic/wrapper/Table.cs: implement a ContainerChild subclass
+ and use it to implement AutoSize again. Also, split XOptions and
+ YOptions into multiple bools.
+
+ * libstetic/wrapper/Box.cs: implement a ContainerChild subclass.
+ (SiteOccupancyChanged): when adding a new widget, set Expand and
+ Fill correctly according to its expandability
+
+ * libstetic/wrapper/ButtonBox.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/Paned.cs: implement a ContainerChild subclass.
+
+ * libstetic/wrapper/Bin.cs:
+ * libstetic/wrapper/Dialog.cs:
+ * libstetic/wrapper/ScrolledWindow.cs:
+ * libstetic/wrapper/Window.cs: make Bin better able to deal with
+ subclasses that create their own WidgetSites.
+
+ * libstetic/wrapper/Scrollbar.cs: kill this. HScrollbar and
+ VScrollbar can inherit directly from Range.
+
+ * libstetic/wrapper/HScale.cs (HExpandable):
+ * libstetic/wrapper/HScrollbar.cs (HExpandable):
+ * libstetic/wrapper/HSeparator.cs (HExpandable):
+ * libstetic/wrapper/VScale.cs (VExpandable):
+ * libstetic/wrapper/VScrollbar.cs (VExpandable):
+ * libstetic/wrapper/VSeparator.cs (VExpandable): return true
+
+ * libstetic/CommandDescriptor.cs:
+ * libstetic/ItemDescriptor.cs:
+ * libstetic/PropertyDescriptor.cs: s/object/ObjectWrapper/ in
+ several parts of the API now that ContainerChildren have
+ ObjectWrappers.
+
+ * stetic/ContextMenu.cs
+ * stetic/PropertyGrid.cs:
+ * stetic/PropertyEditor.cs: update for that
+
+ * libstetic/IStetic.cs:
+ * libstetic/WidgetSite.cs: remove the 2-arg CreateWidgetSite
+ method from IStetic and add an "EmptySize" property to WidgetSite
+ instead.
+
+ * stetic/WidgetFactory.cs:
+ * stetic/WidgetSite.cs: update for CreateWidgetSite/EmptySize
+ changes
+
+ * libstetic/Set.cs: convenience class used by Table.
+
+2005-02-17 Dan Winship <danw@novell.com>
+
+ * libstetic/ObjectWrapper.cs (RegisterWrapper): Renamed from
+ RegisterItems.
+
+ * libstetic/wrapper/*.cs: update for that
+
+ * stetic/Stetic.cs: Put all of the windows into a single notebook.
+ Probably not the best layout, but I'm getting sick of the multiple
+ windows...
+
+2005-02-16 Dan Winship <danw@novell.com>
+
+ * stetic/Grid.cs (Connect): static method to connect multiple
+ grids so they have the same column widths.
+ (OnSizeRequested, OnSizeAllocated): update for that
+
+ * stetic/Stetic.cs (Main): Connect the Properties and
+ ChildProperties grids.
+
+2005-02-15 Dan Winship <danw@novell.com>
+
+ * libstetic/ObjectWrapper.cs: split out parts of
+ libstetic/wrapper/Object.cs into this.
+ (RegisterItems, RegisterContextMenu): static methods to register
+ property grid and context menu items for a wrapper type.
+ (ItemGroups, ContextMenuItems): these can be implemented here now
+ rather than needing to be abstract and then reimplemented by each
+ class.
+
+ * libstetic/wrapper/Object.cs: simplified since most of it is in
+ ObjectWrapper.cs now.
+
+ * libstetic/wrapper/Container.cs: parallel some of the
+ ObjectWrapper stuff for child properties
+
+ * libstetic/wrapper/*: update for new (simplified) itemgroup
+ handling.
+
+ * stetic/PropertyGrid.cs (Notified): update prototype
+
+2005-02-14 Dan Winship <danw@novell.com>
+
+ * libstetic/editor/GroupPicker.cs: property editor for a
+ user-extensible list of strings
+
+ * libstetic/wrapper/RadioButton.cs: use GroupPicker for the Group,
+ and translate that into Gtk's terms.
+
+2005-02-14 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Widget.cs (Widget): Set the Name property
+ (based on the class name and a per-class counter).
+
+ * libstetic/wrapper/Button.cs:
+ * libstetic/wrapper/CheckButton.cs:
+ * libstetic/wrapper/Expander.cs:
+ * libstetic/wrapper/Frame.cs:
+ * libstetic/wrapper/Label.cs:
+ * libstetic/wrapper/RadioButton.cs:
+ * libstetic/wrapper/ToggleButton.cs:
+ * libstetic/wrapper/Window.cs: use the widget name for the default
+ label/title
+
+ * libstetic/wrapper/Notebook.cs: Use real
+ wrapped-labels-in-WidgetSites for the notebook tabs.
+
+ * stetic/WidgetFactory.cs: remove widget naming stuff from here
+
+ * stetic/Grid.cs (OnSizeRequested, OnSizeAllocated): fix layout of
+ misc widgets (ie, command buttons)
+
+2005-02-14 Dan Winship <danw@novell.com>
+
+ * libstetic/wrapper/Range.cs:
+ * libstetic/wrapper/Scale.cs: proxy notifications from the
+ Adjustment so that the PropertyGrid will reflect manual changes to
+ the widget's value
+
+2005-02-14 Dan Winship <danw@novell.com>
+
+ * libstetic/RangeAttribute.cs: new attribute for specifying the
+ range of a property.
+
+ * libstetic/EditorAttribute.cs: local replacement for
+ System.ComponentModel.EditorAttribute
+
+ * libstetic/PropertyDescriptor.cs: update to look for
+ Stetic.EditorAttribute rather than
+ System.ComponentModel.EditorAttribute, and handle
+ Stetic.RangeAttribute too.
+ (PropertyInfo): property to return the underlying PropertyInfo
+ (Minimum, Maximum): new, set from RangeAttribute
+ (CanRead): Gone. We never really supported write-only properties.
+
+ * stetic/PropertyEditor.cs (MakeEditor): use the
+ PropertyDescriptor's Minimum and Maximum if available.
+ (BasicEditor.BasicEditor): Use the property's PropertyInfo rather
+ than its type as the "special" constructor used for enumerations,
+ etc. This will let us have a few more special editor types. Don't
+ bother trying to find a ctor that takes an initial value; it's
+ easy enough to just set it post-construction.
+
+ * libstetic/editor/Enumeration.cs: Change the Type ctor to take a
+ PropertyInfo instead.
+
+ * libstetic/editor/Text.cs: Use a PropertyInfo ctor, and check if
+ there's an EditorAttribute with an EditorSize specified, and use
+ that to set the textview's size if so.
+
+ * libstetic/editor/Boolean.cs:
+ * libstetic/editor/Char.cs:
+ * libstetic/editor/Color.cs:
+ * libstetic/editor/File.cs:
+ * libstetic/editor/FloatRange.cs:
+ * libstetic/editor/IntRange.cs:
+ * libstetic/editor/OptIntRange.cs:
+ * libstetic/editor/StockItem.cs:
+ * libstetic/editor/String.cs: Remove "initial" arg from ctor.
+
+ * libstetic/wrapper/ComboBox.cs (Items):
+ * libstetic/wrapper/Icon.cs (Stock):
+ * libstetic/wrapper/Image.cs (File):
+ * libstetic/wrapper/TextView.cs (Text): use new EditorAttribute
+
+ * libstetic/wrapper/Button.cs (StockId): use new EditorAttribute.
+ Remove unused DefaultValueAttribute.
+
+ * libstetic/wrapper/ColorButton.cs (Alpha): Use RangeAttribute to
+ create a new Alpha property that combines the underlying UseAlpha
+ and Alpha properties into a single "optional int range".
+
+2005-02-13 Dan Winship <danw@novell.com>
+
+ * libstetic/CommandDescriptor.cs: like PropertyDescriptor, but
+ describes commands implemented by the widget wrapper (which, like
+ properties, can become sensitive and insensitive depending on
+ other properties)
+
+ * libstetic/CommandAttribute.cs: attribute for marking methods
+ that will be referred to via CommandDescriptors
+
+ * libstetic/IContextMenuProvider.cs: Gone, this functionality is
+ part of CommandDescriptor now.
+
+ * libstetic/ItemDescriptor.cs: abstract subclass for
+ PropertyDescriptor and CommandDescriptor
+
+ * libstetic/PropertyDescriptor.cs: make this a subclass of
+ ItemDescriptor
+
+ * libstetic/ItemGroup.cs: formerly PropertyGroup, but now can hold
+ any ItemDescriptor.
+
+ * libstetic/wrapper/Object.cs: add a ContextMenuItems property,
+ empty by default.
+
+ * libstetic/wrapper/*.cs: update for Item changes
+
+ * libstetic/wrapper/Button.cs: implement "Remove Button Contents"
+ and "Restore Button Label" as Commands. Add dummy properties
+ HasLabel and HasContents for them to depend on.
+
+ * libstetic/wrapper/Box.cs:
+ * libstetic/wrapper/Notebook.cs:
+ * libstetic/wrapper/Table.cs: change IContextMenuItemProvider
+ stuff to use the new Command stuff
+
+ * libstetic/wrapper/ComboBox.cs: replace Model property with a
+ multi-line-text Items property
+
+ * libstetic/wrapper/ComboBoxEntry.cs: new wrapper
+
+ * libstetic/wrapper/Window.cs: on a DeleteEvent, just hide the window
+
+ * stetic/Grid.cs: Allow adding of arbitrary widgets in addition to
+ the property name/editor pairs.
+
+ * stetic/PropertyGrid.cs: Implement CommandDescriptors by adding
+ buttons to the Grid.
+
+ * stetic/ContextMenu.cs: update for CommandDescriptor stuff
+
+ * stetic/PropertyEditor.cs (EditorValueChanged, Update): Fix this
+ again to avoid updating loops
+
+ * stetic/WidgetSite.cs (WindowSite.Select): Show() the window, in
+ case it was hidden
+
+2005-02-13 Dan Winship <danw@novell.com>
+
+ * libstetic/ParamSpec.cs (gtksharp_get_type_id): Fix the library
+ name in the DllImport attribute
+
+2005-02-11 Dan Winship <danw@novell.com>
+
+ * stetic/Grid.cs: new base class for PropertyGrid. Instead of
+ being a VBox of Expanders, its now a subclass of Container which
+ lays out its contents by hand; this makes it much easier to make
+ everything end up with the size and location we want (particularly
+ in the presence of multi-line editors).
+
+ * stetic/PropertyGrid.cs: Update to be a subclass of Grid
+
+ * libstetic/editor/Text.cs: TextView-based multi-line text editor
+
+ * libstetic/wrapper/TextView.cs: mark the "Text" property as
+ wanting the "Text" editor type. Proxy the TextView's Buffer's
+ "Changed" event so that the property editor will track typing in
+ the widget.
+
+ * stetic/WidgetSite.cs (OnMotionNotifyEvent): force the dragWindow
+ to be at least 20x20, so that widgets that make very small
+ requests expecting to be allocated much more space (eg, TextView)
+ aren't invisible when dragged.
+
+2005-02-09 Dan Winship <danw@novell.com>
+
+ * libstetic/editor/Color.cs: add an editor for Gdk.Color-valued
+ properties
+
+ * stetic/PropertyEditor.cs: Use it
+
+ * stetic/PropertyGrid.cs:
+ * stetic/Stetic.cs: re-enable child packing property page
+
+2005-02-09 Dan Winship <danw@novell.com>
+
+ * Major reorg again... Now instead of having the widget wrappers
+ be subclasses of the types they wrap, they are a parallel set of
+ classes. This lets them share code between each other more easily
+ than before. Touches nearly every file. Also, update to use
+ GLib.Object.AddNotification rather than our own notify hack.
+
+2005-01-27 Dan Winship <danw@novell.com>
+
+ * stetic/ProjectView.cs: TreeView subclass for displaying the
+ widget tree.
+
+ * stetic/Project.cs: model for ProjectView
+
+ * stetic/Palette.cs (IconForType): Split this code out so the
+ Project window can make use of it too.
+
+ * stetic/Stetic.cs (Main): Create a "Project" window. Some day
+ there will be windows whose names don't start with "P".
+
+ * stetic/WidgetSite.cs: s/ExpandabilityChanged/ContentsChanged/
+
+ * stetic/WidgetFactory.cs (WidgetFactory, Create): set the widget
+ Name property, a la glade
+ (WindowFactory.OnButtonPressEvent): call
+ SteticMain.Project.AddWindow()
+
+ * libstetic/IContainerWrapper.cs: subclass IWidgetWrapper, not
+ IObjectWrapper.
+ (ContentsChanged): new event that replaces ExpandabilityChanged
+
+ * libstetic/IWindowWrapper.cs: subclass IContainerWrapper, not
+ IObjectWrapper
+
+ * libstetic/SiteContentEnumerator.cs: IEnumerator to enumerate the
+ real widget children of a container (rather than its WidgetSites)
+
+ * widgets/*.cs: s/ExpandabilityChanged/ContentsChanged/
+
+ * widgets/Dialog.cs:
+ * widgets/MessageDialog.cs:
+ * widgets/Window.cs: Implement ContentsChanged
+
+ * widgets/Paned.cs (Paned): fix a bug in the shared Paned
+ properties
+
+ * widgets/ToggleButton.cs (ToggleButton): Initialize "label"
+
+2005-01-25 Dan Winship <danw@novell.com>
+
+ * libstetic/IWidgetWrapper.cs: New dummy subclass of
+ IObjectWrapper
+
+ * libstetic/WidgetBox.cs: Implement OnSetScrollAdjustments (by
+ passing them on to the child). Needed for ScrolledWindow.
+
+ * widgets/Alignment.cs:
+ * widgets/EventBox.cs:
+ * widgets/Expander.cs:
+ * widgets/ScrolledWindow.cs: Wrap these
+
+ * widgets/*.cs: s/IObjectWrapper/IWidgetWrapper/
+
+ * stetic/WidgetSite.cs (ParentSite): Deal with the fact that the
+ immediate parent won't be a WidgetSite in a few cases.
+
+ * stetic/Palette.cs (AddWidgets): Look for IWidgetWrapper, not
+ IObjectWrapper.
+
+2005-01-20 Dan Winship <danw@novell.com>
+
+ * libstetic/IWindowWrapper.cs: new (empty) interface
+
+ * libstetic/WidgetWrapperAttribute.cs (WidgetType): gone; we can
+ distinguish widget wrappers based on whether they implement
+ IWindowWrapper, IContainerWrapper, or just IObjectWrapper.
+
+ * widgets/*.cs: remove WidgetType declarations from containers and
+ windows.
+
+ * widgets/Dialog.cs:
+ * widgets/Window.cs: Remove IContainerWrapper junk that wasn't
+ being used anyway.
+
+ * widgets/Calendar.cs:
+ * widgets/FontButton.cs:
+ * widgets/MessageDialog.cs: new wrappers
+
+ * widgets/pixmaps/curve.png:
+ * widgets/pixmaps/gammacurve.png:
+ * widgets/pixmaps/hruler.png:
+ * widgets/pixmaps/inputdialog.png:
+ * widgets/pixmaps/selector.png:
+ * widgets/pixmaps/vruler.png: Kill off some glade icons we won't
+ be using
+
+ * stetic/Palette.cs: Update for WidgetType going away, and
+ reorganize into two columns
+
+2005-01-20 Dan Winship <danw@novell.com>
+
+ * Move 90% of the files in the repository somewhere else.
+
+ * libstetic/: classes needed by both Stetic itself and widget
+ wrapper implementations
+
+ * libstetic/editor/: moved from stetic/editor
+
+ * widgets/: moved from stetic/wrapper and modified a bit to only
+ require libstetic. (In particular, all the wrappers now have
+ constructors that take an IStetic object which can be used to
+ create new WidgetSites)
+
+ * widgets/pixmaps: moved from pixmaps/
+
+ * stetic/: now just the app itself, which links to libstetic and
+ dynamically loads libsteticwidgets.
+
+2005-01-20 Dan Winship <danw@novell.com>
+
+ * stetic/IObjectWrapper.cs (PropertyGroup): Make this take a
+ varargs list of property names and build the PropertyDescriptors
+ itself, to cut down on the amount of work the wrappers need to do.
+ Also add an indexer to retrieve a PropertyDescriptor by name.
+ (IPropertySensitizer): Gone
+
+ * stetic/PropertyDescriptor.cs: Update the ctor for how
+ PropertyGroup uses it now.
+ (DependsOn, DependsInverselyOn, Dependencies,
+ InverseDependencies): stuff to specify/probe inter-property
+ dependencies, to replace the old IPropertySensitizer stuff more
+ simply.
+
+ * stetic/PropertyGrid.cs: Replace IPropertySensitizer stuff with
+ PropertyDescriptor.Dependencies, etc
+
+ * stetic/Palette.cs (AddWidgets): Catch exceptions from the
+ Gdk.Pixbuf ctor and use the "broken image" image instead if it
+ can't load the wrapper's specified image.
+
+ * stetic/wrapper/*.cs: Update for new, simpler PropertyGroup
+ creation and inter-property sensitivity settings.
+
+ * stetic/wrapper/ColorButton.cs:
+ * stetic/wrapper/HScale.cs:
+ * stetic/wrapper/ProgressBar.cs:
+ * stetic/wrapper/Scale.cs:
+ * stetic/wrapper/Statusbar.cs:
+ * stetic/wrapper/VScale.cs: New wrappers
+
+ * pixmaps/missing.png: "missing image" pixmap to use for now for
+ widgets I don't have an icon for.
+
+2005-01-14 Dan Winship <danw@novell.com>
+
+ * stetic/PropertyEditor.cs (BasicEditor.EditorValueChanged,
+ BasicEditor.Update, RangeEditor.EditorValueChanged,
+ RangeEditor.Update): Ignore EditorValueChanged if we're inside an
+ Update, since it's just reflecting the change we're already
+ making. Indirectly fixes a problem with deleting characters in an
+ Entry.
+
+ * stetic/wrapper/Arrow.cs: Add Misc.MiscProperties
+
+ * stetic/wrapper/Button.cs: Implement IContextMenuProvider.
+ (ContextMenuItems): Return a context menu with "Remove Button
+ Contents" and "Restore Button Label" items, properly sensitized.
+ (RemoveContents, RestoreLabel): Implement those.
+ (InsensitiveProperties): Update to deal with RemoveContents
+
+ * stetic/wrapper/CheckButton.cs:
+ * stetic/wrapper/RadioButton.cs: Add missing "Label" property plus
+ Button.ButtonExtraProperties
+
+ * stetic/editor/Enumeration.cs: Don't show the enumeration values
+ in the menu.
+
+ * stetic/editor/FloatRange.cs: Show 2 decimal digits
+
+2005-01-14 Dan Winship <danw@novell.com>
+
+ * stetic/WidgetBox.cs: Remove InterceptEvents property and
+ EventWindow. Instead, ConnectBefore to the child's
+ ButtonPressEvent. (This should help to deal with
+ non-container-like containers. Eg, GtkButton if you replace the
+ label widget with something else.)
+ (OnChildButtonPress): called when a button press is intercepted on
+ the child widget
+
+ * stetic/WidgetSite.cs: Update for WidgetBox changes.
+ (OnChildButtonPress): Handle context menu or focus grabbing as
+ needed
+ (StartDrag): Change this to take an EventMotion arg. Return false
+ if the event window isn't the WidgetBox's HandleWindow. (ie, don't
+ allow drags from the widget itself any more, only from its
+ handles).
+
+ * stetic/WidgetFactory.cs (StartDrag): add evt arg
+
+2005-01-13 Dan Winship <danw@novell.com>
+
+ * stetic/ContextMenu.cs (ContextMenuItem): add an "Enabled" field
+ and a ctor to set it
+ (ContextMenu): obey the "Enabled" field on IContextMenuProvider
+ items
+ (IContextMenuProvider): Turn ContextMenuItems from a property to a
+ procedure, so we can pass the context item to it
+
+ * stetic/wrapper/Notebook.cs: update for IContextMenuProvider
+ change. Disable items (eg, "Go To Previous Page") as appropriate.
+
+ * stetic/wrapper/HBox.cs:
+ * stetic/wrapper/VBox.cs:
+ * stetic/wrapper/Table.cs: update for IContextMenuProvider change
+
+2005-01-13 Dan Winship <danw@novell.com>
+
+ * stetic/WidgetSite.cs (EmptySize): new property to set the site's
+ size when empty
+ (set_Occupancy): Use that rather than hardcoding 10x10
+ (WidgetSite): New ctor to set EmptySize
+
+ * stetic/wrapper/Window.cs: Use the new WidgetSite ctor rather
+ than overriding OnSizeRequested
+
+ * stetic/wrapper/Dialog.cs: Use the new WidgetSite ctor
+
+2005-01-13 Dan Winship <danw@novell.com>
+
+ * stetic/Stetic.cs: Rename the main class from "Stetic" to
+ "SteticMain", to work around really annoying C# semantics
+
+ * stetic/WidgetFactory.cs (WindowFactory.OnButtonPressEvent):
+ update for that
+
+2005-01-13 Dan Winship <danw@novell.com>
+
+ * stetic/WidgetFactory.cs (WidgetFactoryAttribute): gone, turned
+ into WidgetWrapperAttribute
+ (WidgetFactory, WindowFactory): Take a Type directly rather than a
+ WidgetFactoryDelegate.
+
+ * stetic/WidgetWrapperAttribute.cs: replaces
+ WidgetFactoryAttribute, but basically the same thing
+
+ * stetic/Palette.cs (AddWidgets): Take an Assembly rather than a
+ Type, and search for all Types in that Assembly with a
+ WidgetWrapperAttribute.
+
+ * stetic/Stetic.cs (Main): Update call to Palette.AddWidgets
+
+ * stetic/wrapper/DefaultWidgets.cs: Gone
+
+ * stetic/wrapper/Dialog.cs:
+ * stetic/wrapper/Notebook.cs:
+ * stetic/wrapper/TextView.cs:
+ * stetic/wrapper/ToggleButton.cs: wrap these
+
+ * stetic/wrapper/*.cs: add WidgetWrapper attributes, make sure
+ every class has a no-arg constructor
+
+2005-01-13 Dan Winship <danw@novell.com>
+
+ * stetic/ContextMenu.cs (IContextMenuProvider): New interface for
+ widget wrappers that want to add items to their context menus.
+ (ContextMenu): support IContextMenuProvider.
+
+ * stetic/IObjectWrapper.cs (IPropertySensitizer): Make
+ InsensitiveProperties a property rather than a method
+
+ * stetic/PropertyDescriptor.cs (PropertyDescriptor): Add a new
+ constructor for "proxy" descriptors, which get a ParamSpec from
+ the base class, but use the property on the derived class. Also,
+ if the passed-in propertyName is invalid, throw an
+ ArgumentException with a useful message rather than causing a
+ NullArgumentException later.
+
+ * stetic/PropertyGrid.cs (SetupSensitivity): Update for
+ InsensitiveProperties change
+
+ * stetic/WidgetSite.cs: Update for ContextMenu ctor change
+
+ * stetic/wrapper/Button.cs: Use a proxy PropertyDescriptor for
+ "Label", update InsensitiveProperties.
+
+ * stetic/wrapper/ComboBox.cs: Fix a crasher typo noted by Peter
+ Williams.
+
+ * stetic/wrapper/Icon.cs: Use proxy PropertyDescriptors for Stock
+ and IconSize.
+
+ * stetic/wrapper/HBox.cs:
+ * stetic/wrapper/VBox.cs: Implement IContextMenuProvider, adding
+ "Insert Before" and "Insert After" commands.
+
+ * stetic/wrapper/Table.cs: Implement IContextMenuProvider, adding
+ "Insert Row/Column Before/After" and "Delete Row/Column". Use
+ proxy PropertyDescriptors for NRows and NColumns since the base
+ properties won't let you remove non-empty rows/columns. Update
+ InsensitiveProperties.
+
+ * stetic/stetic.in: If command-line args are passed, pass them to
+ mono (since stetic doesn't take any arguments at the moment, and I
+ use mono --trace a lot).
+
+2005-01-12 Dan Winship <danw@novell.com>
+
+ * stetic/PropertyGrid.cs: Reorganize stuff so that ContainerChild
+ classes can override properties and implement IPropertySensitizer
+ as well.
+
+ * stetic/IDesignTimeContainer.cs:
+ * stetic/IObjectWrapper.cs (IContainerWrapper): Move the things
+ that used to be in IDesignTimeContainer to IContainerWrapper. Kill
+ IDesignTimeContainer.
+
+ * stetic/WidgetSite.cs: Update for that
+
+ * stetic/wrapper/Frame.cs:
+ * stetic/wrapper/HBox.cs:
+ * stetic/wrapper/HButtonBox.cs:
+ * stetic/wrapper/HPaned.cs:
+ * stetic/wrapper/VBox.cs:
+ * stetic/wrapper/VButtonBox.cs:
+ * stetic/wrapper/VPaned.cs:
+ * stetic/wrapper/Window.cs: Update
+
+ * stetic/wrapper/Table.cs: Update.
+ (TableChild) Subclass Gtk.Table.TableChild with an "AutoSize"
+ property saying whether or not to automatically adjust the packing
+ of child widgets (defaults to on). Also implement
+ IPropertySensitizer.
+ (Sync): Update for that.
+
+2005-01-12 Dan Winship <danw@novell.com>
+
+ * stetic/IObjectWrapper.cs (IContainerWrapper): new interface a la
+ IObjectWrapper, but including child properties as well.
+
+ * stetic/PropertyGrid.cs (ChildPropertyGrid): Use IContainerWrapper
+
+ * stetic/wrapper/Box.cs:
+ * stetic/wrapper/ButtonBox.cs:
+ * stetic/wrapper/Paned.cs: add static child PropertyGroups
+
+ * stetic/wrapper/HBox.cs:
+ * stetic/wrapper/HButtonBox.cs:
+ * stetic/wrapper/HPaned.cs:
+ * stetic/wrapper/Table.cs:
+ * stetic/wrapper/VBox.cs:
+ * stetic/wrapper/VButtonBox.cs:
+ * stetic/wrapper/VPaned.cs: Implement IContainerWrapper, add child
+ PropertyGroups
+
+ * stetic/wrapper/Frame.cs:
+ * stetic/wrapper/Window.cs: Implement IContainerWrapper, but
+ return an empty ChildPropertyGroups
+
+2005-01-11 Dan Winship <danw@novell.com>
+
+ * stetic/WidgetBox.cs (WidgetBox, OnRealized): Use WidgetFlags
+ property instead of Obsolete Flags.
+ (ShowHandles, OnRealized, OnExposeEvent): Set the Background of
+ the HandleWindow to black when creating it, rather than filling in
+ the foreground in OnExposeEvent.
+ (OnSizeAllocated): Don't set HandleAllocation here, since the
+ window may not have been realized yet, which would make
+ TranslateCoordinates not work.
+ (ShapeHandles): Figure out HandleAllocation here.
+
+2005-01-07 Dan Winship <danw@novell.com>
+
+ * stetic/wrapper/Image.cs: wrapper for Gtk.Images that show files
+
+ * stetic/wrapper/Icon.cs: wrapper for Gtk.Images that show stock icons
+
+ * stetic/wrapper/SpinButton.cs: wrapper for Gtk.SpinButton
+
+ * stetic/wrapper/Frame.cs:
+ * stetic/wrapper/HBox.cs:
+ * stetic/wrapper/HButtonBox.cs:
+ * stetic/wrapper/HPaned.cs:
+ * stetic/wrapper/VBox.cs:
+ * stetic/wrapper/VButtonBox.cs:
+ * stetic/wrapper/VPaned.cs:
+ * stetic/wrapper/Table.cs:
+ * stetic/wrapper/Window.cs: Implement IObjectWrapper on these
+ (previously they just implemented IDesignTimeContainer)
+
+ * stetic/wrapper/Box.cs:
+ * stetic/wrapper/ButtonBox.cs:
+ * stetic/wrapper/Paned.cs: static classes that define
+ PropertyDescriptors used by their subclasses
+
+ * stetic/wrapper/DefaultWidgets.cs: Update for new wrappers
+
+ * stetic/editor/File.cs: editor for strings that represent filenames
+
+ * stetic/Stetic.cs: Use Gnome.Program rather than Gtk.Application
+ now, since we're using Gnome.FileEntry.
+
+2005-01-06 Dan Winship <danw@novell.com>
+
+ * stetic/IDesignTimeContainer.cs: New name for the old
+ IWidgetSite.
+
+ * stetic/WidgetSite.cs (IWidgetSite): Now a "parent" for
+ WidgetSite and WindowSite.
+ (WidgetSite): Implement IWidgetSite and IDesignTimeContainer.
+ (WindowSite): IWidgetSite implementation for toplevel windows.
+ Includes the focus-tracking code formerly in
+ Stetic.Wrapper.Window.
+
+ * stetic/ContextMenu.cs (ContextMenu):
+ * stetic/Stetic.cs (Select):
+ * stetic/PropertyGrid.cs (PropertyGrid.Select,
+ ChildPropertyGrid.Select): Change WidgetBox and WidgetSite params
+ to IWidgetSite. This lets us select and show properties for toplevels.
+
+ * stetic/WidgetFactory.cs (WindowFactory.OnButtonPressEvent):
+ Create a WindowSite for the new window and connect to its
+ FocusChanged event.
+
+ * stetic/wrapper/*.cs: s/IWidgetSite/IDesignTimeContainer/
+
+ * stetic/wrapper/Window.cs (OnSetFocus): Gone. Handled by
+ WindowSite now.
+
+2005-01-05 Dan Winship <danw@novell.com>
+
+ * stetic/ContextMenu.cs: Menu subclass to use as a WidgetSite's
+ context menu. Currently a clone of Glade's context menu, but with
+ no widget-specific content, and it doesn't actually implement Cut,
+ Copy, or Paste. (Meaning you can do Select or Delete.)
+
+ * stetic/WidgetSite.cs (OnPopupMenu): create a ContextMenu and pop
+ it up.
+ (OnButtonPressEvent): Call OnPopupMenu() on a right-click.
+ (OnKeyReleaseEvent): hand off Delete key handling to Delete()
+ (Delete): new public method to delete the site's child.
+
+ * stetic/PropertyDescriptor.cs (PropertyDescriptor): fix a bug in
+ the sub-property case
+
+2005-01-05 Dan Winship <danw@novell.com>
+
+ * stetic/IObjectWrapper.cs (IPropertySensitizer): interface for
+ wrapper classes that want to be able to tweak the sensitivity of
+ their editors.
+
+ * stetic/Notify.cs: static helper class for the GObject "notify"
+ signal, which isn't currently bound by glib-sharp.
+
+ * stetic/PropertyDescriptor.cs (EventInfo, ParamSpec, EditorType):
+ Make these be properties of the PropertyDescriptor rather than
+ being figured out in PropertyEditors.
+
+ * stetic/PropertyEditor.cs: Renamed from PropertyEditors.cs and
+ made into an abstract widget class rather than a static class.
+ (MakeEditor): Now returns a PropertyEditor rather than just a
+ Widget.
+ (BasicEditor, RangeEditor, NoEditor): Now subclasses of
+ PropertyEditor, and they implement an Update() method to force the
+ editor to sync with the underlying property.
+
+ * stetic/PropertyGrid.cs: Tweak for PropertyDescriptor and
+ PropertyEditor changes. Use IPropertySensitizer if the displayed
+ widget supports it. Use Stetic.Notify to notice when the user
+ interacts with the displayed widget (eg, toggling a checkbox) and
+ force the relevant property editor to update itself.
+
+ * stetic/ParamSpec.cs (ParamSpecTypeHack): add an unused private
+ subclass of GLib.Object so we can access the static protected
+ LookupGType method. (This wouldn't be needed if ParamSpec was in
+ glib-sharp, because there's an internal method we could use.)
+ (LookupObjectProperty, LookupChildProperty): Take a Type rather
+ than a GLib.Object, so we can look up a type's properties without
+ needing an instatiated object.
+
+ * stetic/wrapper/Button.cs: Make the UI for the "Stock ID" and
+ "Label" properties work more nicely by wrapping both of them at
+ the Stetic.Wrapper.Button level, and watching for notifications on
+ the UseStock property, and setting the wrapper Label to the stock
+ item's Label rather than its Name when setting a stock item (eg,
+ "_OK" rather than "gtk-ok"). Also add the UseStock property, and
+ implement the IPropertySensitizer interface so that only one of
+ Stock ID and Label is sensitive at any time.
+
+ * stetic/editor/StockItem.cs: Remove the "None" option; the editor
+ should be desensitized if no stock item is being used.
+
+ * glue/notify.c: glue for Stetic.Notify
+
+ * glue/paramspec.c (stetic_param_spec_for_property,
+ stetic_param_spec_for_child_property): Take a GType rather than a
+ GObject.
+
+2004-12-20 Dan Winship <danw@novell.com>
+
+ * stetic/IObjectWrapper.cs: interface for Stetic.Wrapper objects
+ to use to allow them to define their properties
+
+ * stetic/PropertyDescriptor.cs: a class describing an editable
+ object property
+
+ * stetic/PropertyGrid.cs: Reimplement this using
+ PropertyDescriptors and PropertyGroups for the model, and
+ Gtk.Expanders for the view.
+
+ * stetic/PropertyEditorAttribute.cs: for Stetic.Editors to use to
+ specify the property and/or event to use to interact with them
+
+ * stetic/PropertyEditors.cs: Updated for PropertyDescriptor, the
+ Stetic.Editor namespace, etc
+
+ * stetic/ParamSpec.cs: make Minimum, Maximum, Default virtual
+ methods on ParamSpec itself, overridden by subclasses.
+
+ * stetic/editor/Boolean.cs:
+ * stetic/editor/Char.cs:
+ * stetic/editor/Enumeration.cs:
+ * stetic/editor/FloatRange.cs:
+ * stetic/editor/IntRange.cs:
+ * stetic/editor/OptIntRange.cs:
+ * stetic/editor/StockItem.cs:
+ * stetic/editor/String.cs: Editors for properties of various types
+
+ * stetic/wrapper/Arrow.cs:
+ * stetic/wrapper/Button.cs:
+ * stetic/wrapper/CheckButton.cs:
+ * stetic/wrapper/ComboBox.cs:
+ * stetic/wrapper/DrawingArea.cs:
+ * stetic/wrapper/Entry.cs:
+ * stetic/wrapper/HScrollbar.cs:
+ * stetic/wrapper/HSeparator.cs:
+ * stetic/wrapper/Label.cs:
+ * stetic/wrapper/RadioButton.cs:
+ * stetic/wrapper/VScrollbar.cs:
+ * stetic/wrapper/VSeparator.cs: IObjectWrapper implementations
+
+ * stetic/wrapper/Misc.cs:
+ * stetic/wrapper/Range.cs:
+ * stetic/wrapper/Widget.cs: static classes defining certain
+ PropertyGroups
+
+ * stetic/wrapper/HBox.cs:
+ * stetic/wrapper/HPaned.cs:
+ * stetic/wrapper/Table.cs:
+ * stetic/wrapper/VBox.cs:
+ * stetic/wrapper/VPaned.cs:
+ * stetic/wrapper/Window.cs: s/Widget/Gtk.Widget/ since there is
+ now a Stetic.Wrapper.Widget
+
+ * stetic/wrapper/DefaultWidgets.cs: use the new wrappers
+
+ * stetic/Makefile.am (stetic_exe_SOURCES): update
+
+ * stetic/stetic.in: pass --debug to mono
+
+2004-12-20 Dan Winship <danw@novell.com>
+
+ * stetic/wrapper: Rename "wrappers" dir to "wrapper", to match the
+ namespace
+
+ * stetic/Makefile.am (stetic_exe_SOURCES): update for that
+
+2004-12-15 Dan Winship <danw@novell.com>
+
+ * stetic/Stetic.cs:
+ * stetic/WidgetSite.cs:
+ * stetic/wrappers/Table.cs: Clean up new mcs warnings
+
+ * stetic/PropertyEditors.cs (Enum): Redo this using ComboBox to
+ avoid the warning about OptionMenu being deprecated
+ (Flags): Make this a no-op for now. The OptionMenu-based
+ implementation wasn't very useful anyway.
+
+2004-12-14 Dan Winship <danw@novell.com>
+
+ * stetic/*Wrapper.cs: Move these all to stetic/wrappers and rename
+
+ * stetic/DefaultWidgets.cs: Moved out of stetic/WidgetFactory.cs
+
+ * stetic/Makefile.am (stetic_exe_SOURCES): Update
+
+2004-12-13 Dan Winship <danw@novell.com>
+
+ * stetic/PropertyEditors.cs (Enum, Flags): implement these by
+ using private classes rather than anonymous delegates, to work
+ around 69614.
+
+ * stetic/TableWrapper.cs: fix a search-and-replace-o ("placesite"
+ instead of "placeholder")
+ (Sync): Don't adjust expand/fill settings of occupied sites.
+ (ChildOccupancyChanged): When a site becomes occupied, reset its
+ attach options.
+
+2004-12-10 Dan Winship <danw@novell.com>
+
+ * stetic/WidgetBox.cs: Always have a GdkWindow, so that the
+ background of a container can be clicked on to select it (if any
+ background is visible). Fix up coordinate handling accordingly.
+
+ * stetic/WidgetFactory.cs (DefaultWidgets): add VButtonBox and
+ HButtonBox.
+
+ * stetic/Makefile.am (stetic_exe_SOURCES): add
+ HButtonBoxWrapper.cs, VButtonBoxWrapper.cs
+ (stetic.exe): Use -pkg:gtk-sharp-2.0 rather than the output we
+ already cached in configure.in, because Miggie says so. :)
+
+2004-12-08 Dan Winship <danw@novell.com>
+
+ * Initial commit
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/Makefile.am b/main/src/addins/MonoDevelop.GtkCore2/Makefile.am
new file mode 100644
index 0000000000..9648571c49
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/Makefile.am
@@ -0,0 +1,112 @@
+SUBDIRS = libstetic libsteticui
+
+ADDIN_BUILD = $(top_builddir)/build/AddIns/MonoDevelop.GtkCore2
+ASSEMBLY = $(ADDIN_BUILD)/MonoDevelop.GtkCore2.dll
+
+DEPS = \
+ $(top_builddir)/build/AddIns/MonoDevelop.Deployment/MonoDevelop.Deployment.dll \
+ $(top_builddir)/build/AddIns/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.dll \
+ $(top_builddir)/build/AddIns/MonoDevelop.GtkCore2/libstetic2.dll \
+ $(top_builddir)/build/AddIns/MonoDevelop.GtkCore2/libsteticui2.dll \
+ $(top_builddir)/build/bin/Mono.TextEditor.dll \
+ $(top_builddir)/build/bin/MonoDevelop.Core.dll \
+ $(top_builddir)/build/bin/MonoDevelop.Ide.dll
+
+REFS = \
+ $(GLADE_SHARP_LIBS) \
+ $(GLIB_SHARP_LIBS) \
+ $(GTK_SHARP_LIBS) \
+ $(MONO_ADDINS_LIBS) \
+ -pkg:monodevelop \
+ -r:Mono.Posix \
+ -r:System \
+ -r:System.Core \
+ -r:System.Xml
+
+FILES = \
+ AssemblyInfo.cs \
+ gtk-gui/generated.cs \
+ gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs \
+ gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs \
+ MonoDevelop.GtkCore.Commands/GtkCommands.cs \
+ MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs \
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs \
+ MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ClassUtils.cs \
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs \
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs \
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs \
+ MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs \
+ MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs \
+ MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs \
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs \
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs \
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs \
+ MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs \
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs \
+ MonoDevelop.GtkCore/Counters.cs \
+ MonoDevelop.GtkCore/GtkCoreService.cs \
+ MonoDevelop.GtkCore/GtkDesignInfo.cs \
+ MonoDevelop.GtkCore/ObjectsDocument.cs \
+ MonoDevelop.GtkCore/ProjectResourceProvider.cs \
+ MonoDevelop.GtkCore/ReferenceManager.cs \
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs \
+ MonoDevelop.GtkCore/WidgetParser.cs
+
+RES = \
+ gtk-gui/gui.stetic \
+ gui.glade \
+ icons/actiongroup.png \
+ icons/gtk-logo.png \
+ icons/gtkx.png \
+ icons/image-x-generic.png \
+ icons/widget.png \
+ MonoDevelop.GtkCore2.addin.xml,MonoDevelop.GtkCore.addin.xml \
+ templates/ActionGroup.xft.xml \
+ templates/ActionGroupPartial.xft.xml \
+ templates/Dialog.xft.xml \
+ templates/DialogPartial.xft.xml \
+ templates/DrawingArea.xft.xml \
+ templates/Widget.xft.xml \
+ templates/WidgetPartial.xft.xml \
+ templates/Window.xft.xml \
+ templates/WindowPartial.xft.xml
+
+
+EXTRA_DIST = $(FILES) $(RES)
+
+update-stetic:
+ svn rm -m "Update Stetic sources" svn+ssh://mono-cvs.ximian.com/source/trunk/monodevelop/main/src/addins/MonoDevelop.GtkCore/lib/stetic && \
+ svn cp -m "Update Stetic sources" svn+ssh://mono-cvs.ximian.com/source/trunk/stetic svn+ssh://mono-cvs.ximian.com/source/trunk/monodevelop/main/src/addins/MonoDevelop.GtkCore/lib/stetic
+
+all: $(ASSEMBLY)
+
+$(ADDIN_BUILD)/%: $(srcdir)/lib/%
+ mkdir -p $(ADDIN_BUILD)
+ cp $< $@
+
+$(ASSEMBLY): $(build_sources) $(build_resources) $(DEPS)
+ mkdir -p $(ADDIN_BUILD)
+ $(CSC) $(CSC_FLAGS) -debug -out:$@ -target:library \
+ $(build_resources:%=/resource:%) $(build_sources) $(REFS) $(build_deps)
+
+assemblydir = $(MD_ADDIN_DIR)/MonoDevelop.GtkCore2
+assembly_DATA = $(ASSEMBLY) $(ASSEMBLY).mdb
+
+CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb
+
+include $(top_srcdir)/Makefile.include
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/ChangeLog
new file mode 100644
index 0000000000..b2765325e1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/ChangeLog
@@ -0,0 +1,4 @@
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GladeCommands.cs:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/GtkCommands.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/GtkCommands.cs
new file mode 100644
index 0000000000..e8772a0680
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Commands/GtkCommands.cs
@@ -0,0 +1,45 @@
+//
+// GtkCommands.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Krzysztof Marecki
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2010 Krzysztof Marecki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MonoDevelop.GtkCore
+{
+ public enum GtkCommands
+ {
+ AddNewDialog,
+ AddNewWindow,
+ AddNewWidget,
+ AddNewActionGroup,
+ ImportGladeFile,
+ EditIcons,
+ GtkSettings,
+ GenerateCode,
+ ReloadDesigner
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs
new file mode 100644
index 0000000000..04bd159640
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs
@@ -0,0 +1,186 @@
+//
+// BindDesignDialog.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+using Glade;
+using Gtk;
+using MonoDevelop.Core;
+using MonoDevelop.Components;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ class BindDesignDialog: IDisposable
+ {
+ [Glade.Widget ("BindDesignDialog")] protected Gtk.Dialog dialog;
+ [Glade.Widget] protected Gtk.Label labelMessage;
+ [Glade.Widget] protected Gtk.ComboBox comboClasses;
+ [Glade.Widget] protected Gtk.Entry entryClassName;
+ [Glade.Widget] protected Gtk.Entry entryNamespace;
+ [Glade.Widget] protected Gtk.RadioButton radioSelect;
+ [Glade.Widget] protected Gtk.RadioButton radioCreate;
+ [Glade.Widget] protected Gtk.Table tableNewClass;
+ [Glade.Widget] protected Gtk.Button okButton;
+ [Glade.Widget] protected Gtk.EventBox fileEntryBox;
+
+ FolderEntry fileEntry;
+
+ ListStore store;
+ static string lastNamespace = "";
+
+ public BindDesignDialog (string id, ArrayList validClasses, string baseFolder)
+ {
+ XML glade = new XML (null, "gui.glade", "BindDesignDialog", null);
+ glade.Autoconnect (this);
+ labelMessage.Text = GettextCatalog.GetString ("The widget design {0} is not currently bound to a class.", id);
+
+ fileEntry = new FolderEntry ();
+ fileEntryBox.Add (fileEntry);
+ fileEntry.ShowAll ();
+
+ if (validClasses.Count > 0) {
+
+ store = new ListStore (typeof (string));
+ foreach (string cname in validClasses)
+ store.AppendValues (cname);
+ comboClasses.Model = store;
+ CellRendererText cr = new CellRendererText ();
+ comboClasses.PackStart (cr, true);
+ comboClasses.AddAttribute (cr, "text", 0);
+ comboClasses.Active = 0;
+
+ } else {
+ radioSelect.Sensitive = false;
+ radioCreate.Active = true;
+ }
+
+ fileEntry.Path = baseFolder;
+
+ // Initialize the class name using the widget name
+ int i = id.IndexOf ('.');
+ if (i != -1) {
+ entryClassName.Text = id.Substring (i+1);
+ entryNamespace.Text = id.Substring (0,i);
+ } else {
+ entryClassName.Text = id;
+ entryNamespace.Text = lastNamespace;
+ }
+
+ dialog.Response += new Gtk.ResponseHandler (OnResponse);
+ UpdateStatus ();
+ }
+
+ void OnResponse (object ob, Gtk.ResponseArgs args)
+ {
+ dialog.Response -= new Gtk.ResponseHandler (OnResponse);
+ if (args.ResponseId == ResponseType.Ok && radioCreate.Active)
+ lastNamespace = Namespace;
+ }
+
+ public bool Run ()
+ {
+ dialog.TransientFor = IdeApp.Workbench.RootWindow;
+ return dialog.Run () == (int) ResponseType.Ok;
+ }
+
+ public bool CreateNew {
+ get { return radioCreate.Active; }
+ }
+
+ public string ClassName {
+ get {
+ if (radioCreate.Active) {
+ return entryClassName.Text;
+ } else {
+ Gtk.TreeIter it;
+ if (!comboClasses.GetActiveIter (out it))
+ return "";
+ string s = (string) store.GetValue (it, 0);
+ int i = s.IndexOf ('.');
+ if (i != -1)
+ return s.Substring (i+1);
+ else
+ return s;
+ }
+ }
+ }
+
+ public string Namespace {
+ get {
+ if (radioCreate.Active) {
+ return entryNamespace.Text;
+ } else {
+ Gtk.TreeIter it;
+ if (!comboClasses.GetActiveIter (out it))
+ return "";
+ string s = (string) store.GetValue (it, 0);
+ int i = s.IndexOf ('.');
+ if (i != -1)
+ return s.Substring (0, i);
+ else
+ return "";
+ }
+ }
+ }
+
+ public string Folder {
+ get { return fileEntry.Path; }
+ }
+
+ protected void OnSelectToggled (object ob, EventArgs args)
+ {
+ UpdateStatus ();
+ }
+
+ protected void OnEntryChanged (object ob, EventArgs a)
+ {
+ UpdateStatus ();
+ }
+
+ void UpdateStatus ()
+ {
+ if (radioSelect.Active) {
+ tableNewClass.Sensitive = false;
+ comboClasses.Sensitive = true;
+ okButton.Sensitive = true;
+ } else {
+ tableNewClass.Sensitive = true;
+ comboClasses.Sensitive = false;
+ okButton.Sensitive = ClassName != "" && Folder != "";
+ }
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ChangeLog
new file mode 100644
index 0000000000..c48d43c59e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ChangeLog
@@ -0,0 +1,18 @@
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectConversionDialog.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectConversionDialog.cs:
+ * WidgetBuilderOptionPanel.cs:
+
+2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectConversionDialog.cs:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectConversionDialog.cs: Initial commit
+ * WidgetBuilderOptionPanel.cs:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs
new file mode 100644
index 0000000000..b0c8031ba5
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs
@@ -0,0 +1,79 @@
+//
+// ConfirmWindowDeleteDialog.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Glade;
+using Gtk;
+using MonoDevelop.Core;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ class ConfirmWindowDeleteDialog: IDisposable
+ {
+ [Glade.Widget ("ConfirmWindowDeleteDialog")] protected Gtk.Dialog dialog;
+ [Glade.Widget] protected Gtk.Label label;
+ [Glade.Widget] protected Gtk.CheckButton checkbox;
+
+ public ConfirmWindowDeleteDialog (string windowName, string fileName, Stetic.ProjectItemInfo obj)
+ {
+ XML glade = new XML (null, "gui.glade", "ConfirmWindowDeleteDialog", null);
+ glade.Autoconnect (this);
+
+ if (obj is Stetic.WidgetInfo && ((Stetic.WidgetInfo)obj).IsWindow) {
+ label.Text = GettextCatalog.GetString ("Are you sure you want to delete the window '{0}'?", windowName);
+ } else if (obj is Stetic.WidgetInfo) {
+ label.Text = GettextCatalog.GetString ("Are you sure you want to delete the widget '{0}'?", windowName);
+ } else if (obj is Stetic.ActionGroupInfo) {
+ label.Text = GettextCatalog.GetString ("Are you sure you want to delete the action group '{0}'?", windowName);
+ } else
+ label.Text = GettextCatalog.GetString ("Are you sure you want to delete '{0}'?", windowName);
+
+ if (fileName != null) {
+ checkbox.Label = string.Format (checkbox.Label, fileName);
+ checkbox.Active = true;
+ } else
+ checkbox.Hide ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ public int Run ()
+ {
+ dialog.TransientFor = IdeApp.Workbench.RootWindow;
+ return dialog.Run ();
+ }
+
+ public bool DeleteFile {
+ get { return checkbox.Active; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs
new file mode 100644
index 0000000000..cce24542b0
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs
@@ -0,0 +1,64 @@
+//
+// GtkDesignerOptionPanelWidget.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using MonoDevelop.GtkCore.GuiBuilder;
+using Gtk;
+using MonoDevelop.Ide.Gui.Dialogs;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ public class GtkDesignerOptionPanel: OptionsPanel
+ {
+ GtkDesignerOptionsPanelWidget widget;
+
+ public override Widget CreatePanelWidget ()
+ {
+ widget = new GtkDesignerOptionsPanelWidget ();
+ widget.AutoSwitchLayout = GuiBuilderService.AutoSwitchGuiLayout;
+ return widget;
+ }
+
+ public override void ApplyChanges ()
+ {
+ GuiBuilderService.AutoSwitchGuiLayout = widget.AutoSwitchLayout;
+ }
+ }
+
+ [System.ComponentModel.ToolboxItem(true)]
+ public partial class GtkDesignerOptionsPanelWidget : Gtk.Bin
+ {
+ public GtkDesignerOptionsPanelWidget()
+ {
+ this.Build();
+ }
+
+ public bool AutoSwitchLayout {
+ get { return checkSwitchLayout.Active; }
+ set { checkSwitchLayout.Active = value; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs
new file mode 100644
index 0000000000..133a6a4a22
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs
@@ -0,0 +1,81 @@
+
+using System;
+using MonoDevelop.Ide.Templates;
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using Gtk;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ class GtkFeatureWidget : Gtk.VBox
+ {
+ ComboBox versionCombo;
+
+ public GtkFeatureWidget (DotNetProject project)
+ {
+ Spacing = 6;
+
+ versionCombo = Gtk.ComboBox.NewText ();
+ ReferenceManager refmgr = new ReferenceManager (project);
+ foreach (string v in refmgr.SupportedGtkVersions)
+ versionCombo.AppendText (v);
+ versionCombo.Active = 0;
+ refmgr.Dispose ();
+
+ // GTK# version selector
+ HBox box = new HBox (false, 6);
+ Gtk.Label vlab = new Label (GettextCatalog.GetString ("Target GTK# version:"));
+ box.PackStart (vlab, false, false, 0);
+ box.PackStart (versionCombo, false, false, 0);
+ box.PackStart (new Label (GettextCatalog.GetString ("(or upper)")), false, false, 0);
+ PackStart (box, false, false, 0);
+
+ ShowAll ();
+ }
+
+ public string SelectedVersion {
+ get { return versionCombo.ActiveText; }
+ }
+ }
+
+ class GtkProjectFeature: ISolutionItemFeature
+ {
+ public string Title {
+ get { return GettextCatalog.GetString ("GTK# Support"); }
+ }
+
+ public string Description {
+ get { return GettextCatalog.GetString ("Enables support for GTK# in the project. Allows the visual design of GTK# windows, and the creation of a GTK# widget library."); }
+ }
+
+ public FeatureSupportLevel GetSupportLevel (SolutionFolder parentCombine, SolutionItem entry)
+ {
+ if (!(entry is DotNetProject) || !GtkDesignInfo.SupportsRefactoring (entry as DotNetProject))
+ return FeatureSupportLevel.NotSupported;
+ else if (GtkDesignInfo.SupportsDesigner ((Project)entry))
+ return FeatureSupportLevel.Enabled;
+ else if (entry is DotNetAssemblyProject)
+ return FeatureSupportLevel.SupportedByDefault;
+ else
+ return FeatureSupportLevel.Supported;
+ }
+
+ public Widget CreateFeatureEditor (SolutionFolder parentCombine, SolutionItem entry)
+ {
+ return new GtkFeatureWidget ((DotNetProject) entry);
+ }
+
+ public void ApplyFeature (SolutionFolder parentCombine, SolutionItem entry, Widget editor)
+ {
+ GtkFeatureWidget fw = (GtkFeatureWidget) editor;
+ ReferenceManager refmgr = new ReferenceManager ((DotNetProject) entry);
+ refmgr.GtkPackageVersion = fw.SelectedVersion;
+ refmgr.Dispose ();
+ }
+
+ public string Validate (SolutionFolder parentCombine, SolutionItem entry, Gtk.Widget editor)
+ {
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs
new file mode 100644
index 0000000000..c7b091c6aa
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs
@@ -0,0 +1,40 @@
+using System;
+using Gtk;
+
+using MonoDevelop.Projects;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ public partial class ProjectConversionDialog : Gtk.Dialog
+ {
+ public ProjectConversionDialog (IntPtr raw)
+ : base (raw)
+ {
+ }
+
+ public string GuiFolderName { get; private set; }
+
+ public bool MakeBackup { get; private set; }
+
+
+ public ProjectConversionDialog (Project project, string guiFolderName)
+ {
+ this.Build ();
+
+ entryFolder.Text = guiFolderName;
+ Title = project.Name;
+ entryFolder.Position = -1;
+
+ buttonConvert.Clicked += HandleButtonConvertClicked;
+ }
+
+ void HandleButtonConvertClicked (object sender, EventArgs e)
+ {
+ GuiFolderName = entryFolder.Text;
+ MakeBackup = checkBackup.Active;
+
+ Respond (ResponseType.Yes);
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs
new file mode 100644
index 0000000000..323a98ba19
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs
@@ -0,0 +1,93 @@
+//
+// SelectRenamedClassDialog.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using Gtk;
+using Gdk;
+using Glade;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ public class SelectRenamedClassDialog: IDisposable
+ {
+ [Glade.Widget ("SelectRenamedClassDialog")] protected Gtk.Dialog dialog;
+ [Glade.Widget] protected Gtk.TreeView treeClasses;
+ ListStore store;
+
+ public SelectRenamedClassDialog (IEnumerable<IType> classes)
+ {
+ XML glade = new XML (null, "gui.glade", "SelectRenamedClassDialog", null);
+ glade.Autoconnect (this);
+
+ store = new ListStore (typeof(Pixbuf), typeof(string));
+ treeClasses.Model = store;
+
+ TreeViewColumn column = new TreeViewColumn ();
+
+ var pr = new CellRendererPixbuf ();
+ column.PackStart (pr, false);
+ column.AddAttribute (pr, "pixbuf", 0);
+
+ CellRendererText crt = new CellRendererText ();
+ column.PackStart (crt, true);
+ column.AddAttribute (crt, "text", 1);
+
+ treeClasses.AppendColumn (column);
+
+ foreach (IType cls in classes) {
+ Pixbuf pic = ImageService.GetPixbuf (cls.StockIcon);
+ store.AppendValues (pic, cls.FullName);
+ }
+ }
+
+ public bool Run ()
+ {
+ dialog.TransientFor = IdeApp.Workbench.RootWindow;
+ return dialog.Run () == (int) ResponseType.Ok;
+ }
+
+ public string SelectedClass {
+ get {
+ Gtk.TreeModel foo;
+ Gtk.TreeIter iter;
+ if (!treeClasses.Selection.GetSelected (out foo, out iter))
+ return null;
+ return (string) store.GetValue (iter, 1);
+ }
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs
new file mode 100644
index 0000000000..fae7e91e7b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs
@@ -0,0 +1,143 @@
+//
+// WidgetBuilderOptionPanel.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Mike Kestner
+//
+// Copyright (C) 2006, 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using Gtk;
+
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui.Dialogs;
+
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ class WidgetBuilderOptionPanel: ItemOptionsPanel
+ {
+ class WidgetBuilderOptionPanelWidget : Gtk.VBox
+ {
+ Gtk.CheckButton checkGettext;
+ Gtk.Entry entryGettext;
+ Gtk.ComboBox comboVersions;
+ Gtk.Entry entryFolderName;
+ Gtk.CheckButton checkHideFiles;
+
+ DotNetProject project;
+
+ public WidgetBuilderOptionPanelWidget (Project project) : base (false, 6)
+ {
+ this.project = project as DotNetProject;
+
+ Gtk.HBox box = new Gtk.HBox (false, 3);
+ Gtk.Label lbl = new Gtk.Label (GettextCatalog.GetString ("Target Gtk# version:"));
+ box.PackStart (lbl, false, false, 0);
+ comboVersions = ComboBox.NewText ();
+ ReferenceManager refmgr = new ReferenceManager (project as DotNetProject);
+ foreach (string v in refmgr.SupportedGtkVersions)
+ comboVersions.AppendText (v);
+ comboVersions.Active = refmgr.SupportedGtkVersions.IndexOf (refmgr.GtkPackageVersion);
+ refmgr.Dispose ();
+ box.PackStart (comboVersions, false, false, 0);
+ box.ShowAll ();
+ PackStart (box, false, false, 0);
+
+ HSeparator sep = new HSeparator ();
+ sep.Show ();
+ PackStart (sep, false, false, 0);
+
+ if (!GtkDesignInfo.HasDesignedObjects (project))
+ return;
+
+ GtkDesignInfo designInfo = GtkDesignInfo.FromProject (project);
+ checkGettext = new CheckButton (GettextCatalog.GetString ("Enable gettext support"));
+ checkGettext.Active = designInfo.GenerateGettext;
+ checkGettext.Show ();
+ PackStart (checkGettext, false, false, 0);
+ box = new Gtk.HBox (false, 3);
+ box.PackStart (new Label (GettextCatalog.GetString ("Gettext class:")), false, false, 0);
+ entryGettext = new Gtk.Entry ();
+ entryGettext.Text = designInfo.GettextClass;
+ entryGettext.Sensitive = checkGettext.Active;
+ box.PackStart (entryGettext, false, false, 0);
+ box.ShowAll ();
+ PackStart (box, false, false, 0);
+
+ sep= new HSeparator ();
+ sep.Show ();
+ PackStart (sep, false, false, 0);
+
+ box = new Gtk.HBox (false, 3);
+ box.PackStart (new Label (GettextCatalog.GetString ("Stetic folder name :")), false, false, 0);
+ entryFolderName = new Gtk.Entry ();
+ entryFolderName.Text = designInfo.SteticFolderName;
+ entryFolderName.Sensitive = false;
+ box.PackStart (entryFolderName, false, false, 0);
+ box.ShowAll ();
+ PackStart (box, false, false, 0);
+
+ checkHideFiles = new CheckButton (GettextCatalog.GetString ("Hide designer files"));
+ checkHideFiles.Active = designInfo.HideGtkxFiles;
+ checkHideFiles.Show ();
+ PackStart (checkHideFiles, false, false, 0);
+ }
+
+ public void Store ()
+ {
+ ReferenceManager refmgr = new ReferenceManager (project);
+ if (!string.IsNullOrEmpty (comboVersions.ActiveText))
+ refmgr.GtkPackageVersion = comboVersions.ActiveText;
+ if (GtkDesignInfo.HasDesignedObjects (project)) {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ info.GenerateGettext = checkGettext.Active;
+ info.GettextClass = entryGettext.Text;
+ info.GuiBuilderProject.SteticProject.TargetGtkVersion = comboVersions.ActiveText;
+ info.SteticFolderName = entryFolderName.Text;
+ info.HideGtkxFiles = checkHideFiles.Active;
+ info.GuiBuilderProject.Save (false);
+ }
+ refmgr.Dispose ();
+ }
+ }
+
+ WidgetBuilderOptionPanelWidget widget;
+
+ public override Widget CreatePanelWidget()
+ {
+ return (widget = new WidgetBuilderOptionPanelWidget (ConfiguredProject));
+ }
+
+ public override bool IsVisible ()
+ {
+ return GtkDesignInfo.SupportsDesigner (DataObject as Project);
+ }
+
+ public override void ApplyChanges ()
+ {
+ widget.Store ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs
new file mode 100644
index 0000000000..dd8bb93383
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs
@@ -0,0 +1,206 @@
+//
+// ActionGroupDisplayBinding.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System.Collections;
+using System.CodeDom;
+
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Projects.CodeGeneration;
+using MonoDevelop.GtkCore.Dialogs;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class ActionGroupDisplayBinding : DisplayBinding
+ {
+ bool excludeThis = false;
+
+ public override string Name {
+ get { return "Action Group Editor"; }
+ }
+
+ public override bool CanCreateContentForUri (string fileName)
+ {
+ Project project = IdeApp.Workspace.GetProjectContainingFile (fileName);
+ GtkDesignInfo info = GtkDesignInfo.FromProject ((DotNetProject) project);
+
+ if (excludeThis)
+ return false;
+
+ if (fileName.Contains (info.BuildFileExtension))
+ return false;
+
+ if (!IdeApp.Workspace.IsOpen)
+ return false;
+
+ if (GetActionGroup (fileName) == null)
+ return false;
+
+
+ excludeThis = true;
+ var db = DisplayBindingService.GetDefaultBindingForUri (fileName);
+ excludeThis = false;
+ return db != null;
+ }
+
+ public override IViewContent CreateContentForUri (string fileName)
+ {
+ excludeThis = true;
+ var db = DisplayBindingService.GetDefaultBindingForUri (fileName);
+
+ Project project = IdeApp.Workspace.GetProjectContainingFile (fileName);
+ GtkDesignInfo info = GtkDesignInfo.FromProject ((DotNetProject) project);
+
+ ActionGroupView view = new ActionGroupView (db.CreateContentForUri (fileName), GetActionGroup (fileName), info.GuiBuilderProject);
+ excludeThis = false;
+ return view;
+ }
+ Stetic.ActionGroupInfo GetActionGroup (string file)
+ {
+ Project project = IdeApp.Workspace.GetProjectContainingFile (file);
+ if (!GtkDesignInfo.HasDesignedObjects (project))
+ return null;
+
+ return GtkDesignInfo.FromProject (project).GuiBuilderProject.GetActionGroupForFile (file);
+ }
+
+ internal static string BindToClass (Project project, Stetic.ActionGroupInfo group)
+ {
+ GuiBuilderProject gproject = GtkDesignInfo.FromProject (project).GuiBuilderProject;
+ string file = gproject.GetSourceCodeFile (group);
+ if (file != null)
+ return file;
+
+ // Find the classes that could be bound to this design
+
+ ArrayList list = new ArrayList ();
+ ProjectDom ctx = gproject.GetParserContext ();
+ foreach (IType cls in ctx.Types)
+ if (IsValidClass (ctx, cls))
+ list.Add (cls.FullName);
+
+ // Ask what to do
+
+ using (BindDesignDialog dialog = new BindDesignDialog (group.Name, list, project.BaseDirectory)) {
+ if (!dialog.Run ())
+ return null;
+
+ if (dialog.CreateNew)
+ CreateClass (project, (Stetic.ActionGroupComponent) group.Component, dialog.ClassName, dialog.Namespace, dialog.Folder);
+
+ string fullName = dialog.Namespace.Length > 0 ? dialog.Namespace + "." + dialog.ClassName : dialog.ClassName;
+ group.Name = fullName;
+ }
+ return gproject.GetSourceCodeFile (group);
+ }
+
+ static IType CreateClass (Project project, Stetic.ActionGroupComponent group, string name, string namspace, string folder)
+ {
+ string fullName = namspace.Length > 0 ? namspace + "." + name : name;
+
+ CodeRefactorer gen = new CodeRefactorer (project.ParentSolution);
+
+ CodeTypeDeclaration type = new CodeTypeDeclaration ();
+ type.Name = name;
+ type.IsClass = true;
+ type.BaseTypes.Add (new CodeTypeReference ("Gtk.ActionGroup"));
+
+ // Generate the constructor. It contains the call that builds the widget.
+
+ CodeConstructor ctor = new CodeConstructor ();
+ ctor.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+ ctor.BaseConstructorArgs.Add (new CodePrimitiveExpression (fullName));
+
+ CodeMethodInvokeExpression call = new CodeMethodInvokeExpression (
+ new CodeMethodReferenceExpression (
+ new CodeTypeReferenceExpression ("Stetic.Gui"),
+ "Build"
+ ),
+ new CodeThisReferenceExpression (),
+ new CodeTypeOfExpression (fullName)
+ );
+ ctor.Statements.Add (call);
+ type.Members.Add (ctor);
+
+ // Add signal handlers
+
+ foreach (Stetic.ActionComponent action in group.GetActions ()) {
+ foreach (Stetic.Signal signal in action.GetSignals ()) {
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = signal.Handler;
+ met.Attributes = MemberAttributes.Family;
+ met.ReturnType = new CodeTypeReference (signal.SignalDescriptor.HandlerReturnTypeName);
+
+ foreach (Stetic.ParameterDescriptor pinfo in signal.SignalDescriptor.HandlerParameters)
+ met.Parameters.Add (new CodeParameterDeclarationExpression (pinfo.TypeName, pinfo.Name));
+
+ type.Members.Add (met);
+ }
+ }
+
+ // Create the class
+
+ IType cls = null;
+ cls = gen.CreateClass (project, ((DotNetProject)project).LanguageName, folder, namspace, type);
+ if (cls == null)
+ throw new UserException ("Could not create class " + fullName);
+
+ project.AddFile (cls.CompilationUnit.FileName, BuildAction.Compile);
+ IdeApp.ProjectOperations.Save (project);
+
+#if TRUNK
+ // Make sure the database is up-to-date
+ ProjectDomService.Parse (project, cls.CompilationUnit.FileName);
+#else
+ ProjectDomService.Parse (project, cls.CompilationUnit.FileName, null);
+
+#endif
+ return cls;
+ }
+
+ internal static bool IsValidClass (ProjectDom ctx, IType cls)
+ {
+ if (cls.BaseTypes != null) {
+ foreach (IReturnType bt in cls.BaseTypes) {
+ if (bt.FullName == "Gtk.ActionGroup")
+ return true;
+
+ IType baseCls = ctx.GetType (bt);
+ if (baseCls != null && IsValidClass (ctx, baseCls))
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs
new file mode 100644
index 0000000000..0be5db765f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs
@@ -0,0 +1,316 @@
+//
+// ActionGroupView.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.DesignerSupport;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class ActionGroupView: CombinedDesignView
+ {
+ Stetic.ActionGroupDesigner designer;
+ CodeBinder codeBinder;
+ GuiBuilderProject project;
+ Stetic.ActionGroupComponent group;
+ Stetic.ActionGroupInfo groupInfo;
+ string groupName;
+
+ public ActionGroupView (IViewContent content, Stetic.ActionGroupInfo group, GuiBuilderProject project): base (content)
+ {
+ groupName = group.Name;
+ this.project = project;
+ LoadDesigner ();
+ }
+
+ void LoadDesigner ()
+ {
+ groupInfo = project.GetActionGroup (groupName);
+ if (groupInfo == null)
+ // Group not found
+ return;
+
+ group = (Stetic.ActionGroupComponent) groupInfo.Component;
+ project.Unloaded += OnDisposeProject;
+
+ designer = project.SteticProject.CreateActionGroupDesigner (groupInfo, false);
+ designer.AllowActionBinding = project.Project.UsePartialTypes;
+ designer.BindField += new EventHandler (OnBindField);
+
+ ActionGroupPage actionsPage = new ActionGroupPage ();
+ actionsPage.PackStart (designer, true, true, 0);
+ actionsPage.ShowAll ();
+
+ AddButton (GettextCatalog.GetString ("Actions"), actionsPage);
+
+ designer.ModifiedChanged += OnGroupModified;
+ designer.SignalAdded += OnSignalAdded;
+ designer.SignalChanged += OnSignalChanged;
+ designer.RootComponentChanged += OnRootComponentChanged;
+
+ codeBinder = new CodeBinder (project.Project, new OpenDocumentFileProvider (), designer.RootComponent);
+ }
+
+ public void CloseDesigner ()
+ {
+ if (designer == null)
+ return;
+ project.Unloaded -= OnDisposeProject;
+ designer.BindField -= OnBindField;
+ designer.RootComponentChanged -= OnRootComponentChanged;
+ designer.ModifiedChanged -= OnGroupModified;
+ designer.SignalAdded -= OnSignalAdded;
+ designer.SignalChanged -= OnSignalChanged;
+ designer.Destroy ();
+ designer = null;
+
+ project.Reloaded += OnReloadProject;
+ }
+
+ public override Stetic.Designer Designer {
+ get { return designer; }
+ }
+
+ void OnDisposeProject (object s, EventArgs args)
+ {
+ RemoveButton (1);
+ CloseDesigner ();
+ }
+
+ void OnReloadProject (object s, EventArgs args)
+ {
+ if (designer == null)
+ LoadDesigner ();
+ }
+
+ public Stetic.ActionGroupComponent ActionGroup {
+ get { return group; }
+ set { Load (value.Name); }
+ }
+
+ public override void ShowPage (int npage)
+ {
+ if (designer != null && group != null) {
+ // At every page switch update the generated code, to make sure code completion works
+ // for the generated fields. The call to GenerateSteticCodeStructure will generate
+ // the code for the window (only the fields in fact) and update the parser database, it
+ // will not save the code to disk.
+ if (project.Project.UsePartialTypes)
+ GuiBuilderService.GenerateSteticCodeStructure ((DotNetProject)project.Project, designer.RootComponent, null, false, false);
+ }
+ base.ShowPage (npage);
+ }
+
+ void OnRootComponentChanged (object s, EventArgs args)
+ {
+ codeBinder.TargetObject = designer.RootComponent;
+ }
+
+ public override void Save (string fileName)
+ {
+ string oldBuildFile = GuiBuilderService.GetBuildCodeFileName (project.Project, groupInfo.Name);
+
+ base.Save (fileName);
+ if (designer == null)
+ return;
+
+ codeBinder.UpdateBindings (fileName);
+
+ designer.Save ();
+
+ string newBuildFile = GuiBuilderService.GetBuildCodeFileName (project.Project, groupInfo.Name);
+ if (oldBuildFile != newBuildFile && oldBuildFile != null && newBuildFile != null)
+ FileService.MoveFile (oldBuildFile, newBuildFile);
+
+ project.Save (true);
+ OnDirtyChanged (EventArgs.Empty);
+ }
+
+ public override void Dispose ()
+ {
+ CloseDesigner ();
+ project.Reloaded -= OnReloadProject;
+ base.Dispose ();
+ }
+
+ public void ShowDesignerView ()
+ {
+ ShowPage (1);
+ }
+
+ public void SelectAction (Stetic.ActionComponent action)
+ {
+ if (designer != null)
+ designer.SelectedAction = action;
+ }
+
+ public override void JumpToSignalHandler (Stetic.Signal signal)
+ {
+ IType cls = codeBinder.GetClass ();
+ foreach (IMethod met in cls.Methods) {
+ if (met.Name == signal.Handler) {
+ ShowPage (1);
+ JumpTo (met.Location.Line, met.Location.Column);
+ break;
+ }
+ }
+ }
+
+ void OnGroupModified (object s, EventArgs a)
+ {
+ if (designer.Modified)
+ OnContentChanged (a);
+ IsDirty = designer.Modified;
+ }
+
+ void OnSignalAdded (object s, Stetic.ComponentSignalEventArgs a)
+ {
+ codeBinder.BindSignal (a.Signal);
+ }
+
+ void OnSignalChanged (object s, Stetic.ComponentSignalEventArgs a)
+ {
+ codeBinder.UpdateSignal (a.OldSignal, a.Signal);
+ }
+
+ void OnBindField (object s, EventArgs args)
+ {
+ if (designer.SelectedAction != null) {
+ codeBinder.BindToField (designer.SelectedAction);
+ }
+ }
+ }
+
+ class ActionGroupPage: Gtk.VBox, ICustomPropertyPadProvider
+ {
+ public ActionGroupPage ()
+ {
+ }
+
+ Gtk.Widget ICustomPropertyPadProvider.GetCustomPropertyWidget ()
+ {
+ return PropertiesWidget.Instance;
+ }
+
+ void ICustomPropertyPadProvider.DisposeCustomPropertyWidget ()
+ {
+ }
+
+ public void ClearChild ()
+ {
+ if (Children.Length > 0) {
+ Gtk.Widget w = Children [0];
+ Remove (w);
+ w.Destroy ();
+ }
+ }
+
+ Stetic.ActionGroupDesigner actionsBox {
+ get { return Children[0] as Stetic.ActionGroupDesigner; }
+ }
+
+ [CommandHandler (EditCommands.Delete)]
+ protected void OnDelete ()
+ {
+ actionsBox.DeleteSelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Delete)]
+ protected void OnUpdateDelete (CommandInfo cinfo)
+ {
+ cinfo.Enabled = actionsBox != null && actionsBox.SelectedAction != null;
+ }
+
+ [CommandHandler (EditCommands.Copy)]
+ protected void OnCopy ()
+ {
+ actionsBox.CopySelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Copy)]
+ protected void OnUpdateCopy (CommandInfo cinfo)
+ {
+ cinfo.Enabled = actionsBox != null && actionsBox.SelectedAction != null;
+ }
+
+ [CommandHandler (EditCommands.Cut)]
+ protected void OnCut ()
+ {
+ actionsBox.CutSelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Cut)]
+ protected void OnUpdateCut (CommandInfo cinfo)
+ {
+ cinfo.Enabled = actionsBox != null && actionsBox.SelectedAction != null;
+ }
+
+ [CommandHandler (EditCommands.Paste)]
+ protected void OnPaste ()
+ {
+ actionsBox.PasteToSelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Paste)]
+ protected void OnUpdatePaste (CommandInfo cinfo)
+ {
+ cinfo.Enabled = false;
+ }
+
+ [CommandHandler (EditCommands.Undo)]
+ protected void OnUndo ()
+ {
+ actionsBox.UndoQueue.Undo ();
+ }
+
+ [CommandHandler (EditCommands.Redo)]
+ protected void OnRedo ()
+ {
+ actionsBox.UndoQueue.Redo ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Undo)]
+ protected void OnUpdateUndo (CommandInfo cinfo)
+ {
+ cinfo.Enabled = actionsBox != null && actionsBox.UndoQueue.CanUndo;
+ }
+
+ [CommandUpdateHandler (EditCommands.Redo)]
+ protected void OnUpdateRedo (CommandInfo cinfo)
+ {
+ cinfo.Enabled = actionsBox != null && actionsBox.UndoQueue.CanRedo;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ChangeLog
new file mode 100644
index 0000000000..a57bb556bb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ChangeLog
@@ -0,0 +1,101 @@
+2010-10-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderView.cs:
+ * GuiBuilderWindow.cs:
+ * GuiBuilderProject.cs:
+
+2010-09-08 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderWindow.cs:
+ * GuiBuilderService.cs:
+ * CombinedDesignView.cs:
+
+2010-08-30 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderProject.cs:
+
+2010-08-16 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderView.cs:
+ * ActionGroupView.cs:
+ * GuiBuilderProject.cs:
+ * GuiBuilderService.cs:
+ * GuiBuilderDisplayBinding.cs:
+ * ActionGroupDisplayBinding.cs:
+ * GtkProjectServiceExtension.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderProject.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderProject.cs:
+ * GuiBuilderService.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderView.cs:
+ * GuiBuilderProject.cs:
+ * GuiBuilderService.cs:
+ * GuiBuilderDisplayBinding.cs:
+ * ActionGroupDisplayBinding.cs:
+
+2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderProject.cs: Generate stetic code after a project converting
+ * GuiBuilderService.cs:
+ * GuiBuilderDisplayBinding.cs: Don't use component display binding for
+ generated partial files
+
+2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderView.cs: Raise OnDirtyChanged after saving.
+ * CombinedDesignView.cs: Track Api Changes.
+
+2010-08-05 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiBuilderView.cs: Remove ModifiedChanged handler
+
+2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
+
+ * CodeBinder.cs: Bump Api
+ * GuiBuilderWindow.cs:
+ * GuiBuilderService.cs:
+ * CombinedDesignView.cs:
+ * ActionGroupDisplayBinding.cs:
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderProject.cs: When Updatinglibraries don't save
+ if Stetic.Project was uninitialized
+
+2010-07-27 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderView.cs:
+ * CombinedDesignView.cs:
+
+2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderProject.cs:
+ * GuiBuilderService.cs:
+
+2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderProject.cs:
+ * CombinedDesignView.cs:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderProject.cs:
+
+2010-06-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderProject.cs: Add Convert method
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiBuilderProject.cs:
+ * GuiBuilderService.cs:
+ * GtkProjectServiceExtension.cs:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ClassUtils.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ClassUtils.cs
new file mode 100644
index 0000000000..ec5c5ea988
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ClassUtils.cs
@@ -0,0 +1,64 @@
+//
+// ClassUtils.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Gtk;
+using System;
+using System.Collections;
+using System.CodeDom;
+using MonoDevelop.Projects.Dom;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ internal class ClassUtils
+ {
+ public static IField FindWidgetField (IType cls, string name)
+ {
+ foreach (IField field in cls.Fields) {
+ if (name == GetWidgetFieldName (field))
+ return field;
+ }
+ return null;
+ }
+
+ public static string GetWidgetFieldName (IField field)
+ {
+ foreach (IAttribute att in field.Attributes) {
+ if (att.Name == "Glade.Widget" || att.Name == "Widget" || att.Name == "Glade.WidgetAttribute" || att.Name == "WidgetAttribute") {
+ if (att.PositionalArguments != null && att.PositionalArguments.Count > 0) {
+ CodePrimitiveExpression exp = att.PositionalArguments [0] as CodePrimitiveExpression;
+ if (exp != null)
+ return exp.Value.ToString ();
+ } else {
+ return field.Name;
+ }
+ }
+ }
+ return field.Name;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs
new file mode 100644
index 0000000000..fc19797521
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs
@@ -0,0 +1,360 @@
+//
+// CodeBinder.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System.CodeDom;
+using System.Collections;
+
+using MonoDevelop.Core;
+using MonoDevelop.Core.ProgressMonitoring;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Text;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Projects.CodeGeneration;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.GtkCore.Dialogs;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ /// This class provides several methods for managing the relation
+ /// between an object (e.g. a window) and the source code that will implement the
+ /// code for that object.
+ ///
+ /// Once created, a CodeBinder object will keep track of the class bound to the
+ /// object. If the class is renamed, it will properly update the object name.
+
+ public class CodeBinder
+ {
+ ITextFileProvider textFileProvider;
+ Stetic.Component targetObject;
+ Project project;
+ GuiBuilderProject gproject;
+ string className;
+ string classFile;
+
+ public CodeBinder (Project project, ITextFileProvider textFileProvider, Stetic.Component targetObject)
+ {
+ this.project = project;
+ this.textFileProvider = textFileProvider;
+
+ gproject = GtkDesignInfo.FromProject (project).GuiBuilderProject;
+
+ TargetObject = targetObject;
+ }
+
+ public Stetic.Component TargetObject {
+ get { return targetObject; }
+ set {
+ this.targetObject = value;
+ if (targetObject != null) {
+ IType cls = gproject.FindClass (GetClassName (targetObject));
+ if (cls != null) {
+ className = cls.FullName;
+ classFile = cls.CompilationUnit.FileName;
+ }
+ }
+ }
+ }
+
+ /// Synchronizes the bindings between the object and the source code
+ public void UpdateBindings (string fileName)
+ {
+ if (targetObject == null)
+ return;
+#if TRUNK
+ ParsedDocument doc = ProjectDomService.Parse (project, fileName);
+#else
+ ParsedDocument doc = ProjectDomService.Parse (project, fileName, null);
+#endif
+ classFile = fileName;
+
+ if (doc != null && doc.CompilationUnit != null) {
+ IType cls = GetClass ();
+ UpdateBindings (targetObject, cls);
+
+ if (cls != null)
+ targetObject.GeneratePublic = cls.IsPublic;
+ }
+ }
+
+ void UpdateBindings (Stetic.Component obj, IType cls)
+ {
+ if (targetObject == null)
+ return;
+
+ // Remove signals for which there isn't a handler in the class
+
+ Stetic.SignalCollection objectSignals = obj.GetSignals ();
+ if (objectSignals != null) {
+ Stetic.Signal[] signals = new Stetic.Signal [objectSignals.Count];
+ objectSignals.CopyTo (signals, 0);
+
+ foreach (Stetic.Signal signal in signals) {
+ if (FindSignalHandler (cls, signal) == null) {
+ obj.RemoveSignal (signal);
+ }
+ }
+ }
+
+ // Update children
+
+ foreach (Stetic.Component ob in obj.GetChildren ())
+ UpdateBindings (ob, cls);
+ }
+
+ IMethod FindSignalHandler (IType cls, Stetic.Signal signal)
+ {
+ foreach (IMethod met in cls.Methods) {
+ if (met.Name == signal.Handler) {
+ return met;
+ }
+ }
+ return null;
+ }
+
+ public void UpdateField (Stetic.Component obj, string oldName)
+ {
+ if (targetObject == null)
+ return;
+
+ CodeRefactorer cr = GetCodeGenerator ();
+
+ IType cls;
+
+ if (obj == targetObject)
+ return; // The root widget name can only be changed internally.
+ else
+ cls = GetClass (false);
+
+ string newName = GetObjectName (obj);
+ if (newName.Length == 0)
+ return;
+
+ if (cls != null) {
+ IField f = ClassUtils.FindWidgetField (cls, oldName);
+ if (f != null) {
+ cr.RenameMember (new NullProgressMonitor (), cls, f, newName, RefactoryScope.File);
+ }
+ }
+ }
+
+ /// Adds a signal handler to the class
+ public void BindSignal (Stetic.Signal signal)
+ {
+ if (targetObject == null)
+ return;
+
+ IType cls = GetClass ();
+ if (cls == null)
+ return;
+
+ if (FindSignalHandler (cls, signal) != null)
+ return;
+
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = signal.Handler;
+ met.Attributes = MemberAttributes.Family;
+ met.ReturnType = new CodeTypeReference (signal.SignalDescriptor.HandlerReturnTypeName);
+
+ foreach (Stetic.ParameterDescriptor pinfo in signal.SignalDescriptor.HandlerParameters)
+ met.Parameters.Add (new CodeParameterDeclarationExpression (pinfo.TypeName, pinfo.Name));
+ CodeRefactorer gen = GetCodeGenerator ();
+ gen.AddMember (cls, met);
+ }
+
+ public void UpdateSignal (Stetic.Signal oldSignal, Stetic.Signal newSignal)
+ {
+ if (targetObject == null)
+ return;
+
+ if (oldSignal.Handler == newSignal.Handler)
+ return;
+
+ IType cls = GetClass ();
+ if (cls == null) return;
+
+ IMethod met = FindSignalHandler (cls, oldSignal);
+ if (met == null) return;
+ CodeRefactorer gen = GetCodeGenerator ();
+ gen.RenameMember (new NullProgressMonitor (), cls, met, newSignal.Handler, RefactoryScope.File);
+ }
+
+ /// Adds a field to the class
+ public void BindToField (Stetic.Component obj)
+ {
+ if (targetObject == null)
+ return;
+
+ string name = GetMemberName (obj);
+ IType cls = GetClass ();
+
+ if (FindField (cls, name) != null)
+ return;
+
+ Document doc = IdeApp.Workbench.OpenDocument (cls.CompilationUnit.FileName, true);
+
+ IEditableTextFile editor = doc.GetContent<IEditableTextFile> ();
+ if (editor != null) {
+ CodeRefactorer gen = GetCodeGenerator ();
+ gen.AddMember (cls, GetFieldCode (obj, name));
+ }
+ }
+
+ CodeMemberField GetFieldCode (Stetic.Component obj, string name)
+ {
+ string type = obj.Type.ClassName;
+ CodeMemberField field = new CodeMemberField (type, name);
+ field.Attributes = MemberAttributes.Family;
+ return field;
+ }
+
+ IField FindField (IType cls, string name)
+ {
+ foreach (IField field in cls.Fields)
+ if (field.Name == name)
+ return field;
+ return null;
+ }
+
+ CodeRefactorer GetCodeGenerator ()
+ {
+ CodeRefactorer cr = new CodeRefactorer (project.ParentSolution);
+ cr.TextFileProvider = textFileProvider;
+ return cr;
+ }
+
+ public IType GetClass ()
+ {
+ return GetClass (true);
+ }
+
+ public IType GetClass (bool getUserClass)
+ {
+ if (targetObject == null)
+ return null;
+
+ IType cls = gproject.FindClass (className, getUserClass);
+ if (cls != null)
+ return cls;
+
+ // The class name may have changed. Try to guess the new name.
+
+ ArrayList matches = new ArrayList ();
+ ICompilationUnit unit = null;
+ ProjectDom ctx = gproject.GetParserContext ();
+#if TRUNK
+ ParsedDocument doc = ProjectDomService.Parse (project, classFile);
+#else
+ ParsedDocument doc = ProjectDomService.Parse (project, classFile, null);
+#endif
+
+ if (doc != null && doc.CompilationUnit != null) {
+ unit = doc.CompilationUnit;
+ foreach (IType fcls in unit.Types) {
+ if (IsValidClass (ctx, fcls, targetObject))
+ matches.Add (fcls);
+ }
+ }
+
+ // If found the class, just return it
+ if (matches.Count == 1) {
+ cls = (IType) matches [0];
+ className = cls.FullName;
+ targetObject.Name = className;
+ gproject.Save (true);
+ return cls;
+ }
+
+ // If not found, warn the user.
+
+ if (unit != null && unit.Types.Count > 0) {
+ using (SelectRenamedClassDialog dialog = new SelectRenamedClassDialog (unit.Types)) {
+ if (dialog.Run ()) {
+ className = dialog.SelectedClass;
+ if (className == null)
+ return null;
+ else {
+ targetObject.Name = className;
+ gproject.Save (true);
+ return gproject.FindClass (className);
+ }
+ }
+ }
+ } else {
+ MessageService.ShowError (GettextCatalog.GetString ("The class bound to the component '{0}' could not be found. This may be due to syntax errors in the source code file.", GetObjectName(targetObject)));
+ }
+
+ return null;
+ }
+
+ static bool IsValidClass (ProjectDom ctx, IType cls, Stetic.Component obj)
+ {
+ if (cls.BaseTypes != null) {
+ string typeName = obj.Type.ClassName;
+
+ foreach (IReturnType bt in cls.BaseTypes) {
+ System.Console.WriteLine("tn:" + typeName + " bt:" + bt.FullName);
+ if (bt.FullName == typeName)
+ return true;
+
+ IType baseCls = ctx.GetType (bt);
+ if (baseCls != null && IsValidClass (ctx, baseCls, obj))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ internal static string GetClassName (Stetic.Component obj)
+ {
+ return GetObjectName (obj);
+ }
+
+ internal static string GetMemberName (Stetic.Component obj)
+ {
+ return obj.Name;
+ }
+
+ internal static string GetObjectName (Stetic.Component obj)
+ {
+ return obj.Name;
+ }
+
+ internal static string GetClassName (Stetic.ProjectItemInfo obj)
+ {
+ return GetObjectName (obj);
+ }
+
+ internal static string GetObjectName (Stetic.ProjectItemInfo obj)
+ {
+ return obj.Name;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs
new file mode 100644
index 0000000000..b7e3313317
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs
@@ -0,0 +1,307 @@
+//
+// CombinedDesignView.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using Gtk;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui.Content;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class CombinedDesignView : AbstractViewContent
+ {
+ IViewContent content;
+ Gtk.Notebook notebook;
+ VBox box;
+ Toolbar toolbar;
+
+ bool updating;
+
+ public CombinedDesignView (IViewContent content)
+ {
+ this.content = content;
+ if (content is IEditableTextBuffer) {
+ ((IEditableTextBuffer)content).CaretPositionSet += delegate {
+ ShowPage (0);
+ };
+ }
+ content.ContentChanged += new EventHandler (OnTextContentChanged);
+ content.DirtyChanged += new EventHandler (OnTextDirtyChanged);
+
+ notebook = new Gtk.Notebook ();
+
+ // Main notebook
+
+ notebook.TabPos = Gtk.PositionType.Bottom;
+ notebook.ShowTabs = false;
+ notebook.ShowBorder = false;
+ notebook.Show ();
+ box = new VBox ();
+
+ // Bottom toolbar
+
+ toolbar = new Toolbar ();
+ toolbar.IconSize = IconSize.SmallToolbar;
+ toolbar.ToolbarStyle = ToolbarStyle.BothHoriz;
+ toolbar.ShowArrow = false;
+
+ CommandRouterContainer crc = new CommandRouterContainer (content.Control, content, true);
+ crc.Show ();
+ AddButton (GettextCatalog.GetString ("Source Code"), crc).Active = true;
+
+ toolbar.ShowAll ();
+
+ box.PackStart (notebook, true, true, 0);
+ box.PackStart (toolbar, false, false, 0);
+
+ box.Show ();
+
+ IdeApp.Workbench.ActiveDocumentChanged += new EventHandler (OnActiveDocumentChanged);
+ content.Control.Realized += delegate {
+ if (content != null && content.WorkbenchWindow != null)
+ content.WorkbenchWindow.ActiveViewContent = notebook.CurrentPageWidget == content.Control ? content : this;
+ };
+ notebook.SwitchPage += delegate {
+ if (content != null && content.WorkbenchWindow != null)
+ content.WorkbenchWindow.ActiveViewContent = notebook.CurrentPageWidget == content.Control ? content : this;
+ };
+ }
+
+ public virtual Stetic.Designer Designer {
+ get { return null; }
+ }
+
+ protected ToggleToolButton AddButton (string label, Gtk.Widget page)
+ {
+ updating = true;
+ ToggleToolButton button = new ToggleToolButton ();
+ button.Label = label;
+ button.IsImportant = true;
+ button.Clicked += new EventHandler (OnButtonToggled);
+ button.ShowAll ();
+ toolbar.Insert (button, -1);
+ notebook.AppendPage (page, new Gtk.Label ());
+ updating = false;
+ return button;
+ }
+
+ public bool HasPage (Gtk.Widget page)
+ {
+ return notebook.PageNum (page) != -1;
+ }
+
+ public void RemoveButton (Gtk.Widget page)
+ {
+ int i = notebook.PageNum (page);
+ if (i != -1)
+ RemoveButton (i);
+ }
+
+ public void RemoveButton (int npage)
+ {
+ if (npage >= toolbar.Children.Length)
+ return;
+ notebook.RemovePage (npage);
+ Gtk.Widget cw = toolbar.Children [npage];
+ toolbar.Remove (cw);
+ cw.Destroy ();
+ ShowPage (0);
+ }
+
+ public override MonoDevelop.Projects.Project Project {
+ get { return base.Project; }
+ set {
+ base.Project = value;
+ content.Project = value;
+ }
+ }
+
+ protected override void OnWorkbenchWindowChanged (EventArgs e)
+ {
+ base.OnWorkbenchWindowChanged (e);
+ content.WorkbenchWindow = WorkbenchWindow;
+ }
+
+ void OnButtonToggled (object s, EventArgs args)
+ {
+ int i = Array.IndexOf (toolbar.Children, s);
+ if (i != -1)
+ ShowPage (i);
+ }
+
+ public virtual void ShowPage (int npage)
+ {
+ if (notebook.CurrentPage == npage)
+ return;
+
+ if (updating) return;
+ updating = true;
+
+ notebook.CurrentPage = npage;
+ Gtk.Widget[] buttons = toolbar.Children;
+ for (int n=0; n<buttons.Length; n++) {
+ ToggleToolButton b = (ToggleToolButton) buttons [n];
+ b.Active = (n == npage);
+ }
+ updating = false;
+ }
+
+ public override void Dispose ()
+ {
+ content.ContentChanged -= new EventHandler (OnTextContentChanged);
+ content.DirtyChanged -= new EventHandler (OnTextDirtyChanged);
+ IdeApp.Workbench.ActiveDocumentChanged -= new EventHandler (OnActiveDocumentChanged);
+ content.Dispose ();
+
+ // Remove and destroy the contents of the Notebook, since the destroy event is
+ // not propagated to pages in some gtk versions.
+
+ foreach (Gtk.Widget cw in notebook.Children) {
+ Gtk.Widget lw = notebook.GetTabLabel (cw);
+ notebook.Remove (cw);
+ cw.Destroy ();
+ if (lw != null)
+ lw.Destroy ();
+ }
+ content = null;
+ box = null;
+
+ base.Dispose ();
+ }
+
+ public override void Load (string fileName)
+ {
+ ShowPage (1);
+ ContentName = fileName;
+ content.Load (fileName);
+ }
+
+ public override Gtk.Widget Control {
+ get { return box; }
+ }
+
+ public override void Save (string fileName)
+ {
+ content.Save (fileName);
+ }
+
+ public override bool IsDirty {
+ get {
+ return content.IsDirty;
+ }
+ set {
+ content.IsDirty = value;
+ }
+ }
+
+ public override bool IsReadOnly
+ {
+ get {
+ return content.IsReadOnly;
+ }
+ }
+
+ public virtual void AddCurrentWidgetToClass ()
+ {
+ }
+
+ public virtual void JumpToSignalHandler (Stetic.Signal signal)
+ {
+ }
+
+ void OnTextContentChanged (object s, EventArgs args)
+ {
+ OnContentChanged (args);
+ }
+
+ void OnTextDirtyChanged (object s, EventArgs args)
+ {
+ OnDirtyChanged (args);
+ }
+
+ void OnActiveDocumentChanged (object s, EventArgs args)
+ {
+ if (IdeApp.Workbench.ActiveDocument != null && IdeApp.Workbench.ActiveDocument.GetContent<CombinedDesignView>() == this)
+ OnDocumentActivated ();
+ }
+
+ protected virtual void OnDocumentActivated ()
+ {
+ }
+
+#if TRUNK
+ public override T GetContent<T> ()
+ {
+// if (type == typeof(IEditableTextBuffer)) {
+// // Intercept the IPositionable interface, since we need to
+// // switch to the text editor when jumping to a line
+// if (content.GetContent (type) != null)
+// return this;
+// else
+// return null;
+// }
+//
+ return base.GetContent<T> () ?? content.GetContent<T> ();
+ }
+
+ public void JumpTo (int line, int column)
+ {
+ IEditableTextBuffer ip = content.GetContent<IEditableTextBuffer> ();
+ if (ip != null) {
+ ShowPage (0);
+ ip.SetCaretTo (line, column);
+ }
+ }
+#else
+ public override object GetContent (Type contentType)
+ {
+ object ob = base.GetContent (contentType);
+ if (ob != null)
+ return ob;
+ else if (content != null)
+ return content.GetContent (contentType);
+ else
+ return null;
+ }
+
+ public void JumpTo (int line, int column)
+ {
+ IEditableTextBuffer ip = (IEditableTextBuffer) content.GetContent (typeof (IEditableTextBuffer));
+ if (ip != null) {
+ ShowPage (0);
+ ip.SetCaretTo (line, column);
+ }
+ }
+#endif
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs
new file mode 100644
index 0000000000..2570dc6d09
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs
@@ -0,0 +1,71 @@
+
+using System;
+using System.Threading;
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class GtkProjectServiceExtension: ProjectServiceExtension
+ {
+ public override bool SupportsItem (IBuildTarget item)
+ {
+ if (!IdeApp.IsInitialized)
+ return false;
+
+ DotNetProject project = item as DotNetProject;
+ return project != null && GtkDesignInfo.HasDesignedObjects (project);
+ }
+
+ protected override BuildResult Build (IProgressMonitor monitor, SolutionEntityItem entry, ConfigurationSelector configuration)
+ {
+ DotNetProject project = (DotNetProject) entry;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+
+ // The code generator must run in the GUI thread since it needs to
+ // access to Gtk classes
+ Generator gen = new Generator ();
+ lock (gen) {
+ Gtk.Application.Invoke (delegate { gen.Run (monitor, project, configuration); });
+ Monitor.Wait (gen);
+ }
+
+ BuildResult res = base.Build (monitor, entry, configuration);
+
+ if (gen.Messages != null) {
+ foreach (string s in gen.Messages)
+// res.AddWarning (info.GuiBuilderProject.File, 0, 0, null, s);
+// TODO: Add gtkx file name in the Generator
+ res.AddWarning ("", 0, 0, null, s);
+
+ if (gen.Messages.Length > 0)
+ info.ForceCodeGenerationOnBuild ();
+ }
+ return res;
+ }
+
+
+ }
+
+ class Generator
+ {
+ public void Run (IProgressMonitor monitor, DotNetProject project, ConfigurationSelector configuration)
+ {
+ lock (this) {
+ try {
+ Stetic.CodeGenerationResult res = GuiBuilderService.GenerateSteticCode (monitor, project, configuration);
+ if (res != null)
+ Messages = res.Warnings;
+ } catch (Exception ex) {
+ Error = ex;
+ LoggingService.LogError (ex.ToString ());
+ Messages = new string [] { Error.Message };
+ }
+ Monitor.PulseAll (this);
+ }
+ }
+ public string[] Messages;
+ public Exception Error;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs
new file mode 100644
index 0000000000..b496919221
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs
@@ -0,0 +1,105 @@
+//
+// GuiBuilderDisplayBinding.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class GuiBuilderDisplayBinding : DisplayBinding
+ {
+ bool excludeThis = false;
+
+ public override string Name {
+ get { return "Window Designer"; }
+ }
+
+ public override bool CanCreateContentForUri (string fileName)
+ {
+ Project project = IdeApp.Workspace.GetProjectContainingFile (fileName);
+ GtkDesignInfo info = GtkDesignInfo.FromProject ((DotNetProject) project);
+
+ if (excludeThis) return false;
+
+ if (fileName.Contains (info.BuildFileExtension))
+ return false;
+
+ if (GetWindow (fileName) == null)
+ return false;
+
+ excludeThis = true;
+ var db = DisplayBindingService.GetDefaultBindingForUri (fileName);
+ excludeThis = false;
+ return db != null;
+ }
+
+ public override IViewContent CreateContentForUri (string fileName)
+ {
+ excludeThis = true;
+ var db = DisplayBindingService.GetDefaultBindingForUri (fileName);
+ GuiBuilderView view = new GuiBuilderView (db.CreateContentForUri (fileName), GetWindow (fileName));
+ excludeThis = false;
+ return view;
+ }
+
+ internal static GuiBuilderWindow GetWindow (string file)
+ {
+ if (!IdeApp.Workspace.IsOpen)
+ return null;
+
+ Project project = null;
+ foreach (Project p in IdeApp.Workspace.GetAllProjects ()) {
+ if (p.IsFileInProject (file)) {
+ project = p;
+ break;
+ }
+ }
+
+ if (!GtkDesignInfo.HasDesignedObjects (project))
+ return null;
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ if (file.StartsWith (info.SteticFolder))
+ return null;
+
+ ParsedDocument doc = ProjectDomService.GetParsedDocument (null, file);
+ if (doc == null || doc.CompilationUnit == null)
+ return null;
+
+ foreach (IType t in doc.CompilationUnit.Types) {
+ GuiBuilderWindow win = info.GuiBuilderProject.GetWindowForClass (t.FullName);
+ if (win != null)
+ return win;
+ }
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs
new file mode 100644
index 0000000000..8cbf2677bb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDocumentOutline.cs
@@ -0,0 +1,104 @@
+//
+// GuiBuilderProjectPad.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using Gtk;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.DesignerSupport;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ internal class GuiBuilderDocumentOutline: Alignment, ICustomPropertyPadProvider
+ {
+ static GuiBuilderDocumentOutline instance;
+
+ GuiBuilderDocumentOutline () : base (0, 0, 1, 1)
+ {
+ BorderWidth = 0;
+ GuiBuilderService.SteticApp.WidgetTreeWidget.BorderWidth = 0;
+ Add (GuiBuilderService.SteticApp.WidgetTreeWidget);
+ ShowAll ();
+ }
+
+ internal static GuiBuilderDocumentOutline Instance {
+ get {
+ if (instance == null)
+ instance = new GuiBuilderDocumentOutline ();
+ return instance;
+ }
+ }
+
+ Gtk.Widget ICustomPropertyPadProvider.GetCustomPropertyWidget ()
+ {
+ return PropertiesWidget.Instance;
+ }
+
+ void ICustomPropertyPadProvider.DisposeCustomPropertyWidget ()
+ {
+ }
+
+ [CommandHandler (EditCommands.Undo)]
+ protected void OnUndo ()
+ {
+// GuiBuilderService.App.CommandUndo ();
+ }
+
+ [CommandHandler (EditCommands.Redo)]
+ protected void OnRedo ()
+ {
+// GuiBuilderService.App.CommandRedo ();
+ }
+
+ [CommandHandler (EditCommands.Copy)]
+ protected void OnCopy ()
+ {
+// GuiBuilderService.App.CommandCopy ();
+ }
+
+ [CommandHandler (EditCommands.Cut)]
+ protected void OnCut ()
+ {
+// GuiBuilderService.App.CommandCut ();
+ }
+
+ [CommandHandler (EditCommands.Paste)]
+ protected void OnPaste ()
+ {
+// GuiBuilderService.App.CommandPaste ();
+ }
+
+ [CommandHandler (EditCommands.Delete)]
+ protected void OnDelete ()
+ {
+// GuiBuilderService.App.CommandDelete ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs
new file mode 100644
index 0000000000..5dd66c5b6d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs
@@ -0,0 +1,743 @@
+//
+// GuiBuilderProject.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Krzysztof Marecki
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.CodeDom.Compiler;
+
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class GuiBuilderProject
+ {
+ //to save temporarily GuiBuilderWindow while files are being moved between projects
+ static List<GuiBuilderWindow> formInfosRemoved;
+
+ internal object MemoryProbe = Counters.GuiProjectsInMemory.CreateMemoryProbe ();
+
+ List<GuiBuilderWindow> formInfos;
+ Stetic.Project gproject;
+ DotNetProject project;
+ string folderName;
+ bool hasError;
+ bool needsUpdate = true;
+
+ FileSystemWatcher watcher;
+ DateTime lastSaveTime;
+ object fileSaveLock = new object ();
+ bool disposed;
+ bool librariesUpdated;
+
+ public event WindowEventHandler WindowAdded;
+ public event WindowEventHandler WindowRemoved;
+ public event EventHandler Reloaded;
+ public event EventHandler Unloaded;
+ public event EventHandler Changed;
+
+ static GuiBuilderProject ()
+ {
+ formInfosRemoved = new List<GuiBuilderWindow> ();
+ }
+
+ public GuiBuilderProject (DotNetProject project, string folderName)
+ {
+ this.folderName = folderName;
+ this.project = project;
+ Counters.GuiProjectsLoaded++;
+ }
+
+ public void Convert (string guiFolderName, bool makeBackup)
+ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ Stetic.Project gproject = GuiBuilderService.SteticApp.CreateProject (info);
+ //Stetic.Project does not implement IDisposable
+ try {
+ string newGuiFolderName = project.BaseDirectory.Combine (guiFolderName);
+ gproject.ConvertProject (info.SteticFile, newGuiFolderName);
+ info.ConvertGtkFolder (guiFolderName, makeBackup);
+ info.UpdateGtkFolder ();
+ folderName = newGuiFolderName;
+ IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBuildProgressMonitor ();
+ try {
+ ConfigurationSelector configuration = IdeApp.Workspace.ActiveConfiguration;
+ Generator generator = new Generator ();
+ generator.Run (monitor, project, configuration);
+ monitor.ReportSuccess ("Converting was succesfull");
+ } finally {
+ monitor.Dispose ();
+ }
+ } finally {
+ gproject.Dispose ();
+ }
+ }
+
+ public void GenerateCode (string componentFile)
+ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ string gtkxFile = info.GetDesignerFileFromComponent (componentFile);
+ if (gtkxFile != null && File.Exists (gtkxFile)) {
+
+ Save (false);
+ FileInfo fi = new FileInfo (gtkxFile);
+ fi.LastWriteTime = DateTime.Now;
+
+ IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBuildProgressMonitor ();
+ try {
+ ConfigurationSelector configuration = IdeApp.Workspace.ActiveConfiguration;
+ Generator generator = new Generator ();
+ generator.Run (monitor, project, configuration);
+ } finally {
+ monitor.Dispose ();
+ }
+ }
+ }
+
+ void Load ()
+ {
+ if (gproject != null || disposed || folderName == null)
+ return;
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ gproject = GuiBuilderService.SteticApp.CreateProject (info);
+ formInfos = new List<GuiBuilderWindow> ();
+
+// TODO : when expanding project, UpdateGtkFolder causes in throwing exception by gtk
+// info.UpdateGtkFolder ();
+
+ try {
+ gproject.Load (folderName);
+ } catch (Exception ex) {
+ MessageService.ShowException (ex, GettextCatalog.GetString ("The GUI designer project folder '{0}' could not be loaded.", folderName));
+ hasError = true;
+ }
+
+ Counters.SteticProjectsLoaded++;
+ gproject.ResourceProvider = GtkDesignInfo.FromProject (project).ResourceProvider;
+// gproject.DesignInfo = info;
+ gproject.WidgetAdded += OnAddWidget;
+ gproject.WidgetRemoved += OnRemoveWidget;
+ gproject.ActionGroupsChanged += OnGroupsChanged;
+ project.FileAddedToProject += OnFileAdded;
+ project.FileRemovedFromProject += OnFileRemoved;
+ project.ReferenceAddedToProject += OnReferenceAdded;
+ project.ReferenceRemovedFromProject += OnReferenceRemoved;
+
+ foreach (Stetic.WidgetInfo ob in gproject.Widgets)
+ RegisterWindow (ob, false);
+ }
+
+ void Unload ()
+ {
+ if (gproject == null)
+ return;
+
+ Counters.SteticProjectsLoaded--;
+
+ if (Unloaded != null)
+ Unloaded (this, EventArgs.Empty);
+ if (formInfos != null) {
+ foreach (GuiBuilderWindow win in formInfos)
+ win.Dispose ();
+ formInfos = null;
+ }
+ if (gproject != null) {
+ gproject.WidgetAdded -= OnAddWidget;
+ gproject.WidgetRemoved -= OnRemoveWidget;
+ gproject.ActionGroupsChanged -= OnGroupsChanged;
+ gproject.Dispose ();
+ gproject = null;
+ }
+ if (project != null) {
+ project.FileAddedToProject -= OnFileAdded;
+ project.FileRemovedFromProject -= OnFileRemoved;
+ project.ReferenceAddedToProject -= OnReferenceAdded;
+ project.ReferenceRemovedFromProject -= OnReferenceRemoved;
+ }
+ needsUpdate = true;
+ hasError = false;
+ librariesUpdated = false;
+ if (watcher != null) {
+ watcher.Dispose ();
+ watcher = null;
+ }
+ NotifyChanged ();
+ }
+
+ void OnSteticFileChanged (object s, FileSystemEventArgs args)
+ {
+ lock (fileSaveLock) {
+ if (lastSaveTime == System.IO.File.GetLastWriteTime (folderName))
+ return;
+ }
+
+ if (GuiBuilderService.HasOpenDesigners (project, true)) {
+ if (MessageService.AskQuestion (GettextCatalog.GetString ("The project '{0}' has been modified by an external application. Do you want to reload it?", project.Name), GettextCatalog.GetString ("Unsaved changes in the open GTK designers will be lost."), AlertButton.Cancel, AlertButton.Reload) != AlertButton.Reload)
+ return;
+ }
+ if (!disposed)
+ Reload ();
+ }
+
+ public void Reload ()
+ {
+ if (disposed)
+ return;
+ Unload ();
+ if (Reloaded != null)
+ Reloaded (this, EventArgs.Empty);
+ NotifyChanged ();
+ }
+
+ public void ReloadFile (string fileName)
+ {
+ GuiBuilderWindow window = GetWindowForFile (fileName);
+ if (window != null) {
+ var root = window.RootWidget;
+ UnregisterWindow (window);
+ gproject.ReloadComponent (window.Name);
+ RegisterWindow (root, false);
+ }
+ }
+
+ public bool HasError {
+ get { return hasError; }
+ }
+
+ public bool IsEmpty {
+ get {
+ // If the project is not loaded, assume not empty
+ return gproject != null && Windows != null && Windows.Count == 0;
+ }
+ }
+
+ public void Save (bool saveMdProject)
+ {
+ if (disposed)
+ return;
+
+ if (gproject != null && !hasError) {
+ lock (fileSaveLock) {
+ gproject.Save (folderName);
+ lastSaveTime = System.IO.File.GetLastWriteTime (folderName);
+ }
+ }
+
+ if (GtkDesignInfo.FromProject (project).UpdateGtkFolder () && saveMdProject)
+ IdeApp.ProjectOperations.Save (project);
+ }
+
+ public Stetic.Project SteticProject {
+ get {
+ Load ();
+ return gproject;
+
+ }
+ }
+
+ public ICollection<GuiBuilderWindow> Windows {
+ get {
+ Load ();
+ return formInfos;
+ }
+ }
+
+ public DotNetProject Project {
+ get { return project; }
+ }
+
+ public void Dispose ()
+ {
+ if (disposed)
+ return;
+ Counters.GuiProjectsLoaded--;
+ disposed = true;
+ if (watcher != null)
+ watcher.Dispose ();
+ Unload ();
+ }
+
+ public Stetic.WidgetInfo AddNewComponent (Stetic.ComponentType type, string name)
+ {
+ Stetic.WidgetInfo c = SteticProject.AddNewComponent (type, name);
+ RegisterWindow (c, true);
+ return c;
+ }
+
+ public Stetic.WidgetInfo AddNewComponent (XmlElement element)
+ {
+ Stetic.WidgetInfo c = SteticProject.AddNewComponent (element);
+ // Register the window now, don't wait for the WidgetAdded event since
+ // it may take some time, and the GuiBuilderWindow object is needed
+ // just after this call
+ RegisterWindow (c, true);
+ return c;
+ }
+
+ public void AddNewComponent (string fileName)
+ {
+ object ob = SteticProject.AddNewComponent (fileName);
+
+ if (ob is Stetic.WidgetInfo) {
+ var c = (Stetic.WidgetInfo) ob;
+ RegisterWindow (c, true);
+ }
+ }
+
+ public void RegisterWindow (Stetic.WidgetInfo widget, bool notify)
+ {
+ if (formInfos != null) {
+ foreach (GuiBuilderWindow w in formInfos)
+ if (w.RootWidget == widget)
+ return;
+
+ GuiBuilderWindow win = new GuiBuilderWindow (this, gproject, widget);
+ formInfos.Add (win);
+
+ GuiBuilderWindow winToRemove = null;
+ foreach (GuiBuilderWindow form in formInfosRemoved)
+ if (form.RootWidget == widget) {
+ winToRemove = form;
+ break;
+ }
+
+ if (winToRemove != null)
+ formInfosRemoved.Remove (winToRemove);
+
+ if (notify) {
+ if (WindowAdded != null)
+ WindowAdded (this, new WindowEventArgs (win));
+ NotifyChanged ();
+ }
+ }
+ }
+
+ public void UnregisterWindow (GuiBuilderWindow win)
+ {
+ if (!formInfos.Contains (win))
+ return;
+
+ formInfos.Remove (win);
+ formInfosRemoved.Add (win);
+
+ if (WindowRemoved != null)
+ WindowRemoved (this, new WindowEventArgs (win));
+
+ win.Dispose ();
+ NotifyChanged ();
+ }
+
+ public void Remove (GuiBuilderWindow win)
+ {
+ gproject.RemoveComponent (win.RootWidget);
+ UnregisterWindow (win);
+ }
+
+ public void RemoveActionGroup (Stetic.ActionGroupInfo group)
+ {
+ gproject.RemoveActionGroup (group);
+ }
+
+ void OnAddWidget (object s, Stetic.WidgetInfoEventArgs args)
+ {
+ if (!disposed)
+ RegisterWindow (args.WidgetInfo, true);
+ }
+
+ void OnRemoveWidget (object s, Stetic.WidgetInfoEventArgs args)
+ {
+ if (disposed || Windows == null)
+ return;
+ foreach (GuiBuilderWindow form in Windows) {
+ if (form.RootWidget.Name == args.WidgetInfo.Name) {
+ UnregisterWindow (form);
+ break;
+ }
+ }
+ }
+
+ void OnFileAdded (object sender, ProjectFileEventArgs args)
+ {
+ FilePath path = args.ProjectFile.FilePath;
+
+ if (path.Extension == ".gtkx") {
+ AddNewComponent (path);
+ }
+ }
+
+ void OnFileRemoved (object sender, ProjectFileEventArgs args)
+ {
+ ArrayList toDelete = new ArrayList ();
+ ArrayList toDeleteGroups = new ArrayList ();
+
+ ParsedDocument doc = ProjectDomService.GetParsedDocument (ProjectDomService.GetProjectDom (args.Project), args.ProjectFile.Name);
+ if (doc == null || doc.CompilationUnit == null)
+ return;
+
+ foreach (IType t in doc.CompilationUnit.Types) {
+ GuiBuilderWindow win = GetWindowForClass (t.FullName);
+ if (win != null) {
+ toDelete.Add (win);
+ continue;
+ }
+
+ Stetic.ActionGroupInfo group = GetActionGroup (t.FullName);
+ if (group != null) {
+ toDeleteGroups.Add (group);
+ }
+ }
+
+ foreach (GuiBuilderWindow win in toDelete)
+ Remove (win);
+
+ foreach (Stetic.ActionGroupInfo group in toDeleteGroups)
+ RemoveActionGroup (group);
+ }
+
+ void OnGroupsChanged (object s, EventArgs a)
+ {
+ if (!disposed)
+ NotifyChanged ();
+ }
+
+ void OnReferenceAdded (object ob, ProjectReferenceEventArgs args)
+ {
+ if (disposed || !librariesUpdated)
+ return;
+ string pref = GetReferenceLibraryPath (args.ProjectReference);
+ if (pref != null) {
+ gproject.AddWidgetLibrary (pref);
+ Save (false);
+ }
+ }
+
+ void OnReferenceRemoved (object ob, ProjectReferenceEventArgs args)
+ {
+ if (disposed || !librariesUpdated)
+ return;
+ string pref = GetReferenceLibraryPath (args.ProjectReference);
+ if (pref != null) {
+ gproject.RemoveWidgetLibrary (pref);
+ Save (false);
+ }
+ }
+
+ string GetReferenceLibraryPath (ProjectReference pref)
+ {
+ string path = null;
+
+ if (pref.ReferenceType == ReferenceType.Project) {
+ DotNetProject p = project.ParentSolution.FindProjectByName (pref.Reference) as DotNetProject;
+ if (p != null)
+ path = p.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration);
+ } else if (pref.ReferenceType == ReferenceType.Assembly) {
+ path = pref.Reference;
+ } else if (pref.ReferenceType == ReferenceType.Gac) {
+ path = pref.Reference;
+ }
+ if (path != null && GuiBuilderService.SteticApp.IsWidgetLibrary (path))
+ return path;
+ else
+ return null;
+ }
+
+ public void ImportGladeFile ()
+ {
+ var dlg = new MonoDevelop.Components.SelectFileDialog (GettextCatalog.GetString ("Open Glade File"));
+ dlg.AddFilter (GettextCatalog.GetString ("Glade files"), "*.glade");
+ dlg.AddAllFilesFilter ();
+ if (dlg.Run ()) {
+ SteticProject.ImportGlade (dlg.SelectedFile);
+ Save (true);
+ }
+ }
+
+ public GuiBuilderWindow GetWindowForClass (string className)
+ {
+ if (Windows != null) {
+ foreach (GuiBuilderWindow form in Windows) {
+ if (CodeBinder.GetObjectName (form.RootWidget) == className)
+ return form;
+ }
+ }
+
+ if (formInfosRemoved != null) {
+ foreach (GuiBuilderWindow form in formInfosRemoved) {
+ if (CodeBinder.GetObjectName (form.RootWidget) == className)
+ return form;
+ }
+ }
+ return null;
+ }
+
+ public GuiBuilderWindow GetWindowForFile (FilePath fileName)
+ {
+ if (Windows != null) {
+ foreach (GuiBuilderWindow win in Windows) {
+ if (fileName == win.SourceCodeFile)
+ return win;
+ }
+ }
+ return null;
+ }
+
+ public GuiBuilderWindow GetWindow (string name)
+ {
+ if (Windows != null) {
+ foreach (GuiBuilderWindow win in Windows) {
+ if (name == win.Name)
+ return win;
+ }
+ }
+ return null;
+ }
+
+ public Stetic.ActionGroupInfo GetActionGroupForFile (FilePath fileName)
+ {
+ foreach (Stetic.ActionGroupInfo group in SteticProject.ActionGroups) {
+ if (fileName == GetSourceCodeFile (group, true))
+ return group;
+ }
+ return null;
+ }
+
+ public Stetic.ActionGroupInfo GetActionGroup (string name)
+ {
+ return (SteticProject != null) ? SteticProject.GetActionGroup (name) : null;
+ }
+
+ public FilePath GetSourceCodeFile (Stetic.ProjectItemInfo obj)
+ {
+ return GetSourceCodeFile (obj, true);
+ }
+
+ public FilePath GetSourceCodeFile (Stetic.ProjectItemInfo obj, bool getUserClass)
+ {
+ IType cls = GetClass (obj, getUserClass);
+ if (cls != null && cls.CompilationUnit != null)
+ return cls.CompilationUnit.FileName;
+ return null;
+ }
+
+ IType GetClass (Stetic.ProjectItemInfo obj, bool getUserClass)
+ {
+ string name = CodeBinder.GetClassName (obj);
+ return FindClass (name, getUserClass);
+ }
+
+ public IType FindClass (string className)
+ {
+ return FindClass (className, true);
+ }
+
+ public IType FindClass (string className, bool getUserClass)
+ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ FilePath gui_folder = info.SteticFolder;
+ ProjectDom ctx = GetParserContext ();
+
+ if (ctx == null)
+ return null;
+ IEnumerable<IType> classes = ctx.Types;
+ if (classes == null)
+ return null;
+ foreach (IType cls in classes) {
+ if (cls.FullName == className) {
+ if (getUserClass) {
+ // Return this class only if it is declared outside the gtk-gui
+ // folder. Generated partial classes will be ignored.
+ foreach (IType part in cls.Parts) {
+ if (part.CompilationUnit.FileName.FullPath.IsChildPathOf (gui_folder))
+ continue;
+ if (part.CompilationUnit != null && !part.CompilationUnit.FileName.IsNullOrEmpty && !part.CompilationUnit.FileName.FileName.Contains (info.BuildFileExtension)) {
+ return part;
+ }
+ }
+ continue;
+ }
+ if (getUserClass && cls.CompilationUnit != null && !string.IsNullOrEmpty (cls.CompilationUnit.FileName) && cls.CompilationUnit.FileName.IsChildPathOf (gui_folder))
+ continue;
+ return cls;
+ }
+ }
+ return null;
+ }
+
+ public ProjectDom GetParserContext ()
+ {
+ ProjectDom dom = ProjectDomService.GetProjectDom (Project);
+ if (dom != null && needsUpdate) {
+ needsUpdate = false;
+ dom.ForceUpdate ();
+ }
+ return dom;
+ }
+
+ public WidgetParser WidgetParser {
+ get {
+ return new WidgetParser (GetParserContext ());
+ }
+ }
+
+ public void UpdateLibraries ()
+ {
+ if (hasError || disposed || gproject == null)
+ return;
+
+ bool needsSave = false;
+ librariesUpdated = true;
+
+ string[] oldLibs = gproject.WidgetLibraries;
+
+ ArrayList libs = new ArrayList ();
+ string[] internalLibs;
+
+ foreach (ProjectReference pref in project.References) {
+ string wref = GetReferenceLibraryPath (pref);
+ if (wref != null)
+ libs.Add (wref);
+ }
+
+ ReferenceManager refmgr = new ReferenceManager (project);
+ string target_version = refmgr.TargetGtkVersion;
+ refmgr.Dispose ();
+
+ // Make sure the target gtk version is properly set
+ if (gproject.TargetGtkVersion != target_version) {
+ if (gproject.TargetGtkVersion != string.Empty) {
+ needsSave = true;
+ }
+ gproject.TargetGtkVersion = target_version;
+ }
+
+ string outLib = project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration);
+ if (!string.IsNullOrEmpty (outLib))
+ internalLibs = new string [] { outLib };
+ else
+ internalLibs = new string [0];
+
+ string[] newLibs = (string[]) libs.ToArray (typeof(string));
+
+ // See if something has changed
+ if (LibrariesChanged (oldLibs, internalLibs, newLibs)) {
+ // If oldLibs is empty, gproject was uninitialized, so there are no changes to save
+ if (oldLibs.Length > 0) {
+ needsSave = true;
+ }
+ gproject.SetWidgetLibraries (newLibs, internalLibs);
+ } else {
+ GuiBuilderService.SteticApp.UpdateWidgetLibraries (false);
+ }
+
+ if (needsSave)
+ Save (true);
+ }
+
+ bool LibrariesChanged (string[] oldLibs, string[] internalLibs, string[] newLibs)
+ {
+ if (oldLibs.Length == newLibs.Length + internalLibs.Length) {
+ foreach (string s in newLibs) {
+ if (!((IList)oldLibs).Contains (s))
+ return true;
+ }
+ foreach (string s in internalLibs) {
+ if (!((IList)oldLibs).Contains (s))
+ return true;
+ }
+ return false;
+ } else
+ return true;
+ }
+
+ void NotifyChanged ()
+ {
+ if (Changed != null && !disposed)
+ Changed (this, EventArgs.Empty);
+ }
+
+ public StringCollection GenerateFiles (string guiFolder)
+ {
+ StringCollection files = new StringCollection ();
+
+ if (hasError)
+ return files;
+
+ IDotNetLanguageBinding binding = LanguageBindingService.GetBindingPerLanguageName (project.LanguageName) as IDotNetLanguageBinding;
+ CodeDomProvider provider = binding.GetCodeDomProvider ();
+
+ if (provider == null)
+ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
+// string path = Path.Combine (guiFolder, binding.GetFileName ("generated"));
+// if (!System.IO.File.Exists (path)) {
+// GuiBuilderService.SteticApp.GenerateProjectCode (path, "Stetic", provider, null);
+// }
+// files.Add (path);
+//
+// if (Windows != null) {
+// foreach (GuiBuilderWindow win in Windows)
+// files.Add (GuiBuilderService.GenerateSteticCodeStructure (project, win.RootWidget, true, false));
+// }
+//
+// foreach (Stetic.ActionGroupInfo ag in SteticProject.ActionGroups)
+// files.Add (GuiBuilderService.GenerateSteticCodeStructure (project, ag, true, false));
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ string extension = string.Format("{0}.{1}",info.BuildFileExtension, provider.FileExtension);
+ foreach (string file in Directory.GetFiles (guiFolder)) {
+ if (file.Contains (extension))
+ files.Add (file);
+ }
+
+ return files;
+ }
+ }
+
+ public delegate void WindowEventHandler (object s, WindowEventArgs args);
+
+ public class WindowEventArgs: EventArgs
+ {
+ GuiBuilderWindow win;
+
+ public WindowEventArgs (GuiBuilderWindow win)
+ {
+ this.win = win;
+ }
+
+ public GuiBuilderWindow Window {
+ get { return win; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs
new file mode 100644
index 0000000000..de0d2692ae
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs
@@ -0,0 +1,635 @@
+//
+// GuiBuilderService.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Projects.Text;
+using MonoDevelop.Core;
+using MonoDevelop.Core.Execution;
+using MonoDevelop.Deployment;
+using MonoDevelop.Projects.Policies;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ class GuiBuilderService
+ {
+ static string GuiBuilderLayout = "Visual Design";
+
+#if DUMMY_STRINGS_FOR_TRANSLATION_DO_NOT_COMPILE
+ private void DoNotCompile ()
+ {
+ //The default GUI Builder layout, translated indirectly because it's used as an ID
+ GettextCatalog.GetString ("GUI Builder");
+ }
+#endif
+
+ static string defaultLayout;
+
+ static Stetic.Application steticApp;
+
+ static bool generating;
+
+ static Stetic.IsolationMode IsolationMode = Stetic.IsolationMode.None;
+// static Stetic.IsolationMode IsolationMode = Stetic.IsolationMode.ProcessUnix;
+
+ static GuiBuilderService ()
+ {
+ if (IdeApp.Workbench == null)
+ return;
+ IdeApp.Workbench.ActiveDocumentChanged += new EventHandler (OnActiveDocumentChanged);
+ IdeApp.ProjectOperations.EndBuild += OnProjectCompiled;
+// IdeApp.Workspace.ParserDatabase.AssemblyInformationChanged += (AssemblyInformationEventHandler) DispatchService.GuiDispatch (new AssemblyInformationEventHandler (OnAssemblyInfoChanged));
+
+ IdeApp.Exited += delegate {
+ if (steticApp != null) {
+ StoreConfiguration ();
+ steticApp.Dispose ();
+ }
+ };
+ }
+
+ public static Stetic.Application SteticApp {
+ get {
+ // Stetic is not thread safe, so all has to be done in the gui thread
+ DispatchService.AssertGuiThread ();
+ if (steticApp == null) {
+ steticApp = Stetic.ApplicationFactory.CreateApplication (Stetic.IsolationMode.None);
+ steticApp.AllowInProcLibraries = false;
+ steticApp.ShowNonContainerWarning = PropertyService.Get ("MonoDevelop.GtkCore.ShowNonContainerWarning", true);
+ steticApp.MimeResolver = OnMimeResolve;
+ steticApp.ShowUrl = OnShowUrl;
+ steticApp.WidgetLibraryResolver = OnAssemblyResolve;
+ }
+ return steticApp;
+ }
+ }
+
+ static string OnAssemblyResolve (string assemblyName)
+ {
+ return Runtime.SystemAssemblyService.DefaultAssemblyContext.GetAssemblyLocation (assemblyName, null);
+ }
+
+ static string OnMimeResolve (string url)
+ {
+ return DesktopService.GetMimeTypeForUri (url);
+ }
+
+ static void OnShowUrl (string url)
+ {
+ DesktopService.ShowUrl (url);
+ }
+
+ internal static void StoreConfiguration ()
+ {
+ PropertyService.Set ("MonoDevelop.GtkCore.ShowNonContainerWarning", steticApp.ShowNonContainerWarning);
+ PropertyService.SaveProperties ();
+ }
+
+ public static bool AutoSwitchGuiLayout {
+ get {
+ return PropertyService.Get ("MonoDevelop.GtkCore.AutoSwitchGuiLayout", false);
+ }
+ set {
+ PropertyService.Set ("MonoDevelop.GtkCore.AutoSwitchGuiLayout", value);
+ }
+ }
+
+ public static ActionGroupView OpenActionGroup (Project project, Stetic.ActionGroupInfo group)
+ {
+ GuiBuilderProject p = GtkDesignInfo.FromProject (project).GuiBuilderProject ;
+ string file = p != null ? p.GetSourceCodeFile (group) : null;
+ if (file == null) {
+ file = ActionGroupDisplayBinding.BindToClass (project, group);
+ }
+
+ Document doc = IdeApp.Workbench.OpenDocument (file, true);
+ if (doc != null) {
+ ActionGroupView view = doc.GetContent<ActionGroupView> ();
+ if (view != null) {
+ view.ShowDesignerView ();
+ return view;
+ }
+ }
+ return null;
+ }
+
+ static void OnActiveDocumentChanged (object s, EventArgs args)
+ {
+ if (IdeApp.Workbench.ActiveDocument == null) {
+ if (SteticApp.ActiveDesigner != null) {
+ SteticApp.ActiveDesigner = null;
+ RestoreLayout ();
+ }
+ return;
+ }
+
+ CombinedDesignView view = IdeApp.Workbench.ActiveDocument.GetContent<CombinedDesignView> ();
+ if (view != null) {
+ SteticApp.ActiveDesigner = view.Designer;
+ SetDesignerLayout ();
+ return;
+ }
+ else if (SteticApp.ActiveDesigner != null) {
+ SteticApp.ActiveDesigner = null;
+ RestoreLayout ();
+ }
+ }
+
+ static void SetDesignerLayout ()
+ {
+ if (AutoSwitchGuiLayout && IdeApp.Workbench.CurrentLayout != GuiBuilderLayout) {
+ bool exists = IdeApp.Workbench.Layouts.Contains (GuiBuilderLayout);
+ defaultLayout = IdeApp.Workbench.CurrentLayout;
+ IdeApp.Workbench.CurrentLayout = GuiBuilderLayout;
+ if (!exists) {
+ Pad p = IdeApp.Workbench.GetPad<MonoDevelop.DesignerSupport.ToolboxPad> ();
+ if (p != null) p.Visible = true;
+ p = IdeApp.Workbench.GetPad<MonoDevelop.DesignerSupport.PropertyPad> ();
+ if (p != null) p.Visible = true;
+ }
+ }
+ }
+
+ static void RestoreLayout ()
+ {
+ if (AutoSwitchGuiLayout && defaultLayout != null) {
+ IdeApp.Workbench.CurrentLayout = defaultLayout;
+ defaultLayout = null;
+ }
+ }
+
+ static void OnProjectCompiled (object s, BuildEventArgs args)
+ {
+ if (args.Success) {
+ // Unload stetic projects which are not currently
+ // being used by the IDE. This will avoid unnecessary updates.
+ if (IdeApp.Workspace.IsOpen) {
+ foreach (Project prj in IdeApp.Workspace.GetAllProjects ()) {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (prj);
+ if (!HasOpenDesigners (prj, false)) {
+ info.ReloadGuiBuilderProject ();
+ }
+ }
+ }
+
+ SteticApp.UpdateWidgetLibraries (false);
+ }
+ else {
+ // Some gtk# packages don't include the .pc file unless you install gtk-sharp-devel
+ if (Runtime.SystemAssemblyService.DefaultAssemblyContext.GetPackage ("gtk-sharp-2.0") == null) {
+ string msg = GettextCatalog.GetString ("ERROR: MonoDevelop could not find the Gtk# 2.0 development package. Compilation of projects depending on Gtk# libraries will fail. You may need to install development packages for gtk-sharp-2.0.");
+ args.ProgressMonitor.Log.WriteLine ();
+ args.ProgressMonitor.Log.WriteLine (msg);
+ }
+ }
+ }
+
+ internal static bool HasOpenDesigners (Project project, bool modifiedOnly)
+ {
+ foreach (Document doc in IdeApp.Workbench.Documents) {
+ if ((doc.GetContent<GuiBuilderView>() != null || doc.GetContent<ActionGroupView>() != null) && doc.Project == project && (!modifiedOnly || doc.IsDirty))
+ return true;
+ }
+ return false;
+ }
+
+ //static void OnAssemblyInfoChanged (object s, AssemblyInformationEventArgs args)
+// {
+ //SteticApp.UpdateWidgetLibraries (false);
+// }
+
+ internal static void AddCurrentWidgetToClass ()
+ {
+ if (IdeApp.Workbench.ActiveDocument != null) {
+ GuiBuilderView view = IdeApp.Workbench.ActiveDocument.GetContent<GuiBuilderView> ();
+ if (view != null)
+ view.AddCurrentWidgetToClass ();
+ }
+ }
+
+ internal static void JumpToSignalHandler (Stetic.Signal signal)
+ {
+ if (IdeApp.Workbench.ActiveDocument != null) {
+ CombinedDesignView view = IdeApp.Workbench.ActiveDocument.GetContent<CombinedDesignView> ();
+ if (view != null)
+ view.JumpToSignalHandler (signal);
+ }
+ }
+
+ public static void ImportGladeFile (Project project)
+ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ info.GuiBuilderProject.ImportGladeFile ();
+ }
+
+ public static string GetBuildCodeFileName (Project project, string componentName)
+ {
+ return GetBuildCodeFileName (project, componentName, string.Empty);
+ }
+
+ public static string GetBuildCodeFileName (Project project, string componentName, string nameSpace)
+ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ string componentFile = info.GetComponentFile (componentName);
+
+ if (componentFile == null) {
+ if (nameSpace == "Stetic") {
+ return info.GetBuildFileInSteticFolder (componentName);
+ }
+// else
+// throw new UserException ("Cannot find component file for " + componentName);
+ } else
+ return info.GetBuildFileFromComponent (componentFile);
+
+ return null;
+ }
+
+ public static void GenerateSteticCodeStructure (DotNetProject project, Stetic.ProjectItemInfo item, bool saveToFile, bool overwrite)
+ {
+ GenerateSteticCodeStructure (project, item, null, null, saveToFile, overwrite);
+ }
+
+ public static void GenerateSteticCodeStructure (DotNetProject project, Stetic.Component component, Stetic.ComponentNameEventArgs args, bool saveToFile, bool overwrite)
+ {
+ GenerateSteticCodeStructure (project, null, component, args, saveToFile, overwrite);
+ }
+
+ static void GenerateSteticCodeStructure (DotNetProject project, Stetic.ProjectItemInfo item, Stetic.Component component, Stetic.ComponentNameEventArgs args, bool saveToFile, bool overwrite)
+ {
+ // Generate a class which contains fields for all bound widgets of the component
+
+ string name = item != null ? item.Name : component.Name;
+ string fileName = GetBuildCodeFileName (project, name);
+ if (fileName == null)
+ return;
+
+ string ns = "";
+ int i = name.LastIndexOf ('.');
+ if (i != -1) {
+ ns = name.Substring (0, i);
+ name = name.Substring (i+1);
+ }
+
+ if (saveToFile && !overwrite && File.Exists (fileName))
+ return;
+
+ if (item != null)
+ component = item.Component;
+
+ CodeCompileUnit cu = new CodeCompileUnit ();
+
+ if (project.UsePartialTypes) {
+ CodeNamespace cns = new CodeNamespace (ns);
+ cu.Namespaces.Add (cns);
+
+ CodeTypeDeclaration type = new CodeTypeDeclaration (name);
+ type.IsPartial = true;
+ type.Attributes = MemberAttributes.Public;
+ type.TypeAttributes = System.Reflection.TypeAttributes.Public;
+ cns.Types.Add (type);
+
+ foreach (Stetic.ObjectBindInfo binfo in component.GetObjectBindInfo ()) {
+ // When a component is being renamed, we have to generate the
+ // corresponding field using the old name, since it will be renamed
+ // later using refactory
+ string nname = args != null && args.NewName == binfo.Name ? args.OldName : binfo.Name;
+ type.Members.Add (
+ new CodeMemberField (
+ binfo.TypeName,
+ nname
+ )
+ );
+ }
+ }
+ else {
+ if (!saveToFile)
+ return;
+ CodeNamespace cns = new CodeNamespace ();
+ cns.Comments.Add (new CodeCommentStatement ("Generated code for component " + component.Name));
+ cu.Namespaces.Add (cns);
+ }
+
+ CodeDomProvider provider = project.LanguageBinding.GetCodeDomProvider ();
+ if (provider == null)
+ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
+
+ TextWriter fileStream;
+ if (saveToFile)
+ fileStream = new StreamWriter (fileName);
+ else
+ fileStream = new StringWriter ();
+
+ try {
+ provider.GenerateCodeFromCompileUnit (cu, fileStream, new CodeGeneratorOptions ());
+ } finally {
+ fileStream.Close ();
+ }
+
+ if (ProjectDomService.HasDom (project)) {
+ // Only update the parser database if the project is actually loaded in the IDE.
+ if (saveToFile) {
+ ProjectDomService.Parse (project, fileName, "");
+ FileService.NotifyFileChanged (fileName);
+ }
+ else
+ ProjectDomService.Parse (project, fileName, ((StringWriter)fileStream).ToString ());
+ }
+ }
+
+ public static Stetic.CodeGenerationResult GenerateSteticCode (IProgressMonitor monitor, DotNetProject project, ConfigurationSelector configuration)
+ {
+ if (generating || !GtkDesignInfo.HasDesignedObjects (project))
+ return null;
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ info.CheckGtkFolder ();
+
+ DateTime last_gen_time = File.Exists (info.SteticGeneratedFile) ? File.GetLastWriteTime (info.SteticGeneratedFile) : DateTime.MinValue;
+
+ bool ref_changed = false;
+ foreach (ProjectReference pref in project.References) {
+ if (!pref.IsValid)
+ continue;
+ foreach (string filename in pref.GetReferencedFileNames (configuration)) {
+ if (File.GetLastWriteTime (filename) > last_gen_time) {
+ ref_changed = true;
+ break;
+ }
+ }
+ if (ref_changed)
+ break;
+ }
+
+ // Check if generated code is already up to date.
+// if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
+// return null;
+
+ if (info.GuiBuilderProject.HasError) {
+ monitor.ReportError (GettextCatalog.GetString ("GUI code generation failed for project '{0}'. The file '{1}' could not be loaded.", project.Name, info.SteticFile), null);
+ monitor.AsyncOperation.Cancel ();
+ return null;
+ }
+
+ if (info.GuiBuilderProject.IsEmpty)
+ return null;
+
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Generating GUI code for project '{0}'...", project.Name));
+
+ // Make sure the referenced assemblies are up to date. It is necessary to do
+ // it now since they may contain widget libraries.
+ project.CopySupportFiles (monitor, configuration);
+
+ info.GuiBuilderProject.UpdateLibraries ();
+
+ ArrayList projectFolders = new ArrayList ();
+ projectFolders.Add (info.SteticFolder.FullPath);
+
+ generating = true;
+ Stetic.CodeGenerationResult generationResult = null;
+ Exception generatedException = null;
+
+ bool canGenerateInProcess = IsolationMode != Stetic.IsolationMode.None || info.GuiBuilderProject.SteticProject.CanGenerateCode;
+
+ if (!canGenerateInProcess) {
+ // Run the generation in another thread to avoid freezing the GUI
+ System.Threading.ThreadPool.QueueUserWorkItem ( delegate {
+ try {
+ // Generate the code in another process if stetic is not isolated
+ CodeGeneratorProcess cob = (CodeGeneratorProcess) Runtime.ProcessService.CreateExternalProcessObject (typeof (CodeGeneratorProcess), false);
+ using (cob) {
+ generationResult = cob.GenerateCode (projectFolders, info.GenerateGettext, info.GettextClass, project.UsePartialTypes, info);
+ }
+ } catch (Exception ex) {
+ generatedException = ex;
+ } finally {
+ generating = false;
+ }
+ });
+
+ while (generating) {
+ DispatchService.RunPendingEvents ();
+ System.Threading.Thread.Sleep (100);
+ }
+ } else {
+ // No need to create another process, since stetic has its own backend process
+ // or the widget libraries have no custom wrappers
+ try {
+ Stetic.GenerationOptions options = new Stetic.GenerationOptions ();
+ options.UseGettext = info.GenerateGettext;
+ options.GettextClass = info.GettextClass;
+ generationResult = SteticApp.GenerateProjectCode (options, info.GuiBuilderProject.SteticProject);
+ } catch (Exception ex) {
+ generatedException = ex;
+ }
+ generating = false;
+ }
+
+ if (generatedException != null) {
+ string msg = string.Empty;
+
+ if (generatedException.InnerException != null) {
+ msg = string.Format("{0}\n{1}\nInner Exception {2}\n{3}",
+ generatedException.Message,
+ generatedException.StackTrace,
+ generatedException.InnerException.Message,
+ generatedException.InnerException.StackTrace);
+ } else {
+ msg = string.Format("{0}\n{1}",
+ generatedException.Message,
+ generatedException.StackTrace);
+ }
+
+// LoggingService.LogError ("GUI code generation failed", generatedException);
+ LoggingService.LogError ("GUI code generation failed: " + msg);
+ throw new UserException ("GUI code generation failed: " + msg);
+ }
+
+ if (generationResult == null)
+ return null;
+
+ CodeDomProvider provider = project.LanguageBinding.GetCodeDomProvider ();
+ if (provider == null)
+ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
+
+ foreach (Stetic.SteticCompilationUnit unit in generationResult.Units) {
+ string fname;
+ if (unit.Name.Length == 0)
+ fname = info.SteticGeneratedFile;
+ else
+ fname = GetBuildCodeFileName (project,
+ unit.Name,
+ (unit.Namespace != null) ? unit.Namespace.Name : string.Empty);
+
+ StringWriter sw = new StringWriter ();
+ try {
+ foreach (CodeNamespace ns in unit.Namespaces)
+ ns.Comments.Add (new CodeCommentStatement ("This file has been generated by the GUI designer. Do not modify."));
+ provider.GenerateCodeFromCompileUnit (unit, sw, new CodeGeneratorOptions ());
+ string content = sw.ToString ();
+ content = FormatGeneratedFile (fname, content, provider);
+ File.WriteAllText (fname, content);
+ } finally {
+ FileService.NotifyFileChanged (fname);
+ }
+ }
+
+ // Make sure the generated files are added to the project
+ if (info.UpdateGtkFolder ()) {
+ Gtk.Application.Invoke (delegate {
+ IdeApp.ProjectOperations.Save (project);
+ });
+ }
+
+ return generationResult;
+ }
+
+ internal static string ImportFile (Project prj, string file)
+ {
+ ProjectFile pfile = prj.Files.GetFile (file);
+ if (pfile == null) {
+ var files = IdeApp.ProjectOperations.AddFilesToProject (prj, new string[] { file }, prj.BaseDirectory);
+ if (files.Count == 0 || files[0] == null)
+ return null;
+ pfile = files [0];
+ }
+ if (pfile.BuildAction == BuildAction.EmbeddedResource) {
+ AlertButton embedButton = new AlertButton (GettextCatalog.GetString ("_Use as Source"));
+ if (MessageService.AskQuestion (GettextCatalog.GetString ("You are requesting the file '{0}' to be used as source for an image. However, this file is already added to the project as a resource. Are you sure you want to continue (the file will have to be removed from the resource list)?"), AlertButton.Cancel, embedButton) == embedButton)
+ return null;
+ }
+ pfile.BuildAction = BuildAction.Content;
+ DeployProperties props = DeployService.GetDeployProperties (pfile);
+ props.UseProjectRelativePath = true;
+ return pfile.FilePath;
+ }
+
+ static string FormatGeneratedFile (string file, string content, CodeDomProvider provider)
+ {
+ //TODO : Wait for a fix for Mono.TextEditor.Document in the trunk
+ //content = StripHeaderAndBlankLines (content, provider);
+ string mt = DesktopService.GetMimeTypeForUri (file);
+ Formatter formatter = TextFileService.GetFormatter (mt);
+ if (formatter != null)
+ content = formatter.FormatText (PolicyService.InvariantPolicies, content);
+ return content;
+ }
+
+ static string StripHeaderAndBlankLines (string text, CodeDomProvider provider)
+ {
+ Mono.TextEditor.Document doc = new Mono.TextEditor.Document ();
+ doc.Text = text;
+ int realStartLine = 0;
+ for (int i = 0; i < doc.LineCount; i++) {
+ var lineSegment = doc.GetLine (i);
+ if (lineSegment == null)
+ continue;
+ string lineText = doc.GetTextAt (lineSegment);
+ // Microsoft.NET generates "auto-generated" tags where Mono generates "autogenerated" tags.
+ if (lineText.Contains ("</autofgenerated>") || lineText.Contains ("</auto-generated>")) {
+ realStartLine = i + 2;
+ break;
+ }
+ }
+
+ // The Mono provider inserts additional blank lines, so strip them out
+ // But blank lines might actually be significant in other languages.
+ // We reformat the C# generated output to the user's coding style anyway, but the reformatter preserves blank lines
+ if (provider is Microsoft.CSharp.CSharpCodeProvider) {
+ bool previousWasBlank = false;
+ for (int i = 0; i < doc.LineCount; i++) {
+ Mono.TextEditor.LineSegment line = doc.GetLine (i);
+ bool isBlank, isBracket;
+ CheckLine (doc, line, out isBlank, out isBracket);
+ if (isBlank && previousWasBlank && line.Length > 0) {
+ ((Mono.TextEditor.IBuffer)doc).Remove (line.Offset, line.Length);
+ i--;
+ }
+ previousWasBlank = isBlank || isBracket;
+ }
+ }
+
+ int offset = doc.GetLine (realStartLine).Offset;
+ return doc.GetTextAt (offset, doc.Length - offset);
+ }
+
+ static void CheckLine (Mono.TextEditor.Document doc, Mono.TextEditor.LineSegment line, out bool isBlank, out bool isBracket)
+ {
+ isBlank = true;
+ isBracket = false;
+ if (line == null)
+ return;
+
+ for (int i = 0; i < line.Length; i++) {
+ char c = doc.GetCharAt (line.Offset + i);
+ if (c == '{') {
+ isBracket = true;
+ isBlank = false;
+ }
+ else if (!Char.IsWhiteSpace (c)) {
+ isBlank = false;
+ if (isBracket) {
+ isBracket = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+
+ public class CodeGeneratorProcess: RemoteProcessObject
+ {
+ public Stetic.CodeGenerationResult GenerateCode (ArrayList projectFolders, bool useGettext, string gettextClass, bool usePartialClasses, GtkDesignInfo info)
+ {
+ Gtk.Application.Init ();
+
+ Stetic.Application app = Stetic.ApplicationFactory.CreateApplication (Stetic.IsolationMode.None);
+
+ Stetic.Project[] projects = new Stetic.Project [projectFolders.Count];
+ for (int n=0; n < projectFolders.Count; n++) {
+ projects [n] = app.CreateProject (info);
+ projects [n].Load ((string) projectFolders [n]);
+ }
+
+ Stetic.GenerationOptions options = new Stetic.GenerationOptions ();
+ options.UseGettext = useGettext;
+ options.GettextClass = gettextClass;
+
+ return app.GenerateProjectCode (options, projects);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs
new file mode 100644
index 0000000000..6bff298a7c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs
@@ -0,0 +1,613 @@
+//
+// GuiBuilderView.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Krzysztof Marecki
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.ComponentModel;
+
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui.Content;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.DesignerSupport.Toolbox;
+using MonoDevelop.DesignerSupport;
+
+using Gtk;
+using Gdk;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class GuiBuilderView : CombinedDesignView, IToolboxConsumer, MonoDevelop.DesignerSupport.IOutlinedDocument, ISupportsProjectReload
+ {
+ Stetic.WidgetDesigner designer;
+ Stetic.ActionGroupDesigner actionsBox;
+ GuiBuilderWindow window;
+
+ DesignerPage designerPage;
+ ActionGroupPage actionsPage;
+
+
+ CodeBinder codeBinder;
+ GuiBuilderProject gproject;
+ string rootName;
+ object designerStatus;
+
+ public GuiBuilderView (IViewContent content, GuiBuilderWindow window): base (content)
+ {
+ rootName = window.Name;
+
+ designerPage = new DesignerPage ();
+ designerPage.Show ();
+ AddButton (GettextCatalog.GetString ("Designer"), designerPage);
+
+ actionsPage = new ActionGroupPage ();
+ actionsPage.Show ();
+
+ AttachWindow (window);
+ }
+
+ void AttachWindow (GuiBuilderWindow window)
+ {
+ gproject = window.Project;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (gproject.Project);
+ gproject.SteticProject.ImagesRootPath = FileService.AbsoluteToRelativePath (info.SteticFolder, gproject.Project.BaseDirectory);
+ gproject.UpdateLibraries ();
+ LoadDesigner ();
+ }
+
+ ProjectReloadCapability ISupportsProjectReload.ProjectReloadCapability {
+ get {
+ return ProjectReloadCapability.Full;
+ }
+ }
+
+ void ISupportsProjectReload.Update (Project project)
+ {
+ if (gproject != null && gproject.Project == project)
+ return;
+
+ ReloadDesigner (project);
+ }
+
+ void LoadDesigner ()
+ {
+ this.window = gproject.GetWindow (rootName);
+ if (window == null) {
+ // The window doesn't exist anymore
+ return;
+ }
+
+ gproject.Unloaded += OnDisposeProject;
+
+ designer = gproject.SteticProject.CreateWidgetDesigner (window.RootWidget);
+
+ // Designer page
+ designerPage.ClearChild ();
+ designerPage.Add (designer);
+
+ if (designer.RootComponent == null) {
+ // Something went wrong while creating the designer. Show it, but don't do aything else.
+ designer.ShowAll ();
+ return;
+ }
+
+ designer.AllowWidgetBinding = !gproject.Project.UsePartialTypes;
+
+ codeBinder = new CodeBinder (gproject.Project, new OpenDocumentFileProvider (), designer.RootComponent);
+
+ designer.BindField += OnBindWidgetField;
+ designer.Changed += OnChanged;
+ designer.SignalAdded += OnSignalAdded;
+ designer.SignalRemoved += OnSignalRemoved;
+ designer.SignalChanged += OnSignalChanged;
+ designer.ComponentNameChanged += OnComponentNameChanged;
+ designer.RootComponentChanged += OnRootComponentChanged;
+ designer.ComponentTypesChanged += OnComponentTypesChanged;
+ designer.ImportFileCallback = ImportFile;
+
+ // Actions designer
+ actionsBox = designer.CreateActionGroupDesigner ();
+ actionsBox.AllowActionBinding = !gproject.Project.UsePartialTypes;
+ actionsBox.BindField += new EventHandler (OnBindActionField);
+ actionsBox.ModifiedChanged += new EventHandler (OnActionshanged);
+
+ actionsPage.ClearChild ();
+ actionsPage.PackStart (actionsBox, true, true, 0);
+ actionsPage.ShowAll ();
+
+ if (actionsBox.HasData) {
+ if (!HasPage (actionsPage))
+ AddButton (GettextCatalog.GetString ("Actions"), actionsPage);
+ } else {
+ RemoveButton (actionsPage);
+ }
+
+ designer.ShowAll ();
+ GuiBuilderService.SteticApp.ActiveDesigner = designer;
+ }
+
+ public void ReloadDesigner (Project project)
+ {
+ if (designer != null)
+ designerStatus = designer.SaveStatus ();
+
+ CloseDesigner ();
+ CloseProject ();
+ if (project != null) {
+ GuiBuilderWindow w = GuiBuilderDisplayBinding.GetWindow (this.ContentName);
+ if (w != null) {
+ AttachWindow (w);
+ if (designerStatus != null)
+ designer.LoadStatus (designerStatus);
+ designerStatus = null;
+ }
+ }
+ }
+
+ public override Stetic.Designer Designer {
+ get { return designer; }
+ }
+
+ void OnDisposeProject (object s, EventArgs args)
+ {
+ CloseDesigner ();
+ }
+
+ void OnReloadProject (object s, EventArgs args)
+ {
+ if (designer == null)
+ LoadDesigner ();
+ }
+
+ public GuiBuilderWindow Window {
+ get { return window; }
+ }
+
+ void CloseDesigner ()
+ {
+ if (designer == null)
+ return;
+
+ gproject.Unloaded -= OnDisposeProject;
+ designer.BindField -= OnBindWidgetField;
+ designer.Changed -= OnChanged;
+ designer.SignalAdded -= OnSignalAdded;
+ designer.SignalRemoved -= OnSignalRemoved;
+ designer.SignalChanged -= OnSignalChanged;
+ designer.ComponentNameChanged -= OnComponentNameChanged;
+ designer.RootComponentChanged -= OnRootComponentChanged;
+ designer.ComponentTypesChanged -= OnComponentTypesChanged;
+
+ if (actionsBox != null) {
+ actionsBox.BindField -= OnBindActionField;
+ actionsBox.ModifiedChanged -= OnActionshanged;
+ actionsBox = null;
+ }
+
+ actionsPage.ClearChild ();
+ designerPage.ClearChild ();
+
+ designerPage.Add (CreateDesignerNotAvailableWidget ());
+ actionsPage.Add (CreateDesignerNotAvailableWidget ());
+
+ designer = null;
+
+ gproject.Reloaded += OnReloadProject;
+ }
+
+ void CloseProject ()
+ {
+ gproject.Reloaded -= OnReloadProject;
+ }
+
+ public override void Dispose ()
+ {
+ CloseDesigner ();
+ CloseProject ();
+ codeBinder = null;
+ base.Dispose ();
+ }
+
+ Gtk.Widget CreateDesignerNotAvailableWidget ()
+ {
+ Gtk.Label label = new Gtk.Label (GettextCatalog.GetString ("Designer not available"));
+ label.Show ();
+ return label;
+ }
+
+ public override void ShowPage (int npage)
+ {
+ if (npage == 0 && designer != null && window != null && !ErrorMode) {
+ // At every page switch update the generated code, to make sure code completion works
+ // for the generated fields. The call to GenerateSteticCodeStructure will generate
+ // the code for the window (only the fields in fact) and update the parser database, it
+ // will not save the code to disk.
+ if (gproject.Project.UsePartialTypes)
+ GuiBuilderService.GenerateSteticCodeStructure ((DotNetProject)gproject.Project, designer.RootComponent, null, false, false);
+ }
+ base.ShowPage (npage);
+ }
+
+ string ImportFile (string file)
+ {
+ return GuiBuilderService.ImportFile (gproject.Project, file);
+ }
+
+ void OnRootComponentChanged (object s, EventArgs args)
+ {
+ codeBinder.TargetObject = designer.RootComponent;
+ }
+
+ void OnComponentNameChanged (object s, Stetic.ComponentNameEventArgs args)
+ {
+ try {
+ // Make sure the fields in the partial class are up to date.
+ // Provide the args parameter to GenerateSteticCodeStructure, in this
+ // way the component that has been renamed will be generated with the
+ // old name, and UpdateField will be able to find it (to rename the
+ // references to the field, it needs to have the old name).
+ if (gproject.Project.UsePartialTypes)
+ GuiBuilderService.GenerateSteticCodeStructure ((DotNetProject)gproject.Project, designer.RootComponent, args, false, false);
+
+ codeBinder.UpdateField (args.Component, args.OldName);
+ }
+ catch (Exception ex) {
+ MessageService.ShowException (ex);
+ }
+ }
+
+ void OnComponentTypesChanged (object s, EventArgs a)
+ {
+ if (ToolboxProvider.Instance != null)
+ ToolboxProvider.Instance.NotifyItemsChanged ();
+ }
+
+ void OnActionshanged (object s, EventArgs args)
+ {
+ if (designer != null && !HasPage (actionsPage) && !ErrorMode)
+ AddButton (GettextCatalog.GetString ("Actions"), actionsPage);
+ }
+
+ void OnChanged (object s, EventArgs args)
+ {
+ if (IsDirty)
+ OnContentChanged (args);
+ OnDirtyChanged (args);
+ }
+
+ void OnBindWidgetField (object o, EventArgs a)
+ {
+ if (designer.Selection != null)
+ codeBinder.BindToField (designer.Selection);
+ }
+
+ void OnBindActionField (object o, EventArgs a)
+ {
+ if (actionsBox.SelectedAction != null)
+ codeBinder.BindToField (actionsBox.SelectedAction);
+ }
+
+ void OnSignalAdded (object sender, Stetic.ComponentSignalEventArgs args)
+ {
+ codeBinder.BindSignal (args.Signal);
+ }
+
+ void OnSignalRemoved (object sender, Stetic.ComponentSignalEventArgs args)
+ {
+ }
+
+ void OnSignalChanged (object sender, Stetic.ComponentSignalEventArgs args)
+ {
+ codeBinder.UpdateSignal (args.OldSignal, args.Signal);
+ }
+
+ public override void Save (string fileName)
+ {
+ base.Save (fileName);
+
+ if (designer == null)
+ return;
+
+ string oldBuildFile = GuiBuilderService.GetBuildCodeFileName (gproject.Project, window.RootWidget.Name);
+ codeBinder.UpdateBindings (fileName);
+
+ if (!ErrorMode) {
+ if (designer != null)
+ designer.Save ();
+ if (actionsBox != null)
+ actionsBox.Save ();
+ }
+
+ string newBuildFile = GuiBuilderService.GetBuildCodeFileName (gproject.Project, window.RootWidget.Name);
+
+ if (oldBuildFile != newBuildFile && oldBuildFile != null && newBuildFile != null) {
+ if (System.IO.File.Exists (newBuildFile))
+ FileService.DeleteFile (newBuildFile);
+ if (System.IO.File.Exists (oldBuildFile))
+ FileService.MoveFile (oldBuildFile, newBuildFile);
+ }
+
+ gproject.Save (true);
+ OnDirtyChanged (EventArgs.Empty);
+ }
+
+ public override bool IsDirty {
+ get {
+ // There is no need to check if the action group designer is modified
+ // since changes in the action group are as well changes in the designed widget
+ return base.IsDirty || (designer != null && designer.Modified);
+ }
+ set {
+ base.IsDirty = value;
+ }
+ }
+
+ public override void JumpToSignalHandler (Stetic.Signal signal)
+ {
+ IType cls = codeBinder.GetClass ();
+ if (cls == null)
+ return;
+ foreach (IMethod met in cls.Methods) {
+ if (met.Name == signal.Handler) {
+ ShowPage (0);
+ JumpTo (met.Location.Line, met.Location.Column);
+ break;
+ }
+ }
+ }
+
+ public void ShowDesignerView ()
+ {
+ if (designer != null)
+ ShowPage (1);
+ }
+
+ public void ShowActionDesignerView (string name)
+ {
+ if (designer != null) {
+ ShowPage (2);
+ if (!ErrorMode)
+ actionsBox.ActiveGroup = name;
+ }
+ }
+
+ bool ErrorMode {
+ get { return designer.RootComponent == null; }
+ }
+
+ public Stetic.ComponentType[] GetComponentTypes ()
+ {
+ if (designer != null)
+ return designer.GetComponentTypes ();
+ else
+ return null;
+ }
+
+ void IToolboxConsumer.ConsumeItem (ItemToolboxNode item)
+ {
+ }
+
+ //Toolbox service uses this to filter toolbox items.
+ ToolboxItemFilterAttribute[] IToolboxConsumer.ToolboxFilterAttributes {
+ get {
+ return new ToolboxItemFilterAttribute [] {
+ new ToolboxItemFilterAttribute ("gtk-sharp", ToolboxItemFilterType.Custom)
+ };
+ }
+ }
+
+ //Used if ToolboxItemFilterAttribute demands ToolboxItemFilterType.Custom
+ //If not expecting it, should just return false
+ bool IToolboxConsumer.CustomFilterSupports (ItemToolboxNode item)
+ {
+ ComponentToolboxNode cnode = item as ComponentToolboxNode;
+ if (cnode != null && gproject.SteticProject != null) {
+ if (cnode.GtkVersion == null || Mono.Addins.Addin.CompareVersions (gproject.SteticProject.TargetGtkVersion, cnode.GtkVersion) <= 0)
+ return true;
+ }
+ return false;
+ }
+
+ string IToolboxConsumer.DefaultItemDomain {
+ get { return ComponentToolboxNode.GtkWidgetDomain; }
+ }
+
+ void IToolboxConsumer.DragItem (ItemToolboxNode item, Gtk.Widget source, Gdk.DragContext ctx)
+ {
+ if (designer != null) {
+ ComponentToolboxNode node = item as ComponentToolboxNode;
+ if (node != null) {
+ if (node.Reference == null)
+ designer.BeginComponentDrag (node.ComponentType, source, ctx);
+ else
+ designer.BeginComponentDrag (node.Name, node.ClassName, source, ctx, delegate { CheckReference (node); });
+ }
+ }
+ }
+
+ void CheckReference (ComponentToolboxNode node)
+ {
+ if (node.Reference == null)
+ return;
+
+ ProjectReference pref;
+
+ // If the class name includes an assembly name it means that the
+ // widget is implemented in another assembly, not in the one that
+ // has the objects.xml file.
+ int i = node.ClassName.IndexOf (',');
+ if (i != -1) {
+ string asm = node.ClassName.Substring (i+1).Trim ();
+ if (asm == "gtk-sharp")
+ // If we are adding a widget to a window, the project must already have a gtk# reference
+ return;
+
+ asm = gproject.Project.AssemblyContext.GetAssemblyFullName (asm, gproject.Project.TargetFramework);
+ if (asm == null)
+ return;
+ if (gproject.Project.AssemblyContext.GetPackagesFromFullName (asm).Length > 0) {
+ pref = new ProjectReference (ReferenceType.Gac, asm);
+ } else {
+ asm = gproject.Project.AssemblyContext.GetAssemblyLocation (asm, gproject.Project.TargetFramework);
+ pref = new ProjectReference (ReferenceType.Assembly, asm);
+ }
+ }
+ else
+ pref = new ProjectReference (node.ReferenceType, node.Reference);
+
+ foreach (ProjectReference pr in gproject.Project.References) {
+ if (pr.Reference == pref.Reference)
+ return;
+ }
+ gproject.Project.References.Add (pref);
+ }
+
+ Widget MonoDevelop.DesignerSupport.IOutlinedDocument.GetOutlineWidget ()
+ {
+ return GuiBuilderDocumentOutline.Instance;
+ }
+
+ void MonoDevelop.DesignerSupport.IOutlinedDocument.ReleaseOutlineWidget ()
+ {
+ //Do nothing. We keep the instance to avoid creation cost when switching documents.
+ }
+
+ TargetEntry[] IToolboxConsumer.DragTargets {
+ get { return Stetic.DND.Targets; }
+ }
+ }
+
+ class DesignerPage: Gtk.EventBox, ICustomPropertyPadProvider
+ {
+ public DesignerPage ()
+ {
+ }
+
+ Gtk.Widget ICustomPropertyPadProvider.GetCustomPropertyWidget ()
+ {
+ return PropertiesWidget.Instance;
+ }
+
+ void ICustomPropertyPadProvider.DisposeCustomPropertyWidget ()
+ {
+ }
+
+ Stetic.WidgetDesigner Designer {
+ get {
+ return Child as Stetic.WidgetDesigner;
+ }
+ }
+
+ public void ClearChild ()
+ {
+ if (Child != null) {
+ Gtk.Widget w = Child;
+ Remove (w);
+ w.Destroy ();
+ }
+ }
+
+ [CommandHandler (EditCommands.Delete)]
+ protected void OnDelete ()
+ {
+ Designer.DeleteSelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Delete)]
+ protected void OnUpdateDelete (CommandInfo cinfo)
+ {
+ cinfo.Bypass = Designer != null && !Designer.CanDeleteSelection;
+ }
+
+ [CommandHandler (EditCommands.Copy)]
+ protected void OnCopy ()
+ {
+ Designer.CopySelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Copy)]
+ protected void OnUpdateCopy (CommandInfo cinfo)
+ {
+ cinfo.Enabled = Designer != null && Designer.CanCopySelection;
+ }
+
+ [CommandHandler (EditCommands.Cut)]
+ protected void OnCut ()
+ {
+ Designer.CutSelection ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Cut)]
+ protected void OnUpdateCut (CommandInfo cinfo)
+ {
+ cinfo.Enabled = Designer != null && Designer.CanCutSelection;
+ }
+
+ [CommandHandler (EditCommands.Paste)]
+ protected void OnPaste ()
+ {
+ Designer.PasteToSelection ();
+ }
+
+ [CommandHandler (EditCommands.Undo)]
+ protected void OnUndo ()
+ {
+ Designer.UndoQueue.Undo ();
+ }
+
+ [CommandHandler (EditCommands.Redo)]
+ protected void OnRedo ()
+ {
+ Designer.UndoQueue.Redo ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Paste)]
+ protected void OnUpdatePaste (CommandInfo cinfo)
+ {
+ cinfo.Enabled = Designer != null && Designer.CanPasteToSelection;
+ }
+
+ [CommandUpdateHandler (EditCommands.Undo)]
+ protected void OnUpdateUndo (CommandInfo cinfo)
+ {
+ cinfo.Enabled = Designer != null && Designer.UndoQueue.CanUndo;
+ }
+
+ [CommandUpdateHandler (EditCommands.Redo)]
+ protected void OnUpdateRedo (CommandInfo cinfo)
+ {
+ cinfo.Enabled = Designer != null && Designer.UndoQueue.CanRedo;
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs
new file mode 100644
index 0000000000..9b4fc06ed8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs
@@ -0,0 +1,260 @@
+//
+// GuiBuilderWindow.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Krzysztof Marecki
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.CodeDom;
+
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Projects.CodeGeneration;
+using MonoDevelop.Projects.Text;
+using MonoDevelop.GtkCore.Dialogs;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class GuiBuilderWindow: IDisposable
+ {
+ Stetic.WidgetInfo rootWidget;
+ GuiBuilderProject fproject;
+ Stetic.Project gproject;
+ string name;
+
+ public event WindowEventHandler Changed;
+
+ internal GuiBuilderWindow (GuiBuilderProject fproject, Stetic.Project gproject, Stetic.WidgetInfo rootWidget)
+ {
+ this.fproject = fproject;
+ this.rootWidget = rootWidget;
+ this.gproject = gproject;
+ name = rootWidget.Name;
+ gproject.ProjectReloaded += OnProjectReloaded;
+ rootWidget.Changed += OnChanged;
+ }
+
+ public Stetic.WidgetInfo RootWidget {
+ get { return rootWidget; }
+ }
+
+ public GuiBuilderProject Project {
+ get { return fproject; }
+ }
+
+ public string Name {
+ get { return rootWidget.Name; }
+ }
+
+ public FilePath SourceCodeFile {
+ get { return fproject.GetSourceCodeFile (rootWidget); }
+ }
+
+ public void Dispose ()
+ {
+ gproject.ProjectReloaded -= OnProjectReloaded;
+ rootWidget.Changed -= OnChanged;
+ }
+
+ void OnProjectReloaded (object s, EventArgs args)
+ {
+ rootWidget.Changed -= OnChanged;
+ rootWidget = gproject.GetWidget (name);
+ if (rootWidget != null)
+ rootWidget.Changed += OnChanged;
+ }
+
+ void OnChanged (object o, EventArgs args)
+ {
+ // Update the name, it may have changed
+ name = rootWidget.Name;
+
+ if (Changed != null)
+ Changed (this, new WindowEventArgs (this));
+ }
+
+ public bool BindToClass ()
+ {
+ if (SourceCodeFile != FilePath.Null)
+ return true;
+
+ // Find the classes that could be bound to this design
+ ProjectDom ctx = fproject.GetParserContext ();
+ ArrayList list = new ArrayList ();
+ foreach (IType cls in ctx.Types) {
+ if (IsValidClass (ctx, cls))
+ list.Add (cls.FullName);
+ }
+
+ // Ask what to do
+
+ try {
+ using (BindDesignDialog dialog = new BindDesignDialog (Name, list, Project.Project.BaseDirectory)) {
+ if (!dialog.Run ())
+ return false;
+
+ if (dialog.CreateNew)
+ CreateClass (dialog.ClassName, dialog.Namespace, dialog.Folder);
+
+ string fullName = dialog.Namespace.Length > 0 ? dialog.Namespace + "." + dialog.ClassName : dialog.ClassName;
+ rootWidget.Name = fullName;
+ fproject.Save (true);
+ }
+ return true;
+ } catch (Exception ex) {
+ MessageService.ShowException (ex);
+ return false;
+ }
+ }
+
+ void CreateClass (string name, string namspace, string folder)
+ {
+ string fullName = namspace.Length > 0 ? namspace + "." + name : name;
+
+ CodeRefactorer gen = new CodeRefactorer (fproject.Project.ParentSolution);
+ bool partialSupport = fproject.Project.UsePartialTypes;
+ Stetic.WidgetComponent component = (Stetic.WidgetComponent) rootWidget.Component;
+
+ CodeTypeDeclaration type = new CodeTypeDeclaration ();
+ type.Name = name;
+ type.IsClass = true;
+ type.IsPartial = partialSupport;
+ type.BaseTypes.Add (new CodeTypeReference (component.Type.ClassName));
+
+ // Generate the constructor. It contains the call that builds the widget.
+
+ CodeConstructor ctor = new CodeConstructor ();
+ ctor.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+
+ foreach (object val in component.Type.InitializationValues) {
+ if (val is Enum) {
+ ctor.BaseConstructorArgs.Add (
+ new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (val.GetType ()),
+ val.ToString ()
+ )
+ );
+ }
+ else
+ ctor.BaseConstructorArgs.Add (new CodePrimitiveExpression (val));
+ }
+
+ if (partialSupport) {
+ CodeMethodInvokeExpression call = new CodeMethodInvokeExpression (
+ new CodeMethodReferenceExpression (
+ new CodeThisReferenceExpression (),
+ "Build"
+ )
+ );
+ ctor.Statements.Add (call);
+ } else {
+ CodeMethodInvokeExpression call = new CodeMethodInvokeExpression (
+ new CodeMethodReferenceExpression (
+ new CodeTypeReferenceExpression ("Stetic.Gui"),
+ "Build"
+ ),
+ new CodeThisReferenceExpression (),
+ new CodeTypeOfExpression (fullName)
+ );
+ ctor.Statements.Add (call);
+ }
+ type.Members.Add (ctor);
+
+ // Add signal handlers
+
+ AddSignalsRec (type, component);
+ foreach (Stetic.Component ag in component.GetActionGroups ())
+ AddSignalsRec (type, ag);
+
+ // Create the class
+ IType cls = gen.CreateClass (Project.Project, ((DotNetProject)Project.Project).LanguageName, folder, namspace, type);
+ if (cls == null)
+ throw new UserException ("Could not create class " + fullName);
+
+ Project.Project.AddFile (cls.CompilationUnit.FileName, BuildAction.Compile);
+ IdeApp.ProjectOperations.Save (Project.Project);
+
+#if TRUNK
+ // Make sure the database is up-to-date
+ ProjectDomService.Parse (Project.Project, cls.CompilationUnit.FileName);
+#else
+ ProjectDomService.Parse (Project.Project, cls.CompilationUnit.FileName, null);
+#endif
+ }
+
+ void AddSignalsRec (CodeTypeDeclaration type, Stetic.Component comp)
+ {
+ foreach (Stetic.Signal signal in comp.GetSignals ()) {
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = signal.Handler;
+ met.Attributes = MemberAttributes.Family;
+ met.ReturnType = new CodeTypeReference (signal.SignalDescriptor.HandlerReturnTypeName);
+
+ foreach (Stetic.ParameterDescriptor pinfo in signal.SignalDescriptor.HandlerParameters)
+ met.Parameters.Add (new CodeParameterDeclarationExpression (pinfo.TypeName, pinfo.Name));
+
+ type.Members.Add (met);
+ }
+ foreach (Stetic.Component cc in comp.GetChildren ()) {
+ AddSignalsRec (type, cc);
+ }
+ }
+
+ internal bool IsValidClass (ProjectDom ctx, IType cls)
+ {
+ if (cls.BaseTypes != null) {
+ foreach (IReturnType bt in cls.BaseTypes) {
+ if (bt.FullName == rootWidget.Component.Type.ClassName)
+ return true;
+
+ IType baseCls = ctx.GetType (bt);
+ if (baseCls != null && IsValidClass (ctx, baseCls))
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ class OpenDocumentFileProvider: ITextFileProvider
+ {
+ public IEditableTextFile GetEditableTextFile (FilePath filePath)
+ {
+ foreach (Document doc in IdeApp.Workbench.Documents) {
+ if (doc.FileName == filePath) {
+ IEditableTextFile ef = doc.GetContent<IEditableTextFile> ();
+ if (ef != null) return ef;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs
new file mode 100644
index 0000000000..6cedb0f4b2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs
@@ -0,0 +1,211 @@
+//
+// GuiBuilderPropertiesPad.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using Gtk;
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.Ide.Commands;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ class PropertiesWidget: Gtk.VBox
+ {
+ public static PropertiesWidget Instance;
+
+ Stetic.SignalsEditor signalsEditor;
+
+ static PropertiesWidget ()
+ {
+ Instance = new PropertiesWidget ();
+ }
+
+ public PropertiesWidget ()
+ {
+ Stetic.WidgetPropertyTree grid = GuiBuilderService.SteticApp.PropertiesWidget;
+
+ Notebook tabs = new Notebook ();
+
+ tabs.AppendPage (grid, new Label (GettextCatalog.GetString ("Properties")));
+
+ signalsEditor = GuiBuilderService.SteticApp.SignalsWidget;
+ signalsEditor.SignalActivated += new EventHandler (OnSignalActivated);
+ tabs.AppendPage (signalsEditor, new Label (GettextCatalog.GetString ("Signals")));
+
+ Gtk.EventBox infoBox = new Gtk.EventBox ();
+ tabs.AppendPage (infoBox, new Gtk.Label (""));
+
+ PackStart (tabs, true, true, 0);
+
+ ShowAll ();
+ infoBox.Hide ();
+
+ tabs.Page = 0;
+ }
+
+ void OnSignalActivated (object s, EventArgs a)
+ {
+ GuiBuilderService.JumpToSignalHandler (signalsEditor.SelectedSignal);
+ }
+ }
+
+/* public class GuiBuilderPropertiesPad: AbstractPadContent
+ {
+ Stetic.WidGetTree grid;
+ Stetic.SignalsEditor signalsEditor;
+ Gtk.EventBox infoBox;
+ Gtk.Widget widget;
+ Stetic.Wrapper.Action currentAction;
+ Notebook tabs;
+
+ public GuiBuilderPropertiesPad (): base ("")
+ {
+ grid = GuiBuilderService.SteticApp.PropertiesWidget;
+
+ DefaultPlacement = "MonoDevelop.GtkCore.GuiBuilder.GuiBuilderPalettePad/bottom; right";
+
+ tabs = new Notebook ();
+
+ tabs.AppendPage (grid, new Label (GettextCatalog.GetString ("Properties")));
+
+ signalsEditor = GuiBuilderService.SteticApp.SignalsWidget;
+ signalsEditor.SignalActivated += new EventHandler (OnSignalActivated);
+ tabs.AppendPage (signalsEditor, new Label (GettextCatalog.GetString ("Signals")));
+
+ infoBox = new Gtk.EventBox ();
+ tabs.AppendPage (infoBox, new Gtk.Label (""));
+
+ widget = tabs;
+
+ widget.ShowAll ();
+ infoBox.Hide ();
+
+ tabs.Page = 0;
+ }
+
+ public override Gtk.Widget Control {
+ get { return widget; }
+ }
+
+ void OnSignalActivated (object s, EventArgs a)
+ {
+ GuiBuilderService.JumpToSignalHandler (signalsEditor.SelectedSignal);
+ }
+
+ public object TargetObject {
+ get {
+ return grid.TargetObject;
+ }
+ set {
+ Stetic.Wrapper.Action action = Stetic.ObjectWrapper.Lookup (value) as Stetic.Wrapper.Action;
+ if (action != null) {
+ // Don't allow editing of global actions
+ if (grid.Project != null && grid.Project.ActionGroups.IndexOf (action.ActionGroup) != -1) {
+ if (infoBox.Child != null)
+ infoBox.Remove (infoBox.Child);
+ infoBox.Add (CreateGlobalActionInfo (action));
+ infoBox.ShowAll ();
+ tabs.Page = 2;
+ tabs.ShowTabs = false;
+ grid.Hide ();
+ signalsEditor.Hide ();
+ return;
+ }
+ }
+
+ if (!grid.Visible) {
+ tabs.ShowTabs = true;
+ grid.Show ();
+ signalsEditor.Show ();
+ tabs.Page = 0;
+ infoBox.Hide ();
+ }
+
+ grid.TargetObject = value;
+ signalsEditor.TargetObject = value;
+ }
+ }
+
+ Gtk.Widget CreateGlobalActionInfo (Stetic.Wrapper.Action action)
+ {
+ currentAction = action;
+
+ Gtk.HBox hbox = new Gtk.HBox ();
+ hbox.BorderWidth = 12;
+ Gtk.Image img = new Gtk.Image (Gtk.Stock.DialogInfo, Gtk.IconSize.Menu);
+ img.Yalign = 0;
+ hbox.PackStart (img, false, false, 0);
+
+ Gtk.VBox box = new Gtk.VBox ();
+ Gtk.Label info = new Gtk.Label (GettextCatalog.GetString ("The action '{0}' belongs to the global action group '{1}'. To modify it, open the action group file.", action.MenuLabel, action.ActionGroup.Name));
+ info.Xalign = 0;
+ info.WidthRequest = 200;
+ info.LineWrap = true;
+ box.PackStart (info, false, false, 0);
+
+ HBox bb = new HBox ();
+ Gtk.Button but = new Gtk.Button (GettextCatalog.GetString ("Open Action Group"));
+ but.Clicked += new EventHandler (OnOpenGroup);
+ bb.PackStart (but, false, false, 0);
+ box.PackStart (bb, false, false, 12);
+
+ hbox.PackStart (box, true, true, 12);
+ hbox.ShowAll ();
+ return hbox;
+ }
+
+ void OnOpenGroup (object s, EventArgs args)
+ {
+ Project prj = GetProjectFromDesign (currentAction.ActionGroup);
+ if (prj != null) {
+ ActionGroupView view = GuiBuilderService.OpenActionGroup (prj, currentAction.ActionGroup);
+ if (view != null)
+ view.SelectAction (currentAction);
+ }
+ }
+
+
+ public static Project GetProjectFromDesign (Stetic.Wrapper.ActionGroup group)
+ {
+ if (IdeApp.ProjectOperations.CurrentOpenCombine == null)
+ return null;
+
+ foreach (Project prj in IdeApp.ProjectOperations.CurrentOpenCombine.GetAllProjects ()) {
+ GtkDesignInfo info = GtkCoreService.GetGtkInfo (prj);
+ if (info != null && info.GuiBuilderProject != null && info.GuiBuilderProject.SteticProject.ActionGroups.IndexOf (group) != -1)
+ return prj;
+ }
+ return null;
+ }
+
+ }
+*/
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs
new file mode 100644
index 0000000000..9e62498e33
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs
@@ -0,0 +1,77 @@
+//
+// ToolboxLoader.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using MonoDevelop.DesignerSupport.Toolbox;
+using MonoDevelop.Projects;
+using MonoDevelop.Core;
+using MonoDevelop.Core.Assemblies;
+using Stetic;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class ToolboxLoader: IToolboxLoader
+ {
+ public virtual string[] FileTypes {
+ get { return new string [] { "dll", "exe" }; }
+ }
+
+ public virtual IList<ItemToolboxNode> Load (LoaderContext ctx, string filename)
+ {
+ SystemPackage sp = Runtime.SystemAssemblyService.DefaultAssemblyContext.GetPackageFromPath (filename);
+ ReferenceType rt;
+ string rname;
+
+ if (sp != null) {
+ rt = ReferenceType.Gac;
+ rname = Runtime.SystemAssemblyService.DefaultAssemblyContext.GetAssemblyFullName (filename, null);
+ } else {
+ rt = ReferenceType.Assembly;
+ rname = filename;
+ }
+
+ List<ItemToolboxNode> list = new List<ItemToolboxNode> ();
+ ComponentType[] types = null;
+ DispatchService.GuiSyncDispatch (delegate {
+ // Stetic is not thread safe, it has to be used from the gui thread
+ types = GuiBuilderService.SteticApp.GetComponentTypes (filename);
+ });
+ foreach (ComponentType ct in types) {
+ if (ct.Category == "window")
+ continue;
+ ComponentToolboxNode cn = new ComponentToolboxNode (ct);
+ cn.ReferenceType = rt;
+ cn.Reference = rname;
+ list.Add (cn);
+ }
+ return list;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs
new file mode 100644
index 0000000000..9d46b89d04
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs
@@ -0,0 +1,201 @@
+
+using System;
+using System.ComponentModel;
+using System.Collections;
+using System.Collections.Generic;
+
+using MonoDevelop.DesignerSupport.Toolbox;
+using MonoDevelop.Projects;
+using MonoDevelop.Core.Serialization;
+using Stetic;
+using MonoDevelop.Core;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.GuiBuilder
+{
+ public class ToolboxProvider: IToolboxDynamicProvider, IToolboxDefaultProvider
+ {
+ internal static ToolboxProvider Instance;
+
+ public ToolboxProvider ()
+ {
+ Instance = this;
+ }
+
+ public IEnumerable<ItemToolboxNode> GetDynamicItems (IToolboxConsumer consumer)
+ {
+ GuiBuilderView view = consumer as GuiBuilderView;
+ if (view == null)
+ return null;
+
+ ComponentType[] types = view.GetComponentTypes ();
+ if (types == null)
+ return null;
+
+ Hashtable refs = new Hashtable ();
+ Hashtable projects = new Hashtable ();
+ string of = FileService.GetFullPath (view.Project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration));
+ projects [of] = view.Project.Name;
+ foreach (ProjectReference pr in ((DotNetProject)view.Project).References)
+ foreach (string f in pr.GetReferencedFileNames (IdeApp.Workspace.ActiveConfiguration)) {
+ if (pr.ReferenceType == ReferenceType.Project)
+ projects[FileService.GetFullPath (f)] = pr.Reference;
+ else
+ refs[FileService.GetFullPath (f)] = f;
+ }
+
+ List<ItemToolboxNode> list = new List<ItemToolboxNode> ();
+ foreach (ComponentType type in types) {
+ if (type.Category == "window")
+ continue;
+
+ string fullName = null;
+ if (!String.IsNullOrEmpty (type.Library))
+ fullName = FileService.GetFullPath (type.Library);
+
+ if (type.ClassName == "Gtk.Action" || (fullName != null && refs.Contains (fullName))) {
+ ComponentToolboxNode node = new ComponentToolboxNode (type);
+ list.Add (node);
+ } else if (fullName != null && projects.Contains (fullName)) {
+ ComponentToolboxNode node = new ComponentToolboxNode (type);
+ node.Category = (string) projects [fullName];
+ list.Add (node);
+ }
+ }
+ list.Sort ();
+ return list;
+ }
+
+ public void NotifyItemsChanged ()
+ {
+ if (ItemsChanged != null)
+ ItemsChanged (this, EventArgs.Empty);
+ }
+
+ public virtual IEnumerable<ItemToolboxNode> GetDefaultItems ()
+ {
+ return null;
+ }
+
+ public virtual IEnumerable<string> GetDefaultFiles ()
+ {
+ yield return typeof(Stetic.Wrapper.Widget).Assembly.Location;
+ }
+
+ public event EventHandler ItemsChanged;
+ }
+
+ class ComponentToolboxNode: ItemToolboxNode
+ {
+ public ComponentType componentType;
+
+ [ItemProperty]
+ ReferenceType refType;
+ [ItemProperty]
+ string reference;
+ [ItemProperty]
+ string className;
+ [ItemProperty]
+ string gtkVersion;
+
+ static ToolboxItemFilterAttribute[] attributes = new ToolboxItemFilterAttribute[] {
+ new ToolboxItemFilterAttribute ("gtk-sharp", ToolboxItemFilterType.Require)
+ };
+
+ internal static readonly string GtkWidgetDomain = GettextCatalog.GetString ("GTK# Widgets");
+
+ public ComponentToolboxNode ()
+ {
+ }
+
+ public ComponentToolboxNode (ComponentType type)
+ {
+ if (type.Description.Length > 0)
+ Name = type.Description;
+ else {
+ int i = type.Name.LastIndexOf ('.');
+ if (i == -1)
+ Name = type.Name;
+ else
+ Name = type.Name.Substring (i+1);
+ }
+
+ componentType = type;
+ className = type.ClassName;
+ Category = GetCategoryName (type.Category);
+ Icon = type.Icon;
+ gtkVersion = type.TargetGtkVersion;
+ }
+
+ [Browsable (false)]
+ public override IList<ToolboxItemFilterAttribute> ItemFilters {
+ get { return attributes; }
+ }
+
+ [Browsable (false)]
+ public Stetic.ComponentType ComponentType {
+ get {
+ return componentType;
+ }
+ }
+
+ [ReadOnly (true)]
+ [LocalizedCategory ("Misc")]
+ [LocalizedDisplayName ("Reference Type")]
+ [LocalizedDescription ("The type of the project or assembly from which this component originates.")]
+ public ReferenceType ReferenceType {
+ get {
+ return refType;
+ }
+ set {
+ refType = value;
+ }
+ }
+
+ [ReadOnly (true)]
+ [LocalizedCategory ("Misc")]
+ [LocalizedDisplayName ("Reference Path")]
+ [LocalizedDescription ("The project or assembly from which this component originates.")]
+ public string Reference {
+ get {
+ return reference;
+ }
+ set {
+ reference = value;
+ }
+ }
+
+ [LocalizedCategory ("Misc")]
+ [LocalizedDisplayName ("Class Name")]
+ [LocalizedDescription ("The name of the component class.")]
+ public string ClassName {
+ get {
+ return className;
+ }
+ }
+
+ [LocalizedCategory ("Misc")]
+ [LocalizedDisplayName ("GTK# Version")]
+ [LocalizedDescription ("The minimum GTK# version required to use this component.")]
+ public string GtkVersion {
+ get {
+ return gtkVersion;
+ }
+ }
+
+ string GetCategoryName (string cat)
+ {
+ if (cat == "container")
+ return GettextCatalog.GetString ("Containers");
+ else if (cat == "widget")
+ return GettextCatalog.GetString ("Widgets");
+ else
+ return cat;
+ }
+
+ [Browsable (false)]
+ public override string ItemDomain {
+ get { return GtkWidgetDomain; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs
new file mode 100644
index 0000000000..0a3436e189
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs
@@ -0,0 +1,145 @@
+//
+// ActionGroupNodeBuilder.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.GtkCore.Dialogs;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui.Components;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ public class ActionGroupNodeBuilder: TypeNodeBuilder
+ {
+ public override Type CommandHandlerType {
+ get { return typeof(ActionGroupCommandHandler); }
+ }
+
+ public override string ContextMenuAddinPath {
+ get { return "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.ActionGroup"; }
+ }
+
+ public override Type NodeDataType {
+ get { return typeof(Stetic.ActionGroupInfo); }
+ }
+
+ public override string GetNodeName (ITreeNavigator thisNode, object dataObject)
+ {
+ Stetic.ActionGroupInfo group = (Stetic.ActionGroupInfo) dataObject;
+ return group.Name;
+ }
+
+ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
+ {
+ Stetic.ActionGroupInfo group = (Stetic.ActionGroupInfo) dataObject;
+ label = group.Name;
+ icon = ImageService.GetPixbuf ("md-gtkcore-actiongroup", Gtk.IconSize.Menu);
+ }
+
+ public override void OnNodeAdded (object dataObject)
+ {
+ Stetic.ActionGroupInfo group = (Stetic.ActionGroupInfo) dataObject;
+ group.Changed += new EventHandler (OnChanged);
+ }
+
+ public override void OnNodeRemoved (object dataObject)
+ {
+ Stetic.ActionGroupInfo group = (Stetic.ActionGroupInfo) dataObject;
+ group.Changed -= new EventHandler (OnChanged);
+ }
+
+ void OnChanged (object s, EventArgs a)
+ {
+ ITreeBuilder tb = Context.GetTreeBuilder (s);
+ if (tb != null)
+ tb.Update ();
+ }
+ }
+
+ class ActionGroupCommandHandler: NodeCommandHandler
+ {
+ public override void ActivateItem ()
+ {
+ GuiBuilderWindow w = (GuiBuilderWindow) CurrentNode.GetParentDataItem (typeof(GuiBuilderWindow), false);
+ if (w != null) {
+ if (w.SourceCodeFile == FilePath.Null && !w.BindToClass ())
+ return;
+
+ Document doc = IdeApp.Workbench.OpenDocument (w.SourceCodeFile, true);
+ if (doc != null) {
+ GuiBuilderView view = doc.GetContent<GuiBuilderView> ();
+ if (view != null)
+ view.ShowActionDesignerView (((Stetic.ActionGroupInfo) CurrentNode.DataItem).Name);
+ }
+ }
+ else {
+ Project project = (Project) CurrentNode.GetParentDataItem (typeof(Project), false);
+ Stetic.ActionGroupInfo group = (Stetic.ActionGroupInfo) CurrentNode.DataItem;
+ GuiBuilderService.OpenActionGroup (project, group);
+ }
+ }
+
+ public override bool CanDeleteItem ()
+ {
+ // Don't allow deleting action groups local to a window
+ GuiBuilderWindow w = (GuiBuilderWindow) CurrentNode.GetParentDataItem (typeof(GuiBuilderWindow), false);
+ return (w == null);
+ }
+
+ public override void DeleteItem ()
+ {
+ // Don't allow deleting action groups local to a window
+ GuiBuilderWindow w = (GuiBuilderWindow) CurrentNode.GetParentDataItem (typeof(GuiBuilderWindow), false);
+ if (w != null)
+ return;
+
+ Project project = (Project) CurrentNode.GetParentDataItem (typeof(Project), false);
+ Stetic.ActionGroupInfo group = (Stetic.ActionGroupInfo) CurrentNode.DataItem;
+ GuiBuilderProject gproject = GtkDesignInfo.FromProject (project).GuiBuilderProject;
+ string sfile = gproject.GetSourceCodeFile (group);
+
+ if (sfile != null) {
+ using (ConfirmWindowDeleteDialog dialog = new ConfirmWindowDeleteDialog (group.Name, sfile, group)) {
+ if (dialog.Run () == (int) Gtk.ResponseType.Yes) {
+ if (dialog.DeleteFile) {
+ ProjectFile file = project.GetProjectFile (sfile);
+ if (file != null)
+ project.Files.Remove (file);
+ }
+ gproject.RemoveActionGroup (group);
+ gproject.Save (false);
+ IdeApp.ProjectOperations.Save (project);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ChangeLog
new file mode 100644
index 0000000000..f73c1a92e9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ChangeLog
@@ -0,0 +1,83 @@
+2010-09-17 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GuiProjectFolderNodeBuilder.cs:
+
+2010-09-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectNodeBuilder.cs:
+
+2010-08-30 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectFileNodeBuilderExtension.cs:
+
+2010-08-17 Krzysztof Marecki <freefirma@gmail.com>
+
+ * WindowsFolder.cs:
+ * WidgetNodeBuilder.cs:
+ * WindowsFolderNodeBuilder.cs:
+ * ProjectFileNodeBuilderExtension.cs:
+
+2010-08-16 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectNodeBuilder.cs:
+ * GuiProjectFolderNodeBuilder.cs:
+ * ProjectFolderNodeBuilderExtension.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectNodeBuilder.cs:
+ * GuiProjectFolderNodeBuilder.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectFileExtension.cs:
+ * GuiProjectFolderNodeBuilder.cs:
+ * ProjectFileNodeBuilderExtension.cs:
+ * ProjectFolderNodeBuilderExtension.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectNodeBuilder.cs:
+ * StockIconsNodeBuilder.cs:
+ * ProjectFileNodeBuilderExtension.cs:
+ * ProjectFolderNodeBuilderExtension.cs:
+
+2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GuiProjectFolder.cs: Put gui project folder directly below References
+ in the project pad
+ * ProjectNodeBuilder.cs:
+ * GuiProjectFolderNodeBuilder.cs:
+ * ProjectFolderNodeBuilderExtension.cs:
+
+2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectFileExtension.cs: Move cursor in entryFolder to the end.
+
+2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectFileExtension.cs: Better approach for obtaining GtkComponentType
+ * ProjectFileNodeBuilderExtension.cs:
+ * ProjectFolderNodeBuilderExtension.cs:
+
+2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectNodeBuilder.cs:
+ * ProjectFileNodeBuilderExtension.cs:
+ * ProjectFolderNodeBuilderExtension.cs:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectNodeBuilder.cs:
+ * ProjectFileNodeBuilderExtension.cs: Show ProjectConversionDialog before
+ conversion
+
+2010-06-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectNodeBuilder.cs: Convert a project file layout on open
+ * ProjectFileNodeBuilderExtension.cs: Group components files
+
+2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectFileNodeBuilderExtension.cs:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs
new file mode 100644
index 0000000000..3324cee3d2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs
@@ -0,0 +1,42 @@
+//
+// GuiProjectFolder.cs
+//
+// Author:
+// Krzysztof Marecki <marecki.krzysztof@gmail.com>
+//
+// Copyright (c) 2010 KrzysztofMarecki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui.Pads.ProjectPad;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ public class GuiProjectFolder : ProjectFolder
+ {
+ public GuiProjectFolder (FilePath absolutePath, IWorkspaceObject parentWorkspaceObject, object parent)
+ : base (absolutePath, parentWorkspaceObject, parent)
+ {
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs
new file mode 100644
index 0000000000..a5e9b46dec
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs
@@ -0,0 +1,177 @@
+//
+// GuiProjectFolderNodeBuilder.cs
+//
+// Author:
+// Krzysztof Marecki <marecki.krzysztof@gmail.com>
+//
+// Copyright (c) 2010 KrzysztofMarecki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+using System;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Ide;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Gui.Components;
+using MonoDevelop.Ide.Gui.Pads.ProjectPad;
+using MonoDevelop.Projects;
+
+using MonoDevelop.GtkCore.GuiBuilder;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ public class GuiProjectFolderNodeBuilder : ProjectFolderNodeBuilder
+ {
+ public override Type NodeDataType {
+ get { return typeof(GuiProjectFolder); }
+ }
+
+ public override Type CommandHandlerType {
+ get { return typeof(GuiProjectFolderCommandHandler); }
+ }
+
+ public override string GetNodeName (ITreeNavigator thisNode, object dataObject)
+ {
+ //nodes are sorted alphabetically and we want to have gui folder on the top
+ return string.Empty;
+ }
+
+
+ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
+ {
+ GuiProjectFolder folder = (GuiProjectFolder) dataObject;
+
+ icon = Context.GetIcon (Stock.OpenResourceFolder);
+ closedIcon = Context.GetIcon (Stock.ClosedResourceFolder);
+ label = folder.Name;
+ }
+ }
+
+ public class GuiProjectFolderCommandHandler : ProjectFolderCommandHandler
+ {
+ [CommandHandler (GtkCommands.ImportGladeFile)]
+ protected void OnImportGladeFile ()
+ {
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ GuiBuilderService.ImportGladeFile (project);
+ }
+
+ [CommandUpdateHandler (GtkCommands.ImportGladeFile)]
+ protected void UpdateImportGladeFile (CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow ();
+ }
+
+ [CommandHandler (GtkCommands.EditIcons)]
+ protected void OnEditIcons ()
+ {
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ GuiBuilderProject gp = GtkDesignInfo.FromProject (project).GuiBuilderProject;
+ Stetic.Project sp = gp.SteticProject;
+ sp.EditIcons ();
+ gp.Save (true);
+ }
+
+ [CommandUpdateHandler (GtkCommands.EditIcons)]
+ protected void UpdateEditIcons (CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow ();
+ }
+
+ [CommandHandler (GtkCommands.GtkSettings)]
+ protected void OnGtkSettings ()
+ {
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ IdeApp.ProjectOperations.ShowOptions (project, "SteticOptionsPanel");
+ }
+
+ [CommandUpdateHandler (GtkCommands.EditIcons)]
+ protected void UpdateGtkSettings (CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow ();
+ }
+
+ [CommandUpdateHandler (EditCommands.Delete)]
+ [CommandUpdateHandler (EditCommands.Rename)]
+ [CommandUpdateHandler (ProjectCommands.AddNewFiles)]
+ [CommandUpdateHandler (ProjectCommands.AddFiles)]
+ [CommandUpdateHandler (ProjectCommands.AddSolutionFolder)]
+ [CommandUpdateHandler (ProjectCommands.AddItem)]
+ [CommandUpdateHandler (ProjectCommands.NewFolder)]
+ [CommandUpdateHandler ("MonoDevelop.Refactoring.RefactoryCommands.Rename")]
+ protected void UpdateDisabledCommands (CommandInfo cinfo)
+ {
+ cinfo.Visible = false;
+ cinfo.Enabled = false;
+ }
+
+ bool CanAddWindow ()
+ {
+ DotNetProject project = CurrentNode.GetParentDataItem (typeof(Project), true) as DotNetProject;
+ return GtkDesignInfo.SupportsDesigner (project);
+ }
+
+ public override DragOperation CanDragNode ()
+ {
+ return DragOperation.None;
+ }
+
+ public override bool CanDeleteItem ()
+ {
+ return false;
+ }
+
+ public override bool CanDropMultipleNodes (object[] dataObjects, DragOperation operation)
+ {
+ return false;
+ }
+
+ public override bool CanDropMultipleNodes (object[] dataObjects, DragOperation operation, DropPosition position)
+ {
+ return false;
+ }
+
+ public override bool CanDeleteMultipleItems ()
+ {
+ return false;
+ }
+
+ public override bool CanDropNode (object dataObject, DragOperation operation)
+ {
+ return false;
+ }
+
+ public override bool CanDropNode (object dataObject, DragOperation operation, DropPosition position)
+ {
+ return false;
+ }
+
+ public override void RenameItem (string newName)
+ {
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ info.SteticFolderName = newName;
+
+ base.RenameItem (newName);
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs
new file mode 100644
index 0000000000..9919981679
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs
@@ -0,0 +1,52 @@
+using System;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ public enum GtkComponentType
+ {
+ Dialog,
+ Widget,
+ ActionGroup,
+ IconFactory,
+ None
+ }
+
+ public static class ProjectFileExtension
+ {
+ public static bool IsComponentFile (this ProjectFile pf)
+ {
+ return pf.GetComponentType () != GtkComponentType.None;
+ }
+
+ public static GtkComponentType GetComponentType (this ProjectFile pf)
+ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (pf.Project);
+ ParsedDocument doc = ProjectDomService.GetParsedDocument (ProjectDomService.GetProjectDom (pf.Project), pf.Name);
+ //ParsedDocument doc = ProjectDomService.ParseFile (ProjectDomService.GetProjectDom (pf.Project), pf.FilePath.ToString ());
+ if (doc != null && doc.CompilationUnit != null) {
+ foreach (IType t in doc.CompilationUnit.Types) {
+ string className = t.FullName;
+ if (className != null) {
+ GuiBuilderWindow win = info.GuiBuilderProject.GetWindowForClass (className);
+ if (win != null)
+ return win.RootWidget.IsWindow ? GtkComponentType.Dialog : GtkComponentType.Widget;
+
+ Stetic.ActionGroupInfo action = info.GuiBuilderProject.GetActionGroup (className);
+ if (action != null)
+ return GtkComponentType.ActionGroup;
+
+ }
+ }
+ }
+ if (pf.Name.Contains ("IconFactory.gtkx"))
+ return GtkComponentType.IconFactory;
+
+ return GtkComponentType.None;
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs
new file mode 100644
index 0000000000..8e449efcd1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs
@@ -0,0 +1,179 @@
+using System;
+
+using MonoDevelop.Components.Commands;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.Ide;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Gui.Components;
+using MonoDevelop.Ide.Gui.Content;
+using MonoDevelop.Ide.Gui.Pads.ProjectPad;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ public class ProjectFileBuilder : ProjectFileNodeBuilder
+ {
+
+ }
+
+ public class ProjectFileNodeBuilderExtension : NodeBuilderExtension
+ {
+ public override bool CanBuildNode (Type dataType)
+ {
+ return typeof(ProjectFile).IsAssignableFrom (dataType);
+ }
+
+ public override Type CommandHandlerType {
+ get { return typeof (ComponentCommandHandler); }
+ }
+
+ public override void GetNodeAttributes (ITreeNavigator treeNavigator, object dataObject, ref NodeAttributes attributes)
+ {
+ if (treeNavigator.Options ["ShowAllFiles"])
+ return;
+
+ ProjectFile pf = (ProjectFile) dataObject;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (pf.Project);
+ //Designer files in the designer folder like IconFactory.gtkx should be always visible
+ if (info.HideGtkxFiles &&
+ pf.FilePath.Extension == ".gtkx" &&
+ !pf.FilePath.IsChildPathOf (info.SteticFolder))
+ attributes |= NodeAttributes.Hidden;
+ }
+
+
+ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
+ {
+ ProjectFile pf = (ProjectFile) dataObject;
+
+ //do not show custom icon for generated source files
+ if (pf.DependsOn == null) {
+ GtkComponentType type = pf.GetComponentType ();
+
+ switch (type) {
+ case GtkComponentType.Dialog :
+ icon = ImageService.GetPixbuf ("md-gtkcore-dialog", Gtk.IconSize.Menu);
+ break;
+ case GtkComponentType.Widget :
+ icon = ImageService.GetPixbuf ("md-gtkcore-widget", Gtk.IconSize.Menu);
+ break;
+ case GtkComponentType.ActionGroup :
+ icon = ImageService.GetPixbuf ("md-gtkcore-actiongroup", Gtk.IconSize.Menu);
+ break;
+ case GtkComponentType.IconFactory :
+ icon = ImageService.GetPixbuf ("md-gtkcore-iconfactory", Gtk.IconSize.Menu);
+ label = "Stock icons";
+ break;
+ }
+ }
+ }
+
+ //override
+ public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
+ {
+ return base.HasChildNodes (builder, dataObject);
+ }
+ }
+
+ public class ComponentCommandHandler : NodeCommandHandler
+ {
+ /*public override void ActivateItem ()
+ {
+ ProjectFile pf = (ProjectFile) CurrentNode.DataItem;
+
+ if (pf.IsComponentFile ()) {
+ Document doc = IdeApp.Workbench.OpenDocument (pf.FilePath, true);
+
+ if (doc != null) {
+ GuiBuilderView view = doc.GetContent<GuiBuilderView> ();
+ if (view != null) {
+ GtkComponentType type = pf.GetComponentType ();
+
+ switch (type) {
+ case GtkComponentType.Dialog :
+ case GtkComponentType.Widget :
+ view.ShowDesignerView ();
+ break;
+ case GtkComponentType.ActionGroup :
+ view.ShowActionDesignerView (((Stetic.ActionGroupInfo) CurrentNode.DataItem).Name);
+ break;
+ }
+ }
+ }
+ return;
+ }
+ base.ActivateItem ();
+ }
+ */
+
+ [CommandHandler (GtkCommands.GenerateCode)]
+ protected void OnGenerateCode ()
+ {
+ ProjectFile pf = CurrentNode.DataItem as ProjectFile;
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ GuiBuilderProject gproject = info.GuiBuilderProject;
+
+ gproject.GenerateCode (pf.FilePath);
+ }
+
+ [CommandHandler (GtkCommands.ReloadDesigner)]
+ protected void OnReloadDesigner ()
+ {
+ ProjectFile pf = CurrentNode.DataItem as ProjectFile;
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ GuiBuilderProject gproject = info.GuiBuilderProject;
+
+ Document doc = IdeApp.Workbench.GetDocument (pf.FilePath);
+ if (doc != null) {
+ gproject.ReloadFile(pf.FilePath);
+ GuiBuilderView view = doc.ActiveView as GuiBuilderView;
+ if (view != null)
+ view.ReloadDesigner (project);
+ }
+ }
+
+ [CommandUpdateHandler (GtkCommands.GenerateCode)]
+ [CommandUpdateHandler (GtkCommands.ReloadDesigner)]
+ protected void UpdateGenerateCode (CommandInfo cinfo)
+ {
+ ProjectFile pf = CurrentNode.DataItem as ProjectFile;
+
+ if (pf.DependsOn == null && pf.HasChildren)
+ cinfo.Visible = pf.IsComponentFile ();
+ else
+ cinfo.Visible = false;
+ }
+
+ [CommandUpdateHandler (EditCommands.Copy)]
+ [CommandUpdateHandler (EditCommands.Delete)]
+ [CommandUpdateHandler (EditCommands.Rename)]
+ protected void UpdateDisabledCommands (CommandInfo cinfo)
+ {
+ //disable operations for generated files in designer folder
+ cinfo.Visible = false;//(CurrentNode.GetParentDataItem (typeof (GuiProjectFolder), true) == null);
+ }
+
+ public override DragOperation CanDragNode ()
+ {
+ return DragOperation.None;
+ }
+
+ public override void RenameItem (string newName)
+ {
+ base.RenameItem (newName);
+
+ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+ if (project != null) {
+ ProjectFile pf = CurrentNode.DataItem as ProjectFile;
+ if (pf.IsComponentFile ()) {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ info.RenameComponentFile (pf);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs
new file mode 100644
index 0000000000..6a20ae85de
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs
@@ -0,0 +1,156 @@
+//
+// ProjectFolderNodeBuilderExtension.cs
+//
+// Author:
+// Lluis Sanchez Gual, Krzysztof Marecki
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2010 Krzysztof Marecki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui.Pads.ProjectPad;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Gui.Components;
+using MonoDevelop.Ide;
+using MonoDevelop.Ide.Commands;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ class ProjectFolderNodeBuilderExtension: NodeBuilderExtension
+ {
+ public override bool CanBuildNode (Type dataType)
+ {
+ return typeof(ProjectFolder).IsAssignableFrom (dataType) && !(dataType is GuiProjectFolder);
+ }
+
+ public override Type CommandHandlerType {
+ get { return typeof(UserInterfaceCommandHandler); }
+ }
+
+ public override void GetNodeAttributes (ITreeNavigator treeNavigator, object dataObject, ref NodeAttributes attributes)
+ {
+ if (dataObject is GuiProjectFolder)
+ return;
+
+ ProjectFolder folder = dataObject as ProjectFolder;
+ if (folder != null && folder.Project is DotNetProject) {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (folder.Project);
+ if (info.SteticFolder == folder.Path)
+ attributes |= NodeAttributes.Hidden;
+ }
+ }
+ }
+
+ class UserInterfaceCommandHandler: NodeCommandHandler
+ {
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewDialog)]
+ public void AddNewDialogToProject()
+ {
+ AddNewWindow ("DialogFileTemplate");
+ }
+
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewDialog)]
+ public void UpdateAddNewDialogToProject (CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWindow)]
+ public void AddNewWindowToProject()
+ {
+ AddNewWindow ("WindowFileTemplate");
+ }
+
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWindow)]
+ public void UpdateAddNewWindowToProject (CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWidget)]
+ public void AddNewWidgetToProject()
+ {
+ AddNewWindow ("WidgetFileTemplate");
+ }
+
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWidget)]
+ public void UpdateAddNewWidgetToProject (CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup)]
+ public void AddNewActionGroupToProject()
+ {
+ AddNewWindow ("ActionGroupFileTemplate");
+ }
+
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup)]
+ public void UpdateAddNewActionGroupToProject(CommandInfo cinfo)
+ {
+ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+ public override bool CanDropMultipleNodes (object[] dataObjects, DragOperation operation, DropPosition position)
+ {
+ foreach (object dataObject in dataObjects)
+ if (dataObjects is GuiProjectFolder)
+ return false;
+
+ return base.CanDropMultipleNodes (dataObjects, operation, position);
+ }
+
+ bool CanAddWindow ()
+ {
+ DotNetProject project = CurrentNode.GetParentDataItem (typeof(Project), true) as DotNetProject;
+ return GtkDesignInfo.SupportsDesigner (project);
+ }
+
+ public void AddNewWindow (string id)
+ {
+ DotNetProject project = CurrentNode.GetParentDataItem (typeof(Project), true) as DotNetProject;
+ if (project == null)
+ return;
+
+ object dataItem = CurrentNode.DataItem;
+
+ ProjectFolder folder = CurrentNode.GetParentDataItem (typeof(ProjectFolder), true) as ProjectFolder;
+ id = "Partial" + id;
+
+ string path;
+ if (folder != null)
+ path = folder.Path;
+ else
+ path = project.BaseDirectory;
+
+ IdeApp.ProjectOperations.CreateProjectFile (project, path, id);
+ IdeApp.ProjectOperations.Save (project);
+
+ ITreeNavigator nav = Tree.GetNodeAtObject (dataItem);
+ if (nav != null)
+ nav.Expanded = true;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs
new file mode 100644
index 0000000000..20de8ff9f4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs
@@ -0,0 +1,140 @@
+//
+// ProjectNodeBuilder.cs
+//
+// Author:
+// Lluis Sanchez Gual, Krzysztof Marecki
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2010 Krzysztof Marecki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections;
+using System.IO;
+
+using Gtk;
+
+using MonoDevelop.Projects;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui.Pads;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Gui.Components;
+using MonoDevelop.Ide.Gui.Pads.ProjectPad;
+using MonoDevelop.GtkCore.Dialogs;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ public class ProjectNodeBuilder: NodeBuilderExtension
+ {
+ static ProjectNodeBuilder instance;
+
+ public override bool CanBuildNode (Type dataType)
+ {
+ return typeof(DotNetProject).IsAssignableFrom (dataType);
+ }
+
+ public override Type CommandHandlerType {
+ get {
+ return typeof (UserInterfaceCommandHandler);
+ }
+ }
+
+ protected override void Initialize ()
+ {
+ lock (typeof (ProjectNodeBuilder))
+ instance = this;
+ }
+
+ public override void Dispose ()
+ {
+ lock (typeof (ProjectNodeBuilder))
+ instance = null;
+ }
+
+ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
+ {
+ Project project = dataObject as Project;
+
+ if (project is DotNetProject) {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+
+ if (info.NeedsConversion) {
+ ProjectConversionDialog dialog = new ProjectConversionDialog (project, info.SteticFolderName);
+
+ try
+ {
+ if (dialog.Run () == (int)ResponseType.Yes) {
+ info.GuiBuilderProject.Convert (dialog.GuiFolderName, dialog.MakeBackup);
+ IdeApp.ProjectOperations.Save (project);
+ }
+ } finally {
+ dialog.Destroy ();
+ }
+ }
+
+ project.FileAddedToProject += HandleProjectFileAddedToProject;
+ }
+ }
+
+ void HandleProjectFileAddedToProject (object sender, ProjectFileEventArgs e)
+ {
+ Project project = e.Project;
+ ProjectFile pf = e.ProjectFile;
+ string fileName = pf.FilePath.FullPath.ToString ();
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+
+ string buildFile = info.GetBuildFileFromComponent (fileName);
+ if (!project.IsFileInProject(buildFile) && File.Exists (buildFile)) {
+ ProjectFile pf2 = project.AddFile (buildFile, BuildAction.Compile);
+ pf2.DependsOn = pf.FilePath.FileName;
+ }
+
+ string gtkxFile = info.GetDesignerFileFromComponent (fileName);
+ if (!project.IsFileInProject(gtkxFile) && File.Exists (gtkxFile)) {
+ ProjectFile pf3 = project.AddFile (gtkxFile, BuildAction.EmbeddedResource);
+ pf3.DependsOn = pf.FilePath.FileName;
+ }
+ }
+
+ public override void BuildChildNodes (ITreeBuilder builder, object dataObject)
+ {
+ Project project = (Project)dataObject;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+
+ if (GtkDesignInfo.HasDesignedObjects (project)) {
+ GuiProjectFolder folder = new GuiProjectFolder(info.SteticFolder.FullPath, project, null);
+ builder.AddChild (folder);
+ }
+ }
+
+ public static void OnSupportChanged (Project p)
+ {
+ if (instance == null)
+ return;
+
+ ITreeBuilder tb = instance.Context.GetTreeBuilder (p);
+ if (tb != null)
+ tb.UpdateAll ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs
new file mode 100644
index 0000000000..862112d5ff
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs
@@ -0,0 +1,88 @@
+
+using System;
+using Gdk;
+
+using MonoDevelop.Ide.Gui.Pads;
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.Ide.Gui.Components;
+
+namespace MonoDevelop.GtkCore.NodeBuilders
+{
+ class StockIconsNode
+ {
+ public StockIconsNode (Project project)
+ {
+ this.Project = project;
+ }
+
+ public Project Project;
+ }
+
+ public class StockIconsNodeBuilder: TypeNodeBuilder
+ {
+ Pixbuf iconsIcon;
+
+ public override Type NodeDataType {
+ get { return typeof(StockIconsNode); }
+ }
+
+ public override Type CommandHandlerType {
+ get { return typeof(StockIconsNodeCommandHandler); }
+ }
+
+ public override string ContextMenuAddinPath {
+ get { return "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.StockIcons"; }
+ }
+ public StockIconsNodeBuilder ()
+ {
+ try {
+ iconsIcon = Pixbuf.LoadFromResource ("image-x-generic.png");
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf 'image-x-generic.png': " + e);
+ }
+ }
+ public override int CompareObjects (ITreeNavigator thisNode, ITreeNavigator otherNode)
+ {
+ return -1;
+ }
+
+
+ public override string GetNodeName (ITreeNavigator thisNode, object dataObject)
+ {
+ return "StockIcons";
+ }
+
+ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Pixbuf icon, ref Pixbuf closedIcon)
+ {
+ label = GettextCatalog.GetString ("Stock Icons");
+ icon = iconsIcon;
+ }
+ }
+
+ public class StockIconsNodeCommandHandler: NodeCommandHandler
+ {
+ public override void ActivateItem ()
+ {
+ StockIconsNode node = (StockIconsNode) CurrentNode.DataItem;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (node.Project);
+ GuiBuilderProject gp = info.GuiBuilderProject;
+ Stetic.Project sp = gp.SteticProject;
+ sp.ImagesRootPath = FileService.AbsoluteToRelativePath (info.SteticFolder, gp.Project.BaseDirectory);
+ sp.ImportFileCallback = delegate (string file) {
+ return GuiBuilderService.ImportFile (gp.Project, file);
+ };
+ sp.EditIcons ();
+ gp.Save (true);
+ }
+
+ [CommandHandler (GtkCommands.EditIcons)]
+ protected void OnEditIcons ()
+ {
+ ActivateItem ();
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ChangeLog
new file mode 100644
index 0000000000..a613ab6eb0
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ChangeLog
@@ -0,0 +1,68 @@
+2010-09-20 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * WidgetFileDescriptionTemplate.cs:
+
+2010-09-17 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-09-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-09-08 Krzysztof Marecki <freefirma@gmail.com>
+
+ * WidgetFileDescriptionTemplate.cs:
+
+2010-08-30 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-08-27 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-08-17 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-08-16 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * WidgetFileDescriptionTemplate.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GtkDesignInfo.cs: Add ComponentNeedsCodeGeneration method,
+
+2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
+
+ * WidgetFileDescriptionTemplate.cs: Bump Api
+
+2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GtkDesignInfo.cs: Remove gtk-gui folder after project conversion
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GtkDesignInfo.cs:
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GtkDesignInfo.cs: Transition from project file name to project folder.
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/Counters.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/Counters.cs
new file mode 100644
index 0000000000..970caa63d0
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/Counters.cs
@@ -0,0 +1,38 @@
+//
+// Counters.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using MonoDevelop.Core.Instrumentation;
+
+namespace MonoDevelop.GtkCore
+{
+ internal static class Counters
+ {
+ public static Counter GuiProjectsInMemory = InstrumentationService.CreateCounter ("GUI Projects in Memory", "GTK# Designer");
+ public static Counter GuiProjectsLoaded = InstrumentationService.CreateCounter ("GUI Projects Loaded", "GTK# Designer");
+ public static Counter SteticProjectsLoaded = InstrumentationService.CreateCounter ("Stetic Projects Loaded", "GTK# Designer");
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkCoreService.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkCoreService.cs
new file mode 100644
index 0000000000..ce3bf3268a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkCoreService.cs
@@ -0,0 +1,43 @@
+//
+// GtkCoreService.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using MonoDevelop.Core;
+using MonoDevelop.Components.Commands;
+
+namespace MonoDevelop.GtkCore
+{
+ class GtkCoreStartupCommand: CommandHandler
+ {
+ protected override void Run()
+ {
+ ReferenceManager.Initialize ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkDesignInfo.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkDesignInfo.cs
new file mode 100644
index 0000000000..1a5d790644
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/GtkDesignInfo.cs
@@ -0,0 +1,676 @@
+//
+// GtkDesignInfo.cs
+//
+// Authors:
+// Lluis Sanchez Gual
+// Mike Kestner
+// Krzysztof Marecki
+//
+// Copyright (C) 2006-2008 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2010 Krzysztof Marecki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.CodeGeneration;
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Core.Serialization;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.GtkCore.NodeBuilders;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore
+{
+ public class GtkDesignInfo: IDisposable, Stetic.IProjectDesignInfo
+ {
+ DotNetProject project;
+ GuiBuilderProject builderProject;
+ IDotNetLanguageBinding binding;
+ ProjectResourceProvider resourceProvider;
+ ReferenceManager referenceManager;
+ string langExtension;
+
+ [ItemProperty (DefaultValue = true)]
+ bool generateGettext = true;
+
+ [ItemProperty (DefaultValue = "Mono.Unix.Catalog")]
+ string gettextClass = "Mono.Unix.Catalog";
+
+ [ItemProperty (DefaultValue = "Designer")]
+ string steticFolderName = "Designer";
+
+ [ItemProperty (DefaultValue = true)]
+ bool hideGtkxFiles = true;
+
+ GtkDesignInfo ()
+ {
+ }
+
+ GtkDesignInfo (DotNetProject project)
+ {
+ IExtendedDataItem item = (IExtendedDataItem) project;
+ item.ExtendedProperties ["GtkDesignInfo"] = this;
+ Project = project;
+ }
+
+ DotNetProject Project {
+ get { return project; }
+ set {
+ if (project == value)
+ return;
+
+ if (project != null) {
+ project.FileAddedToProject -= OnFileEvent;
+ project.FileChangedInProject -= OnFileEvent;
+ project.FileRemovedFromProject -= OnFileEvent;
+ binding = null;
+ if (referenceManager != null)
+ referenceManager.Dispose ();
+ referenceManager = null;
+ }
+ project = value;
+
+ if (project != null) {
+ binding = LanguageBindingService.GetBindingPerLanguageName (project.LanguageName) as IDotNetLanguageBinding;
+
+ CodeDomProvider provider = binding.GetCodeDomProvider ();
+ if (provider == null)
+ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
+ langExtension = "." + provider.FileExtension;
+
+ project.FileAddedToProject += OnFileEvent;
+ project.FileChangedInProject += OnFileEvent;
+ project.FileRemovedFromProject += OnFileEvent;
+ }
+ }
+ }
+
+ void OnFileEvent (object o, ProjectFileEventArgs args)
+ {
+ if (!IdeApp.Workspace.IsOpen || !File.Exists (ObjectsFile))
+ return;
+
+ UpdateObjectsFile ();
+ }
+
+ public void Dispose ()
+ {
+ if (resourceProvider != null)
+ System.Runtime.Remoting.RemotingServices.Disconnect (resourceProvider);
+ resourceProvider = null;
+ if (builderProject != null)
+ builderProject.Dispose ();
+ builderProject = null;
+ if (referenceManager != null)
+ referenceManager.Dispose ();
+ referenceManager = null;
+ Project = null;
+ }
+
+ public GuiBuilderProject GuiBuilderProject {
+ get {
+ if (builderProject == null) {
+ if (SupportsDesigner (project)) {
+ builderProject = new GuiBuilderProject (project, SteticFolder.FullPath.FullPath);
+ } else
+ builderProject = new GuiBuilderProject (project, null);
+ }
+ return builderProject;
+ }
+ }
+
+ public ReferenceManager ReferenceManager {
+ get {
+ if (referenceManager == null)
+ referenceManager = new ReferenceManager (project);
+ return referenceManager;
+ }
+ }
+
+ public void ReloadGuiBuilderProject ()
+ {
+ if (builderProject != null)
+ builderProject.Reload ();
+ }
+
+ public ProjectResourceProvider ResourceProvider {
+ get {
+ if (resourceProvider == null) {
+ resourceProvider = new ProjectResourceProvider (project);
+ System.Runtime.Remoting.RemotingServices.Marshal (resourceProvider, null, typeof(Stetic.IResourceProvider));
+ }
+ return resourceProvider;
+ }
+ }
+
+ public bool NeedsConversion {
+ get { return project.IsFileInProject (SteticFile); }
+ }
+
+ FilePath ObjectsFile {
+ get { return SteticFolder.Combine ("objects.xml"); }
+ }
+
+ [Obsolete]
+ public FilePath SteticGeneratedFile {
+ get { return SteticFolder.Combine (binding.GetFileName ("generated")); }
+ }
+
+ [Obsolete]
+ public FilePath SteticFile {
+ get { return SteticFolder.Combine ("gui.stetic"); }
+ }
+
+ public string BuildFileExtension {
+ get { return ".designer"; }
+ }
+
+ public string DesignerFileExtension {
+ get { return ".gtkx"; }
+ }
+
+ public FilePath SteticFolder {
+ get {
+ FilePath oldfolder = project.BaseDirectory.Combine ("gtk-gui");
+ if (Directory.Exists (oldfolder))
+ return oldfolder;
+
+ return project.BaseDirectory.Combine (steticFolderName);
+ }
+ }
+
+ public bool GenerateGettext {
+ get { return generateGettext; }
+ set {
+ generateGettext = value;
+ // Set to default value if gettext is not enabled
+ if (!generateGettext)
+ gettextClass = "Mono.Unix.Catalog";
+ }
+ }
+
+ public string GettextClass {
+ get { return gettextClass; }
+ set { gettextClass = value; }
+ }
+
+ public string SteticFolderName {
+ get { return steticFolderName; }
+ set { steticFolderName = value; }
+ }
+
+ public bool HideGtkxFiles {
+ get { return hideGtkxFiles; }
+ set { hideGtkxFiles = value; }
+ }
+
+ public static bool HasDesignedObjects (Project project)
+ {
+ if (project == null)
+ return false;
+
+ return SupportsDesigner (project);
+ }
+
+ public static bool SupportsDesigner (Project project)
+ {
+ DotNetProject dnp = project as DotNetProject;
+ return dnp != null && HasGtkReference (dnp) && SupportsRefactoring (dnp);
+ }
+
+ public static bool SupportsRefactoring (DotNetProject project)
+ {
+ if (project == null || project.LanguageBinding == null || project.LanguageBinding.GetCodeDomProvider () == null)
+ return false;
+ RefactorOperations ops = RefactorOperations.AddField | RefactorOperations.AddMethod | RefactorOperations.RenameField | RefactorOperations.AddAttribute;
+ CodeRefactorer cref = IdeApp.Workspace.GetCodeRefactorer (project.ParentSolution);
+ return cref.LanguageSupportsOperation (project.LanguageBinding.Language, ops);
+ }
+
+ static bool IsGtkReference (ProjectReference pref)
+ {
+ if (pref.ReferenceType != ReferenceType.Gac)
+ return false;
+
+ int idx = pref.StoredReference.IndexOf (",");
+ if (idx == -1)
+ return false;
+
+ string name = pref.StoredReference.Substring (0, idx).Trim ();
+ return name == "gtk-sharp";
+ }
+
+ static bool HasGtkReference (DotNetProject project)
+ {
+ foreach (ProjectReference pref in project.References)
+ if (IsGtkReference (pref))
+ return true;
+ return false;
+ }
+
+ public void ForceCodeGenerationOnBuild ()
+ {
+ if (!SupportsDesigner (project))
+ return;
+ try {
+ FileInfo fi = new FileInfo (SteticFile);
+ fi.LastWriteTime = DateTime.Now;
+ project.SetNeedsBuilding (true);
+ } catch {
+ // Ignore errors here
+ }
+ }
+
+ public void CheckGtkFolder ()
+ {
+ foreach (string designerFile in GetDesignerFiles ()) {
+ string componentFile = GetComponentFileFromDesigner (designerFile);
+ if (componentFile != null) {
+ string buildFile = GetBuildFileFromComponent (componentFile);
+ if (buildFile != null) {
+ // if build file is missing, force to generate it again
+ if ((project.GetProjectFile (buildFile) == null) || !File.Exists (buildFile)) {
+ FileInfo fi = new FileInfo (designerFile);
+ fi.LastWriteTime = DateTime.Now;
+ }
+ }
+ }
+ }
+ }
+
+ bool CleanGtkFolder (StringCollection remaining_files)
+ {
+ bool projectModified = false;
+ // Remove all project files which are not in the generated list
+ foreach (ProjectFile pf in project.Files.GetFilesInPath (SteticFolder)) {
+ if (remaining_files.Contains (pf.FilePath))
+ continue;
+
+ project.Files.Remove (pf);
+ FileService.DeleteFile (pf.FilePath);
+ projectModified = true;
+ }
+
+ if (remaining_files.Count == 0)
+ FileService.DeleteDirectory (SteticFolder);
+
+ return projectModified;
+ }
+
+ public void ConvertGtkFolder (string guiFolderName, bool makeBackup)
+ {
+ foreach (ProjectFile pf in project.Files.GetFilesInPath (SteticFolder)) {
+ FilePath path = pf.FilePath;
+
+ if (path != SteticGeneratedFile) {
+ project.Files.Remove (path);
+
+ if (path != SteticFile)
+ FileService.DeleteFile (path.FullPath);
+ }
+ }
+
+ string oldGuiFolder = SteticFolder.FullPath;
+ string oldSteticFile = SteticFile;
+ string oldGeneratedFile = SteticGeneratedFile;
+ SteticFolderName = guiFolderName;
+
+ if (!Directory.Exists (SteticFolder))
+ FileService.CreateDirectory (SteticFolder);
+
+ if (makeBackup && File.Exists (oldSteticFile)) {
+ string backupFile = SteticFolder.Combine ("old.stetic");
+ FileService.MoveFile (oldSteticFile, backupFile);
+ }
+
+ if (File.Exists (oldGeneratedFile))
+ FileService.DeleteFile (oldGeneratedFile);
+
+ if (Directory.Exists (oldGuiFolder))
+ FileService.DeleteDirectory (oldGuiFolder);
+ }
+
+ public bool UpdateGtkFolder ()
+ {
+ if (!SupportsDesigner (project))
+ return false;
+
+ // This method synchronizes the current gtk project configuration info
+ // with the needed support files in the gtk-gui folder.
+
+ FileService.CreateDirectory (SteticFolder);
+ bool projectModified = false;
+
+ foreach (string filename in GetDesignerFiles ()) {
+ ProjectFile pf = project.AddFile (filename, BuildAction.EmbeddedResource);
+ pf.ResourceId = Path.GetFileName (filename);
+
+ string componentFile = GetComponentFileFromDesigner (filename);
+
+ if (componentFile != null && File.Exists (componentFile)) {
+ pf.DependsOn = componentFile;
+
+ string buildFile = GetBuildFileFromComponent (componentFile);
+ if (buildFile != null && File.Exists (buildFile)) {
+ ProjectFile pf2 = project.AddFile (buildFile, BuildAction.Compile);
+ pf2.ResourceId = Path.GetFileName (buildFile);
+ pf2.DependsOn = componentFile;
+ }
+ }
+
+ projectModified = true;
+ }
+
+ StringCollection files = GuiBuilderProject.GenerateFiles (SteticFolder);
+ foreach (string filename in files) {
+ if (!project.IsFileInProject (filename)) {
+ project.AddFile (filename, BuildAction.Compile);
+ projectModified = true;
+ }
+
+ }
+
+ UpdateObjectsFile ();
+
+ return ReferenceManager.Update () || projectModified;
+ }
+
+// public bool UpdateGtkFolder ()
+// {
+// if (!SupportsDesigner (project))
+// return false;
+//
+// // This method synchronizes the current gtk project configuration info
+// // with the needed support files in the gtk-gui folder.
+//
+// FileService.CreateDirectory (GtkGuiFolder);
+// bool projectModified = false;
+// bool initialGeneration = false;
+//
+// if (!File.Exists (SteticFile)) {
+// initialGeneration = true;
+// StreamWriter sw = new StreamWriter (SteticFile);
+// sw.WriteLine ("<stetic-interface />");
+// sw.Close ();
+// FileService.NotifyFileChanged (SteticFile);
+// }
+//
+// if (!project.IsFileInProject (SteticFile)) {
+// ProjectFile pf = project.AddFile (SteticFile, BuildAction.EmbeddedResource);
+// pf.ResourceId = "gui.stetic";
+// projectModified = true;
+// }
+//
+// StringCollection files = GuiBuilderProject.GenerateFiles (GtkGuiFolder);
+// DateTime generatedTime = File.GetLastWriteTime (SteticFile).Subtract (TimeSpan.FromSeconds (2));
+//
+// foreach (string filename in files) {
+// if (initialGeneration) {
+// // Ensure that the generation date of this file is < the date of the .stetic file
+// // In this way the code will be properly regenerated when building the project.
+// File.SetLastWriteTime (filename, generatedTime);
+// }
+// if (!project.IsFileInProject (filename)) {
+// project.AddFile (filename, BuildAction.Compile);
+// projectModified = true;
+// }
+// }
+//
+// UpdateObjectsFile ();
+// files.Add (ObjectsFile);
+// files.Add (SteticFile);
+//
+// if (CleanGtkFolder (files))
+// projectModified = true;
+//
+// return ReferenceManager.Update () || projectModified;
+// return true;
+// }
+
+ public void RenameComponentFile (ProjectFile pfComponent)
+ {
+ foreach (ProjectFile pf in pfComponent.DependentChildren) {
+ if (pf.FilePath.FileName.Contains (BuildFileExtension)) {
+ FileService.RenameFile (pf.FilePath,
+ GetBuildFileNameFromComponent (pfComponent.FilePath));
+ }
+ if (pf.FilePath.FileName.Contains (DesignerFileExtension)) {
+ FileService.RenameFile (pf.FilePath,
+ GetDesignerFileNameFromComponent (pfComponent.FilePath));
+ }
+ }
+ }
+
+ public string GetComponentFile (string componentName)
+ {
+ IType type = GuiBuilderProject.FindClass (componentName);
+ if (type != null) {
+ foreach (IType part in type.Parts) {
+ string componentFile = part.CompilationUnit.FileName.FullPath;
+ if (componentFile.Contains (BuildFileExtension))
+ componentFile = componentFile.Replace (BuildFileExtension, string.Empty);
+
+ return componentFile;
+ }
+ }
+
+ //If ProjectDom does not exist, assume that project is being created
+ //and return component file path that is located in the project root folder
+ ProjectDom ctx = ProjectDomService.GetProjectDom (project);
+ if (ctx == null) {
+ string componentFile = Path.Combine (project.BaseDirectory, componentName + langExtension);
+ if (File.Exists (componentFile))
+ return componentFile;
+ }
+
+ return null;
+ }
+
+ public string GetBuildFileInSteticFolder (string componentName)
+ {
+ string name = string.Format ("{0}{1}{2}", componentName, BuildFileExtension, langExtension);
+ string buildFile = Path.Combine (SteticFolder, name);
+
+ return buildFile;
+ }
+
+ public string GetBuildFileFromComponent (string componentFile)
+ {
+ if (componentFile != null) {
+ ProjectFile pf = project.Files.GetFile (componentFile);
+ if (pf != null) {
+ foreach (var child in pf.DependentChildren) {
+ if (child.Name.Contains (BuildFileExtension))
+ return child.FilePath;
+ }
+ }
+ return GetBuildFileNameFromComponent (componentFile);
+ }
+ return null;
+ }
+
+ public string GetBuildFileNameFromComponent (string componentFile)
+ {
+ string buildFile = componentFile.Replace
+ (langExtension, BuildFileExtension + langExtension);
+ return buildFile;
+ }
+
+ public string GetDesignerFileFromComponent (string componentFile)
+ {
+ if (componentFile != null) {
+ ProjectFile pf = project.Files.GetFile (componentFile);
+ if (pf != null) {
+ foreach (var child in pf.DependentChildren) {
+ if (child.Name.Contains (DesignerFileExtension))
+ return child.FilePath;
+ }
+ }
+ return GetDesignerFileNameFromComponent (componentFile);
+ }
+ return null;
+ }
+
+ public string GetDesignerFileNameFromComponent (string componentFile)
+ {
+ string gtkxFile = componentFile.Replace (langExtension, DesignerFileExtension);
+ return gtkxFile;
+ }
+
+ public string GetComponentFileFromDesigner (string gtkxFile)
+ {
+ if (gtkxFile != null) {
+ ProjectFile pf = project.Files.GetFile (gtkxFile);
+ if (pf != null) {
+ if (pf.DependsOn != null)
+ return pf.DependsOn;
+ }
+ string componentFile = gtkxFile.Replace (DesignerFileExtension, langExtension);
+ return componentFile;
+ }
+
+ return null;
+ }
+
+// public string GetBuildFileFromDesigner (string gtkxFile)
+// {
+// string buildFile = gtkxFile.Replace (DesignerFileExtension, BuildFileExtension + langExtension);
+// return buildFile;
+// }
+
+
+ public string GetComponentFolder (string componentName)
+ {
+ IType type = GuiBuilderProject.FindClass (componentName);
+
+ if (type != null) {
+ FilePath folder = type.CompilationUnit.FileName.ParentDirectory;
+ return folder.FullPath.ToString ();
+ }
+
+ return null;
+ }
+
+ public string[] GetComponentFolders ()
+ {
+ List<string> folders = new List<string> ();
+ ProjectDom ctx = GuiBuilderProject.GetParserContext ();
+
+ if (ctx != null) {
+ foreach (IType type in ctx.Types)
+ foreach (IType part in type.Parts) {
+ FilePath folder = part.CompilationUnit.FileName.ParentDirectory;
+ string folderName = folder.FullPath.ToString ();
+
+ if (!folders.Contains (folderName))
+ folders.Add (folder);
+ }
+ }
+
+ return folders.ToArray ();
+ }
+
+ public string[] GetDesignerFiles ()
+ {
+ List<string> files = new List<string> ();
+
+ foreach (string folder in GetComponentFolders ()) {
+ DirectoryInfo dir = new DirectoryInfo (folder);
+
+ foreach (FileInfo file in dir.GetFiles ())
+ if (file.Extension == DesignerFileExtension)
+ files.Add (file.ToString ());
+ }
+
+ return files.ToArray ();
+ }
+
+ public bool HasComponentFile (string componentName)
+ {
+ return (GetComponentFile (componentName) != null);
+ }
+
+ public bool ComponentNeedsCodeGeneration (string componentName)
+ {
+ string componentFile = GetComponentFile (componentName);
+ string gtkxFile = GetDesignerFileFromComponent (componentFile);
+ string buildFile = GetBuildFileFromComponent (componentFile);
+ FileInfo gtkxFileInfo = File.Exists (gtkxFile) ? new FileInfo (gtkxFile) : null;
+ FileInfo buildFileInfo = File.Exists (buildFile) ? new FileInfo (buildFile) : null;
+ if (gtkxFileInfo == null)
+ return false;
+ //file does not exist
+ if (buildFileInfo == null)
+ return true;
+
+ return gtkxFileInfo.LastWriteTime > buildFileInfo.LastWriteTime;
+ }
+
+ void UpdateObjectsFile ()
+ {
+ if (!File.Exists (ObjectsFile))
+ return;
+
+ ObjectsDocument doc = new ObjectsDocument (ObjectsFile);
+ doc.Update (GuiBuilderProject.WidgetParser, GuiBuilderProject.SteticProject, IdeApp.Workspace.GetCodeRefactorer (project.ParentSolution));
+ }
+
+ public static void DisableProject (Project project)
+ {
+ if (HasDesignedObjects (project))
+ return;
+
+ GtkDesignInfo info = FromProject (project);
+ StringCollection saveFiles = new StringCollection ();
+ saveFiles.AddRange (new string[] {info.ObjectsFile, info.SteticFile});
+ info.CleanGtkFolder (saveFiles);
+ project.Files.Remove (info.ObjectsFile);
+ project.Files.Remove (info.SteticFile);
+ IExtendedDataItem item = (IExtendedDataItem) project;
+ item.ExtendedProperties.Remove ("GtkDesignInfo");
+ info.Dispose ();
+ ProjectNodeBuilder.OnSupportChanged (project);
+ }
+
+ public static GtkDesignInfo FromProject (Project project)
+ {
+ if (!(project is DotNetProject))
+ return new GtkDesignInfo ();
+
+ IExtendedDataItem item = (IExtendedDataItem) project;
+ GtkDesignInfo info = item.ExtendedProperties ["GtkDesignInfo"] as GtkDesignInfo;
+ if (info == null)
+ info = new GtkDesignInfo ((DotNetProject) project);
+ else
+ info.Project = (DotNetProject) project;
+ return info;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ObjectsDocument.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ObjectsDocument.cs
new file mode 100644
index 0000000000..90e7deb7be
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ObjectsDocument.cs
@@ -0,0 +1,301 @@
+//
+// ObjectsDocument.cs
+//
+// Authors:
+// Lluis Sanchez Gual
+// Mike Kestner
+//
+// Copyright (C) 2006-2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Xml;
+using System.CodeDom;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.CodeGeneration;
+
+namespace MonoDevelop.GtkCore
+{
+
+
+ public class ObjectsDocument : XmlDocument
+ {
+ string path;
+
+ public ObjectsDocument (string path) : base ()
+ {
+ this.path = path;
+ Load (path);
+ }
+
+ public StringCollection ObjectNames {
+ get {
+ StringCollection names = new StringCollection ();
+ foreach (XmlNode node in DocumentElement) {
+ if (node.Name != "object")
+ continue;
+ XmlElement elem = node as XmlElement;
+ names.Add (elem.GetAttribute ("type"));
+ }
+ return names;
+ }
+ }
+
+ enum SyncState
+ {
+ Unspecified,
+ Off,
+ On,
+ }
+
+ SyncState AttrSyncState {
+ get {
+ if (DocumentElement.HasAttribute ("attr-sync")) {
+ if (DocumentElement.GetAttribute ("attr-sync").ToLower () == "off")
+ return SyncState.Off;
+ else
+ return SyncState.On;
+ } else
+ return SyncState.Unspecified;
+ }
+ set {
+ switch (value) {
+ case SyncState.Unspecified:
+ DocumentElement.RemoveAttribute ("attr-sync");
+ break;
+ case SyncState.Off:
+ DocumentElement.SetAttribute ("attr-sync", "off");
+ break;
+ case SyncState.On:
+ DocumentElement.SetAttribute ("attr-sync", "on");
+ break;
+ default:
+ throw new ArgumentOutOfRangeException ("value");
+ }
+ Save ();
+ }
+ }
+
+ public void Save ()
+ {
+ Save (path);
+ }
+
+ void InsertToolboxItemAttributes (WidgetParser parser, CodeRefactorer cref)
+ {
+ Dictionary<string, IType> tb_items = parser.GetToolboxItems ();
+ foreach (string clsname in ObjectNames) {
+ if (tb_items.ContainsKey (clsname))
+ continue;
+
+ IType cls = parser.GetClass (clsname);
+ if (cls == null)
+ continue;
+
+ cref.AddAttribute (cls, "System.ComponentModel.ToolboxItem", true);
+ XmlElement elem = DocumentElement.SelectSingleNode ("object[@type='" + clsname + "']") as XmlElement;
+ if (elem != null && elem.HasAttribute ("palette-category"))
+ cref.AddAttribute (cls, "System.ComponentModel.Category", elem.GetAttribute ("palette-category"));
+ }
+ }
+
+ public void Update (WidgetParser parser, Stetic.Project stetic, CodeRefactorer refactorer)
+ {
+ if (AttrSyncState == SyncState.Unspecified) {
+ if (refactorer != null) {
+ InsertToolboxItemAttributes (parser, refactorer);
+ AttrSyncState = SyncState.On;
+ }
+ return;
+ } else if (AttrSyncState == SyncState.Off)
+ return;
+
+ StringCollection tb_names = new StringCollection ();
+ foreach (IType cls in parser.GetToolboxItems().Values) {
+ UpdateClass (parser, stetic, cls, null);
+ tb_names.Add (cls.FullName);
+ }
+
+ List<XmlElement> toDelete = new List<XmlElement> ();
+
+ foreach (XmlElement elem in SelectNodes ("objects/object")) {
+ string name = elem.GetAttribute ("type");
+ if (!tb_names.Contains (name))
+ toDelete.Add (elem);
+ }
+
+ foreach (XmlElement elem in toDelete)
+ elem.ParentNode.RemoveChild (elem);
+
+ Save ();
+ }
+
+ void UpdateClass (WidgetParser parser, Stetic.Project stetic, IType widgetClass, IType wrapperClass)
+ {
+ string typeName = widgetClass.FullName;
+ string basetypeName = GetBaseType (parser, widgetClass, stetic);
+ XmlElement objectElem = (XmlElement) SelectSingleNode ("objects/object[@type='" + typeName + "']");
+
+ if (objectElem == null) {
+
+ // The widget class is not yet in the XML file. Create an element for it.
+ objectElem = CreateElement ("object");
+ objectElem.SetAttribute ("type", typeName);
+ string category = parser.GetCategory (widgetClass);
+ if (category == String.Empty)
+ objectElem.SetAttribute ("palette-category", "General");
+ else
+ objectElem.SetAttribute ("palette-category", category);
+ objectElem.SetAttribute ("allow-children", "false");
+ if (wrapperClass != null)
+ objectElem.SetAttribute ("wrapper", wrapperClass.FullName);
+
+ // By default add a reference to Gtk.Widget properties and events
+ XmlElement itemGroups = objectElem.OwnerDocument.CreateElement ("itemgroups");
+ objectElem.AppendChild (itemGroups);
+
+ itemGroups = objectElem.OwnerDocument.CreateElement ("signals");
+ objectElem.AppendChild (itemGroups);
+
+ objectElem.SetAttribute ("base-type", basetypeName);
+ DocumentElement.AppendChild (objectElem);
+ }
+
+ UpdateObject (parser, basetypeName, objectElem, widgetClass, wrapperClass);
+ }
+
+ string GetBaseType (WidgetParser parser, IType widgetClass, Stetic.Project stetic)
+ {
+ string[] types = stetic.GetWidgetTypes ();
+ Hashtable typesHash = new Hashtable ();
+ foreach (string t in types)
+ typesHash [t] = t;
+
+ string ret = parser.GetBaseType (widgetClass, typesHash);
+ return ret ?? "Gtk.Widget";
+ }
+
+ void UpdateObject (WidgetParser parser, string topType, XmlElement objectElem, IType widgetClass, IType wrapperClass)
+ {
+ if (widgetClass.IsPublic)
+ objectElem.RemoveAttribute ("internal");
+ else
+ objectElem.SetAttribute ("internal", "true");
+
+ ListDictionary properties = new ListDictionary ();
+ ListDictionary events = new ListDictionary ();
+
+ parser.CollectMembers (widgetClass, true, topType, properties, events);
+ if (wrapperClass != null)
+ parser.CollectMembers (wrapperClass, false, null, properties, events);
+
+ foreach (IProperty prop in properties.Values)
+ MergeProperty (parser, objectElem, prop);
+
+ foreach (IEvent ev in events.Values)
+ MergeEvent (parser, objectElem, ev);
+
+ // Remove old properties
+ ArrayList toDelete = new ArrayList ();
+ foreach (XmlElement xprop in objectElem.SelectNodes ("itemgroups/itemgroup/property")) {
+ if (!properties.Contains (xprop.GetAttribute ("name")))
+ toDelete.Add (xprop);
+ }
+
+ // Remove old signals
+ foreach (XmlElement xevent in objectElem.SelectNodes ("signals/itemgroup/signal")) {
+ if (!events.Contains (xevent.GetAttribute ("name")))
+ toDelete.Add (xevent);
+ }
+
+ foreach (XmlElement el in toDelete) {
+ XmlElement pe = (XmlElement) el.ParentNode;
+ pe.RemoveChild (el);
+ if (pe.ChildNodes.Count == 0)
+ pe.ParentNode.RemoveChild (pe);
+ }
+ }
+
+ void MergeProperty (WidgetParser parser, XmlElement objectElem, IProperty prop)
+ {
+ XmlElement itemGroups = objectElem ["itemgroups"];
+ if (itemGroups == null) {
+ itemGroups = objectElem.OwnerDocument.CreateElement ("itemgroups");
+ objectElem.AppendChild (itemGroups);
+ }
+
+ string cat = parser.GetCategory (prop);
+ XmlElement itemGroup = GetItemGroup (prop.DeclaringType, itemGroups, cat, "Properties");
+
+ XmlElement propElem = (XmlElement) itemGroup.SelectSingleNode ("property[@name='" + prop.Name + "']");
+ if (propElem == null) {
+ propElem = itemGroup.OwnerDocument.CreateElement ("property");
+ propElem.SetAttribute ("name", prop.Name);
+ itemGroup.AppendChild (propElem);
+ }
+ }
+
+ void MergeEvent (WidgetParser parser, XmlElement objectElem, IEvent evnt)
+ {
+ XmlElement itemGroups = objectElem ["signals"];
+ if (itemGroups == null) {
+ itemGroups = objectElem.OwnerDocument.CreateElement ("signals");
+ objectElem.AppendChild (itemGroups);
+ }
+
+ string cat = parser.GetCategory (evnt);
+ XmlElement itemGroup = GetItemGroup (evnt.DeclaringType, itemGroups, cat, "Signals");
+
+ XmlElement signalElem = (XmlElement) itemGroup.SelectSingleNode ("signal[@name='" + evnt.Name + "']");
+ if (signalElem == null) {
+ signalElem = itemGroup.OwnerDocument.CreateElement ("signal");
+ signalElem.SetAttribute ("name", evnt.Name);
+ itemGroup.AppendChild (signalElem);
+ }
+ }
+
+ XmlElement GetItemGroup (IType cls, XmlElement itemGroups, string cat, string groupName)
+ {
+ XmlElement itemGroup;
+
+ if (cat != "")
+ itemGroup = (XmlElement) itemGroups.SelectSingleNode ("itemgroup[@name='" + cat + "']");
+ else
+ itemGroup = (XmlElement) itemGroups.SelectSingleNode ("itemgroup[(not(@name) or @name='') and not(@ref)]");
+
+ if (itemGroup == null) {
+ itemGroup = itemGroups.OwnerDocument.CreateElement ("itemgroup");
+ if (cat != null && cat != "") {
+ itemGroup.SetAttribute ("name", cat);
+ itemGroup.SetAttribute ("label", cat);
+ } else
+ itemGroup.SetAttribute ("label", cls.Name + " " + groupName);
+ itemGroups.AppendChild (itemGroup);
+ }
+ return itemGroup;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ProjectResourceProvider.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ProjectResourceProvider.cs
new file mode 100644
index 0000000000..e1c46517d8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ProjectResourceProvider.cs
@@ -0,0 +1,89 @@
+//
+// ProjectResourceProvider.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore
+{
+ public class ProjectResourceProvider: MarshalByRefObject, Stetic.IResourceProvider
+ {
+ Project project;
+
+ public ProjectResourceProvider (Project project)
+ {
+ this.project = project;
+ }
+
+ public Stetic.ResourceInfo[] GetResources ()
+ {
+ ArrayList list = new ArrayList ();
+ foreach (ProjectFile file in project.Files) {
+ if (file.BuildAction == BuildAction.EmbeddedResource)
+ list.Add (new Stetic.ResourceInfo (file.ResourceId, file.Name, DesktopService.GetMimeTypeForUri (file.Name)));
+ }
+ return (Stetic.ResourceInfo[]) list.ToArray (typeof(Stetic.ResourceInfo));
+ }
+
+ public Stream GetResourceStream (string resourceName)
+ {
+ foreach (ProjectFile file in project.Files) {
+ if (resourceName == file.ResourceId)
+ return File.OpenRead (file.Name);
+ }
+ return null;
+ }
+
+ public Stetic.ResourceInfo AddResource (string fileName)
+ {
+ ProjectFile file = project.AddFile (fileName, BuildAction.EmbeddedResource);
+ IdeApp.ProjectOperations.Save (project);
+ return new Stetic.ResourceInfo (file.ResourceId, fileName);
+ }
+
+ public void RemoveResource (string resourceName)
+ {
+ foreach (ProjectFile file in project.Files) {
+ if (resourceName == file.ResourceId) {
+ project.Files.Remove (file);
+ IdeApp.ProjectOperations.Save (project);
+ return;
+ }
+ }
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ return null;
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ReferenceManager.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ReferenceManager.cs
new file mode 100644
index 0000000000..920df75a88
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/ReferenceManager.cs
@@ -0,0 +1,291 @@
+// ReferenceManager.cs
+//
+// Author: Mike Kestner <mkestner@novell.com>
+//
+// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+using System;
+using System.Collections.Generic;
+
+using MonoDevelop.Core;
+using MonoDevelop.Core.Assemblies;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore {
+
+ public class ReferenceManager : IDisposable {
+
+ DotNetProject project;
+
+ public ReferenceManager (DotNetProject project)
+ {
+ this.project = project;
+ project.AssemblyContext.Changed += ResetSupportedVersions;
+ }
+
+ public void Dispose ()
+ {
+ project.AssemblyContext.Changed -= ResetSupportedVersions;
+ project = null;
+ }
+
+ void ResetSupportedVersions (object o, EventArgs a)
+ {
+ supported_versions = null;
+ }
+
+ string CurrentAssemblyVersion {
+ get {
+ foreach (ProjectReference pref in project.References) {
+ if (!IsGtkReference (pref))
+ continue;
+ string val = pref.StoredReference;
+ int idx = val.IndexOf (",") + 1;
+ return val.Substring (idx).Trim ();
+ }
+ return String.Empty;
+ }
+ }
+
+ public string GtkPackageVersion {
+ get { return GetGtkPackageVersion (CurrentAssemblyVersion); }
+ set {
+ if (String.IsNullOrEmpty (value))
+ throw new ArgumentException ("value");
+
+ Update (GetGtkAssemblyVersion (value));
+ }
+ }
+
+ public string TargetGtkVersion {
+ get {
+ string assm_version = CurrentAssemblyVersion;
+ if (String.IsNullOrEmpty (assm_version))
+ return String.Empty;
+ int idx = assm_version.IndexOf (",");
+ if (idx > 0)
+ assm_version = assm_version.Substring (0, idx);
+ idx = assm_version.IndexOf ("=");
+ if (idx > 0)
+ assm_version = assm_version.Substring (idx + 1);
+ string[] toks = assm_version.Split ('.');
+ if (toks.Length > 1)
+ return toks[0] + "." + toks[1];
+ return String.Empty;
+ }
+ }
+
+ string GetGtkAssemblyVersion (string pkg_version)
+ {
+ if (String.IsNullOrEmpty (pkg_version))
+ return String.Empty;
+
+ pkg_version = pkg_version + ".";
+ foreach (SystemAssembly asm in project.AssemblyContext.GetAssemblies ()) {
+ if (asm.Name == "gtk-sharp" && asm.Version.StartsWith (pkg_version)) {
+ int i = asm.FullName.IndexOf (',');
+ return asm.FullName.Substring (i+1).Trim ();
+ }
+ }
+ return string.Empty;
+ }
+
+ string GetGtkPackageVersion (string assembly_version)
+ {
+ if (String.IsNullOrEmpty (assembly_version))
+ return String.Empty;
+
+ return GetVersionPrefix (assembly_version);
+ }
+
+ public bool Update ()
+ {
+ return Update (CurrentAssemblyVersion);
+ }
+
+ bool Update (string assm_version)
+ {
+ if (assm_version == null)
+ throw new ArgumentException (assm_version);
+
+ bool changed = false;
+ updating = true;
+
+ bool gdk = false, gtk = false, posix = false;
+
+ foreach (ProjectReference r in new List<ProjectReference> (project.References)) {
+ if (r.ReferenceType != ReferenceType.Gac)
+ continue;
+ string name = GetReferenceName (r);
+ if (name == "gdk-sharp")
+ gdk = true;
+ if (name == "gtk-sharp")
+ gtk = true;
+ else if (name == "Mono.Posix")
+ posix = true;
+
+ // Is a gtk-sharp-2.0 assembly?
+ if (Array.IndexOf (gnome_assemblies, name) == -1)
+ continue;
+
+ string sr = r.StoredReference;
+ string version = sr.Substring (sr.IndexOf (",") + 1).Trim ();
+ if (version != assm_version) {
+ project.References.Remove (r);
+ if (name == "gnome-sharp" && assm_version == "Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f") {
+ project.References.Add (new ProjectReference (ReferenceType.Gac, name + ", Version=2.24.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"));
+ } else {
+ project.References.Add (new ProjectReference (ReferenceType.Gac, name + ", " + assm_version));
+ }
+ changed = true;
+ }
+ }
+
+ if (!gtk) {
+ project.References.Add (new ProjectReference (ReferenceType.Gac, "gtk-sharp" + ", " + assm_version));
+ changed = true;
+ }
+
+ if (!GtkDesignInfo.HasDesignedObjects (project))
+ return changed;
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ if (!gdk) {
+ project.References.Add (new ProjectReference (ReferenceType.Gac, "gdk-sharp" + ", " + assm_version));
+ changed = true;
+ }
+
+ if (!posix && info.GenerateGettext && info.GettextClass == "Mono.Unix.Catalog") {
+ // Add a reference to Mono.Posix. Use the version for the selected project's runtime version.
+ string aname = project.AssemblyContext.FindInstalledAssembly ("Mono.Posix, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756", null, project.TargetFramework);
+ aname = project.AssemblyContext.GetAssemblyNameForVersion (aname, project.TargetFramework);
+ project.References.Add (new ProjectReference (ReferenceType.Gac, aname));
+ changed = true;
+ }
+ updating = false;
+ return changed;
+ }
+
+ static bool updating;
+ static string[] gnome_assemblies = new string [] {
+ "art-sharp", "atk-sharp", "gconf-sharp", "gdk-sharp",
+ "glade-sharp","glib-sharp", "gnome-sharp",
+ "gnome-vfs-sharp", "gtk-dotnet", "gtkhtml-sharp",
+ "gtk-sharp", "pango-sharp", "rsvg-sharp"
+ };
+
+ public static void Initialize ()
+ {
+ IdeApp.Workspace.ReferenceAddedToProject += OnReferenceAdded;
+ IdeApp.Workspace.ReferenceRemovedFromProject += OnReferenceRemoved;
+ }
+
+ static void OnReferenceAdded (object o, ProjectReferenceEventArgs args)
+ {
+ if (updating || !IsGtkReference (args.ProjectReference))
+ return;
+
+ string sr = args.ProjectReference.StoredReference;
+ string version = sr.Substring (sr.IndexOf (",") + 1).Trim ();
+ ReferenceManager rm = new ReferenceManager (args.Project as DotNetProject);
+ rm.Update (version);
+ }
+
+ static void OnReferenceRemoved (object o, ProjectReferenceEventArgs args)
+ {
+ if (updating || !IsGtkReference (args.ProjectReference))
+ return;
+
+ DotNetProject dnp = args.Project as DotNetProject;
+
+ if (MessageService.Confirm (GettextCatalog.GetString ("The Gtk# User Interface designer will be disabled by removing the gtk-sharp reference."), new AlertButton (GettextCatalog.GetString ("Disable Designer"))))
+ GtkDesignInfo.DisableProject (dnp);
+ else
+ dnp.References.Add (new ProjectReference (ReferenceType.Gac, args.ProjectReference.StoredReference));
+ }
+
+ static string GetReferenceName (ProjectReference pref)
+ {
+ string stored = pref.StoredReference;
+ int idx =stored.IndexOf (",");
+ if (idx == -1)
+ return stored.Trim ();
+
+ return stored.Substring (0, idx).Trim ();
+ }
+
+ static bool IsGtkReference (ProjectReference pref)
+ {
+ if (pref.ReferenceType != ReferenceType.Gac)
+ return false;
+
+ return GetReferenceName (pref) == "gtk-sharp";
+ }
+
+ public static bool HasGtkReference (DotNetProject project)
+ {
+ foreach (ProjectReference pref in project.References)
+ if (IsGtkReference (pref))
+ return true;
+ return false;
+ }
+
+ List<string> supported_versions;
+ string default_version;
+
+ public string DefaultGtkVersion {
+ get {
+ if (SupportedGtkVersions.Count > 0 && default_version == null)
+ default_version = SupportedGtkVersions [0];
+ return default_version;
+ }
+ }
+
+ public List<string> SupportedGtkVersions {
+ get {
+ if (supported_versions == null) {
+ supported_versions = new List<string> ();
+ foreach (SystemAssembly asm in project.AssemblyContext.GetAssemblies ()) {
+ if (asm.Name == "gtk-sharp") {
+ string v = GetVersionPrefix (asm.Version);
+ if (!supported_versions.Contains (v))
+ supported_versions.Add (v);
+ if (v == "2.8")
+ default_version = v;
+ }
+ }
+ supported_versions.Sort ();
+ }
+ return supported_versions;
+ }
+ }
+
+ string GetVersionPrefix (string version)
+ {
+ int i = version.IndexOf ('.');
+ i = version.IndexOf ('.', i + 1);
+ return version.Substring (0, i);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs
new file mode 100644
index 0000000000..abb9198654
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs
@@ -0,0 +1,172 @@
+//
+// WidgetFileDescriptionTemplate.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Xml;
+using System.IO;
+
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Ide.Templates;
+using MonoDevelop.GtkCore.GuiBuilder;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.GtkCore
+{
+ public class WidgetFileDescriptionTemplate: FileDescriptionTemplate
+ {
+ SingleFileDescriptionTemplate fileTemplate;
+ XmlElement steticTemplate;
+
+ public override string Name {
+ get { return "Widget"; }
+ }
+#if TRUNK
+ public override void Load (XmlElement filenode, FilePath baseDirectory)
+ {
+ foreach (XmlNode node in filenode.ChildNodes) {
+ XmlElement elem = node as XmlElement;
+ if (elem == null) continue;
+
+ if (elem.Name == "SteticTemplate") {
+ if (steticTemplate != null)
+ throw new InvalidOperationException ("Widget templates can't contain more than one SteticTemplate element");
+ steticTemplate = elem;
+ } else if (fileTemplate == null) {
+ fileTemplate = FileDescriptionTemplate.CreateTemplate (elem, baseDirectory) as SingleFileDescriptionTemplate;
+ if (fileTemplate == null)
+ throw new InvalidOperationException ("Widget templates can only contain single-file and stetic templates.");
+ }
+ }
+ if (fileTemplate == null)
+ throw new InvalidOperationException ("File template not found in widget template.");
+ if (steticTemplate == null)
+ throw new InvalidOperationException ("Stetic template not found in widget template.");
+ }
+#else
+ public override void Load (XmlElement filenode)
+ {
+ foreach (XmlNode node in filenode.ChildNodes) {
+ XmlElement elem = node as XmlElement;
+ if (elem == null) continue;
+
+ if (elem.Name == "SteticTemplate") {
+ if (steticTemplate != null)
+ throw new InvalidOperationException ("Widget templates can't contain more than one SteticTemplate element");
+ steticTemplate = elem;
+ } else if (fileTemplate == null) {
+ fileTemplate = FileDescriptionTemplate.CreateTemplate (elem) as SingleFileDescriptionTemplate;
+ if (fileTemplate == null)
+ throw new InvalidOperationException ("Widget templates can only contain single-file and stetic templates.");
+ }
+ }
+ if (fileTemplate == null)
+ throw new InvalidOperationException ("File template not found in widget template.");
+ if (steticTemplate == null)
+ throw new InvalidOperationException ("Stetic template not found in widget template.");
+ }
+#endif
+
+ public override bool SupportsProject (Project project, string projectPath)
+ {
+ return (project is DotNetProject) && GtkDesignInfo.SupportsRefactoring (project as DotNetProject);
+ }
+
+ public override bool AddToProject (SolutionItem policyParent, Project project, string language, string directory, string name)
+ {
+ if (!GtkDesignInfo.SupportsDesigner (project)) {
+ ReferenceManager mgr = new ReferenceManager (project as DotNetProject);
+ mgr.GtkPackageVersion = mgr.DefaultGtkVersion;
+ mgr.Dispose ();
+ }
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject ((DotNetProject) project);
+
+ GuiBuilderProject gproject = info.GuiBuilderProject;
+
+ string fileName = fileTemplate.GetFileName (policyParent, project, language, directory, name);
+ fileTemplate.AddToProject (policyParent, project, language, directory, name);
+
+#if TRUNK
+ ProjectDomService.Parse (project, fileName);
+#else
+ ProjectDomService.Parse (project, fileName, null);
+#endif
+
+ DotNetProject netProject = project as DotNetProject;
+ string ns = netProject != null ? netProject.GetDefaultNamespace (fileName) : "";
+ string cname = Path.GetFileNameWithoutExtension (fileName);
+ string fullName = ns.Length > 0 ? ns + "." + cname : cname;
+ string[,] tags = {
+ {"Name", cname},
+ {"Namespace", ns},
+ {"FullName", fullName}
+ };
+
+ XmlElement widgetElem = steticTemplate ["widget"];
+ if (widgetElem != null) {
+ string content = widgetElem.OuterXml;
+ content = StringParserService.Parse (content, tags);
+
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml (content);
+
+ gproject.AddNewComponent (doc.DocumentElement);
+ gproject.Save (false);
+ gproject.GenerateCode (fileName);
+ IdeApp.ProjectOperations.Save (project);
+ return true;
+ }
+
+ widgetElem = steticTemplate ["action-group"];
+ if (widgetElem != null) {
+ string content = widgetElem.OuterXml;
+ content = StringParserService.Parse (content, tags);
+
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml (content);
+
+ Stetic.Project sproject = gproject.SteticProject;
+ sproject.AddNewActionGroup (doc.DocumentElement);
+ gproject.Save (false);
+ gproject.GenerateCode (fileName);
+ IdeApp.ProjectOperations.Save (project);
+ return true;
+ }
+
+ throw new InvalidOperationException ("<widget> or <action-group> element not found in widget template.");
+ }
+
+ public override void Show ()
+ {
+ fileTemplate.Show ();
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetParser.cs b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetParser.cs
new file mode 100644
index 0000000000..c846970e5e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore/WidgetParser.cs
@@ -0,0 +1,226 @@
+//
+// ObjectsDocument.cs
+//
+// Authors:
+// Lluis Sanchez Gual
+// Mike Kestner
+//
+// Copyright (C) 2006-2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Xml;
+using System.CodeDom;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+using MonoDevelop.Projects.Dom;
+using MonoDevelop.Projects.Dom.Parser;
+
+namespace MonoDevelop.GtkCore
+{
+
+ public class WidgetParser
+ {
+
+ ProjectDom ctx;
+
+ public WidgetParser (ProjectDom ctx)
+ {
+ this.ctx = ctx;
+ }
+
+ public Dictionary<string, IType> GetToolboxItems ()
+ {
+ Dictionary<string, IType> tb_items = new Dictionary<string, IType> ();
+
+ IType wt = ctx.GetType ("Gtk.Widget", true);
+ if (wt != null) {
+ foreach (IType t in ctx.GetSubclasses (wt, true)) {
+ if (t.SourceProjectDom == ctx && IsToolboxWidget (t))
+ tb_items [t.FullName] = t;
+ }
+ }
+
+ return tb_items;
+ }
+
+ public void CollectMembers (IType cls, bool inherited, string topType, ListDictionary properties, ListDictionary events)
+ {
+ if (cls.FullName == topType)
+ return;
+
+ foreach (IProperty prop in cls.Properties)
+ if (IsBrowsable (prop))
+ properties [prop.Name] = prop;
+
+ foreach (IEvent ev in cls.Events)
+ if (IsBrowsable (ev))
+ events [ev.Name] = ev;
+
+ if (inherited) {
+ foreach (IReturnType bt in cls.BaseTypes) {
+ IType bcls = ctx.GetType (bt);
+ if (bcls != null && bcls.ClassType != ClassType.Interface)
+ CollectMembers (bcls, true, topType, properties, events);
+ }
+ }
+ }
+
+ public string GetBaseType (IType cls, Hashtable knownTypes)
+ {
+ foreach (IReturnType bt in cls.BaseTypes) {
+ if (knownTypes.Contains (bt.FullName))
+ return bt.FullName;
+ }
+
+ foreach (IReturnType bt in cls.BaseTypes) {
+ IType bcls = ctx.GetType (bt);
+ if (bcls != null) {
+ string ret = GetBaseType (bcls, knownTypes);
+ if (ret != null)
+ return ret;
+ }
+ }
+ return null;
+ }
+
+ public string GetCategory (IMember decoration)
+ {
+// foreach (IAttributeSection section in decoration.Attributes) {
+ foreach (IAttribute at in decoration.Attributes) {
+ switch (at.Name) {
+ case "Category":
+ case "CategoryAttribute":
+ case "System.ComponentModel.Category":
+ case "System.ComponentModel.CategoryAttribute":
+ break;
+ default:
+ continue;
+ }
+ if (at.PositionalArguments != null && at.PositionalArguments.Count > 0) {
+ CodePrimitiveExpression exp = at.PositionalArguments [0] as CodePrimitiveExpression;
+ if (exp != null && exp.Value != null)
+ return exp.Value.ToString ();
+ }
+ }
+ // }
+ return "";
+ }
+
+ public IType GetClass (string classname)
+ {
+ return ctx.GetType (classname);
+ }
+
+ public bool IsBrowsable (IMember member)
+ {
+ if (!member.IsPublic)
+ return false;
+
+ IProperty prop = member as IProperty;
+ if (prop != null) {
+ if (!prop.HasGet || !prop.HasSet)
+ return false;
+ if (Array.IndexOf (supported_types, prop.ReturnType.FullName) == -1)
+ return false;
+ }
+
+ // foreach (IAttributeSection section in member.Attributes) {
+ foreach (IAttribute at in member.Attributes) {
+ switch (at.Name) {
+ case "Browsable":
+ case "BrowsableAttribute":
+ case "System.ComponentModel.Browsable":
+ case "System.ComponentModel.BrowsableAttribute":
+ break;
+ default:
+ continue;
+ }
+ if (at.PositionalArguments != null && at.PositionalArguments.Count > 0) {
+ CodePrimitiveExpression exp = at.PositionalArguments [0] as CodePrimitiveExpression;
+ if (exp != null && exp.Value != null && exp.Value is bool) {
+ return (bool) exp.Value;
+ }
+ }
+ }
+ // }
+ return true;
+ }
+
+ public bool IsToolboxWidget (IType cls)
+ {
+ if (!cls.IsPublic)
+ return false;
+
+ foreach (IAttribute at in cls.Attributes) {
+ switch (at.Name) {
+ case "ToolboxItem":
+ case "ToolboxItemAttribute":
+ case "System.ComponentModel.ToolboxItem":
+ case "System.ComponentModel.ToolboxItemAttribute":
+ break;
+ default:
+ continue;
+ }
+ if (at.PositionalArguments != null && at.PositionalArguments.Count > 0) {
+ CodePrimitiveExpression exp = at.PositionalArguments [0] as CodePrimitiveExpression;
+ if (exp == null || exp.Value == null)
+ return false;
+ else if (exp.Value is bool)
+ return (bool) exp.Value;
+ else
+ return exp.Value != null;
+ }
+ }
+
+ foreach (IReturnType bt in cls.BaseTypes) {
+ IType bcls = ctx.GetType (bt);
+ if (bcls != null && bcls.ClassType != ClassType.Interface)
+ return IsToolboxWidget (bcls);
+ }
+
+ return false;
+ }
+
+ static string[] supported_types = new string[] {
+ "System.Boolean",
+ "System.Char",
+ "System.SByte",
+ "System.Byte",
+ "System.Int16",
+ "System.UInt16",
+ "System.Int32",
+ "System.UInt32",
+ "System.Int64",
+ "System.UInt64",
+ "System.Decimal",
+ "System.Single",
+ "System.Double",
+ "System.DateTime",
+ "System.String",
+ "System.TimeSpan",
+ "Gtk.Adjustment",
+ };
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.addin.xml b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.addin.xml
new file mode 100644
index 0000000000..ffd642436f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.addin.xml
@@ -0,0 +1,210 @@
+<Addin id = "GtkCore2"
+ namespace = "MonoDevelop"
+ name = "GTK# Visual Designer (GSOC)"
+ author = "Lluis Sanchez Gual, Krzysztof Marecki"
+ copyright = "X11"
+ url = ""
+ description = "Experimental GTK# visual designer developed during GSOC 2010 as a fork of stetic"
+ category = "IDE extensions"
+ version = "2.4.0.5">
+
+ <Runtime>
+ <Import assembly="libstetic2.dll"/>
+ <Import file="libstetic2.dll.config"/>
+ <Import assembly="libsteticui2.dll"/>
+ <Import file="libsteticui2.dll.config"/>
+ <Import assembly="MonoDevelop.GtkCore2.dll"/>
+ </Runtime>
+
+ <Dependencies>
+ <Addin id="Core" version="2.4"/>
+ <Addin id="Ide" version="2.4"/>
+ <Addin id="DesignerSupport" version="2.4"/>
+ <Addin id="XmlEditor" version="2.4"/>
+ <Addin id="Refactoring" version="2.4"/>
+ </Dependencies>
+
+ <ExtensionPoint path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.ActionGroup">
+ <ExtensionNodeSet id="MonoDevelop.Components.Commands.ItemSet"/>
+ </ExtensionPoint>
+
+ <ExtensionPoint path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.UserInterfaceFolder">
+ <ExtensionNodeSet id="MonoDevelop.Components.Commands.ItemSet"/>
+ </ExtensionPoint>
+
+ <ExtensionPoint path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.Component">
+ <ExtensionNodeSet id="MonoDevelop.Components.Commands.ItemSet"/>
+ </ExtensionPoint>
+
+ <ExtensionPoint path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.StockIcons">
+ <ExtensionNodeSet id="MonoDevelop.Components.Commands.ItemSet"/>
+ </ExtensionPoint>
+
+ <Extension path = "/MonoDevelop/Ide/WorkbenchContexts/Edit">
+ <ContextPad id = "MonoDevelop.GtkCore.GuiBuilder.GuiBuilderProjectPad" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/Pads/ProjectPad">
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.GuiProjectFolderNodeBuilder"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectFolderNodeBuilderExtension"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectFileNodeBuilderExtension"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectNodeBuilder"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.StockIconsNodeBuilder"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectFileNodeBuilderExtension" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/FileTemplates">
+ <FileTemplate id = "DialogFileTemplate" resource = "Dialog.xft.xml"/>
+ <FileTemplate id = "DrawingAreaFileTemplate" resource = "DrawingArea.xft.xml"/>
+ <FileTemplate id = "WindowFileTemplate" resource = "Window.xft.xml"/>
+ <FileTemplate id = "WidgetFileTemplate" resource = "Widget.xft.xml"/>
+ <FileTemplate id = "ActionGroupFileTemplate" resource = "ActionGroup.xft.xml"/>
+ <FileTemplate id = "PartialDialogFileTemplate" resource = "DialogPartial.xft.xml"/>
+ <FileTemplate id = "PartialWindowFileTemplate" resource = "WindowPartial.xft.xml"/>
+ <FileTemplate id = "PartialWidgetFileTemplate" resource = "WidgetPartial.xft.xml"/>
+ <FileTemplate id = "PartialActionGroupFileTemplate" resource = "ActionGroupPartial.xft.xml"/>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/DisplayBindings">
+ <DisplayBinding insertbefore = "DefaultDisplayBinding"
+ class = "MonoDevelop.GtkCore.GuiBuilder.GuiBuilderDisplayBinding" />
+ <DisplayBinding
+ class = "MonoDevelop.GtkCore.GuiBuilder.ActionGroupDisplayBinding" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/Commands">
+ <Category _name = "Gtk# Designer" id = "GtkCore">
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.AddNewDialog"
+ icon = "md-gtkcore-dialog"
+ _label = "New Dialog..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.AddNewWindow"
+ icon = "md-gtkcore-window"
+ _label = "New Window..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.AddNewWidget"
+ icon = "md-gtkcore-widget"
+ _label = "New Widget..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup"
+ icon = "md-gtkcore-actiongroup"
+ _label = "New Action Group..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.ImportGladeFile"
+ _label = "Import Glade file..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.EditIcons"
+ icon = "md-gtkcore-iconfactory"
+ _label = "Edit Project Icons..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.GtkSettings"
+ _label = "GTK# support settings..."
+ icon = "md-gtkcore-gtk-logo"/>
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.GenerateCode"
+ _label = "Generate designer code..."
+ icon="md-gtkcore-gtkx"/>
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.ReloadDesigner"
+ _label = "Reload designer..."/>
+ </Category>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/ContextMenu/ProjectPad/Add">
+ <Condition id="ItemType" value="Project|ProjectFolder">
+ <SeparatorItem insertafter = "MonoDevelop.Ide.Commands.ProjectCommands.AddFiles" />
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewDialog" />
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewWindow" />
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewWidget" />
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup" />
+ </Condition>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/ContextMenu/ProjectPad">
+ <Condition id="ItemType" value="MonoDevelop.GtkCore.NodeBuilders.GuiProjectFolder">
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.EditIcons" insertafter="BuildSectionEnd"/>
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.ImportGladeFile" />
+ <SeparatorItem/>
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.GtkSettings" />
+ </Condition>
+ <Condition id="ItemType" value="ProjectFile">
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.GenerateCode" insertafter="BuildSectionEnd"/>
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.ReloadDesigner"/>
+ </Condition>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.Component">
+ <CommandItem id = "MonoDevelop.Ide.Commands.ViewCommands.Open" />
+ <CommandItem id = "MonoDevelop.Ide.Commands.EditCommands.Delete" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.ActionGroup">
+ <CommandItem id = "MonoDevelop.Ide.Commands.ViewCommands.Open" />
+ <CommandItem id = "MonoDevelop.Ide.Commands.EditCommands.Delete" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.StockIcons">
+ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.EditIcons" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/ProjectModel/ExtendedProperties">
+ <ItemProperty class = "MonoDevelop.Projects.Project"
+ name = "GtkDesignInfo"
+ skipEmpty = "True"
+ type = "MonoDevelop.GtkCore.GtkDesignInfo" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/StartupHandlers">
+ <Class class="MonoDevelop.GtkCore.GtkCoreStartupCommand" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/ProjectModel/Gui/ItemOptionPanels/Common">
+ <Condition id="ItemType" value ="DotNetProject">
+ <Section id = "SteticOptionsPanel"
+ _label = "GTK# Settings"
+ fill="true"
+ class = "MonoDevelop.GtkCore.Dialogs.WidgetBuilderOptionPanel"
+ icon = "md-gtkcore-gtk-logo"/>
+ </Condition>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/FileTemplateTypes">
+ <FileTemplateType name = "Widget" class = "MonoDevelop.GtkCore.WidgetFileDescriptionTemplate"/>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Core/StockIcons">
+ <StockIcon stockid = "md-gtkcore-window" resource = "window.png" />
+ <StockIcon stockid = "md-gtkcore-dialog" resource = "dialog.png" />
+ <StockIcon stockid = "md-gtkcore-widget" resource = "widget.png" />
+ <StockIcon stockid = "md-gtkcore-actiongroup" resource = "actiongroup.png" />
+ <StockIcon stockid = "md-gtkcore-iconfactory" resource = "image-x-generic.png" />
+ <StockIcon stockid = "md-gtkcore-gtkx" resource = "gtkx.png" />
+ <StockIcon stockid = "md-gtkcore-gtk-logo" resource = "gtk-logo.png"/>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Core/MimeTypes">
+ <MimeType id="text/x-gtkx" _description="Gtk# designer file" icon="gtk-page-setup" isText="true">
+ <File pattern="*.gtkx" />
+ </MimeType>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/ProjectModel/ProjectServiceExtensions">
+ <Class class = "MonoDevelop.GtkCore.GuiBuilder.GtkProjectServiceExtension" insertafter="MidStep"/>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/DesignerSupport/ToolboxProviders">
+ <Class class = "MonoDevelop.GtkCore.GuiBuilder.ToolboxProvider" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/DesignerSupport/ToolboxLoaders">
+ <Class id="ToolboxItemLoader" class="MonoDevelop.GtkCore.GuiBuilder.ToolboxLoader"/>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/ProjectModel/SerializableClasses">
+ <DataType class = "MonoDevelop.GtkCore.GuiBuilder.ComponentToolboxNode" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/ProjectFeatures">
+ <Class class = "MonoDevelop.GtkCore.Dialogs.GtkProjectFeature" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/GlobalOptionsDialog/Preferences/Style">
+ <Panel _label = "GTK# Designer" class = "MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionPanel" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/XmlEditor/XmlFileExtensions">
+ <XmlFileExtension extension = ".gtkx"/>
+ </Extension>
+</Addin>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.csproj b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.csproj
new file mode 100644
index 0000000000..94bba9eb12
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.csproj
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4F2E994F-E4F5-407A-8D80-80E3377DEF6E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AssemblyName>MonoDevelop.GtkCore2</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <RootNamespace>MonoDevelop.GtkCore</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\..\build\AddIns\MonoDevelop.GtkCore2</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <DefineConstants>TRUNK</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\..\build\AddIns\MonoDevelop.GtkCore2 </OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <DefineConstants>TRUNK</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Mono.Posix" />
+ <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System.Core" />
+ <Reference Include="NRefactory, Version=2.1.1.0, Culture=neutral, PublicKeyToken=efe927acf176eea2">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.Addins, Version=0.5.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
+ <Reference Include="Mono.Cecil, Version=0.6.9.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.Debugging, Version=0.0.0.0, Culture=neutral, PublicKeyToken=9307d64546e0580d">
+ <Package>monodevelop</Package>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="libsteticui\libsteticui2.csproj">
+ <Project>{8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}</Project>
+ <Name>libsteticui2</Name>
+ </ProjectReference>
+ <ProjectReference Include="libstetic\libstetic2.csproj">
+ <Project>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</Project>
+ <Name>libstetic2</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj">
+ <Project>{7525BB88-6142-4A26-93B9-A30C6983390A}</Project>
+ <Name>MonoDevelop.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Deployment\MonoDevelop.Deployment\MonoDevelop.Deployment.csproj">
+ <Project>{9BC670A8-1851-40EC-9685-279F4C98433D}</Project>
+ <Name>MonoDevelop.Deployment</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MonoDevelop.DesignerSupport\MonoDevelop.DesignerSupport.csproj">
+ <Project>{2C24D515-4A2C-445C-8419-C09231913CFA}</Project>
+ <Name>MonoDevelop.DesignerSupport</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\core\MonoDevelop.Ide\MonoDevelop.Ide.csproj">
+ <Project>{27096E7F-C91C-4AC6-B289-6897A701DF21}</Project>
+ <Name>MonoDevelop.Ide</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\core\Mono.Texteditor\Mono.TextEditor.csproj">
+ <Project>{A2329308-3751-4DBD-9A75-5F7B8B024625}</Project>
+ <Name>Mono.TextEditor</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ChangeLog" />
+ <None Include="Makefile.am" />
+ <None Include="icons\window.png" />
+ <None Include="icons\dialog.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="templates\Dialog.xft.xml">
+ <LogicalName>Dialog.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\Window.xft.xml">
+ <LogicalName>Window.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\Widget.xft.xml">
+ <LogicalName>Widget.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\ActionGroup.xft.xml">
+ <LogicalName>ActionGroup.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="gui.glade">
+ <LogicalName>gui.glade</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\ActionGroupPartial.xft.xml">
+ <LogicalName>ActionGroupPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\DialogPartial.xft.xml">
+ <LogicalName>DialogPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\WidgetPartial.xft.xml">
+ <LogicalName>WidgetPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\DrawingArea.xft.xml">
+ <LogicalName>DrawingArea.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\WindowPartial.xft.xml">
+ <LogicalName>WindowPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\widget.png">
+ <LogicalName>widget.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\actiongroup.png">
+ <LogicalName>actiongroup.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\image-x-generic.png">
+ <LogicalName>image-x-generic.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="gtk-gui\gui.stetic">
+ <LogicalName>gui.stetic</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\gtkx.png">
+ <LogicalName>gtkx.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\gtk-logo.png">
+ <LogicalName>gtk-logo.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="MonoDevelop.GtkCore2.addin.xml">
+ <LogicalName>MonoDevelop.GtkCore.addin.xml</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ClassUtils.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderDisplayBinding.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderProject.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderDocumentOutline.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\PropertiesWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderService.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderWindow.cs" />
+ <Compile Include="MonoDevelop.GtkCore\GtkDesignInfo.cs" />
+ <Compile Include="MonoDevelop.GtkCore\GtkCoreService.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\WidgetBuilderOptionPanel.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFolderNodeBuilderExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore\WidgetFileDescriptionTemplate.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\SelectRenamedClassDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\BindDesignDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\ConfirmWindowDeleteDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ProjectResourceProvider.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ActionGroupView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ActionGroupDisplayBinding.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\CombinedDesignView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\CodeBinder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GtkProjectServiceExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ToolboxProvider.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\StockIconsNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\GtkFeatureWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ToolboxLoader.cs" />
+ <Compile Include="gtk-gui\generated.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ObjectsDocument.cs" />
+ <Compile Include="MonoDevelop.GtkCore\WidgetParser.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ReferenceManager.cs" />
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\GtkDesignerOptionsPanelWidget.cs" />
+ <Compile Include="gtk-gui\MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore\Counters.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFileNodeBuilderExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFileExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\ProjectConversionDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\GuiProjectFolder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\GuiProjectFolderNodeBuilder.cs" />
+ <Compile Include="gtk-gui\MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Commands\GtkCommands.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Mono.Addins.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../../../">
+ <BuildFilesVar Sync="true" Name="FILES" />
+ <DeployFilesVar />
+ <ResourcesVar Sync="true" Name="RES" />
+ <OthersVar />
+ <GacRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <AsmRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <ProjectRefVar Sync="true" Name="DEPS" />
+ </MonoDevelop.Autotools.MakefileInfo>
+ </Properties>
+ </MonoDevelop>
+ </ProjectExtensions>
+</Project>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.sln b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.sln
new file mode 100644
index 0000000000..3f7850226d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.sln
@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libstetic2", "libstetic\libstetic2.csproj", "{90CBA7FD-CB46-4711-97BB-2420DC01F016}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libsteticui2", "libsteticui\libsteticui2.csproj", "{8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.GtkCore2.xbuild", "MonoDevelop.GtkCore2.xbuild.csproj", "{4F2E994F-E4F5-407A-8D80-80E3377DEF6E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = MonoDevelop.GtkCore2.xbuild.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.xbuild.csproj b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.xbuild.csproj
new file mode 100644
index 0000000000..761692829f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.xbuild.csproj
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4F2E994F-E4F5-407A-8D80-80E3377DEF6E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AssemblyName>MonoDevelop.GtkCore2</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <RootNamespace>MonoDevelop.GtkCore</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>build\debug\</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>build\release\ </OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <DefineConstants>TRUNK</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Mono.Posix" />
+ <Reference Include="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System.Core" />
+ <Reference Include="MonoDevelop.Core, Version=2.4.0.0, Culture=neutral">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="MonoDevelop.Ide, Version=2.4.0.0, Culture=neutral">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.TextEditor, Version=1.0.0.0, Culture=neutral">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.Cecil, Version=0.6.9.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="NRefactory, Version=2.1.1.0, Culture=neutral, PublicKeyToken=efe927acf176eea2">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.Debugging, Version=0.0.0.0, Culture=neutral, PublicKeyToken=9307d64546e0580d">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="MonoDevelop.Deployment, Version=2.4.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\build\AddIns\MonoDevelop.Deployment\MonoDevelop.Deployment.dll</HintPath>
+ </Reference>
+ <Reference Include="MonoDevelop.DesignerSupport, Version=2.4.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\build\AddIns\MonoDevelop.DesignerSupport\MonoDevelop.DesignerSupport.dll</HintPath>
+ </Reference>
+ <Reference Include="Mono.TextEditor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\build\bin\Mono.TextEditor.dll</HintPath>
+ </Reference>
+ <Reference Include="MonoDevelop.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\build\bin\MonoDevelop.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="MonoDevelop.Ide, Version=2.4.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\build\bin\MonoDevelop.Ide.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="libsteticui\libsteticui2.csproj">
+ <Project>{8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}</Project>
+ <Name>libsteticui2</Name>
+ </ProjectReference>
+ <ProjectReference Include="libstetic\libstetic2.csproj">
+ <Project>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</Project>
+ <Name>libstetic2</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ChangeLog" />
+ <None Include="Makefile.am" />
+ <None Include="icons\window.png" />
+ <None Include="icons\dialog.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="templates\Dialog.xft.xml">
+ <LogicalName>Dialog.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\Window.xft.xml">
+ <LogicalName>Window.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\Widget.xft.xml">
+ <LogicalName>Widget.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\ActionGroup.xft.xml">
+ <LogicalName>ActionGroup.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="gui.glade">
+ <LogicalName>gui.glade</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\ActionGroupPartial.xft.xml">
+ <LogicalName>ActionGroupPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\DialogPartial.xft.xml">
+ <LogicalName>DialogPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\WidgetPartial.xft.xml">
+ <LogicalName>WidgetPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\DrawingArea.xft.xml">
+ <LogicalName>DrawingArea.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="templates\WindowPartial.xft.xml">
+ <LogicalName>WindowPartial.xft.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\widget.png">
+ <LogicalName>widget.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\actiongroup.png">
+ <LogicalName>actiongroup.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\image-x-generic.png">
+ <LogicalName>image-x-generic.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="gtk-gui\gui.stetic">
+ <LogicalName>gui.stetic</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\gtkx.png">
+ <LogicalName>gtkx.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="icons\gtk-logo.png">
+ <LogicalName>gtk-logo.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="MonoDevelop.GtkCore2.addin.xml">
+ <LogicalName>MonoDevelop.GtkCore.addin.xml</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="MonoDevelop.GtkCore.Commands\GladeCommands.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ClassUtils.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderDisplayBinding.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderProject.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderDocumentOutline.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\PropertiesWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderService.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GuiBuilderWindow.cs" />
+ <Compile Include="MonoDevelop.GtkCore\GtkDesignInfo.cs" />
+ <Compile Include="MonoDevelop.GtkCore\GtkCoreService.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\WidgetBuilderOptionPanel.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFolderNodeBuilderExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore\WidgetFileDescriptionTemplate.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\SelectRenamedClassDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\BindDesignDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\ConfirmWindowDeleteDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ProjectResourceProvider.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ActionGroupView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ActionGroupDisplayBinding.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\CombinedDesignView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\CodeBinder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\GtkProjectServiceExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ToolboxProvider.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\StockIconsNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\GtkFeatureWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ToolboxLoader.cs" />
+ <Compile Include="gtk-gui\generated.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ObjectsDocument.cs" />
+ <Compile Include="MonoDevelop.GtkCore\WidgetParser.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ReferenceManager.cs" />
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\GtkDesignerOptionsPanelWidget.cs" />
+ <Compile Include="gtk-gui\MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore\Counters.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFileNodeBuilderExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFileExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\ProjectConversionDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\GuiProjectFolder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\GuiProjectFolderNodeBuilder.cs" />
+ <Compile Include="gtk-gui\MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../../../">
+ <BuildFilesVar Sync="true" Name="FILES" />
+ <DeployFilesVar />
+ <ResourcesVar Sync="true" Name="RES" />
+ <OthersVar />
+ <GacRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <AsmRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <ProjectRefVar Sync="true" Name="DEPS" />
+ </MonoDevelop.Autotools.MakefileInfo>
+ </Properties>
+ </MonoDevelop>
+ </ProjectExtensions>
+</Project>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/README b/main/src/addins/MonoDevelop.GtkCore2/README
new file mode 100644
index 0000000000..3c12c0b5ec
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/README
@@ -0,0 +1,14 @@
+To build and test experimental GTK# visual designer :
+- checkout and build MonoDevelop trunk
+- copy entire MonoDevelop.GtkCore2 folder into monodevelop-trunk/main/src/
+- create monodevelop-slim folder in the monodevelop-trunk,
+- copy monodevelop-slim.sln into monodevelop-trunk/monodevelop-slim
+- open solution in MonoDevelop
+- build and run
+
+Remarks :
+ - monodevelop-trunk is the name of folder where MonoDevelop was checkouted
+ - old stetic designer should be disabled
+
+
+Krzysztof Marecki <marecki.krzysztof@gmail.com>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/addin-project.xml b/main/src/addins/MonoDevelop.GtkCore2/addin-project.xml
new file mode 100644
index 0000000000..8b3e1e4863
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/addin-project.xml
@@ -0,0 +1,7 @@
+<AddinProject appVersion="2.4">
+ <Project platforms="Linux Win32 Mac">
+ <AddinFile>build/debug/MonoDevelop.GtkCore2.dll</AddinFile>
+ <BuildFile>MonoDevelop.GtkCore2.sln</BuildFile>
+ <BuildConfiguration>Debug</BuildConfiguration>
+ </Project>
+</AddinProject>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/build/debug/Mono.TextEditor.dll.config b/main/src/addins/MonoDevelop.GtkCore2/build/debug/Mono.TextEditor.dll.config
new file mode 100644
index 0000000000..3fd1526914
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/build/debug/Mono.TextEditor.dll.config
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <dllmap os="!windows,osx" dll="libglib-2.0-0.dll" target="libglib-2.0.so.0"/>
+ <dllmap os="!windows,osx" dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0"/>
+ <dllmap os="!windows,osx" dll="libatk-1.0-0.dll" target="libatk-1.0.so.0"/>
+ <dllmap os="!windows,osx" dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0"/>
+ <dllmap os="!windows,osx" dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0"/>
+ <dllmap os="!windows,osx" dll="libpango-1.0-0.dll" target="libpango-1.0.so.0"/>
+ <dllmap os="!windows,osx" dll="libpangocairo-1.0-0.dll" target="libpangocairo-1.0.so.0"/>
+
+ <dllmap os="osx" dll="libglib-2.0-0.dll" target="libglib-2.0.0.dylib"/>
+ <dllmap os="osx" dll="libgobject-2.0-0.dll" target="libgobject-2.0.0.dylib"/>
+ <dllmap os="osx" dll="libatk-1.0-0.dll" target="libatk-1.0.0.dylib"/>
+ <dllmap os="osx" dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.0.dylib"/>
+ <dllmap os="osx" dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.0.dylib"/>
+ <dllmap os="osx" dll="libpango-1.0-0.dll" target="libpango-1.0.0.dylib"/>
+ <dllmap os="osx" dll="libpangocairo-1.0-0.dll" target="libpangocairo-1.0.0.dylib"/>
+</configuration> \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Core.dll.config b/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Core.dll.config
new file mode 100644
index 0000000000..9551af1543
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Core.dll.config
@@ -0,0 +1,4 @@
+<configuration>
+ <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.dylib" os="osx" />
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe b/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe
new file mode 100755
index 0000000000..1b37b819d1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe.config b/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe.config
new file mode 100644
index 0000000000..4e4303ebdf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/build/debug/MonoDevelop.Projects.Formats.MSBuild.exe.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <generatePublisherEvidence enabled="false" />
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="2.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="2.0.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/build/debug/libstetic2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/build/debug/libstetic2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/build/debug/libstetic2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/build/debug/libsteticui2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/build/debug/libsteticui2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/build/debug/libsteticui2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/changes.patch b/main/src/addins/MonoDevelop.GtkCore2/changes.patch
new file mode 100644
index 0000000000..9fbc84e921
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/changes.patch
@@ -0,0 +1,6455 @@
+Index: libsteticui/ProjectBackend.cs
+===================================================================
+--- libsteticui/ProjectBackend.cs (revision 17)
++++ libsteticui/ProjectBackend.cs (working copy)
+@@ -16,7 +16,7 @@
+ bool modified;
+ Gtk.Widget selection;
+ string id;
+- string fileName;
++ string folderName;
+ XmlDocument tempDoc;
+ bool loading;
+ IResourceProvider resourceProvider;
+@@ -33,7 +33,9 @@
+ AssemblyResolver resolver;
+ string imagesRootPath;
+ string targetGtkVersion;
+- //version of stetic xml files
++ List<string> modifiedTopLevels;
++ //During project conversion flag is set
++ bool converting;
+
+ // The action collection of the last selected widget
+ Stetic.Wrapper.ActionGroupCollection oldTopActionCollection;
+@@ -49,8 +51,7 @@
+ public event SignalChangedEventHandler SignalChanged;
+
+ public event Wrapper.WidgetEventHandler SelectionChanged;
+- public event EventHandler ModifiedChanged;
+- public event EventHandler Changed;
++ public event ProjectChangedEventHandler Changed;
+
+ // Fired when the project has been reloaded, due for example to
+ // a change in the registry
+@@ -70,6 +71,7 @@
+ iconFactory = new ProjectIconFactory ();
+ widgetLibraries = new ArrayList ();
+ internalLibs = new ArrayList ();
++ modifiedTopLevels = new List<string> ();
+ }
+
+ public void Dispose ()
+@@ -95,12 +97,18 @@
+ return null;
+ }
+
++
+ public string FileName {
+- get { return fileName; }
++ get { throw new Exception("FileName is obsolete"); }
++ set { throw new Exception("FileName is obsolete"); }
++ }
++
++ public string FolderName {
++ get { return folderName; }
+ set {
+- this.fileName = value;
+- if (fileName != null)
+- Id = System.IO.Path.GetFileName (fileName);
++ this.folderName = value;
++ if (folderName != null )
++ Id = System.IO.Path.GetFullPath (folderName);
+ else
+ Id = null;
+ }
+@@ -134,7 +142,7 @@
+ }
+
+ public string TargetGtkVersion {
+- get { return targetGtkVersion != null ? targetGtkVersion : "2.4"; }
++ get { return targetGtkVersion ?? string.Empty; }
+ set {
+ if (TargetGtkVersion == value)
+ return;
+@@ -149,16 +157,16 @@
+ public string ImagesRootPath {
+ get {
+ if (string.IsNullOrEmpty (imagesRootPath)) {
+- if (string.IsNullOrEmpty (fileName))
++ if (string.IsNullOrEmpty (folderName))
+ return ".";
+ else
+- return Path.GetDirectoryName (fileName);
++ return Path.GetFullPath (folderName);
+ }
+ else {
+ if (Path.IsPathRooted (imagesRootPath))
+ return imagesRootPath;
+- else if (!string.IsNullOrEmpty (fileName))
+- return Path.GetFullPath (Path.Combine (Path.GetDirectoryName (fileName), imagesRootPath));
++ else if (!string.IsNullOrEmpty (folderName))
++ return Path.GetFullPath (Path.Combine (folderName, imagesRootPath));
+ else
+ return imagesRootPath;
+ }
+@@ -190,7 +198,7 @@
+ widgetLibraries.Remove (lib);
+ internalLibs.Remove (lib);
+ }
+-
++
+ public ArrayList GetComponentTypes ()
+ {
+ ArrayList list = new ArrayList ();
+@@ -257,20 +265,13 @@
+ set { iconFactory = value; }
+ }
+
+- internal void SetFileName (string fileName)
+- {
+- this.fileName = fileName;
+- }
+-
+ internal void SetFrontend (Project project)
+ {
+ frontend = project;
+ }
+
+ public void Close ()
+- {
+- fileName = null;
+-
++ {
+ if (actionGroups != null && ownedGlobalActionGroups) {
+ foreach (Stetic.Wrapper.ActionGroup ag in actionGroups)
+ ag.Dispose ();
+@@ -284,24 +285,35 @@
+
+ selection = null;
+ topLevels.Clear ();
+- widgetLibraries.Clear ();
++ //widgetLibraries.Clear ();
++
+
+ iconFactory = new ProjectIconFactory ();
+ }
+
+- public void Load (string fileName)
++ public void Load (string folderName)
+ {
+- Load (fileName, fileName);
++ this.folderName = folderName;
++ XmlDocument doc = new XmlDocument ();
++ doc.PreserveWhitespace = true;
++ XmlElement toplevel = doc.CreateElement ("stetic-interface");
++ doc.AppendChild (toplevel);
++ modifiedTopLevels.Clear ();
++
++ ReadIconFactory (doc);
++ ReadActionGroups (doc);
++ ReadTopLevels (doc);
++ Read (doc);
++
++ Id = System.IO.Path.GetFullPath (folderName);
+ }
+
+- public void Load (string xmlFile, string fileName)
++ public void LoadOldVersion (string fileName)
+ {
+- this.fileName = fileName;
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+- doc.Load (xmlFile);
+- ReadIconFactory (doc);
+- ReadSplitFiles (doc);
++ doc.Load (fileName);
++
+ Read (doc);
+
+ Id = System.IO.Path.GetFileName (fileName);
+@@ -313,7 +325,7 @@
+ if (node == null)
+ return;
+
+- string basePath = fileName != null ? Path.GetDirectoryName (fileName) : null;
++ string basePath = folderName;
+ string xmlfile = Path.Combine(basePath, "IconFactory.gtkx");
+
+ if (File.Exists (xmlfile)) {
+@@ -331,8 +343,18 @@
+ }
+ }
+
+- void ReadSplitFiles (XmlDocument doc)
++ void ReadActionGroups (XmlDocument doc)
+ {
++ ReadSplitFiles (doc, "action-group", "name");
++ }
++
++ void ReadTopLevels (XmlDocument doc)
++ {
++ ReadSplitFiles (doc, "widget", "id");
++ }
++
++ void ReadSplitFiles (XmlDocument doc, string splitElement, string idAttribute)
++ {
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ return;
+@@ -349,88 +371,59 @@
+
+ XmlNode wnode = wdoc.SelectSingleNode ("/stetic-interface");
+
+- foreach (XmlNode toplevel in wnode.SelectNodes ("widget | action-group")) {
+- XmlNode imported = doc.ImportNode (toplevel, true);
+- node.AppendChild (imported);
++ foreach (XmlElement toplevel in wnode.SelectNodes (splitElement)) {
++ string id = toplevel.GetAttribute (idAttribute);
++
++ if (frontend.DesignInfo.HasComponentFile (id)) {
++ XmlNode imported = doc.ImportNode (toplevel, true);
++ node.AppendChild (imported);
++ }
+ }
+ }
+ }
+ }
+ }
+
++ void AddActionGroup (XmlElement groupElem)
++ {
++ ObjectReader reader = new ObjectReader (this, FileFormat.Native);
++
++ Wrapper.ActionGroup actionGroup = new Wrapper.ActionGroup ();
++ actionGroup.Read (reader, groupElem);
++ actionGroups.Add (actionGroup);
++ }
++
++ void AddWidget (XmlElement toplevel)
++ {
++ topLevels.Add (new WidgetData (toplevel.GetAttribute ("id"), toplevel, null));
++ }
++
+ void Read (XmlDocument doc)
+ {
+ loading = true;
+- string basePath = fileName != null ? Path.GetDirectoryName (fileName) : null;
+-
++
+ try {
+- string fn = fileName;
+ Close ();
+- fileName = fn;
+
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ throw new ApplicationException (Catalog.GetString ("Not a Stetic file according to node name."));
+
+- // Load configuration options
+- foreach (XmlNode configNode in node.SelectNodes ("configuration/*")) {
+- XmlElement config = configNode as XmlElement;
+- if (config == null) continue;
+-
+- if (config.LocalName == "images-root-path")
+- imagesRootPath = config.InnerText;
+- else if (config.LocalName == "target-gtk-version")
+- targetGtkVersion = config.InnerText;
+- }
+-
+ // Load the assembly directories
+ resolver = new AssemblyResolver (app);
+- foreach (XmlElement libElem in node.SelectNodes ("import/assembly-directory")) {
+- string dir = libElem.GetAttribute ("path");
+- if (dir.Length > 0) {
+- if (basePath != null && !Path.IsPathRooted (dir)) {
+- dir = Path.Combine (basePath, dir);
+- if (Directory.Exists (dir))
+- dir = Path.GetFullPath (dir);
+- }
+- resolver.Directories.Add (dir);
+- }
+- }
+-
+- // Import the referenced libraries
+- foreach (XmlElement libElem in node.SelectNodes ("import/widget-library")) {
+- string libname = libElem.GetAttribute ("name");
+- if (libname.EndsWith (".dll") || libname.EndsWith (".exe")) {
+- if (basePath != null && !Path.IsPathRooted (libname)) {
+- libname = Path.Combine (basePath, libname);
+- if (File.Exists (libname))
+- libname = Path.GetFullPath (libname);
+- }
+- }
+- widgetLibraries.Add (libname);
+- if (libElem.GetAttribute ("internal") == "true")
+- internalLibs.Add (libname);
+- }
+-
+ app.LoadLibraries (resolver, widgetLibraries);
+
+- ObjectReader reader = new ObjectReader (this, FileFormat.Native);
+-
+ if (ownedGlobalActionGroups) {
+- foreach (XmlElement groupElem in node.SelectNodes ("action-group")) {
+- Wrapper.ActionGroup actionGroup = new Wrapper.ActionGroup ();
+- actionGroup.Read (reader, groupElem);
+- actionGroups.Add (actionGroup);
+- }
++ foreach (XmlElement groupElem in node.SelectNodes ("action-group"))
++ AddActionGroup (groupElem);
+ }
+
+ XmlElement iconsElem = node.SelectSingleNode ("icon-factory") as XmlElement;
+ if (iconsElem != null)
+ iconFactory.Read (this, iconsElem);
+
+- foreach (XmlElement toplevel in node.SelectNodes ("widget")) {
+- topLevels.Add (new WidgetData (toplevel.GetAttribute ("id"), toplevel, null));
+- }
++ foreach (XmlElement toplevel in node.SelectNodes ("widget"))
++ AddWidget (toplevel);
+
+ } finally {
+ loading = false;
+@@ -443,8 +436,9 @@
+ try {
+ loading = true;
+ ObjectReader reader = new ObjectReader (this, FileFormat.Native);
+- Wrapper.Container wrapper = Stetic.ObjectWrapper.ReadObject (reader, data.XmlData) as Wrapper.Container;
++ Wrapper.Container wrapper = Stetic.ObjectWrapper.ReadObject (reader, data.XmlData, null) as Wrapper.Container;
+ data.Widget = wrapper.Wrapped;
++ data.Widget.Destroyed += (s,e) => data.Widget = null;
+ } finally {
+ loading = false;
+ }
+@@ -453,9 +447,62 @@
+ return data.Widget;
+ }
+
+- public void Save (string fileName)
++ public bool ReloadTopLevel (string topLevelName)
+ {
+- this.fileName = fileName;
++ XmlElement topLevelElem = ReadDesignerFile (topLevelName, "widget");
++ if (topLevelName != null) {
++ WidgetData data = GetWidgetData (topLevelName);
++
++ if (data != null) {
++ //Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (data.Widget);
++ data.SetXmlData (topLevelName, topLevelElem);
++ GetWidget (data);
++ return true;
++ }
++ }
++ return false;
++ }
++
++ public void ReloadActionGroup (string groupName)
++ {
++
++ }
++
++ XmlElement ReadDesignerFile (string componentName, string elementName)
++ {
++ string gtkxFile = GetDesignerFileName (componentName);
++ if (gtkxFile != null) {
++ XmlDocument wdoc = new XmlDocument ();
++ wdoc.PreserveWhitespace = true;
++ wdoc.Load (gtkxFile);
++
++ XmlNode wnode = wdoc.SelectSingleNode ("/stetic-interface");
++ foreach (XmlElement toplevel in wnode.SelectNodes (elementName)) {
++ return toplevel;
++ }
++
++ string msg = string.Format (@"Cannot find /stetic-interface/{0} element in {1} file.",
++ elementName, gtkxFile);
++ throw new InvalidOperationException (msg);
++ }
++
++ return null;
++ }
++
++ public void ConvertProject (string oldSteticFileName, string newGuiFolderName)
++ {
++ converting = true;
++ try {
++ LoadOldVersion (oldSteticFileName);
++ Save (newGuiFolderName);
++ } finally {
++ converting = false;
++ }
++ }
++
++ public void Save (string folderName)
++ {
++ this.folderName = folderName;
+ XmlDocument doc = Write (false);
+
+ XmlTextWriter writer = null;
+@@ -463,15 +510,7 @@
+ WriteIconFactory (doc);
+ WriteActionGroups (doc);
+ WriteTopLevels (doc);
+- // Write to a temporary file first, just in case something fails
+- writer = new XmlTextWriter (fileName + "~", System.Text.Encoding.UTF8);
+- writer.Formatting = Formatting.Indented;
+- doc.Save (writer);
+- writer.Close ();
+-
+- File.Copy (fileName + "~", fileName, true);
+- File.Delete (fileName + "~");
+-
++
+ } finally {
+ if (writer != null)
+ writer.Close ();
+@@ -497,7 +536,7 @@
+ XmlNode ifnode2 = doc2.ImportNode (ifnode, true);
+ node2.AppendChild (ifnode2);
+
+- string basePath = this.fileName != null ? Path.GetDirectoryName (this.fileName) : null;
++ string basePath = this.folderName;
+ string xmlFile = Path.Combine (basePath, "IconFactory.gtkx");
+ WriteXmlFile (xmlFile, doc2);
+
+@@ -520,34 +559,35 @@
+ if (node == null)
+ return;
+
+- List<XmlElement> toplevels = new List<XmlElement> ();
+ foreach (XmlElement toplevel in node.SelectNodes (splitElement)) {
+
+ string id = toplevel.GetAttribute (idAttribute);
+- string basePath = frontend.DesignInfo.GetComponentFolder (id);
+- string xmlFile = Path.Combine (basePath, id + ".gtkx");
+-
+- XmlDocument doc2 = new XmlDocument ();
+- doc2.PreserveWhitespace = true;
+-
+- XmlElement node2 = doc2.CreateElement ("stetic-interface");
+- doc2.AppendChild (node2);
+-
+- XmlNode wnode2 = doc2.ImportNode (toplevel, true);
+- node2.AppendChild (wnode2);
+-
+- //after saving component need to remove its xml element definition,
+- //otherwise it would be saved in gui.stetic
+- toplevels.Add (toplevel);
+-
+- WriteXmlFile (xmlFile, doc2);
++ if (modifiedTopLevels.Contains (id) || converting) {
++ string xmlFile = GetDesignerFileName (id);
++ if (xmlFile != null) {
++ XmlDocument doc2 = new XmlDocument ();
++ doc2.PreserveWhitespace = true;
++
++ XmlElement node2 = doc2.CreateElement ("stetic-interface");
++ doc2.AppendChild (node2);
++
++ XmlNode wnode2 = doc2.ImportNode (toplevel, true);
++ node2.AppendChild (wnode2);
++
++ WriteXmlFile (xmlFile, doc2);
++ if (modifiedTopLevels.Contains (id))
++ modifiedTopLevels.Remove (id);
++ }
++ }
+ }
+-
+- foreach (XmlElement toplevel in toplevels)
+- //now it is safe to remove
+- node.RemoveChild (toplevel);
+ }
+
++ private string GetDesignerFileName (string componentName)
++ {
++ string componentFile = frontend.DesignInfo.GetComponentFile (componentName);
++ return frontend.DesignInfo.GetGtkxFile (componentFile);
++ }
++
+ void WriteXmlFile (string xmlFile, XmlDocument doc)
+ {
+ XmlTextWriter writer = null;
+@@ -574,52 +614,6 @@
+ XmlElement toplevel = doc.CreateElement ("stetic-interface");
+ doc.AppendChild (toplevel);
+
+- XmlElement config = doc.CreateElement ("configuration");
+- if (!string.IsNullOrEmpty (imagesRootPath)) {
+- XmlElement iroot = doc.CreateElement ("images-root-path");
+- iroot.InnerText = imagesRootPath;
+- config.AppendChild (iroot);
+- }
+- if (!string.IsNullOrEmpty (targetGtkVersion)) {
+- XmlElement iroot = doc.CreateElement ("target-gtk-version");
+- iroot.InnerText = targetGtkVersion;
+- config.AppendChild (iroot);
+- }
+-
+- if (config.ChildNodes.Count > 0)
+- toplevel.AppendChild (config);
+-
+- if (widgetLibraries.Count > 0 || (resolver != null && resolver.Directories.Count > 0)) {
+- XmlElement importElem = doc.CreateElement ("import");
+- toplevel.AppendChild (importElem);
+- string basePath = Path.GetDirectoryName (fileName);
+-
+- if (resolver != null && resolver.Directories.Count > 0) {
+- foreach (string dir in resolver.Directories) {
+- XmlElement dirElem = doc.CreateElement ("assembly-directory");
+- if (basePath != null)
+- dirElem.SetAttribute ("path", AbsoluteToRelativePath (basePath, dir));
+- else
+- dirElem.SetAttribute ("path", dir);
+- toplevel.AppendChild (dirElem);
+- }
+- }
+-
+- foreach (string wlib in widgetLibraries) {
+- string libName = wlib;
+- XmlElement libElem = doc.CreateElement ("widget-library");
+- if (wlib.EndsWith (".dll") || wlib.EndsWith (".exe")) {
+- if (basePath != null)
+- libName = AbsoluteToRelativePath (basePath, wlib);
+- }
+-
+- libElem.SetAttribute ("name", libName);
+- if (IsInternalLibrary (wlib))
+- libElem.SetAttribute ("internal", "true");
+- importElem.AppendChild (libElem);
+- }
+- }
+-
+ ObjectWriter writer = new ObjectWriter (doc, FileFormat.Native);
+ writer.CreateUndoInfo = includeUndoInfo;
+ if (ownedGlobalActionGroups) {
+@@ -670,9 +664,14 @@
+ }
+ }
+
+- internal WidgetEditSession CreateWidgetDesignerSession (WidgetDesignerFrontend frontend, string windowName, Stetic.ProjectBackend editingBackend, bool autoCommitChanges)
++// internal WidgetEditSession CreateWidgetDesignerSession (WidgetDesignerFrontend frontend, string windowName, Stetic.ProjectBackend editingBackend, bool autoCommitChanges)
++// {
++// return new WidgetEditSession (this, frontend, windowName, editingBackend, autoCommitChanges);
++// }
++
++ internal WidgetEditSession CreateWidgetDesignerSession (WidgetDesignerFrontend frontend, string windowName)
+ {
+- return new WidgetEditSession (this, frontend, windowName, editingBackend, autoCommitChanges);
++ return new WidgetEditSession (this, frontend, windowName);
+ }
+
+ internal ActionGroupEditSession CreateGlobalActionGroupDesignerSession (ActionGroupDesignerFrontend frontend, string groupName, bool autoCommitChanges)
+@@ -687,7 +686,7 @@
+
+ public Wrapper.Container GetTopLevelWrapper (string name, bool throwIfNotFound)
+ {
+- Gtk.Widget w = GetTopLevel (name);
++ Gtk.Widget w = GetWidget (name);
+ if (w != null) {
+ Wrapper.Container ww = Wrapper.Container.Lookup (w);
+ if (ww != null)
+@@ -698,6 +697,23 @@
+ return null;
+ }
+
++ public object AddNewComponent (string fileName)
++ {
++ XmlDocument doc = new XmlDocument();
++ doc.PreserveWhitespace = true;
++ doc.Load (fileName);
++
++ XmlElement toplevel = (XmlElement)doc.SelectSingleNode ("/stetic-interface/widget");
++ if (toplevel != null)
++ return AddNewWidgetFromTemplate (toplevel.OuterXml);
++
++ XmlElement groupElem = (XmlElement)doc.SelectSingleNode ("/stetic-interface/action-group");
++ if (groupElem != null)
++ return AddNewActionGroupFromTemplate (groupElem.OuterXml);
++
++ return null;
++ }
++
+ public object AddNewWidget (string type, string name)
+ {
+ ClassDescriptor cls = Registry.LookupClassByName (type);
+@@ -724,22 +740,9 @@
+
+ if (frontend != null)
+ frontend.NotifyWidgetRemoved (data.Name);
+-
+- XmlElement elem;
+- if (data.Widget != null)
+- elem = Stetic.WidgetUtils.ExportWidget (data.Widget);
+- else
+- elem = (XmlElement) data.XmlData.Clone ();
+- XmlDocument doc = new XmlDocument ();
+- XmlNode node = doc.ImportNode (elem, true);
+- doc.AppendChild (node);
+- string dir = Path.Combine (Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), "stetic"), "deleted-designs");
+- if (!Directory.Exists (dir))
+- Directory.CreateDirectory (dir);
+- doc.Save (Path.Combine (dir, name + ".xml"));
+- topLevels.Remove (data);
+- if (data.Widget != null)
+- data.Widget.Destroy ();
++
++ if (modifiedTopLevels.Contains (name))
++ modifiedTopLevels.Remove (name);
+ }
+
+ public Stetic.Wrapper.ActionGroup AddNewActionGroup (string name)
+@@ -747,6 +750,7 @@
+ Stetic.Wrapper.ActionGroup group = new Stetic.Wrapper.ActionGroup ();
+ group.Name = name;
+ ActionGroups.Add (group);
++ this.modifiedTopLevels.Add (name);
+ return group;
+ }
+
+@@ -758,12 +762,16 @@
+ Stetic.Wrapper.ActionGroup group = new Stetic.Wrapper.ActionGroup ();
+ group.Read (or, doc.DocumentElement);
+ ActionGroups.Add (group);
++ this.modifiedTopLevels.Add (group.Name);
+ return group;
+ }
+
+ public void RemoveActionGroup (Stetic.Wrapper.ActionGroup group)
+ {
+ ActionGroups.Remove (group);
++ string name = group.Name;
++ if (modifiedTopLevels.Contains (name))
++ modifiedTopLevels.Remove (name);
+ }
+
+ public Wrapper.ActionGroup[] GetActionGroups ()
+@@ -771,40 +779,7 @@
+ // Needed since ActionGroupCollection can't be made serializable
+ return ActionGroups.ToArray ();
+ }
+-
+- public void CopyWidgetToProject (string name, ProjectBackend other, string replacedName)
+- {
+- WidgetData wdata = GetWidgetData (name);
+- if (name == null)
+- throw new InvalidOperationException ("Component not found: " + name);
+
+- XmlElement data;
+- if (wdata.Widget != null)
+- data = Stetic.WidgetUtils.ExportWidget (wdata.Widget);
+- else
+- data = (XmlElement) wdata.XmlData.Clone ();
+-
+- // If widget already exist, replace it
+- wdata = other.GetWidgetData (replacedName);
+- if (wdata == null) {
+- wdata = new WidgetData (name, data, null);
+- other.topLevels.Add (wdata);
+- } else {
+- if (wdata.Widget != null) {
+- // If a widget instance already exist, load the new data on it
+- Wrapper.Widget sw = Wrapper.Widget.Lookup (wdata.Widget);
+- sw.Read (new ObjectReader (other, FileFormat.Native), data);
+- sw.NotifyChanged ();
+- if (name != replacedName)
+- other.OnWidgetNameChanged (new Wrapper.WidgetNameChangedArgs (sw, replacedName, name), true);
+- } else {
+- wdata.SetXmlData (name, data);
+- if (name != replacedName)
+- other.OnWidgetNameChanged (new Wrapper.WidgetNameChangedArgs (null, replacedName, name), true);
+- }
+- }
+- }
+-
+ void CleanUndoData (XmlElement elem)
+ {
+ elem.RemoveAttribute ("undoId");
+@@ -861,10 +836,19 @@
+ NotifyComponentTypesChanged ();
+ }
+
++ bool preserveWidgetLibraries;
++
+ public void Reload ()
+ {
+- OnRegistryChanging (null, null);
+- OnRegistryChanged (null, null);
++ try {
++ preserveWidgetLibraries = true;
++ OnRegistryChanging (null, null);
++ OnRegistryChanged (null, null);
++ }
++ finally
++ {
++ preserveWidgetLibraries = false;
++ }
+ }
+
+ public string Id {
+@@ -872,18 +856,16 @@
+ set { id = value; }
+ }
+
+- public bool Modified {
+- get { return modified; }
+- set {
+- if (modified != value) {
+- modified = value;
+- if (frontend != null)
+- frontend.NotifyModifiedChanged ();
+- OnModifiedChanged (EventArgs.Empty);
+- }
+- }
++ public bool WasModified (string topLevel)
++ {
++ return modifiedTopLevels.Contains (topLevel);
+ }
+
++ public bool ComponentNeedsCodeGeneration (string topLevel)
++ {
++ return frontend.DesignInfo.ComponentNeedsCodeGeneration (topLevel);
++ }
++
+ public AssemblyResolver Resolver {
+ get { return resolver; }
+ }
+@@ -913,6 +895,7 @@
+
+ if (!loading) {
+ Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (widget);
++
+ if (ww == null)
+ throw new InvalidOperationException ("Widget not wrapped");
+ if (frontend != null)
+@@ -925,7 +908,7 @@
+ {
+ if (loading)
+ return;
+- NotifyChanged ();
++ NotifyChanged (args.Wrapper.RootWrapperName);
+ if (ObjectChanged != null)
+ ObjectChanged (this, args);
+ }
+@@ -934,7 +917,7 @@
+ {
+ if (loading)
+ return;
+- NotifyChanged ();
++ NotifyChanged (args.WidgetWrapper.RootWrapperName);
+ OnWidgetNameChanged (args, args.WidgetWrapper.IsTopLevel);
+ }
+
+@@ -1027,7 +1010,7 @@
+ }
+ }
+
+- public Gtk.Widget GetTopLevel (string name)
++ public Gtk.Widget GetWidget (string name)
+ {
+ WidgetData w = GetWidgetData (name);
+ if (w != null)
+@@ -1174,24 +1157,19 @@
+ OnComponentTypesChanged (null, null);
+ }
+
+- void NotifyChanged ()
++ void NotifyChanged (string rootWidgetName)
+ {
+- Modified = true;
++ if (!modifiedTopLevels.Contains (rootWidgetName))
++ modifiedTopLevels.Add (rootWidgetName);
+ if (frontend != null)
+- frontend.NotifyChanged ();
++ frontend.NotifyChanged (rootWidgetName);
+ if (Changed != null)
+- Changed (this, EventArgs.Empty);
++ Changed (this, new ProjectChangedEventArgs (rootWidgetName));
+ }
+
+- protected virtual void OnModifiedChanged (EventArgs args)
+- {
+- if (ModifiedChanged != null)
+- ModifiedChanged (this, args);
+- }
+-
+ protected virtual void OnWidgetAdded (Stetic.Wrapper.WidgetEventArgs args)
+ {
+- NotifyChanged ();
++ NotifyChanged (args.WidgetWrapper.RootWrapperName);
+ if (WidgetAdded != null)
+ WidgetAdded (this, args);
+ }
+@@ -1226,4 +1204,16 @@
+ }
+ }
+ }
++
++ public class ProjectChangedEventArgs : EventArgs
++ {
++ public string ChangedTopLevelName { get; private set; }
++
++ public ProjectChangedEventArgs (string changedTopLevel)
++ {
++ ChangedTopLevelName = changedTopLevel;
++ }
++ }
++
++ public delegate void ProjectChangedEventHandler (object sender, ProjectChangedEventArgs args);
+ }
+Index: libsteticui/IProjectDesignInfo.cs
+===================================================================
+--- libsteticui/IProjectDesignInfo.cs (revision 17)
++++ libsteticui/IProjectDesignInfo.cs (working copy)
+@@ -2,14 +2,21 @@
+
+ namespace Stetic
+ {
+- //Provides access to informations menaged by ide
++ //Provides access to informations managed by ide
+ public interface IProjectDesignInfo
+ {
+- //Returns component source file folder
+- string GetComponentFolder(string componentName);
++ //Returns component source file for given component
++ string GetComponentFile (string componentName);
++ bool HasComponentFile (string componentFile);
+
++ //Returns gtkx file name for given component file
++ string GetGtkxFile (string componentFile);
++
+ //Search for all components source file folders
+ string[] GetComponentFolders ();
++
++ // Checks if code generation for a component is needed
++ bool ComponentNeedsCodeGeneration (string componentName);
+ }
+ }
+
+Index: libsteticui/WidgetEditSession.cs
+===================================================================
+--- libsteticui/WidgetEditSession.cs (revision 17)
++++ libsteticui/WidgetEditSession.cs (working copy)
+@@ -39,14 +39,12 @@
+ internal class WidgetEditSession: MarshalByRefObject, IDisposable
+ {
+ string sourceWidget;
+- Stetic.ProjectBackend sourceProject;
++ Stetic.ProjectBackend project;
+
+- Stetic.ProjectBackend gproject;
+ Stetic.Wrapper.Container rootWidget;
+ Stetic.WidgetDesignerBackend widget;
+ Gtk.VBox designer;
+ Gtk.Plug plug;
+- bool autoCommitChanges;
+ WidgetActionBar toolbar;
+ WidgetDesignerFrontend frontend;
+ bool allowBinding;
+@@ -55,61 +53,27 @@
+ ContainerUndoRedoManager undoManager;
+ UndoQueue undoQueue;
+
+- public event EventHandler ModifiedChanged;
+ public event EventHandler RootWidgetChanged;
+ public event Stetic.Wrapper.WidgetEventHandler SelectionChanged;
+
+- public WidgetEditSession (ProjectBackend sourceProject, WidgetDesignerFrontend frontend, string windowName, Stetic.ProjectBackend editingBackend, bool autoCommitChanges)
++ public WidgetEditSession (ProjectBackend sourceProject, WidgetDesignerFrontend frontend, string windowName)
+ {
+ this.frontend = frontend;
+- this.autoCommitChanges = autoCommitChanges;
+ undoManager = new ContainerUndoRedoManager ();
+ undoQueue = new UndoQueue ();
+ undoManager.UndoQueue = undoQueue;
+
+ sourceWidget = windowName;
+- this.sourceProject = sourceProject;
+-
+- if (!autoCommitChanges) {
+- // Reuse the action groups and icon factory of the main project
+- gproject = editingBackend;
+-
+- // Attach will prevent the destruction of the action group list by gproject
+- gproject.AttachActionGroups (sourceProject.ActionGroups);
+-
+- gproject.IconFactory = sourceProject.IconFactory;
+- gproject.FileName = sourceProject.FileName;
+- gproject.ImagesRootPath = sourceProject.ImagesRootPath;
+- gproject.ResourceProvider = sourceProject.ResourceProvider;
+- gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
+- gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
+- gproject.TargetGtkVersion = sourceProject.TargetGtkVersion;
+- sourceProject.ComponentTypesChanged += OnSourceProjectLibsChanged;
+- sourceProject.ProjectReloaded += OnSourceProjectReloaded;
+-
+- rootWidget = editingBackend.GetTopLevelWrapper (sourceWidget, false);
+- if (rootWidget == null) {
+- // Copy the widget to edit from the source project
+- // When saving the file, this project will be merged with the main project.
+- sourceProject.CopyWidgetToProject (windowName, gproject, windowName);
+- rootWidget = gproject.GetTopLevelWrapper (windowName, true);
+- }
+-
+- gproject.Modified = false;
+- }
+- else {
+- rootWidget = sourceProject.GetTopLevelWrapper (windowName, true);
+- gproject = sourceProject;
+- }
+-
++ this.project = sourceProject;
++
++ rootWidget = sourceProject.GetTopLevelWrapper (windowName, true);
+ rootWidget.Select ();
+ undoManager.RootObject = rootWidget;
+
+- gproject.ModifiedChanged += new EventHandler (OnModifiedChanged);
+- gproject.Changed += new EventHandler (OnChanged);
+- gproject.ProjectReloaded += new EventHandler (OnProjectReloaded);
+- gproject.ProjectReloading += new EventHandler (OnProjectReloading);
+-// gproject.WidgetMemberNameChanged += new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
++ this.project.Changed += new ProjectChangedEventHandler (OnChanged);
++ this.project.ProjectReloaded += new EventHandler (OnProjectReloaded);
++ this.project.ProjectReloading += new EventHandler (OnProjectReloading);
++// this.project.WidgetMemberNameChanged += new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
+ }
+
+ public bool AllowWidgetBinding {
+@@ -144,7 +108,8 @@
+ designer.BorderWidth = 3;
+ designer.PackStart (toolbar, false, false, 0);
+ designer.PackStart (widget, true, true, 3);
+- widget.DesignArea.SetSelection (gproject.Selection, gproject.Selection, false);
++ widget.DesignArea.SetSelection (project.Selection, project.Selection, false);
++
+ widget.SelectionChanged += OnSelectionChanged;
+
+ }
+@@ -173,42 +138,24 @@
+ }
+
+ public void Save ()
+- {
+- if (!autoCommitChanges) {
+- gproject.CopyWidgetToProject (rootWidget.Wrapped.Name, sourceProject, sourceWidget);
+- sourceWidget = rootWidget.Wrapped.Name;
+- gproject.Modified = false;
+- }
++ {
+ }
+
+ public ProjectBackend EditingBackend {
+- get { return gproject; }
++ get { return project; }
+ }
+
+ public void Dispose ()
+ {
+- sourceProject.ComponentTypesChanged -= OnSourceProjectLibsChanged;
+- sourceProject.ProjectReloaded -= OnSourceProjectReloaded;
++ project.ComponentTypesChanged -= OnSourceProjectLibsChanged;
++ project.ProjectReloaded -= OnSourceProjectReloaded;
++ project.Changed -= new ProjectChangedEventHandler (OnChanged);
++ project.ProjectReloaded -= OnProjectReloaded;
++ project.ProjectReloading -= OnProjectReloading;
++// project.WidgetMemberNameChanged -= new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
+
+- gproject.ModifiedChanged -= new EventHandler (OnModifiedChanged);
+- gproject.Changed -= new EventHandler (OnChanged);
+- gproject.ProjectReloaded -= OnProjectReloaded;
+- gproject.ProjectReloading -= OnProjectReloading;
+-// gproject.WidgetMemberNameChanged -= new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
+-
+- if (!autoCommitChanges) {
+- // Don't dispose the project here! it will be disposed by the frontend
+- if (widget != null) {
+- widget.SelectionChanged -= OnSelectionChanged;
+- // Don't dispose the widget. It will be disposed when destroyed together
+- // with the container
+- widget = null;
+- }
+- }
+-
+ if (plug != null)
+ plug.Destroy ();
+- gproject = null;
+ rootWidget = null;
+ frontend = null;
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+@@ -231,7 +178,7 @@
+ }
+
+ public bool Modified {
+- get { return gproject.Modified; }
++ get { return project.WasModified (RootWidget.Name); }
+ }
+
+ public UndoQueue UndoQueue {
+@@ -243,32 +190,22 @@
+ }
+ }
+
+- void OnModifiedChanged (object s, EventArgs a)
++ void OnChanged (object s, ProjectChangedEventArgs a)
+ {
++ if (a.ChangedTopLevelName != RootWidget.Name)
++ return;
++
+ if (frontend != null)
+- frontend.NotifyModifiedChanged ();
+- }
+-
+- void OnChanged (object s, EventArgs a)
+- {
+- if (frontend != null)
+ frontend.NotifyChanged ();
+ }
+
+ void OnSourceProjectReloaded (object s, EventArgs a)
+ {
+- // Propagate gtk version change
+- if (sourceProject.TargetGtkVersion != gproject.TargetGtkVersion)
+- gproject.TargetGtkVersion = sourceProject.TargetGtkVersion;
++
+ }
+
+ void OnSourceProjectLibsChanged (object s, EventArgs a)
+ {
+- // If component types have changed in the source project, they must also change
+- // in this project.
+- gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
+- gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
+- gproject.NotifyComponentTypesChanged ();
+ }
+
+ void OnProjectReloading (object s, EventArgs a)
+@@ -279,16 +216,10 @@
+
+ void OnProjectReloaded (object s, EventArgs a)
+ {
+- // Update the actions group list
+- if (!autoCommitChanges) {
+- gproject.AttachActionGroups (sourceProject.ActionGroups);
+- gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
+- gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
+- }
++ Gtk.Widget topWidget = project.GetWidget (sourceWidget);
+
+- Gtk.Widget[] tops = gproject.Toplevels;
+- if (tops.Length > 0) {
+- rootWidget = Stetic.Wrapper.Container.Lookup (tops[0]);
++ if (topWidget != null) {
++ rootWidget = Stetic.Wrapper.Container.Lookup (topWidget);
+ undoManager.RootObject = rootWidget;
+ if (rootWidget != null) {
+ Gtk.Widget oldWidget = designer;
+@@ -305,8 +236,8 @@
+ return false;
+ });
+ }
+-
+- gproject.NotifyComponentTypesChanged ();
++
++ project.NotifyComponentTypesChanged ();
+ return;
+ }
+ }
+@@ -375,7 +306,7 @@
+ public object SaveState ()
+ {
+ return new object[] {
+- gproject.SaveStatus (),
++ project.SaveStatus (),
+ undoQueue
+ };
+ }
+@@ -383,7 +314,7 @@
+ public void RestoreState (object sessionData)
+ {
+ object[] status = (object[]) sessionData;
+- gproject.LoadStatus (status [0]);
++ project.LoadStatus (status [0]);
+ undoQueue = (UndoQueue) status [1];
+ foreach (UndoRedoChange ch in undoQueue.Changes) {
+ ObjectWrapperUndoRedoChange och = ch as ObjectWrapperUndoRedoChange;
+Index: libsteticui/ChangeLog
+===================================================================
+--- libsteticui/ChangeLog (revision 17)
++++ libsteticui/ChangeLog (working copy)
+@@ -1,3 +1,155 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * CodeGenerator.cs:
++ * ProjectBackend.cs:
++ * WidgetEditSession.cs:
++ * CodeGeneratorPartialClass.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * Project.cs:
++ * Makefile.am:
++ * CodeGenerator.cs:
++ * libsteticui2.csproj:
++ * ActionGroupEditSession.cs:
++ * CodeGeneratorPartialClass.cs:
++ * CodeGeneratorInternalClass.cs: Remove class
++
++2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
++
++ * Project.cs: Add ComponentNeedsCodeGeneration method
++ * ProjectBackend.cs:
++ * IProjectDesignInfo.cs:
++ * CodeGeneratorPartialClass.cs: Only generate code for components that
++ have been changed
++
++2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs: Remove Modifies property
++ * ProjectBackend.cs: Add modifiedTopLevel list, handled on project loading, saving.
++ * libsteticui2.csproj:
++ * WidgetEditSession.cs: Use ProjectBackend.WasModified to determine if it was modified
++
++2010-08-05 Krzysztof Marecki <freefirma@gmail.com>
++
++ * WidgetDesigner.cs:
++ * ProjectBackend.cs:
++
++2010-08-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++ Remove ModifiedChanged event,
++ change Changed event to ProjectChangedEventHandler (pass name of changed widget)
++ * Project.cs:
++ * WidgetDesigner.cs:
++ * ProjectBackend.cs:
++ * WidgetEditSession.cs:
++
++2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
++
++ * Project.cs: Pass root widget name in NotifyChanged
++ * Makefile.am:
++ * ProjectBackend.cs:
++ * libsteticui2.csproj:
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Glade.cs:
++ * Makefile.am:
++ * ProjectBackend.cs:
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * ProjectBackend.cs: Return empty string when GtktargetVersion
++ is not initialized
++
++2010-07-27 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs: Remove autoCommit argument
++ * Makefile.am:
++ * WidgetDesigner.cs: Remove temporary project
++ * ProjectBackend.cs: Do not clear libraries on Close
++ * WidgetEditSession.cs: Remove temporary project
++
++2010-07-27 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs:
++ * WidgetDesigner.cs:
++ * ProjectBackend.cs:
++
++2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs: Add parameter to Convert method for passing
++ a new gtk gui folder name.
++ * ProjectBackend.cs:
++
++2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Glade.cs:
++ * Project.cs: AddComponent method
++ * Makefile.am:
++ * ProjectBackend.cs:
++ * libsteticui2.csproj:
++
++2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs: Find class name for given .gtkx file
++ * Makefile.am:
++ * ProjectBackend.cs:
++ * IProjectDesignInfo.cs:
++
++2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * ProjectBackend.cs:
++ * libsteticui2.csproj:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * libsteticui2.csproj:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * libsteticui2.csproj:
++
++2010-06-22 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++
++2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++
++2010-06-15 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs: Create backend for Convert
++
++2010-06-09 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * libsteticui2.csproj:
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs: Transition from project file name to project folder.
++ * Makefile.am:
++ * Application.cs:
++ * ProjectBackend.cs:
++ * WidgetEditSession.cs:
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Project.cs:
++ * Makefile.am:
++ * ProjectBackend.cs:
++ * IProjectDesignInfo.cs:
++
++2010-06-02 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * libsteticui2.csproj:
++
+ 2010-04-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * CecilSignalDescriptor.cs: Cecil uses '/' as separator for
+Index: libsteticui/libsteticui2.csproj
+===================================================================
+--- libsteticui/libsteticui2.csproj (revision 17)
++++ libsteticui/libsteticui2.csproj (working copy)
+@@ -60,17 +60,34 @@
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System.Core" />
++ <Reference Include="NRefactory, Version=2.1.1.0, Culture=neutral, PublicKeyToken=efe927acf176eea2">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="Mono.TextEditor, Version=1.0.0.0, Culture=neutral">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="MonoDevelop.Core, Version=2.4.0.0, Culture=neutral">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="MonoDevelop.Ide, Version=2.4.0.0, Culture=neutral">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="Mono.Debugging, Version=0.0.0.0, Culture=neutral, PublicKeyToken=9307d64546e0580d">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="Mono.Cecil, Version=0.6.9.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
++ <Package>monodevelop</Package>
++ </Reference>
+ </ItemGroup>
+ <ItemGroup>
++ <ProjectReference Include="..\libstetic\libstetic2.csproj">
++ <Project>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</Project>
++ <Name>libstetic2</Name>
++ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\contrib\Mono.Cecil\Mono.Cecil.csproj">
+ <Project>{3EC06433-F168-4C5B-A885-99CE4AB617E1}</Project>
+ <Name>Mono.Cecil</Name>
+- <Private>False</Private>
+ </ProjectReference>
+- <ProjectReference Include="..\libstetic\libstetic2.csproj">
+- <Project>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</Project>
+- <Name>libstetic2</Name>
+- </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ActionComponent.cs" />
+@@ -90,7 +107,6 @@
+ <Compile Include="CecilWidgetLibrary.cs" />
+ <Compile Include="CodeGenerationResult.cs" />
+ <Compile Include="CodeGenerator.cs" />
+- <Compile Include="CodeGeneratorInternalClass.cs" />
+ <Compile Include="CodeGeneratorPartialClass.cs" />
+ <Compile Include="Component.cs" />
+ <Compile Include="ComponentEventHandler.cs" />
+Index: libsteticui/ActionGroupEditSession.cs
+===================================================================
+--- libsteticui/ActionGroupEditSession.cs (revision 17)
++++ libsteticui/ActionGroupEditSession.cs (working copy)
+@@ -197,6 +197,9 @@
+ get { return modified; }
+ set { modified = value; frontend.NotifyModified (); }
+ }
++// public bool Modified {
++// get { return project.WasModified (); }
++// }
+
+ public string ActiveGroup {
+ get {
+Index: libsteticui/CodeGenerator.cs
+===================================================================
+--- libsteticui/CodeGenerator.cs (revision 17)
++++ libsteticui/CodeGenerator.cs (working copy)
+@@ -36,13 +36,13 @@
+ ArrayList warningList = new ArrayList ();
+
+ List<SteticCompilationUnit> units = new List<SteticCompilationUnit> ();
+- SteticCompilationUnit globalUnit = new SteticCompilationUnit ("");
+- units.Add (globalUnit);
++// SteticCompilationUnit globalUnit = new SteticCompilationUnit ("");
++// units.Add (globalUnit);
+
+ if (options == null)
+ options = new GenerationOptions ();
+ CodeNamespace globalNs = new CodeNamespace (options.GlobalNamespace);
+- globalUnit.Namespaces.Add (globalNs);
++// globalUnit.Namespaces.Add (globalNs);
+
+ // Global class
+
+@@ -73,11 +73,7 @@
+ warningList.AddRange (initContext.Warnings);
+
+ // Generate the code
+-
+- if (options.UsePartialClasses)
+- CodeGeneratorPartialClass.GenerateProjectGuiCode (globalUnit, globalNs, globalType, options, units, projects, warningList);
+- else
+- CodeGeneratorInternalClass.GenerateProjectGuiCode (globalUnit, globalNs, globalType, options, units, projects, warningList);
++ CodeGeneratorPartialClass.GenerateProjectGuiCode (globalNs, globalType, options, units, projects, warningList);
+
+ GenerateProjectActionsCode (globalNs, options, projects);
+
+@@ -108,6 +104,19 @@
+ initMethod.Statements.Clear ();
+ initMethod.Statements.Add (initCondition);
+
++ //create separate compilation unit for each type in the global namespace
++ //and insert them at the begining of the units list.
++ int index = 0;
++ foreach (CodeTypeDeclaration type in globalNs.Types)
++ {
++ SteticCompilationUnit unit = new SteticCompilationUnit (type.Name);
++ CodeNamespace ns = new CodeNamespace (globalNs.Name);
++
++ ns.Types.Add (type);
++ unit.Namespaces.Add (ns);
++ units.Insert (index++, unit);
++ }
++
+ return new CodeGenerationResult (units.ToArray (), (string[]) warningList.ToArray (typeof(string)));
+ }
+
+@@ -116,26 +125,11 @@
+ foreach (Signal signal in wrapper.Signals) {
+ SignalDescriptor descriptor = signal.SignalDescriptor;
+
+- CodeExpression createDelegate;
++ CodeExpression createDelegate = new CodeDelegateCreateExpression (
++ new CodeTypeReference (descriptor.HandlerTypeName, CodeTypeReferenceOptions.GlobalReference),
++ new CodeThisReferenceExpression (),
++ signal.Handler);
+
+- if (options.UsePartialClasses) {
+- createDelegate =
+- new CodeDelegateCreateExpression (
+- new CodeTypeReference (descriptor.HandlerTypeName, CodeTypeReferenceOptions.GlobalReference),
+- new CodeThisReferenceExpression (),
+- signal.Handler);
+- } else {
+- createDelegate =
+- new CodeMethodInvokeExpression (
+- new CodeTypeReferenceExpression (new CodeTypeReference (typeof(Delegate), CodeTypeReferenceOptions.GlobalReference)),
+- "CreateDelegate",
+- new CodeTypeOfExpression (descriptor.HandlerTypeName),
+- targetObjectVar,
+- new CodePrimitiveExpression (signal.Handler));
+-
+- createDelegate = new CodeCastExpression (descriptor.HandlerTypeName.ToGlobalTypeRef (), createDelegate);
+- }
+-
+ CodeAttachEventStatement cevent = new CodeAttachEventStatement (
+ new CodeEventReferenceExpression (
+ map.GetWidgetExp (wrapper),
+@@ -374,7 +368,7 @@
+ if (memberName == null)
+ return base.GenerateInstanceExpression (wrapper, newObject);
+
+- if (Options.UsePartialClasses) {
++// if (Options.UsePartialClasses) {
+ // Don't generate fields for top level widgets and for widgets accessible
+ // through other widget's properties
+ Wrapper.Widget ww = wrapper as Wrapper.Widget;
+@@ -399,19 +393,19 @@
+ return var;
+ } else
+ return base.GenerateInstanceExpression (wrapper, newObject);
+- } else {
+- CodeExpression var = base.GenerateInstanceExpression (wrapper, newObject);
+- Statements.Add (
+- new CodeAssignStatement (
+- new CodeIndexerExpression (
+- new CodeVariableReferenceExpression ("bindings"),
+- new CodePrimitiveExpression (memberName)
+- ),
+- var
+- )
+- );
+- return var;
+- }
++// } else {
++// CodeExpression var = base.GenerateInstanceExpression (wrapper, newObject);
++// Statements.Add (
++// new CodeAssignStatement (
++// new CodeIndexerExpression (
++// new CodeVariableReferenceExpression ("bindings"),
++// new CodePrimitiveExpression (memberName)
++// ),
++// var
++// )
++// );
++// return var;
++// }
+ }
+ }
+
+@@ -429,5 +423,10 @@
+ get { return name; }
+ internal set { name = value; }
+ }
++
++ public CodeNamespace Namespace
++ {
++ get { return (Namespaces.Count > 0) ? Namespaces [0] : null; }
++ }
+ }
+ }
+Index: libsteticui/CodeGeneratorPartialClass.cs
+===================================================================
+--- libsteticui/CodeGeneratorPartialClass.cs (revision 17)
++++ libsteticui/CodeGeneratorPartialClass.cs (working copy)
+@@ -11,32 +11,47 @@
+ {
+ internal static class CodeGeneratorPartialClass
+ {
+- public static void GenerateProjectGuiCode (SteticCompilationUnit globalUnit, CodeNamespace globalNs, CodeTypeDeclaration globalType, GenerationOptions options, List<SteticCompilationUnit> units, ProjectBackend[] projects, ArrayList warnings)
++ public static void GenerateProjectGuiCode (CodeNamespace globalNs, CodeTypeDeclaration globalType, GenerationOptions options, List<SteticCompilationUnit> units, ProjectBackend[] projects, ArrayList warnings)
+ {
+ // Generate code for each project
+ foreach (ProjectBackend gp in projects) {
+
+ // Generate top levels
+- foreach (Gtk.Widget w in gp.Toplevels)
+- GenerateWidgetCode (globalUnit, globalNs, options, units, w, warnings);
++ foreach (Gtk.Widget w in gp.Toplevels) {
++ Stetic.Wrapper.Widget wwidget = Stetic.Wrapper.Widget.Lookup (w);
++ string topLevelName = wwidget.Name;
++ if (gp.ComponentNeedsCodeGeneration (topLevelName)) {
++ //designer file for widget could be changed beyond stetic process
++ //and we nead update wrapper before code generation
++ //during reloading wrappered widget w could be changed;
++ Gtk.Widget currentw = w;
++ if (gp.ReloadTopLevel (topLevelName)) {
++ currentw = gp.GetWidget (topLevelName);
++ }
++ GenerateWidgetCode (globalNs, options, units, currentw, warnings);
++ }
++ }
+
+ // Generate global action groups
+- foreach (Wrapper.ActionGroup agroup in gp.ActionGroups)
+- GenerateGlobalActionGroupCode (globalUnit, globalNs, options, units, agroup, warnings);
++ foreach (Wrapper.ActionGroup agroup in gp.ActionGroups) {
++ string groupName = agroup.Name;
++ if (gp.ComponentNeedsCodeGeneration (groupName)) {
++ //designer file for action group could be changed beyond stetic process
++ //and we nead update wrapper
++ gp.ReloadActionGroup (groupName);
++ GenerateGlobalActionGroupCode (globalNs, options, units, agroup, warnings);
++ }
++ }
+ }
+ }
+
+- static CodeTypeDeclaration CreatePartialClass (SteticCompilationUnit globalUnit, List<SteticCompilationUnit> units, GenerationOptions options, string name)
++ static CodeTypeDeclaration CreatePartialClass (List<SteticCompilationUnit> units, GenerationOptions options, string name)
+ {
+ SteticCompilationUnit unit;
+-
+- if (options.GenerateSingleFile)
+- unit = globalUnit;
+- else {
+- unit = new SteticCompilationUnit (name);
+- units.Add (unit);
+- }
+-
++
++ unit = new SteticCompilationUnit (name);
++ units.Add (unit);
++
+ string ns = "";
+ int i = name.LastIndexOf ('.');
+ if (i != -1) {
+@@ -56,11 +71,11 @@
+ }
+
+
+- static void GenerateWidgetCode (SteticCompilationUnit globalUnit, CodeNamespace globalNs, GenerationOptions options, List<SteticCompilationUnit> units, Gtk.Widget w, ArrayList warnings)
++ static void GenerateWidgetCode (CodeNamespace globalNs, GenerationOptions options, List<SteticCompilationUnit> units, Gtk.Widget w, ArrayList warnings)
+ {
+ // Generate the build method
+
+- CodeTypeDeclaration type = CreatePartialClass (globalUnit, units, options, w.Name);
++ CodeTypeDeclaration type = CreatePartialClass (units, options, w.Name);
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = "Build";
+ type.Members.Add (met);
+@@ -107,9 +122,9 @@
+ }
+
+
+- static void GenerateGlobalActionGroupCode (SteticCompilationUnit globalUnit, CodeNamespace globalNs, GenerationOptions options, List<SteticCompilationUnit> units, Wrapper.ActionGroup agroup, ArrayList warnings)
++ static void GenerateGlobalActionGroupCode (CodeNamespace globalNs, GenerationOptions options, List<SteticCompilationUnit> units, Wrapper.ActionGroup agroup, ArrayList warnings)
+ {
+- CodeTypeDeclaration type = CreatePartialClass (globalUnit, units, options, agroup.Name);
++ CodeTypeDeclaration type = CreatePartialClass (units, options, agroup.Name);
+
+ // Generate the build method
+
+Index: libsteticui/WidgetDesigner.cs
+===================================================================
+--- libsteticui/WidgetDesigner.cs (revision 17)
++++ libsteticui/WidgetDesigner.cs (working copy)
+@@ -1,4 +1,3 @@
+-
+ using System;
+ using System.Collections;
+
+@@ -14,17 +13,14 @@
+ Component rootWidget;
+
+ Project project;
+- Project editedProject;
+ int reloadCount;
+
+ string componentName;
+- bool autoCommitChanges;
+ bool disposed;
+
+ bool canCut, canCopy, canPaste, canDelete;
+
+ public event EventHandler BindField;
+- public event EventHandler ModifiedChanged;
+ public event EventHandler Changed;
+ public event EventHandler SelectionChanged;
+ public event EventHandler RootComponentChanged;
+@@ -34,26 +30,18 @@
+ public event ComponentNameEventHandler ComponentNameChanged;
+ public event EventHandler ComponentTypesChanged;
+
+- internal WidgetDesigner (Project project, string componentName, bool autoCommitChanges): base (project.App)
++ internal WidgetDesigner (Project project, string componentName): base (project.App)
+ {
+ this.componentName = componentName;
+- this.autoCommitChanges = autoCommitChanges;
+ this.project = project;
+ frontend = new WidgetDesignerFrontend (this);
+
+- if (autoCommitChanges)
+- editedProject = project;
+- else
+- editedProject = new Project (project.App, project.DesignInfo);
+-
+- editedProject.SignalAdded += OnSignalAdded;
+- editedProject.SignalRemoved += OnSignalRemoved;
+- editedProject.SignalChanged += OnSignalChanged;
+- editedProject.ComponentNameChanged += OnComponentNameChanged;
+- editedProject.ComponentTypesChanged += OnComponentTypesChanged;
+-
++ project.SignalAdded += OnSignalAdded;
++ project.SignalRemoved += OnSignalRemoved;
++ project.SignalChanged += OnSignalChanged;
++ project.ComponentNameChanged += OnComponentNameChanged;
++ project.ComponentTypesChanged += OnComponentTypesChanged;
+ project.BackendChanged += OnProjectBackendChanged;
+- editedProject.BackendChanged += OnProjectBackendChanged;
+
+ CreateSession ();
+ }
+@@ -70,8 +58,8 @@
+ {
+ if (!disposed) {
+ ArrayList types = new ArrayList ();
+- types.AddRange (editedProject.GetComponentTypes ());
+-
++ types.AddRange (project.GetComponentTypes ());
++
+ // Add actions from the local action groups
+
+ WidgetComponent c = rootWidget as WidgetComponent;
+@@ -90,12 +78,14 @@
+ public void BeginComponentDrag (ComponentType type, Gtk.Widget source, Gdk.DragContext ctx)
+ {
+ Stetic.ObjectWrapper wrapper = type.Action != null ? (Stetic.ObjectWrapper) type.Action.Backend : null;
+- app.Backend.BeginComponentDrag (editedProject.ProjectBackend, type.Description, type.ClassName, wrapper, source, ctx, null);
++ app.Backend.BeginComponentDrag (project.ProjectBackend, type.Description, type.ClassName, wrapper, source, ctx, null);
++
+ }
+
+ public void BeginComponentDrag (string title, string className, Gtk.Widget source, Gdk.DragContext ctx, ComponentDropCallback callback)
+ {
+- app.Backend.BeginComponentDrag (editedProject.ProjectBackend, title, className, null, source, ctx, callback);
++ app.Backend.BeginComponentDrag (project.ProjectBackend, title, className, null, source, ctx, callback);
++
+ }
+
+ // Creates an action group designer for the widget being edited by this widget designer
+@@ -103,7 +93,8 @@
+ {
+ if (disposed)
+ throw new ObjectDisposedException ("WidgetDesigner");
+- return new ActionGroupDesigner (editedProject, componentName, null, this, true);
++ return new ActionGroupDesigner (project, componentName, null, this, true);
++
+ }
+
+ public bool Modified {
+@@ -113,7 +104,7 @@
+ internal override void SetActive ()
+ {
+ if (!disposed)
+- project.App.SetActiveDesignSession (editedProject, session);
++ project.App.SetActiveDesignSession (project, session);
+ }
+
+ public bool AllowWidgetBinding {
+@@ -125,8 +116,8 @@
+ }
+
+ public ImportFileDelegate ImportFileCallback {
+- get { return editedProject.ImportFileCallback; }
+- set { editedProject.ImportFileCallback = value; }
++ get { return project.ImportFileCallback; }
++ set { project.ImportFileCallback = value; }
+ }
+
+ public object SaveStatus ()
+@@ -142,7 +133,7 @@
+ void CreateSession ()
+ {
+ try {
+- session = project.ProjectBackend.CreateWidgetDesignerSession (frontend, componentName, editedProject.ProjectBackend, autoCommitChanges);
++ session = project.ProjectBackend.CreateWidgetDesignerSession (frontend, componentName);
+ ResetCustomWidget ();
+ rootWidget = app.GetComponent (session.RootWidget, null, null);
+ } catch (Exception ex) {
+@@ -232,27 +223,23 @@
+ if (disposed)
+ return;
+
+- if (project.App.ActiveProject == editedProject)
++ if (project.App.ActiveProject == project)
+ project.App.ActiveProject = null;
+
+ disposed = true;
+ frontend.disposed = true;
+- editedProject.SignalAdded -= OnSignalAdded;
+- editedProject.SignalRemoved -= OnSignalRemoved;
+- editedProject.SignalChanged -= OnSignalChanged;
+- editedProject.ComponentNameChanged -= OnComponentNameChanged;
+- editedProject.BackendChanged -= OnProjectBackendChanged;
+- editedProject.ComponentTypesChanged -= OnComponentTypesChanged;
++ project.SignalAdded -= OnSignalAdded;
++ project.SignalRemoved -= OnSignalRemoved;
++ project.SignalChanged -= OnSignalChanged;
++ project.ComponentNameChanged -= OnComponentNameChanged;
++ project.ComponentTypesChanged -= OnComponentTypesChanged;
+ project.BackendChanged -= OnProjectBackendChanged;
+
+ if (session != null) {
+ session.Dispose ();
+ session = null;
+ }
+-
+- if (!autoCommitChanges)
+- editedProject.Dispose ();
+-
++
+ System.Runtime.Remoting.RemotingServices.Disconnect (frontend);
+ frontend = null;
+ rootWidget = null;
+@@ -309,10 +296,10 @@
+ if (++reloadCount == 2) {
+ object sessionData = null;
+
+- if (oldBackend != null && !autoCommitChanges) {
+- sessionData = session.SaveState ();
+- session.DestroyWrapperWidgetPlug ();
+- }
++// if (oldBackend != null && !autoCommitChanges) {
++// sessionData = session.SaveState ();
++// session.DestroyWrapperWidgetPlug ();
++// }
+
+ // Don't dispose the session here, since it will dispose
+ // the underlying project, and we can't do it because
+@@ -359,12 +346,6 @@
+ BindField (this, EventArgs.Empty);
+ }
+
+- internal void NotifyModifiedChanged ()
+- {
+- if (ModifiedChanged != null)
+- ModifiedChanged (this, EventArgs.Empty);
+- }
+-
+ internal void NotifyChanged ()
+ {
+ if (Changed != null)
+@@ -405,13 +386,6 @@
+ );
+ }
+
+- public void NotifyModifiedChanged ()
+- {
+- GuiDispatch.InvokeSync (
+- delegate { if (!disposed) designer.NotifyModifiedChanged (); }
+- );
+- }
+-
+ public void NotifyChanged ()
+ {
+ GuiDispatch.InvokeSync (
+Index: libsteticui/Makefile.am
+===================================================================
+--- libsteticui/Makefile.am (revision 17)
++++ libsteticui/Makefile.am (working copy)
+@@ -21,7 +21,6 @@
+ CecilWidgetLibrary.cs \
+ CodeGenerationResult.cs \
+ CodeGenerator.cs \
+- CodeGeneratorInternalClass.cs \
+ CodeGeneratorPartialClass.cs \
+ Component.cs \
+ ComponentEventHandler.cs \
+@@ -83,6 +82,7 @@
+ $(GLADE_SHARP_LIBS) \
+ $(GLIB_SHARP_LIBS) \
+ $(GTK_SHARP_LIBS) \
++ -pkg:monodevelop \
+ -r:Mono.Posix \
+ -r:System \
+ -r:System.Core \
+Index: libsteticui/Project.cs
+===================================================================
+--- libsteticui/Project.cs (revision 17)
++++ libsteticui/Project.cs (working copy)
+@@ -12,7 +12,8 @@
+ {
+ Application app;
+ ProjectBackend backend;
+- string fileName;
++ //string fileName;
++ string folderName;
+ IResourceProvider resourceProvider;
+ Component selection;
+ string tmpProjectFile;
+@@ -72,8 +73,8 @@
+ backend.SetFrontend (this);
+ if (resourceProvider != null)
+ backend.ResourceProvider = resourceProvider;
+- if (fileName != null)
+- backend.Load (fileName);
++ if (folderName != null)
++ backend.Load (folderName);
+ }
+ return backend;
+ }
+@@ -114,9 +115,9 @@
+ return null;
+ }
+
+- public string FileName {
+- get { return fileName; }
+- }
++// public string FileName {
++// get { return fileName; }
++// }
+
+ public IResourceProvider ResourceProvider {
+ get { return resourceProvider; }
+@@ -161,41 +162,16 @@
+ backend.Close ();
+ }
+
+- public void Load (string fileName)
++ public void Load (string folderName)
+ {
+- this.fileName = fileName;
++ this.folderName = folderName;
+ if (backend != null)
+- backend.Load (fileName);
++ backend.Load (folderName);
+
+- using (StreamReader sr = new StreamReader (fileName)) {
+- XmlTextReader reader = new XmlTextReader (sr);
++ foreach (string basePath in DesignInfo.GetComponentFolders ()) {
++ if (!Directory.Exists (basePath))
++ continue;
+
+- reader.MoveToContent ();
+- if (reader.IsEmptyElement)
+- return;
+-
+- reader.ReadStartElement ("stetic-interface");
+- if (reader.IsEmptyElement)
+- return;
+- while (reader.NodeType != XmlNodeType.EndElement) {
+- if (reader.NodeType == XmlNodeType.Element) {
+- if (reader.LocalName == "widget")
+- ReadWidget (reader);
+- else if (reader.LocalName == "action-group")
+- ReadActionGroup (reader);
+- else
+- reader.Skip ();
+- }
+- else {
+- reader.Skip ();
+- }
+- reader.MoveToContent ();
+- }
+- }
+-
+-// string basePath = fileName != null ? Path.GetDirectoryName (fileName) : null;
+-
+- foreach (string basePath in DesignInfo.GetComponentFolders ()) {
+ DirectoryInfo dir = new DirectoryInfo (basePath);
+
+ foreach (FileInfo file in dir.GetFiles ()) {
+@@ -257,11 +233,21 @@
+ reader.Skip ();
+ }
+
+- public void Save (string fileName)
++ public void ConvertProject (string oldSteticFileName, string newGuiFolderName)
+ {
+- this.fileName = fileName;
++ //ProjectBackend property when created invokes Load method which is not valid
++ //for old file layout
++
++ ProjectBackend backend = app.Backend.CreateProject ();
++ backend.SetFrontend (this);
++ backend.ConvertProject (oldSteticFileName, newGuiFolderName);
++ }
++
++ public void Save (string folderName)
++ {
++ this.folderName = folderName;
+ if (backend != null)
+- backend.Save (fileName);
++ backend.Save (folderName);
+ }
+
+ public void ImportGlade (string fileName)
+@@ -274,31 +260,6 @@
+ ProjectBackend.ExportGlade (fileName);
+ }
+
+- public object SaveStatus ()
+- {
+- return ProjectBackend.SaveStatus ();
+- }
+-
+- public void LoadStatus (object status)
+- {
+- ProjectBackend.LoadStatus (status);
+- }
+-
+- public bool Modified {
+- get {
+- if (backend != null)
+- return backend.Modified;
+- else
+- return modified;
+- }
+- set {
+- if (backend != null)
+- backend.Modified = value;
+- else
+- modified = true;
+- }
+- }
+-
+ public IEnumerable<WidgetInfo> Widgets {
+ get { return widgets; }
+ }
+@@ -323,9 +284,14 @@
+ return null;
+ }
+
+- public WidgetDesigner CreateWidgetDesigner (WidgetInfo widgetInfo, bool autoCommitChanges)
++// public WidgetDesigner CreateWidgetDesigner (WidgetInfo widgetInfo, bool autoCommitChanges)
++// {
++// return new WidgetDesigner (this, widgetInfo.Name, autoCommitChanges);
++// }
++
++ public WidgetDesigner CreateWidgetDesigner (WidgetInfo widgetInfo)
+ {
+- return new WidgetDesigner (this, widgetInfo.Name, autoCommitChanges);
++ return new WidgetDesigner (this, widgetInfo.Name);
+ }
+
+ public ActionGroupDesigner CreateActionGroupDesigner (ActionGroupInfo actionGroup, bool autoCommitChanges)
+@@ -341,7 +307,7 @@
+ if (wi == null) {
+ wi = new WidgetInfo (this, wc);
+ widgets.Add (wi);
+- }
++ }
+ return wi;
+ }
+
+@@ -357,6 +323,36 @@
+ return wi;
+ }
+
++ public object AddNewComponent (string fileName)
++ {
++ object ob = ProjectBackend.AddNewComponent (fileName);
++ object component = App.GetComponent (ob, null, null);
++
++ if (component is WidgetComponent) {
++ var wc = (WidgetComponent) component;
++ WidgetInfo wi = GetWidget (wc.Name);
++ if (wi == null) {
++ wi = new WidgetInfo (this, wc);
++ widgets.Add (wi);
++ }
++ return wi;
++ }
++
++ if (component is ActionGroupComponent) {
++ var ac = (ActionGroupComponent) component;
++ // Don't wait for the group added event to come to update the groups list since
++ // it may be too late.
++ ActionGroupInfo gi = GetActionGroup (ac.Name);
++ if (gi == null) {
++ gi = new ActionGroupInfo (this, ac.Name);
++ groups.Add (gi);
++ }
++ return gi;
++ }
++
++ return null;
++ }
++
+ public ComponentType[] GetComponentTypes ()
+ {
+ ArrayList types = new ArrayList ();
+@@ -574,7 +570,7 @@
+ );
+ }
+
+- internal void NotifyChanged ()
++ internal void NotifyChanged (string rootWidgetName)
+ {
+ GuiDispatch.InvokeSync (
+ delegate {
+@@ -582,10 +578,14 @@
+ Changed (this, EventArgs.Empty);
+
+ // TODO: Optimize
+- foreach (ProjectItemInfo it in widgets)
+- it.NotifyChanged ();
+- foreach (ProjectItemInfo it in groups)
+- it.NotifyChanged ();
++ foreach (ProjectItemInfo it in widgets) {
++ if (it.Name == rootWidgetName)
++ it.NotifyChanged ();
++ }
++ foreach (ProjectItemInfo it in groups) {
++ if (it.Name == rootWidgetName)
++ it.NotifyChanged ();
++ }
+ }
+ );
+ }
+@@ -732,11 +732,12 @@
+ backend.SetFrontend (this);
+
+ if (tmpProjectFile != null && File.Exists (tmpProjectFile)) {
+- backend.Load (tmpProjectFile, fileName);
++// backend.Load (tmpProjectFile, fileName);
++ throw new NotImplementedException ("OnBackendChanged");
+ File.Delete (tmpProjectFile);
+ tmpProjectFile = null;
+- } else if (fileName != null) {
+- backend.Load (fileName);
++ } else if (folderName != null) {
++ backend.Load (folderName);
+ }
+
+ if (resourceProvider != null)
+Index: libsteticui/Application.cs
+===================================================================
+--- libsteticui/Application.cs (revision 17)
++++ libsteticui/Application.cs (working copy)
+@@ -308,14 +308,14 @@
+ UpdateWidgetLibraries (false, false);
+ }
+
+- public Project LoadProject (string path, IProjectDesignInfo info)
+- {
+- Project p = new Project (this, info);
+- p.Load (path);
+- projects.Add (p);
+- p.Disposed += ProjectDisposed;
+- return p;
+- }
++// public Project LoadProject (string path, IProjectDesignInfo info)
++// {
++// Project p = new Project (this, info);
++// p.Load (path);
++// projects.Add (p);
++// p.Disposed += ProjectDisposed;
++// return p;
++// }
+
+ public Project CreateProject (IProjectDesignInfo info)
+ {
+Index: libsteticui/CodeGeneratorInternalClass.cs
+===================================================================
+--- libsteticui/CodeGeneratorInternalClass.cs (revision 17)
++++ libsteticui/CodeGeneratorInternalClass.cs (working copy)
+@@ -1,319 +0,0 @@
+-
+-using System;
+-using System.Reflection;
+-using System.CodeDom;
+-using System.CodeDom.Compiler;
+-using System.Collections.Generic;
+-using System.IO;
+-using System.Xml.Serialization;
+-using System.Collections;
+-
+-namespace Stetic
+-{
+- internal static class CodeGeneratorInternalClass
+- {
+- static CodeExpression bindingFlags;
+-
+- static CodeGeneratorInternalClass ()
+- {
+- CodeTypeReferenceExpression flagsType = new CodeTypeReferenceExpression (new CodeTypeReference ("System.Reflection.BindingFlags", CodeTypeReferenceOptions.GlobalReference));
+- bindingFlags = new CodeBinaryOperatorExpression (
+- new CodeFieldReferenceExpression (flagsType, "Public"),
+- CodeBinaryOperatorType.BitwiseOr,
+- new CodeFieldReferenceExpression (flagsType, "NonPublic")
+- );
+-
+- bindingFlags = new CodeBinaryOperatorExpression (
+- bindingFlags,
+- CodeBinaryOperatorType.BitwiseOr,
+- new CodeFieldReferenceExpression (flagsType, "Instance")
+- );
+- }
+-
+- public static void GenerateProjectGuiCode (SteticCompilationUnit globalUnit, CodeNamespace globalNs, CodeTypeDeclaration globalType, GenerationOptions options, List<SteticCompilationUnit> units, ProjectBackend[] projects, ArrayList warnings)
+- {
+- bool multiProject = projects.Length > 1;
+-
+- // Build method overload that takes a type as parameter.
+-
+- CodeMemberMethod met = new CodeMemberMethod ();
+- met.Name = "Build";
+- globalType.Members.Add (met);
+- met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "cobj"));
+- met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(Type), "type"));
+- if (multiProject)
+- met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "file"));
+- met.ReturnType = new CodeTypeReference (typeof(void));
+- met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+-
+- CodeMethodInvokeExpression call = new CodeMethodInvokeExpression (
+- new CodeMethodReferenceExpression (
+- new CodeTypeReferenceExpression (new CodeTypeReference (globalNs.Name + ".Gui", CodeTypeReferenceOptions.GlobalReference)),
+- "Build"
+- ),
+- new CodeArgumentReferenceExpression ("cobj"),
+- new CodePropertyReferenceExpression (
+- new CodeArgumentReferenceExpression ("type"),
+- "FullName"
+- )
+- );
+- if (multiProject)
+- call.Parameters.Add (new CodeArgumentReferenceExpression ("file"));
+-
+- met.Statements.Add (call);
+-
+- // Generate the build method
+-
+- met = new CodeMemberMethod ();
+- met.Name = "Build";
+- globalType.Members.Add (met);
+-
+- met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "cobj"));
+- met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "id"));
+- if (multiProject)
+- met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "file"));
+- met.ReturnType = new CodeTypeReference (typeof(void));
+- met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+-
+- if (options.GenerateEmptyBuildMethod)
+- return;
+-
+- CodeArgumentReferenceExpression cobj = new CodeArgumentReferenceExpression ("cobj");
+- CodeArgumentReferenceExpression cfile = new CodeArgumentReferenceExpression ("file");
+- CodeArgumentReferenceExpression cid = new CodeArgumentReferenceExpression ("id");
+-
+- CodeStatementCollection projectCol = met.Statements;
+-
+- CodeConditionStatement tcond = new CodeConditionStatement ();
+- tcond.Condition = new CodeMethodInvokeExpression (new CodeTypeOfExpression (typeof(Gtk.Widget)), "IsAssignableFrom", cobj);
+-
+- tcond.TrueStatements.Add (
+- new CodeMethodInvokeExpression (
+- new CodeTypeReferenceExpression (new CodeTypeReference (globalNs.Name + ".Gui", CodeTypeReferenceOptions.GlobalReference)),
+- "Initialize",
+- cobj
+- )
+- );
+-
+- // Generate code for each project
+-
+- foreach (ProjectBackend gp in projects) {
+-
+- CodeStatementCollection widgetCol;
+-
+- if (multiProject) {
+- CodeConditionStatement pcond = new CodeConditionStatement ();
+- pcond.Condition = new CodeBinaryOperatorExpression (
+- cfile,
+- CodeBinaryOperatorType.IdentityEquality,
+- new CodePrimitiveExpression (gp.Id)
+- );
+- projectCol.Add (pcond);
+-
+- widgetCol = pcond.TrueStatements;
+- projectCol = pcond.FalseStatements;
+- } else {
+- widgetCol = projectCol;
+- }
+-
+- // Generate top levels
+-
+- CodeIdentifiers ids = new CodeIdentifiers ();
+-
+- foreach (Gtk.Widget w in gp.Toplevels) {
+- CodeConditionStatement cond = new CodeConditionStatement ();
+- cond.Condition = new CodeBinaryOperatorExpression (
+- cid,
+- CodeBinaryOperatorType.IdentityEquality,
+- new CodePrimitiveExpression (w.Name)
+- );
+- widgetCol.Add (cond);
+-
+- GenerateComponentCode (w, globalUnit, globalNs, cobj, cond.TrueStatements, globalType, options, units, ids, warnings);
+-
+- widgetCol = cond.FalseStatements;
+- }
+-
+- // Generate action groups
+-
+- foreach (Wrapper.ActionGroup agroup in gp.ActionGroups) {
+- CodeConditionStatement cond = new CodeConditionStatement ();
+- cond.Condition = new CodeBinaryOperatorExpression (
+- cid,
+- CodeBinaryOperatorType.IdentityEquality,
+- new CodePrimitiveExpression (agroup.Name)
+- );
+- widgetCol.Add (cond);
+-
+- GenerateComponentCode (agroup, globalUnit, globalNs, cobj, cond.TrueStatements, globalType, options, units, ids, warnings);
+-
+- widgetCol = cond.FalseStatements;
+- }
+- }
+- }
+-
+- static CodeMemberMethod GetBuildMethod (string name, string internalClassName, string typeName, SteticCompilationUnit globalUnit, GenerationOptions options, List<SteticCompilationUnit> units)
+- {
+- SteticCompilationUnit unit;
+-
+- if (options.GenerateSingleFile)
+- unit = globalUnit;
+- else {
+- unit = new SteticCompilationUnit (name);
+- units.Add (unit);
+- }
+-
+- CodeTypeDeclaration type = new CodeTypeDeclaration (internalClassName);
+- type.Attributes = MemberAttributes.Private;
+- type.TypeAttributes = TypeAttributes.NestedAssembly;
+-
+- CodeNamespace cns = new CodeNamespace (options.GlobalNamespace + ".SteticGenerated");
+- cns.Types.Add (type);
+- unit.Namespaces.Add (cns);
+-
+- // Create the build method for the component
+-
+- CodeMemberMethod met = new CodeMemberMethod ();
+- met.Name = "Build";
+- type.Members.Add (met);
+-
+- met.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeName), "cobj"));
+- met.ReturnType = new CodeTypeReference (typeof(void));
+- met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+-
+- return met;
+- }
+-
+- static void GenerateComponentCode (object component, SteticCompilationUnit globalUnit, CodeNamespace globalNs, CodeExpression cobj, CodeStatementCollection statements, CodeTypeDeclaration globalType, GenerationOptions options, List<SteticCompilationUnit> units, CodeIdentifiers ids, ArrayList warnings)
+- {
+- Gtk.Widget widget = component as Gtk.Widget;
+- Wrapper.Widget wwidget = Stetic.Wrapper.Widget.Lookup (widget);
+- Wrapper.ActionGroup agroup = component as Wrapper.ActionGroup;
+-
+- string name = widget != null ? widget.Name : agroup.Name;
+- string internalClassName = ids.MakeUnique (CodeIdentifier.MakeValid (name));
+-
+- string typeName = widget != null ? wwidget.WrappedTypeName : "Gtk.ActionGroup";
+- // Create the build method for the top level
+-
+- CodeMemberMethod met;
+- met = GetBuildMethod (name, internalClassName, typeName, globalUnit, options, units);
+-
+- // Generate the build code
+-
+- CodeVariableDeclarationStatement varDecHash = new CodeVariableDeclarationStatement (typeof(System.Collections.Hashtable).ToGlobalTypeRef (), "bindings");
+- met.Statements.Add (varDecHash);
+- varDecHash.InitExpression = new CodeObjectCreateExpression (
+- typeof(System.Collections.Hashtable),
+- new CodeExpression [0]
+- );
+-
+- CodeVariableReferenceExpression targetObjectVar = new CodeVariableReferenceExpression ("cobj");
+- Stetic.WidgetMap map;
+-
+- if (widget != null) {
+- map = Stetic.CodeGenerator.GenerateCreationCode (globalNs, globalType, widget, targetObjectVar, met.Statements, options, warnings);
+- CodeGenerator.BindSignalHandlers (targetObjectVar, wwidget, map, met.Statements, options);
+- } else {
+- map = Stetic.CodeGenerator.GenerateCreationCode (globalNs, globalType, agroup, targetObjectVar, met.Statements, options, warnings);
+- foreach (Wrapper.Action ac in agroup.Actions)
+- CodeGenerator.BindSignalHandlers (targetObjectVar, ac, map, met.Statements, options);
+- }
+-
+- GenerateBindFieldCode (met.Statements, cobj);
+-
+- // Add a method call to the build method
+-
+- statements.Add (
+- new CodeMethodInvokeExpression (
+- new CodeTypeReferenceExpression (new CodeTypeReference (options.GlobalNamespace + ".SteticGenerated." + internalClassName, CodeTypeReferenceOptions.GlobalReference)),
+- "Build",
+- new CodeCastExpression (typeName.ToGlobalTypeRef (), cobj)
+- )
+- );
+- }
+-
+- static void GenerateBindFieldCode (CodeStatementCollection statements, CodeExpression cobj)
+- {
+- // Bind the fields
+-
+- CodeVariableDeclarationStatement varDecIndex = new CodeVariableDeclarationStatement (typeof(int), "n");
+- varDecIndex.InitExpression = new CodePrimitiveExpression (0);
+- CodeExpression varIndex = new CodeVariableReferenceExpression ("n");
+-
+- CodeVariableDeclarationStatement varDecArray = new CodeVariableDeclarationStatement (typeof(FieldInfo[]).ToGlobalTypeRef (), "fields");
+- varDecArray.InitExpression = new CodeMethodInvokeExpression (
+- new CodeMethodInvokeExpression (
+- cobj,
+- "GetType",
+- new CodeExpression [0]
+- ),
+- "GetFields",
+- bindingFlags
+- );
+- statements.Add (varDecArray);
+- CodeVariableReferenceExpression varArray = new CodeVariableReferenceExpression ("fields");
+-
+- CodeIterationStatement iteration = new CodeIterationStatement ();
+- statements.Add (iteration);
+-
+- iteration.InitStatement = varDecIndex;
+-
+- iteration.TestExpression = new CodeBinaryOperatorExpression (
+- varIndex,
+- CodeBinaryOperatorType.LessThan,
+- new CodePropertyReferenceExpression (varArray, "Length")
+- );
+- iteration.IncrementStatement = new CodeAssignStatement (
+- varIndex,
+- new CodeBinaryOperatorExpression (
+- varIndex,
+- CodeBinaryOperatorType.Add,
+- new CodePrimitiveExpression (1)
+- )
+- );
+-
+- CodeVariableDeclarationStatement varDecField = new CodeVariableDeclarationStatement (typeof(FieldInfo).ToGlobalTypeRef (), "field");
+- varDecField.InitExpression = new CodeArrayIndexerExpression (varArray, new CodeExpression [] {varIndex});
+- CodeVariableReferenceExpression varField = new CodeVariableReferenceExpression ("field");
+- iteration.Statements.Add (varDecField);
+-
+- CodeVariableDeclarationStatement varDecWidget = new CodeVariableDeclarationStatement (typeof(object), "widget");
+- iteration.Statements.Add (varDecWidget);
+- varDecWidget.InitExpression = new CodeIndexerExpression (
+- new CodeVariableReferenceExpression ("bindings"),
+- new CodePropertyReferenceExpression (varField, "Name")
+- );
+- CodeVariableReferenceExpression varWidget = new CodeVariableReferenceExpression ("widget");
+-
+- // Make sure the type of the field matches the type of the widget
+-
+- CodeConditionStatement fcond = new CodeConditionStatement ();
+- iteration.Statements.Add (fcond);
+- fcond.Condition = new CodeBinaryOperatorExpression (
+- new CodeBinaryOperatorExpression (
+- varWidget,
+- CodeBinaryOperatorType.IdentityInequality,
+- new CodePrimitiveExpression (null)
+- ),
+- CodeBinaryOperatorType.BooleanAnd,
+- new CodeMethodInvokeExpression (
+- new CodePropertyReferenceExpression (varField, "FieldType"),
+- "IsInstanceOfType",
+- varWidget
+- )
+- );
+-
+- // Set the variable value
+-
+- fcond.TrueStatements.Add (
+- new CodeMethodInvokeExpression (
+- varField,
+- "SetValue",
+- cobj,
+- varWidget
+- )
+- );
+- }
+- }
+-}
+Index: libsteticui/Glade.cs
+===================================================================
+--- libsteticui/Glade.cs (revision 17)
++++ libsteticui/Glade.cs (working copy)
+@@ -17,7 +17,6 @@
+ doc.PreserveWhitespace = true;
+ doc.XmlResolver = null;
+ doc.Load (filename);
+- project.SetFileName (filename);
+ project.Id = System.IO.Path.GetFileName (filename);
+ doc = GladeUtils.XslImportTransform (doc);
+
+@@ -27,7 +26,7 @@
+
+ ObjectReader reader = new ObjectReader (project, FileFormat.Glade);
+ foreach (XmlElement toplevel in node.SelectNodes ("widget")) {
+- Wrapper.Container wrapper = Stetic.ObjectWrapper.ReadObject (reader, toplevel) as Wrapper.Container;
++ Wrapper.Container wrapper = Stetic.ObjectWrapper.ReadObject (reader, toplevel, null) as Wrapper.Container;
+ if (wrapper != null)
+ project.AddWidget ((Gtk.Widget)wrapper.Wrapped);
+ }
+Index: libstetic/IProject.cs
+===================================================================
+--- libstetic/IProject.cs (revision 17)
++++ libstetic/IProject.cs (working copy)
+@@ -4,15 +4,16 @@
+ {
+ public interface IProject
+ {
+- string FileName { get; }
++ //string FileName { get; }
++ string FolderName { get; }
+ Gtk.Widget[] Toplevels { get; }
+- Gtk.Widget GetTopLevel (string name);
++ Gtk.Widget GetWidget (string name);
+ Gtk.Widget Selection { get; set; }
+ Wrapper.ActionGroupCollection ActionGroups { get; }
+ ProjectIconFactory IconFactory { get; }
+ string ImagesRootPath { get; }
+ string TargetGtkVersion { get; }
+- bool Modified { get; set; }
++// bool Modified { get; set; }
+ IResourceProvider ResourceProvider { get; set; }
+
+ void PopupContextMenu (Stetic.Wrapper.Widget wrapper);
+Index: libstetic/editor/ChangeLog
+===================================================================
+--- libstetic/editor/ChangeLog (revision 0)
++++ libstetic/editor/ChangeLog (revision 111)
+@@ -0,0 +1,16 @@
++2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * SelectIconDialog.cs: Remove setting Project.Modified property
++ * EditIconFactoryDialog.cs: Remove setting Project.Modified property
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ActionMenu.cs: Pass root wrapper as an argument for ObjectWrapper.Create
++ * ActionToolbar.cs:
++ * ActionMenuBar.cs:
++ * ActionGroupEditor.cs:
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * SelectImageDialog.cs:
++
+Index: libstetic/editor/EditIconFactoryDialog.cs
+===================================================================
+--- libstetic/editor/EditIconFactoryDialog.cs (revision 17)
++++ libstetic/editor/EditIconFactoryDialog.cs (working copy)
+@@ -53,7 +53,7 @@
+ iconFactory.Icons.Add (icon);
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+- project.Modified = true;
++// project.Modified = true;
+ }
+ }
+ }
+@@ -69,7 +69,7 @@
+ if (md.Run () == (int) Gtk.ResponseType.Yes) {
+ iconFactory.Icons.Remove (icon);
+ customIconList.Refresh ();
+- project.Modified = true;
++// project.Modified = true;
+ }
+ md.Destroy ();
+ }
+@@ -86,7 +86,7 @@
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+- project.Modified = true;
++// project.Modified = true;
+ }
+ }
+ }
+Index: libstetic/editor/SelectIconDialog.cs
+===================================================================
+--- libstetic/editor/SelectIconDialog.cs (revision 17)
++++ libstetic/editor/SelectIconDialog.cs (working copy)
+@@ -137,7 +137,7 @@
+ project.IconFactory.Icons.Add (icon);
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+- project.Modified = true;
++// project.Modified = true;
+ }
+ }
+ }
+@@ -153,7 +153,7 @@
+ if (md.Run () == (int) Gtk.ResponseType.Yes) {
+ project.IconFactory.Icons.Remove (icon);
+ customIconList.Refresh ();
+- project.Modified = true;
++// project.Modified = true;
+ }
+ md.Destroy ();
+ }
+@@ -170,7 +170,7 @@
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+- project.Modified = true;
++// project.Modified = true;
+ }
+ }
+ }
+Index: libstetic/editor/ActionMenuBar.cs
+===================================================================
+--- libstetic/editor/ActionMenuBar.cs (revision 17)
++++ libstetic/editor/ActionMenuBar.cs (working copy)
+@@ -258,7 +258,9 @@
+ {
+ Widget wrapper = Widget.Lookup (this);
+ using (wrapper.UndoManager.AtomicChange) {
+- Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project, new Gtk.Action ("", "", null, null));
++ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project,
++ new Gtk.Action ("", "", null, null),
++ wrapper);
+ ActionTreeNode node = new ActionTreeNode (Gtk.UIManagerItemType.Menu, "", ac);
+ actionTree.Children.Insert (pos, node);
+
+Index: libstetic/editor/ActionMenu.cs
+===================================================================
+--- libstetic/editor/ActionMenu.cs (revision 17)
++++ libstetic/editor/ActionMenu.cs (working copy)
+@@ -196,7 +196,9 @@
+ ActionTreeNode InsertAction (int pos)
+ {
+ using (wrapper.UndoManager.AtomicChange) {
+- Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project, new Gtk.Action ("", "", null, null));
++ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project,
++ new Gtk.Action ("", "", null, null),
++ wrapper);
+ ActionTreeNode newNode = new ActionTreeNode (Gtk.UIManagerItemType.Menuitem, null, ac);
+ nodes.Insert (pos, newNode);
+ ActionMenuItem item = FindMenuItem (newNode);
+Index: libstetic/editor/SelectImageDialog.cs
+===================================================================
+--- libstetic/editor/SelectImageDialog.cs (revision 17)
++++ libstetic/editor/SelectImageDialog.cs (working copy)
+@@ -80,7 +80,7 @@
+ FillResources ();
+ resourceList.Selection.Changed += OnResourceSelectionChanged;
+
+- if (project.FileName != null)
++ if (project.FolderName != null)
+ fileChooser.SetCurrentFolder (project.ImagesRootPath);
+
+ fileChooser.SelectionChanged += delegate (object s, EventArgs a) {
+Index: libstetic/editor/ActionToolbar.cs
+===================================================================
+--- libstetic/editor/ActionToolbar.cs (revision 17)
++++ libstetic/editor/ActionToolbar.cs (working copy)
+@@ -237,7 +237,9 @@
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ using (wrapper.UndoManager.AtomicChange) {
+- Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project, new Gtk.Action ("", "", null, null));
++ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project,
++ new Gtk.Action ("", "", null, null),
++ wrapper);
+ ActionTreeNode node = new ActionTreeNode (Gtk.UIManagerItemType.Toolitem, "", ac);
+ actionTree.Children.Insert (pos, node);
+
+Index: libstetic/editor/ActionGroupEditor.cs
+===================================================================
+--- libstetic/editor/ActionGroupEditor.cs (revision 17)
++++ libstetic/editor/ActionGroupEditor.cs (working copy)
+@@ -275,7 +275,9 @@
+
+ void OnAddClicked (object s, Gtk.ButtonPressEventArgs args)
+ {
+- Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (project, new Gtk.Action ("", "", null, null));
++ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (project,
++ new Gtk.Action ("", "", null, null),
++ ActionGroup);
+ ActionMenuItem item = InsertAction (ac, actionGroup.Actions.Count);
+ item.EditingDone += OnEditDone;
+ item.Select ();
+Index: libstetic/ChangeLog
+===================================================================
+--- libstetic/ChangeLog (revision 17)
++++ libstetic/ChangeLog (working copy)
+@@ -1,3 +1,40 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * DND.cs:
++ * IProject.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GeneratorContext.cs:
++
++2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * IProject.cs: Remove Modified property, add WasModified method which check state of a given top level
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GladeUtils.cs: Set ObjectWrapper.RootWrapperName when reading from xml
++ * WidgetUtils.cs:
++ * ObjectReader.cs:
++ * ObjectWrapper.cs:
++ * wrapper/Frame.cs:
++ * wrapper/Window.cs:
++ * wrapper/MenuItem.cs:
++ * wrapper/Expander.cs:
++ * undo/UndoManager.cs:
++ * wrapper/Notebook.cs:
++ * wrapper/Container.cs:
++ * wrapper/OptionMenu.cs:
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ObjectWrapper.cs: Save a root wrapper name
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * IProject.cs:
++ * ErrorWidget.cs:
++
+ 2010-04-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * editor/ActionMenu.cs: Explicit destroy of children should
+Index: libstetic/GeneratorContext.cs
+===================================================================
+--- libstetic/GeneratorContext.cs (revision 17)
++++ libstetic/GeneratorContext.cs (working copy)
+@@ -522,11 +522,6 @@
+ set { gettextClass = value; }
+ }
+
+- public bool UsePartialClasses {
+- get { return partialClasses; }
+- set { partialClasses = value; }
+- }
+-
+ public string Path {
+ get { return path; }
+ set { path = value; }
+@@ -537,11 +532,6 @@
+ set { generateEmptyBuildMethod = value; }
+ }
+
+- public bool GenerateSingleFile {
+- get { return generateSingleFile; }
+- set { generateSingleFile = value; }
+- }
+-
+ public string GlobalNamespace {
+ get { return globalNamespace; }
+ set { globalNamespace = value; }
+Index: libstetic/DND.cs
+===================================================================
+--- libstetic/DND.cs (revision 17)
++++ libstetic/DND.cs (working copy)
+@@ -181,7 +181,7 @@
+
+ if (targetWrapper.IsDisposed) {
+ // The project has been reloaded. Find the wrapper again.
+- Gtk.Widget twidget = project.GetTopLevel (tname);
++ Gtk.Widget twidget = project.GetWidget (tname);
+ ObjectWrapper ow = ObjectWrapper.Lookup (twidget);
+ if (ow != null)
+ targetWrapper = ow.FindObjectByUndoId (uid);
+Index: libstetic/ObjectReader.cs
+===================================================================
+--- libstetic/ObjectReader.cs (revision 17)
++++ libstetic/ObjectReader.cs (working copy)
+@@ -25,14 +25,14 @@
+ get { return proj; }
+ }
+
+- public virtual ObjectWrapper ReadObject (XmlElement elem)
++ public virtual ObjectWrapper ReadObject (XmlElement elem, ObjectWrapper root)
+ {
+- return Stetic.ObjectWrapper.ReadObject (this, elem);
++ return Stetic.ObjectWrapper.ReadObject (this, elem, root);
+ }
+
+- public virtual void ReadObject (ObjectWrapper wrapper, XmlElement elem)
++ public virtual void ReadExistingObject (ObjectWrapper wrapper, XmlElement elem)
+ {
+- Stetic.ObjectWrapper.ReadObject (this, elem, wrapper);
++ Stetic.ObjectWrapper.ReadExistingObject (this, elem, wrapper);
+ }
+ }
+ }
+Index: libstetic/undo/UndoManager.cs
+===================================================================
+--- libstetic/undo/UndoManager.cs (revision 17)
++++ libstetic/undo/UndoManager.cs (working copy)
+@@ -227,17 +227,17 @@
+ this.undoManager = undoManager;
+ }
+
+- public override ObjectWrapper ReadObject (XmlElement elem)
++ public override ObjectWrapper ReadObject (XmlElement elem, ObjectWrapper root)
+ {
+- ObjectWrapper ww = base.ReadObject (elem);
++ ObjectWrapper ww = base.ReadObject (elem, root);
+ if (ww is Widget)
+ undoManager.RegisterObject ((Widget)ww, elem);
+ return ww;
+ }
+
+- public override void ReadObject (ObjectWrapper wrapper, XmlElement elem)
++ public override void ReadExistingObject (ObjectWrapper wrapper, XmlElement elem)
+ {
+- base.ReadObject (wrapper, elem);
++ base.ReadExistingObject (wrapper, elem);
+ if (wrapper is Widget)
+ undoManager.RegisterObject ((Widget)wrapper, elem);
+ }
+Index: libstetic/ObjectWrapper.cs
+===================================================================
+--- libstetic/ObjectWrapper.cs (revision 17)
++++ libstetic/ObjectWrapper.cs (working copy)
+@@ -149,10 +149,13 @@
+ get { return disposed; }
+ }
+
+- public static ObjectWrapper Create (IProject proj, object wrapped)
++ public static ObjectWrapper Create (IProject proj, object wrapped, ObjectWrapper root)
+ {
+ ClassDescriptor klass = Registry.LookupClassByName (wrapped.GetType ().FullName);
+ ObjectWrapper wrapper = klass.CreateWrapper ();
++ if (root != null) {
++ wrapper.RootWrapperName = (root.RootWrapperName != null) ? root.RootWrapperName : root.Name;
++ }
+ wrapper.Loading = true;
+ wrapper.proj = proj;
+ wrapper.classDescriptor = klass;
+@@ -180,7 +183,7 @@
+ throw new System.NotImplementedException ();
+ }
+
+- public static ObjectWrapper ReadObject (ObjectReader reader, XmlElement elem)
++ public static ObjectWrapper ReadObject (ObjectReader reader, XmlElement elem, ObjectWrapper root)
+ {
+ string className = elem.GetAttribute ("class");
+ ClassDescriptor klass;
+@@ -191,24 +194,29 @@
+
+ if (klass == null) {
+ ErrorWidget we = new ErrorWidget (className, elem.GetAttribute ("id"));
+- ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we);
++ ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we, null);
+ wrap.Read (reader, elem);
+ return wrap;
+ }
+ if (!klass.SupportsGtkVersion (reader.Project.TargetGtkVersion)) {
+ ErrorWidget we = new ErrorWidget (className, klass.TargetGtkVersion, reader.Project.TargetGtkVersion, elem.GetAttribute ("id"));
+- ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we);
++ ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we, null);
+ wrap.Read (reader, elem);
+ return wrap;
+ }
+
+ ObjectWrapper wrapper = klass.CreateWrapper ();
++ if (root != null) {
++ if (root.RootWrapperName != null) {
++ wrapper.RootWrapperName = root.RootWrapperName;
++ }
++ }
+ wrapper.classDescriptor = klass;
+ wrapper.proj = reader.Project;
+- return ReadObject (reader, elem, wrapper);
++ return ReadExistingObject (reader, elem, wrapper);
+ }
+
+- public static ObjectWrapper ReadObject (ObjectReader reader, XmlElement elem, ObjectWrapper wrapper)
++ public static ObjectWrapper ReadExistingObject (ObjectReader reader, XmlElement elem, ObjectWrapper wrapper)
+ {
+ try {
+ wrapper.OnBeginRead (reader.Format);
+@@ -218,7 +226,7 @@
+ catch (Exception ex) {
+ Console.WriteLine (ex);
+ ErrorWidget we = new ErrorWidget (ex, elem.GetAttribute ("id"));
+- ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we);
++ ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we, null);
+ wrap.Read (reader, elem);
+ return wrap;
+ }
+@@ -329,6 +337,10 @@
+ OnObjectChanged (new ObjectWrapperEventArgs (this));
+ }
+
++ public abstract string Name { get; set; }
++
++ public string RootWrapperName { get; protected set; }
++
+ static object GetIndentityObject (object ob)
+ {
+ if (ob is Gtk.Container.ContainerChild) {
+Index: libstetic/wrapper/ChangeLog
+===================================================================
+--- libstetic/wrapper/ChangeLog (revision 0)
++++ libstetic/wrapper/ChangeLog (revision 107)
+@@ -0,0 +1,12 @@
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Frame.cs: Pass root wrapper as an argument for ObjectWrapper.Create
++ * Action.cs:
++ * Window.cs:
++ * Button.cs:
++ * Widget.cs:
++ * Expander.cs:
++ * Container.cs:
++ * ActionGroup.cs:
++ * ScrolledWindow.cs:
++
+Index: libstetic/wrapper/Button.cs
+===================================================================
+--- libstetic/wrapper/Button.cs (revision 17)
++++ libstetic/wrapper/Button.cs (working copy)
+@@ -208,11 +208,12 @@
+ Gtk.Alignment alignment = new Gtk.Alignment (button.Xalign, button.Yalign, 0.0f, 0.0f);
+ alignment.Add (box);
+
+- Widget wrapper = (Widget)ObjectWrapper.Create (proj, labelWidget);
++ ObjectWrapper buttonWrapper = ObjectWrapper.Lookup (this);
++ Widget wrapper = (Widget)ObjectWrapper.Create (proj, labelWidget, buttonWrapper);
+ wrapper.Unselectable = true;
+- wrapper = (Widget)ObjectWrapper.Create (proj, box);
++ wrapper = (Widget)ObjectWrapper.Create (proj, box, buttonWrapper);
+ wrapper.Unselectable = true;
+- wrapper = (Widget)ObjectWrapper.Create (proj, alignment);
++ wrapper = (Widget)ObjectWrapper.Create (proj, alignment, buttonWrapper);
+ wrapper.Unselectable = true;
+
+ alignment.ShowAll ();
+Index: libstetic/wrapper/Action.cs
+===================================================================
+--- libstetic/wrapper/Action.cs (revision 17)
++++ libstetic/wrapper/Action.cs (working copy)
+@@ -43,7 +43,7 @@
+ get { return (Gtk.Action) Wrapped; }
+ }
+
+- public string Name {
++ public override string Name {
+ get {
+ if (name == null || name.Length == 0) {
+ name = nameRoot = oldDefaultName = GetDefaultName ();
+@@ -250,7 +250,7 @@
+
+ public Action Clone ()
+ {
+- Action a = (Action) ObjectWrapper.Create (Project, new Gtk.Action ("", ""));
++ Action a = (Action) ObjectWrapper.Create (Project, new Gtk.Action ("", ""), this);
+ a.CopyFrom (this);
+ return a;
+ }
+Index: libstetic/wrapper/Container.cs
+===================================================================
+--- libstetic/wrapper/Container.cs (revision 17)
++++ libstetic/wrapper/Container.cs (working copy)
+@@ -41,7 +41,7 @@
+ Gtk.Widget child = prop.GetValue (container) as Gtk.Widget;
+ if (child == null)
+ continue;
+- Widget wrapper = ObjectWrapper.Create (proj, child) as Stetic.Wrapper.Widget;
++ Widget wrapper = ObjectWrapper.Create (proj, child, this) as Stetic.Wrapper.Widget;
+ wrapper.InternalChildProperty = prop;
+ if (child.Name == ((GLib.GType)child.GetType ()).ToString ())
+ child.Name = container.Name + "_" + prop.Name;
+@@ -361,7 +361,7 @@
+
+ protected virtual ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+- ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"]);
++ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ Container.ContainerChild childwrapper = null;
+
+ try {
+@@ -414,7 +414,7 @@
+ Gtk.Widget child = prop.GetValue (container) as Gtk.Widget;
+ Widget wrapper = Widget.Lookup (child);
+ if (wrapper != null) {
+- reader.ReadObject (wrapper, child_elem["widget"]);
++ reader.ReadExistingObject (wrapper, child_elem["widget"]);
+ if (reader.Format == FileFormat.Glade)
+ GladeUtils.SetPacking (ChildWrapper (wrapper), child_elem);
+ else
+@@ -770,7 +770,7 @@
+ if (cwrap != null)
+ return cwrap;
+ else
+- return Stetic.ObjectWrapper.Create (parentWrapper.proj, cc) as ContainerChild;
++ return Stetic.ObjectWrapper.Create (parentWrapper.proj, cc, parentWrapper) as ContainerChild;
+ }
+
+ protected Gtk.Container.ContainerChild ContextChildProps (Gtk.Widget context)
+@@ -1449,6 +1449,8 @@
+ EmitNotify ("AutoSize");
+ }
+ }
++
++ public override string Name { get; set; }
+ }
+ }
+ }
+Index: libstetic/wrapper/Widget.cs
+===================================================================
+--- libstetic/wrapper/Widget.cs (revision 17)
++++ libstetic/wrapper/Widget.cs (working copy)
+@@ -241,7 +241,7 @@
+ Wrapped.Name = name;
+ }
+
+- public string Name {
++ public override string Name {
+ get { return Wrapped.Name; }
+ set { Wrapped.Name = value; EmitNotify ("Name"); }
+ }
+@@ -806,7 +806,7 @@
+ Gtk.ScrolledWindow scw = new Gtk.ScrolledWindow ();
+ scw.HscrollbarPolicy = scw.VscrollbarPolicy = Gtk.PolicyType.Automatic;
+ scw.ShadowType = Gtk.ShadowType.In;
+- ScrolledWindow wrapper = (ScrolledWindow) ObjectWrapper.Create (Project, scw);
++ ScrolledWindow wrapper = (ScrolledWindow) ObjectWrapper.Create (Project, scw, ParentWrapper);
+ ParentWrapper.ReplaceChild (Wrapped, scw, false);
+ if (Wrapped.SetScrollAdjustments (null, null))
+ scw.Add (Wrapped);
+Index: libstetic/wrapper/Frame.cs
+===================================================================
+--- libstetic/wrapper/Frame.cs (revision 17)
++++ libstetic/wrapper/Frame.cs (working copy)
+@@ -17,21 +17,21 @@
+ if (AllowPlaceholders) {
+ Gtk.Alignment align = new Gtk.Alignment (0, 0, 1, 1);
+ align.LeftPadding = 12;
+- Container align_wrapper = (Container)ObjectWrapper.Create (proj, align);
++ Container align_wrapper = (Container)ObjectWrapper.Create (proj, align, this);
+ align_wrapper.AddPlaceholder ();
+ ReplaceChild (frame.Child, (Gtk.Widget)align_wrapper.Wrapped, true);
+ }
+ }
+
+ if (frame.LabelWidget != null)
+- ObjectWrapper.Create (proj, frame.LabelWidget);
++ ObjectWrapper.Create (proj, frame.LabelWidget, this);
+ frame.AddNotification ("label-widget", LabelWidgetChanged);
+ }
+
+ void LabelWidgetChanged (object obj, GLib.NotifyArgs args)
+ {
+ if (!IsDisposed && frame.LabelWidget != null && !(frame.LabelWidget is Stetic.Placeholder))
+- ObjectWrapper.Create (proj, frame.LabelWidget);
++ ObjectWrapper.Create (proj, frame.LabelWidget, this);
+ }
+
+ Gtk.Frame frame {
+@@ -43,7 +43,7 @@
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if ((string)GladeUtils.GetChildProperty (child_elem, "type", "") == "label_item") {
+- ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"]);
++ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ frame.LabelWidget = (Gtk.Widget)wrapper.Wrapped;
+ return wrapper;
+ } else
+Index: libstetic/wrapper/ActionGroup.cs
+===================================================================
+--- libstetic/wrapper/ActionGroup.cs (revision 17)
++++ libstetic/wrapper/ActionGroup.cs (working copy)
+@@ -39,7 +39,7 @@
+ get { return actions; }
+ }
+
+- public string Name {
++ public override string Name {
+ get { return name; }
+ set {
+ name = value;
+Index: libstetic/wrapper/OptionMenu.cs
+===================================================================
+--- libstetic/wrapper/OptionMenu.cs (revision 17)
++++ libstetic/wrapper/OptionMenu.cs (working copy)
+@@ -50,7 +50,7 @@
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (optionmenu.Menu);
+- reader.ReadObject (wrapper, child_elem["widget"]);
++ reader.ReadExistingObject (wrapper, child_elem["widget"]);
+ return wrapper;
+ }
+
+Index: libstetic/wrapper/ScrolledWindow.cs
+===================================================================
+--- libstetic/wrapper/ScrolledWindow.cs (revision 17)
++++ libstetic/wrapper/ScrolledWindow.cs (working copy)
+@@ -55,7 +55,7 @@
+ internal void AddWithViewport (Gtk.Widget child)
+ {
+ Gtk.Viewport viewport = new Gtk.Viewport (scrolled.Hadjustment, scrolled.Vadjustment);
+- ObjectWrapper.Create (proj, viewport);
++ ObjectWrapper.Create (proj, viewport, this);
+ viewport.ShadowType = Gtk.ShadowType.None;
+ viewport.Add (child);
+ viewport.Show ();
+Index: libstetic/wrapper/Window.cs
+===================================================================
+--- libstetic/wrapper/Window.cs (revision 17)
++++ libstetic/wrapper/Window.cs (working copy)
+@@ -10,7 +10,9 @@
+ public override void Wrap (object obj, bool initialized)
+ {
+ TopLevelWindow window = (TopLevelWindow) obj;
++ RootWrapperName = window.Name;
+
++ //during Wrap RootWrapperName will be set in the children widgets
+ base.Wrap (obj, initialized);
+
+ if (!initialized) {
+Index: libstetic/wrapper/Notebook.cs
+===================================================================
+--- libstetic/wrapper/Notebook.cs (revision 17)
++++ libstetic/wrapper/Notebook.cs (working copy)
+@@ -31,7 +31,7 @@
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if ((string)GladeUtils.GetChildProperty (child_elem, "type", "") == "tab") {
+- ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"]);
++ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ Gtk.Widget widget = (Gtk.Widget)wrapper.Wrapped;
+ notebook.SetTabLabel (notebook.GetNthPage (notebook.NPages - 1), widget);
+ tabs.Add (widget);
+Index: libstetic/wrapper/MenuItem.cs
+===================================================================
+--- libstetic/wrapper/MenuItem.cs (revision 17)
++++ libstetic/wrapper/MenuItem.cs (working copy)
+@@ -18,7 +18,7 @@
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+- ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"]);
++ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ menuitem.Submenu = (Gtk.Menu)wrapper.Wrapped;
+ return wrapper;
+ }
+Index: libstetic/wrapper/objects.xml
+===================================================================
+--- libstetic/wrapper/objects.xml (revision 17)
++++ libstetic/wrapper/objects.xml (working copy)
+@@ -104,17 +104,17 @@
+ <!-- "events" property has extra spaces around "|"s -->
+ <import>
+ <xsl:template match="widget/property[@name='events']/text()">
+- <xsl:call-template name="GtkWidget_fixevents">
++ <xsl:call-template name="GtkWidget_fixevents2">
+ <xsl:with-param name="string" select="." />
+ </xsl:call-template>
+ </xsl:template>
+- <xsl:template name="GtkWidget_fixevents">
++ <xsl:template name="GtkWidget_fixevents2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, ' | ')">
+ <xsl:value-of select="substring-before($string, ' | ')"/>
+ <xsl:text>|</xsl:text>
+- <xsl:call-template name="GtkWidget_fixevents">
++ <xsl:call-template name="GtkWidget_fixevents2">
+ <xsl:with-param name="string" select="substring-after($string, ' | ')"/>
+ </xsl:call-template>
+ </xsl:when>
+@@ -126,17 +126,17 @@
+ </import>
+ <export>
+ <xsl:template match="widget/property[@name='events']/text()">
+- <xsl:call-template name="GtkWidget_breakevents">
++ <xsl:call-template name="GtkWidget_breakevents2">
+ <xsl:with-param name="string" select="." />
+ </xsl:call-template>
+ </xsl:template>
+- <xsl:template name="GtkWidget_breakevents">
++ <xsl:template name="GtkWidget_breakevents2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '|')">
+ <xsl:value-of select="substring-before($string, '|')"/>
+ <xsl:text> | </xsl:text>
+- <xsl:call-template name="GtkWidget_breakevents">
++ <xsl:call-template name="GtkWidget_breakevents2">
+ <xsl:with-param name="string" select="substring-after($string, '|')"/>
+ </xsl:call-template>
+ </xsl:when>
+@@ -1316,19 +1316,19 @@
+ <!-- Child packing options are non-standard ("expand" instead of "GTK_EXPAND") -->
+ <import>
+ <xsl:template match="widget[@class='GtkTable']/child/packing/property[@name='x_options' or @name='y_options']/text()">
+- <xsl:call-template name="GtkTable_fixoptions">
++ <xsl:call-template name="GtkTable_fixoptions2">
+ <xsl:with-param name="string" select="." />
+ </xsl:call-template>
+ </xsl:template>
+- <xsl:template name="GtkTable_fixoptions">
++ <xsl:template name="GtkTable_fixoptions2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '|')">
+- <xsl:call-template name="GtkTable_fixoptions">
++ <xsl:call-template name="GtkTable_fixoptions2">
+ <xsl:with-param name="string" select="substring-before($string, '|')"/>
+ </xsl:call-template>
+ <xsl:text>|</xsl:text>
+- <xsl:call-template name="GtkTable_fixoptions">
++ <xsl:call-template name="GtkTable_fixoptions2">
+ <xsl:with-param name="string" select="substring-after($string, '|')"/>
+ </xsl:call-template>
+ </xsl:when>
+@@ -1341,19 +1341,19 @@
+ </import>
+ <export>
+ <xsl:template match="widget[@class='GtkTable']/child/packing/property[@name='x_options' or @name='y_options']/text()">
+- <xsl:call-template name="GtkTable_breakoptions">
++ <xsl:call-template name="GtkTable_breakoptions2">
+ <xsl:with-param name="options" select="." />
+ </xsl:call-template>
+ </xsl:template>
+- <xsl:template name="GtkTable_breakoptions">
++ <xsl:template name="GtkTable_breakoptions2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '|')">
+- <xsl:call-template name="GtkTable_breakoptions">
++ <xsl:call-template name="GtkTable_breakoptions2">
+ <xsl:with-param name="string" select="substring-before($string, '|')"/>
+ </xsl:call-template>
+ <xsl:text>|</xsl:text>
+- <xsl:call-template name="GtkTable_breakoptions">
++ <xsl:call-template name="GtkTable_breakoptions2">
+ <xsl:with-param name="string" select="substring-after($string, '|')"/>
+ </xsl:call-template>
+ </xsl:when>
+Index: libstetic/wrapper/Expander.cs
+===================================================================
+--- libstetic/wrapper/Expander.cs (revision 17)
++++ libstetic/wrapper/Expander.cs (working copy)
+@@ -21,13 +21,13 @@
+ AddPlaceholder ();
+ }
+ if (expander.LabelWidget != null)
+- ObjectWrapper.Create (proj, expander.LabelWidget);
++ ObjectWrapper.Create (proj, expander.LabelWidget, this);
+ }
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if ((string)GladeUtils.GetChildProperty (child_elem, "type", "") == "label_item") {
+- ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"]);
++ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ expander.LabelWidget = (Gtk.Widget)wrapper.Wrapped;
+ return wrapper;
+ } else
+Index: libstetic/GladeUtils.cs
+===================================================================
+--- libstetic/GladeUtils.cs (revision 17)
++++ libstetic/GladeUtils.cs (working copy)
+@@ -104,31 +104,31 @@
+ return doc;
+ }
+
+- public static Stetic.Wrapper.Widget Import (IProject project, XmlDocument doc)
+- {
+- try {
+- doc = XslImportTransform (doc);
+- } catch {
+- return null;
+- }
+-
+- ObjectReader reader = new ObjectReader (project, FileFormat.Glade);
+-
+- XmlElement elem = (XmlElement)doc.SelectSingleNode ("glade-interface/widget");
+- if (elem.GetAttribute ("class") != "GtkWindow" ||
+- elem.GetAttribute ("id") != "glade-dummy-container") {
+- // Creating a new toplevel
+- Stetic.Wrapper.Widget toplevel = (Stetic.Wrapper.Widget)
+- Stetic.ObjectWrapper.ReadObject (reader, elem);
+- if (toplevel != null) {
+- project.AddWindow ((Gtk.Window)toplevel.Wrapped);
+- }
+- return toplevel;
+- }
+-
+- return (Stetic.Wrapper.Widget)
+- Stetic.ObjectWrapper.ReadObject (reader, (XmlElement)elem.SelectSingleNode ("child/widget"));
+- }
++// public static Stetic.Wrapper.Widget Import (IProject project, XmlDocument doc)
++// {
++// try {
++// doc = XslImportTransform (doc);
++// } catch {
++// return null;
++// }
++//
++// ObjectReader reader = new ObjectReader (project, FileFormat.Glade);
++//
++// XmlElement elem = (XmlElement)doc.SelectSingleNode ("glade-interface/widget");
++// if (elem.GetAttribute ("class") != "GtkWindow" ||
++// elem.GetAttribute ("id") != "glade-dummy-container") {
++// // Creating a new toplevel
++// Stetic.Wrapper.Widget toplevel = (Stetic.Wrapper.Widget)
++// Stetic.ObjectWrapper.ReadObject (reader, elem);
++// if (toplevel != null) {
++// project.AddWindow ((Gtk.Window)toplevel.Wrapped);
++// }
++// return toplevel;
++// }
++//
++// return (Stetic.Wrapper.Widget)
++// Stetic.ObjectWrapper.ReadObject (reader, (XmlElement)elem.SelectSingleNode ("child/widget"));
++// }
+
+ public static void Copy (Gtk.Widget widget, Gtk.SelectionData seldata, bool copyAsText)
+ {
+@@ -142,23 +142,23 @@
+ seldata.Set (ApplicationXGladeAtom, 8, System.Text.Encoding.UTF8.GetBytes (doc.OuterXml));
+ }
+
+- public static Stetic.Wrapper.Widget Paste (IProject project, Gtk.SelectionData seldata)
+- {
+- if (seldata.Type != ApplicationXGladeAtom)
+- return null;
+- string data = System.Text.Encoding.UTF8.GetString (seldata.Data);
++// public static Stetic.Wrapper.Widget Paste (IProject project, Gtk.SelectionData seldata)
++// {
++// if (seldata.Type != ApplicationXGladeAtom)
++// return null;
++// string data = System.Text.Encoding.UTF8.GetString (seldata.Data);
++//
++// XmlDocument doc = new XmlDocument ();
++// doc.PreserveWhitespace = true;
++// try {
++// doc.LoadXml (data);
++// } catch {
++// return null;
++// }
++//
++// return Import (project, doc);
++// }
+
+- XmlDocument doc = new XmlDocument ();
+- doc.PreserveWhitespace = true;
+- try {
+- doc.LoadXml (data);
+- } catch {
+- return null;
+- }
+-
+- return Import (project, doc);
+- }
+-
+ static object GetProperty (XmlElement elem, string selector, object defaultValue, bool extract)
+ {
+ XmlElement prop = (XmlElement)elem.SelectSingleNode (selector);
+Index: libstetic/ErrorWidget.cs
+===================================================================
+--- libstetic/ErrorWidget.cs (revision 17)
++++ libstetic/ErrorWidget.cs (working copy)
+@@ -96,9 +96,9 @@
+ ErrorWidget ew = (ErrorWidget) Wrapped;
+ string msg;
+ if (ew.Exception != null)
+- msg = Project.FileName + ": Could not generate code for an invalid widget. The widget failed to load: " + ew.Exception.Message + ". The generated code may be invalid.";
++ msg = Project.FolderName + ": Could not generate code for an invalid widget. The widget failed to load: " + ew.Exception.Message + ". The generated code may be invalid.";
+ else
+- msg = Project.FileName + ": Could not generate code for widgets of type: " + ew.ClassName + ". The widget could not be found in any referenced library. The generated code may be invalid.";
++ msg = Project.FolderName + ": Could not generate code for widgets of type: " + ew.ClassName + ". The widget could not be found in any referenced library. The generated code may be invalid.";
+
+ if (ctx.Options.FailForUnknownWidgets) {
+ throw new InvalidOperationException (msg);
+Index: libstetic/WidgetUtils.cs
+===================================================================
+--- libstetic/WidgetUtils.cs (revision 17)
++++ libstetic/WidgetUtils.cs (working copy)
+@@ -37,7 +37,7 @@
+ public static Gtk.Widget ImportWidget (IProject project, XmlElement element)
+ {
+ ObjectReader reader = new ObjectReader (project, FileFormat.Native);
+- ObjectWrapper wrapper = Stetic.ObjectWrapper.ReadObject (reader, element);
++ ObjectWrapper wrapper = Stetic.ObjectWrapper.ReadObject (reader, element, null);
+ return wrapper.Wrapped as Gtk.Widget;
+ }
+
+@@ -126,11 +126,14 @@
+ Gtk.Widget widget = (Gtk.Widget) wrapper.Wrapped;
+ if (widget == null) {
+ widget = (Gtk.Widget) klass.CreateInstance (wrapper.Project);
++ //set name before binding to ensure
++ //that ObjectWrapper.RootWrapperName will be valid
++ widget.Name = elem.GetAttribute ("id");
+ ObjectWrapper.Bind (wrapper.Project, klass, wrapper, widget, true);
++ } else {
++ widget.Name = elem.GetAttribute ("id");
+ }
+
+- widget.Name = elem.GetAttribute ("id");
+-
+ ReadMembers (klass, wrapper, widget, elem);
+
+ if (!(widget is Gtk.Window))
+Index: MonoDevelop.GtkCore.Commands/GladeCommands.cs
+===================================================================
+--- MonoDevelop.GtkCore.Commands/GladeCommands.cs (revision 17)
++++ MonoDevelop.GtkCore.Commands/GladeCommands.cs (working copy)
+@@ -36,6 +36,7 @@
+ AddNewActionGroup,
+ ImportGladeFile,
+ EditIcons,
+- GtkSettings
++ GtkSettings,
++ GenerateCode
+ }
+ }
+Index: MonoDevelop.GtkCore.Commands/ChangeLog
+===================================================================
+--- MonoDevelop.GtkCore.Commands/ChangeLog (revision 0)
++++ MonoDevelop.GtkCore.Commands/ChangeLog (revision 124)
+@@ -0,0 +1,4 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GladeCommands.cs:
++
+Index: MonoDevelop.GtkCore/GtkDesignInfo.cs
+===================================================================
+--- MonoDevelop.GtkCore/GtkDesignInfo.cs (revision 17)
++++ MonoDevelop.GtkCore/GtkDesignInfo.cs (working copy)
+@@ -29,6 +29,8 @@
+
+ using System;
+ using System.IO;
++using System.CodeDom;
++using System.CodeDom.Compiler;
+ using System.Collections.Generic;
+ using System.Collections.Specialized;
+
+@@ -51,13 +53,23 @@
+ IDotNetLanguageBinding binding;
+ ProjectResourceProvider resourceProvider;
+ ReferenceManager referenceManager;
++ string langExtension;
+
+- [ItemProperty (DefaultValue=true)]
++ [ItemProperty (DefaultValue = true)]
+ bool generateGettext = true;
+
+- [ItemProperty (DefaultValue="Mono.Unix.Catalog")]
++ [ItemProperty (DefaultValue = "Mono.Unix.Catalog")]
+ string gettextClass = "Mono.Unix.Catalog";
+
++ [ItemProperty (DefaultValue = "Stetic")]
++ string steticFolderName = "Stetic";
++
++ [ItemProperty (DefaultValue = false)]
++ bool wasConverted;
++
++ [ItemProperty (DefaultValue = true)]
++ bool hideGtkxFiles = true;
++
+ GtkDesignInfo ()
+ {
+ }
+@@ -85,8 +97,15 @@
+ referenceManager = null;
+ }
+ project = value;
++
+ if (project != null) {
+ binding = LanguageBindingService.GetBindingPerLanguageName (project.LanguageName) as IDotNetLanguageBinding;
++
++ CodeDomProvider provider = binding.GetCodeDomProvider ();
++ if (provider == null)
++ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
++ langExtension = "." + provider.FileExtension;
++
+ project.FileAddedToProject += OnFileEvent;
+ project.FileChangedInProject += OnFileEvent;
+ project.FileRemovedFromProject += OnFileEvent;
+@@ -120,11 +139,7 @@
+ get {
+ if (builderProject == null) {
+ if (SupportsDesigner (project)) {
+- if (!File.Exists (SteticFile)) {
+- UpdateGtkFolder ();
+- ProjectNodeBuilder.OnSupportChanged (project);
+- }
+- builderProject = new GuiBuilderProject (project, SteticFile);
++ builderProject = new GuiBuilderProject (project, SteticFolder.FullPath.FullPath);
+ } else
+ builderProject = new GuiBuilderProject (project, null);
+ }
+@@ -156,20 +171,27 @@
+ }
+ }
+
++ public bool OldVersion {
++ get { return project.IsFileInProject (SteticFile); }
++ }
++
+ FilePath ObjectsFile {
+- get { return GtkGuiFolder.Combine ("objects.xml"); }
++ get { return SteticFolder.Combine ("objects.xml"); }
+ }
+
++ [Obsolete]
+ public FilePath SteticGeneratedFile {
+- get { return GtkGuiFolder.Combine (binding.GetFileName ("generated")); }
++ get { return SteticFolder.Combine (binding.GetFileName ("generated")); }
+ }
+
++ [Obsolete]
+ public FilePath SteticFile {
+- get { return GtkGuiFolder.Combine ("gui.stetic"); }
++ get { return SteticFolder.Combine ("gui.stetic"); }
+ }
+
+- public FilePath GtkGuiFolder {
+- get { return project.BaseDirectory.Combine ("gtk-gui"); }
++ public FilePath SteticFolder {
++// get { return project.BaseDirectory.Combine ("gtk-gui"); }
++ get { return project.BaseDirectory.Combine (!wasConverted ? "gtk-gui" : steticFolderName); }
+ }
+
+ public bool GenerateGettext {
+@@ -187,13 +209,22 @@
+ set { gettextClass = value; }
+ }
+
++ public string SteticFolderName {
++ get { return steticFolderName; }
++ set { steticFolderName = value; }
++ }
++
++ public bool HideGtkxFiles {
++ get { return hideGtkxFiles; }
++ set { hideGtkxFiles = value; }
++ }
++
+ public static bool HasDesignedObjects (Project project)
+ {
+ if (project == null)
+ return false;
+
+- string stetic_file = Path.Combine (Path.Combine (project.BaseDirectory, "gtk-gui"), "gui.stetic");
+- return SupportsDesigner (project) && File.Exists (stetic_file);
++ return SupportsDesigner (project);
+ }
+
+ public static bool SupportsDesigner (Project project)
+@@ -250,7 +281,7 @@
+ bool projectModified = false;
+
+ // Remove all project files which are not in the generated list
+- foreach (ProjectFile pf in project.Files.GetFilesInPath (GtkGuiFolder)) {
++ foreach (ProjectFile pf in project.Files.GetFilesInPath (SteticFolder)) {
+ if (remaining_files.Contains (pf.FilePath))
+ continue;
+
+@@ -260,68 +291,218 @@
+ }
+
+ if (remaining_files.Count == 0)
+- FileService.DeleteDirectory (GtkGuiFolder);
++ FileService.DeleteDirectory (SteticFolder);
+
+ return projectModified;
+ }
+
++ public void ConvertGtkFolder (string guiFolderName, bool makeBackup)
++ {
++ foreach (ProjectFile pf in project.Files.GetFilesInPath (SteticFolder)) {
++ FilePath path = pf.FilePath;
++
++ if (path != SteticGeneratedFile) {
++ project.Files.Remove (path);
++
++ if (path != SteticFile)
++ FileService.DeleteFile (path.FullPath);
++ }
++ }
++
++ string oldGuiFolder = SteticFolder.FullPath;
++ string oldSteticFile = SteticFile;
++ string oldGeneratedFile = SteticGeneratedFile;
++ SteticFolderName = guiFolderName;
++ wasConverted = true;
++
++ if (!Directory.Exists (SteticFolder))
++ FileService.CreateDirectory (SteticFolder);
++
++ if (makeBackup && File.Exists (oldSteticFile)) {
++ string backupFile = SteticFolder.Combine ("old.stetic");
++ FileService.MoveFile (oldSteticFile, backupFile);
++ }
++
++ if (File.Exists (oldGeneratedFile))
++ FileService.DeleteFile (oldGeneratedFile);
++
++ FileService.DeleteDirectory (oldGuiFolder);
++ }
++
+ public bool UpdateGtkFolder ()
+ {
+ if (!SupportsDesigner (project))
+ return false;
+-
++
+ // This method synchronizes the current gtk project configuration info
+ // with the needed support files in the gtk-gui folder.
+
+- FileService.CreateDirectory (GtkGuiFolder);
++ FileService.CreateDirectory (SteticFolder);
+ bool projectModified = false;
+- bool initialGeneration = false;
+
+- if (!File.Exists (SteticFile)) {
+- initialGeneration = true;
+- StreamWriter sw = new StreamWriter (SteticFile);
+- sw.WriteLine ("<stetic-interface />");
+- sw.Close ();
+- FileService.NotifyFileChanged (SteticFile);
+- }
++ foreach (string filename in GetComponentsFiles ()) {
++ ProjectFile pf = project.AddFile (filename, BuildAction.EmbeddedResource);
++ pf.ResourceId = Path.GetFileName (filename);
++
++ string componentFile = GetComponentFileFromGtkx (filename);
+
+- if (!project.IsFileInProject (SteticFile)) {
+- ProjectFile pf = project.AddFile (SteticFile, BuildAction.EmbeddedResource);
+- pf.ResourceId = "gui.stetic";
++ if (componentFile != null && File.Exists (componentFile)) {
++ pf.DependsOn = componentFile;
++
++ string buildFile = GetBuildFileFromGtkx (filename);
++ if (buildFile != null && File.Exists (buildFile)) {
++ ProjectFile pf2 = project.AddFile (buildFile, BuildAction.Compile);
++ pf2.ResourceId = Path.GetFileName (buildFile);
++ pf2.DependsOn = componentFile;
++ }
++ }
++
+ projectModified = true;
+ }
+-
+- StringCollection files = GuiBuilderProject.GenerateFiles (GtkGuiFolder);
+- DateTime generatedTime = File.GetLastWriteTime (SteticFile).Subtract (TimeSpan.FromSeconds (2));
+-
++
++ StringCollection files = GuiBuilderProject.GenerateFiles (SteticFolder);
+ foreach (string filename in files) {
+- if (initialGeneration) {
+- // Ensure that the generation date of this file is < the date of the .stetic file
+- // In this way the code will be properly regenerated when building the project.
+- File.SetLastWriteTime (filename, generatedTime);
+- }
+ if (!project.IsFileInProject (filename)) {
+ project.AddFile (filename, BuildAction.Compile);
+ projectModified = true;
+ }
++
+ }
+-
++
+ UpdateObjectsFile ();
+- files.Add (ObjectsFile);
+- files.Add (SteticFile);
+-
+- if (CleanGtkFolder (files))
+- projectModified = true;
+-
++
+ return ReferenceManager.Update () || projectModified;
+ }
+
++// public bool UpdateGtkFolder ()
++// {
++// if (!SupportsDesigner (project))
++// return false;
++//
++// // This method synchronizes the current gtk project configuration info
++// // with the needed support files in the gtk-gui folder.
++//
++// FileService.CreateDirectory (GtkGuiFolder);
++// bool projectModified = false;
++// bool initialGeneration = false;
++//
++// if (!File.Exists (SteticFile)) {
++// initialGeneration = true;
++// StreamWriter sw = new StreamWriter (SteticFile);
++// sw.WriteLine ("<stetic-interface />");
++// sw.Close ();
++// FileService.NotifyFileChanged (SteticFile);
++// }
++//
++// if (!project.IsFileInProject (SteticFile)) {
++// ProjectFile pf = project.AddFile (SteticFile, BuildAction.EmbeddedResource);
++// pf.ResourceId = "gui.stetic";
++// projectModified = true;
++// }
++//
++// StringCollection files = GuiBuilderProject.GenerateFiles (GtkGuiFolder);
++// DateTime generatedTime = File.GetLastWriteTime (SteticFile).Subtract (TimeSpan.FromSeconds (2));
++//
++// foreach (string filename in files) {
++// if (initialGeneration) {
++// // Ensure that the generation date of this file is < the date of the .stetic file
++// // In this way the code will be properly regenerated when building the project.
++// File.SetLastWriteTime (filename, generatedTime);
++// }
++// if (!project.IsFileInProject (filename)) {
++// project.AddFile (filename, BuildAction.Compile);
++// projectModified = true;
++// }
++// }
++//
++// UpdateObjectsFile ();
++// files.Add (ObjectsFile);
++// files.Add (SteticFile);
++//
++// if (CleanGtkFolder (files))
++// projectModified = true;
++//
++// return ReferenceManager.Update () || projectModified;
++// return true;
++// }
++
++
++ public string GetComponentFile (string componentName)
++ {
++ IType type = GuiBuilderProject.FindClass (componentName);
++
++ if (type != null) {
++
++ foreach (IType part in type.Parts) {
++ string componentFile = part.CompilationUnit.FileName.FullPath.ToString ();
++// if (!componentFile.Contains (".generated"))
++// return componentFile;
++ if (componentFile.Contains (".generated"))
++ componentFile = componentFile.Replace (".generated", string.Empty);
++
++ return componentFile;
++ }
++ }
++
++ return null;
++ }
++
++ public string GetBuildFile (string componentFile)
++ {
++ if (componentFile != null) {
++ string buildFile = componentFile.Replace
++ (Path.GetExtension (SteticGeneratedFile), ".generated" + langExtension);
++ return buildFile;
++ }
++
++ return null;
++ }
++
++ public string GetBuildFileInSteticFolder (string componentName)
++ {
++ string name = string.Format ("{0}.generated{1}", componentName, langExtension);
++ string buildFile = Path.Combine (SteticFolder, name);
++
++ return buildFile;
++ }
++
++ public string GetGtkxFile (string componentFile)
++ {
++ if (componentFile != null) {
++ string gtkxFile = componentFile.Replace (langExtension, ".gtkx");
++ return gtkxFile;
++ }
++
++ return null;
++ }
++
++ public string GetComponentFileFromGtkx (string gtkxFile)
++ {
++ if (gtkxFile != null) {
++ string componentFile = gtkxFile.Replace (".gtkx", langExtension);
++ return componentFile;
++ }
++
++ return null;
++ }
++
++ public string GetBuildFileFromGtkx (string gtkxFile)
++ {
++ string buildFile = gtkxFile.Replace (".gtkx", ".generated" + langExtension);
++ return buildFile;
++ }
++
++
+ public string GetComponentFolder (string componentName)
+ {
+ IType type = GuiBuilderProject.FindClass (componentName);
+- FilePath folder = type.CompilationUnit.FileName.ParentDirectory;
+
+- return folder.FullPath.ToString ();
++ if (type != null) {
++ FilePath folder = type.CompilationUnit.FileName.ParentDirectory;
++ return folder.FullPath.ToString ();
++ }
++
++ return null;
+ }
+
+ public string[] GetComponentFolders ()
+@@ -329,17 +510,54 @@
+ List<string> folders = new List<string> ();
+ ProjectDom ctx = GuiBuilderProject.GetParserContext ();
+
+- foreach (IType type in ctx.Types) {
+- FilePath folder = type.CompilationUnit.FileName.ParentDirectory;
+- string folderName = folder.FullPath.ToString ();
++ foreach (IType type in ctx.Types)
++ foreach (IType part in type.Parts) {
++ FilePath folder = part.CompilationUnit.FileName.ParentDirectory;
++ string folderName = folder.FullPath.ToString ();
+
+- if (!folders.Contains (folderName))
+- folders.Add (folder);
++ if (!folders.Contains (folderName))
++ folders.Add (folder);
+ }
+
+ return folders.ToArray ();
+ }
++
++ public string[] GetComponentsFiles ()
++ {
++ List<string> files = new List<string> ();
++
++ foreach (string folder in GetComponentFolders ()) {
++ DirectoryInfo dir = new DirectoryInfo (folder);
++
++ foreach (FileInfo file in dir.GetFiles ())
++ if (file.Extension == ".gtkx")
++ files.Add (file.ToString ());
++ }
++
++ return files.ToArray ();
++ }
+
++ public bool HasComponentFile (string componentName)
++ {
++ return (GetComponentFile (componentName) != null);
++ }
++
++ public bool ComponentNeedsCodeGeneration (string componentName)
++ {
++ string componentFile = GetComponentFile (componentName);
++ string gtkxFile = GetGtkxFile (componentFile);
++ string buildFile = GetBuildFile (componentFile);
++ FileInfo gtkxFileInfo = File.Exists (gtkxFile) ? new FileInfo (gtkxFile) : null;
++ FileInfo buildFileInfo = File.Exists (buildFile) ? new FileInfo (buildFile) : null;
++ Console.WriteLine(gtkxFile);
++ if (gtkxFileInfo == null)
++ return false;
++ if (buildFileInfo == null)
++ //file does not exist
++ return true;
++ return gtkxFileInfo.LastWriteTime > buildFileInfo.LastWriteTime;
++ }
++
+ void UpdateObjectsFile ()
+ {
+ if (!File.Exists (ObjectsFile))
+Index: MonoDevelop.GtkCore/ChangeLog
+===================================================================
+--- MonoDevelop.GtkCore/ChangeLog (revision 0)
++++ MonoDevelop.GtkCore/ChangeLog (revision 125)
+@@ -0,0 +1,36 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * WidgetFileDescriptionTemplate.cs:
++
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GtkDesignInfo.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GtkDesignInfo.cs:
++
++2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GtkDesignInfo.cs: Add ComponentNeedsCodeGeneration method,
++
++2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
++
++ * WidgetFileDescriptionTemplate.cs: Bump Api
++
++2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GtkDesignInfo.cs: Remove gtk-gui folder after project conversion
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GtkDesignInfo.cs:
++
++2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GtkDesignInfo.cs:
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GtkDesignInfo.cs: Transition from project file name to project folder.
++
+Index: MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs
+===================================================================
+--- MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs (revision 17)
++++ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs (working copy)
+@@ -91,7 +91,7 @@
+ string fileName = fileTemplate.GetFileName (policyParent, project, language, directory, name);
+ fileTemplate.AddToProject (policyParent, project, language, directory, name);
+
+- ProjectDomService.Parse (project, fileName, null);
++ ProjectDomService.Parse (project, fileName);
+
+ DotNetProject netProject = project as DotNetProject;
+ string ns = netProject != null ? netProject.GetDefaultNamespace (fileName) : "";
+@@ -125,7 +125,8 @@
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml (content);
+
+- gproject.SteticProject.AddNewActionGroup (doc.DocumentElement);
++ Stetic.Project sproject = gproject.SteticProject;
++ sproject.AddNewActionGroup (doc.DocumentElement);
+ gproject.Save (false);
+ IdeApp.ProjectOperations.Save (project);
+ return true;
+Index: ChangeLog
+===================================================================
+--- ChangeLog (revision 17)
++++ ChangeLog (working copy)
+@@ -1,3 +1,117 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * MonoDevelop.GtkCore.addin.xml:
++
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore.addin.xml:
++
++2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore.addin.xml: Add GuiFolderBuilderNode extension
++
++2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * MonoDevelop.GtkCore2.csproj:
++
++2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
++
++ * MonoDevelop.GtkCore2.csproj:
++
++2010-07-27 Krzysztof Marecki <freefirma@gmail.com>
++
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
++ Remove autoCommit argument
++
++2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore.addin.xml:
++
++2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
++ Fixes fo better file grouping in the project pad
++
++
++2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * MonoDevelop.GtkCore2.csproj:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++ Draw action group icon
++ * gtk-gui/gui.stetic:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++
++2010-06-22 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore.addin.xml:
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
++
++
++2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * MonoDevelop.GtkCore.addin.xml:
++
++2010-06-15 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++ Changes in the project pad for displaying grouped component files
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore.addin.xml:
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
++ * MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs:
++
++
++2010-06-09 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gtk-gui/gui.stetic:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Add gtkx files to project
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gtk-gui/gui.stetic:
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
++
++2010-06-02 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * Makefile.am:
++ * MonoDevelop.GtkCore2.csproj:
++ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
++ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
++ Move generated partial class for components from gtk-gui.
++
+ 2010-04-29 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track
+Index: MonoDevelop.GtkCore.addin.xml
+===================================================================
+--- MonoDevelop.GtkCore.addin.xml (revision 17)
++++ MonoDevelop.GtkCore.addin.xml (working copy)
+@@ -1,6 +1,6 @@
+ <Addin id = "GtkCore2"
+ namespace = "MonoDevelop"
+- name = "GTK# Visual Designer 2"
++ name = "GTK# Visual Designer (experimental)"
+ author = "Lluis Sanchez Gual, Krzysztof Marecki"
+ copyright = "X11"
+ url = ""
+@@ -20,6 +20,7 @@
+ <Addin id="Core" version="2.4"/>
+ <Addin id="Ide" version="2.4"/>
+ <Addin id="DesignerSupport" version="2.4"/>
++ <Addin id="XmlEditor" version="2.4"/>
+ </Dependencies>
+
+ <ExtensionPoint path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.ActionGroup">
+@@ -43,12 +44,13 @@
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/Pads/ProjectPad">
++ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.GuiProjectFolderNodeBuilder"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectFolderNodeBuilderExtension"/>
++ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectFileNodeBuilderExtension"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectNodeBuilder"/>
+- <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.WidgetNodeBuilder"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.WindowsFolderNodeBuilder"/>
+- <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ActionGroupNodeBuilder"/>
+ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.StockIconsNodeBuilder"/>
++ <NodeBuilder class = "MonoDevelop.GtkCore.NodeBuilders.ProjectFileNodeBuilderExtension" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/FileTemplates">
+@@ -87,9 +89,13 @@
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.ImportGladeFile"
+ _label = "Import Glade file..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.EditIcons"
++ icon = "md-gtkcore-iconfactory"
+ _label = "Edit Project Icons..." />
+ <Command id = "MonoDevelop.GtkCore.GtkCommands.GtkSettings"
+- _label = "GTK# support settings..." />
++ _label = "GTK# support settings..."
++ icon = "md-gtkcore-gtk-logo"/>
++ <Command id = "MonoDevelop.GtkCore.GtkCommands.GenerateCode"
++ _label = "Generate code..."/>
+ </Category>
+ </Extension>
+
+@@ -103,16 +109,16 @@
+ </Condition>
+ </Extension>
+
+- <Extension path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.UserInterfaceFolder">
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewDialog" />
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewWindow" />
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewWidget" />
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup" />
+- <SeparatorItem />
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.EditIcons" />
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.ImportGladeFile" />
+- <SeparatorItem />
+- <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.GtkSettings" />
++ <Extension path = "/MonoDevelop/Ide/ContextMenu/ProjectPad">
++ <Condition id="ItemType" value="Project|MonoDevelop.GtkCore.NodeBuilders.GuiProjectFolder">
++ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.EditIcons" insertafter="BuildSectionEnd"/>
++ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.ImportGladeFile" />
++ <SeparatorItem/>
++ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.GtkSettings" />
++ </Condition>
++ <Condition id="ItemType" value="ProjectFile">
++ <CommandItem id = "MonoDevelop.GtkCore.GtkCommands.GenerateCode" insertafter="BuildSectionEnd"/>
++ </Condition>
+ </Extension>
+
+ <Extension path = "/MonoDevelop/GtkCore/ContextMenu/ProjectPad.Component">
+@@ -145,7 +151,8 @@
+ <Section id = "SteticOptionsPanel"
+ _label = "GTK# Settings"
+ fill="true"
+- class = "MonoDevelop.GtkCore.Dialogs.WidgetBuilderOptionPanel"/>
++ class = "MonoDevelop.GtkCore.Dialogs.WidgetBuilderOptionPanel"
++ icon = "md-gtkcore-gtk-logo"/>
+ </Condition>
+ </Extension>
+
+@@ -158,8 +165,17 @@
+ <StockIcon stockid = "md-gtkcore-dialog" resource = "dialog.png" />
+ <StockIcon stockid = "md-gtkcore-widget" resource = "widget.png" />
+ <StockIcon stockid = "md-gtkcore-actiongroup" resource = "actiongroup.png" />
++ <StockIcon stockid = "md-gtkcore-iconfactory" resource = "image-x-generic.png" />
++ <StockIcon stockid = "md-gtkcore-gtkx" resource = "gtkx.png" />
++ <StockIcon stockid = "md-gtkcore-gtk-logo" resource = "gtk-logo.png"/>
+ </Extension>
+
++ <Extension path = "/MonoDevelop/Core/MimeTypes">
++ <MimeType id="text/x-gtkx" _description="Gtk# designer file" icon="gtk-page-setup" isText="true">
++ <File pattern="*.gtkx" />
++ </MimeType>
++ </Extension>
++
+ <Extension path = "/MonoDevelop/ProjectModel/ProjectServiceExtensions">
+ <Class class = "MonoDevelop.GtkCore.GuiBuilder.GtkProjectServiceExtension" insertafter="MidStep"/>
+ </Extension>
+@@ -181,6 +197,10 @@
+ </Extension>
+
+ <Extension path = "/MonoDevelop/Ide/GlobalOptionsDialog/Preferences/Style">
+- <Panel _label = "GTK# Designer" class = "MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionPanel" />
++ <Panel _label = "GTK# Designer" class = "MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionPanel" />
+ </Extension>
++
++ <Extension path = "/MonoDevelop/XmlEditor/XmlFileExtensions">
++ <XmlFileExtension extension = ".gtkx"/>
++ </Extension>
+ </Addin>
+Index: MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs (revision 17)
++++ MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs (working copy)
+@@ -25,15 +25,15 @@
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ //
+-
+-
+ using System;
+ using MonoDevelop.Projects;
+ using MonoDevelop.Ide.Gui.Pads.ProjectPad;
+ using MonoDevelop.Components.Commands;
+ using MonoDevelop.GtkCore.GuiBuilder;
++using MonoDevelop.Ide.Gui;
+ using MonoDevelop.Ide.Gui.Components;
+ using MonoDevelop.Ide;
++using MonoDevelop.Ide.Commands;
+
+ namespace MonoDevelop.GtkCore.NodeBuilders
+ {
+@@ -41,8 +41,9 @@
+ {
+ public override bool CanBuildNode (Type dataType)
+ {
+- return typeof(ProjectFolder).IsAssignableFrom (dataType) ||
+- typeof(DotNetProject).IsAssignableFrom (dataType);
++ return typeof(ProjectFolder).IsAssignableFrom (dataType) && !(dataType is GuiProjectFolder);
++// typeof(DotNetProject).IsAssignableFrom (dataType);
++ return false;
+ }
+
+ public override Type CommandHandlerType {
+@@ -51,13 +52,13 @@
+
+ public override void GetNodeAttributes (ITreeNavigator treeNavigator, object dataObject, ref NodeAttributes attributes)
+ {
+- if (treeNavigator.Options ["ShowAllFiles"])
++ if (dataObject is GuiProjectFolder)
+ return;
+-
++
+ ProjectFolder folder = dataObject as ProjectFolder;
+ if (folder != null && folder.Project is DotNetProject) {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (folder.Project);
+- if (info.GtkGuiFolder == folder.Path)
++ if (info.SteticFolder == folder.Path)
+ attributes |= NodeAttributes.Hidden;
+ }
+ }
+@@ -74,7 +75,7 @@
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewDialog)]
+ public void UpdateAddNewDialogToProject (CommandInfo cinfo)
+ {
+- cinfo.Visible = CanAddWindow ();
++ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWindow)]
+@@ -86,7 +87,7 @@
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWindow)]
+ public void UpdateAddNewWindowToProject (CommandInfo cinfo)
+ {
+- cinfo.Visible = CanAddWindow ();
++ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWidget)]
+@@ -98,8 +99,8 @@
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewWidget)]
+ public void UpdateAddNewWidgetToProject (CommandInfo cinfo)
+ {
+- cinfo.Visible = CanAddWindow ();
+- }
++ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
++ }
+
+ [CommandHandler (MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup)]
+ public void AddNewActionGroupToProject()
+@@ -110,51 +111,20 @@
+ [CommandUpdateHandler (MonoDevelop.GtkCore.GtkCommands.AddNewActionGroup)]
+ public void UpdateAddNewActionGroupToProject(CommandInfo cinfo)
+ {
+- cinfo.Visible = CanAddWindow ();
++ cinfo.Visible = CanAddWindow () && !(CurrentNode.DataItem is GuiProjectFolder);
+ }
+
+- [CommandHandler (GtkCommands.ImportGladeFile)]
+- protected void OnImportGladeFile ()
++ public override bool CanDropMultipleNodes (object[] dataObjects, DragOperation operation, DropPosition position)
+ {
+- Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+- GuiBuilderService.ImportGladeFile (project);
++ return false;
++
++ foreach (object dataObject in dataObjects)
++ if (dataObjects is GuiProjectFolder)
++ return false;
++
++ return base.CanDropMultipleNodes (dataObjects, operation, position);
+ }
+-
+- [CommandUpdateHandler (GtkCommands.ImportGladeFile)]
+- protected void UpdateImportGladeFile (CommandInfo cinfo)
+- {
+- cinfo.Visible = CanAddWindow ();
+- }
+-
+- [CommandHandler (GtkCommands.EditIcons)]
+- protected void OnEditIcons ()
+- {
+- Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+- GuiBuilderProject gp = GtkDesignInfo.FromProject (project).GuiBuilderProject;
+- Stetic.Project sp = gp.SteticProject;
+- sp.EditIcons ();
+- gp.Save (true);
+- }
+-
+- [CommandUpdateHandler (GtkCommands.EditIcons)]
+- protected void UpdateEditIcons (CommandInfo cinfo)
+- {
+- cinfo.Visible = CanAddWindow ();
+- }
+-
+- [CommandHandler (GtkCommands.GtkSettings)]
+- protected void OnGtkSettings ()
+- {
+- Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
+- IdeApp.ProjectOperations.ShowOptions (project, "SteticOptionsPanel");
+- }
+-
+- [CommandUpdateHandler (GtkCommands.EditIcons)]
+- protected void UpdateGtkSettings (CommandInfo cinfo)
+- {
+- cinfo.Visible = CanAddWindow ();
+- }
+-
++
+ bool CanAddWindow ()
+ {
+ DotNetProject project = CurrentNode.GetParentDataItem (typeof(Project), true) as DotNetProject;
+Index: MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs (revision 17)
++++ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs (working copy)
+@@ -70,7 +70,7 @@
+ GtkDesignInfo info = GtkDesignInfo.FromProject (node.Project);
+ GuiBuilderProject gp = info.GuiBuilderProject;
+ Stetic.Project sp = gp.SteticProject;
+- sp.ImagesRootPath = FileService.AbsoluteToRelativePath (info.GtkGuiFolder, gp.Project.BaseDirectory);
++ sp.ImagesRootPath = FileService.AbsoluteToRelativePath (info.SteticFolder, gp.Project.BaseDirectory);
+ sp.ImportFileCallback = delegate (string file) {
+ return GuiBuilderService.ImportFile (gp.Project, file);
+ };
+Index: MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs (revision 0)
++++ MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs (revision 124)
+@@ -0,0 +1,144 @@
++using System;
++
++using MonoDevelop.Components.Commands;
++using MonoDevelop.GtkCore.GuiBuilder;
++using MonoDevelop.Ide;
++using MonoDevelop.Ide.Commands;
++using MonoDevelop.Ide.Gui;
++using MonoDevelop.Ide.Gui.Components;
++using MonoDevelop.Ide.Gui.Pads.ProjectPad;
++using MonoDevelop.Projects;
++using MonoDevelop.Projects.Dom;
++
++namespace MonoDevelop.GtkCore.NodeBuilders
++{
++ public class ProjectFileBuilder : ProjectFileNodeBuilder
++ {
++
++ }
++
++ public class ProjectFileNodeBuilderExtension : NodeBuilderExtension
++ {
++ public override bool CanBuildNode (Type dataType)
++ {
++ return typeof(ProjectFile).IsAssignableFrom (dataType);
++ }
++
++ public override Type CommandHandlerType {
++ get { return typeof (ComponentCommandHandler); }
++ }
++
++ public override void GetNodeAttributes (ITreeNavigator treeNavigator, object dataObject, ref NodeAttributes attributes)
++ {
++ if (treeNavigator.Options ["ShowAllFiles"])
++ return;
++
++ ProjectFile pf = (ProjectFile) dataObject;
++ GtkDesignInfo info = GtkDesignInfo.FromProject (pf.Project);
++ if (info.HideGtkxFiles && pf.FilePath.Extension == ".gtkx")
++ attributes |= NodeAttributes.Hidden;
++ }
++
++
++ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
++ {
++ ProjectFile pf = (ProjectFile) dataObject;
++
++ //do not show custom icon for generated source files
++ if (pf.DependsOn == null) {
++ GtkComponentType type = pf.GetComponentType ();
++
++ switch (type) {
++ case GtkComponentType.Dialog :
++ icon = ImageService.GetPixbuf ("md-gtkcore-dialog", Gtk.IconSize.Menu);
++ break;
++ case GtkComponentType.Widget :
++ icon = ImageService.GetPixbuf ("md-gtkcore-widget", Gtk.IconSize.Menu);
++ break;
++ case GtkComponentType.ActionGroup :
++ icon = ImageService.GetPixbuf ("md-gtkcore-actiongroup", Gtk.IconSize.Menu);
++ break;
++ case GtkComponentType.IconFactory :
++ icon = ImageService.GetPixbuf ("md-gtkcore-iconfactory", Gtk.IconSize.Menu);
++ label = "Stock icons";
++ break;
++ }
++ }
++ }
++
++ //override
++ public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
++ {
++ return base.HasChildNodes (builder, dataObject);
++ }
++ }
++
++ public class ComponentCommandHandler : NodeCommandHandler
++ {
++ /*public override void ActivateItem ()
++ {
++ ProjectFile pf = (ProjectFile) CurrentNode.DataItem;
++
++ if (pf.IsComponentFile ()) {
++ Document doc = IdeApp.Workbench.OpenDocument (pf.FilePath, true);
++
++ if (doc != null) {
++ GuiBuilderView view = doc.GetContent<GuiBuilderView> ();
++ if (view != null) {
++ GtkComponentType type = pf.GetComponentType ();
++
++ switch (type) {
++ case GtkComponentType.Dialog :
++ case GtkComponentType.Widget :
++ view.ShowDesignerView ();
++ break;
++ case GtkComponentType.ActionGroup :
++ view.ShowActionDesignerView (((Stetic.ActionGroupInfo) CurrentNode.DataItem).Name);
++ break;
++ }
++ }
++ }
++ return;
++ }
++ base.ActivateItem ();
++ }
++ */
++
++ [CommandHandler (GtkCommands.GenerateCode)]
++ protected void OnGenerateCode ()
++ {
++ ProjectFile pf = CurrentNode.DataItem as ProjectFile;
++ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++ GuiBuilderProject gproject = info.GuiBuilderProject;
++
++ gproject.GenerateCode (pf.FilePath);
++ }
++
++ [CommandUpdateHandler (GtkCommands.GenerateCode)]
++ protected void UpdateGenerateCode (CommandInfo cinfo)
++ {
++ ProjectFile pf = CurrentNode.DataItem as ProjectFile;
++
++ if (pf.DependsOn == null && pf.HasChildren)
++ cinfo.Visible = pf.IsComponentFile ();
++ else
++ cinfo.Visible = false;
++ }
++
++ [CommandUpdateHandler (EditCommands.Copy)]
++ [CommandUpdateHandler (EditCommands.Delete)]
++ [CommandUpdateHandler (EditCommands.Rename)]
++ protected void UpdateDisabledCommands (CommandInfo cinfo)
++ {
++ //disable operations for generated files in designer folder
++ cinfo.Visible = false;//(CurrentNode.GetParentDataItem (typeof (GuiProjectFolder), true) == null);
++ }
++
++ public override DragOperation CanDragNode ()
++ {
++ return DragOperation.None;
++ }
++
++ }
++}
+\ No newline at end of file
+Index: MonoDevelop.GtkCore.NodeBuilders/ChangeLog
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/ChangeLog (revision 0)
++++ MonoDevelop.GtkCore.NodeBuilders/ChangeLog (revision 125)
+@@ -0,0 +1,58 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * ProjectNodeBuilder.cs:
++ * GuiProjectFolderNodeBuilder.cs:
++
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * ProjectFileExtension.cs:
++ * GuiProjectFolderNodeBuilder.cs:
++ * ProjectFileNodeBuilderExtension.cs:
++ * ProjectFolderNodeBuilderExtension.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * ProjectNodeBuilder.cs:
++ * StockIconsNodeBuilder.cs:
++ * ProjectFileNodeBuilderExtension.cs:
++ * ProjectFolderNodeBuilderExtension.cs:
++
++2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GuiProjectFolder.cs: Put gui project folder directly below References
++ in the project pad
++ * ProjectNodeBuilder.cs:
++ * GuiProjectFolderNodeBuilder.cs:
++ * ProjectFolderNodeBuilderExtension.cs:
++
++2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectFileExtension.cs: Move cursor in entryFolder to the end.
++
++2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectFileExtension.cs: Better approach for obtaining GtkComponentType
++ * ProjectFileNodeBuilderExtension.cs:
++ * ProjectFolderNodeBuilderExtension.cs:
++
++2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectNodeBuilder.cs:
++ * ProjectFileNodeBuilderExtension.cs:
++ * ProjectFolderNodeBuilderExtension.cs:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectNodeBuilder.cs:
++ * ProjectFileNodeBuilderExtension.cs: Show ProjectConversionDialog before
++ conversion
++
++2010-06-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectNodeBuilder.cs: Convert a project file layout on open
++ * ProjectFileNodeBuilderExtension.cs: Group components files
++
++2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectFileNodeBuilderExtension.cs:
++
+Index: MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs (revision 17)
++++ MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs (working copy)
+@@ -28,14 +28,19 @@
+
+ using System;
+ using System.Collections;
++using System.IO;
+
++using Gtk;
++
+ using MonoDevelop.Projects;
+ using MonoDevelop.Core;
+ using MonoDevelop.Ide.Gui.Pads;
+ using MonoDevelop.Ide.Gui;
+ using MonoDevelop.Ide.Gui.Components;
+-
++using MonoDevelop.Ide.Gui.Pads.ProjectPad;
++using MonoDevelop.GtkCore.Dialogs;
+ using MonoDevelop.GtkCore.GuiBuilder;
++using MonoDevelop.Ide;
+
+ namespace MonoDevelop.GtkCore.NodeBuilders
+ {
+@@ -48,6 +53,12 @@
+ return typeof(DotNetProject).IsAssignableFrom (dataType);
+ }
+
++ public override Type CommandHandlerType {
++ get {
++ return typeof (GuiProjectFolderCommandHandler);
++ }
++ }
++
+ protected override void Initialize ()
+ {
+ lock (typeof (ProjectNodeBuilder))
+@@ -60,10 +71,62 @@
+ instance = null;
+ }
+
++ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
++ {
++ Project project = dataObject as Project;
++
++ if (project is DotNetProject) {
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++
++ if (info.OldVersion) {
++ ProjectConversionDialog dialog = new ProjectConversionDialog (project, info.SteticFolderName);
++
++ try
++ {
++ if (dialog.Run () == (int)ResponseType.Yes) {
++ info.GuiBuilderProject.Convert (dialog.GuiFolderName, dialog.MakeBackup);
++ IdeApp.ProjectOperations.Save (project);
++ }
++ } finally {
++ dialog.Destroy ();
++ }
++ }
++
++ project.FileAddedToProject += HandleProjectFileAddedToProject;
++ }
++ }
++
++ void HandleProjectFileAddedToProject (object sender, ProjectFileEventArgs e)
++ {
++ Project project = e.Project;
++ ProjectFile pf = e.ProjectFile;
++ string fileName = pf.FilePath.FullPath.ToString ();
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++
++ string buildFile = info.GetBuildFile (fileName);
++ if (!project.IsFileInProject(buildFile) && File.Exists (buildFile)) {
++ ProjectFile pf2 = project.AddFile (buildFile, BuildAction.Compile);
++ pf2.DependsOn = pf.FilePath.FileName;
++ }
++
++ string gtkxFile = info.GetGtkxFile (fileName);
++ if (!project.IsFileInProject(gtkxFile) && File.Exists (gtkxFile)) {
++ ProjectFile pf3 = project.AddFile (gtkxFile, BuildAction.EmbeddedResource);
++ pf3.DependsOn = pf.FilePath.FileName;
++ }
++ }
++
+ public override void BuildChildNodes (ITreeBuilder builder, object dataObject)
+ {
+- if (GtkDesignInfo.HasDesignedObjects ((Project)dataObject))
+- builder.AddChild (new WindowsFolder ((Project)dataObject));
++ Project project = (Project)dataObject;
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++
++ if (GtkDesignInfo.HasDesignedObjects (project)) {
++ GuiProjectFolder folder = new GuiProjectFolder(info.SteticFolder.FullPath, project, null);
++
++ builder.AddChild (new WindowsFolder (project));
++ builder.AddChild (folder);
++ }
+ }
+
+ public static void OnSupportChanged (Project p)
+Index: MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs (revision 0)
++++ MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs (revision 124)
+@@ -0,0 +1,52 @@
++using System;
++using MonoDevelop.GtkCore.GuiBuilder;
++using MonoDevelop.Projects;
++using MonoDevelop.Projects.Dom;
++using MonoDevelop.Projects.Dom.Parser;
++
++namespace MonoDevelop.GtkCore.NodeBuilders
++{
++ public enum GtkComponentType
++ {
++ Dialog,
++ Widget,
++ ActionGroup,
++ IconFactory,
++ None
++ }
++
++ public static class ProjectFileExtension
++ {
++ public static bool IsComponentFile (this ProjectFile pf)
++ {
++ return pf.GetComponentType () != GtkComponentType.None;
++ }
++
++ public static GtkComponentType GetComponentType (this ProjectFile pf)
++ {
++ GtkDesignInfo info = GtkDesignInfo.FromProject (pf.Project);
++ ParsedDocument doc = ProjectDomService.GetParsedDocument (ProjectDomService.GetProjectDom (pf.Project), pf.Name);
++ //ParsedDocument doc = ProjectDomService.ParseFile (ProjectDomService.GetProjectDom (pf.Project), pf.FilePath.ToString ());
++ if (doc != null && doc.CompilationUnit != null) {
++ foreach (IType t in doc.CompilationUnit.Types) {
++ string className = t.FullName;
++ if (className != null) {
++ GuiBuilderWindow win = info.GuiBuilderProject.GetWindowForClass (className);
++ if (win != null)
++ return win.RootWidget.IsWindow ? GtkComponentType.Dialog : GtkComponentType.Widget;
++
++ Stetic.ActionGroupInfo action = info.GuiBuilderProject.GetActionGroup (className);
++ if (action != null)
++ return GtkComponentType.ActionGroup;
++
++ }
++ }
++ }
++ if (pf.Name.Contains ("IconFactory.gtkx"))
++ return GtkComponentType.IconFactory;
++
++ return GtkComponentType.None;
++ }
++ }
++}
++
+Index: MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs (revision 0)
++++ MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs (revision 125)
+@@ -0,0 +1,176 @@
++//
++// GuiProjectFolderNodeBuilder.cs
++//
++// Author:
++// Krzysztof Marecki <marecki.krzysztof@gmail.com>
++//
++// Copyright (c) 2010 KrzysztofMarecki
++//
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++using System;
++using MonoDevelop.Components.Commands;
++using MonoDevelop.Core;
++using MonoDevelop.Ide.Commands;
++using MonoDevelop.Ide;
++using MonoDevelop.Ide.Gui;
++using MonoDevelop.Ide.Gui.Components;
++using MonoDevelop.Ide.Gui.Pads.ProjectPad;
++using MonoDevelop.Projects;
++
++using MonoDevelop.GtkCore.GuiBuilder;
++
++namespace MonoDevelop.GtkCore.NodeBuilders
++{
++ public class GuiProjectFolderNodeBuilder : ProjectFolderNodeBuilder
++ {
++ public override Type NodeDataType {
++ get { return typeof(GuiProjectFolder); }
++ }
++
++ public override Type CommandHandlerType {
++ get { return typeof(GuiProjectFolderCommandHandler); }
++ }
++
++ public override string GetNodeName (ITreeNavigator thisNode, object dataObject)
++ {
++ //nodes are sorted alphabetically and we want to have gui folder on the top
++ return string.Empty;
++ }
++
++
++ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon)
++ {
++ GuiProjectFolder folder = (GuiProjectFolder) dataObject;
++
++ icon = Context.GetIcon (Stock.OpenResourceFolder);
++ closedIcon = Context.GetIcon (Stock.ClosedResourceFolder);
++ label = folder.Name;
++ }
++ }
++
++ public class GuiProjectFolderCommandHandler : ProjectFolderCommandHandler
++ {
++ [CommandHandler (GtkCommands.ImportGladeFile)]
++ protected void OnImportGladeFile ()
++ {
++ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
++ GuiBuilderService.ImportGladeFile (project);
++ }
++
++ [CommandUpdateHandler (GtkCommands.ImportGladeFile)]
++ protected void UpdateImportGladeFile (CommandInfo cinfo)
++ {
++ cinfo.Visible = CanAddWindow ();
++ }
++
++ [CommandHandler (GtkCommands.EditIcons)]
++ protected void OnEditIcons ()
++ {
++ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
++ GuiBuilderProject gp = GtkDesignInfo.FromProject (project).GuiBuilderProject;
++ Stetic.Project sp = gp.SteticProject;
++ sp.EditIcons ();
++ gp.Save (true);
++ }
++
++ [CommandUpdateHandler (GtkCommands.EditIcons)]
++ protected void UpdateEditIcons (CommandInfo cinfo)
++ {
++ cinfo.Visible = CanAddWindow ();
++ }
++
++ [CommandHandler (GtkCommands.GtkSettings)]
++ protected void OnGtkSettings ()
++ {
++ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
++ IdeApp.ProjectOperations.ShowOptions (project, "SteticOptionsPanel");
++ }
++
++ [CommandUpdateHandler (GtkCommands.EditIcons)]
++ protected void UpdateGtkSettings (CommandInfo cinfo)
++ {
++ //cinfo.Visible = CanAddWindow ();
++ }
++
++ [CommandUpdateHandler (EditCommands.Delete)]
++ [CommandUpdateHandler (EditCommands.Rename)]
++ [CommandUpdateHandler (ProjectCommands.AddNewFiles)]
++ [CommandUpdateHandler (ProjectCommands.AddFiles)]
++ [CommandUpdateHandler (ProjectCommands.AddSolutionFolder)]
++ [CommandUpdateHandler (ProjectCommands.AddItem)]
++ [CommandUpdateHandler (ProjectCommands.NewFolder)]
++ protected void UpdateDisabledCommands (CommandInfo cinfo)
++ {
++ cinfo.Visible = false;
++ cinfo.Enabled = false;
++ }
++
++ bool CanAddWindow ()
++ {
++ DotNetProject project = CurrentNode.GetParentDataItem (typeof(Project), true) as DotNetProject;
++ return GtkDesignInfo.SupportsDesigner (project);
++ }
++
++ public override DragOperation CanDragNode ()
++ {
++ return DragOperation.None;
++ }
++
++ public override bool CanDeleteItem ()
++ {
++ return false;
++ }
++
++ public override bool CanDropMultipleNodes (object[] dataObjects, DragOperation operation)
++ {
++ return false;
++ }
++
++ public override bool CanDropMultipleNodes (object[] dataObjects, DragOperation operation, DropPosition position)
++ {
++ return false;
++ }
++
++ public override bool CanDeleteMultipleItems ()
++ {
++ return false;
++ }
++
++ public override bool CanDropNode (object dataObject, DragOperation operation)
++ {
++ return false;
++ }
++
++ public override bool CanDropNode (object dataObject, DragOperation operation, DropPosition position)
++ {
++ return false;
++ }
++
++ public override void RenameItem (string newName)
++ {
++ Project project = CurrentNode.GetParentDataItem (typeof(Project), true) as Project;
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++ info.SteticFolderName = newName;
++
++ base.RenameItem (newName);
++ }
++ }
++}
++
+Index: MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs (revision 0)
++++ MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs (revision 112)
+@@ -0,0 +1,42 @@
++//
++// GuiProjectFolder.cs
++//
++// Author:
++// Krzysztof Marecki <marecki.krzysztof@gmail.com>
++//
++// Copyright (c) 2010 KrzysztofMarecki
++//
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++using MonoDevelop.Core;
++using MonoDevelop.Ide.Gui.Pads.ProjectPad;
++using MonoDevelop.Projects;
++using MonoDevelop.Projects.Dom;
++
++namespace MonoDevelop.GtkCore.NodeBuilders
++{
++ public class GuiProjectFolder : ProjectFolder
++ {
++ public GuiProjectFolder (FilePath absolutePath, IWorkspaceObject parentWorkspaceObject, object parent)
++ : base (absolutePath, parentWorkspaceObject, parent)
++ {
++ }
++ }
++}
++
+Index: MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs
+===================================================================
+--- MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs (revision 17)
++++ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs (working copy)
+@@ -82,10 +82,10 @@
+ GtkDesignInfo info = GtkDesignInfo.FromProject (p);
+ if (!info.GuiBuilderProject.HasError) {
+ builder.AddChild (new StockIconsNode (p));
+- foreach (GuiBuilderWindow fi in info.GuiBuilderProject.Windows)
+- builder.AddChild (fi);
+- foreach (Stetic.ActionGroupInfo group in info.GuiBuilderProject.SteticProject.ActionGroups)
+- builder.AddChild (group);
++// foreach (GuiBuilderWindow fi in info.GuiBuilderProject.Windows)
++// builder.AddChild (fi);
++// foreach (Stetic.ActionGroupInfo group in info.GuiBuilderProject.SteticProject.ActionGroups)
++// builder.AddChild (group);
+ }
+ }
+
+Index: MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs
+===================================================================
+--- MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs (revision 0)
++++ MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs (revision 124)
+@@ -0,0 +1,40 @@
++using System;
++using Gtk;
++
++using MonoDevelop.Projects;
++
++namespace MonoDevelop.GtkCore.Dialogs
++{
++ public partial class ProjectConversionDialog : Gtk.Dialog
++ {
++ public ProjectConversionDialog (IntPtr raw)
++ : base (raw)
++ {
++ }
++
++ public string GuiFolderName { get; private set; }
++
++ public bool MakeBackup { get; private set; }
++
++
++ public ProjectConversionDialog (Project project, string guiFolderName)
++ {
++ this.Build ();
++
++ entryFolder.Text = guiFolderName;
++ Title = project.Name;
++ entryFolder.Position = -1;
++
++ buttonConvert.Clicked += HandleButtonConvertClicked;
++ }
++
++ void HandleButtonConvertClicked (object sender, EventArgs e)
++ {
++ GuiFolderName = entryFolder.Text;
++ MakeBackup = checkBackup.Active;
++
++ Respond (ResponseType.Yes);
++ }
++ }
++}
++
+Index: MonoDevelop.GtkCore.Dialogs/ChangeLog
+===================================================================
+--- MonoDevelop.GtkCore.Dialogs/ChangeLog (revision 0)
++++ MonoDevelop.GtkCore.Dialogs/ChangeLog (revision 124)
+@@ -0,0 +1,18 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * ProjectConversionDialog.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * ProjectConversionDialog.cs:
++ * WidgetBuilderOptionPanel.cs:
++
++2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectConversionDialog.cs:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * ProjectConversionDialog.cs: Initial commit
++ * WidgetBuilderOptionPanel.cs:
++
+Index: MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs
+===================================================================
+--- MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs (revision 17)
++++ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs (working copy)
+@@ -43,6 +43,8 @@
+ Gtk.CheckButton checkGettext;
+ Gtk.Entry entryGettext;
+ Gtk.ComboBox comboVersions;
++ Gtk.Entry entryFolderName;
++ Gtk.CheckButton checkHideFiles;
+
+ DotNetProject project;
+
+@@ -84,11 +86,23 @@
+ box.ShowAll ();
+ PackStart (box, false, false, 0);
+
+- checkGettext.Clicked += delegate {
+- box.Sensitive = checkGettext.Active;
+- if (checkGettext.Active)
+- entryGettext.Text = "Mono.Unix.Catalog";
+- };
++ sep= new HSeparator ();
++ sep.Show ();
++ PackStart (sep, false, false, 0);
++
++ box = new Gtk.HBox (false, 3);
++ box.PackStart (new Label (GettextCatalog.GetString ("Stetic folder name :")), false, false, 0);
++ entryFolderName = new Gtk.Entry ();
++ entryFolderName.Text = designInfo.SteticFolderName;
++ entryFolderName.Sensitive = false;
++ box.PackStart (entryFolderName, false, false, 0);
++ box.ShowAll ();
++ PackStart (box, false, false, 0);
++
++ checkHideFiles = new CheckButton (GettextCatalog.GetString ("Hide designer files"));
++ checkHideFiles.Active = designInfo.HideGtkxFiles;
++ checkHideFiles.Show ();
++ PackStart (checkHideFiles, false, false, 0);
+ }
+
+ public void Store ()
+@@ -101,6 +115,8 @@
+ info.GenerateGettext = checkGettext.Active;
+ info.GettextClass = entryGettext.Text;
+ info.GuiBuilderProject.SteticProject.TargetGtkVersion = comboVersions.ActiveText;
++ info.SteticFolderName = entryFolderName.Text;
++ info.HideGtkxFiles = checkHideFiles.Active;
+ info.GuiBuilderProject.Save (false);
+ }
+ refmgr.Dispose ();
+Index: MonoDevelop.GtkCore2.csproj
+===================================================================
+--- MonoDevelop.GtkCore2.csproj (revision 17)
++++ MonoDevelop.GtkCore2.csproj (working copy)
+@@ -59,12 +59,21 @@
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
++ <Reference Include="System.Core" />
++ <Reference Include="Mono.Cecil, Version=0.6.9.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="NRefactory, Version=2.1.1.0, Culture=neutral, PublicKeyToken=efe927acf176eea2">
++ <Package>monodevelop</Package>
++ </Reference>
++ <Reference Include="Mono.Debugging, Version=0.0.0.0, Culture=neutral, PublicKeyToken=9307d64546e0580d">
++ <Package>monodevelop</Package>
++ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj">
+ <Project>{7525BB88-6142-4A26-93B9-A30C6983390A}</Project>
+ <Name>MonoDevelop.Core</Name>
+- <Private>False</Private>
+ </ProjectReference>
+ <ProjectReference Include="..\..\core\MonoDevelop.Ide\MonoDevelop.Ide.csproj">
+ <Project>{27096E7F-C91C-4AC6-B289-6897A701DF21}</Project>
+@@ -76,11 +85,6 @@
+ <Name>MonoDevelop.DesignerSupport</Name>
+ <Private>False</Private>
+ </ProjectReference>
+- <ProjectReference Include="..\..\..\contrib\Mono.Cecil\Mono.Cecil.csproj">
+- <Project>{3EC06433-F168-4C5B-A885-99CE4AB617E1}</Project>
+- <Name>Mono.Cecil</Name>
+- <Private>False</Private>
+- </ProjectReference>
+ <ProjectReference Include="..\Deployment\MonoDevelop.Deployment\MonoDevelop.Deployment.csproj">
+ <Project>{9BC670A8-1851-40EC-9685-279F4C98433D}</Project>
+ <Name>MonoDevelop.Deployment</Name>
+@@ -151,6 +155,12 @@
+ <EmbeddedResource Include="gtk-gui\gui.stetic">
+ <LogicalName>gui.stetic</LogicalName>
+ </EmbeddedResource>
++ <EmbeddedResource Include="icons\gtkx.png">
++ <LogicalName>gtkx.png</LogicalName>
++ </EmbeddedResource>
++ <EmbeddedResource Include="icons\gtk-logo.png">
++ <LogicalName>gtk-logo.png</LogicalName>
++ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="MonoDevelop.GtkCore.Commands\GladeCommands.cs" />
+@@ -166,7 +176,6 @@
+ <Compile Include="MonoDevelop.GtkCore\GtkCoreService.cs" />
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\WidgetBuilderOptionPanel.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectNodeBuilder.cs" />
+- <Compile Include="MonoDevelop.GtkCore.NodeBuilders\WidgetNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFolderNodeBuilderExtension.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\WindowsFolderNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\WindowsFolder.cs" />
+@@ -176,7 +185,6 @@
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\ConfirmWindowDeleteDialog.cs" />
+ <Compile Include="MonoDevelop.GtkCore\ProjectResourceProvider.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ActionGroupView.cs" />
+- <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ActionGroupNodeBuilder.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\ActionGroupDisplayBinding.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\CombinedDesignView.cs" />
+ <Compile Include="MonoDevelop.GtkCore.GuiBuilder\CodeBinder.cs" />
+@@ -193,8 +201,15 @@
+ <Compile Include="MonoDevelop.GtkCore.Dialogs\GtkDesignerOptionsPanelWidget.cs" />
+ <Compile Include="gtk-gui\MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs" />
+ <Compile Include="MonoDevelop.GtkCore\Counters.cs" />
++ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFileNodeBuilderExtension.cs" />
++ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\ProjectFileExtension.cs" />
++ <Compile Include="MonoDevelop.GtkCore.Dialogs\ProjectConversionDialog.cs" />
++ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\GuiProjectFolder.cs" />
++ <Compile Include="MonoDevelop.GtkCore.NodeBuilders\GuiProjectFolderNodeBuilder.cs" />
++ <Compile Include="gtk-gui\MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
++ <Import Project="$(MSBuildExtensionsPath)\Mono.Addins.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+Index: gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs
+===================================================================
+--- gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs (revision 0)
++++ gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs (revision 124)
+@@ -0,0 +1,183 @@
++// ------------------------------------------------------------------------------
++// <autogenerated>
++// This code was generated by a tool.
++// Mono Runtime Version: 2.0.50727.1433
++//
++// Changes to this file may cause incorrect behavior and will be lost if
++// the code is regenerated.
++// </autogenerated>
++// ------------------------------------------------------------------------------
++
++
++// This file has been generated by the GUI designer. Do not modify.
++namespace MonoDevelop.GtkCore.Dialogs
++{
++ public partial class ProjectConversionDialog
++ {
++ private global::Gtk.HBox hbox;
++
++ private global::Gtk.Alignment alignmentLogo;
++
++ private global::Gtk.Image imageLogo;
++
++ private global::Gtk.VBox vbox2;
++
++ private global::Gtk.Label labelProject;
++
++ private global::Gtk.Label labelInfo;
++
++ private global::Gtk.HSeparator hseparator1;
++
++ private global::Gtk.HBox hbox1;
++
++ private global::Gtk.Label labelFolder;
++
++ private global::Gtk.Entry entryFolder;
++
++ private global::Gtk.CheckButton checkBackup;
++
++ private global::Gtk.Button buttonConvert;
++
++ protected virtual void Build ()
++ {
++ global::Stetic.Gui.Initialize (this);
++ // Widget MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog
++ this.Name = "MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog";
++ this.Title = global::Mono.Unix.Catalog.GetString ("Project Name");
++ this.WindowPosition = ((global::Gtk.WindowPosition)(4));
++ this.Modal = true;
++ this.SkipTaskbarHint = true;
++ // Internal child MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.VBox
++ global::Gtk.VBox w1 = this.VBox;
++ w1.Name = "dialog1_VBox";
++ w1.BorderWidth = ((uint)(2));
++ // Container child dialog1_VBox.Gtk.Box+BoxChild
++ this.hbox = new global::Gtk.HBox ();
++ this.hbox.Name = "hbox";
++ this.hbox.Spacing = 6;
++ // Container child hbox.Gtk.Box+BoxChild
++ this.alignmentLogo = new global::Gtk.Alignment (1f, 0.15f, 1f, 0f);
++ this.alignmentLogo.Name = "alignmentLogo";
++ // Container child alignmentLogo.Gtk.Container+ContainerChild
++ this.imageLogo = new global::Gtk.Image ();
++ this.imageLogo.WidthRequest = 180;
++ this.imageLogo.Name = "imageLogo";
++ this.imageLogo.Yalign = 0f;
++ this.imageLogo.Pixbuf = global::Gdk.Pixbuf.LoadFromResource ("gtk-logo.png");
++ this.alignmentLogo.Add (this.imageLogo);
++ this.hbox.Add (this.alignmentLogo);
++ global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox[this.alignmentLogo]));
++ w3.Position = 0;
++ w3.Expand = false;
++ w3.Fill = false;
++ // Container child hbox.Gtk.Box+BoxChild
++ this.vbox2 = new global::Gtk.VBox ();
++ this.vbox2.Name = "vbox2";
++ this.vbox2.Spacing = 6;
++ // Container child vbox2.Gtk.Box+BoxChild
++ this.labelProject = new global::Gtk.Label ();
++ this.labelProject.Name = "labelProject";
++ this.labelProject.LabelProp = global::Mono.Unix.Catalog.GetString ("<b><big>GTK# Project Conversion</big></b>");
++ this.labelProject.UseMarkup = true;
++ this.vbox2.Add (this.labelProject);
++ global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.labelProject]));
++ w4.Position = 0;
++ w4.Expand = false;
++ w4.Fill = false;
++ // Container child vbox2.Gtk.Box+BoxChild
++ this.labelInfo = new global::Gtk.Label ();
++ this.labelInfo.Name = "labelInfo";
++ this.labelInfo.Xalign = 0f;
++ this.labelInfo.Yalign = 0f;
++ this.labelInfo.LabelProp = global::Mono.Unix.Catalog.GetString ("This project has been created in the previous\nversion of GTK# addin and must be converted. \n\n<b>Following changes will be made :</b>\n\t- split gui.stetic into separate .gtkx files\n\t- split generated.cs into separate helper classes\n\t- remove gtk-gui folder.\n\t- create a designer folder for stock icons\n\t and generated helper classes. ");
++ this.labelInfo.UseMarkup = true;
++ this.labelInfo.Wrap = true;
++ this.vbox2.Add (this.labelInfo);
++ global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.labelInfo]));
++ w5.Position = 1;
++ w5.Expand = false;
++ w5.Fill = false;
++ // Container child vbox2.Gtk.Box+BoxChild
++ this.hseparator1 = new global::Gtk.HSeparator ();
++ this.hseparator1.Name = "hseparator1";
++ this.vbox2.Add (this.hseparator1);
++ global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hseparator1]));
++ w6.Position = 2;
++ w6.Expand = false;
++ w6.Fill = false;
++ // Container child vbox2.Gtk.Box+BoxChild
++ this.hbox1 = new global::Gtk.HBox ();
++ this.hbox1.Name = "hbox1";
++ this.hbox1.Spacing = 6;
++ // Container child hbox1.Gtk.Box+BoxChild
++ this.labelFolder = new global::Gtk.Label ();
++ this.labelFolder.Name = "labelFolder";
++ this.labelFolder.LabelProp = global::Mono.Unix.Catalog.GetString ("Designer folder name:");
++ this.hbox1.Add (this.labelFolder);
++ global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.labelFolder]));
++ w7.Position = 0;
++ w7.Expand = false;
++ w7.Fill = false;
++ // Container child hbox1.Gtk.Box+BoxChild
++ this.entryFolder = new global::Gtk.Entry ();
++ this.entryFolder.CanFocus = true;
++ this.entryFolder.Name = "entryFolder";
++ this.entryFolder.IsEditable = true;
++ this.entryFolder.InvisibleChar = '●';
++ this.hbox1.Add (this.entryFolder);
++ global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.entryFolder]));
++ w8.Position = 1;
++ this.vbox2.Add (this.hbox1);
++ global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hbox1]));
++ w9.Position = 3;
++ w9.Expand = false;
++ w9.Fill = false;
++ // Container child vbox2.Gtk.Box+BoxChild
++ this.checkBackup = new global::Gtk.CheckButton ();
++ this.checkBackup.CanFocus = true;
++ this.checkBackup.Name = "checkBackup";
++ this.checkBackup.Label = global::Mono.Unix.Catalog.GetString ("Make a backup before converting");
++ this.checkBackup.Active = true;
++ this.checkBackup.DrawIndicator = true;
++ this.checkBackup.UseUnderline = true;
++ this.vbox2.Add (this.checkBackup);
++ global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.checkBackup]));
++ w10.Position = 4;
++ w10.Expand = false;
++ w10.Fill = false;
++ this.hbox.Add (this.vbox2);
++ global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.hbox[this.vbox2]));
++ w11.Position = 1;
++ w11.Expand = false;
++ w11.Fill = false;
++ w1.Add (this.hbox);
++ global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(w1[this.hbox]));
++ w12.Position = 0;
++ w12.Expand = false;
++ w12.Fill = false;
++ // Internal child MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.ActionArea
++ global::Gtk.HButtonBox w13 = this.ActionArea;
++ w13.Name = "dialog1_ActionArea";
++ w13.Spacing = 10;
++ w13.BorderWidth = ((uint)(5));
++ w13.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4));
++ // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
++ this.buttonConvert = new global::Gtk.Button ();
++ this.buttonConvert.CanDefault = true;
++ this.buttonConvert.CanFocus = true;
++ this.buttonConvert.Name = "buttonConvert";
++ this.buttonConvert.UseUnderline = true;
++ this.buttonConvert.Label = global::Mono.Unix.Catalog.GetString ("_Convert");
++ this.AddActionWidget (this.buttonConvert, -5);
++ global::Gtk.ButtonBox.ButtonBoxChild w14 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w13[this.buttonConvert]));
++ w14.Expand = false;
++ w14.Fill = false;
++ if ((this.Child != null)) {
++ this.Child.ShowAll ();
++ }
++ this.DefaultWidth = 532;
++ this.DefaultHeight = 292;
++ this.Show ();
++ }
++ }
++}
+Index: gtk-gui/ChangeLog
+===================================================================
+--- gtk-gui/ChangeLog (revision 0)
++++ gtk-gui/ChangeLog (revision 124)
+@@ -0,0 +1,46 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * gui.stetic:
++ * MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * gui.stetic:
++
++2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
++
++ * gui.stetic:
++
++2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gui.stetic:
++
++2010-08-05 Krzysztof Marecki <freefirma@gmail.com>
++
++ * gui.stetic:
++
++2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
++
++ * gui.stetic:
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gui.stetic:
++
++2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gui.stetic:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gui.stetic:
++ * MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs:
++
++2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gui.stetic:
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * gui.stetic:
++
+Index: gtk-gui/gui.stetic
+===================================================================
+--- gtk-gui/gui.stetic (revision 17)
++++ gtk-gui/gui.stetic (working copy)
+@@ -8,10 +8,11 @@
+ <widget-library name="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+ <widget-library name="../../../../build/bin/MonoDevelop.Ide.dll" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.dll" />
+- <widget-library name="../../../../build/AddIns/MonoDevelop.Deployment/MonoDevelop.Deployment.dll" />
+ <widget-library name="../../../../build/bin/Mono.TextEditor.dll" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.GtkCore2/libsteticui2.dll" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.GtkCore2/libstetic2.dll" />
++ <widget-library name="MonoDevelop.Ide, Version=2.4.0.0, Culture=neutral" />
++ <widget-library name="Mono.TextEditor, Version=1.0.0.0, Culture=neutral" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.dll" internal="true" />
+ </import>
+ <widget class="Gtk.Bin" id="MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget" design-size="503 22">
+@@ -40,4 +41,190 @@
+ </widget>
+ </child>
+ </widget>
++ <widget class="Gtk.Dialog" id="MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog" design-size="532 308">
++ <property name="MemberName" />
++ <property name="Title" translatable="yes">Project Name</property>
++ <property name="WindowPosition">CenterOnParent</property>
++ <property name="Modal">True</property>
++ <property name="SkipTaskbarHint">True</property>
++ <property name="Buttons">1</property>
++ <property name="HelpButton">False</property>
++ <child internal-child="VBox">
++ <widget class="Gtk.VBox" id="dialog1_VBox">
++ <property name="MemberName" />
++ <property name="BorderWidth">2</property>
++ <child>
++ <widget class="Gtk.HBox" id="hbox">
++ <property name="MemberName" />
++ <property name="Spacing">6</property>
++ <child>
++ <widget class="Gtk.Alignment" id="alignmentLogo">
++ <property name="MemberName" />
++ <property name="Yscale">0</property>
++ <property name="Xalign">1</property>
++ <property name="Yalign">0.15</property>
++ <child>
++ <widget class="Gtk.Image" id="imageLogo">
++ <property name="MemberName" />
++ <property name="WidthRequest">180</property>
++ <property name="Yalign">0</property>
++ <property name="Pixbuf">resource:gtk-logo.png</property>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="Position">0</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="Gtk.VBox" id="vbox2">
++ <property name="MemberName" />
++ <property name="Spacing">6</property>
++ <child>
++ <widget class="Gtk.Label" id="labelProject">
++ <property name="MemberName" />
++ <property name="LabelProp" translatable="yes">&lt;b&gt;&lt;big&gt;GTK# Project Conversion&lt;/big&gt;&lt;/b&gt;</property>
++ <property name="UseMarkup">True</property>
++ </widget>
++ <packing>
++ <property name="Position">0</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="Gtk.Label" id="labelInfo">
++ <property name="MemberName" />
++ <property name="Xalign">0</property>
++ <property name="Yalign">0</property>
++ <property name="LabelProp" translatable="yes">This project has been created in the previous
++version of GTK# addin and must be converted.
++
++&lt;b&gt;Following changes will be made :&lt;/b&gt;
++ - split gui.stetic into separate .gtkx files
++ - split generated.cs into separate helper classes
++ - remove gtk-gui folder.
++ - create a designer folder for stock icons
++ and generated helper classes.</property>
++ <property name="UseMarkup">True</property>
++ <property name="Wrap">True</property>
++ </widget>
++ <packing>
++ <property name="Position">1</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="Gtk.HSeparator" id="hseparator1">
++ <property name="MemberName" />
++ </widget>
++ <packing>
++ <property name="Position">2</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="Gtk.HBox" id="hbox1">
++ <property name="MemberName" />
++ <property name="Spacing">6</property>
++ <child>
++ <widget class="Gtk.Label" id="labelFolder">
++ <property name="MemberName" />
++ <property name="LabelProp" translatable="yes">Designer folder name:</property>
++ </widget>
++ <packing>
++ <property name="Position">0</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="Gtk.Entry" id="entryFolder">
++ <property name="MemberName" />
++ <property name="CanFocus">True</property>
++ <property name="IsEditable">True</property>
++ <property name="InvisibleChar">●</property>
++ </widget>
++ <packing>
++ <property name="Position">1</property>
++ <property name="AutoSize">True</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="Position">3</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="Gtk.CheckButton" id="checkBackup">
++ <property name="MemberName" />
++ <property name="CanFocus">True</property>
++ <property name="Label" translatable="yes">Make a backup before converting</property>
++ <property name="Active">True</property>
++ <property name="DrawIndicator">True</property>
++ <property name="HasLabel">True</property>
++ <property name="UseUnderline">True</property>
++ </widget>
++ <packing>
++ <property name="Position">4</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="Position">1</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="Position">0</property>
++ <property name="AutoSize">True</property>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ <child internal-child="ActionArea">
++ <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
++ <property name="MemberName" />
++ <property name="Spacing">10</property>
++ <property name="BorderWidth">5</property>
++ <property name="Size">1</property>
++ <property name="LayoutStyle">End</property>
++ <child>
++ <widget class="Gtk.Button" id="buttonConvert">
++ <property name="MemberName" />
++ <property name="CanDefault">True</property>
++ <property name="CanFocus">True</property>
++ <property name="Type">TextOnly</property>
++ <property name="Label" translatable="yes">_Convert</property>
++ <property name="UseUnderline">True</property>
++ <property name="ResponseId">-5</property>
++ </widget>
++ <packing>
++ <property name="Expand">False</property>
++ <property name="Fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ </widget>
+ </stetic-interface>
+\ No newline at end of file
+Index: Makefile.am
+===================================================================
+--- Makefile.am (revision 17)
++++ Makefile.am (working copy)
+@@ -1,14 +1,13 @@
+ SUBDIRS = libstetic libsteticui
+
+-ADDIN_BUILD = $(top_builddir)/build/AddIns/MonoDevelop.GtkCore
+-ASSEMBLY = $(ADDIN_BUILD)/MonoDevelop.GtkCore.dll
++ADDIN_BUILD = $(top_builddir)/build/AddIns/MonoDevelop.GtkCore2
++ASSEMBLY = $(ADDIN_BUILD)/MonoDevelop.GtkCore2.dll
+
+ DEPS = \
+ $(top_builddir)/build/AddIns/MonoDevelop.Deployment/MonoDevelop.Deployment.dll \
+ $(top_builddir)/build/AddIns/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.dll \
+ $(top_builddir)/build/AddIns/MonoDevelop.GtkCore2/libstetic2.dll \
+ $(top_builddir)/build/AddIns/MonoDevelop.GtkCore2/libsteticui2.dll \
+- $(top_builddir)/build/bin/Mono.Cecil.dll \
+ $(top_builddir)/build/bin/Mono.TextEditor.dll \
+ $(top_builddir)/build/bin/MonoDevelop.Core.dll \
+ $(top_builddir)/build/bin/MonoDevelop.Ide.dll
+@@ -18,19 +17,23 @@
+ $(GLIB_SHARP_LIBS) \
+ $(GTK_SHARP_LIBS) \
+ $(MONO_ADDINS_LIBS) \
++ -pkg:monodevelop \
+ -r:Mono.Posix \
+ -r:System \
++ -r:System.Core \
+ -r:System.Xml
+
+ FILES = \
+ AssemblyInfo.cs \
+ gtk-gui/generated.cs \
+ gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs \
++ gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs \
+ MonoDevelop.GtkCore.Commands/GladeCommands.cs \
+ MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/GtkDesignerOptionsPanelWidget.cs \
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs \
++ MonoDevelop.GtkCore.Dialogs/ProjectConversionDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs \
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs \
+@@ -48,11 +51,13 @@
+ MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs \
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs \
+- MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs \
++ MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolder.cs \
++ MonoDevelop.GtkCore.NodeBuilders/GuiProjectFolderNodeBuilder.cs \
++ MonoDevelop.GtkCore.NodeBuilders/ProjectFileExtension.cs \
++ MonoDevelop.GtkCore.NodeBuilders/ProjectFileNodeBuilderExtension.cs \
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs \
+ MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs \
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs \
+- MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs \
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs \
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs \
+ MonoDevelop.GtkCore/Counters.cs \
+@@ -68,6 +73,8 @@
+ gtk-gui/gui.stetic \
+ gui.glade \
+ icons/actiongroup.png \
++ icons/gtk-logo.png \
++ icons/gtkx.png \
+ icons/image-x-generic.png \
+ icons/widget.png \
+ MonoDevelop.GtkCore.addin.xml \
+@@ -99,7 +106,7 @@
+ $(CSC) $(CSC_FLAGS) -debug -out:$@ -target:library \
+ $(build_resources:%=/resource:%) $(build_sources) $(REFS) $(build_deps)
+
+-assemblydir = $(MD_ADDIN_DIR)/MonoDevelop.GtkCore
++assemblydir = $(MD_ADDIN_DIR)/MonoDevelop.GtkCore2
+ assembly_DATA = $(ASSEMBLY) $(ASSEMBLY).mdb
+
+ CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb
+Index: icons/gtkx.png
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+
+Property changes on: icons/gtkx.png
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+Index: icons/gtk-logo.png
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+
+Property changes on: icons/gtk-logo.png
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+Index: icons/ChangeLog
+===================================================================
+--- icons/ChangeLog (revision 0)
++++ icons/ChangeLog (revision 124)
+@@ -0,0 +1,5 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * gtkx.png:
++ * gtk-logo.png:
++
+Index: MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs (working copy)
+@@ -53,12 +53,17 @@
+ {
+ if (excludeThis)
+ return false;
++
++ if (fileName.Contains ("generated"))
++ return false;
++
+ if (!IdeApp.Workspace.IsOpen)
+ return false;
+
+ if (GetActionGroup (fileName) == null)
+ return false;
+
++
+ excludeThis = true;
+ var db = DisplayBindingService.GetDefaultBindingForUri (fileName);
+ excludeThis = false;
+@@ -171,7 +176,7 @@
+ IdeApp.ProjectOperations.Save (project);
+
+ // Make sure the database is up-to-date
+- ProjectDomService.Parse (project, cls.CompilationUnit.FileName, null);
++ ProjectDomService.Parse (project, cls.CompilationUnit.FileName);
+ return cls;
+ }
+
+Index: MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs (working copy)
+@@ -34,6 +34,7 @@
+
+ using MonoDevelop.Ide.Gui;
+ using MonoDevelop.Projects;
++using MonoDevelop.Projects.Dom;
+ using MonoDevelop.Projects.Dom.Parser;
+ using MonoDevelop.Projects.Text;
+ using MonoDevelop.Core;
+@@ -257,12 +258,21 @@
+
+ public static string GetBuildCodeFileName (Project project, string componentName)
+ {
++ return GetBuildCodeFileName (project, componentName, string.Empty);
++ }
++
++ public static string GetBuildCodeFileName (Project project, string componentName, string nameSpace)
++ {
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+-// var type=info.GuiBuilderProject.FindClass(componentName);
+- var folder = info.GtkGuiFolder;
++ string componentFile = info.GetComponentFile (componentName);
+
+-// folder=type.CompilationUnit.FileName.ParentDirectory;
+- return Path.Combine (folder, componentName + Path.GetExtension (info.SteticGeneratedFile));
++ if (componentFile == null) {
++ if (nameSpace == "Stetic") {
++ return info.GetBuildFileInSteticFolder (componentName);
++ } else
++ throw new UserException ("Cannot find component file for " + componentName);
++ } else
++ return info.GetBuildFile (componentFile);
+ }
+
+ public static string GenerateSteticCodeStructure (DotNetProject project, Stetic.ProjectItemInfo item, bool saveToFile, bool overwrite)
+@@ -351,13 +361,12 @@
+ FileService.NotifyFileChanged (fileName);
+ }
+ else
+- ProjectDomService.Parse (project, fileName, "", ((StringWriter)fileStream).ToString ());
++ ProjectDomService.Parse (project, fileName, ((StringWriter)fileStream).ToString ());
+ }
+
+ return fileName;
+ }
+
+-
+ public static Stetic.CodeGenerationResult GenerateSteticCode (IProgressMonitor monitor, DotNetProject project, ConfigurationSelector configuration)
+ {
+ if (generating || !GtkDesignInfo.HasDesignedObjects (project))
+@@ -382,8 +391,8 @@
+ }
+
+ // Check if generated code is already up to date.
+- if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
+- return null;
++// if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
++// return null;
+
+ if (info.GuiBuilderProject.HasError) {
+ monitor.ReportError (GettextCatalog.GetString ("GUI code generation failed for project '{0}'. The file '{1}' could not be loaded.", project.Name, info.SteticFile), null);
+@@ -402,8 +411,8 @@
+
+ info.GuiBuilderProject.UpdateLibraries ();
+
+- ArrayList projects = new ArrayList ();
+- projects.Add (info.GuiBuilderProject.File);
++ ArrayList projectFolders = new ArrayList ();
++ projectFolders.Add (info.SteticFolder.FullPath);
+
+ generating = true;
+ Stetic.CodeGenerationResult generationResult = null;
+@@ -418,7 +427,7 @@
+ // Generate the code in another process if stetic is not isolated
+ CodeGeneratorProcess cob = (CodeGeneratorProcess) Runtime.ProcessService.CreateExternalProcessObject (typeof (CodeGeneratorProcess), false);
+ using (cob) {
+- generationResult = cob.GenerateCode (projects, info.GenerateGettext, info.GettextClass, project.UsePartialTypes, info);
++ generationResult = cob.GenerateCode (projectFolders, info.GenerateGettext, info.GettextClass, project.UsePartialTypes, info);
+ }
+ } catch (Exception ex) {
+ generatedException = ex;
+@@ -438,8 +447,6 @@
+ Stetic.GenerationOptions options = new Stetic.GenerationOptions ();
+ options.UseGettext = info.GenerateGettext;
+ options.GettextClass = info.GettextClass;
+- options.UsePartialClasses = project.UsePartialTypes;
+- options.GenerateSingleFile = false;
+ generationResult = SteticApp.GenerateProjectCode (options, info.GuiBuilderProject.SteticProject);
+ } catch (Exception ex) {
+ generatedException = ex;
+@@ -448,8 +455,23 @@
+ }
+
+ if (generatedException != null) {
+- LoggingService.LogError ("GUI code generation failed", generatedException);
+- throw new UserException ("GUI code generation failed: " + generatedException.Message);
++ string msg = string.Empty;
++
++ if (generatedException.InnerException != null) {
++ msg = string.Format("{0}\n{1}\nInner Exception {2}\n{3}",
++ generatedException.Message,
++ generatedException.StackTrace,
++ generatedException.InnerException.Message,
++ generatedException.InnerException.StackTrace);
++ } else {
++ msg = string.Format("{0}\n{1}",
++ generatedException.Message,
++ generatedException.StackTrace);
++ }
++
++// LoggingService.LogError ("GUI code generation failed", generatedException);
++ LoggingService.LogError ("GUI code generation failed: " + msg);
++ throw new UserException ("GUI code generation failed: " + msg);
+ }
+
+ if (generationResult == null)
+@@ -459,15 +481,15 @@
+ if (provider == null)
+ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
+
+- string basePath = Path.GetDirectoryName (info.SteticGeneratedFile);
+- string ext = Path.GetExtension (info.SteticGeneratedFile);
+-
+ foreach (Stetic.SteticCompilationUnit unit in generationResult.Units) {
+ string fname;
+ if (unit.Name.Length == 0)
+ fname = info.SteticGeneratedFile;
+ else
+- fname = Path.Combine (basePath, unit.Name) + ext;
++ fname = GetBuildCodeFileName (project,
++ unit.Name,
++ (unit.Namespace != null) ? unit.Namespace.Name : string.Empty);
++
+ StringWriter sw = new StringWriter ();
+ try {
+ foreach (CodeNamespace ns in unit.Namespaces)
+@@ -476,6 +498,12 @@
+ string content = sw.ToString ();
+ content = FormatGeneratedFile (fname, content, provider);
+ File.WriteAllText (fname, content);
++// if (File.Exists (fname)) {
++// FileInfo file = new FileInfo (fname);
++// DateTime now = DateTime.Now;
++// file.LastWriteTime = now;
++// file.LastWriteTimeUtc = now;
++// }
+ } finally {
+ FileService.NotifyFileChanged (fname);
+ }
+@@ -580,23 +608,21 @@
+
+ public class CodeGeneratorProcess: RemoteProcessObject
+ {
+- public Stetic.CodeGenerationResult GenerateCode (ArrayList projectFiles, bool useGettext, string gettextClass, bool usePartialClasses, GtkDesignInfo info)
++ public Stetic.CodeGenerationResult GenerateCode (ArrayList projectFolders, bool useGettext, string gettextClass, bool usePartialClasses, GtkDesignInfo info)
+ {
+ Gtk.Application.Init ();
+
+ Stetic.Application app = Stetic.ApplicationFactory.CreateApplication (Stetic.IsolationMode.None);
+
+- Stetic.Project[] projects = new Stetic.Project [projectFiles.Count];
+- for (int n=0; n < projectFiles.Count; n++) {
++ Stetic.Project[] projects = new Stetic.Project [projectFolders.Count];
++ for (int n=0; n < projectFolders.Count; n++) {
+ projects [n] = app.CreateProject (info);
+- projects [n].Load ((string) projectFiles [n]);
++ projects [n].Load ((string) projectFolders [n]);
+ }
+
+ Stetic.GenerationOptions options = new Stetic.GenerationOptions ();
+ options.UseGettext = useGettext;
+ options.GettextClass = gettextClass;
+- options.UsePartialClasses = usePartialClasses;
+- options.GenerateSingleFile = false;
+
+ return app.GenerateProjectCode (options, projects);
+ }
+Index: MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs (working copy)
+@@ -46,6 +46,9 @@
+ {
+ if (excludeThis) return false;
+
++ if (fileName.Contains ("generated"))
++ return false;
++
+ if (GetWindow (fileName) == null)
+ return false;
+
+@@ -81,7 +84,7 @@
+ return null;
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+- if (file.StartsWith (info.GtkGuiFolder))
++ if (file.StartsWith (info.SteticFolder))
+ return null;
+
+ ParsedDocument doc = ProjectDomService.GetParsedDocument (null, file);
+Index: MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs (working copy)
+@@ -44,12 +44,15 @@
+ {
+ public class GuiBuilderProject
+ {
++ //to save temporarily GuiBuilderWindow while files are being moved between projects
++ static List<GuiBuilderWindow> formInfosRemoved;
++
+ internal object MemoryProbe = Counters.GuiProjectsInMemory.CreateMemoryProbe ();
+
+ List<GuiBuilderWindow> formInfos;
+ Stetic.Project gproject;
+ DotNetProject project;
+- string fileName;
++ string folderName;
+ bool hasError;
+ bool needsUpdate = true;
+
+@@ -64,38 +67,87 @@
+ public event EventHandler Reloaded;
+ public event EventHandler Unloaded;
+ public event EventHandler Changed;
++
++ static GuiBuilderProject ()
++ {
++ formInfosRemoved = new List<GuiBuilderWindow> ();
++ }
+
+- public GuiBuilderProject (DotNetProject project, string fileName)
++ public GuiBuilderProject (DotNetProject project, string folderName)
+ {
+- this.fileName = fileName;
++ this.folderName = folderName;
+ this.project = project;
+ Counters.GuiProjectsLoaded++;
+ }
+
++ public void Convert (string guiFolderName, bool makeBackup)
++ {
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++ Stetic.Project gproject = GuiBuilderService.SteticApp.CreateProject (info);
++ //Stetic.Project does not implement IDisposable
++ try {
++ string newGuiFolderName = project.BaseDirectory.Combine (guiFolderName);
++ gproject.ConvertProject (info.SteticFile, newGuiFolderName);
++ info.ConvertGtkFolder (guiFolderName, makeBackup);
++ info.UpdateGtkFolder ();
++ folderName = newGuiFolderName;
++ IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBuildProgressMonitor ();
++ try {
++ ConfigurationSelector configuration = IdeApp.Workspace.ActiveConfiguration;
++ Generator generator = new Generator ();
++ generator.Run (monitor, project, configuration);
++ monitor.ReportSuccess ("Converting was succesfull");
++ } finally {
++ monitor.Dispose ();
++ }
++ } finally {
++ gproject.Dispose ();
++ }
++ }
++
++ public void GenerateCode (string componentFile)
++ {
++ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
++ string gtkxFile = info.GetGtkxFile (componentFile);
++ if (gtkxFile != null && File.Exists (gtkxFile)) {
++
++ Save (false);
++ FileInfo fi = new FileInfo (gtkxFile);
++ fi.LastWriteTime = DateTime.Now;
++
++ IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBuildProgressMonitor ();
++ try {
++ ConfigurationSelector configuration = IdeApp.Workspace.ActiveConfiguration;
++ Generator generator = new Generator ();
++ generator.Run (monitor, project, configuration);
++ } finally {
++ monitor.Dispose ();
++ }
++ }
++ }
++
+ void Load ()
+ {
+- if (gproject != null || disposed || fileName == null)
++ if (gproject != null || disposed || folderName == null)
+ return;
+
+ GtkDesignInfo info = GtkDesignInfo.FromProject (project);
+ gproject = GuiBuilderService.SteticApp.CreateProject (info);
+ formInfos = new List<GuiBuilderWindow> ();
+-
+- if (!System.IO.File.Exists (fileName)) {
+- // Regenerate the gtk-gui folder if the stetic project
+- // doesn't exist.
+- info.UpdateGtkFolder ();
+- }
++
++// TODO : when expanding project, UpdateGtkFolder causes in throwing exception by gtk
++// info.UpdateGtkFolder ();
+
+ try {
+- gproject.Load (fileName);
++ gproject.Load (folderName);
+ } catch (Exception ex) {
+- MessageService.ShowException (ex, GettextCatalog.GetString ("The GUI designer project file '{0}' could not be loaded.", fileName));
++ MessageService.ShowException (ex, GettextCatalog.GetString ("The GUI designer project folder '{0}' could not be loaded.", folderName));
+ hasError = true;
+ }
+
+ Counters.SteticProjectsLoaded++;
+ gproject.ResourceProvider = GtkDesignInfo.FromProject (project).ResourceProvider;
++// gproject.DesignInfo = info;
+ gproject.WidgetAdded += OnAddWidget;
+ gproject.WidgetRemoved += OnRemoveWidget;
+ gproject.ActionGroupsChanged += OnGroupsChanged;
+@@ -108,14 +160,14 @@
+ RegisterWindow (ob, false);
+
+ // Monitor changes in the file
+- lastSaveTime = System.IO.File.GetLastWriteTime (fileName);
+- watcher = new FileSystemWatcher ();
+- if (System.IO.File.Exists (fileName)) {
+- watcher.Path = Path.GetDirectoryName (fileName);
+- watcher.Filter = Path.GetFileName (fileName);
+- watcher.Changed += (FileSystemEventHandler) DispatchService.GuiDispatch (new FileSystemEventHandler (OnSteticFileChanged));
+- watcher.EnableRaisingEvents = true;
+- }
++// lastSaveTime = System.IO.File.GetLastWriteTime (fileName);
++// watcher = new FileSystemWatcher ();
++// if (System.IO.File.Exists (fileName)) {
++// watcher.Path = Path.GetDirectoryName (fileName);
++// watcher.Filter = Path.GetFileName (fileName);
++// watcher.Changed += (FileSystemEventHandler) DispatchService.GuiDispatch (new FileSystemEventHandler (OnSteticFileChanged));
++// watcher.EnableRaisingEvents = true;
++// }
+ }
+
+ void Unload ()
+@@ -158,7 +210,7 @@
+ void OnSteticFileChanged (object s, FileSystemEventArgs args)
+ {
+ lock (fileSaveLock) {
+- if (lastSaveTime == System.IO.File.GetLastWriteTime (fileName))
++ if (lastSaveTime == System.IO.File.GetLastWriteTime (folderName))
+ return;
+ }
+
+@@ -198,8 +250,8 @@
+
+ if (gproject != null && !hasError) {
+ lock (fileSaveLock) {
+- gproject.Save (fileName);
+- lastSaveTime = System.IO.File.GetLastWriteTime (fileName);
++ gproject.Save (folderName);
++ lastSaveTime = System.IO.File.GetLastWriteTime (folderName);
+ }
+ }
+
+@@ -207,14 +259,11 @@
+ IdeApp.ProjectOperations.Save (project);
+ }
+
+- public string File {
+- get { return fileName; }
+- }
+-
+ public Stetic.Project SteticProject {
+ get {
+ Load ();
+ return gproject;
++
+ }
+ }
+
+@@ -256,6 +305,16 @@
+ RegisterWindow (c, true);
+ return c;
+ }
++
++ public void AddNewComponent (string fileName)
++ {
++ object ob = SteticProject.AddNewComponent (fileName);
++
++ if (ob is Stetic.WidgetInfo) {
++ var c = (Stetic.WidgetInfo) ob;
++ RegisterWindow (c, true);
++ }
++ }
+
+ void RegisterWindow (Stetic.WidgetInfo widget, bool notify)
+ {
+@@ -266,6 +325,16 @@
+
+ GuiBuilderWindow win = new GuiBuilderWindow (this, gproject, widget);
+ formInfos.Add (win);
++
++ GuiBuilderWindow winToRemove = null;
++ foreach (GuiBuilderWindow form in formInfosRemoved)
++ if (form.RootWidget == widget) {
++ winToRemove = form;
++ break;
++ }
++
++ if (winToRemove != null)
++ formInfosRemoved.Remove (winToRemove);
+
+ if (notify) {
+ if (WindowAdded != null)
+@@ -281,6 +350,7 @@
+ return;
+
+ formInfos.Remove (win);
++ formInfosRemoved.Add (win);
+
+ if (WindowRemoved != null)
+ WindowRemoved (this, new WindowEventArgs (win));
+@@ -319,30 +389,18 @@
+ }
+
+ void OnFileAdded (object sender, ProjectFileEventArgs args)
+- {
++ {
++ FilePath path = args.ProjectFile.FilePath;
+
+- ParsedDocument doc = ProjectDomService.GetParsedDocument (ProjectDomService.GetProjectDom (args.Project), args.ProjectFile.Name);
+- if (doc == null || doc.CompilationUnit == null)
+- return;
+-
+- string dir = Path.Combine (Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), "stetic"), "deleted-designs");
+- if (!Directory.Exists (dir) || Directory.GetFiles (dir).Length == 0)
+- return;
+-
+- foreach (IType t in doc.CompilationUnit.Types) {
+- string path = Path.Combine (dir, t.FullName + ".xml");
+- if (!System.IO.File.Exists (path))
+- continue;
+- XmlDocument xmldoc = new XmlDocument ();
+- xmldoc.Load (path);
+- AddNewComponent (xmldoc.DocumentElement);
+- System.IO.File.Delete (path);
++ if (path.Extension == ".gtkx") {
++ AddNewComponent (path);
+ }
+ }
+
+ void OnFileRemoved (object sender, ProjectFileEventArgs args)
+ {
+ ArrayList toDelete = new ArrayList ();
++ ArrayList toDeleteGroups = new ArrayList ();
+
+ ParsedDocument doc = ProjectDomService.GetParsedDocument (ProjectDomService.GetProjectDom (args.Project), args.ProjectFile.Name);
+ if (doc == null || doc.CompilationUnit == null)
+@@ -350,12 +408,22 @@
+
+ foreach (IType t in doc.CompilationUnit.Types) {
+ GuiBuilderWindow win = GetWindowForClass (t.FullName);
+- if (win != null)
++ if (win != null) {
+ toDelete.Add (win);
++ continue;
++ }
++
++ Stetic.ActionGroupInfo group = GetActionGroup (t.FullName);
++ if (group != null) {
++ toDeleteGroups.Add (group);
++ }
+ }
+-
++
+ foreach (GuiBuilderWindow win in toDelete)
+ Remove (win);
++
++ foreach (Stetic.ActionGroupInfo group in toDeleteGroups)
++ RemoveActionGroup (group);
+ }
+
+ void OnGroupsChanged (object s, EventArgs a)
+@@ -424,6 +492,13 @@
+ return form;
+ }
+ }
++
++ if (formInfosRemoved != null) {
++ foreach (GuiBuilderWindow form in formInfosRemoved) {
++ if (CodeBinder.GetObjectName (form.RootWidget) == className)
++ return form;
++ }
++ }
+ return null;
+ }
+
+@@ -460,7 +535,7 @@
+
+ public Stetic.ActionGroupInfo GetActionGroup (string name)
+ {
+- return SteticProject.GetActionGroup (name);
++ return (SteticProject != null) ? SteticProject.GetActionGroup (name) : null;
+ }
+
+ public FilePath GetSourceCodeFile (Stetic.ProjectItemInfo obj)
+@@ -489,8 +564,9 @@
+
+ public IType FindClass (string className, bool getUserClass)
+ {
+- FilePath gui_folder = GtkDesignInfo.FromProject (project).GtkGuiFolder;
++ FilePath gui_folder = GtkDesignInfo.FromProject (project).SteticFolder;
+ ProjectDom ctx = GetParserContext ();
++
+ if (ctx == null)
+ return null;
+ IEnumerable<IType> classes = ctx.Types;
+@@ -502,7 +578,9 @@
+ // Return this class only if it is declared outside the gtk-gui
+ // folder. Generated partial classes will be ignored.
+ foreach (IType part in cls.Parts) {
+- if (part.CompilationUnit != null && !part.CompilationUnit.FileName.IsNullOrEmpty && !part.CompilationUnit.FileName.IsChildPathOf (gui_folder)) {
++ if (part.CompilationUnit.FileName.FullPath.IsChildPathOf (gui_folder))
++ continue;
++ if (part.CompilationUnit != null && !part.CompilationUnit.FileName.IsNullOrEmpty && !part.CompilationUnit.FileName.FileName.Contains ("generated")) {
+ return part;
+ }
+ }
+@@ -557,8 +635,10 @@
+
+ // Make sure the target gtk version is properly set
+ if (gproject.TargetGtkVersion != target_version) {
++ if (gproject.TargetGtkVersion != string.Empty) {
++ needsSave = true;
++ }
+ gproject.TargetGtkVersion = target_version;
+- needsSave = true;
+ }
+
+ string outLib = project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration);
+@@ -571,8 +651,11 @@
+
+ // See if something has changed
+ if (LibrariesChanged (oldLibs, internalLibs, newLibs)) {
++ // If oldLibs is empty, gproject was uninitialized, so there are no changes to save
++ if (oldLibs.Length > 0) {
++ needsSave = true;
++ }
+ gproject.SetWidgetLibraries (newLibs, internalLibs);
+- needsSave = true;
+ } else {
+ GuiBuilderService.SteticApp.UpdateWidgetLibraries (false);
+ }
+@@ -611,24 +694,30 @@
+ return files;
+
+ IDotNetLanguageBinding binding = LanguageBindingService.GetBindingPerLanguageName (project.LanguageName) as IDotNetLanguageBinding;
+- string path = Path.Combine (guiFolder, binding.GetFileName ("generated"));
+- if (!System.IO.File.Exists (path)) {
+- // Generate an empty build class
+- CodeDomProvider provider = binding.GetCodeDomProvider ();
+- if (provider == null)
+- throw new UserException ("Code generation not supported for language: " + project.LanguageName);
+- GuiBuilderService.SteticApp.GenerateProjectCode (path, "Stetic", provider, null);
++ CodeDomProvider provider = binding.GetCodeDomProvider ();
++
++ if (provider == null)
++ throw new UserException ("Code generation not supported for language: " + project.LanguageName);
++// string path = Path.Combine (guiFolder, binding.GetFileName ("generated"));
++// if (!System.IO.File.Exists (path)) {
++// GuiBuilderService.SteticApp.GenerateProjectCode (path, "Stetic", provider, null);
++// }
++// files.Add (path);
++//
++// if (Windows != null) {
++// foreach (GuiBuilderWindow win in Windows)
++// files.Add (GuiBuilderService.GenerateSteticCodeStructure (project, win.RootWidget, true, false));
++// }
++//
++// foreach (Stetic.ActionGroupInfo ag in SteticProject.ActionGroups)
++// files.Add (GuiBuilderService.GenerateSteticCodeStructure (project, ag, true, false));
++
++ string extension = "generated." + provider.FileExtension;
++ foreach (string file in Directory.GetFiles (guiFolder)) {
++ if (file.Contains (extension))
++ files.Add (file);
+ }
+- files.Add (path);
+
+- if (Windows != null) {
+- foreach (GuiBuilderWindow win in Windows)
+- files.Add (GuiBuilderService.GenerateSteticCodeStructure (project, win.RootWidget, true, false));
+- }
+-
+- foreach (Stetic.ActionGroupInfo ag in SteticProject.ActionGroups)
+- files.Add (GuiBuilderService.GenerateSteticCodeStructure (project, ag, true, false));
+-
+ return files;
+ }
+ }
+Index: MonoDevelop.GtkCore.GuiBuilder/ChangeLog
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/ChangeLog (revision 0)
++++ MonoDevelop.GtkCore.GuiBuilder/ChangeLog (revision 125)
+@@ -0,0 +1,75 @@
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GuiBuilderProject.cs:
++
++2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GuiBuilderProject.cs:
++ * GuiBuilderService.cs:
++
++2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GuiBuilderView.cs:
++ * GuiBuilderProject.cs:
++ * GuiBuilderService.cs:
++ * GuiBuilderDisplayBinding.cs:
++ * ActionGroupDisplayBinding.cs:
++
++2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GuiBuilderProject.cs: Generate stetic code after a project converting
++ * GuiBuilderService.cs:
++ * GuiBuilderDisplayBinding.cs: Don't use component display binding for
++ generated partial files
++
++2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderView.cs: Raise OnDirtyChanged after saving.
++ * CombinedDesignView.cs: Track Api Changes.
++
++2010-08-05 Krzysztof Marecki <freefirma@gmail.com>
++
++ * GuiBuilderView.cs: Remove ModifiedChanged handler
++
++2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
++
++ * CodeBinder.cs: Bump Api
++ * GuiBuilderWindow.cs:
++ * GuiBuilderService.cs:
++ * CombinedDesignView.cs:
++ * ActionGroupDisplayBinding.cs:
++
++2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderProject.cs: When Updatinglibraries don't save
++ if Stetic.Project was uninitialized
++
++2010-07-27 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderView.cs:
++ * CombinedDesignView.cs:
++
++2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderProject.cs:
++ * GuiBuilderService.cs:
++
++2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderProject.cs:
++ * CombinedDesignView.cs:
++
++2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderProject.cs:
++
++2010-06-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderProject.cs: Add Convert method
++
++2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
++
++ * GuiBuilderProject.cs:
++ * GuiBuilderService.cs:
++ * GtkProjectServiceExtension.cs:
++
+Index: MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs (working copy)
+@@ -203,7 +203,7 @@
+ IdeApp.ProjectOperations.Save (Project.Project);
+
+ // Make sure the database is up-to-date
+- ProjectDomService.Parse (Project.Project, cls.CompilationUnit.FileName, null);
++ ProjectDomService.Parse (Project.Project, cls.CompilationUnit.FileName);
+ }
+
+ void AddSignalsRec (CodeTypeDeclaration type, Stetic.Component comp)
+Index: MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs (working copy)
+@@ -79,7 +79,7 @@
+ {
+ gproject = window.Project;
+ GtkDesignInfo info = GtkDesignInfo.FromProject (gproject.Project);
+- gproject.SteticProject.ImagesRootPath = FileService.AbsoluteToRelativePath (info.GtkGuiFolder, gproject.Project.BaseDirectory);
++ gproject.SteticProject.ImagesRootPath = FileService.AbsoluteToRelativePath (info.SteticFolder, gproject.Project.BaseDirectory);
+ gproject.UpdateLibraries ();
+ LoadDesigner ();
+ }
+@@ -121,7 +121,7 @@
+
+ gproject.Unloaded += OnDisposeProject;
+
+- designer = gproject.SteticProject.CreateWidgetDesigner (window.RootWidget, false);
++ designer = gproject.SteticProject.CreateWidgetDesigner (window.RootWidget);
+
+ // Designer page
+ designerPage.ClearChild ();
+@@ -138,7 +138,7 @@
+ codeBinder = new CodeBinder (gproject.Project, new OpenDocumentFileProvider (), designer.RootComponent);
+
+ designer.BindField += OnBindWidgetField;
+- designer.ModifiedChanged += OnWindowModifiedChanged;
++ designer.Changed += OnChanged;
+ designer.SignalAdded += OnSignalAdded;
+ designer.SignalRemoved += OnSignalRemoved;
+ designer.SignalChanged += OnSignalChanged;
+@@ -194,7 +194,7 @@
+
+ gproject.Unloaded -= OnDisposeProject;
+ designer.BindField -= OnBindWidgetField;
+- designer.ModifiedChanged -= OnWindowModifiedChanged;
++ designer.Changed -= OnChanged;
+ designer.SignalAdded -= OnSignalAdded;
+ designer.SignalRemoved -= OnSignalRemoved;
+ designer.SignalChanged -= OnSignalChanged;
+@@ -292,7 +292,7 @@
+ AddButton (GettextCatalog.GetString ("Actions"), actionsPage);
+ }
+
+- void OnWindowModifiedChanged (object s, EventArgs args)
++ void OnChanged (object s, EventArgs args)
+ {
+ if (IsDirty)
+ OnContentChanged (args);
+@@ -351,6 +351,7 @@
+ }
+
+ gproject.Save (true);
++ OnDirtyChanged (EventArgs.Empty);
+ }
+
+ public override bool IsDirty {
+Index: MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs (working copy)
+@@ -89,7 +89,7 @@
+ if (targetObject == null)
+ return;
+
+- ParsedDocument doc = ProjectDomService.Parse (project, fileName, null);
++ ParsedDocument doc = ProjectDomService.Parse (project, fileName);
+ classFile = fileName;
+
+ if (doc != null && doc.CompilationUnit != null) {
+@@ -266,7 +266,7 @@
+ ArrayList matches = new ArrayList ();
+ ICompilationUnit unit = null;
+ ProjectDom ctx = gproject.GetParserContext ();
+- ParsedDocument doc = ProjectDomService.Parse (project, classFile, null);
++ ParsedDocument doc = ProjectDomService.Parse (project, classFile);
+ if (doc != null && doc.CompilationUnit != null) {
+ unit = doc.CompilationUnit;
+ foreach (IType fcls in unit.Types) {
+Index: MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs (working copy)
+@@ -200,6 +200,7 @@
+
+ public override void Load (string fileName)
+ {
++ ShowPage (1);
+ ContentName = fileName;
+ content.Load (fileName);
+ }
+@@ -257,7 +258,9 @@
+ {
+ }
+
+- public override object GetContent (Type type)
++// public override object GetContent (Type type)
++// public override T GetContent<T> ()
++ public override T GetContent<T> ()
+ {
+ // if (type == typeof(IEditableTextBuffer)) {
+ // // Intercept the IPositionable interface, since we need to
+@@ -268,18 +271,12 @@
+ // return null;
+ // }
+ //
+- object ob = base.GetContent (type);
+- if (ob != null)
+- return ob;
+- else if (content != null)
+- return content.GetContent (type);
+- else
+- return null;
++ return base.GetContent<T> () ?? content.GetContent<T> ();
+ }
+
+ public void JumpTo (int line, int column)
+ {
+- IEditableTextBuffer ip = (IEditableTextBuffer) content.GetContent (typeof(IEditableTextBuffer));
++ IEditableTextBuffer ip = (IEditableTextBuffer) content.GetContent<IEditableTextBuffer> ();
+ if (ip != null) {
+ ShowPage (0);
+ ip.SetCaretTo (line, column);
+Index: MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs
+===================================================================
+--- MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs (revision 17)
++++ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs (working copy)
+@@ -35,7 +35,9 @@
+
+ if (gen.Messages != null) {
+ foreach (string s in gen.Messages)
+- res.AddWarning (info.GuiBuilderProject.File, 0, 0, null, s);
++// res.AddWarning (info.GuiBuilderProject.File, 0, 0, null, s);
++// TODO: Add gtkx file name in the Generator
++ res.AddWarning ("", 0, 0, null, s);
+
+ if (gen.Messages.Length > 0)
+ info.ForceCodeGenerationOnBuild ();
diff --git a/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/ChangeLog
new file mode 100644
index 0000000000..3e2aea8cac
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/ChangeLog
@@ -0,0 +1,50 @@
+2010-08-27 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gui.stetic:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gui.stetic:
+ * MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gui.stetic:
+
+2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gui.stetic:
+
+2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gui.stetic:
+
+2010-08-05 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gui.stetic:
+
+2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gui.stetic:
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gui.stetic:
+
+2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gui.stetic:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gui.stetic:
+ * MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs:
+
+2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gui.stetic:
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * gui.stetic:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs
new file mode 100644
index 0000000000..0af9212faa
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.cs
@@ -0,0 +1,40 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ public partial class GtkDesignerOptionsPanelWidget
+ {
+ private global::Gtk.VBox vbox2;
+
+ private global::Gtk.CheckButton checkSwitchLayout;
+
+ protected virtual void Build ()
+ {
+ global::Stetic.Gui.Initialize (this);
+ // Widget MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget
+ global::Stetic.BinContainer.Attach (this);
+ this.Name = "MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget";
+ // Container child MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget.Gtk.Container+ContainerChild
+ this.vbox2 = new global::Gtk.VBox ();
+ this.vbox2.Name = "vbox2";
+ this.vbox2.Spacing = 6;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.checkSwitchLayout = new global::Gtk.CheckButton ();
+ this.checkSwitchLayout.CanFocus = true;
+ this.checkSwitchLayout.Name = "checkSwitchLayout";
+ this.checkSwitchLayout.Label = global::Mono.Unix.Catalog.GetString ("Automatically switch to the \"GUI Builder\" layout when opening the designer");
+ this.checkSwitchLayout.DrawIndicator = true;
+ this.checkSwitchLayout.UseUnderline = true;
+ this.vbox2.Add (this.checkSwitchLayout);
+ global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.checkSwitchLayout]));
+ w1.Position = 0;
+ w1.Expand = false;
+ w1.Fill = false;
+ this.Add (this.vbox2);
+ if ((this.Child != null)) {
+ this.Child.ShowAll ();
+ }
+ this.Hide ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs
new file mode 100644
index 0000000000..b7650fd16e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.cs
@@ -0,0 +1,183 @@
+// ------------------------------------------------------------------------------
+// <autogenerated>
+// This code was generated by a tool.
+// Mono Runtime Version: 2.0.50727.1433
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </autogenerated>
+// ------------------------------------------------------------------------------
+
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace MonoDevelop.GtkCore.Dialogs
+{
+ public partial class ProjectConversionDialog
+ {
+ private global::Gtk.HBox hbox;
+
+ private global::Gtk.Alignment alignmentLogo;
+
+ private global::Gtk.Image imageLogo;
+
+ private global::Gtk.VBox vbox2;
+
+ private global::Gtk.Label labelProject;
+
+ private global::Gtk.Label labelInfo;
+
+ private global::Gtk.HSeparator hseparator1;
+
+ private global::Gtk.HBox hbox1;
+
+ private global::Gtk.Label labelFolder;
+
+ private global::Gtk.Entry entryFolder;
+
+ private global::Gtk.CheckButton checkBackup;
+
+ private global::Gtk.Button buttonConvert;
+
+ protected virtual void Build ()
+ {
+ global::Stetic.Gui.Initialize (this);
+ // Widget MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog
+ this.Name = "MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog";
+ this.Title = global::Mono.Unix.Catalog.GetString ("Project Name");
+ this.WindowPosition = ((global::Gtk.WindowPosition)(4));
+ this.Modal = true;
+ this.SkipTaskbarHint = true;
+ // Internal child MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.VBox
+ global::Gtk.VBox w1 = this.VBox;
+ w1.Name = "dialog1_VBox";
+ w1.BorderWidth = ((uint)(2));
+ // Container child dialog1_VBox.Gtk.Box+BoxChild
+ this.hbox = new global::Gtk.HBox ();
+ this.hbox.Name = "hbox";
+ this.hbox.Spacing = 6;
+ // Container child hbox.Gtk.Box+BoxChild
+ this.alignmentLogo = new global::Gtk.Alignment (1f, 0.15f, 1f, 0f);
+ this.alignmentLogo.Name = "alignmentLogo";
+ // Container child alignmentLogo.Gtk.Container+ContainerChild
+ this.imageLogo = new global::Gtk.Image ();
+ this.imageLogo.WidthRequest = 180;
+ this.imageLogo.Name = "imageLogo";
+ this.imageLogo.Yalign = 0f;
+ this.imageLogo.Pixbuf = global::Gdk.Pixbuf.LoadFromResource ("gtk-logo.png");
+ this.alignmentLogo.Add (this.imageLogo);
+ this.hbox.Add (this.alignmentLogo);
+ global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox[this.alignmentLogo]));
+ w3.Position = 0;
+ w3.Expand = false;
+ w3.Fill = false;
+ // Container child hbox.Gtk.Box+BoxChild
+ this.vbox2 = new global::Gtk.VBox ();
+ this.vbox2.Name = "vbox2";
+ this.vbox2.Spacing = 6;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.labelProject = new global::Gtk.Label ();
+ this.labelProject.Name = "labelProject";
+ this.labelProject.LabelProp = global::Mono.Unix.Catalog.GetString ("<b><big>GTK# Project Conversion</big></b>");
+ this.labelProject.UseMarkup = true;
+ this.vbox2.Add (this.labelProject);
+ global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.labelProject]));
+ w4.Position = 0;
+ w4.Expand = false;
+ w4.Fill = false;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.labelInfo = new global::Gtk.Label ();
+ this.labelInfo.Name = "labelInfo";
+ this.labelInfo.Xalign = 0f;
+ this.labelInfo.Yalign = 0f;
+ this.labelInfo.LabelProp = global::Mono.Unix.Catalog.GetString ("This project has been created in the previous\nversion of GTK# addin and must be converted. \n\n<b>Following changes will be made :</b>\n\t- split gui.stetic into separate .gtkx files\n\t- split generated.cs into separate helper classes\n\t- remove gtk-gui folder.\n\t- create a designer folder for stock icons\n\t and generated helper classes. ");
+ this.labelInfo.UseMarkup = true;
+ this.labelInfo.Wrap = true;
+ this.vbox2.Add (this.labelInfo);
+ global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.labelInfo]));
+ w5.Position = 1;
+ w5.Expand = false;
+ w5.Fill = false;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.hseparator1 = new global::Gtk.HSeparator ();
+ this.hseparator1.Name = "hseparator1";
+ this.vbox2.Add (this.hseparator1);
+ global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hseparator1]));
+ w6.Position = 2;
+ w6.Expand = false;
+ w6.Fill = false;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.hbox1 = new global::Gtk.HBox ();
+ this.hbox1.Name = "hbox1";
+ this.hbox1.Spacing = 6;
+ // Container child hbox1.Gtk.Box+BoxChild
+ this.labelFolder = new global::Gtk.Label ();
+ this.labelFolder.Name = "labelFolder";
+ this.labelFolder.LabelProp = global::Mono.Unix.Catalog.GetString ("Designer folder name:");
+ this.hbox1.Add (this.labelFolder);
+ global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.labelFolder]));
+ w7.Position = 0;
+ w7.Expand = false;
+ w7.Fill = false;
+ // Container child hbox1.Gtk.Box+BoxChild
+ this.entryFolder = new global::Gtk.Entry ();
+ this.entryFolder.CanFocus = true;
+ this.entryFolder.Name = "entryFolder";
+ this.entryFolder.IsEditable = true;
+
+ this.hbox1.Add (this.entryFolder);
+ global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.entryFolder]));
+ w8.Position = 1;
+ this.vbox2.Add (this.hbox1);
+ global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hbox1]));
+ w9.Position = 3;
+ w9.Expand = false;
+ w9.Fill = false;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.checkBackup = new global::Gtk.CheckButton ();
+ this.checkBackup.CanFocus = true;
+ this.checkBackup.Name = "checkBackup";
+ this.checkBackup.Label = global::Mono.Unix.Catalog.GetString ("Make a backup before converting");
+ this.checkBackup.Active = true;
+ this.checkBackup.DrawIndicator = true;
+ this.checkBackup.UseUnderline = true;
+ this.vbox2.Add (this.checkBackup);
+ global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.checkBackup]));
+ w10.Position = 4;
+ w10.Expand = false;
+ w10.Fill = false;
+ this.hbox.Add (this.vbox2);
+ global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.hbox[this.vbox2]));
+ w11.Position = 1;
+ w11.Expand = false;
+ w11.Fill = false;
+ w1.Add (this.hbox);
+ global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(w1[this.hbox]));
+ w12.Position = 0;
+ w12.Expand = false;
+ w12.Fill = false;
+ // Internal child MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog.ActionArea
+ global::Gtk.HButtonBox w13 = this.ActionArea;
+ w13.Name = "dialog1_ActionArea";
+ w13.Spacing = 10;
+ w13.BorderWidth = ((uint)(5));
+ w13.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4));
+ // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
+ this.buttonConvert = new global::Gtk.Button ();
+ this.buttonConvert.CanDefault = true;
+ this.buttonConvert.CanFocus = true;
+ this.buttonConvert.Name = "buttonConvert";
+ this.buttonConvert.UseUnderline = true;
+ this.buttonConvert.Label = global::Mono.Unix.Catalog.GetString ("_Convert");
+ this.AddActionWidget (this.buttonConvert, -5);
+ global::Gtk.ButtonBox.ButtonBoxChild w14 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w13[this.buttonConvert]));
+ w14.Expand = false;
+ w14.Fill = false;
+ if ((this.Child != null)) {
+ this.Child.ShowAll ();
+ }
+ this.DefaultWidth = 532;
+ this.DefaultHeight = 292;
+ this.Show ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/generated.cs b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/generated.cs
new file mode 100644
index 0000000000..aa96390c4a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/generated.cs
@@ -0,0 +1,82 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace Stetic
+{
+ internal class Gui
+ {
+ private static bool initialized;
+
+ static internal void Initialize (Gtk.Widget iconRenderer)
+ {
+ if ((Stetic.Gui.initialized == false)) {
+ Stetic.Gui.initialized = true;
+ }
+ }
+ }
+
+ internal class BinContainer
+ {
+ private Gtk.Widget child;
+
+ private Gtk.UIManager uimanager;
+
+ public static BinContainer Attach (Gtk.Bin bin)
+ {
+ BinContainer bc = new BinContainer ();
+ bin.SizeRequested += new Gtk.SizeRequestedHandler (bc.OnSizeRequested);
+ bin.SizeAllocated += new Gtk.SizeAllocatedHandler (bc.OnSizeAllocated);
+ bin.Added += new Gtk.AddedHandler (bc.OnAdded);
+ return bc;
+ }
+
+ private void OnSizeRequested (object sender, Gtk.SizeRequestedArgs args)
+ {
+ if ((this.child != null)) {
+ args.Requisition = this.child.SizeRequest ();
+ }
+ }
+
+ private void OnSizeAllocated (object sender, Gtk.SizeAllocatedArgs args)
+ {
+ if ((this.child != null)) {
+ this.child.Allocation = args.Allocation;
+ }
+ }
+
+ private void OnAdded (object sender, Gtk.AddedArgs args)
+ {
+ this.child = args.Widget;
+ }
+
+ public void SetUiManager (Gtk.UIManager uim)
+ {
+ this.uimanager = uim;
+ this.child.Realized += new System.EventHandler (this.OnRealized);
+ }
+
+ private void OnRealized (object sender, System.EventArgs args)
+ {
+ if ((this.uimanager != null)) {
+ Gtk.Widget w;
+ w = this.child.Toplevel;
+ if (((w != null) && typeof(Gtk.Window).IsInstanceOfType (w))) {
+ ((Gtk.Window)(w)).AddAccelGroup (this.uimanager.AccelGroup);
+ this.uimanager = null;
+ }
+ }
+ }
+ }
+
+ internal class ActionGroups
+ {
+ public static Gtk.ActionGroup GetActionGroup (System.Type type)
+ {
+ return Stetic.ActionGroups.GetActionGroup (type.FullName);
+ }
+
+ public static Gtk.ActionGroup GetActionGroup (string name)
+ {
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/gui.stetic b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/gui.stetic
new file mode 100644
index 0000000000..819d4c1aa8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/gtk-gui/gui.stetic
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="utf-8"?>
+<stetic-interface>
+ <configuration>
+ <images-root-path>..</images-root-path>
+ <target-gtk-version>2.12</target-gtk-version>
+ </configuration>
+ <import>
+ <widget-library name="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.GtkCore2/libsteticui2.dll" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.GtkCore2/libstetic2.dll" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.Deployment/MonoDevelop.Deployment.dll" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.dll" />
+ <widget-library name="../../../../build/bin/MonoDevelop.Ide.dll" />
+ <widget-library name="../../../../build/bin/Mono.TextEditor.dll" />
+ <widget-library name="MonoDevelop.Ide, Version=2.4.0.0, Culture=neutral" />
+ <widget-library name="Mono.TextEditor, Version=1.0.0.0, Culture=neutral" />
+ <widget-library name="../../../../build/AddIns/MonoDevelop.GtkCore2/MonoDevelop.GtkCore2.dll" internal="true" />
+ </import>
+ <widget class="Gtk.Bin" id="MonoDevelop.GtkCore.Dialogs.GtkDesignerOptionsPanelWidget" design-size="503 22">
+ <property name="MemberName" />
+ <property name="Visible">False</property>
+ <child>
+ <widget class="Gtk.VBox" id="vbox2">
+ <property name="MemberName" />
+ <property name="Spacing">6</property>
+ <child>
+ <widget class="Gtk.CheckButton" id="checkSwitchLayout">
+ <property name="MemberName" />
+ <property name="CanFocus">True</property>
+ <property name="Label" translatable="yes">Automatically switch to the "GUI Builder" layout when opening the designer</property>
+ <property name="DrawIndicator">True</property>
+ <property name="HasLabel">True</property>
+ <property name="UseUnderline">True</property>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="Gtk.Dialog" id="MonoDevelop.GtkCore.Dialogs.ProjectConversionDialog" design-size="532 308">
+ <property name="MemberName" />
+ <property name="Title" translatable="yes">Project Name</property>
+ <property name="WindowPosition">CenterOnParent</property>
+ <property name="Modal">True</property>
+ <property name="SkipTaskbarHint">True</property>
+ <property name="Buttons">1</property>
+ <property name="HelpButton">False</property>
+ <child internal-child="VBox">
+ <widget class="Gtk.VBox" id="dialog1_VBox">
+ <property name="MemberName" />
+ <property name="BorderWidth">2</property>
+ <child>
+ <widget class="Gtk.HBox" id="hbox">
+ <property name="MemberName" />
+ <property name="Spacing">6</property>
+ <child>
+ <widget class="Gtk.Alignment" id="alignmentLogo">
+ <property name="MemberName" />
+ <property name="Yscale">0</property>
+ <property name="Xalign">1</property>
+ <property name="Yalign">0.15</property>
+ <child>
+ <widget class="Gtk.Image" id="imageLogo">
+ <property name="MemberName" />
+ <property name="WidthRequest">180</property>
+ <property name="Yalign">0</property>
+ <property name="Pixbuf">resource:gtk-logo.png</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.VBox" id="vbox2">
+ <property name="MemberName" />
+ <property name="Spacing">6</property>
+ <child>
+ <widget class="Gtk.Label" id="labelProject">
+ <property name="MemberName" />
+ <property name="LabelProp" translatable="yes">&lt;b&gt;&lt;big&gt;GTK# Project Conversion&lt;/big&gt;&lt;/b&gt;</property>
+ <property name="UseMarkup">True</property>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.Label" id="labelInfo">
+ <property name="MemberName" />
+ <property name="Xalign">0</property>
+ <property name="Yalign">0</property>
+ <property name="LabelProp" translatable="yes">This project has been created in the previous
+version of GTK# addin and must be converted.
+
+&lt;b&gt;Following changes will be made :&lt;/b&gt;
+ - split gui.stetic into separate .gtkx files
+ - split generated.cs into separate helper classes
+ - remove gtk-gui folder.
+ - create a designer folder for stock icons
+ and generated helper classes.</property>
+ <property name="UseMarkup">True</property>
+ <property name="Wrap">True</property>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.HSeparator" id="hseparator1">
+ <property name="MemberName" />
+ </widget>
+ <packing>
+ <property name="Position">2</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.HBox" id="hbox1">
+ <property name="MemberName" />
+ <property name="Spacing">6</property>
+ <child>
+ <widget class="Gtk.Label" id="labelFolder">
+ <property name="MemberName" />
+ <property name="LabelProp" translatable="yes">Designer folder name:</property>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.Entry" id="entryFolder">
+ <property name="MemberName" />
+ <property name="CanFocus">True</property>
+ <property name="IsEditable">True</property>
+ <property name="InvisibleChar">●</property>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="AutoSize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">3</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.CheckButton" id="checkBackup">
+ <property name="MemberName" />
+ <property name="CanFocus">True</property>
+ <property name="Label" translatable="yes">Make a backup before converting</property>
+ <property name="Active">True</property>
+ <property name="DrawIndicator">True</property>
+ <property name="HasLabel">True</property>
+ <property name="UseUnderline">True</property>
+ </widget>
+ <packing>
+ <property name="Position">4</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">True</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child internal-child="ActionArea">
+ <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
+ <property name="MemberName" />
+ <property name="Spacing">10</property>
+ <property name="BorderWidth">5</property>
+ <property name="Size">1</property>
+ <property name="LayoutStyle">End</property>
+ <child>
+ <widget class="Gtk.Button" id="buttonConvert">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="Type">TextOnly</property>
+ <property name="Label" translatable="yes">_Convert</property>
+ <property name="UseUnderline">True</property>
+ <property name="ResponseId">-5</property>
+ </widget>
+ <packing>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</stetic-interface> \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.GtkCore2/gui.glade b/main/src/addins/MonoDevelop.GtkCore2/gui.glade
new file mode 100644
index 0000000000..92f5740b91
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/gui.glade
@@ -0,0 +1,710 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+<requires lib="gnome"/>
+
+<widget class="GtkDialog" id="SelectRenamedClassDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">GUI Designer</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="labelMessage">
+ <property name="width_request">549</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">The class that was bound to the design currently edited could not be found. Please select the class you want to bind to the design:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="treeClasses">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="BindDesignDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Bind Widget Design</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area2">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="labelMessage">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">The widget design {0} is not currently bound to a class.</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="radioSelect">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Bind the design to an existing class</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnSelectToggled" last_modification_time="Mon, 27 Feb 2006 15:28:25 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="width_request">24</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Select a class: </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="comboClasses">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="radioCreate">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Create a new class</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radioSelect</property>
+ <signal name="toggled" handler="OnSelectToggled" last_modification_time="Mon, 27 Feb 2006 15:28:54 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="tableNewClass">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">3</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Name:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Namespace:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Location:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label9">
+ <property name="width_request">24</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entryClassName">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnEntryChanged" last_modification_time="Mon, 27 Feb 2006 18:53:06 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entryNamespace">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnEntryChanged" last_modification_time="Mon, 27 Feb 2006 18:53:28 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEventBox" id="fileEntryBox">
+ <property name="visible">True</property>
+ <property name="visible_window">True</property>
+ <property name="above_child">False</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="ConfirmWindowDeleteDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">MonoDevelop</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area3">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton3">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-no</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-9</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-yes</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-8</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-question</property>
+ <property name="icon_size">6</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="label">Are you sure you want to delete the window '{0}'?</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="checkbox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Also remove the file '{0}'</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/icons/ChangeLog
new file mode 100644
index 0000000000..86f901e6a8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/ChangeLog
@@ -0,0 +1,5 @@
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * gtkx.png:
+ * gtk-logo.png:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/actiongroup.png b/main/src/addins/MonoDevelop.GtkCore2/icons/actiongroup.png
new file mode 100644
index 0000000000..de43e0a5c4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/actiongroup.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/dialog.png b/main/src/addins/MonoDevelop.GtkCore2/icons/dialog.png
new file mode 100644
index 0000000000..6e81b2fd60
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/dialog.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo-orig.png b/main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo-orig.png
new file mode 100644
index 0000000000..9809fa4e09
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo-orig.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo.png b/main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo.png
new file mode 100644
index 0000000000..5ebee707d9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/gtk-logo.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/gtkx.png b/main/src/addins/MonoDevelop.GtkCore2/icons/gtkx.png
new file mode 100644
index 0000000000..87a1d7946d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/gtkx.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/image-x-generic.png b/main/src/addins/MonoDevelop.GtkCore2/icons/image-x-generic.png
new file mode 100644
index 0000000000..68da5027cf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/image-x-generic.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/widget.png b/main/src/addins/MonoDevelop.GtkCore2/icons/widget.png
new file mode 100644
index 0000000000..7f5844bbfc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/widget.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/icons/window.png b/main/src/addins/MonoDevelop.GtkCore2/icons/window.png
new file mode 100644
index 0000000000..8f82250f04
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/icons/window.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ChangeLog
new file mode 100644
index 0000000000..4d98b372cf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ChangeLog
@@ -0,0 +1,1793 @@
+2010-10-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+
+2010-10-04 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * TypedClassDescriptor.cs:
+
+2010-09-30 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Registry.cs:
+
+2010-09-30 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Registry.cs:
+ * TypedClassDescriptor.cs:
+
+2010-09-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * wrapper/Bin.cs: Set RootWrapperName
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * DND.cs:
+ * IProject.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * GeneratorContext.cs:
+
+2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * IProject.cs: Remove Modified property, add WasModified method which check state of a given top level
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * GladeUtils.cs: Set ObjectWrapper.RootWrapperName when reading from xml
+ * WidgetUtils.cs:
+ * ObjectReader.cs:
+ * ObjectWrapper.cs:
+ * wrapper/Frame.cs:
+ * wrapper/Window.cs:
+ * wrapper/MenuItem.cs:
+ * wrapper/Expander.cs:
+ * undo/UndoManager.cs:
+ * wrapper/Notebook.cs:
+ * wrapper/Container.cs:
+ * wrapper/OptionMenu.cs:
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ObjectWrapper.cs: Save a root wrapper name
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * IProject.cs:
+ * ErrorWidget.cs:
+
+2010-04-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * editor/ActionMenu.cs: Explicit destroy of children should
+ not be required.
+
+2010-04-30 Mike Krüger <mkrueger@novell.com>
+
+ * editor/ActionMenu.cs: moved code from dispose -> destroy.
+
+2010-04-29 Mike Krüger <mkrueger@novell.com>
+
+ * editor/ActionMenu.cs:
+ * editor/ActionToolbar.cs:
+ * editor/ActionMenuBar.cs: Destroy gtk components instead of
+ disposing them.
+
+2010-04-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * GladeUtils.cs: Fix glade import. GtkWindow and GtkDialog
+ need to be special cased, since we are not creating real
+ Gtk.Window objects anymore.
+
+2010-04-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Misc.cs: Show alignment buttons as toggles.
+
+2010-03-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Widget.cs:
+ * wrapper/Container.cs: When setting the name of a widget,
+ make sure the old name field is also set. Fixes bug #549463
+ - Forms designer renames variables it shouldn't.
+
+2010-01-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * TypedPropertyDescriptor.cs: Don't translate property names
+ in the property grid. See bug #571351.
+
+2010-01-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * GeneratorContext.cs: When loading an icon, don't hardcode
+ the required size. Instead, call SizeLookup to get the
+ correct size for the current theme.
+
+2010-01-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * ImageInfo.cs:
+ * wrapper/Bin.cs:
+ * WidgetUtils.cs:
+ * libstetic.csproj:
+ * ObjectWrapper.cs:
+ * wrapper/Action.cs:
+ * wrapper/Widget.cs:
+ * wrapper/VScale.cs:
+ * wrapper/HScale.cs:
+ * wrapper/MenuBar.cs:
+ * wrapper/Expander.cs:
+ * GeneratorContext.cs:
+ * wrapper/Notebook.cs:
+ * wrapper/ComboBox.cs:
+ * wrapper/Container.cs:
+ * RadioGroupManager.cs:
+ * wrapper/VScrollbar.cs:
+ * ProjectIconFactory.cs:
+ * wrapper/HScrollbar.cs:
+ * wrapper/ToolButton.cs:
+ * wrapper/ActionTree.cs:
+ * wrapper/ActionGroup.cs:
+ * wrapper/ComboBoxEntry.cs:
+ * wrapper/ActionToolbarWrapper.cs:
+ * wrapper/RadioActionGroupManager.cs: Use global:: for type
+ references in generated code.
+
+ * Placeholder.cs:
+ * editor/Flags.cs:
+ * editor/Enumeration.cs:
+ * editor/ActionMenuItem.cs:
+ * editor/ActionToolItem.cs: Fix warnings.
+
+2009-12-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic.csproj: Flush.
+
+2009-12-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Table.cs: Fix table creation issue. Sync call has no
+ effect while loading a widget.
+
+2009-12-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Widget.cs: Fix check for top level window.
+
+2009-11-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * wrapper/MenuBar.cs:
+ * wrapper/ActionToolbarWrapper.cs: Propagate the menu name to
+ the action tree. Fixes bug #540512.
+
+2009-11-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * ObjectReader.cs:
+ * ObjectWrapper.cs:
+ * ClassDescriptor.cs: Ensure the Loading flag is set when
+ loading internal children of a widget.
+
+2009-11-05 Mike Kestner <mkestner@novell.com>
+
+ * wrapper/*.cs: improper new keyword warning cleanup.
+
+2009-10-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * libstetic.csproj: Reference mono-cairo package.
+
+2009-10-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Widget.cs: Don't fire the name changed event while
+ loading.
+
+ * wrapper/Container.cs: Set the loading flag when loading.
+
+2009-10-16 Mike Krüger <mkrueger@novell.com>
+
+ * DND.cs:
+ * WidgetUtils.cs:
+ * CommandDescriptor.cs:
+ * editor/Translatable.cs:
+ * editor/ActionMenuItem.cs: Handled icon loading failures.
+
+2009-09-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Paned.cs: Avoid unnecessary Changed event.
+
+2009-09-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper\Paned.cs: Restore the paned position after
+ realizing. It may have been reset during the realization.
+ Fixes bug #542227.
+
+2009-09-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Widget.cs: Fire name change event when name changes.
+ Fixes bug #540512 - NullReferenceException in stetic
+ generated code.
+
+2009-09-10 Christian Hergert <chris@dronelabs.com>
+
+ * libstetic/libstetic.dll.config: Use quartz on osx.
+
+2009-09-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Action.cs: For stock gtk and gnome icons, use the
+ stock id as base name for the action identifier. Fixes bug
+ #525571.
+
+2009-08-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic.csproj: Updated dependencies. We now depend on
+ gtk# 2.12.8, Mono 2.4, and Mono.Addins 0.4.
+
+2009-08-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Container.cs: Properly validate widget ids when
+ pasting a child. If there is a conflict, the child has to be
+ modified. Fixes bug #530086 - When copy/pasting widgets in
+ stetic, the original is renamed.
+
+2009-08-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Notebook.cs: Fix issue with adding a widget with
+ ShowScrollbars=true to a notebook. Fixes bug 526434 -
+ Notebook Tab Labels Revert Back to "Page 1".
+
+2009-08-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/ComboBox.cs:
+ * wrapper/ComboBoxEntry.cs: Changed the sensitivity mode to
+ 'always on'. Since gtk+ 2.14, empty combos are disabled by
+ default.
+
+2009-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/objects.xml: Fix invalid xml.
+
+2009-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/objects.xml: Fix some default values.
+
+2009-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/objects.xml: Make sure the default value for
+ HasSeparator is true.
+
+2009-07-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/objects.xml: Removed Version=2.6.0.0 specification
+ from Pango.EllipsizeMode type. This allows other GTK
+ versions to work. Patch by Daniel Newton.
+
+
+2009-07-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * ClassDescriptor.cs: When creating a widget instance,
+ initialize the properties after creating the wrapper, since
+ some properties may be implemented in the wrapper. This
+ should fix bug #505083 - hbuttonbox1.cs file being created
+ in gtk-gui causing problems with compilation.
+
+2009-05-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * Placeholder.cs:
+ * libstetic.csproj: Improved the look of placeholders.
+
+2009-05-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * ItemDescriptor.cs: Added missing BindingFlags.Instance flag.
+
+ * wrapper/Container.cs: Fix bug when showing the selection
+ box.
+
+ * TopLevelWindow.cs:
+ * TopLevelDialog.cs:
+ * wrapper/Dialog.cs:
+ * wrapper/Window.cs:
+ * wrapper/objects.xml: Top level windows are not represented
+ using a Gtk.Window anymore at design time. Instead they are
+ represented by TopLevelWindow. This is a regular widget, so
+ window embedding hacks are not required anymore. The same
+ has been done for Gtk.Dialog/TopLevelDialog.
+
+ * libstetic.csproj: Added new files.
+
+ * Makefile.am: Updated.
+
+ * DND.cs: Accept copy as drop target. Fixed the target list.
+
+ * TypedClassDescriptor.cs: Invocation of a constructor does
+ not need an instance reference.
+
+2009-05-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Registry.cs: Make sure GetType can find the type when the
+ provided assembly name does not have version info.
+
+ * libstetic.csproj: Copy the config file to the output dir.
+
+ * TypedPropertyDescriptor.cs: Catch ambiguous match exception
+ when looking for properties.
+
+2009-04-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic.csproj: Don't require a specific gtk# version.
+
+2009-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Registry.cs:
+ * WidgetLibrary.cs: Flush cached data when closing a change
+ set.
+
+2009-02-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/Table.cs:
+ * wrapper/objects.xml: A better fix for the default row/column
+ issue.
+
+2009-02-10 Michael Hutchinson <mhutchinson@novell.com>
+
+ * libstetic.csproj: Don't build with make, since MD can build
+ these just fine.
+
+2009-02-07 Mike Krüger <mkrueger@novell.com>
+
+ * GladeUtils.cs: fixed compiler warning.
+
+2009-02-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic.mdp:
+ * libstetic.csproj: Migrated to MSBuild file format.
+
+2009-01-26 Michael Hutchinson <mhutchinson@novell.com>
+
+ * libstetic.mdp: Flush project format changes.
+
+2009-01-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * wrapper/objects.xml: Added some defaults.
+
+2008-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libstetic.mdp: All projects now require fx 3.5.
+
+2008-09-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * PropertyDescriptor.cs: Use invariant culture when converting types.
+
+2008-07-27 Mike Krüger <mkrueger@novell.com>
+
+
+
+2008-02-23 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp: Removed some unused glade
+ and gnome-sharp references (only the unused). But I'll continue to
+ remove glade, we need to lower the dependency tree a bit.
+
+2008-02-22 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Added IViewContent
+ switching logic (but should be done centrally using the secondaryview
+ paradigmn).
+
+2008-02-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Workaround for mono bug
+ #350432.
+
+2008-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Handle the delete
+ key in TreeViewPad, so it will work event if the shortcut is not
+ defined.
+
+2008-01-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am,
+ icons/pad-widget-tree-16.png: Added widget tree icon.
+
+2008-01-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Update MD version.
+
+2008-01-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Made internal
+ some classes that don't need to be public.
+
+2008-01-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Notify file changes
+ through the FileService.
+
+2008-01-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Stetic code must be
+ generated in the GUI thread. Should fix bug #349505.
+
+2008-01-15 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Feed default layout
+ name to Gettext for translation.
+
+2008-01-15 Michael Hutchinson <mhutchinson@novell.com>
+
+ * templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/ActionGroupPartial.xft.xml,
+ templates/Window.xft.xml, templates/ActionGroup.xft.xml,
+ templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Make template
+ categories translatable.
+
+2008-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Added null check on the
+ result of UpdateFile. Should fix bug #352194.
+
+2008-01-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: Handle
+ projects which don't support the GTK# designer. Window and widget
+ generation options are hidden, and code is never generated. Fixes bug
+ #350632.
+
+2007-12-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Don't update bindings if the
+ file has syntax errors. May fix bug #347590.
+
+2007-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump add-in versions.
+
+2007-12-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am: Update after build reorg.
+
+2007-12-06 Geoff Norton <gnorton@novell.com>
+
+ * Makefile.am: Only build the GtkCore addin if we have gnome-sharp
+ available.
+
+2007-12-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp, lib/libstetic.mdp,
+ Makefile.am: Directory reorganization.
+
+2007-11-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade, MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs: Removed
+ Gnome.FileEntry.
+
+2007-11-09 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: Track
+ LoggingService API changes.
+
+2007-11-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Use RootCombine
+ instead of CurrentOpenCombine when possible.
+
+2007-10-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2007-10-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Fix nullref. Happens
+ when removing a project from a solution while one of the windows of that
+ project is open.
+
+2007-10-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * templates/ActionGroup.xft.xml, templates/ActionGroupPartial.xft.xml,
+ templates/Dialog.xft.xml, templates/DialogPartial.xft.xml,
+ templates/Widget.xft.xml, templates/WidgetPartial.xft.xml,
+ templates/Window.xft.xml, templates/WindowPartial.xft.xml: Use tango
+ file icons. Removed obsolete icons.
+
+2007-10-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Track api changes. Added
+ Description property.
+
+2007-10-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.mdp, lib/libstetic.mdp: Project file names updated by
+ change in MD path functions.
+
+2007-10-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mds, Makefile.am: Added custom command for updating
+ the Stetic sources.
+
+2007-10-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Set a more meaningful category name for
+ addin commands.
+ * MonoDevelop.GtkCore.mdp, MonoDevelop.GtkCore.mds: Updated.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: If the current selection
+ can't be deleted, just ignore the delete command, so the default handler
+ will be executed. Fixes bug #325440.
+
+2007-10-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.mdp: Fix required gtk# version.
+
+2007-10-12 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Applied changes that
+ were neccassary for to the new FileService.
+
+2007-10-11 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Changed calls for
+ the new StringParser.
+
+2007-10-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: In Bind(), don't subscribe the
+ NameChanged event at every call.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: The designer needs to
+ be explicitely destroyed.
+
+2007-10-03 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: No need to implement
+ IComparable; it's done in the base class now.
+
+2007-09-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Assign the selected
+ target gtk# version to the new project.
+
+2007-09-21 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Use ProjectReference.StoredReference
+ rather than ProjectReference.Reference, in order to refer to the actual
+ stored reference string rather than a temporarily bumped version.
+
+2007-09-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Bump MD version.
+
+2007-09-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Implemented an
+ assembly resolver for the stetic app, so assembly widgets registered
+ with .pc files can be found.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs: If a widget dll belongs
+ to a package, store it as a package reference in the toolbox index.
+
+2007-09-19 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Allow setting TargetGtkVersion to
+ DefaultGtkVersion when current value is null.
+
+2007-09-19 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Don't touch GTK# assembly versions
+ when a target version is not set. Don't use gtkVersion=null to represent
+ default version.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Set TargetGtkVersion on new
+ projects. Bump default version to 2.8.
+
+2007-09-17 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.mdp, lib/libstetic.mdp,
+ lib/Makefile.am, MonoDevelop.GtkCore.mds, Makefile.am: Use projects for
+ imported stetic libraries.
+
+2007-09-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Removed access to
+ Component object.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Remove unused method.
+
+2007-09-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/SelectRenamedClassDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs,
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs: Fix warnings.
+
+2007-09-13 Michael Hutchinson <mhutchinson@novell.com>
+
+ * lib/stetic, Makefile.am, lib/Makefile.am: Build stetic from
+ svn:externals.
+ * lib/libsteticui.dll.config, lib/libstetic.dll.config,
+ lib/libstetic.dll, lib/libsteticui.dll: Removed.
+
+2007-09-10 Michael Hutchinson <mhutchinson@novell.com>
+
+ * templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml,
+ templates/ActionGroupPartial.xft.xml, templates/ActionGroup.xft.xml,
+ templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Remove
+ deprecated FileOptions element from templates.
+
+2007-09-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Changed the way to
+ set the active designer (the api changed). Fixed some renaming issues.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Track api changes.
+
+2007-09-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * templates/Window.xft.xml: Oops, PartialTypeSupport should be set to
+ Disabled for non-partial window.
+
+2007-09-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Updated.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs: Use DotNetProject.UsePartialTypes
+ instead of custom setting.
+ * MonoDevelop.GtkCore/WidgetFileTemplatePartialClass.cs,
+ MonoDevelop.GtkCore/WidgetFileTemplateFullClass.cs: No longer needed.
+ * templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml,
+ templates/ActionGroupPartial.xft.xml, templates/ActionGroup.xft.xml,
+ templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Use
+ PartialTypes condition instead of custom file template.
+
+2007-09-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes fixes for bugs #82671, #82527, #82476, #81763 and #81238.
+
+2007-08-31 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs: Changes due to new
+ property infrastructure.
+
+2007-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs: By default use the project name
+ as category name for new custom widgets.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Don't show the full
+ name of widgets in the toolbar.
+
+2007-08-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: In FindClass, make
+ sure the getUserClass parameter is taken into account when the found
+ class is not a multi-part class. Fixes bug #82258.
+
+2007-08-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Removed the CommandService class.
+ Everything is done directly with CommandManager. Moved all extension
+ node types to MD.Components.
+
+2007-08-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.mdp, Makefile.am: Reorganized the extension point
+ hierarchy. Embedded all add-in manifests as resources.
+ * lib/libstetic.dll: Updated from stetic module.
+
+2007-08-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Improved error
+ reporting.
+
+2007-08-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Converted
+ DispatchService to a static class.
+
+2007-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fixed some
+ problems with the target gtk version. It was not assigned to the
+ stetic project. Also fixed some stock icon rendering issues in
+ Stetic.
+
+2007-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes a nullref fix.
+
+2007-07-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Layout switch
+ delay is not needed anymore.
+
+2007-07-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Fix nullref
+ when gtk support is not enabled. Patch by Chris Howie.
+
+2007-07-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Don't try to use the CurrentNode property after adding the file,
+ since it may have changed. Should fix bug #82123.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+ Fixes bugs #81846 and #82144.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fix window
+ source file lookup.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Use the new methods
+ for checking clipboard operations on the current selection.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Include the
+ current project in the list of libraries to show in the toolbox.
+ Fixes bug #82125.
+
+2007-07-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated. Fixes bugs 81977,
+ 81810 and 82052.
+
+2007-07-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Properly rename
+ fields when the widget name is changed. Fixes bug #81976.
+
+2007-07-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Update the
+ properties pad when the focus is on the widget tree pad. Fixes bug
+ #81971.
+
+2007-07-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Added null
+ check.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Track api changes
+ in DesignerSupport. When adding a project reference to a widget
+ library, take into account that widgets may be implemented in a
+ library different from the one providing the widget list.
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: In
+ GetDynamicItems, only return widgets provided by libraries
+ referenced by the project. Don't return widgets from libstetic
+ since those are already included by default in the toolbox.
+ Implemented IToolboxDefaultProvider.
+
+2007-07-03 Mike Krüger <mkrueger@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Changed a bit
+ because of the removal of custom collections in the Ide project.
+
+2007-06-30 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * gui.glade: Fixed capitalization.
+
+2007-06-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs: Don't show windows
+ in the toolbox.
+ * lib/libstetic.dll, lib/libsteticui.dll: Updated from Stetic module.
+
+2007-06-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+
+2007-06-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade, MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Allow selecting
+ the target GTK# version of the project.
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxLoader.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Implemented a
+ toolbox loader, which allows registering assemblies in the toolbox.
+ When a widget from a toolbox is dropped to a window, MD will now
+ add a reference to the required assembly.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll: One last update.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+
+2007-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Set the import
+ file callback when editing project stock icons.
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: The GetResources
+ method only returns resource files now.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-06-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Default pad
+ placement is now specified in the xml file.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: In GetBaseType, use
+ Project.GetWidgetTypes to get all registered wiget types, including
+ base widget types (which were not provided by GetComponentTypes).
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes fix for bug #81785.
+
+2007-05-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Don't include non-public
+ members to the objects.xml file.
+
+2007-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs: Fix feature message.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+ Includes fixes for bugs #81761, #81758 and #81762.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ (UpdateLibraries) Properly check for library changes.
+
+2007-05-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Fixes bugs #80783 and #81683.
+
+2007-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Added new dependency.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from svn. Fixes bug
+ #81590.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: When selecting an
+ image file in the widget designer, import the file into the
+ project.
+
+2007-05-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Added some delay
+ in the code that changes the workbench layout when selecting the
+ designer. Fixes bug #80963.
+
+2007-05-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPalettePad.cs: Removed old
+ palette pad.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Set the 'internal' flag for
+ widgets implemented by private classes.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from svn module.
+ Fixes bugs #80875, #81261, #81365.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: If the project
+ is a library, add itself as an internal widget library, so widgets
+ with internal visibility will be shown.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: When saving a window,
+ use the visibility of the class to set the visibility of the
+ component. Together with all changes done in stetic, fixes bug
+ #80875.
+
+2007-05-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs,
+ MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Track api changes in
+ Stetic.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: Delay
+ library updating until really necessary.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-05-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Copy the .addins.xml file to the output dir.
+
+2007-05-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Copy stetic dlls together with the assembly.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated.
+
+2007-05-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Reference shared assemblies
+ from the correct location.
+
+2007-05-04 Wade Berrier <wberrier@novell.com>
+ * lib/libstetic.dll.config:
+ * lib/libsteticui.dll.config:
+ Fix os attribute formats (mono-config.c separates oses by comma,
+ and ignores or includes the whole string.)
+
+2007-05-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp, Makefile.am:
+ Migration to Mono.Addins.
+
+2007-04-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml, MonoDevelop.GtkCore.mdp,
+ MonoDevelop.GtkCore.Dialogs/GtkFeatureWidget.cs, Makefile.am:
+ Implemented project feature for enabling gtk# support in new
+ projects.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: Use
+ Menu icon size in the project pad.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+
+2007-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Show a
+ relative path in the window delete confirm dialog, since the
+ absolute path may take too much space.
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * templates/DialogPartial.xft.xml, templates/Dialog.xft.xml: Add
+ Ok/Cancel buttons by default in new dialogs.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ Includes fixes for bugs 81033, 81086, 81239, 81143, 81014 and
+ 81015.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Allow pasting when
+ a placeholder is selected. Fixes bug #81246.
+
+2007-03-28 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/StockIconsNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.mdp, Makefile.am, icons/image-x-generic.png:
+ Show a "Stock Icons" node in the User Interface folder. It's easier
+ to discover than the context menu option.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.Commands/GladeCommands.cs: Added menu option
+ for opening the gtk# settings.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Don't crash if
+ the gtk-gui folder doesn't exist. Fixes bug #81152.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Hide the border
+ of the combined view notebook.
+
+2007-03-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated from stetic module. Fixes NRE crash.
+
+2007-03-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Fix null ref.
+
+2007-03-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Register a new toolbox loader. Removed
+ old properties pads.
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Added reference to
+ MonoDevelop.DesignerSupport.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from svn module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/PropertiesWidget.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs: Integrate Stetic
+ widgets in the main toolbox.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Implement
+ ICustomPropertyPadProvider and return the Stetic property pad.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs: Renamed.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Fix warning.
+
+2007-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ Updated from Stetic module. Includes fix for bug #80864.
+
+2007-02-20 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from SVN. Fixes some
+ memory leaks and bug #79453.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Explicitely
+ destroy notebook children, since notebook doesnt do it because of a
+ gtk bug.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Some fixes in the
+ dispose code.
+
+2007-02-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Use
+ ProjectOperations.SaveProject to save projects.
+
+2007-02-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Change add-in versions to 0.13.
+
+2007-02-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Fix nullref.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs: Log
+ error message.
+ * Makefile.am, MonoDevelop.GtkCore.mdp: Synchronized MD project and
+ makefile.
+
+2007-02-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Avoid throwing
+ delayed events after the project has been disposed.
+
+2007-02-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added missing
+ null check.
+
+2007-02-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Ask for user
+ confirmation when reloading a designer only when the designer has
+ unsaved changes.
+
+2007-02-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs,
+ MonoDevelop.GtkCore/GtkDesignInfo.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Detect external
+ changes in the gui.stetic files, and reload it when it changes.
+ Take into account that the load of gui.stetic can fail. Added
+ several workarounds for this case.
+
+2007-02-13 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from SVN. Includes
+ fixes for bugs #80722, #79427 and #80127.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Store some
+ Stetic configuration in the MD properties.
+
+2007-02-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade, MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Added options
+ for enabling/disabling gtk support, and for gettext support.
+ * MonoDevelop.GtkCore.addin.xml: Change options panel name.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Make sure the
+ MD project is saved together with the stetic project, if necessary.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Avoid saving
+ the MD project twice.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectNodeBuilder.cs: If gtk
+ integration status changes for a project, refresh the tree.
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs: Null check.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added support for gettext and
+ gettext class options for generated code.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Added events for notifying
+ when the gtk integration status changes for a project.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * Makefile.am: distcheck fixes
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs,
+ MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: When a designer
+ project is disposed, hide the designer view in the editor.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Factorized some code into GtkDesignInfo.
+
+2007-02-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Make sure the code generation
+ extension is executed before the last step.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Hide the add window commands when the project is not DotNet
+ * MonoDevelop.GtkCore.mdp, lib/libsteticui.dll, lib/libstetic.dll:
+ Updated.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Intercept calls
+ to the IPositionable interface, and show the editor page when
+ jumping to a line.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: When looking for
+ the window class, avoid returning the generated partial class.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Show the editor
+ page when jumping to a signal handler.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Warn the user if
+ the gtk-sharp-2 package can't be found. Some distros don't include
+ the .pc file in the gtk# package, only in the -devel package.
+
+2007-02-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from Stetic module.
+
+2007-01-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll.config, lib/libsteticui.dll, lib/libstetic.dll,
+ lib/libsteticui.dll.config: Updated from Stetic module.
+
+2007-01-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs,
+ MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Track api
+ changes in Document class.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated form Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Removed
+ implementation of all text editor interfaces. Now the view
+ overrides GetContent and calls editor.GetContent when a requested
+ interface is not found.
+
+2007-01-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Removed unused namespace.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Use the new base-type property
+ to describe custom widgets. When looking for properties and events,
+ look in the base classes as well as in the widget class.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * Makefile.am,
+ MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/ProjectSignalDescriptor.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/ProjectPropertyDescriptor.cs:
+ Removed unused files. All widget library functionality has been
+ moved to stetic.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Removed all
+ widget library management, which has been moved to Stetic.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Added some null checks.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Use the new way
+ of managing dependencies in projects.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml: The
+ window constructor now takes the window type.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Some gui
+ improvements and added some null checks.
+
+2007-01-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't crash if the
+ designer can't be loaded for some reason.
+
+2007-01-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml,
+ MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs,
+ MonoDevelop.GtkCore/GtkCoreService.cs,
+ MonoDevelop.GtkCore/WidgetFileTemplatePartialClass.cs,
+ MonoDevelop.GtkCore/WidgetFileTemplateFullClass.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs,
+ MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs,
+ templates/WidgetPartial.xft.xml, templates/Widget.xft.xml,
+ templates/WindowPartial.xft.xml, templates/Window.xft.xml,
+ templates/ActionGroupPartial.xft.xml,
+ templates/ActionGroup.xft.xml, templates/DialogPartial.xft.xml,
+ templates/Dialog.xft.xml: Implemented support for generating code
+ in partial classes.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Use the
+ correct method for saving the project.
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs: Refresh the user
+ interface folder when the gui project is reloaded.
+ * MonoDevelop.GtkCore.mdp: Updated.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added support for partial
+ classes. In the GuiBuilderProject property, don't update the
+ gtk-gui folder since this call may change the contents of the
+ project, and weird things happen when called by the project pad to
+ fill the tree.
+ * lib/libsteticui.dll, lib/libstetic.dll: Updated from stetic module.
+ * Makefile.am: Added new files.
+ * MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs,
+ MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs:
+ Make it work even when the assembly it references has been deleted
+ (maybe as a result of cleaning a project). In this case the widget
+ library is shown as empty.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added support
+ for Loading/Unloading a project, to optimize use of memory for
+ solutions with many gui projects. Implemented support for
+ generating code in partial classes.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs,
+ MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Implemented
+ support for generating code in partial classes. Implemented support
+ for UNDO/REDO.
+ * MonoDevelop.GtkCore.GuiBuilder/GtkProjectServiceExtension.cs:
+ Generation of gui code is now done from the Build method of a
+ project service extension. Fixes some issues when building a
+ project which contains custom components.
+
+2006-12-17 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Track API changes in
+ FileService.
+
+2006-12-13 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Don't
+ generate stetic code if CurrentOpenCombine is null.
+
+2006-12-07 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * MonoDevelop.GtkCore.mdp: Updated to it can be
+ built from MonoDevelop.
+
+2006-11-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Simplified the
+ code by using global events from the Ide, instead of combine
+ events.
+
+2006-10-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added RemoveExportedWidget method.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: track
+ API changes.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: If the name of a
+ widget changes and it is being exported, update it in the objects.xml
+ file. Fixes bug #79656.
+
+2006-09-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module. It provides a redesigned API
+ which will allow running designers in a separate process.
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs:
+ * MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs:
+ * MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPalettePad.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs:
+ Track api changes.
+
+ * MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs: Make sure
+ parse information is up to date before loading an assembly library.
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: Make sure this object
+ is always alive when remoted.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Added null check.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Not needed anymore.
+ * MonoDevelop.GtkCore.addin.xml: Removed build step. Code generation
+ is done now before compiling.
+
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectWidgetLibrary.cs:
+ * MonoDevelop.GtkCore.WidgetLibrary/CachedProjectWidgetLibrary.cs:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: ProjectWidgetLibrary is not used
+ anymore. All libraries are now handled by AssemblyReferenceWidgetLibrary.
+
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopWidgetActionBar.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopActionGroupToolbar.cs:
+ Moved to Stetic.
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-09-23 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track api changes.
+
+2006-09-19 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * .: Added svn:ignore for MonoDevelop.GtkCore.pidb
+
+2006-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from stetic module. Includes fix for bug #79247.
+
+2006-09-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from stetic module.
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ Save the project after editing the icons.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Set the
+ ResourceProvider for the main stetic project. Added null check.
+
+2006-08-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Fixed bug about
+ adding the wrong widget as action designer page.
+
+2006-08-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Only export properties which
+ return primitive types. Fixes bug #79195.
+ * lib/*: Updated from stetic module.
+ * MonoDevelop.GtkCore.Dialogs/BindDesignDialog.cs: Unsubscribe close
+ event when done.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Handle designer
+ commands in its own tab page.
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Explicitely dispose
+ custom widgets to avoid memory leaks.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Track api changes.
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-08-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * gui.glade: Minor fix.
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Track api
+ changes.
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Stetic files don't need
+ to be added as resource to projects.
+ * MonoDevelop.GtkCore.Dialogs/ConfirmWindowDeleteDialog.cs: Make it
+ work for action groups.
+ * lib/*: several fixes.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Added method
+ for removing an action group.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Track API changes
+ in Stetic. Properly bound edit commands from the main menu.
+
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs:
+ * MonoDevelop.GtkCore.addin.xml: Implemented Open and Delete
+ commands for global action groups.
+
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-08-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module. Includes fixes for
+ bugs #79043, #79044 and #79045
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Don't
+ crash if something goes wrong when binding a class.
+ Fixed nullref.
+
+2006-08-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ CreateContentForFile should not load the file, just create
+ the view.
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Add
+ support for IEncodedTextContent.
+
+2006-08-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ Set the resource provider before loading the project.
+ Fixes bug #78966.
+
+ * libs/*: Updated from Stetic module. Fixes several bugs:
+ 78938, 78916, 78909, 78956, and 78867.
+
+2006-07-27 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs:
+ Added null check.
+
+ * MonoDevelop.GtkCore.WidgetLibrary/AssemblyReferenceWidgetLibrary.cs:
+ Get the parser context using the assembly file name, not the full
+ assembly name.
+
+2006-07-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Factorized several
+ more or less duplicate methods into GuiBuilderProject, specially
+ methods for locating the class bound to a window. GuiBuilderProject
+ now will explicitelly update the parser database the first time it
+ needs to locate a class, so it will work even if the parser service
+ is busy parsing assemblies.
+
+2006-07-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated from stetic module. Fixes a bug
+ in the table wrapper which may cause an endless loop.
+
+2006-07-05 Matej Urbas <matej.urbas@gmail.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.WidgetLibrary/BaseWidgetLibrary.cs: Updated to use
+ ReturnType as BaseTypes in IClass instances.
+
+2006-07-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Fixed automatic
+ layout switch policy.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Fix showing of
+ action group view.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Properly
+ bind actions when pressing "BindToField".
+
+ * MonoDevelop.GtkCore.addin.xml: Updated versions.
+
+2006-06-29 Michael Hutchinson <m.j.hutchinson@gmail.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Only display WidgetBuilderOptionPanel
+ for "DotNet" projects.
+
+2006-06-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Switch to the
+ designer workbench layout when selecting an action group file.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Support jumping
+ to signal hanlder when double-clicking it in the signals editor.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Removed debug code.
+
+ * templates/ActionGroup.xft.xml:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ Fix code generation of action groups.
+
+2006-06-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: If a member has a [Browsable(false)]
+ attribute, don't add it to the objects.xml file. Also don't add
+ read-only properties.
+ * lib/*: Updated from stetic module. Fixes bugs #78622 and #78620.
+ Adds an icon for expander and fixes a bug in ColorButton (fix by ml)
+
+2006-06-11 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libsteticui.dll:
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopWidgetActionBar.cs:
+ Track changes in the api.
+
+2006-06-09 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Updated from stetic module. Several improvements.
+ Also fixes bug #78160.
+
+2006-05-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderDisplayBinding.cs:
+ Added DisplayName property.
+
+2006-05-29 David Makovský (Yakeen) <yakeen@sannyas-on.net>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: reverted interface changes - missing file change
+
+2006-05-29 David Makovský (Yakeen) <yakeen@sannyas-on.net>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: reverted interface changes
+
+2006-05-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Updated from stetic module. Adds support for toolbars.
+
+2006-05-23 David Makovský (Yakeen) <yakeen@sannyas-on.net>
+
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: track api changes
+
+2006-05-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.Commands/GladeCommands.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ProjectFolderNodeBuilderExtension.cs:
+ * MonoDevelop.GtkCore.addin.xml: Added commands for creating
+ an action group and editing the project icons.
+
+ * MonoDevelop.GtkCore.NodeBuilders/WidgetNodeBuilder.cs: Show local
+ action groups as children of the window node.
+
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolder.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs: Moved
+ some event subscriptions to WindowsFolder.cs
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs:
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: Open the
+ corresponding file when clicking on local action groups.
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Added action group template.
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Added support for
+ action group file templates.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs: Notify changes in
+ local action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't show the actions
+ tab until there is at least one action group.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs: Don't show
+ properties or signals for global actions.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Added virtual method
+ OnActiveDocumentChanged, which is called when the view is brought to front.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Use the new MemberName
+ field when binding fields.
+
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopActionGroupToolbar.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: Several minor fixes.
+
+ * lib/*: Updated.
+
+
+2006-05-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Initial support for the menu editor. Still very unstable!!
+
+ * lib/*: Updated from Stetic module.
+ * MonoDevelop.GtkCore.addin.xml: Register a node builder and and
+ display binding for action groups.
+ * MonoDevelop.GtkCore.NodeBuilders/WindowsFolderNodeBuilder.cs: Update
+ the folder when action groups change.
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Fix nullref.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Factorized
+ some code into CodeBinder.cs
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Factorized some
+ code into CombinedDesignView.cs.
+
+ * MonoDevelop.GtkCore.NodeBuilders/ActionGroupNodeBuilder.cs: New node
+ builder for action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupDisplayBinding.cs: New display
+ binding for editing global action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopWidgetActionBar.cs: Moved from
+ GuiBuilderView.cs.
+ * MonoDevelop.GtkCore.GuiBuilder/MonoDevelopActionGroupToolbar.cs: A new
+ toolbar for the action group designer.
+ * MonoDevelop.GtkCore.GuiBuilder/ActionGroupView.cs: A view for editing
+ global action groups.
+ * MonoDevelop.GtkCore.GuiBuilder/CodeBinder.cs: Moved here some code
+ from GuiBuilderEditSession.cs.
+ * MonoDevelop.GtkCore.GuiBuilder/CombinedDesignView.cs: Moved here some
+ code from GuiBuilderView.cs.
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Added new files.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track api changes.
+
+2006-05-05 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/libstetic.dll: Updated from Stetic module. Includes
+ a fix for bug #78307.
+
+2006-05-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Updated versions.
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+2006-05-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated from Stetic module. Includes fixes for
+ bugs #78266, #78240 and #78276.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderWindow.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs:
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Track changes
+ in the Stetic API.
+
+2006-04-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProject.cs: Don't
+ crash if a stetic project can't be loaded. Fixes bug #78169.
+ * lib/libstetic.dll: Updated from Stetic module. Fixes bug #78167.
+
+2006-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Updated from stetic module. Fixed construction of
+ scales and scrollbars.
+
+2006-04-19 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs: When
+ creating a widget from a widget design, remove the signals since
+ those signals reference handlers in the widget class, not the
+ widget container class.
+
+2006-04-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libs/*: Fix nullref in some themes.
+
+2006-04-10 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/WidgetFileDescriptionTemplate.cs: Fix typo.
+ * libs/*: Fix for #78111, #78092 and #78090.
+
+2006-04-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/ProjectResourceProvider.cs: Save the project
+ after adding or removing a resource.
+
+2006-04-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * lib/*: Updated.
+
+2006-03-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Get open
+ combine events in the GUI thread.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs: Properly
+ delete signals for which there isn't a handler. Half fixed field
+ renaming.
+ * lib/*: Updated.
+
+2006-03-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore/MonoDevelop.GtkCore.addin.xml: Fix ID and
+ description. Added stetic config files to add-in package.
+
+2006-03-30 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml: Updated references.
+
+2006-03-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ Don't crash if no parse info is available for the file
+ being edited. Should fix #77885.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Don't show
+ the bind to field button for the root container.
+ * lib/*: Updated.
+
+2006-03-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am: Use an unified format. Patch by Matze Braun.
+ * MonoDevelop.GtkCore.addin.xml: Updated add-in versions.
+
+2006-03-22 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.addin.xml:
+ * MonoDevelop.GtkCore.mdp: Removed GladeFileDisplayBinding.
+ * lib/*: Updated.
+ * Makefile.am: Updated. Some files have been moved to Stetic.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs: Fixed
+ layout switching. Don't show the widget tree pad by default,
+ since it is already available as a combo in the designer.
+ * MonoDevelop.GtkCore.GuiBuilder/GladeFileDisplayBinding.cs: Removed.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderPropertiesPad.cs: use
+ the new property tree instead of the grid.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: The designer
+ toolbar has been moved to Stetic.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderProjectPad.cs: Changed
+ default placement.
+
+2006-03-19 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
+
+ * .: Added Makefile.in and Makefile to svn:ignore.
+
+2006-03-15 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * MonoDevelop.GtkCore.mdp: Updated.
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderEditSession.cs:
+ * MonoDevelop.GtkCore/GtkDesignInfo.cs: Added support for using
+ resource images in the designer.
+
+ * MonoDevelop.GtkCore/GtkCoreService.cs: Check if the objects.xml
+ file exists before loading it.
+ * MonoDevelop.GtkCore/GeneratorBuildStep.cs: Don't generate code
+ if the stetic file has not been modified since the last
+ generation.
+ * MonoDevelop.GtkCore.Dialogs/WidgetBuilderOptionPanel.cs: If Gtk
+ support is not enabled, don't enable it if no widgets have
+ been selected.
+ * lib/libstetic.dll: Updated.
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Mapped some
+ commands.
+ * templates/Window.xft.xml: The constructor of Gtk.Window requires
+ the title of the window.
+
+2006-03-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.mdp, Makefile.am: Updated.
+ * MonoDevelop.GtkCore/GeneratorBuildStep.cs: When generating
+ code for a project that exports widgets, include the own
+ project library to the generation, since there can be
+ widgets that contain other widgets defined in the project.
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectClassDescriptor.cs:
+ removed some IdeApp dependencies.
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectWidgetLibrary.cs:
+ added method for getting the class information from
+ a project.
+ * CachedProjectWidgetLibrary.cs: New widget library class
+ which takes class information from a collection of
+ ProjectClassInfo objects.
+ * MonoDevelop.GtkCore.WidgetLibrary/ProjectPropertyDescriptor.cs:
+ Consider all properties runtime-properties, since they have
+ been created from class properties.
+ * lib/*: Updated.
+
+2006-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am: removed debug files.
+
+2006-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ * MonoDevelop.GtkCore.GuiBuilder/GuiBuilderView.cs: Propagate
+ project changes to the editor.
+
+2006-03-02 Lluis Sanchez Gual <lluis@novell.com>
+
+ Initial implementation of the Stetic add-in.
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ClassDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ClassDescriptor.cs
new file mode 100644
index 0000000000..29a1f9a593
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ClassDescriptor.cs
@@ -0,0 +1,344 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Xml;
+
+namespace Stetic {
+
+
+ public abstract class ClassDescriptor
+ {
+ protected string label, category, cname;
+ protected bool deprecated, hexpandable, vexpandable, allowChildren = true;
+
+ protected ItemGroupCollection groups = new ItemGroupCollection ();
+ protected ItemGroupCollection signals = new ItemGroupCollection ();
+
+ protected int importantGroups;
+ protected ItemGroup contextMenu;
+ protected ItemGroup internalChildren;
+ protected string baseType;
+ protected bool isInternal;
+ protected string targetGtkVersion;
+
+ WidgetLibrary library;
+ PropertyDescriptor[] initializationProperties;
+ static PropertyDescriptor[] emptyPropArray = new PropertyDescriptor[0];
+
+ int counter;
+
+ protected void Load (XmlElement elem)
+ {
+ if (elem.HasAttribute ("cname"))
+ cname = elem.GetAttribute ("cname");
+ else if (cname == null)
+ cname = elem.GetAttribute ("type");
+
+ label = elem.GetAttribute ("label");
+ if (label == "") {
+ label = WrappedTypeName;
+ int i = label.LastIndexOf ('.');
+ if (i != -1)
+ label = label.Substring (i+1);
+ }
+
+ if (elem.HasAttribute ("allow-children"))
+ allowChildren = elem.GetAttribute ("allow-children") == "yes" || elem.GetAttribute ("allow-children") == "true";
+
+ category = elem.GetAttribute ("palette-category");
+
+ if (elem.HasAttribute ("deprecated"))
+ deprecated = true;
+ if (elem.HasAttribute ("hexpandable"))
+ hexpandable = true;
+ if (elem.HasAttribute ("vexpandable"))
+ vexpandable = true;
+ if (elem.GetAttribute ("internal") == "true")
+ isInternal = true;
+
+ contextMenu = ItemGroup.Empty;
+
+ baseType = elem.GetAttribute ("base-type");
+ if (baseType.Length > 0) {
+ ClassDescriptor basec = Registry.LookupClassByName (baseType);
+ if (basec == null)
+ throw new InvalidOperationException ("Base type '" + baseType + "' not found.");
+ foreach (ItemGroup group in basec.ItemGroups)
+ groups.Add (group);
+ foreach (ItemGroup group in basec.SignalGroups)
+ signals.Add (group);
+ contextMenu = basec.ContextMenu;
+ } else
+ baseType = null;
+
+ XmlElement groupsElem = elem["itemgroups"];
+ if (groupsElem != null) {
+ foreach (XmlElement groupElem in groupsElem.SelectNodes ("itemgroup")) {
+ ItemGroup itemgroup;
+
+ if (groupElem.HasAttribute ("ref")) {
+ string refname = groupElem.GetAttribute ("ref");
+ itemgroup = Registry.LookupItemGroup (refname);
+ } else
+ itemgroup = new ItemGroup (groupElem, this);
+ groups.Add (itemgroup);
+
+ if (groupElem.HasAttribute ("important")) {
+ if (groupElem.GetAttribute ("important") == "true")
+ importantGroups++;
+ } else if (groups.Count == 1)
+ importantGroups++;
+ }
+ }
+
+ XmlElement signalsElem = elem["signals"];
+ if (signalsElem != null) {
+ foreach (XmlElement groupElem in signalsElem.SelectNodes ("itemgroup")) {
+ ItemGroup itemgroup;
+ if (groupElem.HasAttribute ("ref")) {
+ string refname = groupElem.GetAttribute ("ref");
+ itemgroup = Registry.LookupSignalGroup (refname);
+ } else
+ itemgroup = new ItemGroup (groupElem, this);
+ signals.Add (itemgroup);
+ }
+ }
+
+ XmlElement contextElem = elem["contextmenu"];
+ if (contextElem != null) {
+ if (contextElem.HasAttribute ("ref")) {
+ string refname = contextElem.GetAttribute ("ref");
+ contextMenu = Registry.LookupContextMenu (refname);
+ } else
+ contextMenu = new ItemGroup (contextElem, this);
+ }
+
+ XmlElement ichildElem = elem["internal-children"];
+ if (ichildElem != null)
+ internalChildren = new ItemGroup (ichildElem, this);
+ else
+ internalChildren = ItemGroup.Empty;
+
+ string initProps = elem.GetAttribute ("init-properties");
+ if (initProps.Length > 0) {
+ string[] props = initProps.Split (' ');
+ ArrayList list = new ArrayList ();
+ foreach (string prop in props) {
+ PropertyDescriptor idesc = this [prop] as PropertyDescriptor;
+ if (idesc == null)
+ throw new InvalidOperationException ("Initialization property not found: " + prop);
+ list.Add (idesc);
+ }
+ initializationProperties = (PropertyDescriptor[]) list.ToArray (typeof(PropertyDescriptor));
+ } else
+ initializationProperties = emptyPropArray;
+
+ targetGtkVersion = elem.GetAttribute ("gtk-version");
+ if (targetGtkVersion.Length == 0)
+ targetGtkVersion = null;
+ }
+
+ public virtual string Name {
+ get {
+ return WrappedTypeName;
+ }
+ }
+
+ public virtual bool IsInternal {
+ get { return isInternal; }
+ }
+
+ public abstract string WrappedTypeName {
+ get;
+ }
+
+ public string CName {
+ get {
+ return cname;
+ }
+ }
+
+ public bool Deprecated {
+ get {
+ return deprecated;
+ }
+ }
+
+ public bool HExpandable {
+ get {
+ return hexpandable;
+ }
+ }
+
+ public bool VExpandable {
+ get {
+ return vexpandable;
+ }
+ }
+
+ public string Label {
+ get {
+ return label;
+ }
+ }
+
+ public abstract Gdk.Pixbuf Icon {
+ get;
+ }
+
+ public string Category {
+ get {
+ return category;
+ }
+ }
+
+ public virtual string TargetGtkVersion {
+ get {
+ if (targetGtkVersion == null)
+ return library.TargetGtkVersion;
+ else
+ return targetGtkVersion;
+ }
+ }
+
+ public bool SupportsGtkVersion (string targetVersion)
+ {
+ return WidgetUtils.CompareVersions (TargetGtkVersion, targetVersion) >= 0;
+ }
+
+ public PropertyDescriptor[] InitializationProperties {
+ get { return initializationProperties; }
+ }
+
+ public object NewInstance (IProject proj)
+ {
+ return NewInstance (proj, true);
+ }
+
+ public object NewInstance (IProject proj, bool initialize)
+ {
+ object ob = CreateInstance (proj);
+
+ string name = WrappedTypeName.ToLower () + (++counter).ToString ();
+ int i = name.LastIndexOf ('.');
+ if (i != -1) {
+ if (i < name.Length)
+ name = name.Substring (i+1);
+ else
+ name = name.Replace (".", "");
+ }
+
+ ObjectWrapper ow = CreateWrapper ();
+ try {
+ ow.Loading = true;
+ ObjectWrapper.Bind (proj, this, ow, ob, !initialize);
+
+ // Initialize the properties after creating the wrapper, since some properties
+ // may be implemented in the wrapper
+
+ foreach (ItemGroup group in groups) {
+ foreach (ItemDescriptor item in group) {
+ PropertyDescriptor prop = item as PropertyDescriptor;
+ if (prop != null && prop.InitWithName) {
+ prop.SetValue (ob, name);
+ }
+ }
+ }
+ }
+ finally {
+ ow.Loading = false;
+ }
+
+ return ob;
+ }
+
+ // Sets the default values for an instance
+ public virtual void ResetInstance (object obj)
+ {
+ foreach (ItemGroup group in groups) {
+ foreach (ItemDescriptor item in group) {
+ PropertyDescriptor prop = item as PropertyDescriptor;
+ if (prop != null) {
+ try {
+ prop.ResetValue (obj);
+ } catch (Exception ex) {
+ // Ignore. ResetInstance should never crash since it can
+ // leave a widget half initialized
+ Console.WriteLine (ex);
+ }
+ }
+ }
+ }
+ }
+
+ public abstract object CreateInstance (IProject proj);
+
+ public abstract ObjectWrapper CreateWrapper ();
+
+ public ItemDescriptor this[string name] {
+ get {
+ if (groups != null) {
+ foreach (ItemGroup group in groups) {
+ ItemDescriptor item = group[name];
+ if (item != null)
+ return item;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ public ItemGroupCollection ItemGroups {
+ get {
+ return groups;
+ }
+ }
+
+ public ItemGroupCollection SignalGroups {
+ get {
+ return signals;
+ }
+ }
+
+ public int ImportantGroups {
+ get {
+ return importantGroups;
+ }
+ }
+
+ public ItemGroup ContextMenu {
+ get {
+ return contextMenu;
+ }
+ }
+
+ public ItemGroup InternalChildren {
+ get {
+ return internalChildren;
+ }
+ }
+
+ public WidgetLibrary Library {
+ get { return library; }
+ }
+
+ public virtual bool AllowChildren {
+ get { return allowChildren; }
+ }
+
+ internal protected virtual ItemDescriptor CreateItemDescriptor (XmlElement elem, ItemGroup group)
+ {
+ if (elem.Name == "command")
+ return new CommandDescriptor (elem, group, this);
+ else
+ throw new ApplicationException ("Bad item name " + elem.Name + " in " + WrappedTypeName);
+ }
+
+ internal void SetLibrary (WidgetLibrary library)
+ {
+ this.library = library;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/Clipboard.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Clipboard.cs
new file mode 100644
index 0000000000..9c27ceec40
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Clipboard.cs
@@ -0,0 +1,91 @@
+using Gtk;
+using System;
+using System.Xml;
+
+namespace Stetic {
+
+ internal static class Clipboard {
+
+ const int SteticType = 0;
+ const int TextType = 1;
+
+ static Gtk.TargetEntry[] targets;
+ static Gtk.TargetEntry[] Targets {
+ get {
+ if (targets == null) {
+#if GTK_SHARP_2_6
+ Gtk.TargetList list = new Gtk.TargetList ();
+ list.Add ((string)WidgetUtils.ApplicationXSteticAtom, 0, SteticType);
+ list.AddTextTargets (TextType);
+ targets = (Gtk.TargetEntry[])list;
+#else
+ targets = new Gtk.TargetEntry[] {
+ new Gtk.TargetEntry ((string)WidgetUtils.ApplicationXSteticAtom, 0, SteticType)
+ };
+#endif
+ }
+ return targets;
+ }
+ }
+
+ static Gtk.Clipboard MainClipboard {
+ get {
+ return Gtk.Clipboard.Get (Gdk.Selection.Clipboard);
+ }
+ }
+
+ static XmlElement selection;
+
+ static void ClipboardGet (Gtk.Clipboard clipboard, Gtk.SelectionData seldata, uint info)
+ {
+ if (selection == null)
+ return;
+
+ if (info == TextType)
+ seldata.Text = selection.OuterXml;
+ else
+ seldata.Set (WidgetUtils.ApplicationXSteticAtom, 8, System.Text.Encoding.UTF8.GetBytes (selection.OuterXml));
+ }
+
+ static void ClipboardClear (Gtk.Clipboard clipboard)
+ {
+ selection = null;
+ }
+
+ public static void Copy (Gtk.Widget widget)
+ {
+ MainClipboard.SetWithData (Targets, ClipboardGet, ClipboardClear);
+ selection = widget != null ? WidgetUtils.ExportWidget (widget) : null;
+ }
+
+ public static void Cut (Gtk.Widget widget)
+ {
+ Copy (widget);
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+ if (wrapper != null)
+ wrapper.Delete ();
+ }
+
+ static Placeholder target;
+
+ static void ClipboardPaste (Gtk.Clipboard clipboard, Gtk.SelectionData seldata)
+ {
+ Stetic.Wrapper.Container parent = Stetic.Wrapper.Container.LookupParent (target);
+ if (parent == null)
+ return;
+
+ Stetic.Wrapper.Widget wrapper = WidgetUtils.Paste (parent.Project, seldata);
+ if (wrapper == null)
+ return;
+
+ parent.PasteChild (target, wrapper.Wrapped);
+ target = null;
+ }
+
+ public static void Paste (Placeholder target)
+ {
+ Clipboard.target = target;
+ MainClipboard.RequestContents (WidgetUtils.ApplicationXSteticAtom, ClipboardPaste);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/CommandDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/CommandDescriptor.cs
new file mode 100644
index 0000000000..eadd8b3970
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/CommandDescriptor.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+
+namespace Stetic {
+
+ public class CommandDescriptor : ItemDescriptor {
+
+ string name, checkName, label, description, icon;
+
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ public CommandDescriptor (XmlElement elem, ItemGroup group, ClassDescriptor klass) : base (elem, group, klass)
+ {
+ name = elem.GetAttribute ("name");
+ label = elem.GetAttribute ("label");
+ description = elem.GetAttribute ("description");
+ checkName = elem.GetAttribute ("check");
+ icon = elem.GetAttribute ("icon");
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ public string Label {
+ get {
+ return label;
+ }
+ }
+
+ public string Description {
+ get {
+ return description;
+ }
+ }
+
+ public bool IsToggleCommand (object obj)
+ {
+ object target;
+ return (FindBoolProperty (obj, out target) != null);
+ }
+
+ public bool IsToogled (object obj)
+ {
+ object target;
+ PropertyInfo prop = FindBoolProperty (obj, out target);
+ return prop != null && (bool) prop.GetValue (target, null);
+ }
+
+ PropertyInfo FindBoolProperty (object obj, out object target)
+ {
+ PropertyInfo prop = obj.GetType().GetProperty (name, flags);
+ if (prop != null && prop.PropertyType == typeof(bool)) {
+ target = obj;
+ return prop;
+ }
+
+ ObjectWrapper wrap = ObjectWrapper.Lookup (obj);
+ if (wrap != null) {
+ prop = wrap.GetType().GetProperty (name, flags);
+ if (prop != null && prop.PropertyType == typeof(bool)) {
+ target = wrap;
+ return prop;
+ }
+ }
+ target = null;
+ return null;
+ }
+
+ public Gtk.Image GetImage ()
+ {
+ if (icon == null || icon.Length == 0)
+ return null;
+ if (icon.StartsWith ("res:")) {
+ System.IO.Stream s = this.ClassDescriptor.Library.GetResource (icon.Substring (4));
+ if (s == null)
+ return null;
+ using (s) {
+ Gdk.Pixbuf pixbuf;
+ try {
+ pixbuf = new Gdk.Pixbuf (s);
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf '" + icon.Substring (4) + "': " + e);
+ return null;
+ }
+ return new Gtk.Image (pixbuf);
+ }
+ } else {
+ return new Gtk.Image (icon, Gtk.IconSize.Menu);
+ }
+ }
+
+ public bool Enabled (object obj)
+ {
+ if (checkName == "")
+ return EnabledFor (obj);
+ else
+ return (bool) InvokeMethod (ObjectWrapper.Lookup (obj), checkName, null, false);
+ }
+
+ public bool Enabled (object obj, Gtk.Widget context)
+ {
+ if (checkName == "")
+ return EnabledFor (obj);
+
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ return (bool) InvokeMethod (wrapper, checkName, context, true);
+ }
+
+ public void Run (object obj)
+ {
+ ObjectWrapper ww = ObjectWrapper.Lookup (obj);
+ using (ww.UndoManager.AtomicChange) {
+ InvokeMethod (ww, name, null, false);
+ }
+ }
+
+ public void Run (object obj, Gtk.Widget context)
+ {
+ ObjectWrapper ww = ObjectWrapper.Lookup (obj);
+ using (ww.UndoManager.AtomicChange) {
+ InvokeMethod (ww, name, context, true);
+ }
+ }
+
+ object InvokeMethod (object target, string name, object context, bool withContext)
+ {
+ object ptarget;
+ PropertyInfo prop = FindBoolProperty (target, out ptarget);
+ if (prop != null) {
+ prop.SetValue (ptarget, !(bool)prop.GetValue (ptarget, null), null);
+ return null;
+ }
+
+ if (withContext) {
+ MethodInfo metc = target.GetType().GetMethod (name, flags, null, new Type[] {typeof(Gtk.Widget)}, null);
+ if (metc != null)
+ return metc.Invoke (target, new object[] { context });
+ }
+
+ MethodInfo met = target.GetType().GetMethod (name, flags, null, Type.EmptyTypes, null);
+ if (met != null)
+ return met.Invoke (target, new object[0]);
+
+ throw new ArgumentException ("Invalid command or checker name. Method '" + name +"' not found in class '" + target.GetType() + "'");
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/CustomWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/CustomWidget.cs
new file mode 100644
index 0000000000..f9f3934343
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/CustomWidget.cs
@@ -0,0 +1,27 @@
+
+using System;
+
+namespace Stetic
+{
+ // This widget is used at design-time to represent a Gtk.Bin container.
+ // Gtk.Bin is the base class for custom widgets.
+
+ public class CustomWidget: Gtk.EventBox
+ {
+ public CustomWidget (IntPtr ptr): base (ptr)
+ {
+ }
+
+ public CustomWidget ()
+ {
+ this.VisibleWindow = false;
+ this.Events |= Gdk.EventMask.ButtonPressMask;
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ // Avoid forwarding event to parent widget
+ return true;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/DND.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/DND.cs
new file mode 100644
index 0000000000..a1e58fc21a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/DND.cs
@@ -0,0 +1,630 @@
+using System;
+using System.Collections;
+
+namespace Stetic {
+
+ public static class DND {
+ static Gtk.TargetEntry[] targets;
+ static Gtk.TargetList targetList;
+ static Gdk.Atom steticWidgetType;
+ static Gdk.Pixbuf widgetIcon;
+
+ const int SteticType = 0;
+ const int GladeType = 1;
+
+ static DND ()
+ {
+ try {
+ widgetIcon = Gdk.Pixbuf.LoadFromResource ("widget.png");
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf 'widget.png': " + e);
+ }
+
+ steticWidgetType = Gdk.Atom.Intern ("application/x-stetic-widget", false);
+
+ targets = new Gtk.TargetEntry[2];
+ targets[0] = new Gtk.TargetEntry (steticWidgetType, 0, SteticType);
+ targets[1] = new Gtk.TargetEntry ((string) GladeUtils.ApplicationXGladeAtom, 0, GladeType);
+
+ targetList = new Gtk.TargetList (targets);
+ targets = (Gtk.TargetEntry[]) targetList;
+ }
+
+ public static Gtk.TargetEntry[] Targets {
+ get { return targets; }
+ }
+
+ public static void SourceSet (Gtk.Widget source)
+ {
+ Gtk.Drag.SourceSet (source, Gdk.ModifierType.Button1Mask,
+ targets, Gdk.DragAction.Move);
+ }
+
+ public static void SourceUnset (Gtk.Widget source)
+ {
+ Gtk.Drag.SourceUnset (source);
+ }
+
+ public static void DestSet (Gtk.Widget dest, bool automatic)
+ {
+ Gtk.Drag.DestSet (dest, automatic ? Gtk.DestDefaults.All : 0,
+ targets, Gdk.DragAction.Move | Gdk.DragAction.Copy);
+ }
+
+ public static void DestUnset (Gtk.Widget dest)
+ {
+ Gtk.Drag.DestUnset (dest);
+ }
+
+ static Gtk.Widget dragWidget;
+ static WidgetDropCallback dropCallback;
+ static int dragHotX;
+ static int dragHotY;
+
+ // Drag function for non-automatic sources, called from MotionNotifyEvent
+ public static void Drag (Gtk.Widget source, Gdk.Event evt, Gtk.Widget dragWidget)
+ {
+ Gdk.DragContext ctx;
+
+ ctx = Gtk.Drag.Begin (source, targetList, Gdk.DragAction.Move,
+ 1 /* button */, evt);
+ Drag (source, ctx, dragWidget);
+ }
+
+ // Drag function for automatic sources, called from DragBegin
+ public static void Drag (Gtk.Widget source, Gdk.DragContext ctx, WidgetDropCallback dropCallback, string label)
+ {
+ Gtk.Frame fr = new Gtk.Frame ();
+ fr.ShadowType = Gtk.ShadowType.Out;
+ Gtk.HBox box = new Gtk.HBox ();
+ box.Spacing = 3;
+ box.BorderWidth = 3;
+ box.PackStart (new Gtk.Image (widgetIcon), false, false, 0);
+ Gtk.Label lab = new Gtk.Label (label);
+ lab.Xalign = 0;
+ box.PackStart (lab, true, true, 0);
+ fr.Add (box);
+ fr.ShowAll ();
+ Drag (source, ctx, dropCallback, fr);
+ }
+
+ // Drag function for automatic sources, called from DragBegin
+ public static void Drag (Gtk.Widget source, Gdk.DragContext ctx, Gtk.Widget dragWidget)
+ {
+ Drag (source, ctx, null, dragWidget);
+ }
+
+ // Drag function for automatic sources, called from DragBegin
+ static void Drag (Gtk.Widget source, Gdk.DragContext ctx, WidgetDropCallback dropCallback, Gtk.Widget dragWidget)
+ {
+ if (ctx == null)
+ return;
+
+ Gtk.Window dragWin;
+ Gtk.Requisition req;
+
+ ShowFaults ();
+ DND.dragWidget = dragWidget;
+ DND.dropCallback = dropCallback;
+
+ dragWin = new Gtk.Window (Gtk.WindowType.Popup);
+ dragWin.Add (dragWidget);
+
+ req = dragWidget.SizeRequest ();
+ if (req.Width < 20 && req.Height < 20)
+ dragWin.SetSizeRequest (20, 20);
+ else if (req.Width < 20)
+ dragWin.SetSizeRequest (20, -1);
+ else if (req.Height < 20)
+ dragWin.SetSizeRequest (-1, 20);
+
+ req = dragWin.SizeRequest ();
+
+ int px, py, rx, ry;
+ Gdk.ModifierType pmask;
+ ctx.SourceWindow.GetPointer (out px, out py, out pmask);
+ ctx.SourceWindow.GetRootOrigin (out rx, out ry);
+
+ dragWin.Move (rx + px, ry + py);
+ dragWin.Show ();
+
+ dragHotX = req.Width / 2;
+ dragHotY = -3;
+
+ Gtk.Drag.SetIconWidget (ctx, dragWin, dragHotX, dragHotY);
+
+ if (source != null) {
+ source.DragDataGet += DragDataGet;
+ source.DragEnd += DragEnded;
+ }
+ }
+
+ public static Gtk.Widget DragWidget {
+ get {
+ return dragWidget;
+ }
+ }
+
+ public static int DragHotX {
+ get {
+ return dragHotX;
+ }
+ }
+
+ public static int DragHotY {
+ get {
+ return dragHotY;
+ }
+ }
+
+ // Call this from a DragDrop event to receive the dragged widget
+ public static void Drop (Gdk.DragContext ctx, uint time, ObjectWrapper targetWrapper, string dropData)
+ {
+ if (dropCallback == null) {
+ Gtk.Widget w = Drop (ctx, (Gtk.Widget) targetWrapper.Wrapped, time);
+ targetWrapper.DropObject (dropData, w);
+ return;
+ }
+
+ Cancel ();
+ Gtk.Drag.Finish (ctx, true, true, time);
+
+ Gtk.Application.Invoke (delegate {
+ IProject project = targetWrapper.Project;
+ string uid = targetWrapper.UndoId;
+ string tname = ((Wrapper.Widget)targetWrapper).GetTopLevel ().Wrapped.Name;
+
+ // This call may cause the project to be reloaded
+ dragWidget = dropCallback ();
+ if (dragWidget == null)
+ return;
+
+ if (targetWrapper.IsDisposed) {
+ // The project has been reloaded. Find the wrapper again.
+ Gtk.Widget twidget = project.GetWidget (tname);
+ ObjectWrapper ow = ObjectWrapper.Lookup (twidget);
+ if (ow != null)
+ targetWrapper = ow.FindObjectByUndoId (uid);
+ else
+ targetWrapper = null;
+
+ if (targetWrapper == null) {
+ // Target wrapper not found. Just ignore the drop.
+ return;
+ }
+ }
+
+ targetWrapper.DropObject (dropData, dragWidget);
+ });
+ }
+
+ public static Gtk.Widget Drop (Gdk.DragContext ctx, Gtk.Widget target, uint time)
+ {
+ if (dropCallback != null) {
+ dragWidget = dropCallback ();
+ }
+
+ if (dragWidget == null) {
+ Gtk.Drag.GetData (target, ctx, GladeUtils.ApplicationXGladeAtom, time);
+ return null;
+ }
+
+ Gtk.Widget w = Cancel ();
+ Gtk.Drag.Finish (ctx, true, true, time);
+ return w;
+ }
+
+ // Call this from a DragEnd event to check if the widget wasn't dropped
+ public static Gtk.Widget Cancel ()
+ {
+ if (dragWidget == null)
+ return null;
+
+ Gtk.Widget w = dragWidget;
+ dragWidget = null;
+
+ // Remove the widget from its dragWindow
+ Gtk.Container parent = w.Parent as Gtk.Container;
+ if (parent != null) {
+ parent.Remove (w);
+ parent.Destroy ();
+ }
+ return w;
+ }
+
+ static void DragEnded (object obj, Gtk.DragEndArgs args)
+ {
+ dragWidget = null;
+ HideFaults ();
+
+ ((Gtk.Widget)obj).DragEnd -= DragEnded;
+ ((Gtk.Widget)obj).DragDataGet -= DragDataGet;
+ }
+
+ static void DragDataGet (object obj, Gtk.DragDataGetArgs args)
+ {
+ if (args.Info == GladeType) {
+ Gtk.Widget w = Cancel ();
+ if (w != null)
+ WidgetUtils.Copy (w, args.SelectionData, false);
+ }
+ }
+
+ class Fault {
+ public Stetic.Wrapper.Widget Owner;
+ public object Id;
+ public Gtk.Orientation Orientation;
+ public Gdk.Window Window;
+
+ public Fault (Stetic.Wrapper.Widget owner, object id,
+ Gtk.Orientation orientation, Gdk.Window window)
+ {
+ Owner = owner;
+ Id = id;
+ Orientation = orientation;
+ Window = window;
+ }
+ }
+
+ static Hashtable faultGroups = new Hashtable ();
+ const int FaultOverlap = 3;
+
+ public static void AddFault (Stetic.Wrapper.Widget owner, object faultId,
+ Gtk.Orientation orientation, Gdk.Rectangle fault)
+ {
+ AddFault (owner, faultId, orientation,
+ fault.X, fault.Y, fault.Width, fault.Height);
+ }
+
+ public static void AddFault (Stetic.Wrapper.Widget owner, object faultId,
+ Gtk.Orientation orientation,
+ int x, int y, int width, int height)
+ {
+ Gtk.Widget widget = owner.Wrapped;
+ if (!widget.IsRealized)
+ return;
+
+ Gdk.Window win = NewWindow (widget, Gdk.WindowClass.InputOnly);
+ win.MoveResize (x, y, width, height);
+
+ Hashtable widgetFaults = faultGroups[widget] as Hashtable;
+ if (widgetFaults == null) {
+ faultGroups[widget] = widgetFaults = new Hashtable ();
+ widget.Destroyed += FaultWidgetDestroyed;
+ widget.DragMotion += FaultDragMotion;
+ widget.DragLeave += FaultDragLeave;
+ widget.DragDrop += FaultDragDrop;
+ widget.DragDataReceived += FaultDragDataReceived;
+ DND.DestSet (widget, false);
+ }
+ widgetFaults[win] = new Fault (owner, faultId, orientation, win);
+ }
+
+ public static void AddFault (Stetic.Wrapper.Widget owner, object faultId,
+ Gtk.Orientation orientation,
+ Gtk.Widget before, Gtk.Widget after)
+ {
+ if (orientation == Gtk.Orientation.Horizontal)
+ AddHFault (owner, faultId, before, after);
+ else
+ AddVFault (owner, faultId, before, after);
+ }
+
+ public static void AddHFault (Stetic.Wrapper.Widget owner, object faultId,
+ Gtk.Widget above, Gtk.Widget below)
+ {
+ Gtk.Widget widget = owner.Wrapped;
+ if (!widget.IsRealized)
+ return;
+
+ Gdk.Rectangle aboveAlloc, belowAlloc;
+ int x1, y1, x2, y2;
+
+ if (above != null && below != null) {
+ aboveAlloc = above.Allocation;
+ belowAlloc = below.Allocation;
+
+ x1 = Math.Min (aboveAlloc.X, belowAlloc.X);
+ x2 = Math.Max (aboveAlloc.X + aboveAlloc.Width, belowAlloc.X + belowAlloc.Width);
+ y1 = aboveAlloc.Y + aboveAlloc.Height;
+ y2 = belowAlloc.Y;
+
+ while (y2 - y1 < FaultOverlap * 2) {
+ y1--;
+ y2++;
+ }
+ } else if (above == null) {
+ belowAlloc = below.Allocation;
+
+ x1 = belowAlloc.X;
+ x2 = belowAlloc.X + belowAlloc.Width;
+ y1 = 0;
+ y2 = Math.Max (belowAlloc.Y, FaultOverlap);
+ } else {
+ aboveAlloc = above.Allocation;
+
+ x1 = aboveAlloc.X;
+ x2 = aboveAlloc.X + aboveAlloc.Width;
+ y1 = Math.Min (aboveAlloc.Y + aboveAlloc.Height, widget.Allocation.Height - FaultOverlap);
+ y2 = widget.Allocation.Height;
+ }
+
+ AddFault (owner, faultId, Gtk.Orientation.Horizontal,
+ x1, y1, x2 - x1, y2 - y1);
+ }
+
+ public static void AddVFault (Stetic.Wrapper.Widget owner, object faultId,
+ Gtk.Widget left, Gtk.Widget right)
+ {
+ Gtk.Widget widget = owner.Wrapped;
+ if (!widget.IsRealized)
+ return;
+
+ Gdk.Rectangle leftAlloc, rightAlloc;
+ int x1, y1, x2, y2;
+
+ if (left != null && right != null) {
+ leftAlloc = left.Allocation;
+ rightAlloc = right.Allocation;
+
+ x1 = leftAlloc.X + leftAlloc.Width;
+ x2 = rightAlloc.X;
+
+ y1 = Math.Min (leftAlloc.Y, rightAlloc.Y);
+ y2 = Math.Max (leftAlloc.Y + leftAlloc.Height, rightAlloc.Y + rightAlloc.Height);
+
+ while (x2 - x1 < FaultOverlap * 2) {
+ x1--;
+ x2++;
+ }
+ } else if (left == null) {
+ rightAlloc = right.Allocation;
+
+ x1 = 0;
+ x2 = Math.Max (rightAlloc.X, FaultOverlap);
+
+ y1 = rightAlloc.Y;
+ y2 = rightAlloc.Y + rightAlloc.Height;
+ } else {
+ leftAlloc = left.Allocation;
+
+ x1 = Math.Min (leftAlloc.X + leftAlloc.Width, widget.Allocation.Width - FaultOverlap);
+ x2 = widget.Allocation.Width;
+
+ y1 = leftAlloc.Y;
+ y2 = leftAlloc.Y + leftAlloc.Height;
+ }
+
+ AddFault (owner, faultId, Gtk.Orientation.Vertical,
+ x1, y1, x2 - x1, y2 - y1);
+ }
+
+ public static void AddFault (Stetic.Wrapper.Widget owner, object faultId,
+ Gtk.SideType side, Gtk.Widget widget)
+ {
+ Gdk.Rectangle fault;
+ Gtk.Orientation orientation;
+
+ if (widget == null) {
+ fault = owner.Wrapped.Allocation;
+ int border = (int)((Gtk.Container)owner.Wrapped).BorderWidth;
+ fault.Inflate (-border, -border);
+ } else
+ fault = widget.Allocation;
+
+ switch (side) {
+ case Gtk.SideType.Top:
+ fault.Y -= FaultOverlap;
+ fault.Height = 2 * FaultOverlap;
+ orientation = Gtk.Orientation.Horizontal;
+ break;
+ case Gtk.SideType.Bottom:
+ fault.Y += fault.Height - FaultOverlap;
+ fault.Height = 2 * FaultOverlap;
+ orientation = Gtk.Orientation.Horizontal;
+ break;
+ case Gtk.SideType.Left:
+ fault.X -= FaultOverlap;
+ fault.Width = 2 * FaultOverlap;
+ orientation = Gtk.Orientation.Vertical;
+ break;
+ case Gtk.SideType.Right:
+ fault.X += fault.Width - FaultOverlap;
+ fault.Width = 2 *FaultOverlap;
+ orientation = Gtk.Orientation.Vertical;
+ break;
+ default:
+ throw new Exception ("not reached");
+ }
+
+ AddFault (owner, faultId, orientation, fault);
+ }
+
+ static void FaultWidgetDestroyed (object widget, EventArgs args)
+ {
+ ClearFaults ((Gtk.Widget)widget);
+ }
+
+ public static void ClearFaults (Stetic.Wrapper.Widget owner)
+ {
+ ClearFaults (owner.Wrapped);
+ }
+
+ static void ClearFaults (Gtk.Widget widget)
+ {
+ Hashtable widgetFaults = faultGroups[widget] as Hashtable;
+ if (widgetFaults == null)
+ return;
+ faultGroups.Remove (widget);
+
+ foreach (Gdk.Window win in widgetFaults.Keys)
+ win.Destroy ();
+ widgetFaults.Clear ();
+ DND.DestUnset (widget);
+ }
+
+ static void ShowFaults ()
+ {
+ foreach (Hashtable widgetFaults in faultGroups.Values) {
+ foreach (Gdk.Window win in widgetFaults.Keys)
+ win.Show ();
+ }
+ }
+
+ static void HideFaults ()
+ {
+ foreach (Hashtable widgetFaults in faultGroups.Values) {
+ foreach (Gdk.Window win in widgetFaults.Keys)
+ win.Hide ();
+ }
+ DestroySplitter ();
+ dragFault = null;
+ }
+
+ static Fault dragFault;
+ static Gdk.Window splitter;
+
+ static void DestroySplitter ()
+ {
+ if (splitter != null) {
+ splitter.Hide ();
+ splitter.Destroy ();
+ splitter = null;
+ }
+ }
+
+ static Fault FindFault (int x, int y, Gtk.Widget w)
+ {
+ int wx, wy, width, height, depth;
+
+ Hashtable widgetFaults = (Hashtable) faultGroups [w];
+ if (widgetFaults == null)
+ return null;
+
+ foreach (Fault f in widgetFaults.Values) {
+ f.Window.GetGeometry (out wx, out wy, out width, out height, out depth);
+ if (x >= wx && y >= wy && x <= wx + width && y <= wy + height) {
+ return f;
+ }
+ }
+ return null;
+ }
+
+ static void FaultDragMotion (object obj, Gtk.DragMotionArgs args)
+ {
+ int wx, wy, width, height, depth;
+
+ Gtk.Widget widget = (Gtk.Widget) obj;
+ int px = args.X + widget.Allocation.X;
+ int py = args.Y + widget.Allocation.Y;
+
+ Fault fault = FindFault (px, py, widget);
+
+ // If there's a splitter visible, and we're not currently dragging
+ // in the fault that owns that splitter, hide it
+ if (splitter != null && dragFault != fault)
+ DestroySplitter ();
+
+ if (dragFault != fault) {
+ dragFault = fault;
+ if (dragFault == null)
+ return;
+
+ splitter = NewWindow (fault.Owner.Wrapped, Gdk.WindowClass.InputOutput);
+ fault.Window.GetGeometry (out wx, out wy, out width, out height, out depth);
+ if (fault.Orientation == Gtk.Orientation.Horizontal) {
+ splitter.MoveResize (wx, wy + height / 2 - FaultOverlap,
+ width, 2 * FaultOverlap);
+ } else {
+ splitter.MoveResize (wx + width / 2 - FaultOverlap, wy,
+ 2 * FaultOverlap, height);
+ }
+ splitter.ShowUnraised ();
+ fault.Window.Lower ();
+ } else if (dragFault == null)
+ return;
+
+ Gdk.Drag.Status (args.Context, Gdk.DragAction.Move, args.Time);
+ args.RetVal = true;
+ }
+
+ static void FaultDragLeave (object obj, Gtk.DragLeaveArgs args)
+ {
+ DestroySplitter ();
+ dragFault = null;
+ }
+
+ static void FaultDrop (Stetic.Wrapper.Widget wrapper, int x, int y, Gtk.Widget targetWidget)
+ {
+ Fault fault = FindFault (x, y, targetWidget);
+ if (fault != null) {
+ fault.Owner.Drop (wrapper.Wrapped, fault.Id);
+ wrapper.Select ();
+ }
+ }
+
+ static void FaultDragDrop (object obj, Gtk.DragDropArgs args)
+ {
+ Gtk.Widget w = DND.Drop (args.Context, (Gtk.Widget)obj, args.Time);
+ Stetic.Wrapper.Widget dropped = Stetic.Wrapper.Widget.Lookup (w);
+ if (dropped != null) {
+ Gtk.Widget targetWidget = (Gtk.Widget) obj;
+ int px = args.X + targetWidget.Allocation.X;
+ int py = args.Y + targetWidget.Allocation.Y;
+
+ FaultDrop (dropped, px, py, targetWidget);
+ args.RetVal = true;
+ }
+ }
+
+ static void FaultDragDataReceived (object obj, Gtk.DragDataReceivedArgs args)
+ {
+ Stetic.Wrapper.Widget dropped = null;
+
+ Stetic.Wrapper.Widget faultOwner = Stetic.Wrapper.Widget.Lookup ((Gtk.Widget)obj);
+ if (faultOwner != null)
+ dropped = WidgetUtils.Paste (faultOwner.Project, args.SelectionData);
+ Gtk.Drag.Finish (args.Context, dropped != null,
+ dropped != null, args.Time);
+ if (dropped != null) {
+ Gtk.Widget targetWidget = (Gtk.Widget) obj;
+ int px = args.X + targetWidget.Allocation.X;
+ int py = args.Y + targetWidget.Allocation.Y;
+ FaultDrop (dropped, px, py, targetWidget);
+ }
+ }
+
+ static Gdk.Window NewWindow (Gtk.Widget parent, Gdk.WindowClass wclass)
+ {
+ Gdk.WindowAttr attributes;
+ Gdk.WindowAttributesType attributesMask;
+ Gdk.Window win;
+
+ attributes = new Gdk.WindowAttr ();
+ attributes.WindowType = Gdk.WindowType.Child;
+ attributes.Wclass = wclass ;
+ attributes.Visual = parent.Visual;
+ attributes.Colormap = parent.Colormap;
+ attributes.Mask = (Gdk.EventMask.ButtonPressMask |
+ Gdk.EventMask.ButtonMotionMask |
+ Gdk.EventMask.ButtonReleaseMask |
+ Gdk.EventMask.ExposureMask |
+ Gdk.EventMask.EnterNotifyMask |
+ Gdk.EventMask.LeaveNotifyMask);
+
+ attributesMask =
+ Gdk.WindowAttributesType.Visual |
+ Gdk.WindowAttributesType.Colormap;
+
+ win = new Gdk.Window (parent.GdkWindow, attributes, attributesMask);
+ win.UserData = parent.Handle;
+
+ if (wclass == Gdk.WindowClass.InputOutput)
+ parent.Style.Attach (win);
+
+ return win;
+ }
+ }
+
+ public delegate Gtk.Widget WidgetDropCallback ();
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/EnumDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/EnumDescriptor.cs
new file mode 100644
index 0000000000..79ee48b3c9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/EnumDescriptor.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+
+namespace Stetic {
+ public class EnumValue {
+ public Enum Value;
+ public string Label;
+ public string Description;
+
+ internal EnumValue (Enum value, string label, string description)
+ {
+ Value = value;
+ Label = label;
+ Description = description;
+ }
+ }
+
+ public class EnumDescriptor {
+
+ Type enumType;
+ Hashtable values;
+ Enum[] values_array;
+ string name;
+
+ public EnumDescriptor (XmlElement elem)
+ {
+ string cls = elem.GetAttribute ("type");
+ enumType = Registry.GetType (cls, true);
+ this.name = enumType.FullName;
+
+ values = new Hashtable ();
+
+ // This gets the list of enum names and gets the value of each of them.
+ // This is not done the other way (get the values, and then the names from them)
+ // because it won't work if two different enum members have the same value
+ ArrayList list = new ArrayList ();
+ Hashtable evalues = new Hashtable ();
+ foreach (string name in Enum.GetNames (enumType)) {
+ object value = Enum.Parse (enumType, name);
+ list.Add (value);
+ evalues[name] = value;
+ }
+
+ foreach (XmlElement valueElem in elem.SelectNodes ("value")) {
+ string name = valueElem.GetAttribute ("name");
+ if (!evalues.Contains (name))
+ throw new ArgumentException ("<enum> node for " + enumType.FullName + " contains extra element " + name);
+ Enum value = (Enum)evalues[name];
+ values[value] = new EnumValue (value,
+ valueElem.GetAttribute ("label"),
+ valueElem.GetAttribute ("description"));
+ evalues.Remove (name);
+ }
+
+ // Remove from the array the values not declared in the xml file
+ foreach (object val in evalues.Values)
+ list.Remove (val);
+
+ values_array = (Enum[]) list.ToArray (typeof(Enum));
+ }
+
+ public string Name {
+ get { return name; }
+ }
+
+ public Type EnumType {
+ get {
+ return enumType;
+ }
+ }
+
+ public Enum[] Values {
+ get {
+ return values_array;
+ }
+ }
+
+ public EnumValue this[Enum value] {
+ get {
+ return (EnumValue)values[value];
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ErrorWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ErrorWidget.cs
new file mode 100644
index 0000000000..82ec4ecc50
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ErrorWidget.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Xml;
+using System.CodeDom;
+using Mono.Unix;
+
+namespace Stetic
+{
+ // This widget is shown in place of widgets with unknown classes.
+
+ public class ErrorWidget: Gtk.Frame
+ {
+ readonly string className;
+ readonly Exception exc;
+
+ public ErrorWidget (Exception ex, string id)
+ {
+ exc = ex;
+ Init (Catalog.GetString ("Load Error:") + " " + ex.Message, id);
+ }
+
+ public ErrorWidget (string className, string id)
+ {
+ this.className = className;
+ Init (Catalog.GetString ("Unknown widget:") + " " + className, id);
+ }
+
+ public ErrorWidget (string className, string minGtkVersion, string foundGtkVersion, string id)
+ {
+ this.className = className;
+ Init (string.Format (Catalog.GetString ("Widget '{0}' not available in GTK# {1}"), className, foundGtkVersion), id);
+ }
+
+ void Init (string message, string id)
+ {
+ Gtk.Label lab = new Gtk.Label ();
+ lab.Markup = "<b><span foreground='red'>" + message + "</span></b>";
+ this.CanFocus = false;
+ Add (lab);
+ this.ShadowType = Gtk.ShadowType.In;
+ ShowAll ();
+ if (id != null && id.Length > 0)
+ Name = id;
+ }
+
+ public string ClassName {
+ get { return className; }
+ }
+
+ public Exception Exception {
+ get { return exc; }
+ }
+ }
+
+ internal class ErrorWidgetWrapper: Wrapper.Widget
+ {
+ XmlElement elementData;
+ FileFormat format;
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ elementData = elem;
+ this.format = reader.Format;
+ }
+
+ public override XmlElement Write (ObjectWriter writer)
+ {
+ if (writer.Format != this.format) {
+ ErrorWidget ew = (ErrorWidget) Wrapped;
+ XmlElement elem = writer.XmlDocument.CreateElement ("widget");
+ elem.SetAttribute ("class", "Gtk.Label");
+ elem.SetAttribute ("id", Wrapped.Name);
+ XmlElement ce = writer.XmlDocument.CreateElement ("property");
+ string msg;
+ if (ew.Exception != null)
+ msg = "Invalid widget";
+ else
+ msg = "Unknown widget: " + ew.ClassName;
+ ce.SetAttribute ("name", "LabelProp");
+ ce.InnerText = msg;
+ elem.AppendChild (ce);
+ return elem;
+ }
+ else
+ return (XmlElement) writer.XmlDocument.ImportNode (elementData, true);
+ }
+
+ public override string WrappedTypeName {
+ get {
+ ErrorWidget ew = (ErrorWidget) Wrapped;
+ return ew.ClassName;
+ }
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ ErrorWidget ew = (ErrorWidget) Wrapped;
+ string msg;
+ if (ew.Exception != null)
+ msg = Project.FolderName + ": Could not generate code for an invalid widget. The widget failed to load: " + ew.Exception.Message + ". The generated code may be invalid.";
+ else
+ msg = Project.FolderName + ": Could not generate code for widgets of type: " + ew.ClassName + ". The widget could not be found in any referenced library. The generated code may be invalid.";
+
+ if (ctx.Options.FailForUnknownWidgets) {
+ throw new InvalidOperationException (msg);
+ } else {
+ ctx.ReportWarning (msg);
+ return new CodePrimitiveExpression (null);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/GeneratorContext.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/GeneratorContext.cs
new file mode 100644
index 0000000000..65b6daa416
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/GeneratorContext.cs
@@ -0,0 +1,546 @@
+using System;
+using System.CodeDom;
+using System.Collections;
+
+namespace Stetic
+{
+ public class GeneratorContext
+ {
+ CodeNamespace cns;
+ int n;
+ string idPrefix;
+ Hashtable vars = new Hashtable ();
+ ArrayList generatedWrappers = new ArrayList ();
+ WidgetMap map;
+ CodeStatementCollection statements;
+ GenerationOptions options;
+ ArrayList warnings = new ArrayList ();
+ CodeExpression rootObject;
+
+ public GeneratorContext (CodeNamespace cns, string idPrefix, CodeStatementCollection statements, GenerationOptions options)
+ {
+ this.cns = cns;
+ this.idPrefix = idPrefix;
+ this.statements = statements;
+ this.options = options;
+ map = new WidgetMap (vars);
+ }
+
+ public CodeNamespace GlobalCodeNamespace {
+ get { return cns; }
+ }
+
+ public CodeStatementCollection Statements {
+ get { return statements; }
+ }
+
+ public GenerationOptions Options {
+ get { return options; }
+ }
+
+ public string[] Warnings {
+ get { return (string[]) warnings.ToArray (typeof(string)); }
+ }
+
+ public void ReportWarning (string s)
+ {
+ warnings.Add (s);
+ }
+
+ public string NewId ()
+ {
+ return idPrefix + (++n);
+ }
+
+ public CodeExpression GenerateNewInstanceCode (Wrapper.Widget widget)
+ {
+ CodeExpression exp = widget.GenerateObjectCreation (this);
+ CodeExpression var = GenerateInstanceExpression (widget, exp);
+ GenerateBuildCode (widget, var);
+ return var;
+ }
+
+ public virtual CodeExpression GenerateInstanceExpression (ObjectWrapper wrapper, CodeExpression newObject)
+ {
+ string varName = NewId ();
+ CodeVariableDeclarationStatement varDec = new CodeVariableDeclarationStatement (wrapper.WrappedTypeName.ToGlobalTypeRef (), varName);
+ varDec.InitExpression = newObject;
+ statements.Add (varDec);
+ return new CodeVariableReferenceExpression (varName);
+ }
+
+ public virtual void GenerateCreationCode (ObjectWrapper wrapper, CodeExpression varExp)
+ {
+ rootObject = varExp;
+ wrapper.GenerateInitCode (this, varExp);
+ GenerateBuildCode (wrapper, varExp);
+ }
+
+ public virtual void GenerateBuildCode (ObjectWrapper wrapper, CodeExpression var)
+ {
+ vars [wrapper] = var;
+ wrapper.GenerateBuildCode (this, var);
+ generatedWrappers.Add (wrapper);
+ }
+
+ public virtual void GenerateCreationCode (Wrapper.ActionGroup agroup, CodeExpression var)
+ {
+ rootObject = var;
+ vars [agroup] = var;
+ agroup.GenerateBuildCode (this, var);
+ }
+
+ public CodeExpression GenerateValue (object value, Type type)
+ {
+ return GenerateValue (value, type, false);
+ }
+
+ public CodeExpression GenerateValue (object value, Type type, bool translatable)
+ {
+ if (value == null)
+ return new CodePrimitiveExpression (value);
+
+ if (value.GetType ().IsEnum) {
+ if (!type.IsEnum) {
+ object ival = Convert.ChangeType (value, type);
+ return new CodePrimitiveExpression (ival);
+ } else {
+ long ival = (long) Convert.ChangeType (value, typeof(long));
+ return new CodeCastExpression (
+ value.GetType ().ToGlobalTypeRef (),
+ new CodePrimitiveExpression (ival)
+ );
+ }
+ }
+
+ if (value is Gtk.Adjustment) {
+ Gtk.Adjustment adj = value as Gtk.Adjustment;
+ return new CodeObjectCreateExpression (
+ typeof(Gtk.Adjustment).ToGlobalTypeRef (),
+ new CodePrimitiveExpression (adj.Value),
+ new CodePrimitiveExpression (adj.Lower),
+ new CodePrimitiveExpression (adj.Upper),
+ new CodePrimitiveExpression (adj.StepIncrement),
+ new CodePrimitiveExpression (adj.PageIncrement),
+ new CodePrimitiveExpression (adj.PageSize));
+ }
+ if (value is ushort || value is uint) {
+ return new CodeCastExpression (
+ value.GetType ().ToGlobalTypeRef (),
+ new CodePrimitiveExpression (Convert.ChangeType (value, typeof(long))));
+ }
+ if (value is ulong) {
+ return new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (value.GetType ()),
+ "Parse",
+ new CodePrimitiveExpression (value.ToString ()));
+ }
+
+ if (value is ImageInfo && typeof(Gdk.Pixbuf).IsAssignableFrom (type))
+ return ((ImageInfo)value).ToCodeExpression (this);
+
+ if (value is Wrapper.ActionGroup) {
+ return new CodeMethodInvokeExpression (
+ new CodeMethodReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (GlobalCodeNamespace.Name + ".ActionGroups", CodeTypeReferenceOptions.GlobalReference)),
+ "GetActionGroup"
+ ),
+ new CodePrimitiveExpression (((Wrapper.ActionGroup)value).Name)
+ );
+ }
+
+ if (value is Array) {
+ ArrayList list = new ArrayList ();
+ foreach (object val in (Array)value)
+ list.Add (GenerateValue (val, val != null ? val.GetType() : null, translatable));
+ return new CodeArrayCreateExpression (value.GetType().GetElementType(), (CodeExpression[]) list.ToArray(typeof(CodeExpression)));
+ }
+
+ if (value is DateTime) {
+ return new CodeObjectCreateExpression (
+ typeof(DateTime).ToGlobalTypeRef (),
+ new CodePrimitiveExpression (((DateTime)value).Ticks)
+ );
+ }
+
+ if (value is TimeSpan) {
+ return new CodeObjectCreateExpression (
+ typeof(TimeSpan).ToGlobalTypeRef (),
+ new CodePrimitiveExpression (((TimeSpan)value).Ticks)
+ );
+ }
+
+ string str = value as string;
+ if (translatable && str != null && str.Length > 0 && options.UseGettext) {
+ return new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (options.GettextClass, CodeTypeReferenceOptions.GlobalReference)),
+ "GetString",
+ new CodePrimitiveExpression (str)
+ );
+ }
+
+ return new CodePrimitiveExpression (value);
+ }
+
+ public WidgetMap WidgetMap {
+ get { return map; }
+ }
+
+ public System.CodeDom.CodeExpression RootObject {
+ get {
+ return rootObject;
+ }
+ set {
+ rootObject = value;
+ }
+ }
+
+ public void EndGeneration ()
+ {
+ foreach (ObjectWrapper w in generatedWrappers) {
+ CodeExpression var = (CodeExpression) vars [w];
+ w.GeneratePostBuildCode (this, var);
+ }
+ }
+
+ public void Reset ()
+ {
+ vars.Clear ();
+ generatedWrappers.Clear ();
+ map = new WidgetMap (vars);
+ n = 0;
+ }
+
+ public CodeExpression GenerateLoadPixbuf (string name, Gtk.IconSize size)
+ {
+ bool found = false;
+ foreach (CodeTypeDeclaration t in cns.Types) {
+ if (t.Name == "IconLoader") {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ CodeTypeDeclaration cls = new CodeTypeDeclaration ("IconLoader");
+ cls.Attributes = MemberAttributes.Private;
+ cls.TypeAttributes = System.Reflection.TypeAttributes.NestedAssembly;
+ cns.Types.Add (cls);
+
+ CodeMemberMethod met = new CodeMemberMethod ();
+ cls.Members.Add (met);
+ met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+ met.Name = "LoadIcon";
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(Gtk.Widget), "widget"));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "name"));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(Gtk.IconSize), "size"));
+ met.ReturnType = new CodeTypeReference (typeof(Gdk.Pixbuf));
+
+ CodeExpression widgetExp = new CodeVariableReferenceExpression ("widget");
+ CodeExpression nameExp = new CodeVariableReferenceExpression ("name");
+ CodeExpression sizeExp = new CodeVariableReferenceExpression ("size");
+ CodeExpression szExp = new CodeVariableReferenceExpression ("sz");
+ CodeExpression mgExp = new CodeBinaryOperatorExpression (szExp, CodeBinaryOperatorType.Divide, new CodePrimitiveExpression (4));
+ CodeExpression pmapExp = new CodeVariableReferenceExpression ("pmap");
+ CodeExpression gcExp = new CodeVariableReferenceExpression ("gc");
+ CodeExpression szM1Exp = new CodeBinaryOperatorExpression (szExp, CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression (1));
+ CodeExpression zeroExp = new CodePrimitiveExpression (0);
+ CodeExpression resExp = new CodeVariableReferenceExpression ("res");
+
+ met.Statements.Add (
+ new CodeVariableDeclarationStatement (typeof(Gdk.Pixbuf), "res",
+ new CodeMethodInvokeExpression (
+ widgetExp,
+ "RenderIcon",
+ nameExp,
+ sizeExp,
+ new CodePrimitiveExpression (null)
+ )
+ )
+ );
+
+ CodeConditionStatement nullcheck = new CodeConditionStatement ();
+ met.Statements.Add (nullcheck);
+ nullcheck.Condition = new CodeBinaryOperatorExpression (
+ resExp,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression (null)
+ );
+ nullcheck.TrueStatements.Add (new CodeMethodReturnStatement (resExp));
+
+ // int sz, h;
+ // Gtk.Icon.SizeLookup (size, out sz, out h);
+
+ nullcheck.FalseStatements.Add (new CodeVariableDeclarationStatement (typeof(int), "sz"));
+ nullcheck.FalseStatements.Add (new CodeVariableDeclarationStatement (typeof(int), "sy"));
+ nullcheck.FalseStatements.Add (new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (typeof(Gtk.Icon).ToGlobalTypeRef ()),
+ "SizeLookup",
+ sizeExp,
+ new CodeDirectionExpression (FieldDirection.Out, szExp),
+ new CodeDirectionExpression (FieldDirection.Out, new CodeVariableReferenceExpression ("sy"))
+ ));
+
+ CodeTryCatchFinallyStatement trycatch = new CodeTryCatchFinallyStatement ();
+ nullcheck.FalseStatements.Add (trycatch);
+ trycatch.TryStatements.Add (
+ new CodeMethodReturnStatement (
+ new CodeMethodInvokeExpression (
+ new CodePropertyReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(Gtk.IconTheme))),
+ "Default"
+ ),
+ "LoadIcon",
+ nameExp,
+ szExp,
+ zeroExp
+ )
+ )
+ );
+
+ CodeCatchClause ccatch = new CodeCatchClause ();
+ trycatch.CatchClauses.Add (ccatch);
+
+ CodeConditionStatement cond = new CodeConditionStatement ();
+ ccatch.Statements.Add (cond);
+
+ cond.Condition = new CodeBinaryOperatorExpression (
+ nameExp,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression ("gtk-missing-image")
+ );
+
+ cond.TrueStatements.Add (
+ new CodeMethodReturnStatement (
+ new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (cns.Name + "." + cls.Name),
+ "LoadIcon",
+ widgetExp,
+ new CodePrimitiveExpression ("gtk-missing-image"),
+ sizeExp
+ )
+ )
+ );
+
+ CodeStatementCollection stms = cond.FalseStatements;
+
+ stms.Add (
+ new CodeVariableDeclarationStatement (typeof(Gdk.Pixmap), "pmap",
+ new CodeObjectCreateExpression (
+ typeof(Gdk.Pixmap),
+ new CodePropertyReferenceExpression (
+ new CodePropertyReferenceExpression (
+ new CodeTypeReferenceExpression (typeof(Gdk.Screen)),
+ "Default"
+ ),
+ "RootWindow"
+ ),
+ szExp,
+ szExp
+ )
+ )
+ );
+ stms.Add (
+ new CodeVariableDeclarationStatement (typeof(Gdk.GC), "gc",
+ new CodeObjectCreateExpression (typeof(Gdk.GC), pmapExp)
+ )
+ );
+ stms.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ gcExp,
+ "RgbFgColor"
+ ),
+ new CodeObjectCreateExpression (
+ typeof(Gdk.Color),
+ new CodePrimitiveExpression (255),
+ new CodePrimitiveExpression (255),
+ new CodePrimitiveExpression (255)
+ )
+ )
+ );
+ stms.Add (
+ new CodeMethodInvokeExpression (
+ pmapExp,
+ "DrawRectangle",
+ gcExp,
+ new CodePrimitiveExpression (true),
+ zeroExp,
+ zeroExp,
+ szExp,
+ szExp
+ )
+ );
+ stms.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ gcExp,
+ "RgbFgColor"
+ ),
+ new CodeObjectCreateExpression (
+ typeof(Gdk.Color),
+ zeroExp, zeroExp, zeroExp
+ )
+ )
+ );
+ stms.Add (
+ new CodeMethodInvokeExpression (
+ pmapExp,
+ "DrawRectangle",
+ gcExp,
+ new CodePrimitiveExpression (false),
+ zeroExp,
+ zeroExp,
+ szM1Exp,
+ szM1Exp
+ )
+ );
+ stms.Add (
+ new CodeMethodInvokeExpression (
+ gcExp,
+ "SetLineAttributes",
+ new CodePrimitiveExpression (3),
+ new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typeof(Gdk.LineStyle)), "Solid"),
+ new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typeof(Gdk.CapStyle)), "Round"),
+ new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typeof(Gdk.JoinStyle)), "Round")
+ )
+ );
+ stms.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ gcExp,
+ "RgbFgColor"
+ ),
+ new CodeObjectCreateExpression (
+ typeof(Gdk.Color),
+ new CodePrimitiveExpression (255),
+ zeroExp,
+ zeroExp
+ )
+ )
+ );
+ stms.Add (
+ new CodeMethodInvokeExpression (
+ pmapExp,
+ "DrawLine",
+ gcExp,
+ mgExp,
+ mgExp,
+ new CodeBinaryOperatorExpression (szM1Exp, CodeBinaryOperatorType.Subtract, mgExp),
+ new CodeBinaryOperatorExpression (szM1Exp, CodeBinaryOperatorType.Subtract, mgExp)
+ )
+ );
+ stms.Add (
+ new CodeMethodInvokeExpression (
+ pmapExp,
+ "DrawLine",
+ gcExp,
+ new CodeBinaryOperatorExpression (szM1Exp, CodeBinaryOperatorType.Subtract, mgExp),
+ mgExp,
+ mgExp,
+ new CodeBinaryOperatorExpression (szM1Exp, CodeBinaryOperatorType.Subtract, mgExp)
+ )
+ );
+ stms.Add (
+ new CodeMethodReturnStatement (
+ new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (typeof(Gdk.Pixbuf)),
+ "FromDrawable",
+ pmapExp,
+ new CodePropertyReferenceExpression (pmapExp, "Colormap"),
+ zeroExp, zeroExp, zeroExp, zeroExp, szExp, szExp
+ )
+ )
+ );
+ }
+
+ int sz, h;
+ Gtk.Icon.SizeLookup (size, out sz, out h);
+
+ return new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (cns.Name + ".IconLoader", CodeTypeReferenceOptions.GlobalReference)),
+ "LoadIcon",
+ rootObject,
+ new CodePrimitiveExpression (name),
+ new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(Gtk.IconSize), CodeTypeReferenceOptions.GlobalReference)),
+ size.ToString ()
+ )
+ );
+ }
+ }
+
+ public class WidgetMap
+ {
+ Hashtable vars;
+
+ internal WidgetMap (Hashtable vars)
+ {
+ this.vars = vars;
+ }
+
+ public CodeExpression GetWidgetExp (ObjectWrapper wrapper)
+ {
+ return (CodeExpression) vars [wrapper];
+ }
+
+ public CodeExpression GetWidgetExp (object wrapped)
+ {
+ ObjectWrapper w = ObjectWrapper.Lookup (wrapped);
+ if (w != null)
+ return GetWidgetExp (w);
+ else
+ return null;
+ }
+ }
+
+ [Serializable]
+ public class GenerationOptions
+ {
+ bool useGettext;
+ bool partialClasses;
+ bool generateEmptyBuildMethod;
+ bool generateSingleFile = true;
+ bool failForUnknownWidgets = false;
+ string path;
+ string globalNamespace = "Stetic";
+ string gettextClass;
+
+ public bool UseGettext {
+ get { return useGettext; }
+ set { useGettext = value; }
+ }
+
+ public string GettextClass {
+ get {
+ if (gettextClass == null || gettextClass.Length == 0)
+ return "Mono.Unix.Catalog";
+ else
+ return gettextClass;
+ }
+ set { gettextClass = value; }
+ }
+
+ public string Path {
+ get { return path; }
+ set { path = value; }
+ }
+
+ public bool GenerateEmptyBuildMethod {
+ get { return generateEmptyBuildMethod; }
+ set { generateEmptyBuildMethod = value; }
+ }
+
+ public string GlobalNamespace {
+ get { return globalNamespace; }
+ set { globalNamespace = value; }
+ }
+
+ public bool FailForUnknownWidgets {
+ get { return failForUnknownWidgets; }
+ set { failForUnknownWidgets = value; }
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeException.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeException.cs
new file mode 100644
index 0000000000..504dab9823
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeException.cs
@@ -0,0 +1,59 @@
+using System;
+
+namespace Stetic {
+
+ public class GladeException : ApplicationException {
+
+ public GladeException (string message) : base (message) { }
+
+ public GladeException (string message, string className) :
+ this (message + " (class " + className + ")")
+ {
+ this.className = className;
+ }
+
+ public GladeException (string message, string className,
+ bool childprop, string propName) :
+ this (message + " (class " + className + ", " + (childprop ? "child " : "") + "property " + propName + ")")
+ {
+ this.childprop = childprop;
+ this.propName = propName;
+ }
+
+ public GladeException (string message, string className,
+ bool childprop, string propName, string propVal) :
+ this (message + " (class " + className + ", " + (childprop ? "child " : "") + "property " + propName + ", value " + propVal + ")")
+ {
+ this.childprop = childprop;
+ this.propName = propName;
+ this.propVal = propVal;
+ }
+
+ string className, propName, propVal;
+ bool childprop;
+
+ public string ClassName {
+ get {
+ return className;
+ }
+ }
+
+ public bool ChildProp {
+ get {
+ return childprop;
+ }
+ }
+
+ public string PropName {
+ get {
+ return propName;
+ }
+ }
+
+ public string PropVal {
+ get {
+ return propVal;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeUtils.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeUtils.cs
new file mode 100644
index 0000000000..bb02c0e198
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/GladeUtils.cs
@@ -0,0 +1,773 @@
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Runtime.InteropServices;
+using System.Xml;
+using Stetic.Wrapper;
+
+namespace Stetic {
+
+ public static class GladeUtils {
+
+ public const string Glade20SystemId = "http://glade.gnome.org/glade-2.0.dtd";
+
+ static Gdk.Atom gladeAtom;
+ public static Gdk.Atom ApplicationXGladeAtom {
+ get {
+ if (gladeAtom == null)
+ gladeAtom = Gdk.Atom.Intern ("application/x-glade", false);
+ return gladeAtom;
+ }
+ }
+
+ public static XmlDocument XslImportTransform (XmlDocument doc)
+ {
+/* XmlDocumentType doctype = doc.DocumentType;
+ if (doctype == null ||
+ doctype.Name != "glade-interface" ||
+ doctype.SystemId != Glade20SystemId)
+ throw new GladeException ("Not a glade file according to doctype");
+*/
+ XmlReader reader = Registry.GladeImportXsl.Transform (doc, null, (XmlResolver)null);
+ doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+ doc.Load (reader);
+
+ return doc;
+ }
+
+ public static XmlDocument XslExportTransform (XmlDocument doc)
+ {
+ XmlReader reader = Registry.GladeExportXsl.Transform (doc, null, (XmlResolver)null);
+ doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+ doc.Load (reader);
+
+ XmlDocumentType doctype = doc.CreateDocumentType ("glade-interface", null, Glade20SystemId, null);
+ doc.PrependChild (doctype);
+
+ return doc;
+ }
+
+ public static XmlDocument Export (Gtk.Widget widget)
+ {
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+ if (wrapper == null)
+ return null;
+
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+
+ XmlElement toplevel = doc.CreateElement ("glade-interface");
+ doc.AppendChild (toplevel);
+
+ // For toplevel widgets, glade just saves it as-is. For
+ // non-toplevels, it puts the widget into a dummy GtkWindow,
+ // but using the packing attributes of the widget's real
+ // container (so as to preserve expand/fill settings and the
+ // like).
+
+ XmlElement elem;
+ Stetic.Wrapper.Container parent = wrapper.ParentWrapper;
+ ObjectWriter writer = new ObjectWriter (doc, FileFormat.Glade);
+
+ if (parent == null) {
+ elem = wrapper.Write (writer);
+ if (elem == null)
+ return null;
+ if (!(widget is Gtk.Window)) {
+ XmlElement window = doc.CreateElement ("widget");
+ window.SetAttribute ("class", "GtkWindow");
+ window.SetAttribute ("id", "glade-dummy-container");
+ XmlElement child = doc.CreateElement ("child");
+ window.AppendChild (child);
+ child.AppendChild (elem);
+ elem = window;
+ }
+ } else {
+ elem = doc.CreateElement ("widget");
+ // Set the class correctly (temporarily) so the XSL
+ // transforms will work correctly.
+ ClassDescriptor klass = parent.ClassDescriptor;
+ elem.SetAttribute ("class", klass.CName);
+ elem.AppendChild (parent.WriteContainerChild (writer, wrapper));
+ }
+ toplevel.AppendChild (elem);
+
+ doc = XslExportTransform (doc);
+
+ if (parent != null) {
+ elem = (XmlElement)doc.SelectSingleNode ("glade-interface/widget");
+ elem.SetAttribute ("class", "GtkWindow");
+ elem.SetAttribute ("id", "glade-dummy-container");
+ }
+ return doc;
+ }
+
+// public static Stetic.Wrapper.Widget Import (IProject project, XmlDocument doc)
+// {
+// try {
+// doc = XslImportTransform (doc);
+// } catch {
+// return null;
+// }
+//
+// ObjectReader reader = new ObjectReader (project, FileFormat.Glade);
+//
+// XmlElement elem = (XmlElement)doc.SelectSingleNode ("glade-interface/widget");
+// if (elem.GetAttribute ("class") != "GtkWindow" ||
+// elem.GetAttribute ("id") != "glade-dummy-container") {
+// // Creating a new toplevel
+// Stetic.Wrapper.Widget toplevel = (Stetic.Wrapper.Widget)
+// Stetic.ObjectWrapper.ReadObject (reader, elem);
+// if (toplevel != null) {
+// project.AddWindow ((Gtk.Window)toplevel.Wrapped);
+// }
+// return toplevel;
+// }
+//
+// return (Stetic.Wrapper.Widget)
+// Stetic.ObjectWrapper.ReadObject (reader, (XmlElement)elem.SelectSingleNode ("child/widget"));
+// }
+
+ public static void Copy (Gtk.Widget widget, Gtk.SelectionData seldata, bool copyAsText)
+ {
+ XmlDocument doc = Export (widget);
+ if (doc == null)
+ return;
+
+ if (copyAsText)
+ seldata.Text = doc.OuterXml;
+ else
+ seldata.Set (ApplicationXGladeAtom, 8, System.Text.Encoding.UTF8.GetBytes (doc.OuterXml));
+ }
+
+// public static Stetic.Wrapper.Widget Paste (IProject project, Gtk.SelectionData seldata)
+// {
+// if (seldata.Type != ApplicationXGladeAtom)
+// return null;
+// string data = System.Text.Encoding.UTF8.GetString (seldata.Data);
+//
+// XmlDocument doc = new XmlDocument ();
+// doc.PreserveWhitespace = true;
+// try {
+// doc.LoadXml (data);
+// } catch {
+// return null;
+// }
+//
+// return Import (project, doc);
+// }
+
+ static object GetProperty (XmlElement elem, string selector, object defaultValue, bool extract)
+ {
+ XmlElement prop = (XmlElement)elem.SelectSingleNode (selector);
+ if (prop == null)
+ return defaultValue;
+ if (extract)
+ prop.ParentNode.RemoveChild (prop);
+ return ParseProperty (null, defaultValue.GetType (), prop.InnerText).Val;
+ }
+
+ public static object GetProperty (XmlElement elem, string name, object defaultValue)
+ {
+ return GetProperty (elem, "./property[@name='" + name + "']", defaultValue, false);
+ }
+
+ public static object ExtractProperty (XmlElement elem, string name, object defaultValue)
+ {
+ return GetProperty (elem, "./property[@name='" + name + "']", defaultValue, true);
+ }
+
+ public static object GetChildProperty (XmlElement elem, string name, object defaultValue)
+ {
+ return GetProperty (elem, "./packing/property[@name='" + name + "']", defaultValue, false);
+ }
+
+ public static object ExtractChildProperty (XmlElement elem, string name, object defaultValue)
+ {
+ return GetProperty (elem, "./packing/property[@name='" + name + "']", defaultValue, true);
+ }
+
+ public static void SetProperty (XmlElement elem, string name, string value)
+ {
+ XmlElement prop_elem = elem.OwnerDocument.CreateElement ("property");
+ prop_elem.SetAttribute ("name", name);
+ prop_elem.InnerText = value;
+ elem.AppendChild (prop_elem);
+ }
+
+ public static void SetChildProperty (XmlElement elem, string name, string value)
+ {
+ XmlElement packing_elem = elem["packing"];
+ if (packing_elem == null) {
+ packing_elem = elem.OwnerDocument.CreateElement ("packing");
+ elem.AppendChild (packing_elem);
+ }
+ SetProperty (packing_elem, name, value);
+ }
+
+ static GLib.Value ParseBasicType (GLib.TypeFundamentals type, string strval)
+ {
+ switch (type) {
+ case GLib.TypeFundamentals.TypeChar:
+ return new GLib.Value (SByte.Parse (strval));
+ case GLib.TypeFundamentals.TypeUChar:
+ return new GLib.Value (Byte.Parse (strval));
+ case GLib.TypeFundamentals.TypeBoolean:
+ return new GLib.Value (strval == "True");
+ case GLib.TypeFundamentals.TypeInt:
+ return new GLib.Value (Int32.Parse (strval));
+ case GLib.TypeFundamentals.TypeUInt:
+ return new GLib.Value (UInt32.Parse (strval));
+ case GLib.TypeFundamentals.TypeInt64:
+ return new GLib.Value (Int64.Parse (strval));
+ case GLib.TypeFundamentals.TypeUInt64:
+ return new GLib.Value (UInt64.Parse (strval));
+ case GLib.TypeFundamentals.TypeFloat:
+ return new GLib.Value (Single.Parse (strval, System.Globalization.CultureInfo.InvariantCulture));
+ case GLib.TypeFundamentals.TypeDouble:
+ return new GLib.Value (Double.Parse (strval, System.Globalization.CultureInfo.InvariantCulture));
+ case GLib.TypeFundamentals.TypeString:
+ return new GLib.Value (strval);
+ default:
+ throw new GladeException ("Could not parse");
+ }
+ }
+
+ static GLib.Value ParseEnum (IntPtr gtype, string strval)
+ {
+ IntPtr enum_class = g_type_class_ref (gtype);
+ try {
+ IntPtr enum_value = g_enum_get_value_by_name (enum_class, strval);
+ if (enum_value == IntPtr.Zero)
+ throw new GladeException ("Could not parse");
+
+ int eval = Marshal.ReadInt32 (enum_value);
+ return new GLib.Value (Enum.ToObject (GLib.GType.LookupType (gtype), eval));
+ } finally {
+ g_type_class_unref (enum_class);
+ }
+ }
+
+ static GLib.Value ParseFlags (IntPtr gtype, string strval)
+ {
+ IntPtr flags_class = g_type_class_ref (gtype);
+ uint fval = 0;
+
+ try {
+ foreach (string flag in strval.Split ('|')) {
+ if (flag == "")
+ continue;
+ IntPtr flags_value = g_flags_get_value_by_name (flags_class, flag);
+ if (flags_value == IntPtr.Zero)
+ throw new GladeException ("Could not parse");
+
+ int bits = Marshal.ReadInt32 (flags_value);
+ fval |= (uint)bits;
+ }
+
+ return new GLib.Value (Enum.ToObject (GLib.GType.LookupType (gtype), fval));
+ } finally {
+ g_type_class_unref (flags_class);
+ }
+ }
+
+ static GLib.Value ParseAdjustment (string strval)
+ {
+ string[] vals = strval.Split (' ');
+ double deflt, min, max, step, page_inc, page_size;
+
+ deflt = Double.Parse (vals[0], System.Globalization.CultureInfo.InvariantCulture);
+ min = Double.Parse (vals[1], System.Globalization.CultureInfo.InvariantCulture);
+ max = Double.Parse (vals[2], System.Globalization.CultureInfo.InvariantCulture);
+ step = Double.Parse (vals[3], System.Globalization.CultureInfo.InvariantCulture);
+ page_inc = Double.Parse (vals[4], System.Globalization.CultureInfo.InvariantCulture);
+ page_size = Double.Parse (vals[5], System.Globalization.CultureInfo.InvariantCulture);
+ return new GLib.Value (new Gtk.Adjustment (deflt, min, max, step, page_inc, page_size));
+ }
+
+ /* static GLib.Value ParseUnichar (string strval)
+ {
+ return new GLib.Value (strval.Length == 1 ? (uint)strval[0] : 0U);
+ }*/
+
+ static GLib.Value ParseProperty (ParamSpec pspec, Type propType, string strval)
+ {
+ IntPtr gtype;
+ if (propType != null)
+ gtype = ((GLib.GType)propType).Val;
+/*
+ FIXME: ValueType is not supported right now
+
+ else if (pspec != null)
+ gtype = pspec.ValueType;
+*/
+ else
+ throw new GladeException ("Bad type");
+
+ GLib.TypeFundamentals typef = (GLib.TypeFundamentals)(int)g_type_fundamental (gtype);
+
+ if (gtype == Gtk.Adjustment.GType.Val)
+ return ParseAdjustment (strval);
+ else if (typef == GLib.TypeFundamentals.TypeEnum)
+ return ParseEnum (gtype, strval);
+ else if (typef == GLib.TypeFundamentals.TypeFlags)
+ return ParseFlags (gtype, strval);
+// FIXME: Enable when ParamSpec.IsUnichar is implemented.
+// else if (pspec != null && pspec.IsUnichar)
+// return ParseUnichar (strval);
+ else
+ return ParseBasicType (typef, strval);
+ }
+
+ static PropertyInfo FindClrProperty (Type type, string name, bool childprop)
+ {
+ if (childprop) {
+ Type[] types = type.GetNestedTypes ();
+ foreach (Type t in types) {
+ if (typeof(Gtk.Container.ContainerChild).IsAssignableFrom (t)) {
+ type = t;
+ break;
+ }
+ }
+ foreach (PropertyInfo pi in type.GetProperties ()) {
+ Gtk.ChildPropertyAttribute at = (Gtk.ChildPropertyAttribute) Attribute.GetCustomAttribute (pi, typeof(Gtk.ChildPropertyAttribute), false);
+ if (at != null && at.Name == name)
+ return pi;
+ }
+ if (typeof(GLib.Object).IsAssignableFrom (type.BaseType))
+ return FindClrProperty (type.BaseType, name, true);
+ }
+
+ foreach (PropertyInfo pi in type.GetProperties ()) {
+ GLib.PropertyAttribute at = (GLib.PropertyAttribute) Attribute.GetCustomAttribute (pi, typeof(GLib.PropertyAttribute), false);
+ if (at != null && at.Name == name)
+ return pi;
+ }
+ return null;
+ }
+
+ static GLib.Value ParseProperty (Type type, bool childprop, string name, string strval)
+ {
+ ParamSpec pspec;
+
+ // FIXME: this can be removed when GParamSpec supports ValueType.
+ PropertyInfo pi = FindClrProperty (type, name, childprop);
+ if (pi == null)
+ throw new GladeException ("Unknown property", type.ToString (), childprop, name, strval);
+
+ if (childprop)
+ pspec = ParamSpec.LookupChildProperty (type, name);
+ else
+ pspec = ParamSpec.LookupObjectProperty (type, name);
+ if (pspec == null)
+ throw new GladeException ("Unknown property", type.ToString (), childprop, name, strval);
+
+ try {
+ return ParseProperty (pspec, pi.PropertyType, strval);
+ } catch {
+ throw new GladeException ("Could not parse property", type.ToString (), childprop, name, strval);
+ }
+ }
+
+ static void ParseProperties (Type type, bool childprops, IEnumerable props,
+ out string[] propNames, out GLib.Value[] propVals)
+ {
+ ArrayList names = new ArrayList ();
+ ArrayList values = new ArrayList ();
+
+ foreach (XmlElement prop in props) {
+ string name = prop.GetAttribute ("name").Replace ("_","-");
+ string strval = prop.InnerText;
+
+ // Skip translation context
+ if (prop.GetAttribute ("context") == "yes" &&
+ strval.IndexOf ('|') != -1)
+ strval = strval.Substring (strval.IndexOf ('|') + 1);
+
+ GLib.Value value;
+ try {
+ value = ParseProperty (type, childprops, name, strval);
+ names.Add (name);
+ values.Add (value);
+ } catch (GladeException ge) {
+ Console.Error.WriteLine (ge.Message);
+ }
+ }
+
+ propNames = (string[])names.ToArray (typeof (string));
+ propVals = (GLib.Value[])values.ToArray (typeof (GLib.Value));
+ }
+
+ static void ExtractProperties (TypedClassDescriptor klass, XmlElement elem,
+ out Hashtable rawProps, out Hashtable overrideProps)
+ {
+ rawProps = new Hashtable ();
+ overrideProps = new Hashtable ();
+ foreach (ItemGroup group in klass.ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ TypedPropertyDescriptor prop = item as TypedPropertyDescriptor;
+ if (prop == null)
+ continue;
+ prop = prop.GladeProperty;
+ if (prop.GladeName == null)
+ continue;
+
+ XmlNode prop_node = elem.SelectSingleNode ("property[@name='" + prop.GladeName + "']");
+ if (prop_node == null)
+ continue;
+
+ if (prop.GladeOverride)
+ overrideProps[prop] = prop_node;
+ else
+ rawProps[prop] = prop_node;
+ }
+ }
+ }
+
+ static void ReadSignals (TypedClassDescriptor klass, ObjectWrapper wrapper, XmlElement elem)
+ {
+ Stetic.Wrapper.Widget ob = wrapper as Stetic.Wrapper.Widget;
+ if (ob == null) return;
+
+ foreach (ItemGroup group in klass.SignalGroups) {
+ foreach (TypedSignalDescriptor signal in group) {
+ if (signal.GladeName == null)
+ continue;
+
+ XmlElement signal_elem = elem.SelectSingleNode ("signal[@name='" + signal.GladeName + "']") as XmlElement;
+ if (signal_elem == null)
+ continue;
+
+ string handler = signal_elem.GetAttribute ("handler");
+ bool after = signal_elem.GetAttribute ("after") == "yes";
+ ob.Signals.Add (new Signal (signal, handler, after));
+ }
+ }
+ }
+
+ static public void ImportWidget (ObjectWrapper wrapper, XmlElement elem)
+ {
+ string className = elem.GetAttribute ("class");
+ if (className == null)
+ throw new GladeException ("<widget> node with no class name");
+
+ ClassDescriptor klassBase = Registry.LookupClassByCName (className);
+ if (klassBase == null)
+ throw new GladeException ("No stetic ClassDescriptor for " + className);
+
+ TypedClassDescriptor klass = klassBase as TypedClassDescriptor;
+ if (klass == null)
+ throw new GladeException ("The widget class " + className + " is not supported by Glade");
+
+ ReadSignals (klass, wrapper, elem);
+
+ Hashtable rawProps, overrideProps;
+ ExtractProperties (klass, elem, out rawProps, out overrideProps);
+
+ string[] propNames;
+ GLib.Value[] propVals;
+ ParseProperties (klass.WrappedType, false, rawProps.Values,
+ out propNames, out propVals);
+
+ Gtk.Widget widget;
+
+ if (wrapper.Wrapped == null) {
+ if (className == "GtkWindow" || className == "GtkDialog") {
+ widget = (Gtk.Widget) klass.CreateInstance (wrapper.Project);
+ ObjectWrapper.Bind (wrapper.Project, klass, wrapper, widget, true);
+ SetProperties (klass, widget, propNames, propVals);
+ } else {
+ IntPtr raw = gtksharp_object_newv (klass.GType.Val, propNames.Length, propNames, propVals);
+ if (raw == IntPtr.Zero)
+ throw new GladeException ("Could not create widget", className);
+ widget = (Gtk.Widget)GLib.Object.GetObject (raw, true);
+ if (widget == null) {
+ gtk_object_sink (raw);
+ throw new GladeException ("Could not create gtk# wrapper", className);
+ }
+ ObjectWrapper.Bind (wrapper.Project, klass, wrapper, widget, true);
+ }
+ } else {
+ widget = (Gtk.Widget)wrapper.Wrapped;
+ for (int i = 0; i < propNames.Length; i++)
+ g_object_set_property (widget.Handle, propNames[i], ref propVals[i]);
+ }
+ MarkTranslatables (widget, rawProps);
+
+ widget.Name = elem.GetAttribute ("id");
+
+ SetOverrideProperties (wrapper, overrideProps);
+ MarkTranslatables (widget, overrideProps);
+ }
+
+ static void SetProperties (TypedClassDescriptor klass, Gtk.Widget widget, string[] propNames, GLib.Value[] propVals)
+ {
+ for (int n=0; n<propNames.Length; n++) {
+ foreach (ItemGroup grp in klass.ItemGroups) {
+ foreach (ItemDescriptor it in grp) {
+ if (it is TypedPropertyDescriptor) {
+ TypedPropertyDescriptor prop = (TypedPropertyDescriptor)it;
+ if (prop.GladeName == propNames[n]) {
+ prop.SetValue (widget, propVals[n].Val);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ static void SetOverrideProperties (ObjectWrapper wrapper, Hashtable overrideProps)
+ {
+ foreach (TypedPropertyDescriptor prop in overrideProps.Keys) {
+ XmlElement prop_elem = overrideProps[prop] as XmlElement;
+
+ try {
+ GLib.Value value = ParseProperty (prop.ParamSpec, prop.PropertyType, prop_elem.InnerText);
+ prop.SetValue (wrapper.Wrapped, value.Val);
+ } catch {
+ throw new GladeException ("Could not parse property", wrapper.GetType ().ToString (), wrapper is Stetic.Wrapper.Container.ContainerChild, prop.GladeName, prop_elem.InnerText);
+ }
+ }
+ }
+
+ static void MarkTranslatables (object obj, Hashtable props)
+ {
+ foreach (PropertyDescriptor prop in props.Keys) {
+ if (!prop.Translatable)
+ continue;
+
+ XmlElement prop_elem = props[prop] as XmlElement;
+ if (prop_elem.GetAttribute ("translatable") != "yes") {
+ prop.SetTranslated (obj, false);
+ continue;
+ }
+
+ prop.SetTranslated (obj, true);
+ if (prop_elem.GetAttribute ("context") == "yes") {
+ string strval = prop_elem.InnerText;
+ int bar = strval.IndexOf ('|');
+ if (bar != -1)
+ prop.SetTranslationContext (obj, strval.Substring (0, bar));
+ }
+
+ if (prop_elem.HasAttribute ("comments"))
+ prop.SetTranslationComment (obj, prop_elem.GetAttribute ("comments"));
+ }
+ }
+
+ static public void SetPacking (Stetic.Wrapper.Container.ContainerChild wrapper, XmlElement child_elem)
+ {
+ XmlElement packing = child_elem["packing"];
+ if (packing == null)
+ return;
+
+ Gtk.Container.ContainerChild cc = wrapper.Wrapped as Gtk.Container.ContainerChild;
+
+ TypedClassDescriptor klass = wrapper.ClassDescriptor as TypedClassDescriptor;
+ if (klass == null)
+ throw new GladeException ("The widget class " + cc.GetType () + " is not supported by Glade");
+
+ Hashtable rawProps, overrideProps;
+ ExtractProperties (klass, packing, out rawProps, out overrideProps);
+
+ string[] propNames;
+ GLib.Value[] propVals;
+ ParseProperties (cc.Parent.GetType (), true, rawProps.Values,
+ out propNames, out propVals);
+
+ for (int i = 0; i < propNames.Length; i++)
+ cc.Parent.ChildSetProperty (cc.Child, propNames[i], propVals[i]);
+ MarkTranslatables (cc, rawProps);
+
+ SetOverrideProperties (wrapper, overrideProps);
+ MarkTranslatables (cc, overrideProps);
+ }
+
+ internal static XmlElement CreatePacking (XmlDocument doc, Stetic.Wrapper.Container.ContainerChild childwrapper)
+ {
+ XmlElement packing_elem = doc.CreateElement ("packing");
+ GetProps (childwrapper, packing_elem);
+ return packing_elem;
+ }
+
+ static string PropToString (ObjectWrapper wrapper, TypedPropertyDescriptor prop)
+ {
+ object value;
+
+ if (!prop.GladeOverride) {
+ Stetic.Wrapper.Container.ContainerChild ccwrap = wrapper as Stetic.Wrapper.Container.ContainerChild;
+ GLib.Value gval;
+
+ if (ccwrap != null) {
+ Gtk.Container.ContainerChild cc = (Gtk.Container.ContainerChild)ccwrap.Wrapped;
+ gval = new GLib.Value ((GLib.GType) prop.PropertyType);
+ gtk_container_child_get_property (cc.Parent.Handle, cc.Child.Handle, prop.GladeName, ref gval);
+ } else {
+ Gtk.Widget widget = wrapper.Wrapped as Gtk.Widget;
+ gval = new GLib.Value (widget, prop.GladeName);
+ g_object_get_property (widget.Handle, prop.GladeName, ref gval);
+ }
+ value = gval.Val;
+ } else
+ value = prop.GetValue (wrapper.Wrapped);
+ if (value == null)
+ return null;
+
+ // If the property has its default value, we don't need to write it
+ if (prop.HasDefault && prop.ParamSpec.IsDefaultValue (value))
+ return null;
+
+ if (value is Gtk.Adjustment) {
+ Gtk.Adjustment adj = value as Gtk.Adjustment;
+ return String.Format ("{0:G} {1:G} {2:G} {3:G} {4:G} {5:G}",
+ adj.Value, adj.Lower, adj.Upper,
+ adj.StepIncrement, adj.PageIncrement,
+ adj.PageSize);
+ } else if (value is Enum && prop.ParamSpec != null) {
+ IntPtr klass = g_type_class_ref (((GLib.GType)prop.PropertyType).Val);
+
+ if (prop.PropertyType.IsDefined (typeof (FlagsAttribute), false)) {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder ();
+ uint val = (uint)System.Convert.ChangeType (value, typeof (uint));
+
+ while (val != 0) {
+ IntPtr flags_value = g_flags_get_first_value (klass, val);
+ if (flags_value == IntPtr.Zero)
+ break;
+ IntPtr fval = Marshal.ReadIntPtr (flags_value);
+ val &= ~(uint)fval;
+
+ IntPtr name = Marshal.ReadIntPtr (flags_value, Marshal.SizeOf (typeof (IntPtr)));
+ if (name != IntPtr.Zero) {
+ if (sb.Length != 0)
+ sb.Append ('|');
+ sb.Append (GLib.Marshaller.Utf8PtrToString (name));
+ }
+ }
+
+ g_type_class_unref (klass);
+ return sb.ToString ();
+ } else {
+ int val = (int)System.Convert.ChangeType (value, typeof (int));
+ IntPtr enum_value = g_enum_get_value (klass, val);
+ g_type_class_unref (klass);
+
+ IntPtr name = Marshal.ReadIntPtr (enum_value, Marshal.SizeOf (typeof (IntPtr)));
+ return GLib.Marshaller.Utf8PtrToString (name);
+ }
+ } else if (value is bool)
+ return (bool)value ? "True" : "False";
+ else
+ return value.ToString ();
+ }
+
+ static public XmlElement ExportWidget (ObjectWrapper wrapper, XmlDocument doc)
+ {
+ XmlElement elem = doc.CreateElement ("widget");
+ elem.SetAttribute ("class", wrapper.ClassDescriptor.CName);
+ elem.SetAttribute ("id", ((Gtk.Widget)wrapper.Wrapped).Name);
+
+ GetProps (wrapper, elem);
+ GetSignals (wrapper, elem);
+ return elem;
+ }
+
+ static public void GetProps (ObjectWrapper wrapper, XmlElement parent_elem)
+ {
+ ClassDescriptor klass = wrapper.ClassDescriptor;
+
+ foreach (ItemGroup group in klass.ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ TypedPropertyDescriptor prop = item as TypedPropertyDescriptor;
+ if (prop == null)
+ continue;
+ prop = prop.GladeProperty;
+ if (prop.GladeName == null)
+ continue;
+ if (!prop.VisibleFor (wrapper.Wrapped))
+ continue;
+
+ string val = PropToString (wrapper, prop);
+ if (val == null)
+ continue;
+
+ XmlElement prop_elem = parent_elem.OwnerDocument.CreateElement ("property");
+ prop_elem.SetAttribute ("name", prop.GladeName);
+ if (val.Length > 0)
+ prop_elem.InnerText = val;
+
+ if (prop.Translatable && prop.IsTranslated (wrapper.Wrapped)) {
+ prop_elem.SetAttribute ("translatable", "yes");
+ if (prop.TranslationContext (wrapper.Wrapped) != null) {
+ prop_elem.SetAttribute ("context", "yes");
+ prop_elem.InnerText = prop.TranslationContext (wrapper.Wrapped) + "|" + prop_elem.InnerText;
+ }
+ if (prop.TranslationComment (wrapper.Wrapped) != null)
+ prop_elem.SetAttribute ("comments", prop.TranslationComment (wrapper.Wrapped));
+ }
+
+ parent_elem.AppendChild (prop_elem);
+ }
+ }
+ }
+
+ static public void GetSignals (ObjectWrapper wrapper, XmlElement parent_elem)
+ {
+ Stetic.Wrapper.Widget ob = wrapper as Stetic.Wrapper.Widget;
+ if (ob == null) return;
+
+ foreach (Signal signal in ob.Signals) {
+ if (((TypedSignalDescriptor)signal.SignalDescriptor).GladeName == null)
+ continue;
+ if (!signal.SignalDescriptor.VisibleFor (wrapper.Wrapped))
+ continue;
+
+ XmlElement signal_elem = parent_elem.OwnerDocument.CreateElement ("signal");
+ signal_elem.SetAttribute ("name", ((TypedSignalDescriptor)signal.SignalDescriptor).GladeName);
+ signal_elem.SetAttribute ("handler", signal.Handler);
+ if (signal.After)
+ signal_elem.SetAttribute ("after", "yes");
+ parent_elem.AppendChild (signal_elem);
+ }
+ }
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_type_fundamental (IntPtr gtype);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_type_class_ref (IntPtr gtype);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_type_class_unref (IntPtr klass);
+
+ [DllImport("glibsharpglue-2")]
+ static extern IntPtr gtksharp_object_newv (IntPtr gtype, int n_params, string[] names, GLib.Value[] vals);
+
+ [DllImport("libgtk-win32-2.0-0.dll")]
+ static extern void gtk_object_sink (IntPtr raw);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern void g_object_get_property (IntPtr obj, string name, ref GLib.Value val);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern void g_object_set_property (IntPtr obj, string name, ref GLib.Value val);
+
+ [DllImport("libgtk-win32-2.0-0.dll")]
+ static extern void gtk_container_child_get_property (IntPtr parent, IntPtr child, string name, ref GLib.Value val);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_enum_get_value_by_name (IntPtr enum_class, string name);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_enum_get_value (IntPtr enum_class, int val);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_flags_get_value_by_name (IntPtr flags_class, string nick);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_flags_get_first_value (IntPtr flags_class, uint val);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/IDesignArea.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IDesignArea.cs
new file mode 100644
index 0000000000..7fb86f1beb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IDesignArea.cs
@@ -0,0 +1,39 @@
+
+using System;
+
+namespace Stetic
+{
+ public interface IDesignArea
+ {
+ IObjectSelection SetSelection (Gtk.Widget widget, object selectedInstance);
+ IObjectSelection SetSelection (Gtk.Widget widget, object selectedInstance, bool allowDrag);
+ void ResetSelection (Gtk.Widget widget);
+ bool IsSelected (Gtk.Widget widget);
+ IObjectSelection GetSelection ();
+ IObjectSelection GetSelection (Gtk.Widget widget);
+
+ void AddWidget (Gtk.Widget w, int x, int y);
+ void RemoveWidget (Gtk.Widget w);
+ void MoveWidget (Gtk.Widget w, int x, int y);
+ Gdk.Rectangle GetCoordinates (Gtk.Widget w);
+
+ event EventHandler SelectionChanged;
+ }
+
+ public delegate void DragDelegate (Gdk.EventMotion evt, int dx, int dy);
+
+ public interface IObjectViewer
+ {
+ object TargetObject { get; set; }
+ }
+
+ public interface IObjectSelection: IDisposable
+ {
+ Gtk.Widget Widget { get; }
+ object DataObject { get; }
+ bool AllowDrag {get; set; }
+
+ event DragDelegate Drag;
+ event EventHandler Disposed;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/IEditableObject.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IEditableObject.cs
new file mode 100644
index 0000000000..dd2e54c5df
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IEditableObject.cs
@@ -0,0 +1,18 @@
+
+using System;
+
+namespace Stetic
+{
+ public interface IEditableObject
+ {
+ bool CanCopy { get; }
+ bool CanCut { get; }
+ bool CanPaste { get; }
+ bool CanDelete { get; }
+
+ void Copy ();
+ void Cut ();
+ void Paste ();
+ void Delete ();
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/IProject.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IProject.cs
new file mode 100644
index 0000000000..03e1c4c477
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IProject.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Stetic
+{
+ public interface IProject
+ {
+ //string FileName { get; }
+ string FolderName { get; }
+ Gtk.Widget[] Toplevels { get; }
+ Gtk.Widget GetWidget (string name);
+ Gtk.Widget Selection { get; set; }
+ Wrapper.ActionGroupCollection ActionGroups { get; }
+ ProjectIconFactory IconFactory { get; }
+ string ImagesRootPath { get; }
+ string TargetGtkVersion { get; }
+// bool Modified { get; set; }
+ IResourceProvider ResourceProvider { get; set; }
+
+ void PopupContextMenu (Stetic.Wrapper.Widget wrapper);
+ void PopupContextMenu (Placeholder ph);
+ void AddWindow (Gtk.Window window);
+ string ImportFile (string filePath);
+
+ event Wrapper.WidgetEventHandler SelectionChanged;
+
+ void NotifyObjectChanged (ObjectWrapperEventArgs args);
+ void NotifyNameChanged (Stetic.Wrapper.WidgetNameChangedArgs args);
+ void NotifySignalAdded (SignalEventArgs args);
+ void NotifySignalRemoved (SignalEventArgs args);
+ void NotifySignalChanged (SignalChangedEventArgs args);
+ void NotifyWidgetContentsChanged (Wrapper.Widget w);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/IPropertyEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IPropertyEditor.cs
new file mode 100644
index 0000000000..f0cb14a48b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IPropertyEditor.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace Stetic
+{
+ // Property editors must be Gtk Widgets and implement this interface
+
+ public interface IPropertyEditor: IDisposable
+ {
+ // Called once to initialize the editor.
+ void Initialize (PropertyDescriptor descriptor);
+
+ // Called when the object to be edited changes.
+ void AttachObject (object obj);
+
+ // Gets/Sets the value of the editor. If the editor supports
+ // several value types, it is the responsibility of the editor
+ // to return values with the expected type.
+ object Value { get; set; }
+
+ // To be fired when the edited value changes.
+ event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/IRadioGroupManager.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IRadioGroupManager.cs
new file mode 100644
index 0000000000..fe0cdec704
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IRadioGroupManager.cs
@@ -0,0 +1,21 @@
+
+using System;
+using System.Collections;
+
+namespace Stetic
+{
+ public delegate void GroupsChangedDelegate ();
+
+ public interface IRadioGroupManagerProvider
+ {
+ IRadioGroupManager GetGroupManager ();
+ }
+
+ public interface IRadioGroupManager
+ {
+ event GroupsChangedDelegate GroupsChanged;
+ IEnumerable GroupNames { get; }
+ void Rename (string oldName, string newName);
+ void Add (string group);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/IResourceProvider.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IResourceProvider.cs
new file mode 100644
index 0000000000..3394cf77a6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/IResourceProvider.cs
@@ -0,0 +1,72 @@
+
+using System;
+using System.IO;
+
+namespace Stetic
+{
+ public interface IResourceProvider
+ {
+ ResourceInfo[] GetResources ();
+ Stream GetResourceStream (string resourceName);
+ ResourceInfo AddResource (string fileName);
+ void RemoveResource (string resourceName);
+ }
+
+ public delegate string MimeResolverDelegate (string url);
+
+ [Serializable]
+ public class ResourceInfo
+ {
+ public static MimeResolverDelegate MimeResolver;
+
+ string name;
+ string fileName;
+ string mimeType;
+
+ public ResourceInfo (string name, string fileName): this (name, fileName, null)
+ {
+ }
+
+ public ResourceInfo (string name, string fileName, string mimeType)
+ {
+ this.name = name;
+ this.fileName = fileName;
+ this.mimeType = mimeType;
+ }
+
+ public string Name {
+ get { return name; }
+ }
+
+ public string FileName {
+ get { return fileName; }
+ }
+
+ public string MimeType {
+ get {
+ if (mimeType == null) {
+ if (MimeResolver == null)
+ return null;
+
+ if (File.Exists (fileName)) {
+ mimeType = MimeResolver (fileName);
+ } else {
+ // Guess the mime type creating a temp file with the same extension
+ string fn = Path.GetTempFileName ();
+ string ext = Path.GetExtension (fileName);
+ int n=0;
+ while (File.Exists (fn + n + ext))
+ n++;
+ string tname = fn + n + ext;
+ File.Move (fn, tname);
+ mimeType = MimeResolver (tname);
+ File.Delete (tname);
+ }
+ if (mimeType == null || mimeType == "")
+ mimeType = "text";
+ }
+ return mimeType;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ImageInfo.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ImageInfo.cs
new file mode 100644
index 0000000000..d21e46c0f5
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ImageInfo.cs
@@ -0,0 +1,215 @@
+
+using System;
+using System.IO;
+using System.CodeDom;
+
+namespace Stetic
+{
+ public enum ImageSource
+ {
+ Theme,
+ Resource,
+ File
+ }
+
+ public class ImageInfo
+ {
+ ImageSource source;
+ string name;
+ Gtk.IconSize size;
+ Gdk.Pixbuf image;
+
+ private ImageInfo ()
+ {
+ }
+
+ public string Label {
+ get {
+ if (source == ImageSource.File)
+ return Path.GetFileName (name);
+ else
+ return name;
+ }
+ }
+
+ public string Name {
+ get { return name; }
+ }
+
+ public Gtk.IconSize ThemeIconSize {
+ get { return size; }
+ }
+
+ public ImageSource Source {
+ get { return source; }
+ }
+
+ public override string ToString ()
+ {
+ if (source == ImageSource.Theme)
+ return "stock:" + name + " " + size;
+ else if (source == ImageSource.Resource)
+ return "resource:" + name;
+ else
+ return "file:" + name;
+ }
+
+ public static ImageInfo FromResource (string resourceName)
+ {
+ ImageInfo info = new ImageInfo ();
+ info.name = resourceName;
+ info.source = ImageSource.Resource;
+ return info;
+ }
+
+ public static ImageInfo FromTheme (string iconId, Gtk.IconSize size)
+ {
+ ImageInfo info = new ImageInfo ();
+ info.name = iconId;
+ info.size = size;
+ info.source = ImageSource.Theme;
+ return info;
+ }
+
+ public static ImageInfo FromFile (string file)
+ {
+ ImageInfo info = new ImageInfo ();
+ info.name = file;
+ info.source = ImageSource.File;
+ return info;
+ }
+
+ public static ImageInfo FromString (string str)
+ {
+ ImageInfo info = new ImageInfo ();
+ if (str.StartsWith ("resource:")) {
+ info.source = ImageSource.Resource;
+ info.name = str.Substring (9);
+ } else if (str.StartsWith ("stock:")) {
+ info.source = ImageSource.Theme;
+ string[] s = str.Substring (6).Split (' ');
+ if (s.Length != 2)
+ return null;
+ info.name = s[0];
+ info.size = (Gtk.IconSize) Enum.Parse (typeof(Gtk.IconSize), s[1]);
+ } else if (str.StartsWith ("file:")) {
+ info.source = ImageSource.File;
+ info.name = str.Substring (5);
+ } else
+ return null;
+ return info;
+ }
+
+ public Gdk.Pixbuf GetImage (IProject project)
+ {
+ if (image != null)
+ return image;
+
+ switch (source) {
+ case ImageSource.Resource:
+ if (project.ResourceProvider == null)
+ return null;
+ System.IO.Stream s = project.ResourceProvider.GetResourceStream (name);
+ if (s == null)
+ return null;
+ try {
+ return image = new Gdk.Pixbuf (s);
+ } catch {
+ // Not a valid image
+ return WidgetUtils.MissingIcon;
+ }
+
+ case ImageSource.Theme:
+ return image = WidgetUtils.LoadIcon (name, size);
+
+ case ImageSource.File:
+ try {
+ string file = Path.Combine (project.ImagesRootPath, name);
+ return image = new Gdk.Pixbuf (file);
+ } catch {
+ return WidgetUtils.MissingIcon;
+ }
+ }
+ return null;
+ }
+
+ public Gdk.Pixbuf GetThumbnail (IProject project, int thumbnailSize)
+ {
+ Gdk.Pixbuf pix = GetImage (project);
+ if (pix == null)
+ return null;
+
+ if (pix.Width >= pix.Height && pix.Width > thumbnailSize) {
+ return ScaleImage (pix, thumbnailSize, thumbnailSize);
+ } else if (pix.Height > pix.Width && pix.Height > thumbnailSize) {
+ return ScaleImage (pix, thumbnailSize, thumbnailSize);
+ }
+ return pix;
+ }
+
+ public Gdk.Pixbuf GetScaledImage (IProject project, Gtk.IconSize size)
+ {
+ int w, h;
+ Gtk.Icon.SizeLookup (size, out w, out h);
+ return GetScaledImage (project, w, h);
+ }
+
+ public Gdk.Pixbuf GetScaledImage (IProject project, int width, int height)
+ {
+ Gdk.Pixbuf pix = GetImage (project);
+ if (pix == null)
+ return null;
+ else
+ return ScaleImage (pix, width, height);
+ }
+
+ Gdk.Pixbuf ScaleImage (Gdk.Pixbuf pix, int width, int height)
+ {
+ if ((pix.Width - width) > (pix.Height - height)) {
+ if (pix.Width != width) {
+ float prop = (float) pix.Height / (float) pix.Width;
+ return pix.ScaleSimple (width, (int)(width * prop), Gdk.InterpType.Bilinear);
+ }
+ } else {
+ if (pix.Height != height) {
+ float prop = (float) pix.Width / (float) pix.Height;
+ return pix.ScaleSimple ((int)(height * prop), height, Gdk.InterpType.Bilinear);
+ }
+ }
+ return pix;
+ }
+
+ public CodeExpression ToCodeExpression (GeneratorContext ctx)
+ {
+ switch (source) {
+ case ImageSource.Resource:
+ return new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(Gdk.Pixbuf), CodeTypeReferenceOptions.GlobalReference)),
+ "LoadFromResource",
+ new CodePrimitiveExpression (name)
+ );
+
+ case ImageSource.Theme:
+ return ctx.GenerateLoadPixbuf (name, size);
+
+ case ImageSource.File:
+ return new CodeObjectCreateExpression (
+ typeof(Gdk.Pixbuf).ToGlobalTypeRef (),
+ new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(System.IO.Path), CodeTypeReferenceOptions.GlobalReference)),
+ "Combine",
+ new CodePropertyReferenceExpression (
+ new CodePropertyReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(AppDomain), CodeTypeReferenceOptions.GlobalReference)),
+ "CurrentDomain"
+ ),
+ "BaseDirectory"
+ ),
+ new CodePrimitiveExpression (name)
+ )
+ );
+ }
+ return new CodePrimitiveExpression (null);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemDescriptor.cs
new file mode 100644
index 0000000000..a64644eb06
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemDescriptor.cs
@@ -0,0 +1,158 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.Reflection;
+
+namespace Stetic
+{
+ [Serializable]
+ public abstract class ItemDescriptor
+ {
+ [NonSerialized]
+ ArrayList deps;
+
+ [NonSerialized]
+ ArrayList visdeps;
+
+ [NonSerialized]
+ bool isInternal;
+
+ [NonSerialized]
+ ClassDescriptor klass;
+
+ protected string targetGtkVersion;
+
+ protected ItemDescriptor () {}
+
+ protected ItemDescriptor (XmlElement elem, ItemGroup group, ClassDescriptor klass)
+ {
+ this.klass = klass;
+ isInternal = elem.HasAttribute ("internal");
+ deps = AddSubprops (elem.SelectNodes ("./disabled-if"), group, klass);
+ visdeps = AddSubprops (elem.SelectNodes ("./invisible-if"), group, klass);
+ targetGtkVersion = elem.GetAttribute ("gtk-version");
+ if (targetGtkVersion.Length == 0)
+ targetGtkVersion = null;
+ }
+
+ ArrayList AddSubprops (XmlNodeList nodes, ItemGroup group, ClassDescriptor klass)
+ {
+ ArrayList list = null;
+
+ // Sub-properties can have a name+value (which checks for the value of a
+ // property) or a method name, which should return true if the item has
+ // to be disabled/hidden.
+
+ foreach (XmlElement elem in nodes) {
+ string name = elem.GetAttribute ("name");
+ if (name.Length > 0) {
+ string value = elem.GetAttribute ("value");
+
+ PropertyDescriptor prop = (PropertyDescriptor)group[name];
+ if (prop == null)
+ prop = (PropertyDescriptor)klass[name];
+ if (prop == null)
+ throw new ArgumentException ("Bad sub-prop " + name);
+ if (list == null)
+ list = new ArrayList ();
+
+ DepInfo info = new DepInfo ();
+ info.Property = prop;
+ info.Value = prop.StringToValue (value);
+ list.Add (info);
+ } else if ((name = elem.GetAttribute ("check")).Length > 0) {
+ DepInfo info = new DepInfo ();
+ info.CheckName = name;
+ if (list == null)
+ list = new ArrayList ();
+ list.Add (info);
+ } else {
+ throw new ArgumentException ("Bad sub-prop");
+ }
+ }
+ return list;
+ }
+
+ // The property's display name
+ public abstract string Name { get; }
+
+ public virtual string TargetGtkVersion {
+ get {
+ if (targetGtkVersion == null)
+ return klass.TargetGtkVersion;
+ else
+ return targetGtkVersion;
+ }
+ }
+
+ public bool SupportsGtkVersion (string targetVersion)
+ {
+ return WidgetUtils.CompareVersions (TargetGtkVersion, targetVersion) >= 0;
+ }
+
+ public bool HasDependencies {
+ get {
+ return deps != null || visdeps != null;
+ }
+ }
+
+ public bool EnabledFor (object obj)
+ {
+ if (deps == null)
+ return true;
+
+ foreach (DepInfo dep in deps) {
+ if (dep.Check (obj))
+ return false;
+ }
+ return true;
+ }
+
+ public bool HasVisibility {
+ get {
+ return visdeps != null;
+ }
+ }
+
+ public bool VisibleFor (object obj)
+ {
+ if (visdeps == null)
+ return true;
+
+ foreach (DepInfo dep in visdeps) {
+ if (dep.Check (obj))
+ return false;
+ }
+ return true;
+ }
+
+ public bool IsInternal {
+ get {
+ return isInternal;
+ }
+ }
+
+ public ClassDescriptor ClassDescriptor {
+ get { return klass; }
+ }
+
+ class DepInfo
+ {
+ public string CheckName;
+ public PropertyDescriptor Property;
+ public object Value;
+
+ public bool Check (object obj)
+ {
+ if (Property != null) {
+ object depValue = Property.GetValue (obj);
+ return Value.Equals (depValue);
+ } else {
+ object wrapper = ObjectWrapper.Lookup (obj);
+ object res = wrapper.GetType ().InvokeMember (CheckName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, wrapper, null);
+ return !(bool) res;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroup.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroup.cs
new file mode 100644
index 0000000000..f66a9d5603
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroup.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Xml;
+
+namespace Stetic {
+ public class ItemGroup : IEnumerable
+ {
+ public static ItemGroup Empty;
+
+ string label, name;
+ ListDictionary items = new ListDictionary ();
+ ClassDescriptor declaringType;
+
+ static ItemGroup ()
+ {
+ Empty = new ItemGroup ();
+ }
+
+ private ItemGroup ()
+ {
+ }
+
+ public ItemGroup (XmlElement elem, ClassDescriptor klass)
+ {
+ declaringType = klass;
+ label = elem.GetAttribute ("label");
+ name = elem.GetAttribute ("name");
+
+ XmlNodeList nodes = elem.SelectNodes ("property | command | signal");
+ for (int i = 0; i < nodes.Count; i++) {
+ XmlElement item = (XmlElement)nodes[i];
+ string refname = item.GetAttribute ("ref");
+ if (refname != "") {
+ if (refname.IndexOf ('.') != -1) {
+ ItemDescriptor desc = (ItemDescriptor) Registry.LookupItem (refname);
+ items.Add (desc.Name, desc);
+ } else {
+ ItemDescriptor desc = (ItemDescriptor) klass[refname];
+ items.Add (desc.Name, desc);
+ }
+ continue;
+ }
+
+ ItemDescriptor idesc = klass.CreateItemDescriptor ((XmlElement)item, this);
+ if (idesc != null)
+ items.Add (idesc.Name, idesc);
+ }
+ }
+
+ public string Label {
+ get {
+ return label;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return items.Values.GetEnumerator ();
+ }
+
+ public ItemDescriptor this [string name] {
+ get {
+ return (ItemDescriptor) items [name];
+ }
+ }
+
+ public ClassDescriptor DeclaringType {
+ get { return declaringType; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroupCollection.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroupCollection.cs
new file mode 100644
index 0000000000..9fb9296315
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ItemGroupCollection.cs
@@ -0,0 +1,42 @@
+
+using System;
+using System.Collections;
+
+namespace Stetic
+{
+ public class ItemGroupCollection: CollectionBase
+ {
+ public void Add (ItemGroup group)
+ {
+ List.Add (group);
+ }
+
+ public ItemGroup this [int n]
+ {
+ get {
+ return (ItemGroup) List [n];
+ }
+ }
+
+ public ItemGroup this [string name]
+ {
+ get {
+ for (int n=0; n<List.Count; n++) {
+ if (((ItemGroup) List [n]).Name == name)
+ return (ItemGroup) List [n];
+ }
+ return null;
+ }
+ }
+
+ public ItemDescriptor GetItem (string name)
+ {
+ for (int n=0; n<List.Count; n++) {
+ ItemDescriptor item = ((ItemGroup) List [n])[name];
+ if (item != null)
+ return item;
+ }
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/Makefile.am b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Makefile.am
new file mode 100644
index 0000000000..c90eb8c78b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Makefile.am
@@ -0,0 +1,269 @@
+ADDIN_BUILD = $(top_builddir)/build/AddIns/MonoDevelop.GtkCore
+ASSEMBLY = $(ADDIN_BUILD)/libstetic.dll
+assemblydir = $(MD_ADDIN_DIR)/MonoDevelop.GtkCore
+assembly_DATA = $(ASSEMBLY) $(ASSEMBLY).mdb $(build_dll_config)
+
+FILES = \
+ ClassDescriptor.cs \
+ Clipboard.cs \
+ CommandDescriptor.cs \
+ CustomWidget.cs \
+ DND.cs \
+ editor/Accelerator.cs \
+ editor/ActionGroupEditor.cs \
+ editor/ActionItem.cs \
+ editor/ActionMenu.cs \
+ editor/ActionMenuBar.cs \
+ editor/ActionMenuItem.cs \
+ editor/ActionToolbar.cs \
+ editor/ActionToolItem.cs \
+ editor/Boolean.cs \
+ editor/CellRendererComboBox.cs \
+ editor/Char.cs \
+ editor/Color.cs \
+ editor/DateTimeEditor.cs \
+ editor/EditIconDialog.cs \
+ editor/EditIconFactoryDialog.cs \
+ editor/Enumeration.cs \
+ editor/Flags.cs \
+ editor/FlagsSelectorDialog.cs \
+ editor/FloatRange.cs \
+ editor/GroupPicker.cs \
+ editor/IconList.cs \
+ editor/IconSelectorItem.cs \
+ editor/IconSelectorMenu.cs \
+ editor/IconSelectorMenuItem.cs \
+ editor/Identifier.cs \
+ editor/Image.cs \
+ editor/ImageFile.cs \
+ editor/ImageSelector.cs \
+ editor/IntRange.cs \
+ editor/NonContainerWarningDialog.cs \
+ editor/OptIntRange.cs \
+ editor/ProjectIconList.cs \
+ editor/ProjectIconSelectorItem.cs \
+ editor/ResponseId.cs \
+ editor/SelectIconDialog.cs \
+ editor/SelectImageDialog.cs \
+ editor/StockIconList.cs \
+ editor/StockIconSelectorItem.cs \
+ editor/StockItem.cs \
+ editor/String.cs \
+ editor/StringArray.cs \
+ editor/Text.cs \
+ editor/TextBox.cs \
+ editor/TextEditor.cs \
+ editor/TextEditorDialog.cs \
+ editor/ThemedIcon.cs \
+ editor/ThemedIconList.cs \
+ editor/TimeSpanEditor.cs \
+ editor/Translatable.cs \
+ editor/TreeViewCellContainer.cs \
+ editor/WidgetSelector.cs \
+ EnumDescriptor.cs \
+ ErrorWidget.cs \
+ GeneratorContext.cs \
+ GladeException.cs \
+ GladeUtils.cs \
+ IDesignArea.cs \
+ IEditableObject.cs \
+ ImageInfo.cs \
+ IProject.cs \
+ IPropertyEditor.cs \
+ IRadioGroupManager.cs \
+ IResourceProvider.cs \
+ ItemDescriptor.cs \
+ ItemGroup.cs \
+ ItemGroupCollection.cs \
+ NoGuiDispatchAttribute.cs \
+ ObjectReader.cs \
+ ObjectWrapper.cs \
+ ObjectWrapperEventHandler.cs \
+ ObjectWriter.cs \
+ ParamSpec.cs \
+ Placeholder.cs \
+ ProjectIconFactory.cs \
+ PropertyDescriptor.cs \
+ PropertyEditorAttribute.cs \
+ PropertyEditorCell.cs \
+ RadioGroupManager.cs \
+ Registry.cs \
+ Set.cs \
+ SignalDescriptor.cs \
+ TopLevelDialog.cs \
+ TopLevelWindow.cs \
+ TranslatableAttribute.cs \
+ TypedClassDescriptor.cs \
+ TypedPropertyDescriptor.cs \
+ TypedSignalDescriptor.cs \
+ undo/ActionDiffAdaptor.cs \
+ undo/DiffGenerator.cs \
+ undo/IDiffAdaptor.cs \
+ undo/UndoManager.cs \
+ undo/XmlDiffAdaptor.cs \
+ WidgetLibrary.cs \
+ WidgetUtils.cs \
+ wrapper/Action.cs \
+ wrapper/ActionGroup.cs \
+ wrapper/ActionToolbarWrapper.cs \
+ wrapper/ActionTree.cs \
+ wrapper/Bin.cs \
+ wrapper/Box.cs \
+ wrapper/Button.cs \
+ wrapper/ButtonBox.cs \
+ wrapper/CheckButton.cs \
+ wrapper/ColorButton.cs \
+ wrapper/ComboBox.cs \
+ wrapper/ComboBoxEntry.cs \
+ wrapper/Container.cs \
+ wrapper/Custom.cs \
+ wrapper/Dialog.cs \
+ wrapper/Entry.cs \
+ wrapper/Expander.cs \
+ wrapper/Fixed.cs \
+ wrapper/FontButton.cs \
+ wrapper/FontSelectionDialog.cs \
+ wrapper/Frame.cs \
+ wrapper/HScale.cs \
+ wrapper/HScrollbar.cs \
+ wrapper/IconView.cs \
+ wrapper/Image.cs \
+ wrapper/ImageMenuItem.cs \
+ wrapper/Label.cs \
+ wrapper/MenuBar.cs \
+ wrapper/MenuItem.cs \
+ wrapper/MessageDialog.cs \
+ wrapper/Misc.cs \
+ wrapper/Notebook.cs \
+ wrapper/Object.cs \
+ wrapper/OptionMenu.cs \
+ wrapper/Paned.cs \
+ wrapper/RadioActionGroupManager.cs \
+ wrapper/RadioButton.cs \
+ wrapper/RadioMenuItem.cs \
+ wrapper/RadioToolButton.cs \
+ wrapper/Range.cs \
+ wrapper/Scale.cs \
+ wrapper/ScrolledWindow.cs \
+ wrapper/Signal.cs \
+ wrapper/SignalChangedEventHandler.cs \
+ wrapper/SignalCollection.cs \
+ wrapper/SignalEventHandler.cs \
+ wrapper/SpinButton.cs \
+ wrapper/Table.cs \
+ wrapper/TextView.cs \
+ wrapper/ToggleToolButton.cs \
+ wrapper/Toolbar.cs \
+ wrapper/ToolButton.cs \
+ wrapper/TreeView.cs \
+ wrapper/Viewport.cs \
+ wrapper/VScale.cs \
+ wrapper/VScrollbar.cs \
+ wrapper/Widget.cs \
+ wrapper/WidgetEventHandler.cs \
+ wrapper/WidgetNameChangedHandler.cs \
+ wrapper/Window.cs
+
+RES = \
+ stetic.glade \
+ wrapper/objects.xml \
+ wrapper/pixmaps/accellabel.png \
+ wrapper/pixmaps/actiongroup.png \
+ wrapper/pixmaps/add-check-label.png \
+ wrapper/pixmaps/add-menu.png \
+ wrapper/pixmaps/alignment.png \
+ wrapper/pixmaps/arrow.png \
+ wrapper/pixmaps/box-expand.png \
+ wrapper/pixmaps/box-fill.png \
+ wrapper/pixmaps/button.png \
+ wrapper/pixmaps/calendar.png \
+ wrapper/pixmaps/cell-expand-h.png \
+ wrapper/pixmaps/cell-expand-v.png \
+ wrapper/pixmaps/cell-fill-h.png \
+ wrapper/pixmaps/cell-fill-v.png \
+ wrapper/pixmaps/checkbutton.png \
+ wrapper/pixmaps/colorbutton.png \
+ wrapper/pixmaps/colorselection.png \
+ wrapper/pixmaps/colorselectiondialog.png \
+ wrapper/pixmaps/combo.png \
+ wrapper/pixmaps/comboentry.png \
+ wrapper/pixmaps/custom.png \
+ wrapper/pixmaps/dec-border.png \
+ wrapper/pixmaps/dialog.png \
+ wrapper/pixmaps/drawingarea.png \
+ wrapper/pixmaps/entry.png \
+ wrapper/pixmaps/eventbox.png \
+ wrapper/pixmaps/expander.png \
+ wrapper/pixmaps/fileselection.png \
+ wrapper/pixmaps/fixed.png \
+ wrapper/pixmaps/fontbutton.png \
+ wrapper/pixmaps/fontselection.png \
+ wrapper/pixmaps/fontselectiondialog.png \
+ wrapper/pixmaps/frame.png \
+ wrapper/pixmaps/globe.png \
+ wrapper/pixmaps/globe-not.png \
+ wrapper/pixmaps/handlebox.png \
+ wrapper/pixmaps/hbox.png \
+ wrapper/pixmaps/hbuttonbox.png \
+ wrapper/pixmaps/hpaned.png \
+ wrapper/pixmaps/hscale.png \
+ wrapper/pixmaps/hscrollbar.png \
+ wrapper/pixmaps/hseparator.png \
+ wrapper/pixmaps/iconview.png \
+ wrapper/pixmaps/image.png \
+ wrapper/pixmaps/inc-border.png \
+ wrapper/pixmaps/label.png \
+ wrapper/pixmaps/menu.png \
+ wrapper/pixmaps/menubar.png \
+ wrapper/pixmaps/messagedialog.png \
+ wrapper/pixmaps/missing.png \
+ wrapper/pixmaps/notebook.png \
+ wrapper/pixmaps/optionmenu.png \
+ wrapper/pixmaps/progressbar.png \
+ wrapper/pixmaps/radiobutton.png \
+ wrapper/pixmaps/remove-check-label.png \
+ wrapper/pixmaps/remove-menu.png \
+ wrapper/pixmaps/scrolledwindow.png \
+ wrapper/pixmaps/spinbutton.png \
+ wrapper/pixmaps/statusbar.png \
+ wrapper/pixmaps/table.png \
+ wrapper/pixmaps/textview.png \
+ wrapper/pixmaps/togglebutton.png \
+ wrapper/pixmaps/toolbar.png \
+ wrapper/pixmaps/treeview.png \
+ wrapper/pixmaps/vbox.png \
+ wrapper/pixmaps/vbuttonbox.png \
+ wrapper/pixmaps/viewport.png \
+ wrapper/pixmaps/vpaned.png \
+ wrapper/pixmaps/vscale.png \
+ wrapper/pixmaps/vscrollbar.png \
+ wrapper/pixmaps/vseparator.png \
+ wrapper/pixmaps/widget.png \
+ wrapper/pixmaps/window.png
+
+REFS = \
+ $(GLADE_SHARP_LIBS) \
+ $(GLIB_SHARP_LIBS) \
+ $(GTK_SHARP_LIBS) \
+ $(MONO_CAIRO_LIBS) \
+ -r:Mono.Posix \
+ -r:System \
+ -r:System.Core \
+ -r:System.Xml
+
+dll_config = libstetic.dll.config
+build_dll_config = $(ADDIN_BUILD)/$(dll_config)
+
+EXTRA_DIST = $(FILES) $(RES) $(dll_config) wrapper/pixmaps/COPIED
+
+$(ASSEMBLY): $(build_sources) $(build_resources) $(DEPS)
+ mkdir -p $(ADDIN_BUILD)
+ $(CSC) $(CSC_FLAGS) -debug -out:$@ -target:library $(build_resources:%=/resource:%) $(build_sources) $(REFS)
+
+$(build_dll_config): $(srcdir)/$(dll_config)
+ mkdir -p $(ADDIN_BUILD)
+ cp $(srcdir)/$(dll_config) $@
+
+CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb $(build_dll_config)
+
+include $(top_srcdir)/Makefile.include
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/NoGuiDispatchAttribute.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/NoGuiDispatchAttribute.cs
new file mode 100644
index 0000000000..e1ad777512
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/NoGuiDispatchAttribute.cs
@@ -0,0 +1,9 @@
+
+using System;
+
+namespace Stetic
+{
+ public class NoGuiDispatchAttribute: Attribute
+ {
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectReader.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectReader.cs
new file mode 100644
index 0000000000..2f463d1d52
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectReader.cs
@@ -0,0 +1,38 @@
+
+using System;
+using System.Collections;
+using System.Xml;
+
+namespace Stetic
+{
+ public class ObjectReader
+ {
+ FileFormat format;
+ IProject proj;
+ internal ArrayList GladeChildStack = new ArrayList ();
+
+ public ObjectReader (IProject proj, FileFormat format)
+ {
+ this.format = format;
+ this.proj = proj;
+ }
+
+ public FileFormat Format {
+ get { return format; }
+ }
+
+ public IProject Project {
+ get { return proj; }
+ }
+
+ public virtual ObjectWrapper ReadObject (XmlElement elem, ObjectWrapper root)
+ {
+ return Stetic.ObjectWrapper.ReadObject (this, elem, root);
+ }
+
+ public virtual void ReadExistingObject (ObjectWrapper wrapper, XmlElement elem)
+ {
+ Stetic.ObjectWrapper.ReadExistingObject (this, elem, wrapper);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapper.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapper.cs
new file mode 100644
index 0000000000..6225267e24
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapper.cs
@@ -0,0 +1,482 @@
+using System;
+using System.Collections;
+using System.CodeDom;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Xml;
+
+namespace Stetic {
+
+ public enum FileFormat {
+ Native,
+ Glade
+ }
+
+ public abstract class ObjectWrapper : MarshalByRefObject, IDisposable
+ {
+ static Hashtable wrappers = new Hashtable ();
+
+ protected IProject proj;
+ protected object wrapped;
+ protected ClassDescriptor classDescriptor;
+ SignalCollection signals;
+ internal Hashtable translationInfo;
+ Hashtable extendedData;
+ bool loading;
+ IObjectFrontend frontend;
+ bool disposed;
+
+ // This id is used by the undo methods to identify an object.
+ // This id is not stored, since it's used only while the widget is being
+ // edited in the designer
+ string undoId = WidgetUtils.GetUndoId ();
+
+ UndoManager undoManager;
+ static UndoManager defaultUndoManager = new UndoManager (true);
+
+ public ObjectWrapper ()
+ {
+ undoManager = defaultUndoManager;
+ }
+
+ public SignalCollection Signals {
+ get {
+ if (signals == null)
+ signals = new SignalCollection (this);
+ return signals;
+ }
+ }
+
+ public UndoManager UndoManager {
+ get { return GetUndoManagerInternal (); }
+ internal set { undoManager = value; }
+ }
+
+ // Called the get a diff of changes since the last call to GetUndoDiff().
+ // The returned object can be used to restore the object status by calling
+ // ApplyUndoRedoDiff. The implementation can use the UndoManager object to
+ // store status information.
+ public virtual object GetUndoDiff ()
+ {
+ return null;
+ }
+
+ // Called to apply a set of changes to the object. It returns
+ // a set of changes which can be used to reverse the operation.
+ public virtual object ApplyUndoRedoDiff (object diff)
+ {
+ return null;
+ }
+
+ public string UndoId {
+ get { return undoId; }
+ internal set { undoId = value; }
+ }
+
+ public virtual ObjectWrapper FindObjectByUndoId (string id)
+ {
+ if (undoId == id)
+ return this;
+ else
+ return null;
+ }
+
+ internal virtual UndoManager GetUndoManagerInternal ()
+ {
+ return undoManager;
+ }
+
+ internal protected bool Loading {
+ get { return loading; }
+ set { loading = value; }
+ }
+
+ public IObjectFrontend Frontend {
+ [NoGuiDispatch]
+ get { return frontend; }
+ [NoGuiDispatch]
+ set {
+ if (disposed)
+ throw new InvalidOperationException ("Can't bind component to disposed wrapper");
+ if (frontend != null)
+ frontend.Dispose ();
+ frontend = value;
+ }
+ }
+
+ public IDictionary ExtendedData {
+ get {
+ if (extendedData == null)
+ extendedData = new Hashtable ();
+ return extendedData;
+ }
+ }
+
+ public void AttachDesigner (IDesignArea designer)
+ {
+ OnDesignerAttach (designer);
+ }
+
+ public void DetachDesigner (IDesignArea designer)
+ {
+ OnDesignerDetach (designer);
+ }
+
+ public virtual void Wrap (object obj, bool initialized)
+ {
+ this.wrapped = obj;
+ wrappers [GetIndentityObject (obj)] = this;
+ }
+
+ public virtual void Dispose ()
+ {
+ if (IsDisposed)
+ return;
+
+ if (Disposed != null)
+ Disposed (this, EventArgs.Empty);
+ disposed = true;
+ if (frontend != null)
+ frontend.Dispose ();
+ frontend = null;
+ if (wrapped != null)
+ wrappers.Remove (GetIndentityObject (wrapped));
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public bool IsDisposed {
+ [NoGuiDispatch]
+ get { return disposed; }
+ }
+
+ public static ObjectWrapper Create (IProject proj, object wrapped, ObjectWrapper root)
+ {
+ ClassDescriptor klass = Registry.LookupClassByName (wrapped.GetType ().FullName);
+ ObjectWrapper wrapper = klass.CreateWrapper ();
+ if (root != null) {
+ wrapper.RootWrapperName = (root.RootWrapperName != null) ? root.RootWrapperName : root.Name;
+ }
+ wrapper.Loading = true;
+ wrapper.proj = proj;
+ wrapper.classDescriptor = klass;
+ wrapper.Wrap (wrapped, true);
+ wrapper.OnWrapped ();
+ wrapper.Loading = false;
+ return wrapper;
+ }
+
+ internal static void Bind (IProject proj, ClassDescriptor klass, ObjectWrapper wrapper, object wrapped, bool initialized)
+ {
+ wrapper.proj = proj;
+ wrapper.classDescriptor = klass;
+ wrapper.Wrap (wrapped, initialized);
+ wrapper.OnWrapped ();
+ }
+
+ public virtual void Read (ObjectReader reader, XmlElement element)
+ {
+ throw new System.NotImplementedException ();
+ }
+
+ public virtual XmlElement Write (ObjectWriter writer)
+ {
+ throw new System.NotImplementedException ();
+ }
+
+ public static ObjectWrapper ReadObject (ObjectReader reader, XmlElement elem, ObjectWrapper root)
+ {
+ string className = elem.GetAttribute ("class");
+ ClassDescriptor klass;
+ if (reader.Format == FileFormat.Native)
+ klass = Registry.LookupClassByName (className);
+ else
+ klass = Registry.LookupClassByCName (className);
+
+ if (klass == null) {
+ ErrorWidget we = new ErrorWidget (className, elem.GetAttribute ("id"));
+ ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we, null);
+ wrap.Read (reader, elem);
+ return wrap;
+ }
+ if (!klass.SupportsGtkVersion (reader.Project.TargetGtkVersion)) {
+ ErrorWidget we = new ErrorWidget (className, klass.TargetGtkVersion, reader.Project.TargetGtkVersion, elem.GetAttribute ("id"));
+ ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we, null);
+ wrap.Read (reader, elem);
+ return wrap;
+ }
+
+ ObjectWrapper wrapper = klass.CreateWrapper ();
+ if (root != null) {
+ if (root.RootWrapperName != null) {
+ wrapper.RootWrapperName = root.RootWrapperName;
+ }
+ }
+ wrapper.classDescriptor = klass;
+ wrapper.proj = reader.Project;
+ return ReadExistingObject (reader, elem, wrapper);
+ }
+
+ public static ObjectWrapper ReadExistingObject (ObjectReader reader, XmlElement elem, ObjectWrapper wrapper)
+ {
+ try {
+ wrapper.OnBeginRead (reader.Format);
+ wrapper.Read (reader, elem);
+ return wrapper;
+ }
+ catch (Exception ex) {
+ Console.WriteLine (ex);
+ ErrorWidget we = new ErrorWidget (ex, elem.GetAttribute ("id"));
+ ErrorWidgetWrapper wrap = (ErrorWidgetWrapper) Create (reader.Project, we, null);
+ wrap.Read (reader, elem);
+ return wrap;
+ }
+ finally {
+ wrapper.OnEndRead (reader.Format);
+ }
+ }
+
+ internal void GenerateInitCode (GeneratorContext ctx, CodeExpression var)
+ {
+ // Set the value for initialization properties. The value for those properties is
+ // usually set in the constructor, but top levels are created by the user, so
+ // those properties need to be explicitely set in the Gui.Build method.
+ foreach (PropertyDescriptor prop in ClassDescriptor.InitializationProperties) {
+ GeneratePropertySet (ctx, var, prop);
+ }
+ }
+
+ internal protected virtual void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ // Write the widget properties
+ foreach (ItemGroup group in ClassDescriptor.ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ if (!item.SupportsGtkVersion (Project.TargetGtkVersion))
+ continue;
+ PropertyDescriptor prop = item as PropertyDescriptor;
+ if (prop == null || !prop.IsRuntimeProperty)
+ continue;
+ if (ClassDescriptor.InitializationProperties != null && Array.IndexOf (ClassDescriptor.InitializationProperties, prop) != -1)
+ continue;
+ GeneratePropertySet (ctx, var, prop);
+ }
+ }
+ }
+
+ internal protected virtual void GeneratePostBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ }
+
+ internal protected virtual CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ if (ClassDescriptor.InitializationProperties != null) {
+ CodeExpression[] paramters = new CodeExpression [ClassDescriptor.InitializationProperties.Length];
+ for (int n=0; n < paramters.Length; n++) {
+ PropertyDescriptor prop = ClassDescriptor.InitializationProperties [n];
+ paramters [n] = ctx.GenerateValue (prop.GetValue (Wrapped), prop.RuntimePropertyType, prop.Translatable && prop.IsTranslated (Wrapped));
+ }
+ return new CodeObjectCreateExpression (WrappedTypeName.ToGlobalTypeRef (), paramters);
+ } else
+ return new CodeObjectCreateExpression (WrappedTypeName.ToGlobalTypeRef ());
+ }
+
+ protected virtual void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ object oval = prop.GetValue (Wrapped);
+ if (oval == null || (prop.HasDefault && prop.IsDefaultValue (oval)))
+ return;
+
+ CodeExpression val = ctx.GenerateValue (oval, prop.RuntimePropertyType, prop.Translatable && prop.IsTranslated (Wrapped));
+ CodeExpression cprop;
+
+ TypedPropertyDescriptor tprop = prop as TypedPropertyDescriptor;
+ if (tprop == null || tprop.GladeProperty == prop) {
+ cprop = new CodePropertyReferenceExpression (var, prop.Name);
+ } else {
+ cprop = new CodePropertyReferenceExpression (var, tprop.GladeProperty.Name);
+ cprop = new CodePropertyReferenceExpression (cprop, prop.Name);
+ }
+ ctx.Statements.Add (new CodeAssignStatement (cprop, val));
+ }
+
+ public static ObjectWrapper Lookup (object obj)
+ {
+ if (obj == null)
+ return null;
+ else
+ return wrappers [GetIndentityObject (obj)] as Stetic.ObjectWrapper;
+ }
+
+ public object Wrapped {
+ get {
+ return wrapped;
+ }
+ }
+
+ public IProject Project {
+ get {
+ return proj;
+ }
+ }
+
+ public ClassDescriptor ClassDescriptor {
+ get { return classDescriptor; }
+ }
+
+ public virtual string WrappedTypeName {
+ get { return classDescriptor.WrappedTypeName; }
+ }
+
+ public void NotifyChanged ()
+ {
+ if (UndoManager.CanNotifyChanged (this))
+ OnObjectChanged (new ObjectWrapperEventArgs (this));
+ }
+
+ internal void FireObjectChangedEvent ()
+ {
+ OnObjectChanged (new ObjectWrapperEventArgs (this));
+ }
+
+ public abstract string Name { get; set; }
+
+ public string RootWrapperName { get; protected set; }
+
+ static object GetIndentityObject (object ob)
+ {
+ if (ob is Gtk.Container.ContainerChild) {
+ // We handle ContainerChild in a special way here since
+ // the Gtk.Container indexer always returns a new ContainerChild
+ // instance. We register its wrapper using ContainerChildHashItem
+ // to make sure that two different instance of the same ContainerChild
+ // can be found equal.
+ ContainerChildHashItem p = new ContainerChildHashItem ();
+ p.ContainerChild = (Gtk.Container.ContainerChild) ob;
+ return p;
+ }
+ else
+ return ob;
+ }
+
+ public delegate void WrapperNotificationDelegate (object obj, string propertyName);
+
+ public event WrapperNotificationDelegate Notify;
+ public event SignalEventHandler SignalAdded;
+ public event SignalEventHandler SignalRemoved;
+ public event SignalChangedEventHandler SignalChanged;
+ public event EventHandler Disposed;
+
+ // Fired when any information of the object changes.
+ public event ObjectWrapperEventHandler ObjectChanged;
+
+ protected virtual void OnBeginRead (FileFormat format)
+ {
+ loading = true;
+ }
+
+ protected virtual void OnEndRead (FileFormat format)
+ {
+ loading = false;
+ }
+
+ internal protected virtual void OnObjectChanged (ObjectWrapperEventArgs args)
+ {
+ if (frontend != null)
+ frontend.NotifyChanged ();
+ if (!Loading) {
+ if (proj != null)
+ proj.NotifyObjectChanged (args);
+ if (ObjectChanged != null)
+ ObjectChanged (this, args);
+ }
+ }
+
+ protected virtual void EmitNotify (string propertyName)
+ {
+ if (!Loading) {
+ NotifyChanged ();
+ if (!Loading && Notify != null)
+ Notify (this, propertyName);
+ }
+ }
+
+ internal protected virtual void OnSignalAdded (SignalEventArgs args)
+ {
+ OnObjectChanged (args);
+ if (!Loading) {
+ if (proj != null)
+ proj.NotifySignalAdded (args);
+ if (SignalAdded != null)
+ SignalAdded (this, args);
+ }
+ }
+
+ internal protected virtual void OnSignalRemoved (SignalEventArgs args)
+ {
+ OnObjectChanged (args);
+ if (!Loading) {
+ if (proj != null)
+ proj.NotifySignalRemoved (args);
+ if (SignalRemoved != null)
+ SignalRemoved (this, args);
+ }
+ }
+
+ internal protected virtual void OnSignalChanged (SignalChangedEventArgs args)
+ {
+ OnObjectChanged (args);
+ if (!Loading) {
+ if (proj != null)
+ proj.NotifySignalChanged (args);
+ if (SignalChanged != null)
+ SignalChanged (this, args);
+ }
+ }
+
+ internal protected virtual void OnDesignerAttach (IDesignArea designer)
+ {
+ }
+
+ internal protected virtual void OnDesignerDetach (IDesignArea designer)
+ {
+ }
+
+ internal protected virtual void OnWrapped ()
+ {
+ }
+
+ internal protected virtual void DropObject (string data, Gtk.Widget obj)
+ {
+ // Called by DND.Drop
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+
+ // Wraps a ContainerChild, and properly implements GetHashCode() and Equals()
+ struct ContainerChildHashItem
+ {
+ public Gtk.Container.ContainerChild ContainerChild;
+
+ public override int GetHashCode ()
+ {
+ return ContainerChild.Parent.GetHashCode () + ContainerChild.Child.GetHashCode ();
+ }
+
+ public override bool Equals (object ob)
+ {
+ if (!(ob is ContainerChildHashItem))
+ return false;
+ ContainerChildHashItem ot = (ContainerChildHashItem) ob;
+ return ot.ContainerChild.Child == ContainerChild.Child && ot.ContainerChild.Parent == ContainerChild.Parent;
+ }
+ }
+
+ public interface IObjectFrontend: IDisposable
+ {
+ void NotifyChanged ();
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapperEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapperEventHandler.cs
new file mode 100644
index 0000000000..a9645e3384
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWrapperEventHandler.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Stetic
+{
+ public delegate void ObjectWrapperEventHandler (object sender, ObjectWrapperEventArgs args);
+
+ public class ObjectWrapperEventArgs: EventArgs
+ {
+ ObjectWrapper objectWrapper;
+
+ public ObjectWrapperEventArgs (ObjectWrapper objectWrapper)
+ {
+ this.objectWrapper = objectWrapper;
+ }
+
+ public ObjectWrapper Wrapper {
+ get { return objectWrapper; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWriter.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWriter.cs
new file mode 100644
index 0000000000..cb2e7fd41f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ObjectWriter.cs
@@ -0,0 +1,38 @@
+
+using System;
+using System.Xml;
+using Stetic.Wrapper;
+
+namespace Stetic
+{
+ public class ObjectWriter
+ {
+ XmlDocument doc;
+ FileFormat format;
+ bool createUndo;
+
+ public ObjectWriter (XmlDocument doc, FileFormat format)
+ {
+ this.doc = doc;
+ this.format = format;
+ }
+
+ public FileFormat Format {
+ get { return format; }
+ }
+
+ public XmlDocument XmlDocument {
+ get { return doc; }
+ }
+
+ public bool CreateUndoInfo {
+ get { return createUndo; }
+ set { createUndo = value; }
+ }
+
+ public virtual XmlElement WriteObject (ObjectWrapper wrapper)
+ {
+ return wrapper.Write (this);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ParamSpec.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ParamSpec.cs
new file mode 100644
index 0000000000..c244285f22
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ParamSpec.cs
@@ -0,0 +1,225 @@
+using GLib;
+using Gtk;
+using System;
+using System.Collections;
+using System.Runtime.InteropServices;
+
+namespace Stetic {
+
+ public class ParamSpec : IDisposable {
+ IntPtr _obj;
+
+ public ParamSpec (IntPtr raw)
+ {
+ Raw = raw;
+ }
+
+ ~ParamSpec ()
+ {
+ Dispose ();
+ }
+
+ public void Dispose ()
+ {
+ Raw = IntPtr.Zero;
+ GC.SuppressFinalize (this);
+ }
+
+ IntPtr Raw {
+ get {
+ return _obj;
+ }
+ set {
+ if (_obj != IntPtr.Zero)
+ g_param_spec_unref (_obj);
+ _obj = value;
+ if (_obj != IntPtr.Zero) {
+ g_param_spec_ref (_obj);
+ g_param_spec_sink (_obj);
+ }
+ }
+ }
+
+ public string Name {
+ get {
+ return GLib.Marshaller.Utf8PtrToString (g_param_spec_get_name (_obj));
+ }
+ }
+
+ public string Nick {
+ get {
+ return GLib.Marshaller.Utf8PtrToString (g_param_spec_get_nick (_obj));
+ }
+ }
+
+ public string Blurb {
+ get {
+ return GLib.Marshaller.Utf8PtrToString (g_param_spec_get_blurb (_obj));
+ }
+ }
+
+/* [DllImport("libsteticglue")]
+ static extern bool stetic_param_spec_get_minimum (IntPtr pspec, ref GLib.Value value);
+
+ public object Minimum {
+ get {
+ GLib.Value value = new GLib.Value ();
+
+ if (stetic_param_spec_get_minimum (Raw, ref value))
+ return value.Val;
+ else
+ return null;
+ }
+ }
+*/
+ public object Minimum {
+ get {
+ return null;
+ }
+ }
+
+/* [DllImport("libsteticglue")]
+ static extern bool stetic_param_spec_get_maximum (IntPtr pspec, ref GLib.Value value);
+
+ public object Maximum {
+ get {
+ GLib.Value value = new GLib.Value ();
+
+ if (stetic_param_spec_get_maximum (Raw, ref value))
+ return value.Val;
+ else
+ return null;
+ }
+ }
+*/
+ public object Maximum {
+ get {
+ return null;
+ }
+ }
+
+ public bool IsDefaultValue (object value)
+ {
+ GLib.Value gvalue = new GLib.Value (value);
+ return g_param_value_defaults (Raw, ref gvalue);
+ }
+
+/* [DllImport("libsteticglue")]
+ static extern bool stetic_param_spec_get_default (IntPtr pspec, ref GLib.Value value);
+ public object Default {
+ get {
+ GLib.Value value = new GLib.Value ();
+
+ if (stetic_param_spec_get_default (Raw, ref value))
+ return value.Val;
+ else
+ return null;
+ }
+ }
+
+ [DllImport("libsteticglue")]
+ static extern IntPtr stetic_param_spec_get_value_type (IntPtr obj);
+
+ public IntPtr ValueType {
+ get {
+ return stetic_param_spec_get_value_type (_obj);
+ }
+ }
+*/
+
+/* [DllImport("libsteticglue")]
+ static extern bool stetic_param_spec_is_unichar (IntPtr pspec);
+
+ public bool IsUnichar {
+ get {
+ return stetic_param_spec_is_unichar (_obj);
+ }
+ }
+*/
+ static Hashtable props = new Hashtable (), childProps = new Hashtable ();
+
+ private class ParamSpecTypeHack : GLib.Object {
+ private ParamSpecTypeHack () : base (IntPtr.Zero) {}
+
+ static Hashtable classes = new Hashtable ();
+
+ public static IntPtr LookupGTypeClass (System.Type t)
+ {
+ if (classes[t] == null) {
+ GType gtype = GLib.Object.LookupGType (t);
+ classes[t] = g_type_class_ref (gtype.Val);
+ }
+
+ return (IntPtr)classes[t];
+ }
+ }
+
+ public static ParamSpec LookupObjectProperty (Type type, string name)
+ {
+ string key = type.FullName + ":" + name;
+ if (props[key] != null)
+ return (ParamSpec)props[key];
+
+ IntPtr klass = ParamSpecTypeHack.LookupGTypeClass (type);
+ if (klass == IntPtr.Zero)
+ return null;
+
+ IntPtr pspec_raw = g_object_class_find_property (klass, name);
+ if (pspec_raw == IntPtr.Zero)
+ return null;
+
+ ParamSpec pspec = new ParamSpec (pspec_raw);
+ props[key] = pspec;
+ return pspec;
+ }
+
+ public static ParamSpec LookupChildProperty (Type type, string name)
+ {
+ string key = type.FullName + ":" + name;
+ if (childProps[key] != null)
+ return (ParamSpec)childProps[key];
+
+ IntPtr klass = ParamSpecTypeHack.LookupGTypeClass (type);
+ if (klass == IntPtr.Zero)
+ return null;
+
+ IntPtr pspec_raw = gtk_container_class_find_child_property (klass, name);
+ if (pspec_raw == IntPtr.Zero)
+ return null;
+
+ ParamSpec pspec = new ParamSpec (pspec_raw);
+ childProps[key] = pspec;
+ return pspec;
+ }
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern void g_param_spec_ref (IntPtr obj);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern void g_param_spec_unref (IntPtr obj);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern void g_param_spec_sink (IntPtr obj);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_param_spec_get_name (IntPtr obj);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_param_spec_get_nick (IntPtr obj);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_param_spec_get_blurb (IntPtr obj);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern bool g_param_value_defaults (IntPtr obj, ref GLib.Value value);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_type_class_ref (IntPtr gtype);
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_object_class_find_property (IntPtr klass, string name);
+
+ [DllImport("libgtk-win32-2.0-0.dll")]
+ static extern IntPtr gtk_container_class_find_child_property (IntPtr klass, string name);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/Placeholder.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Placeholder.cs
new file mode 100644
index 0000000000..d5a6b69bec
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Placeholder.cs
@@ -0,0 +1,149 @@
+using Gtk;
+using System;
+
+namespace Stetic {
+
+ public class Placeholder : Gtk.DrawingArea, IEditableObject
+ {
+ // This id is used by the undo methods to identify a child of a container.
+ string undoId;
+
+ public Placeholder ()
+ {
+ undoId = WidgetUtils.GetUndoId ();
+ DND.DestSet (this, true);
+ Events |= Gdk.EventMask.ButtonPressMask;
+ WidgetFlags |= WidgetFlags.AppPaintable;
+ }
+
+ internal string UndoId {
+ get { return undoId; }
+ set { undoId = value; }
+ }
+
+ const int minSize = 10;
+
+ protected override void OnSizeRequested (ref Requisition req)
+ {
+ base.OnSizeRequested (ref req);
+ if (req.Width <= 0)
+ req.Width = minSize;
+ if (req.Height <= 0)
+ req.Height = minSize;
+ }
+
+ protected override void OnRealized ()
+ {
+ base.OnRealized ();
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose evt)
+ {
+ if (!IsDrawable)
+ return false;
+
+ int width, height;
+ GdkWindow.GetSize (out width, out height);
+
+ Gdk.Rectangle a = new Gdk.Rectangle (0,0,width,height);
+
+ byte b2 = 210;
+
+ int ssLT = 12;
+ int ssRB = 7;
+ double grey = 0.6;
+ double greyb1 = 0.9;
+ double greyb2 = 0.6;
+
+ Gdk.Rectangle rect = a;
+ Cairo.Color back1 = new Cairo.Color (greyb1, greyb1, greyb1);
+ Cairo.Color back2 = new Cairo.Color (greyb2, greyb2, greyb2);
+ Cairo.Color cdark = new Cairo.Color (grey, grey, grey, 1);
+ Cairo.Color clight = new Cairo.Color (grey, grey, grey, 0);
+ using (Cairo.Context cr = Gdk.CairoHelper.Create (evt.Window)) {
+
+ DrawGradient (cr, rect, 0, 0, 1, 1, back1, back2);
+
+ rect.X = a.X;
+ rect.Y = a.Y;
+ rect.Height = ssLT;
+ rect.Width = a.Width;
+ DrawGradient (cr, rect, 0, 0, 0, 1, cdark, clight);
+
+ rect.Y = a.Bottom - ssRB;
+ rect.Height = ssRB;
+ DrawGradient (cr, rect, 0, 0, 0, 1, clight, cdark);
+
+ rect.X = a.X;
+ rect.Y = a.Y;
+ rect.Width = ssLT;
+ rect.Height = a.Height;
+ DrawGradient (cr, rect, 0, 0, 1, 0, cdark, clight);
+
+ rect.X = a.Right - ssRB;
+ rect.Width = ssRB;
+ DrawGradient (cr, rect, 0, 0, 1, 0, clight, cdark);
+
+ Gdk.GC gc = new Gdk.GC (GdkWindow);
+ gc.RgbBgColor = new Gdk.Color (b2,b2,b2);
+ gc.RgbFgColor = new Gdk.Color (b2,b2,b2);
+ GdkWindow.DrawRectangle (gc, false, a.X, a.Y, a.Width, a.Height);
+ gc.Dispose ();
+ }
+
+ return base.OnExposeEvent (evt);
+ }
+
+ void DrawGradient (Cairo.Context cr, Gdk.Rectangle rect, int fx, int fy, int fw, int fh, Cairo.Color c1, Cairo.Color c2)
+ {
+ cr.NewPath ();
+ cr.MoveTo (rect.X, rect.Y);
+ cr.RelLineTo (rect.Width, 0);
+ cr.RelLineTo (0, rect.Height);
+ cr.RelLineTo (-rect.Width, 0);
+ cr.RelLineTo (0, -rect.Height);
+ cr.ClosePath ();
+ Cairo.LinearGradient pat = new Cairo.LinearGradient (rect.X + rect.Width*fx, rect.Y + rect.Height*fy, rect.X + rect.Width*fw, rect.Y + rect.Height*fh);
+ pat.AddColorStop (0, c1);
+ pat.AddColorStop (1, c2);
+ cr.Pattern = pat;
+ cr.FillPreserve ();
+ }
+
+ bool IEditableObject.CanDelete {
+ get { return true; }
+ }
+
+ bool IEditableObject.CanPaste {
+ get { return true; }
+ }
+
+ bool IEditableObject.CanCut {
+ get { return false; }
+ }
+
+ bool IEditableObject.CanCopy {
+ get { return false; }
+ }
+
+ void IEditableObject.Delete ()
+ {
+ Stetic.Wrapper.Container wc = Stetic.Wrapper.Container.LookupParent (this);
+ if (wc != null)
+ wc.Delete (this);
+ }
+
+ void IEditableObject.Paste ()
+ {
+ Clipboard.Paste (this);
+ }
+
+ void IEditableObject.Cut ()
+ {
+ }
+
+ void IEditableObject.Copy ()
+ {
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/ProjectIconFactory.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ProjectIconFactory.cs
new file mode 100644
index 0000000000..79d6918625
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/ProjectIconFactory.cs
@@ -0,0 +1,335 @@
+
+using System;
+using System.CodeDom;
+using System.Xml;
+using System.Collections;
+
+namespace Stetic
+{
+ public class ProjectIconFactory
+ {
+ ProjectIconSetCollection icons = new ProjectIconSetCollection ();
+
+ public ProjectIconFactory()
+ {
+ }
+
+ public ProjectIconSetCollection Icons {
+ get { return icons; }
+ }
+
+ public ProjectIconSet GetIcon (string name)
+ {
+ foreach (ProjectIconSet icon in icons)
+ if (icon.Name == name)
+ return icon;
+ return null;
+ }
+
+ public XmlElement Write (XmlDocument doc)
+ {
+ XmlElement elem = doc.CreateElement ("icon-factory");
+ foreach (ProjectIconSet icon in icons)
+ elem.AppendChild (icon.Write (doc));
+ return elem;
+ }
+
+ public void Read (IProject project, XmlElement elem)
+ {
+ icons.Clear ();
+ foreach (XmlElement child in elem.SelectNodes ("icon-set")) {
+ ProjectIconSet icon = new ProjectIconSet ();
+ icon.Read (project, child);
+ icons.Add (icon);
+ }
+ }
+
+ public void GenerateBuildCode (GeneratorContext ctx)
+ {
+ string varName = ctx.NewId ();
+ CodeVariableDeclarationStatement varDec = new CodeVariableDeclarationStatement (typeof(Gtk.IconFactory).ToGlobalTypeRef (), varName);
+ varDec.InitExpression = new CodeObjectCreateExpression (typeof(Gtk.IconFactory).ToGlobalTypeRef ());
+ ctx.Statements.Add (varDec);
+
+ CodeVariableReferenceExpression var = new CodeVariableReferenceExpression (varName);
+ foreach (ProjectIconSet icon in icons) {
+
+ CodeExpression exp = new CodeMethodInvokeExpression (
+ var,
+ "Add",
+ new CodePrimitiveExpression (icon.Name),
+ icon.GenerateObjectBuild (ctx)
+ );
+ ctx.Statements.Add (exp);
+ }
+
+ CodeExpression addd = new CodeMethodInvokeExpression (
+ var,
+ "AddDefault"
+ );
+ ctx.Statements.Add (addd);
+ }
+
+ public Gdk.Pixbuf RenderIcon (IProject project, string name, Gtk.IconSize size)
+ {
+ ProjectIconSet icon = GetIcon (name);
+ if (icon == null)
+ return null;
+
+ foreach (ProjectIconSource src in icon.Sources) {
+ if (src.SizeWildcarded || src.Size == size)
+ return src.Image.GetScaledImage (project, size);
+ }
+
+ return icon.Sources [0].Image.GetScaledImage (project, size);
+ }
+
+ public Gdk.Pixbuf RenderIcon (IProject project, string name, int size)
+ {
+ ProjectIconSet icon = GetIcon (name);
+ if (icon == null)
+ return null;
+
+ return icon.Sources [0].Image.GetScaledImage (project, size, size);
+ }
+ }
+
+ public class ProjectIconSet
+ {
+ ProjectIconSourceCollection sources = new ProjectIconSourceCollection ();
+ string name;
+
+ public string Name {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public ProjectIconSourceCollection Sources {
+ get { return sources; }
+ }
+
+ public XmlElement Write (XmlDocument doc)
+ {
+ XmlElement elem = doc.CreateElement ("icon-set");
+ elem.SetAttribute ("id", name);
+ foreach (ProjectIconSource src in sources)
+ elem.AppendChild (src.Write (doc));
+ return elem;
+ }
+
+ public void Read (IProject project, XmlElement elem)
+ {
+ sources.Clear ();
+ name = elem.GetAttribute ("id");
+ if (name.Length == 0)
+ throw new InvalidOperationException ("Name attribute not found");
+
+ foreach (XmlElement child in elem.SelectNodes ("source")) {
+ ProjectIconSource src = new ProjectIconSource ();
+ src.Read (project, child);
+ sources.Add (src);
+ }
+ }
+
+ internal CodeExpression GenerateObjectBuild (GeneratorContext ctx)
+ {
+ string varName = ctx.NewId ();
+ CodeVariableDeclarationStatement varDec = new CodeVariableDeclarationStatement (typeof(Gtk.IconSet).ToGlobalTypeRef (), varName);
+ ctx.Statements.Add (varDec);
+
+ CodeVariableReferenceExpression var = new CodeVariableReferenceExpression (varName);
+
+ if (sources.Count == 1 && sources[0].AllWildcarded) {
+ varDec.InitExpression = new CodeObjectCreateExpression (
+ typeof(Gtk.IconSet).ToGlobalTypeRef (),
+ sources[0].Image.ToCodeExpression (ctx)
+ );
+ } else {
+ varDec.InitExpression = new CodeObjectCreateExpression (typeof(Gtk.IconSet).ToGlobalTypeRef ());
+ foreach (ProjectIconSource src in sources) {
+ CodeExpression exp = new CodeMethodInvokeExpression (
+ var,
+ "AddSource",
+ src.GenerateObjectBuild (ctx)
+ );
+ ctx.Statements.Add (exp);
+ }
+ }
+ return var;
+ }
+ }
+
+ public class ProjectIconSource: Gtk.IconSource
+ {
+ ImageInfo imageInfo;
+
+ public ImageInfo Image {
+ get { return imageInfo; }
+ set { imageInfo = value; }
+ }
+
+ public bool AllWildcarded {
+ get {
+ return DirectionWildcarded && SizeWildcarded && StateWildcarded;
+ }
+ set {
+ DirectionWildcarded = SizeWildcarded = StateWildcarded = true;
+ }
+ }
+
+ public XmlElement Write (XmlDocument doc)
+ {
+ XmlElement elem = doc.CreateElement ("source");
+
+ XmlElement prop = doc.CreateElement ("property");
+ prop.SetAttribute ("name", "Image");
+ prop.InnerText = imageInfo.ToString ();
+ elem.AppendChild (prop);
+
+ if (!SizeWildcarded) {
+ prop = doc.CreateElement ("property");
+ prop.SetAttribute ("name", "Size");
+ prop.InnerText = Size.ToString ();
+ elem.AppendChild (prop);
+ }
+
+ if (!StateWildcarded) {
+ prop = doc.CreateElement ("property");
+ prop.SetAttribute ("name", "State");
+ prop.InnerText = State.ToString ();
+ elem.AppendChild (prop);
+ }
+
+ if (!DirectionWildcarded) {
+ prop = doc.CreateElement ("property");
+ prop.SetAttribute ("name", "Direction");
+ prop.InnerText = Direction.ToString ();
+ elem.AppendChild (prop);
+ }
+
+ return elem;
+ }
+
+ public void Read (IProject project, XmlElement elem)
+ {
+ XmlElement prop = elem.SelectSingleNode ("property[@name='Image']") as XmlElement;
+ if (prop != null)
+ imageInfo = ImageInfo.FromString (prop.InnerText);
+
+ prop = elem.SelectSingleNode ("property[@name='Size']") as XmlElement;
+ if (prop != null && prop.InnerText != "*") {
+ SizeWildcarded = false;
+ Size = (Gtk.IconSize) Enum.Parse (typeof(Gtk.IconSize), prop.InnerText);
+ } else
+ SizeWildcarded = true;
+
+ prop = elem.SelectSingleNode ("property[@name='State']") as XmlElement;
+ if (prop != null && prop.InnerText != "*") {
+ StateWildcarded = false;
+ State = (Gtk.StateType) Enum.Parse (typeof(Gtk.StateType), prop.InnerText);
+ } else
+ StateWildcarded = true;
+
+ prop = elem.SelectSingleNode ("property[@name='Direction']") as XmlElement;
+ if (prop != null && prop.InnerText != "*") {
+ DirectionWildcarded = false;
+ Direction = (Gtk.TextDirection) Enum.Parse (typeof(Gtk.TextDirection), prop.InnerText);
+ } else
+ DirectionWildcarded = true;
+ }
+
+ internal CodeExpression GenerateObjectBuild (GeneratorContext ctx)
+ {
+ string varName = ctx.NewId ();
+ CodeVariableDeclarationStatement varDec = new CodeVariableDeclarationStatement (typeof(Gtk.IconSource).ToGlobalTypeRef (), varName);
+ varDec.InitExpression = new CodeObjectCreateExpression (typeof(Gtk.IconSource).ToGlobalTypeRef ());
+ ctx.Statements.Add (varDec);
+
+ CodeVariableReferenceExpression var = new CodeVariableReferenceExpression (varName);
+
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Pixbuf"),
+ imageInfo.ToCodeExpression (ctx)
+ ));
+
+ if (!SizeWildcarded) {
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "SizeWildcarded"),
+ new CodePrimitiveExpression (false)
+ ));
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Size"),
+ new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference ("Gtk.IconSize", CodeTypeReferenceOptions.GlobalReference)),
+ Size.ToString ()
+ )
+ ));
+ }
+
+ if (!StateWildcarded) {
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "StateWildcarded"),
+ new CodePrimitiveExpression (false)
+ ));
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "State"),
+ new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference ("Gtk.StateType", CodeTypeReferenceOptions.GlobalReference)),
+ State.ToString ()
+ )
+ ));
+ }
+
+ if (!DirectionWildcarded) {
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "DirectionWildcarded"),
+ new CodePrimitiveExpression (false)
+ ));
+ ctx.Statements.Add (new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Direction"),
+ new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference ("Gtk.TextDirection", CodeTypeReferenceOptions.GlobalReference)),
+ Direction.ToString ()
+ )
+ ));
+ }
+
+ return var;
+ }
+ }
+
+ public class ProjectIconSetCollection: CollectionBase
+ {
+ public ProjectIconSet this [int n] {
+ get { return (ProjectIconSet) List [n]; }
+ }
+
+ public void Add (ProjectIconSet icon)
+ {
+ List.Add (icon);
+ }
+
+ public void Remove (ProjectIconSet icon)
+ {
+ List.Remove (icon);
+ }
+ }
+
+ public class ProjectIconSourceCollection: CollectionBase
+ {
+ public void AddRange (ICollection c)
+ {
+ foreach (ProjectIconSource s in c)
+ List.Add (s);
+ }
+
+ public ProjectIconSource this [int n] {
+ get { return (ProjectIconSource) List [n]; }
+ }
+
+ public void Add (ProjectIconSource source)
+ {
+ List.Add (source);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyDescriptor.cs
new file mode 100644
index 0000000000..3a4a5e9ffb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyDescriptor.cs
@@ -0,0 +1,310 @@
+using System;
+using System.ComponentModel;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+
+namespace Stetic {
+
+ class TranslationInfo {
+ public bool Translated;
+ public string Context, Comment;
+ }
+
+ public abstract class PropertyDescriptor : ItemDescriptor
+ {
+ protected string label, description, gladeName;
+ protected bool gladeOverride;
+
+ protected bool isRuntimeProperty, hasDefault, initWithName;
+ protected Type editorType;
+ protected object minimum, maximum;
+ protected object defaultValue;
+ protected TypeConverter typeConverter;
+ protected bool translatable;
+
+ protected PropertyDescriptor ()
+ {
+ }
+
+ protected PropertyDescriptor (XmlElement elem, ItemGroup group, ClassDescriptor klass): base (elem, group, klass)
+ {
+ }
+
+ protected void Load (XmlElement elem)
+ {
+ if (elem.HasAttribute ("label"))
+ label = elem.GetAttribute ("label");
+
+ if (label == null)
+ label = elem.GetAttribute ("name");
+
+ if (elem.HasAttribute ("description"))
+ description = elem.GetAttribute ("description");
+
+ if (elem.HasAttribute ("min"))
+ minimum = StringToValue (elem.GetAttribute ("min"));
+
+ if (elem.HasAttribute ("max"))
+ maximum = StringToValue (elem.GetAttribute ("max"));
+
+ if (elem.HasAttribute ("glade-override"))
+ gladeOverride = true;
+
+ if (elem.HasAttribute ("glade-name"))
+ gladeName = elem.GetAttribute ("glade-name");
+
+ if (elem.HasAttribute ("init-with-name"))
+ initWithName = true;
+
+ if (elem.HasAttribute ("translatable"))
+ translatable = true;
+
+ if (elem.HasAttribute ("default")) {
+ defaultValue = StringToValue (elem.GetAttribute ("default"));
+ hasDefault = true;
+ }
+
+ string convTypeName = elem.GetAttribute ("type-converter");
+ if (convTypeName.Length > 0) {
+ Type type = Registry.GetType (convTypeName, true);
+ typeConverter = (TypeConverter) Activator.CreateInstance (type);
+ }
+ }
+
+ // The property's user-visible name
+ public virtual string Label {
+ get {
+ return label;
+ }
+ }
+
+ // The property's type
+ public abstract Type PropertyType {
+ get ;
+ }
+
+ // The property's user-visible description
+ public virtual string Description {
+ get {
+ return description;
+ }
+ }
+
+ // The property's GUI editor type, if overridden
+ public virtual Type EditorType {
+ get {
+ return editorType;
+ }
+ }
+
+ // The property's minimum value, if declared
+ public virtual object Minimum {
+ get {
+ return minimum;
+ }
+ }
+
+ // The property's maximum value, if declared
+ public virtual object Maximum {
+ get {
+ return maximum;
+ }
+ }
+
+ public virtual string InternalChildId {
+ get { return null; }
+ }
+
+ // Whether or not the property has a default value
+ public virtual bool HasDefault {
+ get {
+ return hasDefault;
+ }
+ set {
+ hasDefault = value;
+ }
+ }
+
+ public virtual bool IsDefaultValue (object value)
+ {
+ if (value == null)
+ return true;
+ if (defaultValue != null)
+ return value.Equals (defaultValue);
+ return false;
+ }
+
+ public virtual void ResetValue (object instance)
+ {
+ if (HasDefault)
+ SetValue (instance, defaultValue);
+ }
+
+ // The property's type at run time
+ public virtual Type RuntimePropertyType {
+ get { return PropertyType; }
+ }
+
+ // Gets the value of the property on @obj
+ public abstract object GetValue (object obj);
+
+ // Gets the value of the property on @obj, bypassing the wrapper.
+ public virtual object GetRuntimeValue (object obj)
+ {
+ return GetValue (obj);
+ }
+
+ // Whether or not the property is writable
+ public virtual bool CanWrite {
+ get { return true; }
+ }
+
+ // Sets the value of the property on @obj
+ public abstract void SetValue (object obj, object value);
+
+ // Sets the value of the property on @obj, bypassing the wrapper.
+ public virtual void SetRuntimeValue (object obj, object value)
+ {
+ SetValue (obj, value);
+ }
+
+ // Parses a string an returns a value valid for this property
+ public virtual object StringToValue (string value)
+ {
+ if (typeConverter != null && typeConverter.CanConvertFrom (typeof(string)))
+ return typeConverter.ConvertFromString (value);
+ else if (PropertyType.IsEnum)
+ return Enum.Parse (PropertyType, value);
+ else if (PropertyType == typeof(ImageInfo))
+ return ImageInfo.FromString (value);
+ else if (PropertyType == typeof(string[]))
+ return string.IsNullOrEmpty (value) ? null : value.Split ('\n');
+ else if (PropertyType == typeof(DateTime))
+ return new DateTime (long.Parse (value));
+ else if (PropertyType == typeof(TimeSpan))
+ return new TimeSpan (long.Parse (value));
+ else if (PropertyType == typeof(double)) {
+ try {
+ return Convert.ChangeType (value, PropertyType);
+ }
+ catch (InvalidCastException) {
+ return Convert.ChangeType (value, PropertyType, System.Globalization.CultureInfo.InvariantCulture);
+ }
+ } else
+ return Convert.ChangeType (value, PropertyType, System.Globalization.CultureInfo.InvariantCulture);
+ }
+
+ // Returns a string representation of the provided property value
+ public virtual string ValueToString (object value)
+ {
+ if (typeConverter != null && typeConverter.CanConvertTo (typeof(string)))
+ return typeConverter.ConvertToString (value);
+ else if (PropertyType == typeof(string[]))
+ return value == null ? string.Empty : string.Join ("\n", (string[])value);
+ else if (PropertyType == typeof(DateTime))
+ return ((DateTime)value).Ticks.ToString ();
+ else if (PropertyType == typeof(TimeSpan))
+ return ((TimeSpan)value).Ticks.ToString ();
+ else if (PropertyType == typeof(double))
+ return ((double)value).ToString (System.Globalization.CultureInfo.InvariantCulture);
+ else
+ return value.ToString ();
+ }
+
+ public virtual bool InitWithName {
+ get {
+ return initWithName;
+ }
+ }
+
+ public virtual bool IsRuntimeProperty {
+ get { return isRuntimeProperty; }
+ }
+
+ public virtual bool Translatable {
+ get {
+ return translatable;
+ }
+ }
+
+ public virtual bool IsTranslated (object obj)
+ {
+ if (!translatable)
+ return false;
+
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ if (wrapper == null)
+ return false;
+
+ // Since translatable properties are assumed to be translated
+ // by default, we return true if there is no TranslationInfo
+ // for the object
+
+ if (wrapper.translationInfo == null)
+ return true;
+
+ TranslationInfo info = (TranslationInfo)wrapper.translationInfo[obj];
+ return (info == null || info.Translated == true);
+ }
+
+ public virtual void SetTranslated (object obj, bool translated)
+ {
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ if (wrapper == null) return;
+
+ if (wrapper.translationInfo == null)
+ wrapper.translationInfo = new Hashtable ();
+
+ TranslationInfo info = (TranslationInfo)wrapper.translationInfo[obj];
+ if (info == null) {
+ info = new TranslationInfo ();
+ wrapper.translationInfo[obj] = info;
+ }
+
+ if (translated)
+ info.Translated = true;
+ else
+ info.Translated = false;
+ // We leave the old Context and Comment around, so that if
+ // you toggle Translated off and then back on, the old info
+ // is still there.
+ }
+
+ public virtual string TranslationContext (object obj)
+ {
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ if (wrapper == null || wrapper.translationInfo == null) return null;
+
+ TranslationInfo info = (TranslationInfo)wrapper.translationInfo[obj];
+ return info != null ? info.Context : null;
+ }
+
+ public virtual void SetTranslationContext (object obj, string context)
+ {
+ SetTranslated (obj, true);
+
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ if (wrapper == null) return;
+ ((TranslationInfo)wrapper.translationInfo[obj]).Context = context;
+ }
+
+ public virtual string TranslationComment (object obj)
+ {
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ if (wrapper == null || wrapper.translationInfo == null) return null;
+
+ TranslationInfo info = (TranslationInfo)wrapper.translationInfo[obj];
+ return info != null ? info.Comment : null;
+ }
+
+ public virtual void SetTranslationComment (object obj, string comment)
+ {
+ SetTranslated (obj, true);
+
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (obj);
+ if (wrapper == null) return;
+ ((TranslationInfo)wrapper.translationInfo[obj]).Comment = comment;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorAttribute.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorAttribute.cs
new file mode 100644
index 0000000000..05c2bb720b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorAttribute.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Stetic {
+
+ [AttributeUsage (AttributeTargets.Class)]
+ public sealed class PropertyEditorAttribute : Attribute {
+
+ public PropertyEditorAttribute (string property, string evt)
+ {
+ this.property = property;
+ this.evt = evt;
+ }
+
+ public PropertyEditorAttribute (string property) : this (property, property + "Changed") {}
+
+ string property;
+ public string Property {
+ get {
+ return property;
+ }
+ set {
+ property = value;
+ }
+ }
+
+ string evt;
+ public string Event {
+ get {
+ return evt;
+ }
+ set {
+ evt = value;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorCell.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorCell.cs
new file mode 100644
index 0000000000..faec75ffc3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/PropertyEditorCell.cs
@@ -0,0 +1,302 @@
+
+using System;
+using System.Collections;
+using Gtk;
+using Gdk;
+
+namespace Stetic
+{
+ public class PropertyEditorCell
+ {
+ Pango.Layout layout;
+ PropertyDescriptor property;
+ object obj;
+ Gtk.Widget container;
+
+ static Hashtable editors;
+ static PropertyEditorCell Default = new PropertyEditorCell ();
+ static Hashtable cellCache = new Hashtable ();
+
+ static PropertyEditorCell ()
+ {
+ editors = new Hashtable ();
+
+ editors[typeof (bool)] = typeof (Stetic.Editor.Boolean);
+ editors[typeof (byte)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (sbyte)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (short)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (ushort)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (int)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (uint)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (long)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (ulong)] = typeof (Stetic.Editor.IntRange);
+ editors[typeof (float)] = typeof (Stetic.Editor.FloatRange);
+ editors[typeof (double)] = typeof (Stetic.Editor.FloatRange);
+ editors[typeof (char)] = typeof (Stetic.Editor.Char);
+ editors[typeof (string)] = typeof (Stetic.Editor.TextEditor);
+ editors[typeof (DateTime)] = typeof (Stetic.Editor.DateTimeEditorCell);
+ editors[typeof (TimeSpan)] = typeof (Stetic.Editor.TimeSpanEditorCell);
+ editors[typeof (string[])] = typeof (Stetic.Editor.StringArray);
+ editors[typeof (Gdk.Color)] = typeof (Stetic.Editor.Color);
+ editors[typeof (Stetic.ImageInfo)] = typeof (Stetic.Editor.ImageSelector);
+ }
+
+ public object Instance {
+ get { return obj; }
+ }
+
+ public PropertyDescriptor Property {
+ get { return property; }
+ }
+
+ public Gtk.Widget Container {
+ get { return container; }
+ }
+
+ public void Initialize (Widget container, PropertyDescriptor property, object obj)
+ {
+ this.container = container;
+ layout = new Pango.Layout (container.PangoContext);
+ layout.Width = -1;
+
+ Pango.FontDescription des = container.Style.FontDescription.Copy();
+ layout.FontDescription = des;
+
+ this.property = property;
+ this.obj = obj;
+ Initialize ();
+ }
+
+ public EditSession StartEditing (Gdk.Rectangle cell_area, StateType state)
+ {
+ IPropertyEditor ed = CreateEditor (cell_area, state);
+ if (ed == null)
+ return null;
+ ed.Initialize (property);
+ if (obj != null) {
+ ed.AttachObject (obj);
+ ed.Value = property.GetValue (obj);
+ }
+ return new EditSession (container, obj, property, ed);
+ }
+
+ protected virtual string GetValueText ()
+ {
+ if (obj == null) return "";
+ object val = property.GetValue (obj);
+ if (val == null) return "";
+ else return property.ValueToString (val);
+ }
+
+ string GetNormalizedText ()
+ {
+ string s = GetValueText ();
+ if (s == null)
+ return "";
+
+ int i = s.IndexOf ('\n');
+ if (i == -1)
+ return s;
+
+ s = s.TrimStart ('\n',' ','\t');
+ i = s.IndexOf ('\n');
+ if (i != -1)
+ return s.Substring (0, i) + "...";
+ else
+ return s;
+ }
+
+ public object Value {
+ get { return obj != null ? property.GetValue (obj) : null; }
+ }
+
+ protected virtual void Initialize ()
+ {
+ layout.SetText (GetNormalizedText ());
+ }
+
+ public virtual void GetSize (int availableWidth, out int width, out int height)
+ {
+ layout.GetPixelSize (out width, out height);
+ }
+
+ public virtual void Render (Drawable window, Gdk.Rectangle bounds, StateType state)
+ {
+ int w, h;
+ layout.GetPixelSize (out w, out h);
+ int dy = (bounds.Height - h) / 2;
+ window.DrawLayout (container.Style.TextGC (state), bounds.X, dy + bounds.Y, layout);
+ }
+
+ protected virtual IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, StateType state)
+ {
+ Type editorType = property.EditorType;
+
+ if (editorType == null) {
+ editorType = GetEditorForType (property.PropertyType);
+ if (editorType == null)
+ return null;
+ }
+
+ IPropertyEditor editor = Activator.CreateInstance (editorType) as IPropertyEditor;
+ if (editor == null)
+ throw new Exception ("The property editor '" + editorType + "' must implement the interface IPropertyEditor");
+ return editor;
+ }
+
+ public static Type GetEditorForType (Type propertyType)
+ {
+ if (propertyType.IsEnum) {
+ if (propertyType.IsDefined (typeof (FlagsAttribute), true))
+ return typeof (Stetic.Editor.Flags);
+ else
+ return typeof (Stetic.Editor.Enumeration);
+ } else {
+ return editors [propertyType] as Type;
+ }
+ }
+
+ public static PropertyEditorCell GetPropertyCell (PropertyDescriptor property)
+ {
+ Type editorType = property.EditorType;
+
+ if (editorType == null)
+ editorType = GetEditorForType (property.PropertyType);
+
+ if (editorType == null)
+ return Default;
+
+ if (typeof(IPropertyEditor).IsAssignableFrom (editorType)) {
+ if (!typeof(Gtk.Widget).IsAssignableFrom (editorType))
+ throw new Exception ("The property editor '" + editorType + "' must be a Gtk Widget");
+ return Default;
+ }
+
+ PropertyEditorCell cell = (PropertyEditorCell) cellCache [editorType];
+ if (cell != null)
+ return cell;
+
+ if (!typeof(PropertyEditorCell).IsAssignableFrom (editorType))
+ throw new Exception ("The property editor '" + editorType + "' must be a subclass of Stetic.PropertyEditorCell or implement Stetic.IPropertyEditor");
+
+ cell = (PropertyEditorCell) Activator.CreateInstance (editorType);
+ cellCache [editorType] = cell;
+ return cell;
+ }
+ }
+
+
+ class DefaultPropertyEditor: Gtk.Entry, IPropertyEditor
+ {
+ PropertyDescriptor property;
+
+ public void Initialize (PropertyDescriptor property)
+ {
+ this.property = property;
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ public object Value {
+ get {
+ return Convert.ChangeType (Text, property.PropertyType);
+ }
+ set {
+ if (value == null)
+ Text = "";
+ else
+ Text = Convert.ToString (value);
+ }
+ }
+
+ protected override void OnChanged ()
+ {
+ base.OnChanged ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+
+ public class EditSession
+ {
+ PropertyDescriptor property;
+ object obj;
+ Gtk.Widget container;
+ IPropertyEditor currentEditor;
+ bool syncing;
+ object initialVal;
+
+ public EditSession (Gtk.Widget container, object instance, PropertyDescriptor property, IPropertyEditor currentEditor)
+ {
+ this.property = property;
+ this.obj = instance;
+ this.container = container;
+ this.currentEditor = currentEditor;
+ currentEditor.ValueChanged += OnValueChanged;
+ initialVal = currentEditor.Value;
+ }
+
+ public object Instance {
+ get { return obj; }
+ }
+
+ public PropertyDescriptor Property {
+ get { return property; }
+ }
+
+ public Gtk.Widget Container {
+ get { return container; }
+ }
+
+ public IPropertyEditor Editor {
+ get { return currentEditor; }
+ }
+
+ void OnValueChanged (object s, EventArgs a)
+ {
+ if (!syncing) {
+ syncing = true;
+ property.SetValue (obj, currentEditor.Value);
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (obj) as Stetic.Wrapper.Widget;
+ if (wrapper != null)
+ wrapper.NotifyChanged ();
+ syncing = false;
+ }
+ }
+
+ public void AttachObject (object ob)
+ {
+ if (ob == null)
+ throw new ArgumentNullException ("ob");
+
+ syncing = true;
+ this.obj = ob;
+ currentEditor.AttachObject (obj);
+
+ // It is the responsibility of the editor to convert value types
+ object initial = property.GetValue (obj);
+ currentEditor.Value = initial;
+
+ syncing = false;
+ }
+
+ public void UpdateEditor ()
+ {
+ if (!syncing) {
+ syncing = true;
+ currentEditor.Value = property.GetValue (obj);
+ syncing = false;
+ }
+ }
+
+ public void Dispose ()
+ {
+ if (!object.Equals (initialVal, currentEditor.Value))
+ OnValueChanged (null, null);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/RadioGroupManager.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/RadioGroupManager.cs
new file mode 100644
index 0000000000..73c8fb8f69
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/RadioGroupManager.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.CodeDom;
+
+// The stetic representation of "radio widget" (Gtk.RadioButton,
+// Gtk.RadioToolButton, and Gtk.RadioMenuItem) groups is that the
+// groups have names, and each widget's "Group" property stores the
+// name of its group. The glade representation is similar, except that
+// the group names aren't arbitrary; they have to be the name of the
+// first widget in the group. (On disk, the "group leader" has no
+// "group" property, and the other widgets have the leader's name as
+// their group property.)
+//
+// The internal gtk representation of groups is that each radio widget
+// has a GLib.SList "Group" property. The content of the list is
+// essentially opaque. (For Gtk.RadioButton, the list contains all of
+// the RadioButtons in the group. But for Gtk.ToolRadioButton it
+// contains pointers to internal widgets, not the ToolRadioButtons
+// themselves.) The only thing we can do with them then is to read one
+// widget's group and then immediately assign it to another widget. We
+// can't look into the list, or assume that a widget's Group property
+// will keep the same value if any other widget's Group changes.
+//
+// Each radio widget type wrapper class keeps a static
+// RadioGroupManager to handle this string<->GLib.SList translation
+// for it.
+
+namespace Stetic {
+
+ public class RadioGroup {
+ public string Name;
+ public ArrayList Widgets;
+
+ public RadioGroup (string name)
+ {
+ Name = name;
+ Widgets = new ArrayList ();
+ }
+ }
+
+ public class RadioGroupManager: IRadioGroupManager
+ {
+ PropertyInfo groupProperty;
+ ArrayList groups;
+ Hashtable widgets;
+
+ public RadioGroupManager (Type widgetType)
+ {
+ groupProperty = widgetType.GetProperty ("Group");
+ if (groupProperty == null || groupProperty.PropertyType != typeof (GLib.SList))
+ throw new ArgumentException ("No 'public GLib.SList Group' property on '" + widgetType.FullName + "'");
+
+ groups = new ArrayList ();
+ widgets = new Hashtable ();
+ }
+
+ public event GroupsChangedDelegate GroupsChanged;
+
+ void EmitGroupsChanged ()
+ {
+ if (GroupsChanged != null)
+ GroupsChanged ();
+ }
+
+ public IEnumerable GroupNames {
+ get {
+ string[] names = new string[groups.Count];
+ for (int i = 0; i < groups.Count; i++)
+ names[i] = ((RadioGroup)groups[i]).Name;
+ return names;
+ }
+ }
+
+ public string LastGroup {
+ get {
+ if (groups.Count == 0)
+ Add ("group1");
+ RadioGroup group = groups[groups.Count - 1] as RadioGroup;
+ return group.Name;
+ }
+ }
+
+ public RadioGroup FindGroup (string name)
+ {
+ for (int i = 0; i < groups.Count; i++) {
+ RadioGroup group = groups[i] as RadioGroup;
+ if (group.Name == name)
+ return group;
+ }
+ return null;
+ }
+
+ void IRadioGroupManager.Add (string name)
+ {
+ Add (name);
+ }
+
+ public RadioGroup Add (string name)
+ {
+ RadioGroup group = new RadioGroup (name);
+ groups.Add (group);
+ EmitGroupsChanged ();
+ return group;
+ }
+
+ public void Rename (string oldName, string newName)
+ {
+ RadioGroup group = FindGroup (oldName);
+ if (group != null) {
+ group.Name = newName;
+ EmitGroupsChanged ();
+ }
+ }
+
+ void RadioDestroyed (object obj, EventArgs args)
+ {
+ Gtk.Widget radio = obj as Gtk.Widget;
+ this[radio] = null;
+ }
+
+ public string this[Gtk.Widget radio] {
+ get {
+ RadioGroup group = widgets[radio] as RadioGroup;
+ if (group != null)
+ return group.Name;
+ else
+ return null;
+ }
+ set {
+ GLib.SList group_value;
+
+ RadioGroup oldGroup = widgets[radio] as RadioGroup;
+ if (oldGroup == null) {
+ radio.Destroyed += RadioDestroyed;
+ } else {
+ if (oldGroup.Name == value)
+ return;
+ oldGroup.Widgets.Remove (radio);
+ if (oldGroup.Widgets.Count == 0) {
+ groups.Remove (oldGroup);
+ EmitGroupsChanged ();
+ }
+ }
+
+ if (value == null) {
+ radio.Destroyed -= RadioDestroyed;
+ groupProperty.SetValue (radio, new GLib.SList (IntPtr.Zero), null);
+ widgets.Remove (radio);
+ return;
+ }
+
+ RadioGroup newGroup = FindGroup (value);
+ if (newGroup == null)
+ newGroup = Add (value);
+
+ if (newGroup.Widgets.Count == 0)
+ group_value = new GLib.SList (IntPtr.Zero);
+ else
+ group_value = (GLib.SList)groupProperty.GetValue (newGroup.Widgets[0], null);
+
+ groupProperty.SetValue (radio, group_value, null);
+ newGroup.Widgets.Add (radio);
+ widgets[radio] = newGroup;
+ }
+ }
+
+ public string GladeGroupName (Gtk.Widget radio)
+ {
+ RadioGroup group = widgets[radio] as RadioGroup;
+ if (group == null || group.Widgets.Count == 0)
+ return null;
+
+ Gtk.Widget leader = (Gtk.Widget)group.Widgets[0];
+ return leader.Name;
+ }
+
+ public CodeExpression GenerateGroupExpression (GeneratorContext ctx, Gtk.Widget widget)
+ {
+ // Returns and expression that represents the group to which the radio belongs.
+ // This expression can be an empty SList, if this is the first radio of the
+ // group that has been generated, or an SList taken from previously generated
+ // radios from the same group.
+
+ RadioGroup group = widgets[widget] as RadioGroup;
+ CodeExpression var = null;
+
+ foreach (Gtk.Widget radio in group.Widgets) {
+ if (radio == widget)
+ continue;
+ var = ctx.WidgetMap.GetWidgetExp (radio);
+ if (var != null)
+ break;
+ }
+
+ if (var == null) {
+ return new CodeObjectCreateExpression (
+ "GLib.SList".ToGlobalTypeRef (),
+ new CodePropertyReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(IntPtr), CodeTypeReferenceOptions.GlobalReference)),
+ "Zero"
+ )
+ );
+ } else {
+ return new CodePropertyReferenceExpression (
+ var,
+ "Group"
+ );
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/Registry.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Registry.cs
new file mode 100644
index 0000000000..3316a524eb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Registry.cs
@@ -0,0 +1,370 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+using System.Xml.Xsl;
+
+namespace Stetic {
+ public static class Registry {
+
+ static ArrayList libraries = new ArrayList ();
+ static ArrayList classes = new ArrayList ();
+
+ static XslTransform gladeImport, gladeExport;
+ static WidgetLibrary coreLib;
+ static WidgetLibrary coreLib2;
+
+ public static event EventHandler RegistryChanging;
+ public static event EventHandler RegistryChanged;
+
+ static int changing;
+ static bool changed;
+
+ public static void Initialize (WidgetLibrary coreLibrary)
+ {
+ RegisterWidgetLibrary (coreLibrary);
+
+ coreLib = coreLibrary;
+
+ }
+
+ public static WidgetLibrary CoreWidgetLibrary {
+ get { return coreLib; }
+ }
+
+ public static WidgetLibrary CoreWidgetLibrary2 {
+ get { return coreLib2; }
+ }
+
+ public static void BeginChangeSet ()
+ {
+ if (changing == 0)
+ changed = false;
+ changing++;
+ }
+
+ public static void EndChangeSet ()
+ {
+ if (--changing == 0) {
+ if (changed) {
+ foreach (WidgetLibrary lib in libraries)
+ lib.Flush ();
+ NotifyChanged ();
+ }
+ changed = false;
+ }
+ }
+
+ public static void RegisterWidgetLibrary (WidgetLibrary library)
+ {
+ NotifyChanging ();
+
+ try {
+ if (coreLib != null && library.Name == coreLib.Name) {
+ libraries.Remove (coreLib);
+ InternalUpdate ();
+ coreLib = library;
+ }
+ libraries.Add (library);
+ library.Load ();
+ classes.AddRange (library.AllClasses);
+ UpdateGladeTransform ();
+ } catch (Exception ex) {
+ Console.WriteLine (ex);
+ throw;
+ } finally {
+ NotifyChanged ();
+ }
+ }
+
+ public static void UnregisterWidgetLibrary (WidgetLibrary library)
+ {
+ if (library == coreLib)
+ return;
+
+ NotifyChanging ();
+
+ libraries.Remove (library);
+ library.Dispose ();
+ InternalUpdate ();
+
+ NotifyChanged ();
+ }
+
+
+ // Returns true if all libraries that need reloading
+ // could be reloaded
+
+ public static bool ReloadWidgetLibraries ()
+ {
+ bool needsReload = false;
+
+ // If there is a lib which can't be reloaded,
+ // there is no need to start the reloading process
+
+ foreach (WidgetLibrary lib in libraries) {
+ if (lib != coreLib && lib.NeedsReload) {
+ if (!lib.CanReload)
+ return false;
+ needsReload = true;
+ }
+ }
+
+ if (!needsReload)
+ return true;
+
+ try {
+ NotifyChanging ();
+
+ foreach (WidgetLibrary lib in libraries)
+ if (lib != coreLib && lib.NeedsReload)
+ lib.Reload ();
+
+ InternalUpdate ();
+ } finally {
+ NotifyChanged ();
+ }
+
+ return true;
+ }
+
+ public static bool IsRegistered (WidgetLibrary library)
+ {
+ return libraries.Contains (library);
+ }
+
+ public static WidgetLibrary GetWidgetLibrary (string name)
+ {
+ foreach (WidgetLibrary lib in libraries)
+ if (lib.Name == name)
+ return lib;
+ return null;
+ }
+
+ public static bool IsRegistered (string name)
+ {
+ foreach (WidgetLibrary lib in libraries)
+ if (lib.Name == name)
+ return true;
+ return false;
+ }
+
+ public static WidgetLibrary[] RegisteredWidgetLibraries {
+ get { return (WidgetLibrary[]) libraries.ToArray (typeof(WidgetLibrary)); }
+ }
+
+ static void NotifyChanging ()
+ {
+ if (changing > 0) {
+ if (changed)
+ return;
+ else
+ changed = true;
+ }
+ if (RegistryChanging != null)
+ RegistryChanging (null, EventArgs.Empty);
+ }
+
+ static void NotifyChanged ()
+ {
+ if (changing == 0 && RegistryChanged != null)
+ RegistryChanged (null, EventArgs.Empty);
+ }
+
+ static void InternalUpdate ()
+ {
+ classes.Clear ();
+ foreach (WidgetLibrary lib in libraries)
+ classes.AddRange (lib.AllClasses);
+ UpdateGladeTransform ();
+ }
+
+ static void UpdateGladeTransform ()
+ {
+ XmlDocument doc = CreateGladeTransformBase ();
+ XmlNamespaceManager nsm = new XmlNamespaceManager (doc.NameTable);
+ nsm.AddNamespace ("xsl", "http://www.w3.org/1999/XSL/Transform");
+
+ foreach (WidgetLibrary lib in libraries) {
+ foreach (XmlElement elem in lib.GetGladeImportTransformElements ())
+ doc.FirstChild.PrependChild (doc.ImportNode (elem, true));
+ }
+
+ gladeImport = new XslTransform ();
+ gladeImport.Load (doc, null, null);
+
+ doc = CreateGladeTransformBase ();
+
+ foreach (WidgetLibrary lib in libraries) {
+ foreach (XmlElement elem in lib.GetGladeExportTransformElements ())
+ doc.FirstChild.PrependChild (doc.ImportNode (elem, true));
+ }
+
+ gladeExport = new XslTransform ();
+ gladeExport.Load (doc, null, null);
+ }
+
+ static XmlDocument CreateGladeTransformBase ()
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml (
+ "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" +
+ " <xsl:template match='@*|node()'>" +
+ " <xsl:copy>" +
+ " <xsl:apply-templates select='@*|node()' />" +
+ " </xsl:copy>" +
+ " </xsl:template>" +
+ "</xsl:stylesheet>"
+ );
+ return doc;
+ }
+
+ public static IEnumerable AllClasses {
+ get {
+ return classes;
+ }
+ }
+
+ public static XslTransform GladeImportXsl {
+ get {
+ return gladeImport;
+ }
+ }
+
+ public static XslTransform GladeExportXsl {
+ get {
+ return gladeExport;
+ }
+ }
+
+ public static EnumDescriptor LookupEnum (string typeName)
+ {
+ foreach (WidgetLibrary lib in libraries) {
+ EnumDescriptor desc = lib.LookupEnum (typeName);
+ if (desc != null)
+ return desc;
+ }
+ return null;
+ }
+
+ public static ClassDescriptor LookupClassByCName (string cname)
+ {
+ foreach (WidgetLibrary lib in libraries) {
+ ClassDescriptor desc = lib.LookupClassByCName (cname);
+ if (desc != null)
+ return desc;
+ }
+ return null;
+ }
+
+ public static ClassDescriptor LookupClassByName (string cname)
+ {
+ foreach (WidgetLibrary lib in libraries) {
+ ClassDescriptor desc = lib.LookupClassByName (cname);
+ if (desc != null)
+ return desc;
+ }
+ return null;
+ }
+
+ static ClassDescriptor FindGroupClass (string name, out string groupname)
+ {
+ int sep = name.LastIndexOf ('.');
+ string classname = name.Substring (0, sep);
+ groupname = name.Substring (sep + 1);
+ ClassDescriptor klass = LookupClassByName (classname);
+ if (klass == null) {
+ klass = LookupClassByName (name);
+ if (klass == null)
+ throw new ArgumentException ("No class for itemgroup " + name);
+ classname = name;
+ groupname = "";
+ }
+ return klass;
+ }
+
+ public static ItemGroup LookupItemGroup (string name)
+ {
+ string groupname;
+ ClassDescriptor klass = FindGroupClass (name, out groupname);
+
+ foreach (ItemGroup grp in klass.ItemGroups)
+ if (grp.Name == groupname && grp.DeclaringType == klass)
+ return grp;
+
+ throw new ArgumentException ("No itemgroup '" + groupname + "' in class " + klass.WrappedTypeName);
+ }
+
+ public static ItemGroup LookupSignalGroup (string name)
+ {
+ string groupname;
+ ClassDescriptor klass = FindGroupClass (name, out groupname);
+
+ foreach (ItemGroup grp in klass.SignalGroups)
+ if (grp.Name == groupname && grp.DeclaringType == klass)
+ return grp;
+ throw new ArgumentException ("No itemgroup '" + groupname + "' in class " + klass.WrappedTypeName);
+ }
+
+ public static ItemDescriptor LookupItem (string name)
+ {
+ int sep = name.LastIndexOf ('.');
+ string classname = name.Substring (0, sep);
+ string propname = name.Substring (sep + 1);
+ ClassDescriptor klass = LookupClassByName (classname);
+ if (klass == null)
+ throw new ArgumentException ("No class " + classname + " for property " + propname);
+ ItemDescriptor idesc = klass[propname];
+ if (idesc == null)
+ throw new ArgumentException ("Property '" + propname + "' not found in class '" + classname + "'");
+ return idesc;
+ }
+
+ public static ItemGroup LookupContextMenu (string classname)
+ {
+ ClassDescriptor klass = LookupClassByName (classname);
+ if (klass == null)
+ throw new ArgumentException ("No class for contextmenu " + classname);
+ return klass.ContextMenu;
+ }
+
+ public static object NewInstance (string typeName, IProject proj)
+ {
+ return LookupClassByName (typeName).NewInstance (proj);
+ }
+
+ public static Type GetType (string typeName, bool throwOnError)
+ {
+ Type t = Type.GetType (typeName, false);
+ if (t != null) return t;
+
+ foreach (WidgetLibrary lib in libraries) {
+ t = lib.GetType (typeName);
+ if (t != null) return t;
+ }
+
+ string tname, aname;
+ int i = typeName.IndexOf (',');
+ if (i != -1) {
+ tname = typeName.Substring (0, i).Trim ();
+ aname = typeName.Substring (i + 1).Trim ();
+ }
+ else {
+ tname = typeName;
+ aname = null;
+ }
+ foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ()) {
+ if (aname == null || asm.GetName ().Name == aname) {
+ t = asm.GetType (tname);
+ if (t != null)
+ return t;
+ }
+ }
+
+ if (throwOnError)
+ throw new TypeLoadException ("Could not load type '" + typeName + "'");
+
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/Set.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Set.cs
new file mode 100644
index 0000000000..58f0b26b0b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/Set.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections;
+
+namespace Stetic {
+
+ public class Set : IEnumerable, IEnumerator {
+
+ Hashtable hash = new Hashtable ();
+
+ public bool this [object obj] {
+ get {
+ return hash[obj] != null;
+ }
+ set {
+ if (value)
+ hash[obj] = obj;
+ else
+ hash.Remove (obj);
+ }
+ }
+
+ public void Clear ()
+ {
+ hash.Clear ();
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return this;
+ }
+
+ IDictionaryEnumerator hashEnum;
+
+ public void Reset ()
+ {
+ hashEnum = hash.GetEnumerator ();
+ hashEnum.Reset ();
+ }
+
+ public bool MoveNext ()
+ {
+ return hashEnum.MoveNext ();
+ }
+
+ public object Current {
+ get {
+ return hashEnum.Key;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/SignalDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/SignalDescriptor.cs
new file mode 100644
index 0000000000..871364d67b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/SignalDescriptor.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Reflection;
+using System.Xml;
+
+namespace Stetic
+{
+ [Serializable]
+ public abstract class SignalDescriptor: ItemDescriptor
+ {
+ protected string name, label, description;
+ protected string handlerTypeName;
+ protected string handlerReturnTypeName;
+ protected ParameterDescriptor[] handlerParameters;
+
+ public SignalDescriptor (XmlElement elem, ItemGroup group, ClassDescriptor klass) : base (elem, group, klass)
+ {
+ }
+
+ protected virtual void Load (XmlElement elem)
+ {
+ name = elem.GetAttribute ("name");
+ label = elem.GetAttribute ("label");
+ description = elem.GetAttribute ("description");
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public string Label {
+ get { return label; }
+ }
+
+ public string Description {
+ get { return description; }
+ }
+
+ public string HandlerTypeName {
+ get { return handlerTypeName; }
+ }
+
+ public string HandlerReturnTypeName {
+ get { return handlerReturnTypeName; }
+ }
+
+ public ParameterDescriptor[] HandlerParameters {
+ get { return handlerParameters; }
+ }
+ }
+
+ [Serializable]
+ public class ParameterDescriptor
+ {
+ string name, type;
+
+ public ParameterDescriptor (string name, string type)
+ {
+ this.name = name;
+ this.type = type;
+ }
+
+ public string Name {
+ get { return name; }
+ }
+
+ public string TypeName {
+ get { return type; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelDialog.cs
new file mode 100644
index 0000000000..04f066e507
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelDialog.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Gtk;
+
+namespace Stetic
+{
+ public class TopLevelDialog: TopLevelWindow
+ {
+ HButtonBox buttonBox;
+ VBox vbox;
+ HSeparator separator;
+
+ public TopLevelDialog ( )
+ {
+ vbox = new VBox ();
+ separator = new HSeparator ();
+ buttonBox = new HButtonBox ();
+ vbox.PackEnd (buttonBox, false, false, 0);
+ vbox.PackEnd (separator, false, false, 0);
+ vbox.ShowAll ();
+ Add (vbox);
+ }
+
+ public HButtonBox ActionArea {
+ get { return buttonBox; }
+ }
+
+ public VBox VBox {
+ get { return vbox; }
+ }
+
+ public bool HasSeparator
+ {
+ get { return separator.Visible; }
+ set { separator.Visible = value; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelWindow.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelWindow.cs
new file mode 100644
index 0000000000..3e3cdc694a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TopLevelWindow.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Stetic
+{
+ public class TopLevelWindow: Gtk.EventBox
+ {
+ string title;
+ Gdk.WindowTypeHint typeHint;
+ bool modal;
+ bool resizable = true;
+
+ public event EventHandler PropertyChanged;
+
+ public string Title {
+ get { return title; }
+ set {
+ title = value;
+ NotifyChange ();
+ }
+ }
+
+ public Gdk.WindowTypeHint TypeHint {
+ get { return typeHint; }
+ set {
+ typeHint = value;
+ NotifyChange ();
+ }
+ }
+
+ public bool Modal {
+ get { return modal; }
+ set
+ {
+ modal = value;
+ NotifyChange ();
+ }
+ }
+
+ public bool Resizable
+ {
+ get { return resizable; }
+ set
+ {
+ resizable = value;
+ NotifyChange ();
+ }
+ }
+
+ void NotifyChange ( )
+ {
+ if (PropertyChanged != null)
+ PropertyChanged (this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/TranslatableAttribute.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TranslatableAttribute.cs
new file mode 100644
index 0000000000..2b938420e6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TranslatableAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace Stetic {
+
+ [AttributeUsage (AttributeTargets.Property | AttributeTargets.Field)]
+ public sealed class TranslatableAttribute : Attribute {
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedClassDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedClassDescriptor.cs
new file mode 100644
index 0000000000..dbf7c6d5af
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedClassDescriptor.cs
@@ -0,0 +1,221 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Xml;
+
+namespace Stetic
+{
+ public class TypedClassDescriptor: ClassDescriptor
+ {
+ Type wrapped, wrapper;
+ GLib.GType gtype;
+
+ MethodInfo ctorMethodInfo;
+ MethodInfo ctorMethodInfoWithClass;
+ ConstructorInfo cinfo;
+ ConstructorInfo cinfoNoParams;
+ bool useGTypeCtor;
+ Gdk.Pixbuf icon;
+ bool defaultValuesLoaded;
+
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ static Gdk.Pixbuf missingIcon;
+
+ public TypedClassDescriptor (Assembly assembly, XmlElement elem)
+ {
+ bool inheritedWrapper = false;
+
+ wrapped = Registry.GetType (elem.GetAttribute ("type"), true);
+ if (wrapped != null) {
+ ConstructorInfo[] cInfos = wrapped.GetConstructors();
+ foreach (ConstructorInfo ci in cInfos) {
+ if (ci.GetParameters().Length == 0) {
+ cinfoNoParams = ci;
+ break;
+ }
+ }
+ }
+
+ if (elem.HasAttribute ("wrapper"))
+ wrapper = Registry.GetType (elem.GetAttribute ("wrapper"), true);
+ else {
+ inheritedWrapper = true;
+ string baseClass = elem.GetAttribute ("base-type");
+ if (baseClass.Length > 0) {
+ // If a base type is specified, use the wrapper of that base type
+ TypedClassDescriptor parent = Registry.LookupClassByName (baseClass) as TypedClassDescriptor;
+ if (parent != null)
+ wrapper = parent.WrapperType;
+ }
+ else {
+ for (Type type = wrapped.BaseType; type != null; type = type.BaseType) {
+ TypedClassDescriptor parent = Registry.LookupClassByName (type.FullName) as TypedClassDescriptor;
+ if (parent != null) {
+ wrapper = parent.WrapperType;
+ break;
+ }
+ }
+ }
+ if (wrapper == null)
+ throw new ArgumentException (string.Format ("No wrapper type for class {0}", wrapped.FullName));
+ }
+
+ gtype = (GLib.GType)wrapped;
+ cname = gtype.ToString ();
+
+ string iconname = elem.GetAttribute ("icon");
+ if (iconname.Length > 0) {
+ try {
+ // Using the pixbuf resource constructor generates a gdk warning.
+ Gdk.PixbufLoader loader = new Gdk.PixbufLoader (assembly, iconname);
+ icon = loader.Pixbuf;
+ } catch {
+ Console.WriteLine ("Could not load icon: " + iconname);
+ icon = GetDefaultIcon ();
+ }
+ } else
+ icon = GetDefaultIcon ();
+
+ BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
+
+ // If the wrapper is inherited from a base class, ignore the CreateInstance method
+ // since it is going to create an instance of the base class.
+ if (!inheritedWrapper) {
+ ctorMethodInfoWithClass = wrapper.GetMethod ("CreateInstance", flags, null, new Type[] { typeof(ClassDescriptor)}, null);
+ if (ctorMethodInfoWithClass == null) {
+ ctorMethodInfo = wrapper.GetMethod ("CreateInstance", flags, null, Type.EmptyTypes, null);
+ }
+ }
+
+ // Look for a constructor even if a CreateInstance method was
+ // found, since it may return null.
+ cinfo = wrapped.GetConstructor (Type.EmptyTypes);
+ if (cinfo == null) {
+ useGTypeCtor = true;
+ cinfo = wrapped.GetConstructor (new Type[] { typeof (IntPtr) });
+ }
+
+ Load (elem);
+ }
+
+ public override Gdk.Pixbuf Icon {
+ get {
+ return icon;
+ }
+ }
+
+ public override string WrappedTypeName {
+ get { return WrappedType.FullName; }
+ }
+
+ public Type WrapperType {
+ get {
+ return wrapper;
+ }
+ }
+
+ public Type WrappedType {
+ get {
+ return wrapped;
+ }
+ }
+
+ public GLib.GType GType {
+ get {
+ return gtype;
+ }
+ }
+
+ public override ObjectWrapper CreateWrapper ()
+ {
+ return (ObjectWrapper) Activator.CreateInstance (WrapperType);
+ }
+
+ [DllImport("libgobject-2.0-0.dll")]
+ static extern IntPtr g_object_new (IntPtr gtype, IntPtr dummy);
+
+ public override object CreateInstance (IProject proj)
+ {
+ object inst;
+
+
+ if (ctorMethodInfoWithClass != null) {
+ inst = ctorMethodInfoWithClass.Invoke (null, new object[] { this });
+ if (inst != null) return inst;
+ }
+ if (ctorMethodInfo != null) {
+ inst = ctorMethodInfo.Invoke (null, new object[0]);
+ if (inst != null) return inst;
+ }
+
+ if (cinfoNoParams != null) {
+ inst = cinfoNoParams.Invoke (null, null);
+ if (inst != null) return inst;
+ }
+
+
+ if (cinfo == null)
+ throw new InvalidOperationException ("The class '" + wrapped + "' does not have a default constructor.");
+
+ if (!useGTypeCtor)
+ inst = cinfo.Invoke (new object[0]);
+ else {
+ IntPtr raw = g_object_new (gtype.Val, IntPtr.Zero);
+ inst = cinfo.Invoke (new object[] { raw });
+ }
+
+ return inst;
+ }
+
+ internal protected override ItemDescriptor CreateItemDescriptor (XmlElement elem, ItemGroup group)
+ {
+ if (elem.Name == "property")
+ return new TypedPropertyDescriptor (elem, group, this);
+ else if (elem.Name == "signal")
+ return new TypedSignalDescriptor (elem, group, this);
+ else
+ return base.CreateItemDescriptor (elem, group);
+ }
+
+ Gdk.Pixbuf GetDefaultIcon ()
+ {
+ if (missingIcon == null)
+ missingIcon = WidgetUtils.MissingIcon;
+ return missingIcon;
+ }
+
+ internal void LoadDefaultValues ()
+ {
+ // This is a hack because there is no managed way of getting
+ // the default value of a GObject property.
+ // This method creates an dummy instance of this class and
+ // gets the values for their properties. Those values are
+ // considered the default
+
+ if (defaultValuesLoaded)
+ return;
+ defaultValuesLoaded = true;
+
+ object ob = NewInstance (null, false);
+
+ foreach (ItemGroup group in ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ TypedPropertyDescriptor prop = item as TypedPropertyDescriptor;
+ if (prop == null)
+ continue;
+
+ if (!prop.HasDefault) {
+ prop.SetDefault (null);
+ } else {
+ object val = prop.GetValue (ob);
+ prop.SetDefault (val);
+ }
+ }
+ }
+ ObjectWrapper ww = ObjectWrapper.Lookup (ob);
+ ww.Dispose ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedPropertyDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedPropertyDescriptor.cs
new file mode 100644
index 0000000000..5be86a0ad6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedPropertyDescriptor.cs
@@ -0,0 +1,321 @@
+using System;
+using System.ComponentModel;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+
+namespace Stetic
+{
+ public class TypedPropertyDescriptor : PropertyDescriptor {
+
+ PropertyInfo memberInfo, propertyInfo, runtimePropertyInfo, runtimeMemberInfo;
+ ParamSpec pspec;
+ TypedPropertyDescriptor gladeProperty;
+ bool isWrapperProperty;
+ TypedClassDescriptor klass;
+ bool defaultSet;
+
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ public TypedPropertyDescriptor (XmlElement elem, ItemGroup group, TypedClassDescriptor klass) : base (elem, group, klass)
+ {
+ this.klass = klass;
+ string propertyName = elem.GetAttribute ("name");
+ int dot = propertyName.IndexOf ('.');
+
+ if (dot != -1) {
+ // Sub-property (eg, "Alignment.Value")
+ memberInfo = FindProperty (klass.WrapperType, klass.WrappedType, propertyName.Substring (0, dot));
+ isWrapperProperty = memberInfo.DeclaringType.IsSubclassOf (typeof (ObjectWrapper));
+ gladeProperty = new TypedPropertyDescriptor (isWrapperProperty ? klass.WrapperType : klass.WrappedType, memberInfo.Name);
+ propertyInfo = FindProperty (memberInfo.PropertyType, propertyName.Substring (dot + 1));
+ } else {
+ // Basic simple property
+ propertyInfo = FindProperty (klass.WrapperType, klass.WrappedType, propertyName);
+ isWrapperProperty = propertyInfo.DeclaringType.IsSubclassOf (typeof (ObjectWrapper));
+ }
+
+ // Wrapper properties that override widgets properties (using the same name)
+ // must be considered runtime properties (will be available at run-time).
+ if (!isWrapperProperty || klass.WrappedType.GetProperty (propertyName) != null)
+ isRuntimeProperty = true;
+
+ if (!IsInternal && propertyInfo.PropertyType.IsEnum &&
+ Registry.LookupEnum (propertyInfo.PropertyType.FullName) == null)
+ throw new ArgumentException ("No EnumDescriptor for " + propertyInfo.PropertyType.FullName + "(" + klass.WrappedType.FullName + "." + propertyName + ")");
+
+ pspec = FindPSpec (propertyInfo);
+
+ if (isWrapperProperty && pspec == null) {
+ PropertyInfo pinfo = klass.WrappedType.GetProperty (propertyInfo.Name, flags);
+ if (pinfo != null)
+ pspec = FindPSpec (pinfo);
+ }
+
+ if (pspec != null) {
+ // This information will be overridden by what's specified in the xml file
+ description = pspec.Blurb;
+ minimum = pspec.Minimum;
+ maximum = pspec.Maximum;
+ label = propertyName;
+ if (!elem.HasAttribute ("ignore-default"))
+ hasDefault = Type.GetTypeCode (PropertyType) != TypeCode.Object || PropertyType.IsEnum;
+ } else {
+ label = propertyInfo.Name;
+ gladeOverride = true;
+ }
+
+ string typeName = elem.GetAttribute ("editor");
+ if (typeName.Length > 0)
+ editorType = Registry.GetType (typeName, false);
+
+ // Look for a default value attribute
+
+ object[] ats = propertyInfo.GetCustomAttributes (typeof(DefaultValueAttribute), true);
+ if (ats.Length > 0) {
+ DefaultValueAttribute at = (DefaultValueAttribute) ats [0];
+ defaultValue = at.Value;
+ }
+
+ // Load default data
+ Load (elem);
+ }
+
+ TypedPropertyDescriptor (Type objectType, string propertyName)
+ {
+ propertyInfo = FindProperty (objectType, propertyName);
+ isWrapperProperty = false;
+
+ pspec = FindPSpec (propertyInfo);
+ if (pspec != null) {
+ label = propertyName;
+ description = pspec.Blurb;
+ minimum = pspec.Minimum;
+ maximum = pspec.Maximum;
+ hasDefault = Type.GetTypeCode (PropertyType) != TypeCode.Object || PropertyType.IsEnum;
+ } else
+ label = propertyInfo.Name;
+ }
+
+ static PropertyInfo FindProperty (Type type, string propertyName) {
+ return FindProperty (null, type, propertyName);
+ }
+
+ static PropertyInfo FindProperty (Type wrapperType, Type objectType, string propertyName)
+ {
+ PropertyInfo info = null;
+
+ if (wrapperType != null) {
+ info = wrapperType.GetProperty (propertyName, flags);
+ if (info != null)
+ return info;
+ }
+
+ try {
+ info = objectType.GetProperty (propertyName, flags);
+ }
+ catch (AmbiguousMatchException) {
+ foreach (PropertyInfo pi in objectType.GetProperties ()) {
+ if (pi.Name == propertyName) {
+ info = pi;
+ break;
+ }
+ }
+ }
+
+ if (info != null)
+ return info;
+
+ throw new ArgumentException ("Invalid property name " + objectType.Name + "." + propertyName);
+ }
+
+ ParamSpec FindPSpec (PropertyInfo pinfo)
+ {
+ foreach (object attr in pinfo.GetCustomAttributes (false)) {
+ if (attr is GLib.PropertyAttribute) {
+ GLib.PropertyAttribute pattr = (GLib.PropertyAttribute)attr;
+ return ParamSpec.LookupObjectProperty (pinfo.DeclaringType, pattr.Name);
+ }
+
+ if (attr is Gtk.ChildPropertyAttribute) {
+ Gtk.ChildPropertyAttribute cpattr = (Gtk.ChildPropertyAttribute)attr;
+ return ParamSpec.LookupChildProperty (pinfo.DeclaringType.DeclaringType, cpattr.Name);
+ }
+ }
+ return null;
+ }
+
+ // The property's internal name
+ public override string Name {
+ get {
+ return propertyInfo.Name;
+ }
+ }
+
+ // The property's type
+ public override Type PropertyType {
+ get {
+ return propertyInfo.PropertyType;
+ }
+ }
+
+ // The property's PropertyInfo
+ public PropertyInfo PropertyInfo {
+ get {
+ return propertyInfo;
+ }
+ }
+
+ // The property's ParamSpec
+ public virtual ParamSpec ParamSpec {
+ get {
+ return pspec;
+ }
+ }
+
+ public override bool IsDefaultValue (object value)
+ {
+ if (defaultValue != null)
+ return base.IsDefaultValue (value);
+ if (ParamSpec != null && value != null)
+ return ParamSpec.IsDefaultValue (value);
+ else
+ return false;
+ }
+
+ public override void ResetValue (object instance)
+ {
+ // This is a hack because there is no managed way of getting
+ // the default value of a GObject property. The call to LoadDefaultValues
+ // will guess the default values from a dummy instance
+ if (!defaultSet) {
+ ObjectWrapper ww = ObjectWrapper.Lookup (instance);
+ TypedClassDescriptor td = ww.ClassDescriptor as TypedClassDescriptor;
+ if (td != null)
+ td.LoadDefaultValues ();
+ defaultSet = true;
+ }
+ base.ResetValue (instance);
+ }
+
+ internal void SetDefault (object val)
+ {
+ defaultValue = val;
+ defaultSet = true;
+ }
+
+ // Gets the value of the property on @obj
+ public override object GetValue (object obj)
+ {
+ try {
+ if (isWrapperProperty)
+ obj = ObjectWrapper.Lookup (obj);
+ if (memberInfo != null)
+ obj = memberInfo.GetValue (obj, null);
+ return propertyInfo.GetValue (obj, null);
+ } catch (Exception ex) {
+ throw new InvalidOperationException ("Could not get value for property " + klass.Name + "." + Name + " from object '" + obj + "'", ex);
+ }
+ }
+
+ // Whether or not the property is writable
+ public override bool CanWrite {
+ get {
+ return propertyInfo.CanWrite;
+ }
+ }
+
+ // Sets the value of the property on @obj
+ public override void SetValue (object obj, object value)
+ {
+ ObjectWrapper ww = ObjectWrapper.Lookup (obj);
+ IDisposable t = ww != null && !ww.Loading? ww.UndoManager.AtomicChange : null;
+ try {
+ if (isWrapperProperty)
+ obj = ww;
+ if (memberInfo != null)
+ obj = memberInfo.GetValue (obj, null);
+ propertyInfo.SetValue (obj, value, null);
+ } catch (Exception ex) {
+ throw new InvalidOperationException ("Could not set value for property " + klass.Name + "." + Name + " to object '" + obj + "'", ex);
+ } finally {
+ if (t != null)
+ t.Dispose ();
+ }
+ }
+
+ // The property's type at run time
+ public override Type RuntimePropertyType {
+ get {
+ if (runtimePropertyInfo == null)
+ SetupRuntimeProperties ();
+ return runtimePropertyInfo.PropertyType;
+ }
+ }
+
+ public override void SetRuntimeValue (object obj, object value)
+ {
+ if (runtimePropertyInfo == null)
+ SetupRuntimeProperties ();
+ if (runtimeMemberInfo != null)
+ obj = runtimeMemberInfo.GetValue (obj, null);
+
+ if (runtimePropertyInfo.PropertyType.IsInstanceOfType (value))
+ runtimePropertyInfo.SetValue (obj, value, null);
+ }
+
+ public override object GetRuntimeValue (object obj)
+ {
+ if (runtimePropertyInfo == null)
+ SetupRuntimeProperties ();
+ if (runtimeMemberInfo != null)
+ obj = runtimeMemberInfo.GetValue (obj, null);
+ return runtimePropertyInfo.GetValue (obj, null);
+ }
+
+ void SetupRuntimeProperties ()
+ {
+ if (isWrapperProperty) {
+ Type t = klass.WrappedType;
+ if (memberInfo != null) {
+ runtimeMemberInfo = t.GetProperty (memberInfo.Name, flags);
+ t = runtimeMemberInfo.PropertyType;
+ }
+ runtimePropertyInfo = t.GetProperty (propertyInfo.Name, flags);
+ } else {
+ runtimeMemberInfo = memberInfo;
+ runtimePropertyInfo = propertyInfo;
+ }
+ }
+
+ public virtual bool GladeOverride {
+ get {
+ return gladeOverride;
+ }
+ }
+
+ public TypedPropertyDescriptor GladeProperty {
+ get {
+ if (gladeProperty != null)
+ return gladeProperty;
+ else
+ return this;
+ }
+ }
+
+ public virtual string GladeName {
+ get {
+ if (gladeName != null)
+ return gladeName;
+ else if (pspec != null && pspec.Name != null)
+ return pspec.Name.Replace ('-', '_');
+ else
+ return null;
+ }
+ }
+
+ public override string InternalChildId {
+ get { return GladeName; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedSignalDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedSignalDescriptor.cs
new file mode 100644
index 0000000000..5c87947dee
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/TypedSignalDescriptor.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Reflection;
+using System.Xml;
+
+namespace Stetic
+{
+ [Serializable]
+ public class TypedSignalDescriptor: SignalDescriptor
+ {
+ string gladeName;
+
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ public TypedSignalDescriptor (XmlElement elem, ItemGroup group, TypedClassDescriptor klass) : base (elem, group, klass)
+ {
+ Load (elem);
+
+ EventInfo eventInfo = FindEvent (klass.WrapperType, klass.WrappedType, name);
+ MethodInfo handler = eventInfo.EventHandlerType.GetMethod ("Invoke");
+
+ if (elem.HasAttribute ("glade-name"))
+ gladeName = elem.GetAttribute ("glade-name");
+ else {
+ object[] att = eventInfo.GetCustomAttributes (typeof(GLib.SignalAttribute), true);
+ if (att.Length > 0)
+ gladeName = ((GLib.SignalAttribute)att[0]).CName;
+ }
+
+ handlerTypeName = eventInfo.EventHandlerType.FullName;
+ handlerReturnTypeName = handler.ReturnType.FullName;
+
+ ParameterInfo[] pars = handler.GetParameters ();
+ handlerParameters = new ParameterDescriptor [pars.Length];
+ for (int n=0; n<pars.Length; n++)
+ handlerParameters [n] = new ParameterDescriptor (pars[n].Name, pars [n].ParameterType.FullName);
+ }
+
+ public string GladeName {
+ get { return gladeName; }
+ }
+
+ static EventInfo FindEvent (Type wrapperType, Type objectType, string name)
+ {
+ EventInfo info;
+
+ if (wrapperType != null) {
+ info = wrapperType.GetEvent (name, flags);
+ if (info != null)
+ return info;
+ }
+
+ info = objectType.GetEvent (name, flags);
+ if (info != null)
+ return info;
+
+ throw new ArgumentException ("Invalid event name " + objectType.Name + "." + name);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetLibrary.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetLibrary.cs
new file mode 100644
index 0000000000..b35c376382
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetLibrary.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Collections;
+using System.Xml;
+
+namespace Stetic
+{
+ public abstract class WidgetLibrary: IDisposable
+ {
+ Hashtable classes_by_cname = new Hashtable ();
+ Hashtable classes_by_csname = new Hashtable ();
+ Hashtable enums = new Hashtable ();
+ string targetGtkVersion;
+
+ XmlElement[] importElems = new XmlElement [0];
+ XmlElement[] exportElems = new XmlElement [0];
+
+ public event EventHandler Changed;
+
+ public abstract string Name { get; }
+
+ public virtual bool NeedsReload {
+ get { return false; }
+ }
+
+ public virtual bool CanReload {
+ get { return false; }
+ }
+
+ // Returns true if it is possible to generate code using this widget library.
+ // Not all widget libraries can generate code. For example, when a widget
+ // depends on a wrapper class, and the wrapper class can't be loaded in memory,
+ // then it is not possible to generate code.
+ public virtual bool CanGenerateCode {
+ get { return true; }
+ }
+
+ public virtual string[] GetLibraryDependencies ()
+ {
+ return new string [0];
+ }
+
+ public string TargetGtkVersion {
+ get { return targetGtkVersion != null && targetGtkVersion.Length > 0 ? targetGtkVersion : "2.4"; }
+ }
+
+ public bool SupportsGtkVersion (string targetVersion)
+ {
+ return WidgetUtils.CompareVersions (TargetGtkVersion, targetVersion) >= 0;
+ }
+
+ public virtual void Reload ()
+ {
+ Load ();
+ }
+
+ public virtual void Load ()
+ {
+ }
+
+ protected virtual void Load (XmlDocument objects)
+ {
+ classes_by_cname.Clear ();
+ classes_by_csname.Clear ();
+ enums.Clear ();
+
+ if (objects == null || objects.DocumentElement == null)
+ return;
+
+ targetGtkVersion = objects.DocumentElement.GetAttribute ("gtk-version");
+ if (targetGtkVersion.Length == 0)
+ targetGtkVersion = "2.4";
+
+ foreach (XmlElement element in objects.SelectNodes ("/objects/enum")) {
+ EnumDescriptor enm = new EnumDescriptor (element);
+ enums[enm.Name] = enm;
+ }
+
+ foreach (XmlElement element in objects.SelectNodes ("/objects/object"))
+ AddClass (LoadClassDescriptor (element));
+
+ XmlNamespaceManager nsm = new XmlNamespaceManager (objects.NameTable);
+ nsm.AddNamespace ("xsl", "http://www.w3.org/1999/XSL/Transform");
+
+ XmlNodeList nodes = objects.SelectNodes ("/objects/object/glade-transform/import/xsl:*", nsm);
+ importElems = new XmlElement [nodes.Count];
+ for (int n=0; n<nodes.Count; n++)
+ importElems [n] = (XmlElement) nodes[n];
+
+ nodes = objects.SelectNodes ("/objects/object/glade-transform/export/xsl:*", nsm);
+ exportElems = new XmlElement [nodes.Count];
+ for (int n=0; n<nodes.Count; n++)
+ exportElems [n] = (XmlElement) nodes[n];
+ }
+
+ protected void AddClass (ClassDescriptor klass)
+ {
+ if (klass == null)
+ return;
+ klass.SetLibrary (this);
+ classes_by_cname[klass.CName] = klass;
+ classes_by_csname[klass.WrappedTypeName] = klass;
+ }
+
+ public virtual void Dispose ()
+ {
+ }
+
+ // Flush is called by the registry to free cached data stored in the widget library.
+ public virtual void Flush ()
+ {
+ }
+
+ protected abstract ClassDescriptor LoadClassDescriptor (XmlElement element);
+
+
+ public virtual XmlElement[] GetGladeImportTransformElements ()
+ {
+ return importElems;
+ }
+
+ public virtual XmlElement[] GetGladeExportTransformElements ()
+ {
+ return exportElems;
+ }
+
+ public virtual ICollection AllClasses {
+ get {
+ return classes_by_csname.Values;
+ }
+ }
+
+ public virtual EnumDescriptor LookupEnum (string typeName)
+ {
+ return (EnumDescriptor)enums[typeName];
+ }
+
+ public virtual ClassDescriptor LookupClassByCName (string cname)
+ {
+ return (ClassDescriptor)classes_by_cname[cname];
+ }
+
+ public virtual ClassDescriptor LookupClassByName (string csname)
+ {
+ return (ClassDescriptor)classes_by_csname[csname];
+ }
+
+ public virtual Type GetType (string typeName)
+ {
+ return null;
+ }
+
+ public virtual System.IO.Stream GetResource (string name)
+ {
+ return null;
+ }
+
+ protected virtual void OnChanged ()
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetUtils.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetUtils.cs
new file mode 100644
index 0000000000..e97b352f49
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/WidgetUtils.cs
@@ -0,0 +1,393 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Collections;
+using System.Xml;
+using Stetic.Wrapper;
+
+namespace Stetic
+{
+ public static class WidgetUtils
+ {
+ static Gdk.Atom steticAtom;
+ static int undoIdCount;
+ static Gdk.Pixbuf missingIcon;
+ static Gtk.Widget renderer;
+
+ public static Gdk.Atom ApplicationXSteticAtom {
+ get {
+ if (steticAtom == null)
+ steticAtom = Gdk.Atom.Intern ("application/x-stetic", false);
+ return steticAtom;
+ }
+ }
+
+ public static XmlElement ExportWidget (Gtk.Widget widget)
+ {
+ XmlDocument doc = new XmlDocument ();
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+ if (wrapper == null)
+ throw new InvalidOperationException ();
+
+ XmlElement elem = wrapper.Write (new ObjectWriter (doc, FileFormat.Native));
+ doc.AppendChild (elem);
+ return doc.DocumentElement;
+ }
+
+ public static Gtk.Widget ImportWidget (IProject project, XmlElement element)
+ {
+ ObjectReader reader = new ObjectReader (project, FileFormat.Native);
+ ObjectWrapper wrapper = Stetic.ObjectWrapper.ReadObject (reader, element, null);
+ return wrapper.Wrapped as Gtk.Widget;
+ }
+
+ public static XmlElement Write (ObjectWrapper wrapper, XmlDocument doc)
+ {
+ ClassDescriptor klass = wrapper.ClassDescriptor;
+
+ XmlElement elem = doc.CreateElement ("widget");
+ elem.SetAttribute ("class", klass.Name);
+ elem.SetAttribute ("id", ((Gtk.Widget)wrapper.Wrapped).Name);
+
+ GetProps (wrapper, elem);
+ GetSignals (wrapper, elem);
+ return elem;
+ }
+
+ public static void GetProps (ObjectWrapper wrapper, XmlElement parent_elem)
+ {
+ ClassDescriptor klass = wrapper.ClassDescriptor;
+
+ foreach (ItemGroup group in klass.ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ PropertyDescriptor prop = item as PropertyDescriptor;
+ if (prop == null)
+ continue;
+ if (!prop.VisibleFor (wrapper.Wrapped) || !prop.CanWrite || prop.Name == "Name") // Name is written in the id attribute
+ continue;
+
+ object value = prop.GetValue (wrapper.Wrapped);
+
+ // If the property has its default value, we don't need to write it
+ if (value == null || (prop.HasDefault && prop.IsDefaultValue (value)))
+ continue;
+
+ string val = prop.ValueToString (value);
+ if (val == null)
+ continue;
+
+ XmlElement prop_elem = parent_elem.OwnerDocument.CreateElement ("property");
+ prop_elem.SetAttribute ("name", prop.Name);
+ if (val.Length > 0)
+ prop_elem.InnerText = val;
+
+ if (prop.Translatable && prop.IsTranslated (wrapper.Wrapped)) {
+ prop_elem.SetAttribute ("translatable", "yes");
+ string tcx = prop.TranslationContext (wrapper.Wrapped);
+ if (tcx != null && tcx.Length > 0) {
+ prop_elem.SetAttribute ("context", "yes");
+ prop_elem.InnerText = tcx + "|" + prop_elem.InnerText;
+ }
+ string tcm = prop.TranslationComment (wrapper.Wrapped);
+ if (tcm != null && tcm.Length > 0)
+ prop_elem.SetAttribute ("comments", prop.TranslationComment (wrapper.Wrapped));
+ }
+
+ parent_elem.AppendChild (prop_elem);
+ }
+ }
+ }
+
+ public static void GetSignals (ObjectWrapper ob, XmlElement parent_elem)
+ {
+ foreach (Signal signal in ob.Signals) {
+ if (!signal.SignalDescriptor.VisibleFor (ob.Wrapped))
+ continue;
+
+ XmlElement signal_elem = parent_elem.OwnerDocument.CreateElement ("signal");
+ signal_elem.SetAttribute ("name", signal.SignalDescriptor.Name);
+ signal_elem.SetAttribute ("handler", signal.Handler);
+ if (signal.After)
+ signal_elem.SetAttribute ("after", "yes");
+ parent_elem.AppendChild (signal_elem);
+ }
+ }
+
+ static public void Read (ObjectWrapper wrapper, XmlElement elem)
+ {
+ string className = elem.GetAttribute ("class");
+ if (className == null)
+ throw new GladeException ("<widget> node with no class name");
+
+ ClassDescriptor klass = Registry.LookupClassByName (className);
+ if (klass == null)
+ throw new GladeException ("No stetic ClassDescriptor for " + className);
+
+ Gtk.Widget widget = (Gtk.Widget) wrapper.Wrapped;
+ if (widget == null) {
+ widget = (Gtk.Widget) klass.CreateInstance (wrapper.Project);
+ //set name before binding to ensure
+ //that ObjectWrapper.RootWrapperName will be valid
+ widget.Name = elem.GetAttribute ("id");
+ ObjectWrapper.Bind (wrapper.Project, klass, wrapper, widget, true);
+ } else {
+ widget.Name = elem.GetAttribute ("id");
+ }
+
+ ReadMembers (klass, wrapper, widget, elem);
+
+ if (!(widget is Gtk.Window))
+ widget.ShowAll ();
+ }
+
+ public static void ReadMembers (ClassDescriptor klass, ObjectWrapper wrapper, object wrapped, XmlElement elem)
+ {
+ foreach (XmlNode node in elem.ChildNodes) {
+ XmlElement child = node as XmlElement;
+ if (child == null)
+ continue;
+
+ if (child.LocalName == "signal")
+ ReadSignal (klass, wrapper, child);
+ else if (child.LocalName == "property")
+ ReadProperty (klass, wrapper, wrapped, child);
+ }
+ }
+
+ public static void ReadSignal (ClassDescriptor klass, ObjectWrapper ob, XmlElement elem)
+ {
+ string name = elem.GetAttribute ("name");
+ SignalDescriptor signal = klass.SignalGroups.GetItem (name) as SignalDescriptor;
+ if (signal != null) {
+ string handler = elem.GetAttribute ("handler");
+ bool after = elem.GetAttribute ("after") == "yes";
+ ob.Signals.Add (new Signal (signal, handler, after));
+ }
+ }
+
+ public static void ReadProperty (ClassDescriptor klass, ObjectWrapper wrapper, object wrapped, XmlElement prop_node)
+ {
+ string name = prop_node.GetAttribute ("name");
+ PropertyDescriptor prop = klass [name] as PropertyDescriptor;
+ if (prop == null || !prop.CanWrite)
+ return;
+
+ string strval = prop_node.InnerText;
+
+ // Skip translation context
+ if (prop_node.GetAttribute ("context") == "yes" && strval.IndexOf ('|') != -1)
+ strval = strval.Substring (strval.IndexOf ('|') + 1);
+
+ object value = prop.StringToValue (strval);
+ prop.SetValue (wrapped, value);
+
+ if (prop.Translatable) {
+ if (prop_node.GetAttribute ("translatable") != "yes") {
+ prop.SetTranslated (wrapped, false);
+ }
+ else {
+ prop.SetTranslated (wrapped, true);
+ if (prop_node.GetAttribute ("context") == "yes") {
+ strval = prop_node.InnerText;
+ int bar = strval.IndexOf ('|');
+ if (bar != -1)
+ prop.SetTranslationContext (wrapped, strval.Substring (0, bar));
+ }
+
+ if (prop_node.HasAttribute ("comments"))
+ prop.SetTranslationComment (wrapped, prop_node.GetAttribute ("comments"));
+ }
+ }
+ }
+
+ static public void SetPacking (Stetic.Wrapper.Container.ContainerChild wrapper, XmlElement child_elem)
+ {
+ XmlElement packing = child_elem["packing"];
+ if (packing == null)
+ return;
+
+ Gtk.Container.ContainerChild cc = wrapper.Wrapped as Gtk.Container.ContainerChild;
+ ClassDescriptor klass = wrapper.ClassDescriptor;
+ ReadMembers (klass, wrapper, cc, packing);
+ }
+
+ internal static XmlElement CreatePacking (XmlDocument doc, Stetic.Wrapper.Container.ContainerChild childwrapper)
+ {
+ XmlElement packing_elem = doc.CreateElement ("packing");
+ WidgetUtils.GetProps (childwrapper, packing_elem);
+ return packing_elem;
+ }
+
+ public static void Copy (Gtk.Widget widget, Gtk.SelectionData seldata, bool copyAsText)
+ {
+ XmlElement elem = ExportWidget (widget);
+ if (elem == null)
+ return;
+
+ if (copyAsText)
+ seldata.Text = elem.OuterXml;
+ else
+ seldata.Set (ApplicationXSteticAtom, 8, System.Text.Encoding.UTF8.GetBytes (elem.OuterXml));
+ }
+
+ public static Stetic.Wrapper.Widget Paste (IProject project, Gtk.SelectionData seldata)
+ {
+ if (seldata == null || seldata.Type == null || seldata.Type.Name != ApplicationXSteticAtom.Name)
+ return null;
+
+ string data = System.Text.Encoding.UTF8.GetString (seldata.Data);
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+ try {
+ doc.LoadXml (data);
+ } catch {
+ return null;
+ }
+
+ Gtk.Widget w = ImportWidget (project, doc.DocumentElement);
+ return Wrapper.Widget.Lookup (w);
+ }
+
+ public static IDesignArea GetDesignArea (Gtk.Widget w)
+ {
+ while (w != null && !(w is IDesignArea))
+ w = w.Parent;
+ return w as IDesignArea;
+ }
+
+ internal static void ParseWidgetName (string name, out string baseName, out int idx)
+ {
+ // Extract a numerical suffix from the name
+ // If suffix has more than 4 digits, only the last 4 digits are considered
+ // a numerical suffix.
+
+ int n;
+ for (n = name.Length - 1; n >= name.Length-4 && n >= 0 && char.IsDigit (name [n]); n--)
+ ;
+
+ if (n < name.Length - 1) {
+ baseName = name.Substring (0, n + 1);
+ idx = int.Parse (name.Substring (n + 1));
+ } else {
+ baseName = name;
+ idx = 0;
+ }
+ }
+
+ internal static string GetUndoId ()
+ {
+ return (undoIdCount++).ToString ();
+ }
+
+ public static Gdk.Pixbuf MissingIcon {
+ get {
+ if (missingIcon == null) {
+ try {
+ missingIcon = Gtk.IconTheme.Default.LoadIcon ("gtk-missing-image", 16, 0);
+ } catch {}
+ if (missingIcon == null) {
+ try {
+ missingIcon = Gdk.Pixbuf.LoadFromResource ("missing.png");
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf 'missing.png': " + e);
+ }
+ }
+ }
+ return missingIcon;
+ }
+ }
+
+ public static string AbsoluteToRelativePath (string baseDirectoryPath, string absPath)
+ {
+ if (! Path.IsPathRooted (absPath))
+ return absPath;
+
+ absPath = Path.GetFullPath (absPath);
+ baseDirectoryPath = Path.GetFullPath (baseDirectoryPath);
+
+ char[] separators = { Path.DirectorySeparatorChar, Path.VolumeSeparatorChar, Path.AltDirectorySeparatorChar };
+ baseDirectoryPath = baseDirectoryPath.TrimEnd (separators);
+ string[] bPath = baseDirectoryPath.Split (separators);
+ string[] aPath = absPath.Split (separators);
+ int indx = 0;
+ for(; indx < Math.Min(bPath.Length, aPath.Length); ++indx){
+ if(!bPath[indx].Equals(aPath[indx]))
+ break;
+ }
+
+ if (indx == 0) {
+ return absPath;
+ }
+
+ string erg = "";
+
+ if(indx == bPath.Length) {
+ erg += "." + Path.DirectorySeparatorChar;
+ } else {
+ for (int i = indx; i < bPath.Length; ++i) {
+ erg += ".." + Path.DirectorySeparatorChar;
+ }
+ }
+ erg += String.Join(Path.DirectorySeparatorChar.ToString(), aPath, indx, aPath.Length-indx);
+
+ return erg;
+ }
+
+ public static int CompareVersions (string v1, string v2)
+ {
+ string[] a1 = v1.Split ('.');
+ string[] a2 = v2.Split ('.');
+
+ for (int n=0; n<a1.Length; n++) {
+ if (n >= a2.Length)
+ return -1;
+ if (a1[n].Length == 0) {
+ if (a2[n].Length != 0)
+ return 1;
+ continue;
+ }
+ try {
+ int n1 = int.Parse (a1[n]);
+ int n2 = int.Parse (a2[n]);
+ if (n1 < n2)
+ return 1;
+ else if (n1 > n2)
+ return -1;
+ } catch {
+ return 1;
+ }
+ }
+ if (a2.Length > a1.Length)
+ return 1;
+ return 0;
+ }
+
+ public static Gdk.Pixbuf LoadIcon (string name, Gtk.IconSize size)
+ {
+ if (renderer == null)
+ renderer = new Gtk.HBox ();
+ Gdk.Pixbuf image = renderer.RenderIcon (name, size, null);
+ if (image != null)
+ return image;
+
+ int w, h;
+ Gtk.Icon.SizeLookup (size, out w, out h);
+ try {
+ return Gtk.IconTheme.Default.LoadIcon (name, w, 0);
+ } catch {
+ // Icon not in theme
+ return MissingIcon;
+ }
+ }
+
+ public static System.CodeDom.CodeTypeReference ToGlobalTypeRef (this Type type)
+ {
+ return new System.CodeDom.CodeTypeReference (type, System.CodeDom.CodeTypeReferenceOptions.GlobalReference);
+ }
+
+ public static System.CodeDom.CodeTypeReference ToGlobalTypeRef (this string type)
+ {
+ return new System.CodeDom.CodeTypeReference (type, System.CodeDom.CodeTypeReferenceOptions.GlobalReference);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/bin/Release/libstetic2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libstetic/bin/Release/libstetic2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/bin/Release/libstetic2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Accelerator.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Accelerator.cs
new file mode 100644
index 0000000000..f6f884848d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Accelerator.cs
@@ -0,0 +1,196 @@
+using System;
+using System.Runtime.InteropServices;
+using Mono.Unix;
+
+namespace Stetic.Editor {
+
+ [PropertyEditor ("Accel", "AccelChanged")]
+ public class Accelerator : Gtk.HBox, IPropertyEditor {
+
+ uint keyval;
+ Gdk.ModifierType mask;
+ bool editing;
+
+ Gtk.Button clearButton;
+ Gtk.Entry entry;
+
+ public const Gdk.ModifierType AcceleratorModifierMask = ~(
+ Gdk.ModifierType.Button1Mask |
+ Gdk.ModifierType.Button2Mask |
+ Gdk.ModifierType.Button3Mask |
+ Gdk.ModifierType.Button4Mask |
+ Gdk.ModifierType.Button5Mask);
+
+ public Accelerator ()
+ {
+ entry = new Gtk.Entry ();
+ clearButton = new Gtk.Button (new Gtk.Image (Gtk.Stock.Clear, Gtk.IconSize.Menu));
+ PackStart (entry, true, true, 0);
+ PackStart (clearButton, false, false, 3);
+ clearButton.Clicked += delegate (object s, EventArgs args) {
+ Value = null;
+ };
+ entry.IsEditable = false;
+ entry.ButtonPressEvent += OnButtonPressEvent;
+ entry.KeyPressEvent += OnKeyPressEvent;
+ ShowAll ();
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(string))
+ throw new ApplicationException ("Accelerator editor does not support editing values of type " + descriptor.PropertyType);
+ }
+
+ public void AttachObject (object obj)
+ {
+ Value = null;
+ }
+
+ [GLib.ConnectBefore]
+ void OnButtonPressEvent (object s, Gtk.ButtonPressEventArgs args)
+ {
+ if (editing)
+ Ungrab (args.Event.Time);
+ else
+ Grab (args.Event.Window, args.Event.Time);
+ args.RetVal = true;
+ }
+
+ GrabDialog grabWindow;
+
+ void Ungrab (uint time)
+ {
+ if (!editing)
+ return;
+ editing = false;
+
+ if (Value != null)
+ entry.Text = (string) Value;
+ else
+ entry.Text = "";
+
+ grabWindow.Destroy ();
+ }
+
+ void Grab (Gdk.Window window, uint time)
+ {
+ if (editing)
+ return;
+
+ grabWindow = new GrabDialog ();
+ editing = true;
+ entry.Text = Catalog.GetString ("Press a key...");
+ grabWindow.TransientFor = this.Toplevel as Gtk.Window;
+ grabWindow.Run ();
+ this.keyval = grabWindow.Keyval;
+ this.mask = grabWindow.Mask;
+ Ungrab (time);
+ EmitAccelChanged ();
+ }
+
+ [GLib.ConnectBefore]
+ void OnKeyPressEvent (object s, Gtk.KeyPressEventArgs args)
+ {
+ Gdk.EventKey evt = args.Event;
+
+ if (!editing || !Gtk.Accelerator.Valid (evt.KeyValue, evt.State))
+ return;
+
+ uint keyval;
+ int effectiveGroup, level;
+ Gdk.ModifierType consumedMods, mask;
+
+ // We know this will succeed, since we're already here...
+ Gdk.Keymap.Default.TranslateKeyboardState (evt.HardwareKeycode, evt.State, evt.Group, out keyval, out effectiveGroup, out level, out consumedMods);
+ mask = evt.State & AcceleratorModifierMask & ~consumedMods;
+
+ if (evt.Key != Gdk.Key.Escape || mask != 0) {
+ this.keyval = keyval;
+ this.mask = mask;
+ }
+
+ clearButton.Sensitive = true;
+
+ Ungrab (evt.Time);
+ EmitAccelChanged ();
+ args.RetVal = true;
+ }
+
+ public object Value {
+ get {
+ if (keyval != 0)
+ return Gtk.Accelerator.Name (keyval, mask);
+ else
+ return null;
+ }
+ set {
+ string s = value as string;
+ if (s == null) {
+ keyval = 0;
+ mask = 0;
+ clearButton.Sensitive = false;
+ } else {
+ Gtk.Accelerator.Parse (s, out keyval, out mask);
+ clearButton.Sensitive = true;
+ }
+ if (Value != null)
+ entry.Text = (string) Value;
+ else
+ entry.Text = "";
+ EmitAccelChanged ();
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ void EmitAccelChanged ()
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+
+ class GrabDialog: Gtk.Dialog
+ {
+ public uint Keyval;
+ public Gdk.ModifierType Mask;
+
+ public GrabDialog ()
+ {
+ Decorated = false;
+ this.SkipPagerHint = true;
+ this.SkipTaskbarHint = true;
+ this.WindowPosition = Gtk.WindowPosition.CenterOnParent;
+ Gtk.Frame f = new Gtk.Frame ();
+ f.Shadow = Gtk.ShadowType.Out;
+ this.VBox.PackStart (f, true, true, 0);
+ Gtk.Label lab = new Gtk.Label (Catalog.GetString ("Press the key combination you want to assign to the accelerator..."));
+ lab.Xpad = 12;
+ lab.Ypad = 12;
+ f.Add (lab);
+ ShowAll ();
+ }
+
+ protected override bool OnKeyPressEvent (Gdk.EventKey evt)
+ {
+ uint keyval;
+ int effectiveGroup, level;
+ Gdk.ModifierType consumedMods, mask;
+
+ if (!Gtk.Accelerator.Valid (evt.KeyValue, evt.State))
+ return base.OnKeyPressEvent (evt);
+
+ // We know this will succeed, since we're already here...
+ Gdk.Keymap.Default.TranslateKeyboardState (evt.HardwareKeycode, evt.State, evt.Group, out keyval, out effectiveGroup, out level, out consumedMods);
+ mask = evt.State & Accelerator.AcceleratorModifierMask & ~consumedMods;
+
+ if (evt.Key != Gdk.Key.Escape || mask != 0) {
+ Keyval = keyval;
+ Mask = mask;
+ this.Respond (0);
+ }
+ return false;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionGroupEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionGroupEditor.cs
new file mode 100644
index 0000000000..d5de903948
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionGroupEditor.cs
@@ -0,0 +1,577 @@
+
+using System;
+using System.Collections;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class ActionGroupEditor: Gtk.EventBox, IMenuItemContainer
+ {
+ ActionGroup actionGroup;
+ Gtk.Table table;
+ IProject project;
+ ArrayList items = new ArrayList ();
+ Gtk.EventBox emptyLabel;
+ EditableLabel headerLabel;
+ uint columns = 2;
+ bool modified;
+ bool disposed;
+ ObjectWrapperEventHandler changedEvent;
+ IDesignArea darea;
+
+ public EventHandler GroupModified;
+ public EventHandler SelectionChanged;
+
+ public ActionGroupEditor ()
+ {
+ changedEvent = new ObjectWrapperEventHandler (OnActionChanged);
+
+ Gtk.Fixed fx = new Gtk.Fixed ();
+ table = new Gtk.Table (0, 0, false);
+ table.RowSpacing = 8;
+ table.ColumnSpacing = 8;
+ table.BorderWidth = 12;
+
+ Gtk.EventBox ebox = new Gtk.EventBox ();
+ ebox.ModifyBg (Gtk.StateType.Normal, this.Style.Backgrounds [0]);
+ headerLabel = new EditableLabel ();
+ headerLabel.MarkupTemplate = "<b>$TEXT</b>";
+ headerLabel.Changed += OnGroupNameChanged;
+ Gtk.VBox vbox = new Gtk.VBox ();
+ Gtk.Label grpLabel = new Gtk.Label ();
+ grpLabel.Xalign = 0;
+ grpLabel.Markup = "<small><i>Action Group</i></small>";
+// vbox.PackStart (grpLabel, false, false, 0);
+ vbox.PackStart (headerLabel, false, false, 3);
+ vbox.BorderWidth = 12;
+ ebox.Add (vbox);
+
+ Gtk.VBox box = new Gtk.VBox ();
+ box.Spacing = 6;
+ box.PackStart (ebox, false, false, 0);
+ box.PackStart (table, false, false, 0);
+
+ fx.Put (box, 0, 0);
+ Add (fx);
+ ShowAll ();
+ }
+
+ public override void Dispose ()
+ {
+ if (disposed)
+ return;
+ disposed = true;
+ headerLabel.Changed -= OnGroupNameChanged;
+ if (emptyLabel != null)
+ emptyLabel.ButtonPressEvent -= OnAddClicked;
+
+ foreach (ActionMenuItem aitem in items) {
+ aitem.KeyPressEvent -= OnItemKeyPress;
+ aitem.Node.Dispose ();
+ aitem.Detach ();
+ aitem.Destroy ();
+ }
+ items.Clear ();
+ ActionGroup = null;
+ project = null;
+ headerLabel = null;
+
+ if (darea != null) {
+ darea.SelectionChanged -= OnSelectionChanged;
+ darea = null;
+ }
+
+ base.Dispose ();
+ }
+
+ public ActionGroup ActionGroup {
+ get { return actionGroup; }
+ set {
+ if (actionGroup != null) {
+ actionGroup.ObjectChanged -= OnGroupChanged;
+ actionGroup.ActionAdded -= OnActionAdded;
+ actionGroup.ActionRemoved -= OnActionRemoved;
+ foreach (Wrapper.Action a in actionGroup.Actions)
+ a.ObjectChanged -= changedEvent;
+ }
+ actionGroup = value;
+ if (actionGroup != null) {
+ headerLabel.Text = actionGroup.Name;
+ actionGroup.ObjectChanged += OnGroupChanged;
+ actionGroup.ActionAdded += OnActionAdded;
+ actionGroup.ActionRemoved += OnActionRemoved;
+ foreach (Wrapper.Action a in actionGroup.Actions)
+ a.ObjectChanged += changedEvent;
+ }
+ if (!disposed)
+ Fill ();
+ }
+ }
+
+ public IProject Project {
+ get { return project; }
+ set { project = value; }
+ }
+
+ public bool Modified {
+ get { return modified; }
+ set { modified = value; }
+ }
+
+ public Wrapper.Action SelectedAction {
+ get {
+ IDesignArea designArea = GetDesignArea ();
+ IObjectSelection sel = designArea.GetSelection ();
+ if (sel != null)
+ return ObjectWrapper.Lookup (sel.DataObject) as Wrapper.Action;
+ else
+ return null;
+ }
+ set {
+ foreach (ActionMenuItem item in items) {
+ if (item.Node.Action == value)
+ item.Select ();
+ }
+ }
+ }
+
+ ActionMenuItem SelectedActionMenuItem {
+ get {
+ IDesignArea designArea = GetDesignArea ();
+ IObjectSelection sel = designArea.GetSelection ();
+ if (sel != null)
+ return sel.Widget as ActionMenuItem;
+ else
+ return null;
+ }
+ }
+
+ public void StartEditing ()
+ {
+ IDesignArea designArea = GetDesignArea ();
+ designArea.SetSelection (headerLabel, null);
+ headerLabel.StartEditing ();
+ }
+
+ void Fill ()
+ {
+ IDesignArea designArea = GetDesignArea ();
+ if (designArea == null)
+ return;
+
+ Wrapper.Action selAction = null;
+
+ foreach (ActionMenuItem item in items) {
+ if (designArea.IsSelected (item))
+ selAction = item.Node.Action;
+ item.Node.Dispose ();
+ item.Detach ();
+ item.Destroy ();
+ }
+ items.Clear ();
+
+ if (actionGroup != null) {
+ Wrapper.Action[] sortedActions = new Wrapper.Action [actionGroup.Actions.Count];
+ actionGroup.Actions.CopyTo (sortedActions, 0);
+ Array.Sort (sortedActions, new ActionComparer ());
+ for (int n = 0; n < sortedActions.Length; n++) {
+ Wrapper.Action action = (Wrapper.Action) sortedActions [n];
+ ActionMenuItem item = InsertAction (action, n);
+ if (selAction == action)
+ item.Select ();
+ }
+
+ if (selAction == null)
+ designArea.SetSelection (null, null);
+
+ headerLabel.Sensitive = true;
+ PlaceAddLabel (actionGroup.Actions.Count);
+ } else {
+ HideAddLabel ();
+ headerLabel.Text = Catalog.GetString ("No selection");
+ headerLabel.Sensitive = false;
+ }
+ ShowAll ();
+ }
+
+ ActionMenuItem InsertAction (Wrapper.Action action, int n)
+ {
+ uint row = (uint) n / columns;
+ uint col = (uint) (n % columns) * 3;
+
+ IDesignArea designArea = GetDesignArea ();
+ ActionTreeNode node = new ActionTreeNode (Gtk.UIManagerItemType.Menuitem, "", action);
+ ActionMenuItem aitem = new ActionMenuItem (designArea, project, this, node);
+ aitem.KeyPressEvent += OnItemKeyPress;
+ aitem.MinWidth = 150;
+ aitem.Attach (table, row, col);
+
+ Gtk.Frame fr = new Gtk.Frame ();
+ fr.Shadow = Gtk.ShadowType.Out;
+ aitem.Add (fr);
+
+ items.Add (aitem);
+ return aitem;
+ }
+
+ void PlaceAddLabel (int n)
+ {
+ HideAddLabel ();
+
+ uint r = (uint) n / columns;
+ uint c = (uint) (n % columns) * 3;
+
+ emptyLabel = new Gtk.EventBox ();
+ emptyLabel.VisibleWindow = false;
+ Gtk.Label label = new Gtk.Label ();
+ label.Xalign = 0;
+ label.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("Click to create action") + "</span></i>";
+ emptyLabel.Add (label);
+ emptyLabel.ButtonPressEvent += OnAddClicked;
+ table.Attach (emptyLabel, c, c+3, r, r+1);
+ }
+
+ void HideAddLabel ()
+ {
+ if (emptyLabel != null) {
+ table.Remove (emptyLabel);
+ emptyLabel.ButtonPressEvent -= OnAddClicked;
+ }
+ emptyLabel = null;
+ }
+
+ void OnGroupChanged (object s, ObjectWrapperEventArgs args)
+ {
+ headerLabel.Text = actionGroup.Name;
+ NotifyModified ();
+ }
+
+ void OnActionAdded (object s, ActionEventArgs args)
+ {
+ args.Action.ObjectChanged += changedEvent;
+ Fill ();
+ NotifyModified ();
+ }
+
+ void OnActionRemoved (object s, ActionEventArgs args)
+ {
+ args.Action.ObjectChanged -= changedEvent;
+ Fill ();
+ NotifyModified ();
+ }
+
+ void OnActionChanged (object s, ObjectWrapperEventArgs args)
+ {
+ NotifyModified ();
+ }
+
+ void NotifyModified ()
+ {
+ modified = true;
+ if (GroupModified != null)
+ GroupModified (this, EventArgs.Empty);
+ }
+
+ void OnAddClicked (object s, Gtk.ButtonPressEventArgs args)
+ {
+ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (project,
+ new Gtk.Action ("", "", null, null),
+ ActionGroup);
+ ActionMenuItem item = InsertAction (ac, actionGroup.Actions.Count);
+ item.EditingDone += OnEditDone;
+ item.Select ();
+ item.StartEditing ();
+ HideAddLabel ();
+ ShowAll ();
+ }
+
+ void OnEditDone (object sender, EventArgs args)
+ {
+ ActionMenuItem item = (ActionMenuItem) sender;
+ item.EditingDone -= OnEditDone;
+ if (item.Node.Action.GtkAction.Label.Length > 0 || item.Node.Action.GtkAction.StockId != null) {
+ actionGroup.Actions.Add (item.Node.Action);
+ } else {
+ IDesignArea designArea = GetDesignArea ();
+ designArea.ResetSelection (item);
+ item.Detach ();
+ item.Node.Dispose ();
+ items.Remove (item);
+ item.Destroy ();
+ PlaceAddLabel (actionGroup.Actions.Count);
+ ShowAll ();
+ }
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ IDesignArea designArea = GetDesignArea ();
+ designArea.SetSelection (null, null);
+ return true;
+ }
+
+ void OnItemKeyPress (object s, Gtk.KeyPressEventArgs args)
+ {
+ int pos = items.IndexOf (s);
+
+ switch (args.Event.Key) {
+ case Gdk.Key.Up:
+ pos -= (int) columns;
+ break;
+ case Gdk.Key.Down:
+ pos += (int) columns;
+ break;
+ case Gdk.Key.Right:
+ pos ++;
+ break;
+ case Gdk.Key.Left:
+ pos --;
+ break;
+ }
+ if (pos >= 0 && pos < items.Count) {
+ ((ActionMenuItem)items[pos]).Select ();
+ args.RetVal = true;
+ }
+ else if (pos == items.Count) {
+ OnAddClicked (null, null);
+ args.RetVal = true;
+ }
+ }
+
+ void OnGroupNameChanged (object s, EventArgs args)
+ {
+ if (actionGroup != null)
+ actionGroup.Name = headerLabel.Text;
+ }
+
+ void OnSelectionChanged (object s, EventArgs args)
+ {
+ if (SelectionChanged != null)
+ SelectionChanged (this, args);
+ }
+
+ public void Cut ()
+ {
+ ActionMenuItem menuItem = SelectedActionMenuItem;
+ if (menuItem != null)
+ Cut (SelectedActionMenuItem);
+ }
+
+ public void Copy ()
+ {
+ ActionMenuItem menuItem = SelectedActionMenuItem;
+ if (menuItem != null)
+ Copy (SelectedActionMenuItem);
+ }
+
+ public void Paste ()
+ {
+ }
+
+ public void Delete ()
+ {
+ ActionMenuItem menuItem = SelectedActionMenuItem;
+ if (menuItem != null)
+ Delete (SelectedActionMenuItem);
+ }
+
+ void Cut (ActionMenuItem menuItem)
+ {
+ }
+
+ void Copy (ActionMenuItem menuItem)
+ {
+ }
+
+ void Paste (ActionMenuItem menuItem)
+ {
+ }
+
+ void Delete (ActionMenuItem menuItem)
+ {
+ string msg = string.Format (Catalog.GetString ("Are you sure you want to delete the action '{0}'? It will be removed from all menus and toolbars."), menuItem.Node.Action.Name);
+ Gtk.MessageDialog md = new Gtk.MessageDialog (null, Gtk.DialogFlags.Modal, Gtk.MessageType.Question, Gtk.ButtonsType.YesNo, msg);
+ md.TransientFor = this.Toplevel as Gtk.Window;
+ if (md.Run () == (int) Gtk.ResponseType.Yes) {
+ menuItem.Node.Action.Delete ();
+ darea.SetSelection (null, null);
+ }
+ md.Destroy ();
+ }
+
+ void IMenuItemContainer.ShowContextMenu (ActionItem aitem)
+ {
+ ActionMenuItem menuItem = aitem as ActionMenuItem;
+
+ Gtk.Menu m = new Gtk.Menu ();
+ Gtk.MenuItem item = new Gtk.ImageMenuItem (Gtk.Stock.Cut, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Cut (menuItem);
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Copy, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Copy (menuItem);
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Paste, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Paste (menuItem);
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Delete, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Delete (menuItem);
+ };
+ m.ShowAll ();
+ m.Popup ();
+ }
+
+ IDesignArea GetDesignArea ()
+ {
+ if (darea != null)
+ return darea;
+
+ darea = WidgetUtils.GetDesignArea (this);
+ darea.SelectionChanged += OnSelectionChanged;
+ return darea;
+ }
+
+ ActionMenu IMenuItemContainer.OpenSubmenu {
+ get { return null; }
+ set { }
+ }
+
+ bool IMenuItemContainer.IsTopMenu {
+ get { return false; }
+ }
+
+ Gtk.Widget IMenuItemContainer.Widget {
+ get { return this; }
+ }
+
+ class ActionComparer: IComparer
+ {
+ public int Compare (object x, object y)
+ {
+ return string.Compare (((Wrapper.Action)x).GtkAction.Label, ((Wrapper.Action)y).GtkAction.Label);
+ }
+ }
+ }
+
+ public class EditableLabel: Gtk.EventBox
+ {
+ string text;
+ string markup;
+
+ public EditableLabel (): this ("")
+ {
+ }
+
+ public EditableLabel (string txt)
+ {
+ VisibleWindow = false;
+ text = txt;
+ Add (CreateLabel ());
+ }
+
+ public string Text {
+ get { return text; }
+ set {
+ text = value;
+ if (Child is Gtk.Entry)
+ ((Gtk.Entry)Child).Text = text;
+ else
+ ((Gtk.Label)Child).Markup = Markup;
+ }
+ }
+
+ public string MarkupTemplate {
+ get { return markup; }
+ set {
+ markup = value;
+ if (Child is Gtk.Label)
+ ((Gtk.Label)Child).Markup = Markup;
+ }
+ }
+
+ public string Markup {
+ get { return markup != null ? markup.Replace ("$TEXT",text) : text; }
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ IDesignArea d = WidgetUtils.GetDesignArea (this);
+ if (d.IsSelected (this)) {
+ if (Child is Gtk.Label) {
+ StartEditing ();
+ return true;
+ }
+ } else {
+ d.SetSelection (this, null);
+ return true;
+ }
+ return false;
+ }
+
+ void SelectionDisposed (object s, EventArgs args)
+ {
+ EndEditing ();
+ }
+
+ public void StartEditing ()
+ {
+ if (Child is Gtk.Label) {
+ IDesignArea d = WidgetUtils.GetDesignArea (this);
+ IObjectSelection sel = d.GetSelection (this);
+ if (sel == null)
+ sel = d.SetSelection (this, null);
+
+ sel.Disposed += SelectionDisposed;
+
+ Remove (Child);
+ Add (CreateEntry ());
+ ShowAll ();
+ Child.GrabFocus ();
+ }
+ }
+
+ public void EndEditing ()
+ {
+ if (Child is Gtk.Entry) {
+ Remove (Child);
+ Add (CreateLabel ());
+ ShowAll ();
+ }
+ }
+
+ Gtk.Label CreateLabel ()
+ {
+ Gtk.Label label = new Gtk.Label ();
+ label.Markup = Markup;
+ label.Xalign = 0;
+ return label;
+ }
+
+ Gtk.Entry CreateEntry ()
+ {
+ Gtk.Entry e = new Gtk.Entry (text);
+ e.Changed += delegate (object s, EventArgs a) {
+ text = e.Text;
+ if (Changed != null)
+ Changed (this, a);
+ };
+ e.Activated += delegate (object s, EventArgs a) {
+ EndEditing ();
+ };
+ return e;
+ }
+
+ public event EventHandler Changed;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionItem.cs
new file mode 100644
index 0000000000..5d2d09cdd8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionItem.cs
@@ -0,0 +1,209 @@
+
+using System;
+using Stetic.Wrapper;
+
+namespace Stetic.Editor
+{
+ abstract class ActionItem: Gtk.EventBox, IEditableObject
+ {
+ protected IMenuItemContainer parentMenu;
+ protected ActionTreeNode node;
+ protected Widget wrapper;
+ protected bool localUpdate;
+ protected bool editOnRelease;
+ protected bool editing;
+ protected uint itemSpacing;
+ protected int minWidth;
+
+ // To use in the action editor
+ protected IDesignArea designArea;
+ protected IProject project;
+ bool disposed;
+
+ public ActionItem (ActionTreeNode node, IMenuItemContainer parent, uint itemSpacing)
+ {
+ DND.SourceSet (this);
+ this.parentMenu = parent;
+ this.node = node;
+ this.VisibleWindow = false;
+ this.CanFocus = true;
+ this.Events |= Gdk.EventMask.KeyPressMask;
+ this.itemSpacing = itemSpacing;
+ if (node.Action != null)
+ node.Action.ObjectChanged += OnActionChanged;
+ }
+
+ public ActionTreeNode Node {
+ get { return node; }
+ }
+
+ public uint ItemSpacing {
+ get { return itemSpacing; }
+ set { itemSpacing = value; }
+ }
+
+ public int MinWidth {
+ get { return minWidth; }
+ set { minWidth = value; }
+ }
+
+ public bool IsSelected {
+ get {
+ IDesignArea area = GetDesignArea ();
+ return area.IsSelected (this);
+ }
+ }
+
+ protected void UpdateSelectionStatus ()
+ {
+ IDesignArea area = GetDesignArea ();
+ IObjectSelection sel = area.GetSelection ();
+ sel.Disposed -= OnSelectionDisposed;
+ sel.Drag -= HandleItemDrag;
+
+ area.ResetSelection (this);
+
+ sel = area.SetSelection (this, this);
+ sel.Drag += HandleItemDrag;
+ sel.Disposed += OnSelectionDisposed;
+ }
+
+ public virtual void Select ()
+ {
+ IDesignArea area = GetDesignArea ();
+ if (area.IsSelected (this))
+ return;
+ IObjectSelection sel = area.SetSelection (this, node.Action != null ? node.Action.GtkAction : null);
+ sel.Drag += HandleItemDrag;
+ sel.Disposed += OnSelectionDisposed;
+ GrabFocus ();
+ }
+
+ void OnSelectionDisposed (object ob, EventArgs a)
+ {
+ if (!disposed)
+ EndEditing (Gdk.Key.Return);
+ }
+
+ protected virtual void EndEditing (Gdk.Key exitKey)
+ {
+ }
+
+ public override void Dispose ()
+ {
+ disposed = true;
+ base.Dispose ();
+ }
+
+
+ void HandleItemDrag (Gdk.EventMotion evt, int dx, int dy)
+ {
+ ProcessDragBegin (null, evt);
+ }
+
+ protected IDesignArea GetDesignArea ()
+ {
+ if (wrapper != null)
+ return wrapper.GetDesignArea ();
+ else
+ return designArea;
+ }
+
+ protected IProject GetProject ()
+ {
+ if (wrapper != null)
+ return wrapper.Project;
+ else
+ return project;
+ }
+
+ void OnActionChanged (object ob, ObjectWrapperEventArgs a)
+ {
+ if (!localUpdate)
+ Refresh ();
+ }
+
+ public abstract void Refresh ();
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ return ProcessButtonPress (ev);
+ }
+
+ public bool ProcessButtonPress (Gdk.EventButton ev)
+ {
+ if (ev.Button == 1) {
+ IDesignArea area = GetDesignArea ();
+ if (area == null)
+ return true;
+
+ // Clicking a selected item starts the edit mode
+ if (area.IsSelected (this)) {
+ editOnRelease = true;
+ return true;
+ }
+ } else if (ev.Button == 3) {
+ parentMenu.ShowContextMenu (this);
+ }
+
+ Select ();
+ return true;
+ }
+
+ protected override void OnDragBegin (Gdk.DragContext ctx)
+ {
+ ProcessDragBegin (ctx, null);
+ }
+
+ public virtual void ProcessDragBegin (Gdk.DragContext ctx, Gdk.EventMotion evt)
+ {
+ editOnRelease = false;
+ ActionPaletteItem item = new ActionPaletteItem (node);
+ if (ctx != null)
+ DND.Drag (parentMenu.Widget, ctx, item);
+ else
+ DND.Drag (parentMenu.Widget, evt, item);
+ }
+
+ public bool CanCopy {
+ get { return !editing; }
+ }
+
+ public bool CanCut {
+ get { return false; }
+ }
+
+ public bool CanPaste {
+ get { return false; }
+ }
+
+ public bool CanDelete {
+ get { return !editing; }
+ }
+
+ public void Copy ()
+ {
+ }
+
+ public void Cut ()
+ {
+ }
+
+ public void Paste ()
+ {
+ }
+
+ public void Delete ()
+ {
+ if (node.ParentNode != null)
+ node.ParentNode.Children.Remove (node);
+ Destroy ();
+ }
+
+ void IEditableObject.Delete ()
+ {
+ if (!editing)
+ Delete ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenu.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenu.cs
new file mode 100644
index 0000000000..a34519a194
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenu.cs
@@ -0,0 +1,650 @@
+
+using System;
+using System.Collections;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class ActionMenu: Gtk.EventBox, IMenuItemContainer
+ {
+ ActionTreeNode parentNode;
+ ActionTreeNodeCollection nodes;
+ ArrayList menuItems = new ArrayList ();
+ Gtk.Table table;
+ ActionMenu openSubmenu;
+ Widget wrapper;
+ int dropPosition = -1;
+ int dropIndex;
+ Gtk.EventBox emptyLabel;
+ IMenuItemContainer parentMenu;
+
+ public ActionMenu (IntPtr p): base (p)
+ {}
+
+ internal ActionMenu (Widget wrapper, IMenuItemContainer parentMenu, ActionTreeNode node)
+ {
+ DND.DestSet (this, true);
+ parentNode = node;
+ this.parentMenu = parentMenu;
+ this.wrapper = wrapper;
+ this.nodes = node.Children;
+ table = new Gtk.Table (0, 0, false);
+ table.ColumnSpacing = 5;
+ table.RowSpacing = 5;
+ table.BorderWidth = 5;
+ this.AppPaintable = true;
+
+ Add (table);
+
+ Fill ();
+
+ parentNode.ChildNodeAdded += OnChildAdded;
+ parentNode.ChildNodeRemoved += OnChildRemoved;
+ }
+
+ protected override void OnDestroyed ()
+ {
+ parentNode.ChildNodeAdded -= OnChildAdded;
+ parentNode.ChildNodeRemoved -= OnChildRemoved;
+ parentNode = null;
+
+ base.OnDestroyed ();
+ }
+
+ public void Select (ActionTreeNode node)
+ {
+ if (node != null) {
+ ActionMenuItem item = FindMenuItem (node);
+ if (item != null)
+ item.Select ();
+ } else {
+ if (menuItems.Count > 0)
+ ((ActionMenuItem)menuItems [0]).Select ();
+ else
+ InsertAction (0);
+ }
+ }
+
+ public ActionTreeNode ParentNode {
+ get { return parentNode; }
+ }
+
+ bool IMenuItemContainer.IsTopMenu {
+ get { return false; }
+ }
+
+ Gtk.Widget IMenuItemContainer.Widget {
+ get { return this; }
+ }
+
+ public void TrackWidgetPosition (Gtk.Widget refWidget, bool topMenu)
+ {
+ IDesignArea area = wrapper.GetDesignArea ();
+ Gdk.Rectangle rect = area.GetCoordinates (refWidget);
+ if (topMenu)
+ area.MoveWidget (this, rect.X, rect.Bottom);
+ else
+ area.MoveWidget (this, rect.Right, rect.Top);
+
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (RepositionSubmenu));
+ }
+
+ public bool RepositionSubmenu ()
+ {
+ if (openSubmenu == null)
+ return false;
+
+ ActionMenuItem item = FindMenuItem (openSubmenu.parentNode);
+ if (item != null)
+ openSubmenu.TrackWidgetPosition (item, false);
+ return false;
+ }
+
+ void Fill ()
+ {
+ menuItems.Clear ();
+
+ uint n = 0;
+ ActionMenuItem editItem = null;
+
+ if (nodes.Count > 0) {
+ foreach (ActionTreeNode node in nodes) {
+ ActionMenuItem item = new ActionMenuItem (wrapper, this, node);
+ item.KeyPressEvent += OnItemKeyPress;
+ item.Attach (table, n++, 0);
+ menuItems.Add (item);
+ // If adding an action with an empty name, select and start editing it
+// if (node.Action != null && node.Action.Name.Length == 0)
+// editItem = item;
+ }
+ }
+
+ emptyLabel = new Gtk.EventBox ();
+ emptyLabel.VisibleWindow = false;
+ Gtk.Label label = new Gtk.Label ();
+ label.Xalign = 0;
+ label.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("Click to create action") + "</span></i>";
+ emptyLabel.Add (label);
+ emptyLabel.ButtonPressEvent += OnAddClicked;
+ table.Attach (emptyLabel, 1, 2, n, n + 1);
+
+ ShowAll ();
+
+ if (editItem != null) {
+ // If there is an item with an empty action, it means that it was an item that was
+ // being edited. Restart the editing now.
+ GLib.Timeout.Add (200, delegate {
+ editItem.Select ();
+ editItem.EditingDone += OnEditingDone;
+ editItem.StartEditing ();
+ return false;
+ });
+ }
+ }
+
+ void Refresh ()
+ {
+ IDesignArea area = wrapper.GetDesignArea ();
+ ActionTreeNode selNode = null;
+
+ foreach (Gtk.Widget w in table.Children) {
+ ActionMenuItem ami = w as ActionMenuItem;
+ if (area.IsSelected (w) && ami != null) {
+ selNode = ami.Node;
+ area.ResetSelection (w);
+ }
+ table.Remove (w);
+ }
+
+ Fill ();
+
+ ActionMenuItem mi = FindMenuItem (selNode);
+ if (mi != null)
+ mi.Select ();
+
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (RepositionSubmenu));
+ }
+
+ public ActionMenu OpenSubmenu {
+ get { return openSubmenu; }
+ set {
+ if (openSubmenu != null) {
+ openSubmenu.OpenSubmenu = null;
+ IDesignArea area = wrapper.GetDesignArea ();
+ area.RemoveWidget (openSubmenu);
+ openSubmenu.Destroy ();
+ }
+ openSubmenu = value;
+ }
+ }
+
+ internal void ResetSelection ()
+ {
+ if (OpenSubmenu != null)
+ OpenSubmenu.ResetSelection ();
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area != null) {
+ foreach (Gtk.Widget w in table.Children) {
+ ActionMenuItem ami = w as ActionMenuItem;
+ if (ami != null)
+ area.ResetSelection (w);
+ }
+ }
+ }
+
+ ActionTreeNode InsertAction (int pos)
+ {
+ using (wrapper.UndoManager.AtomicChange) {
+ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project,
+ new Gtk.Action ("", "", null, null),
+ wrapper);
+ ActionTreeNode newNode = new ActionTreeNode (Gtk.UIManagerItemType.Menuitem, null, ac);
+ nodes.Insert (pos, newNode);
+ ActionMenuItem item = FindMenuItem (newNode);
+ item.EditingDone += OnEditingDone;
+ item.Select ();
+ item.StartEditing ();
+ emptyLabel.Hide ();
+
+ if (wrapper.LocalActionGroups.Count == 0)
+ wrapper.LocalActionGroups.Add (new ActionGroup ("Default"));
+ wrapper.LocalActionGroups [0].Actions.Add (ac);
+ return newNode;
+ }
+ }
+
+ void DeleteAction (ActionMenuItem item)
+ {
+ int pos = menuItems.IndexOf (item);
+ item.Delete ();
+ if (pos >= menuItems.Count)
+ SelectLastItem ();
+ else
+ ((ActionMenuItem)menuItems [pos]).Select ();
+ }
+
+ void OnEditingDone (object ob, MenuItemEditEventArgs args)
+ {
+ ActionMenuItem item = (ActionMenuItem) ob;
+ item.EditingDone -= OnEditingDone;
+ if (item.Node.Action.GtkAction.Label.Length == 0 && item.Node.Action.GtkAction.StockId == null) {
+ IDesignArea area = wrapper.GetDesignArea ();
+ area.ResetSelection (item);
+ using (wrapper.UndoManager.AtomicChange) {
+ nodes.Remove (item.Node);
+ wrapper.LocalActionGroups [0].Actions.Remove (item.Node.Action);
+ }
+ SelectLastItem ();
+ }
+ else {
+ if (args.ExitKey == Gdk.Key.Up || args.ExitKey == Gdk.Key.Down)
+ ProcessKey (item, args.ExitKey, Gdk.ModifierType.None);
+ }
+ }
+
+ void SelectLastItem ()
+ {
+ if (menuItems.Count > 0)
+ ((ActionMenuItem)menuItems [menuItems.Count - 1]).Select ();
+ else if (parentMenu.Widget is ActionMenuBar) {
+ ActionMenuBar bar = (ActionMenuBar) parentMenu.Widget;
+ bar.Select (parentNode);
+ }
+ else if (parentMenu.Widget is ActionMenu) {
+ ActionMenu parentAM = (ActionMenu) parentMenu.Widget;
+ parentAM.Select (parentNode);
+ }
+ }
+
+ void OnChildAdded (object ob, ActionTreeNodeArgs args)
+ {
+ Refresh ();
+ }
+
+ void OnChildRemoved (object ob, ActionTreeNodeArgs args)
+ {
+ IDesignArea area = wrapper.GetDesignArea ();
+ IObjectSelection asel = area.GetSelection ();
+ ActionMenuItem curSel = asel != null ? asel.DataObject as ActionMenuItem : null;
+ int pos = menuItems.IndexOf (curSel);
+
+ ActionMenuItem mi = FindMenuItem (args.Node);
+ if (mi != null) {
+ // Remove the table row that contains the menu item
+ Gtk.Table.TableChild tc = (Gtk.Table.TableChild) table [mi];
+ uint row = tc.TopAttach;
+ mi.Detach ();
+ menuItems.Remove (mi);
+ foreach (Gtk.Widget w in table.Children) {
+ tc = (Gtk.Table.TableChild) table [w];
+ if (tc.TopAttach >= row)
+ tc.TopAttach--;
+ if (tc.BottomAttach > row)
+ tc.BottomAttach--;
+ }
+ if (pos != -1 && pos < menuItems.Count)
+ ((ActionMenuItem)menuItems[pos]).Select ();
+ else
+ SelectLastItem ();
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (RepositionSubmenu));
+ }
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ int w, h;
+ this.GdkWindow.GetSize (out w, out h);
+ Gdk.Rectangle clip = new Gdk.Rectangle (0,0,w,h);
+ Gtk.Style.PaintBox (this.Style, this.GdkWindow, Gtk.StateType.Normal, Gtk.ShadowType.Out, clip, this, "menu", 0, 0, w, h);
+
+ bool r = base.OnExposeEvent (ev);
+
+ if (dropPosition != -1) {
+ GdkWindow.DrawRectangle (this.Style.BlackGC, true, 0, dropPosition - 1, w - 2, 3);
+ }
+
+ return r;
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ return true;
+ }
+
+ void OnAddClicked (object s, Gtk.ButtonPressEventArgs args)
+ {
+ InsertAction (menuItems.Count);
+ args.RetVal = true;
+ }
+
+ protected override bool OnDragMotion (Gdk.DragContext context, int x, int y, uint time)
+ {
+ ActionPaletteItem dragItem = DND.DragWidget as ActionPaletteItem;
+ if (dragItem == null)
+ return false;
+
+ if (nodes.Count > 0) {
+ ActionMenuItem item = LocateWidget (x, y);
+ if (item != null) {
+
+ // Show the submenu to allow droping to it, but avoid
+ // droping a submenu inside itself
+ if (item.HasSubmenu && item.Node != dragItem.Node)
+ item.ShowSubmenu (wrapper.GetDesignArea(), item);
+
+ // Look for the index where to insert the new item
+ dropIndex = nodes.IndexOf (item.Node);
+ int mpos = item.Allocation.Y + item.Allocation.Height / 2;
+ if (y > mpos)
+ dropIndex++;
+
+ // Calculate the drop position, used to show the drop bar
+ if (dropIndex == 0)
+ dropPosition = item.Allocation.Y;
+ else if (dropIndex == menuItems.Count)
+ dropPosition = item.Allocation.Bottom;
+ else {
+ item = (ActionMenuItem) menuItems [dropIndex];
+ ActionMenuItem prevItem = (ActionMenuItem) menuItems [dropIndex - 1];
+ dropPosition = prevItem.Allocation.Bottom + (item.Allocation.Y - prevItem.Allocation.Bottom)/2;
+ }
+ }
+ } else
+ dropIndex = 0;
+
+ QueueDraw ();
+ return base.OnDragMotion (context, x, y, time);
+ }
+
+ protected override void OnDragLeave (Gdk.DragContext context, uint time)
+ {
+ dropPosition = -1;
+ QueueDraw ();
+ base.OnDragLeave (context, time);
+ }
+
+ protected override void OnDragDataReceived (Gdk.DragContext context, int x, int y, Gtk.SelectionData data, uint info, uint time)
+ {
+ }
+
+ protected override bool OnDragDrop (Gdk.DragContext context, int x, int y, uint time)
+ {
+ ActionPaletteItem dropped = DND.Drop (context, null, time) as ActionPaletteItem;
+ if (dropped == null)
+ return false;
+
+ if (dropped.Node.Type != Gtk.UIManagerItemType.Menuitem &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Menu &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Toolitem &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Separator)
+ return false;
+
+ ActionTreeNode newNode = null;
+
+ // Toolitems are copied, not moved
+
+ using (wrapper.UndoManager.AtomicChange) {
+ if (dropped.Node.ParentNode != null && dropped.Node.Type != Gtk.UIManagerItemType.Toolitem) {
+ if (dropIndex < nodes.Count) {
+ // Do nothing if trying to drop the node over the same node
+ ActionTreeNode dropNode = nodes [dropIndex];
+ if (dropNode == dropped.Node)
+ return false;
+
+ dropped.Node.ParentNode.Children.Remove (dropped.Node);
+
+ // The drop position may have changed after removing the dropped node,
+ // so get it again.
+ dropIndex = nodes.IndexOf (dropNode);
+ nodes.Insert (dropIndex, dropped.Node);
+ } else {
+ dropped.Node.ParentNode.Children.Remove (dropped.Node);
+ nodes.Add (dropped.Node);
+ dropIndex = nodes.Count - 1;
+ }
+ } else {
+ newNode = new ActionTreeNode (Gtk.UIManagerItemType.Menuitem, null, dropped.Node.Action);
+ nodes.Insert (dropIndex, newNode);
+ }
+ // Select the dropped node
+ ActionMenuItem mi = (ActionMenuItem) menuItems [dropIndex];
+ mi.Select ();
+ }
+
+ return base.OnDragDrop (context, x, y, time);
+ }
+
+ [GLib.ConnectBefore]
+ void OnItemKeyPress (object s, Gtk.KeyPressEventArgs args)
+ {
+ ActionMenuItem item = (ActionMenuItem) s;
+ ProcessKey (item, args.Event.Key, args.Event.State);
+ args.RetVal = true;
+ }
+
+ void ProcessKey (ActionMenuItem item, Gdk.Key key, Gdk.ModifierType modifier)
+ {
+ int pos = menuItems.IndexOf (item);
+
+ switch (key) {
+ case Gdk.Key.Up:
+ if (pos > 0)
+ ((ActionMenuItem)menuItems[pos - 1]).Select ();
+ else if (parentMenu.Widget is ActionMenuBar) {
+ ActionMenuBar bar = (ActionMenuBar) parentMenu.Widget;
+ bar.Select (parentNode);
+ }
+ break;
+ case Gdk.Key.Down:
+ if (pos < menuItems.Count - 1)
+ ((ActionMenuItem)menuItems[pos + 1]).Select ();
+ else if (pos == menuItems.Count - 1) {
+ InsertAction (menuItems.Count);
+ }
+ break;
+ case Gdk.Key.Right:
+ if ((modifier & Gdk.ModifierType.ControlMask) != 0 && item.Node.Type == Gtk.UIManagerItemType.Menuitem) {
+ // Create a submenu
+ using (item.Node.Action.UndoManager.AtomicChange) {
+ item.Node.Type = Gtk.UIManagerItemType.Menu;
+ }
+ item.Node.Action.NotifyChanged ();
+ }
+ if (item.HasSubmenu) {
+ item.ShowSubmenu ();
+ if (openSubmenu != null)
+ openSubmenu.Select (null);
+ } else if (parentNode != null) {
+ ActionMenuBar parentMB = parentMenu.Widget as ActionMenuBar;
+ if (parentMB != null) {
+ int i = parentNode.ParentNode.Children.IndexOf (parentNode);
+ if (i < parentNode.ParentNode.Children.Count - 1)
+ parentMB.DropMenu (parentNode.ParentNode.Children [i + 1]);
+ }
+ }
+ break;
+ case Gdk.Key.Left:
+ if ((modifier & Gdk.ModifierType.ControlMask) != 0 && item.Node.Type == Gtk.UIManagerItemType.Menu) {
+ // Remove the submenu
+ OpenSubmenu = null;
+ using (item.Node.Action.UndoManager.AtomicChange) {
+ item.Node.Type = Gtk.UIManagerItemType.Menuitem;
+ item.Node.Children.Clear ();
+ }
+ item.Node.Action.NotifyChanged ();
+ break;
+ }
+ if (parentNode != null) {
+ ActionMenu parentAM = parentMenu.Widget as ActionMenu;
+ if (parentAM != null) {
+ parentAM.Select (parentNode);
+ }
+ ActionMenuBar parentMB = parentMenu.Widget as ActionMenuBar;
+ if (parentMB != null) {
+ int i = parentNode.ParentNode.Children.IndexOf (parentNode);
+ if (i > 0)
+ parentMB.DropMenu (parentNode.ParentNode.Children [i - 1]);
+ }
+ }
+ break;
+ case Gdk.Key.Return:
+ item.EditingDone += OnEditingDone;
+ item.StartEditing ();
+ break;
+ case Gdk.Key.Insert:
+ if ((modifier & Gdk.ModifierType.ControlMask) != 0)
+ InsertActionAt (item, true, true);
+ else
+ InsertActionAt (item, false, false);
+ break;
+ case Gdk.Key.Delete:
+ DeleteAction (item);
+ break;
+ }
+ }
+
+ void InsertActionAt (ActionMenuItem item, bool after, bool separator)
+ {
+ int pos = menuItems.IndexOf (item);
+ if (pos == -1)
+ return;
+
+ if (after)
+ pos++;
+
+ if (separator) {
+ ActionTreeNode newNode = new ActionTreeNode (Gtk.UIManagerItemType.Separator, null, null);
+ nodes.Insert (pos, newNode);
+ Select (newNode);
+ } else
+ InsertAction (pos);
+ }
+
+ void Paste (ActionMenuItem item)
+ {
+ }
+
+ void IMenuItemContainer.ShowContextMenu (ActionItem aitem)
+ {
+ ActionMenuItem menuItem = aitem as ActionMenuItem;
+ Gtk.Menu m = new Gtk.Menu ();
+ Gtk.MenuItem item = new Gtk.MenuItem (Catalog.GetString ("Insert Before"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, false, false);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert After"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, true, false);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert Separator Before"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, false, true);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert Separator After"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, true, true);
+ };
+
+ m.Add (new Gtk.SeparatorMenuItem ());
+
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Cut, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Cut ();
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Copy, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Copy ();
+ };
+ item.Visible = false;
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Paste, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Paste (menuItem);
+ };
+ item.Visible = false;
+
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Delete, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ DeleteAction (menuItem);
+ };
+ m.ShowAll ();
+ m.Popup ();
+ }
+
+ internal void SaveStatus (ArrayList status)
+ {
+ for (int n=0; n<menuItems.Count; n++) {
+ ActionMenuItem item = (ActionMenuItem) menuItems [n];
+ if (item.IsSelected) {
+ status.Add (n);
+ return;
+ }
+ if (item.IsSubmenuVisible) {
+ status.Add (n);
+ OpenSubmenu.SaveStatus (status);
+ return;
+ }
+ }
+ }
+
+ internal void RestoreStatus (ArrayList status, int index)
+ {
+ int pos = (int) status [index];
+ if (pos >= menuItems.Count)
+ return;
+
+ ActionMenuItem item = (ActionMenuItem)menuItems [pos];
+ if (index == status.Count - 1) {
+ // The last position in the status is the selected item
+ item.Select ();
+ if (item.Node.Action != null && item.Node.Action.Name.Length == 0) {
+ // Then only case when there can have an action when an empty name
+ // is when the user clicked on the "add action" link. In this case,
+ // start editing the item again
+ item.EditingDone += OnEditingDone;
+ item.StartEditing ();
+ }
+ }
+ else {
+ item.ShowSubmenu ();
+ if (OpenSubmenu != null)
+ OpenSubmenu.RestoreStatus (status, index + 1);
+ }
+ }
+
+ ActionMenuItem LocateWidget (int x, int y)
+ {
+ foreach (ActionMenuItem mi in menuItems) {
+ if (mi.Allocation.Contains (x, y))
+ return mi;
+ }
+ return null;
+ }
+
+ ActionMenuItem FindMenuItem (ActionTreeNode node)
+ {
+ foreach (ActionMenuItem mi in menuItems) {
+ if (mi.Node == node)
+ return mi;
+ }
+ return null;
+ }
+ }
+
+ interface IMenuItemContainer
+ {
+ ActionMenu OpenSubmenu { get; set; }
+ bool IsTopMenu { get; }
+ Gtk.Widget Widget { get; }
+ void ShowContextMenu (ActionItem item);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuBar.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuBar.cs
new file mode 100644
index 0000000000..8d834b5583
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuBar.cs
@@ -0,0 +1,555 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ class ActionMenuBar: Gtk.MenuBar, IMenuItemContainer
+ {
+ ActionMenu openSubmenu;
+ ActionTree actionTree;
+ int dropPosition = -1;
+ int dropIndex;
+ ArrayList menuItems = new ArrayList ();
+ bool showPlaceholder;
+ Gtk.Widget addLabel;
+ Gtk.Widget spacerItem;
+
+ public ActionMenuBar ()
+ {
+ DND.DestSet (this, true);
+ }
+
+ public void FillMenu (ActionTree actionTree)
+ {
+ addLabel = null;
+
+ if (this.actionTree != null) {
+ this.actionTree.ChildNodeAdded -= OnChildAdded;
+ this.actionTree.ChildNodeRemoved -= OnChildRemoved;
+ }
+
+ this.actionTree = actionTree;
+ if (actionTree == null) {
+ AddSpacerItem ();
+ return;
+ }
+
+ actionTree.ChildNodeAdded += OnChildAdded;
+ actionTree.ChildNodeRemoved += OnChildRemoved;
+
+ HideSpacerItem ();
+ menuItems.Clear ();
+ Widget wrapper = Widget.Lookup (this);
+
+ foreach (Gtk.Widget w in Children) {
+ Remove (w);
+ w.Destroy ();
+ }
+
+ foreach (ActionTreeNode node in actionTree.Children) {
+ ActionMenuItem aitem = new ActionMenuItem (wrapper, this, node);
+ AddItem (aitem, -1);
+ menuItems.Add (aitem);
+ }
+
+ if (showPlaceholder) {
+ AddCreateItemLabel ();
+ } else if (actionTree.Children.Count == 0) {
+ // Give some height to the toolbar
+ AddSpacerItem ();
+ }
+ }
+
+ public object SaveStatus ()
+ {
+ ArrayList status = new ArrayList ();
+
+ for (int n=0; n<menuItems.Count; n++) {
+ ActionMenuItem item = (ActionMenuItem) menuItems [n];
+ if (item.IsSubmenuVisible) {
+ status.Add (n);
+ OpenSubmenu.SaveStatus (status);
+ break;
+ }
+ }
+ return status;
+ }
+
+ public void RestoreStatus (object data)
+ {
+ ArrayList status = (ArrayList) data;
+ if (status.Count == 0)
+ return;
+
+ int pos = (int) status [0];
+ if (pos >= menuItems.Count)
+ return;
+
+ ActionMenuItem item = (ActionMenuItem) menuItems [pos];
+ if (status.Count == 1) {
+ // The last position in the status is the selected item
+ item.Select ();
+ if (item.Node.Action != null && item.Node.Action.Name.Length == 0) {
+ // Then only case when there can have an action when an empty name
+ // is when the user clicked on the "add action" link. In this case,
+ // start editing the item again
+ item.EditingDone += OnEditingDone;
+ item.StartEditing ();
+ }
+ } else {
+ item.ShowSubmenu ();
+ if (OpenSubmenu != null)
+ OpenSubmenu.RestoreStatus (status, 1);
+ }
+ }
+
+ void AddCreateItemLabel ()
+ {
+ HideSpacerItem ();
+ Gtk.Label emptyLabel = new Gtk.Label ();
+ emptyLabel.Xalign = 0;
+ emptyLabel.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("Click to create menu") + "</span></i>";
+ Gtk.MenuItem mit = new Gtk.MenuItem ();
+ mit.Child = emptyLabel;
+ mit.ButtonPressEvent += OnNewItemPress;
+ Insert (mit, -1);
+ mit.ShowAll ();
+ addLabel = mit;
+ }
+
+ void AddSpacerItem ()
+ {
+ if (spacerItem == null) {
+ Gtk.Label emptyLabel = new Gtk.Label ();
+ emptyLabel.Xalign = 0;
+ emptyLabel.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("Empty menu bar") + "</span></i>";
+ Gtk.MenuItem mit = new Gtk.MenuItem ();
+ mit.Child = emptyLabel;
+ Insert (mit, -1);
+ spacerItem = mit;
+ ShowAll ();
+ }
+ }
+
+ void HideSpacerItem ()
+ {
+ if (spacerItem != null) {
+ Remove (spacerItem);
+ spacerItem = null;
+ }
+ }
+
+ void AddItem (ActionMenuItem aitem, int pos)
+ {
+ Gtk.Table t = new Gtk.Table (1, 3, false);
+ aitem.Attach (t, 0, 0);
+ aitem.KeyPressEvent += OnItemKeyPress;
+ t.ShowAll ();
+
+ CustomMenuBarItem it = new CustomMenuBarItem ();
+ it.ActionMenuItem = aitem;
+ aitem.Bind (it);
+ it.Child = t;
+ it.ShowAll ();
+ Insert (it, pos);
+ }
+
+ public bool ShowInsertPlaceholder {
+ get { return showPlaceholder; }
+ set {
+ showPlaceholder = value;
+ if (value && addLabel == null) {
+ AddCreateItemLabel ();
+ } else if (!value && addLabel != null) {
+ Remove (addLabel);
+ addLabel = null;
+ if (menuItems.Count == 0)
+ AddSpacerItem ();
+ }
+ }
+ }
+
+ public void Unselect ()
+ {
+ // Unselects any selected item and hides any open submenu menu
+ Widget wrapper = Widget.Lookup (this);
+ if (OpenSubmenu != null)
+ OpenSubmenu.ResetSelection ();
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area != null) {
+ foreach (Gtk.Widget w in Children) {
+ CustomMenuBarItem it = w as CustomMenuBarItem;
+ if (it != null)
+ area.ResetSelection (it.ActionMenuItem);
+ }
+ }
+ OpenSubmenu = null;
+ }
+
+ void OnChildAdded (object ob, ActionTreeNodeArgs args)
+ {
+ Refresh ();
+ }
+
+ void OnChildRemoved (object ob, ActionTreeNodeArgs args)
+ {
+ OpenSubmenu = null;
+
+ Widget wrapper = Widget.Lookup (this);
+ IDesignArea area = wrapper.GetDesignArea ();
+ IObjectSelection asel = area.GetSelection ();
+ ActionMenuItem curSel = asel != null ? asel.DataObject as ActionMenuItem : null;
+ int pos = menuItems.IndexOf (curSel);
+
+ foreach (Gtk.Widget w in Children) {
+ if (w is CustomMenuBarItem && ((CustomMenuBarItem)w).ActionMenuItem.Node == args.Node) {
+ Remove (w);
+ menuItems.Remove (((CustomMenuBarItem)w).ActionMenuItem);
+ if (menuItems.Count == 0 && !showPlaceholder)
+ AddSpacerItem ();
+ break;
+ }
+ }
+ if (pos != -1 && pos < menuItems.Count)
+ ((ActionMenuItem)menuItems[pos]).Select ();
+ else if (menuItems.Count > 0)
+ ((ActionMenuItem)menuItems[menuItems.Count-1]).Select ();
+ }
+
+ void Refresh ()
+ {
+ Widget wrapper = Widget.Lookup (this);
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area == null)
+ return;
+
+ ActionTreeNode selNode = null;
+
+ foreach (Gtk.Widget w in Children) {
+ CustomMenuBarItem it = w as CustomMenuBarItem;
+ if (it != null && area.IsSelected (it.ActionMenuItem)) {
+ selNode = it.ActionMenuItem.Node;
+ area.ResetSelection (it.ActionMenuItem);
+ }
+ Remove (w);
+ }
+
+ FillMenu (actionTree);
+
+ if (selNode != null) {
+ ActionMenuItem mi = FindMenuItem (selNode);
+ if (mi != null)
+ mi.Select ();
+ }
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnNewItemPress (object ob, Gtk.ButtonPressEventArgs args)
+ {
+ InsertAction (menuItems.Count);
+ args.RetVal = true;
+ }
+
+ void InsertAction (int pos)
+ {
+ Widget wrapper = Widget.Lookup (this);
+ using (wrapper.UndoManager.AtomicChange) {
+ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project,
+ new Gtk.Action ("", "", null, null),
+ wrapper);
+ ActionTreeNode node = new ActionTreeNode (Gtk.UIManagerItemType.Menu, "", ac);
+ actionTree.Children.Insert (pos, node);
+
+ ActionMenuItem aitem = FindMenuItem (node);
+ aitem.EditingDone += OnEditingDone;
+ aitem.Select ();
+ aitem.StartEditing ();
+
+ if (wrapper.LocalActionGroups.Count == 0)
+ wrapper.LocalActionGroups.Add (new ActionGroup ("Default"));
+ wrapper.LocalActionGroups[0].Actions.Add (ac);
+ }
+ }
+
+ void OnEditingDone (object ob, EventArgs args)
+ {
+ ActionMenuItem item = (ActionMenuItem) ob;
+ item.EditingDone -= OnEditingDone;
+ Widget wrapper = Widget.Lookup (this);
+
+ if (item.Node.Action.GtkAction.Label.Length == 0 && item.Node.Action.GtkAction.StockId == null) {
+ IDesignArea area = wrapper.GetDesignArea ();
+ area.ResetSelection (item);
+ using (wrapper.UndoManager.AtomicChange) {
+ actionTree.Children.Remove (item.Node);
+ wrapper.LocalActionGroups [0].Actions.Remove (item.Node.Action);
+ }
+ }
+ }
+
+ public void Select (ActionTreeNode node)
+ {
+ ActionMenuItem item = FindMenuItem (node);
+ if (item != null)
+ item.Select ();
+ }
+
+ public void DropMenu (ActionTreeNode node)
+ {
+ ActionMenuItem item = FindMenuItem (node);
+ if (item != null) {
+ if (item.HasSubmenu) {
+ item.ShowSubmenu ();
+ if (openSubmenu != null)
+ openSubmenu.Select (null);
+ }
+ else
+ item.Select ();
+ }
+ }
+
+ public ActionMenu OpenSubmenu {
+ get { return openSubmenu; }
+ set {
+ if (openSubmenu != null) {
+ openSubmenu.OpenSubmenu = null;
+ Widget wrapper = Widget.Lookup (this);
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area != null)
+ area.RemoveWidget (openSubmenu);
+ openSubmenu.Destroy ();
+ }
+ openSubmenu = value;
+ }
+ }
+
+ bool IMenuItemContainer.IsTopMenu {
+ get { return true; }
+ }
+
+ Gtk.Widget IMenuItemContainer.Widget {
+ get { return this; }
+ }
+
+ protected override bool OnDragMotion (Gdk.DragContext context, int x, int y, uint time)
+ {
+ ActionPaletteItem dragItem = DND.DragWidget as ActionPaletteItem;
+ if (dragItem == null)
+ return false;
+
+ if (actionTree.Children.Count > 0) {
+ ActionMenuItem item = LocateWidget (x, y);
+ if (item != null) {
+ Widget wrapper = Widget.Lookup (this);
+
+ // Show the submenu to allow droping to it, but avoid
+ // droping a submenu inside itself
+ if (item.HasSubmenu && item.Node != dragItem.Node)
+ item.ShowSubmenu (wrapper.GetDesignArea(), item);
+
+ // Look for the index where to insert the new item
+ dropIndex = actionTree.Children.IndexOf (item.Node);
+ int mpos = item.Allocation.X + item.Allocation.Width / 2;
+ if (x > mpos)
+ dropIndex++;
+
+ // Calculate the drop position, used to show the drop bar
+ if (dropIndex == 0)
+ dropPosition = item.Allocation.X;
+ else if (dropIndex == menuItems.Count)
+ dropPosition = item.Allocation.Right;
+ else {
+ item = (ActionMenuItem) menuItems [dropIndex];
+ ActionMenuItem prevItem = (ActionMenuItem) menuItems [dropIndex - 1];
+ dropPosition = prevItem.Allocation.Right + (item.Allocation.X - prevItem.Allocation.Right)/2;
+ }
+ }
+ } else
+ dropIndex = 0;
+
+ QueueDraw ();
+ return base.OnDragMotion (context, x, y, time);
+ }
+
+ protected override void OnDragLeave (Gdk.DragContext context, uint time)
+ {
+ dropPosition = -1;
+ QueueDraw ();
+ base.OnDragLeave (context, time);
+ }
+
+ protected override bool OnDragDrop (Gdk.DragContext context, int x, int y, uint time)
+ {
+ ActionPaletteItem dropped = DND.Drop (context, null, time) as ActionPaletteItem;
+ if (dropped == null)
+ return false;
+
+ if (dropped.Node.Type != Gtk.UIManagerItemType.Menuitem &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Menu &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Toolitem &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Separator)
+ return false;
+
+ ActionTreeNode newNode = dropped.Node;
+ if (dropped.Node.Type == Gtk.UIManagerItemType.Toolitem) {
+ newNode = newNode.Clone ();
+ newNode.Type = Gtk.UIManagerItemType.Menuitem;
+ }
+
+ Widget wrapper = Widget.Lookup (this);
+ using (wrapper.UndoManager.AtomicChange) {
+ if (dropIndex < actionTree.Children.Count) {
+ // Do nothing if trying to drop the node over the same node
+ ActionTreeNode dropNode = actionTree.Children [dropIndex];
+ if (dropNode == dropped.Node)
+ return false;
+
+ if (newNode.ParentNode != null)
+ newNode.ParentNode.Children.Remove (newNode);
+
+ // The drop position may have changed after removing the dropped node,
+ // so get it again.
+ dropIndex = actionTree.Children.IndexOf (dropNode);
+ actionTree.Children.Insert (dropIndex, newNode);
+ } else {
+ if (newNode.ParentNode != null)
+ newNode.ParentNode.Children.Remove (newNode);
+ actionTree.Children.Add (newNode);
+ dropIndex = actionTree.Children.Count - 1;
+ }
+
+ // Select the dropped node
+ ActionMenuItem mi = (ActionMenuItem) menuItems [dropIndex];
+ mi.Select ();
+ }
+
+ return base.OnDragDrop (context, x, y, time);
+ }
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ bool r = base.OnExposeEvent (ev);
+ int w, h;
+ this.GdkWindow.GetSize (out w, out h);
+ if (dropPosition != -1)
+ GdkWindow.DrawRectangle (this.Style.BlackGC, true, dropPosition, 0, 3, h);
+ return r;
+ }
+
+ void OnItemKeyPress (object s, Gtk.KeyPressEventArgs args)
+ {
+ int pos = menuItems.IndexOf (s);
+ ActionMenuItem item = (ActionMenuItem) s;
+
+ switch (args.Event.Key) {
+ case Gdk.Key.Left:
+ if (pos > 0)
+ ((ActionMenuItem)menuItems[pos - 1]).Select ();
+ break;
+ case Gdk.Key.Right:
+ if (pos < menuItems.Count - 1)
+ ((ActionMenuItem)menuItems[pos + 1]).Select ();
+ else if (pos == menuItems.Count - 1)
+ InsertAction (menuItems.Count);
+ break;
+ case Gdk.Key.Down:
+ if (item.HasSubmenu) {
+ item.ShowSubmenu ();
+ if (openSubmenu != null)
+ openSubmenu.Select (null);
+ }
+ break;
+ case Gdk.Key.Up:
+ OpenSubmenu = null;
+ break;
+ }
+ args.RetVal = true;
+ }
+
+ void InsertActionAt (ActionMenuItem item, bool after, bool separator)
+ {
+ int pos = menuItems.IndexOf (item);
+ if (pos == -1)
+ return;
+
+ if (after)
+ pos++;
+
+ if (separator) {
+ ActionTreeNode newNode = new ActionTreeNode (Gtk.UIManagerItemType.Separator, null, null);
+ actionTree.Children.Insert (pos, newNode);
+ } else
+ InsertAction (pos);
+ }
+
+ void Paste (ActionMenuItem item)
+ {
+ }
+
+ public void ShowContextMenu (ActionItem aitem)
+ {
+ ActionMenuItem menuItem = (ActionMenuItem) aitem;
+
+ Gtk.Menu m = new Gtk.Menu ();
+ Gtk.MenuItem item = new Gtk.MenuItem (Catalog.GetString ("Insert Before"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, false, false);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert After"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, true, false);
+ };
+
+ m.Add (new Gtk.SeparatorMenuItem ());
+
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Cut, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Cut ();
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Copy, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Copy ();
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Paste, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Paste (menuItem);
+ };
+ item.Visible = false; // No copy & paste for now
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Delete, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Delete ();
+ };
+ m.ShowAll ();
+ m.Popup ();
+ }
+
+ ActionMenuItem LocateWidget (int x, int y)
+ {
+ foreach (ActionMenuItem mi in menuItems) {
+ if (mi.Allocation.Contains (x, y))
+ return mi;
+ }
+ return null;
+ }
+
+ ActionMenuItem FindMenuItem (ActionTreeNode node)
+ {
+ foreach (ActionMenuItem mi in menuItems) {
+ if (mi.Node == node)
+ return mi;
+ }
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuItem.cs
new file mode 100644
index 0000000000..9ac08166b0
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionMenuItem.cs
@@ -0,0 +1,588 @@
+
+using System;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ class ActionMenuItem: ActionItem
+ {
+ Gtk.Widget icon;
+ Gtk.Widget label;
+ Gtk.Widget accel;
+ bool motionDrag;
+ CustomMenuBarItem menuBarItem;
+
+ static Gdk.Pixbuf addMenuImage;
+ static Gdk.Pixbuf removeMenuImage;
+
+ public event MenuItemEditEventHandler EditingDone;
+
+ static ActionMenuItem ()
+ {
+ try {
+ addMenuImage = Gdk.Pixbuf.LoadFromResource ("add-menu.png");
+ removeMenuImage = Gdk.Pixbuf.LoadFromResource ("remove-menu.png");
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf: " + e);
+ }
+ }
+
+ internal ActionMenuItem (Widget wrapper, IMenuItemContainer parent, ActionTreeNode node)
+ : this (wrapper, parent, node, 0)
+ {
+ }
+
+ internal ActionMenuItem (IDesignArea designArea, IProject project, IMenuItemContainer parent, ActionTreeNode node)
+ : this (null, parent, node, 6)
+ {
+ this.project = project;
+ this.designArea = designArea;
+ }
+
+ internal ActionMenuItem (Widget wrapper, IMenuItemContainer parent, ActionTreeNode node, uint itemSpacing): base (node, parent, itemSpacing)
+ {
+ this.wrapper = wrapper;
+ CreateControls ();
+ }
+
+ bool disposed;
+
+ public override void Dispose ()
+ {
+ if (disposed)
+ return;
+ disposed = true;
+ if (menuBarItem != null) {
+ menuBarItem.ButtonPressEvent -= OnMenuItemPress;
+ menuBarItem.ButtonReleaseEvent -= OnMemuItemRelease;
+ menuBarItem.MotionNotifyEvent -= OnMotionNotify;
+ }
+ if (node.Action != null)
+ node.Action.ObjectChanged -= OnActionChanged;
+ base.Dispose ();
+ }
+
+ public bool HasSubmenu {
+ get { return node.Type == Gtk.UIManagerItemType.Menu; }
+ }
+
+ public void StartEditing ()
+ {
+ if (!editing) {
+ editing = true;
+
+ Refresh ();
+ if (node.Type == Gtk.UIManagerItemType.Menu)
+ HideSubmenu ();
+
+ UpdateSelectionStatus ();
+ }
+ }
+
+
+ protected override void EndEditing (Gdk.Key exitKey)
+ {
+ if (editing) {
+ Gtk.Entry entry = label as Gtk.Entry;
+ if (entry != null && exitKey != Gdk.Key.Escape) {
+ localUpdate = true;
+ if (entry.Text.Trim().Length > 0 || node.Action.GtkAction.StockId != null) {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Label = entry.Text;
+ node.Action.NotifyChanged ();
+ }
+ }
+ localUpdate = false;
+ }
+
+ editing = false;
+ Refresh ();
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+ if (node.Type == Gtk.UIManagerItemType.Menu) {
+ if (wrapper != null) {
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area != null)
+ ShowSubmenu (area, this);
+ }
+ }
+ GrabFocus ();
+ UpdateSelectionStatus ();
+
+ if (EditingDone != null) {
+ MenuItemEditEventArgs args = new MenuItemEditEventArgs ();
+ args.ExitKey = exitKey;
+ EditingDone (this, args);
+ }
+ }
+ }
+
+ public override void Select ()
+ {
+ base.Select ();
+
+ if (!IsSubmenuVisible) {
+ parentMenu.OpenSubmenu = null;
+ if (HasSubmenu)
+ ShowSubmenu (GetDesignArea (), this);
+ }
+ GrabFocus ();
+ }
+
+ public void Attach (Gtk.Table table, uint row, uint col)
+ {
+ table.Attach (this, col, col + 3, row, row + 1);
+ Show ();
+ AttachChildren (table, row, col);
+ }
+
+ void AttachChildren (Gtk.Table table, uint row, uint col)
+ {
+ if (icon != null) {
+ table.Attach (icon, col, col + 1, row, row + 1);
+ Gtk.Table.TableChild tc = (Gtk.Table.TableChild) table [icon];
+ if (!editing)
+ tc.YPadding = itemSpacing;
+ }
+ if (label != null) {
+ table.Attach (label, col + 1, col + 2, row, row + 1);
+ Gtk.Table.TableChild tc = (Gtk.Table.TableChild) table [label];
+ if (!editing)
+ tc.YPadding = itemSpacing;
+ label.GrabFocus ();
+ }
+ if (accel != null)
+ table.Attach (accel, col + 2, col + 3, row, row + 1);
+
+ if (minWidth > 0 && label != null) {
+ if (label.SizeRequest().Width < minWidth)
+ label.WidthRequest = minWidth;
+ }
+
+ bool sens = editing || node.Action == null || node.Action.GtkAction.Sensitive;
+ if (icon != null)
+ icon.Sensitive = sens;
+ if (label != null)
+ label.Sensitive = sens;
+ if (accel != null)
+ accel.Sensitive = sens;
+ }
+
+ void CreateControls ()
+ {
+ if (node.Type == Gtk.UIManagerItemType.Separator) {
+ Gtk.Widget sep;
+ if (parentMenu.IsTopMenu) {
+ sep = new Gtk.VSeparator ();
+ sep.WidthRequest = 6;
+ } else {
+ sep = new Gtk.HSeparator ();
+ sep.HeightRequest = 6;
+ }
+ Add (sep);
+ ShowAll ();
+ return;
+ } else {
+ if (Child != null && Child is Gtk.Separator)
+ Remove (Child);
+ }
+
+ if (node.Action == null)
+ return;
+
+ bool isGlobal = wrapper != null && wrapper.Project.ActionGroups.IndexOf (node.Action.ActionGroup) != -1;
+
+ Gtk.Action gaction = node.Action.GtkAction;
+ bool barItem = parentMenu.IsTopMenu;
+
+ string text = gaction.Label;
+ string stock = gaction.StockId;
+
+ if (barItem) {
+ icon = null;
+ } else if (node.Action.Type == Stetic.Wrapper.Action.ActionType.Radio) {
+ icon = new CheckActionIcon (true, node.Action.Active);
+ } else if (node.Action.Type == Stetic.Wrapper.Action.ActionType.Toggle) {
+ icon = new CheckActionIcon (node.Action.DrawAsRadio, node.Action.Active);
+ }
+
+ if (stock != null) {
+ Gtk.StockItem item = Gtk.Stock.Lookup (stock);
+ if (text == null || text.Length == 0)
+ text = item.Label;
+
+ if (item.Keyval != 0 && !editing && !barItem) {
+ Gtk.Label lac = new Gtk.Label ();
+ string accelName = Gtk.Accelerator.Name (item.Keyval, item.Modifier).ToUpper ();
+ accelName = accelName.Replace ("<CONTROL>", "Ctrl+");
+ accelName = accelName.Replace ("<SHIFT>", "Shift+");
+ accelName = accelName.Replace ("<ALT>", "Alt+");
+ lac.Text = accelName;
+ accel = lac;
+ }
+
+ if (icon == null && !barItem)
+ icon = node.Action.CreateIcon (Gtk.IconSize.Menu);
+ }
+
+ if (editing && !isGlobal) {
+ if (!barItem) {
+ Gtk.HBox bbox = new Gtk.HBox ();
+ if (icon != null) {
+ bbox.PackStart (icon, false, false, 0);
+ }
+ bbox.PackStart (new Gtk.Arrow (Gtk.ArrowType.Down, Gtk.ShadowType.In), false, false, 0);
+ Gtk.Button b = new Gtk.Button (bbox);
+ b.TooltipText = Catalog.GetString ("Select action type");
+ b.Relief = Gtk.ReliefStyle.None;
+ b.ButtonPressEvent += OnSelectIcon;
+ icon = b;
+ } else
+ icon = null;
+
+ Gtk.Entry entry = new Gtk.Entry ();
+ entry.Text = text;
+ entry.Activated += OnLabelActivated;
+ entry.KeyPressEvent += OnEntryKeyPress;
+ entry.HasFrame = false;
+ this.label = entry;
+ entry.TooltipText = Catalog.GetString ("Action label");
+ } else {
+ Gtk.Label label = new Gtk.Label (text);
+ label.Xalign = 0;
+ this.label = label;
+ }
+
+ if (editing && wrapper != null) {
+ // Add a button for creating / deleting a submenu
+ Gdk.Pixbuf img;
+ string tip;
+ if (node.Type != Gtk.UIManagerItemType.Menu) {
+ img = addMenuImage;
+ tip = Catalog.GetString ("Add submenu (Ctrl+Right)");
+ } else {
+ img = removeMenuImage;
+ tip = Catalog.GetString ("Remove submenu (Ctrl+Left)");
+ }
+
+ Gtk.Button sb = new Gtk.Button (new Gtk.Image (img));
+ sb.TooltipText = tip;
+ sb.Relief = Gtk.ReliefStyle.None;
+ sb.Clicked += OnCreateDeleteSubmenu;
+
+ // Make sure the button is alligned to the right of the column
+ Gtk.HBox bbox = new Gtk.HBox ();
+ bbox.PackEnd (sb, false, false, 0);
+ accel = bbox;
+ }
+
+
+ if (node.Type == Gtk.UIManagerItemType.Menu && !editing && !barItem) {
+ Gtk.Arrow arrow = new Gtk.Arrow (Gtk.ArrowType.Right, Gtk.ShadowType.None);
+ arrow.Xalign = 1;
+ this.accel = arrow;
+ }
+
+ if (itemSpacing > 0 && icon != null) {
+ // Add some padding to the left of the icon
+ Gtk.Alignment a = new Gtk.Alignment (0, 0.5f, 0, 0);
+ a.LeftPadding = itemSpacing;
+ a.Add (icon);
+ icon = a;
+ }
+ }
+
+ public void Detach ()
+ {
+ if (disposed)
+ return;
+
+ Gtk.Table table = (Gtk.Table)Parent;
+ if (table == null)
+ return;
+ if (icon != null)
+ table.Remove (icon);
+ if (label != null)
+ table.Remove (label);
+ if (accel != null)
+ table.Remove (accel);
+ table.Remove (this);
+ }
+
+ void OnCreateDeleteSubmenu (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ if (node.Type == Gtk.UIManagerItemType.Menu) {
+ node.Type = Gtk.UIManagerItemType.Menuitem;
+ node.Children.Clear ();
+ } else {
+ node.Type = Gtk.UIManagerItemType.Menu;
+ }
+
+ EndEditing (Gdk.Key.Return);
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnLabelActivated (object ob, EventArgs args)
+ {
+ EndEditing (Gdk.Key.Return);
+ }
+
+ [GLib.ConnectBefore]
+ void OnEntryKeyPress (object ob, Gtk.KeyPressEventArgs args)
+ {
+ switch (args.Event.Key) {
+ case Gdk.Key.Down:
+ case Gdk.Key.Escape:
+ case Gdk.Key.Up:
+ EndEditing (args.Event.Key);
+ args.RetVal = true;
+ break;
+ }
+ args.RetVal = false;
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnSelectIcon (object sender, Gtk.ButtonPressEventArgs e)
+ {
+ Gtk.Menu menu = new Gtk.Menu ();
+
+ Gtk.CheckMenuItem item = new Gtk.CheckMenuItem (Catalog.GetString ("Action"));
+ item.DrawAsRadio = true;
+ item.Active = (node.Action.Type == Stetic.Wrapper.Action.ActionType.Action);
+ item.Activated += OnSetActionType;
+ menu.Insert (item, -1);
+
+ item = new Gtk.CheckMenuItem (Catalog.GetString ("Radio Action"));
+ item.DrawAsRadio = true;
+ item.Active = (node.Action.Type == Stetic.Wrapper.Action.ActionType.Radio);
+ item.Activated += OnSetRadioType;
+ menu.Insert (item, -1);
+
+ item = new Gtk.CheckMenuItem (Catalog.GetString ("Toggle Action"));
+ item.DrawAsRadio = true;
+ item.Active = (node.Action.Type == Stetic.Wrapper.Action.ActionType.Toggle);
+ item.Activated += OnSetToggleType;
+ menu.Insert (item, -1);
+
+ menu.Insert (new Gtk.SeparatorMenuItem (), -1);
+
+ Gtk.MenuItem itIcons = new Gtk.MenuItem (Catalog.GetString ("Select Icon"));
+ menu.Insert (itIcons, -1);
+ IconSelectorMenu menuIcons = new IconSelectorMenu (GetProject ());
+ menuIcons.IconSelected += OnStockSelected;
+ itIcons.Submenu = menuIcons;
+
+ Gtk.MenuItem it = new Gtk.MenuItem (Catalog.GetString ("Clear Icon"));
+ it.Sensitive = (node.Action.GtkAction.StockId != null);
+ it.Activated += OnClearIcon;
+ menu.Insert (it, -1);
+
+ menu.ShowAll ();
+ menu.Popup (null, null, new Gtk.MenuPositionFunc (OnDropMenuPosition), 3, Gtk.Global.CurrentEventTime);
+ e.RetVal = false;
+ }
+
+ void OnDropMenuPosition (Gtk.Menu menu, out int x, out int y, out bool pushIn)
+ {
+ this.ParentWindow.GetOrigin (out x, out y);
+ x += this.Allocation.X;
+ y += this.Allocation.Y + this.Allocation.Height;
+ pushIn = true;
+ }
+
+ void OnStockSelected (object s, IconEventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.StockId = args.IconId;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnSetToggleType (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Type = Stetic.Wrapper.Action.ActionType.Toggle;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnSetRadioType (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Type = Stetic.Wrapper.Action.ActionType.Radio;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnSetActionType (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Type = Stetic.Wrapper.Action.ActionType.Action;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnClearIcon (object on, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.StockId = null;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ public override void Refresh ()
+ {
+ Gtk.Table table = (Gtk.Table)Parent;
+ if (table == null)
+ return;
+
+ if (icon != null && icon.Parent != null)
+ table.Remove (icon);
+ if (label != null && label.Parent != null)
+ table.Remove (label);
+ if (accel != null && accel.Parent != null)
+ table.Remove (accel);
+
+ icon = label = accel = null;
+ CreateControls ();
+ Gtk.Table.TableChild tc = (Gtk.Table.TableChild)table[this];
+ AttachChildren (table, tc.TopAttach, tc.LeftAttach);
+
+ table.ShowAll ();
+ }
+
+ internal void Bind (CustomMenuBarItem item)
+ {
+ // When embedding the action menu in a MenuBar,
+ // the parent menu item intercepts the mouse events,
+ // so those events must be manually bound here
+ menuBarItem = item;
+ item.ButtonPressEvent += OnMenuItemPress;
+ item.ButtonReleaseEvent += OnMemuItemRelease;
+ item.MotionNotifyEvent += OnMotionNotify;
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnMenuItemPress (object ob, Gtk.ButtonPressEventArgs args)
+ {
+ Gtk.Widget mit = (Gtk.Widget) ob;
+ if (wrapper != null && wrapper.Project.Selection != mit.Parent) {
+ wrapper.Select ();
+ args.RetVal = true;
+ return;
+ }
+ motionDrag = true;
+ args.RetVal = ProcessButtonPress (args.Event);
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnMemuItemRelease (object ob, Gtk.ButtonReleaseEventArgs args)
+ {
+ args.RetVal = ProcessButtonRelease (args.Event);
+ motionDrag = false;
+ }
+
+ void OnMotionNotify (object ob, Gtk.MotionNotifyEventArgs args)
+ {
+ if (motionDrag) {
+ // Looks like drag begin can be intercepted, so the motion notify
+ // has to be used.
+ ProcessDragBegin (null, args.Event);
+ motionDrag = false;
+ }
+ }
+
+ protected override bool OnButtonReleaseEvent (Gdk.EventButton ev)
+ {
+ return ProcessButtonRelease (ev);
+ }
+
+ public bool ProcessButtonRelease (Gdk.EventButton ev)
+ {
+ // Clicking a selected item starts the edit mode
+ if (editOnRelease)
+ StartEditing ();
+
+ editOnRelease = false;
+ return true;
+ }
+
+ public override void ProcessDragBegin (Gdk.DragContext ctx, Gdk.EventMotion evt)
+ {
+ if (HasSubmenu)
+ HideSubmenu ();
+ base.ProcessDragBegin (ctx, evt);
+ }
+
+ void OnActionChanged (object ob, ObjectWrapperEventArgs a)
+ {
+ if (!localUpdate)
+ Refresh ();
+ }
+
+ public bool IsSubmenuVisible {
+ get {
+ ActionMenu menu = parentMenu.OpenSubmenu;
+ return (menu != null && menu.ParentNode == node);
+ }
+ }
+
+ public void ShowSubmenu ()
+ {
+ ShowSubmenu (wrapper.GetDesignArea (), this);
+ }
+
+ public void ShowSubmenu (IDesignArea area, Gtk.Widget refWidget)
+ {
+ HideSubmenu ();
+ Gdk.Rectangle rect = area.GetCoordinates (refWidget);
+ ActionMenu menu = new ActionMenu (wrapper, parentMenu, node);
+ menu.ShowAll ();
+ area.AddWidget (menu, rect.Right, rect.Top);
+ menu.TrackWidgetPosition (refWidget, parentMenu.IsTopMenu);
+
+ parentMenu.OpenSubmenu = menu;
+ }
+
+ void HideSubmenu ()
+ {
+ parentMenu.OpenSubmenu = null;
+ }
+ }
+
+ class CheckActionIcon: Gtk.EventBox
+ {
+ readonly bool isRadio;
+ readonly bool active;
+
+ public CheckActionIcon (bool isRadio, bool active)
+ {
+ this.isRadio = isRadio;
+ this.active = active;
+ WidthRequest = HeightRequest = 16;
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ Gdk.Rectangle rect = Allocation;
+ rect.X = rect.Y = 0;
+
+ Gtk.ShadowType sh = active ? Gtk.ShadowType.In : Gtk.ShadowType.Out;
+ if (isRadio)
+ Gtk.Style.PaintOption (this.Style, this.GdkWindow, this.State, sh, rect, this, "", rect.X, rect.Y, rect.Width, rect.Height);
+ else
+ Gtk.Style.PaintCheck (this.Style, this.GdkWindow, this.State, sh, rect, this, "", rect.X, rect.Y, rect.Width, rect.Height);
+ return true;
+ }
+ }
+
+ delegate void MenuItemEditEventHandler (object s, MenuItemEditEventArgs args);
+
+ class MenuItemEditEventArgs: EventArgs
+ {
+ public Gdk.Key ExitKey;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolItem.cs
new file mode 100644
index 0000000000..5b27ab4c1c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolItem.cs
@@ -0,0 +1,371 @@
+
+using System;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ class ActionToolItem: ActionItem
+ {
+ ActionToolbar parentToolbar;
+
+ bool motionDrag;
+ bool showingText;
+ Gtk.Widget dropButton;
+
+ public event EventHandler EditingDone;
+
+ internal ActionToolItem (Widget wrapper, ActionToolbar parent, ActionTreeNode node)
+ : this (wrapper, parent, node, 0)
+ {
+ }
+
+ internal ActionToolItem (Widget wrapper, ActionToolbar parent, ActionTreeNode node, uint itemSpacing): base (node, parent, itemSpacing)
+ {
+ this.parentToolbar = parent;
+ this.wrapper = wrapper;
+ CreateControls ();
+ }
+
+ public void StartEditing (bool doClick)
+ {
+ if (!editing && node.Action != null) {
+ // Don't allow efiting global actions
+ if (wrapper != null && wrapper.Project.ActionGroups.IndexOf (node.Action.ActionGroup) != -1)
+ return;
+ editing = true;
+ Refresh ();
+
+ if (doClick && dropButton != null) {
+ // Make sure the dropButton is properly shown
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+ OnSelectIcon (null, null);
+ }
+ }
+ }
+
+ protected override void EndEditing (Gdk.Key exitKey)
+ {
+ if (editing) {
+ editing = false;
+ Refresh ();
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+ GrabFocus ();
+ if (EditingDone != null)
+ EditingDone (this, EventArgs.Empty);
+ }
+ }
+
+ void CreateControls ()
+ {
+ Gtk.Widget icon = null;
+ Gtk.Widget label = null;
+ dropButton = null;
+
+ if (Child != null) {
+ Gtk.Widget w = Child;
+ Remove (w);
+ w.Destroy ();
+ }
+
+ if (node.Type == Gtk.UIManagerItemType.Separator) {
+ Gtk.Widget sep;
+ if (parentToolbar.Orientation == Gtk.Orientation.Horizontal) {
+ sep = new Gtk.VSeparator ();
+ } else {
+ sep = new Gtk.HSeparator ();
+ }
+ Gtk.HBox box = new Gtk.HBox ();
+ box.BorderWidth = 6;
+ box.PackStart (sep, true, true, 0);
+ Add (box);
+ return;
+ }
+
+ if (node.Action == null)
+ return;
+
+ Gtk.Action gaction = node.Action.GtkAction;
+
+ bool showText = parentToolbar.ToolbarStyle == Gtk.ToolbarStyle.Text;
+ bool showIcon = parentToolbar.ToolbarStyle == Gtk.ToolbarStyle.Icons;
+ if (parentToolbar.ToolbarStyle == Gtk.ToolbarStyle.Both) {
+ showText = showIcon = true;
+ }
+ else if (parentToolbar.ToolbarStyle == Gtk.ToolbarStyle.BothHoriz) {
+ showText = parentToolbar.Orientation == Gtk.Orientation.Vertical || gaction.IsImportant;
+ showIcon = true;
+ }
+
+ string text = node.Action.ToolLabel;
+ showingText = showText;
+
+ if (showIcon)
+ {
+ if (gaction.StockId != null) {
+ icon = node.Action.CreateIcon (parentToolbar.IconSize);
+ } else if (!gaction.IsImportant) {
+ icon = CreateFakeItem ();
+ }
+ }
+
+ if (editing) {
+ Gtk.HBox bbox = new Gtk.HBox ();
+ bbox.Spacing = 3;
+ if (icon != null) {
+ bbox.PackStart (icon, false, false, 0);
+ }
+ bbox.PackStart (new Gtk.Arrow (Gtk.ArrowType.Down, Gtk.ShadowType.In), false, false, 0);
+ Gtk.Button b = new Gtk.Button (bbox);
+ b.TooltipText = Catalog.GetString ("Select action type");
+ b.Relief = Gtk.ReliefStyle.None;
+ b.ButtonPressEvent += OnSelectIcon;
+ dropButton = b;
+ icon = b;
+
+ if (showText) {
+ Gtk.Entry entry = new Gtk.Entry ();
+ entry.Text = text;
+ entry.Changed += OnLabelChanged;
+ entry.Activated += OnLabelActivated;
+ entry.HasFrame = false;
+ label = entry;
+ entry.TooltipText = Catalog.GetString ("Action label");
+ }
+ } else if (showText && text != null && text.Length > 0) {
+ label = new Gtk.Label (text);
+ label.Sensitive = editing || node.Action == null || node.Action.GtkAction.Sensitive;
+ }
+
+ if (icon != null && label != null) {
+ if (parentToolbar.ToolbarStyle == Gtk.ToolbarStyle.BothHoriz) {
+ Gtk.HBox box = new Gtk.HBox ();
+ box.PackStart (icon, false, false, 0);
+ box.PackStart (label, true, true, 0);
+ icon = box;
+ } else if (parentToolbar.ToolbarStyle == Gtk.ToolbarStyle.Both) {
+ Gtk.VBox box = new Gtk.VBox ();
+ Gtk.Alignment al = new Gtk.Alignment (0.5f, 0f, 0f, 0f);
+ al.Add (icon);
+ box.PackStart (al, false, false, 0);
+ box.PackStart (label, true, true, 0);
+ icon = box;
+ }
+ } else if (label != null) {
+ icon = label;
+ }
+
+ if (icon == null) {
+ icon = CreateFakeItem ();
+ }
+
+ icon.Sensitive = editing || node.Action == null || node.Action.GtkAction.Sensitive;
+
+ if (!editing) {
+ Gtk.Button but = new Gtk.Button (icon);
+ but.Relief = Gtk.ReliefStyle.None;
+ but.ButtonPressEvent += OnToolItemPress;
+ but.ButtonReleaseEvent += OnMemuItemRelease;
+ but.MotionNotifyEvent += OnMotionNotify;
+ but.Events |= Gdk.EventMask.PointerMotionMask;
+ icon = but;
+ }
+
+ Add (icon);
+
+ ShowAll ();
+ }
+
+ Gtk.Widget CreateFakeItem ()
+ {
+ Gtk.Frame frm = new Gtk.Frame ();
+ frm.ShadowType = Gtk.ShadowType.Out;
+ int w, h;
+ Gtk.Icon.SizeLookup (parentToolbar.IconSize, out w, out h);
+ frm.WidthRequest = w;
+ frm.HeightRequest = h;
+ return frm;
+ }
+
+ void OnLabelChanged (object ob, EventArgs args)
+ {
+ localUpdate = true;
+
+ Gtk.Entry entry = ob as Gtk.Entry;
+ if (entry.Text.Length > 0 || node.Action.GtkAction.StockId != null) {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Label = entry.Text;
+ node.Action.NotifyChanged ();
+ }
+ }
+ localUpdate = false;
+ }
+
+ void OnLabelActivated (object ob, EventArgs args)
+ {
+ EndEditing (Gdk.Key.Return);
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnSelectIcon (object s, Gtk.ButtonPressEventArgs args)
+ {
+ Gtk.Menu menu = new Gtk.Menu ();
+
+ Gtk.CheckMenuItem item = new Gtk.CheckMenuItem (Catalog.GetString ("Action"));
+ item.DrawAsRadio = true;
+ item.Active = (node.Action.Type == Stetic.Wrapper.Action.ActionType.Action);
+ item.Activated += OnSetActionType;
+ menu.Insert (item, -1);
+
+ item = new Gtk.CheckMenuItem (Catalog.GetString ("Radio Action"));
+ item.DrawAsRadio = true;
+ item.Active = (node.Action.Type == Stetic.Wrapper.Action.ActionType.Radio);
+ item.Activated += OnSetRadioType;
+ menu.Insert (item, -1);
+
+ item = new Gtk.CheckMenuItem (Catalog.GetString ("Toggle Action"));
+ item.DrawAsRadio = true;
+ item.Active = (node.Action.Type == Stetic.Wrapper.Action.ActionType.Toggle);
+ item.Activated += OnSetToggleType;
+ menu.Insert (item, -1);
+
+ menu.Insert (new Gtk.SeparatorMenuItem (), -1);
+
+ Gtk.MenuItem itIcons = new Gtk.MenuItem (Catalog.GetString ("Select Icon"));
+ menu.Insert (itIcons, -1);
+ IconSelectorMenu menuIcons = new IconSelectorMenu (GetProject ());
+ menuIcons.IconSelected += OnStockSelected;
+ itIcons.Submenu = menuIcons;
+
+ Gtk.MenuItem it = new Gtk.MenuItem (Catalog.GetString ("Clear Icon"));
+ it.Sensitive = (node.Action.GtkAction.StockId != null);
+ it.Activated += OnClearIcon;
+ menu.Insert (it, -1);
+
+ menu.ShowAll ();
+
+ uint but = args != null ? args.Event.Button : 1;
+ menu.Popup (null, null, new Gtk.MenuPositionFunc (OnDropMenuPosition), but, Gtk.Global.CurrentEventTime);
+
+ // Make sure we get the focus after closing the menu, so we can keep browsing buttons
+ // using the keyboard.
+ menu.Hidden += delegate (object sender, EventArgs a) {
+ GrabFocus ();
+ };
+
+ if (args != null)
+ args.RetVal = false;
+ }
+
+ void OnDropMenuPosition (Gtk.Menu menu, out int x, out int y, out bool pushIn)
+ {
+ dropButton.ParentWindow.GetOrigin (out x, out y);
+ x += dropButton.Allocation.X;
+ y += dropButton.Allocation.Y + dropButton.Allocation.Height;
+ pushIn = true;
+ }
+
+ void OnSetToggleType (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Type = Stetic.Wrapper.Action.ActionType.Toggle;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnSetRadioType (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Type = Stetic.Wrapper.Action.ActionType.Radio;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnSetActionType (object ob, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.Type = Stetic.Wrapper.Action.ActionType.Action;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnStockSelected (object s, IconEventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.StockId = args.IconId;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ void OnClearIcon (object on, EventArgs args)
+ {
+ using (node.Action.UndoManager.AtomicChange) {
+ node.Action.StockId = null;
+ node.Action.NotifyChanged ();
+ }
+ }
+
+ public override void Refresh ()
+ {
+ CreateControls ();
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnToolItemPress (object ob, Gtk.ButtonPressEventArgs args)
+ {
+ if (wrapper != null && wrapper.Project.Selection != wrapper.Wrapped) {
+ wrapper.Select ();
+ args.RetVal = true;
+ return;
+ }
+ if (args.Event.Button == 1)
+ motionDrag = true;
+ args.RetVal = ProcessButtonPress (args.Event);
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnMemuItemRelease (object ob, Gtk.ButtonReleaseEventArgs args)
+ {
+ args.RetVal = ProcessButtonRelease (args.Event);
+ motionDrag = false;
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnMotionNotify (object ob, Gtk.MotionNotifyEventArgs args)
+ {
+ if (motionDrag) {
+ // Looks like drag begin can be intercepted, so the motion notify
+ // has to be used.
+ ProcessDragBegin (null, args.Event);
+ motionDrag = false;
+ }
+ }
+
+ protected override bool OnButtonReleaseEvent (Gdk.EventButton ev)
+ {
+ return ProcessButtonRelease (ev);
+ }
+
+ public bool ProcessButtonRelease (Gdk.EventButton ev)
+ {
+ // Clicking a selected item starts the edit mode
+ if (editOnRelease) {
+ StartEditing (!showingText);
+ }
+
+ editOnRelease = false;
+ return true;
+ }
+
+ protected override bool OnKeyPressEvent (Gdk.EventKey e)
+ {
+ if (e.Key == Gdk.Key.Return)
+ EndEditing (Gdk.Key.Return);
+ else if (e.Key == Gdk.Key.Escape)
+ EndEditing (Gdk.Key.Escape);
+ return base.OnKeyPressEvent (e);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolbar.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolbar.cs
new file mode 100644
index 0000000000..3166f669a3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ActionToolbar.cs
@@ -0,0 +1,542 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ class ActionToolbar: Gtk.Toolbar, IMenuItemContainer
+ {
+ ActionTree actionTree;
+ int dropPosition = -1;
+ int dropIndex;
+ ArrayList toolItems = new ArrayList ();
+ bool showPlaceholder = true;
+ Gtk.Widget addLabel;
+ Gtk.Widget spacerItem;
+
+ public ActionToolbar ()
+ {
+ DND.DestSet (this, true);
+ this.ShowArrow = false;
+ }
+
+ public void FillMenu (ActionTree actionTree)
+ {
+ addLabel = null;
+
+ if (this.actionTree != null) {
+ this.actionTree.ChildNodeAdded -= OnChildAdded;
+ this.actionTree.ChildNodeRemoved -= OnChildRemoved;
+ }
+
+ this.actionTree = actionTree;
+ if (actionTree == null) {
+ AddSpacerItem ();
+ return;
+ }
+
+ actionTree.ChildNodeAdded += OnChildAdded;
+ actionTree.ChildNodeRemoved += OnChildRemoved;
+
+ HideSpacerItem ();
+ toolItems.Clear ();
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+
+ foreach (Gtk.Widget w in Children) {
+ Remove (w);
+ w.Destroy ();
+ }
+
+ foreach (ActionTreeNode node in actionTree.Children) {
+ ActionToolItem aitem = new ActionToolItem (wrapper, this, node);
+ AddItem (aitem, -1);
+ toolItems.Add (aitem);
+ }
+
+ if (actionTree.Children.Count == 0) {
+ // If there are no buttons in the toolbar, give it some height so it is selectable.
+ AddSpacerItem ();
+ }
+
+ if (showPlaceholder) {
+ AddCreateItemLabel ();
+ }
+ }
+
+ void AddCreateItemLabel ()
+ {
+ HideSpacerItem ();
+ Gtk.EventBox ebox = new Gtk.EventBox ();
+ ebox.VisibleWindow = false;
+ Gtk.Label emptyLabel = new Gtk.Label ();
+ emptyLabel.Xalign = 0;
+ if (this.Orientation == Gtk.Orientation.Vertical)
+ emptyLabel.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("New\nbutton") + "</span></i>";
+ else
+ emptyLabel.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("New button") + "</span></i>";
+ ebox.BorderWidth = 3;
+ ebox.Add (emptyLabel);
+ Gtk.ToolItem mit = new Gtk.ToolItem ();
+ mit.Child = ebox;
+ ebox.ButtonPressEvent += OnNewItemPress;
+ Insert (mit, -1);
+ mit.ShowAll ();
+ addLabel = mit;
+ }
+
+ void AddSpacerItem ()
+ {
+ if (spacerItem == null) {
+ Gtk.ToolItem tb = new Gtk.ToolItem ();
+ Gtk.Label emptyLabel = new Gtk.Label ();
+ emptyLabel.Xalign = 0;
+ emptyLabel.Xpad = 3;
+ emptyLabel.Ypad = 3;
+ if (this.Orientation == Gtk.Orientation.Vertical)
+ emptyLabel.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("Empty\ntoolbar") + "</span></i>";
+ else
+ emptyLabel.Markup = "<i><span foreground='darkgrey'>" + Catalog.GetString ("Empty toolbar") + "</span></i>";
+ tb.Child = emptyLabel;
+ Insert (tb, -1);
+ ShowAll ();
+ spacerItem = tb;
+ }
+ }
+
+ void HideSpacerItem ()
+ {
+ if (spacerItem != null) {
+ Remove (spacerItem);
+ spacerItem = null;
+ }
+ }
+
+ void AddItem (ActionToolItem aitem, int pos)
+ {
+ aitem.KeyPressEvent += OnItemKeyPress;
+
+ CustomToolbarItem it = new CustomToolbarItem ();
+ it.ActionToolItem = aitem;
+ it.Child = aitem;
+ it.ShowAll ();
+ Insert (it, pos);
+ }
+
+ public bool ShowInsertPlaceholder {
+ get { return showPlaceholder; }
+ set {
+ showPlaceholder = value;
+ if (value && addLabel == null) {
+ AddCreateItemLabel ();
+ } else if (!value && addLabel != null) {
+ Remove (addLabel);
+ addLabel.Destroy ();
+ addLabel = null;
+ if (actionTree.Children.Count == 0)
+ AddSpacerItem ();
+ }
+ }
+ }
+
+ public Stetic.Editor.ActionMenu OpenSubmenu {
+ get { return null; }
+ set { }
+ }
+
+ public bool IsTopMenu {
+ get { return true; }
+ }
+
+ public Gtk.Widget Widget {
+ get { return this; }
+ }
+
+ public void Unselect ()
+ {
+ // Unselects any selected item
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area != null) {
+ foreach (Gtk.Widget w in Children) {
+ CustomToolbarItem it = w as CustomToolbarItem;
+ if (it != null)
+ area.ResetSelection (it.ActionToolItem);
+ }
+ }
+ }
+
+ void OnChildAdded (object ob, ActionTreeNodeArgs args)
+ {
+ Refresh ();
+ }
+
+ void OnChildRemoved (object ob, ActionTreeNodeArgs args)
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ IDesignArea area = wrapper.GetDesignArea ();
+ IObjectSelection asel = area.GetSelection ();
+ ActionToolItem curSel = asel != null ? asel.DataObject as ActionToolItem : null;
+ int pos = toolItems.IndexOf (curSel);
+
+ foreach (Gtk.Widget w in Children) {
+ if (w is CustomToolbarItem && ((CustomToolbarItem)w).ActionToolItem.Node == args.Node) {
+ Remove (w);
+ toolItems.Remove (((CustomToolbarItem)w).ActionToolItem);
+ w.Destroy ();
+ if (!showPlaceholder && toolItems.Count == 0)
+ AddSpacerItem ();
+ break;
+ }
+ }
+
+ if (pos != -1 && pos < toolItems.Count)
+ ((ActionToolItem)toolItems[pos]).Select ();
+ else if (toolItems.Count > 0)
+ ((ActionToolItem)toolItems[toolItems.Count-1]).Select ();
+ }
+
+ void Refresh ()
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area == null)
+ return;
+
+ ActionTreeNode selNode = null;
+
+ foreach (Gtk.Widget w in Children) {
+ CustomToolbarItem it = w as CustomToolbarItem;
+ if (it != null && area.IsSelected (it.ActionToolItem)) {
+ selNode = it.ActionToolItem.Node;
+ area.ResetSelection (it.ActionToolItem);
+ }
+ Remove (w);
+ w.Destroy ();
+ }
+
+ FillMenu (actionTree);
+
+ if (selNode != null) {
+ ActionToolItem mi = FindMenuItem (selNode);
+ if (mi != null)
+ mi.Select ();
+ }
+ }
+
+ [GLib.ConnectBeforeAttribute]
+ void OnNewItemPress (object ob, Gtk.ButtonPressEventArgs args)
+ {
+ InsertAction (toolItems.Count);
+ args.RetVal = true;
+ }
+
+ void InsertAction (int pos)
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ using (wrapper.UndoManager.AtomicChange) {
+ Wrapper.Action ac = (Wrapper.Action) ObjectWrapper.Create (wrapper.Project,
+ new Gtk.Action ("", "", null, null),
+ wrapper);
+ ActionTreeNode node = new ActionTreeNode (Gtk.UIManagerItemType.Toolitem, "", ac);
+ actionTree.Children.Insert (pos, node);
+
+ ActionToolItem aitem = FindMenuItem (node);
+ aitem.EditingDone += OnEditingDone;
+ aitem.Select ();
+ aitem.StartEditing (false);
+ //ShowInsertPlaceholder = false;
+
+ if (wrapper.LocalActionGroups.Count == 0)
+ wrapper.LocalActionGroups.Add (new ActionGroup ("Default"));
+ wrapper.LocalActionGroups[0].Actions.Add (ac);
+ }
+ }
+
+ void OnEditingDone (object ob, EventArgs args)
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ if (wrapper == null)
+ return;
+
+ IDesignArea area = wrapper.GetDesignArea ();
+ if (area == null) // The toolbar may be disposed before ending editing
+ return;
+
+ ActionToolItem item = (ActionToolItem) ob;
+ item.EditingDone -= OnEditingDone;
+
+ if (item.Node.Action.GtkAction.Label.Length == 0 && item.Node.Action.GtkAction.StockId == null) {
+ area.ResetSelection (item);
+ using (wrapper.UndoManager.AtomicChange) {
+ actionTree.Children.Remove (item.Node);
+ wrapper.LocalActionGroups [0].Actions.Remove (item.Node.Action);
+ }
+ }
+ }
+
+ public void Select (ActionTreeNode node)
+ {
+ ActionToolItem item = FindMenuItem (node);
+ if (item != null)
+ item.Select ();
+ }
+
+ protected override bool OnDragMotion (Gdk.DragContext context, int x, int y, uint time)
+ {
+ ActionPaletteItem dragItem = DND.DragWidget as ActionPaletteItem;
+ if (dragItem == null)
+ return false;
+
+ x += Allocation.X;
+ y += Allocation.Y;
+
+ if (actionTree.Children.Count > 0) {
+ ActionToolItem item = LocateWidget (x, y);
+ if (item != null) {
+ // Look for the index where to insert the new item
+ dropIndex = actionTree.Children.IndexOf (item.Node);
+ int spos = (Orientation == Gtk.Orientation.Horizontal) ? x : y;
+ int mpos = GetButtonPos (item) + GetButtonSize (item) / 2;
+ if (spos > mpos)
+ dropIndex++;
+
+ // Calculate the drop position, used to show the drop bar
+ if (dropIndex == 0)
+ dropPosition = GetButtonPos (item);
+ else if (dropIndex == toolItems.Count)
+ dropPosition = GetButtonEndPos (item);
+ else {
+ item = (ActionToolItem) toolItems [dropIndex];
+ ActionToolItem prevItem = (ActionToolItem) toolItems [dropIndex - 1];
+ dropPosition = GetButtonEndPos (prevItem) + (GetButtonPos (item) - GetButtonEndPos (prevItem))/2;
+ }
+ }
+ } else
+ dropIndex = 0;
+
+ QueueDraw ();
+ return base.OnDragMotion (context, x, y, time);
+ }
+
+ int GetButtonPos (Gtk.Widget w)
+ {
+ return (Orientation == Gtk.Orientation.Horizontal) ? w.Allocation.X : w.Allocation.Y;
+ }
+
+ int GetButtonEndPos (Gtk.Widget w)
+ {
+ return (Orientation == Gtk.Orientation.Horizontal) ? w.Allocation.Right : w.Allocation.Bottom;
+ }
+
+ int GetButtonSize (Gtk.Widget w)
+ {
+ return (Orientation == Gtk.Orientation.Horizontal) ? w.Allocation.Width : w.Allocation.Height;
+ }
+
+ protected override void OnDragLeave (Gdk.DragContext context, uint time)
+ {
+ dropPosition = -1;
+ QueueDraw ();
+ base.OnDragLeave (context, time);
+ }
+
+ protected override bool OnDragDrop (Gdk.DragContext context, int x, int y, uint time)
+ {
+ ActionPaletteItem dropped = DND.Drop (context, null, time) as ActionPaletteItem;
+ if (dropped == null)
+ return false;
+
+ if (dropped.Node.Type != Gtk.UIManagerItemType.Menuitem &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Toolitem &&
+ dropped.Node.Type != Gtk.UIManagerItemType.Separator)
+ return false;
+
+ ActionTreeNode newNode = dropped.Node;
+ if (dropped.Node.Type == Gtk.UIManagerItemType.Menuitem) {
+ newNode = newNode.Clone ();
+ newNode.Type = Gtk.UIManagerItemType.Toolitem;
+ }
+
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (this);
+ using (wrapper.UndoManager.AtomicChange) {
+ if (dropIndex < actionTree.Children.Count) {
+ // Do nothing if trying to drop the node over the same node
+ ActionTreeNode dropNode = actionTree.Children [dropIndex];
+ if (dropNode == newNode)
+ return false;
+
+ if (newNode.ParentNode != null)
+ newNode.ParentNode.Children.Remove (newNode);
+
+ // The drop position may have changed after removing the dropped node,
+ // so get it again.
+ dropIndex = actionTree.Children.IndexOf (dropNode);
+ actionTree.Children.Insert (dropIndex, newNode);
+ } else {
+ if (newNode.ParentNode != null)
+ newNode.ParentNode.Children.Remove (newNode);
+ actionTree.Children.Add (newNode);
+ dropIndex = actionTree.Children.Count - 1;
+ }
+ }
+ // Select the dropped node
+ ActionToolItem mi = (ActionToolItem) toolItems [dropIndex];
+ mi.Select ();
+
+ return base.OnDragDrop (context, x, y, time);
+ }
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ bool r = base.OnExposeEvent (ev);
+ if (dropPosition != -1) {
+ if (this.Orientation == Gtk.Orientation.Horizontal)
+ GdkWindow.DrawRectangle (this.Style.BlackGC, true, dropPosition, Allocation.Y, 3, Allocation.Height);
+ else
+ GdkWindow.DrawRectangle (this.Style.BlackGC, true, Allocation.X, dropPosition, Allocation.Width, 3);
+ }
+ return r;
+ }
+
+ void OnItemKeyPress (object s, Gtk.KeyPressEventArgs args)
+ {
+ int pos = toolItems.IndexOf (s);
+ args.RetVal = false;
+
+ switch (args.Event.Key) {
+ case Gdk.Key.Left:
+ args.RetVal = true;
+ if (pos > 0)
+ ((ActionToolItem)toolItems[pos - 1]).Select ();
+ break;
+ case Gdk.Key.Right:
+ args.RetVal = true;
+ if (pos < toolItems.Count - 1)
+ ((ActionToolItem)toolItems[pos + 1]).Select ();
+ else if (pos == toolItems.Count - 1)
+ InsertAction (toolItems.Count);
+ break;
+ }
+ }
+
+ void InsertActionAt (ActionToolItem item, bool after, bool separator)
+ {
+ int pos = toolItems.IndexOf (item);
+ if (pos == -1)
+ return;
+
+ if (after)
+ pos++;
+
+ if (separator) {
+ ActionTreeNode newNode = new ActionTreeNode (Gtk.UIManagerItemType.Separator, null, null);
+ actionTree.Children.Insert (pos, newNode);
+ } else
+ InsertAction (pos);
+ }
+
+ void Paste (ActionToolItem item)
+ {
+ }
+
+ public void ShowContextMenu (ActionItem aitem)
+ {
+ ActionToolItem menuItem = aitem as ActionToolItem;
+
+ Gtk.Menu m = new Gtk.Menu ();
+ Gtk.MenuItem item = new Gtk.MenuItem (Catalog.GetString ("Insert Before"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, false, false);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert After"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, true, false);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert Separator Before"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, false, true);
+ };
+ item = new Gtk.MenuItem (Catalog.GetString ("Insert Separator After"));
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ InsertActionAt (menuItem, true, true);
+ };
+
+ m.Add (new Gtk.SeparatorMenuItem ());
+
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Cut, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Cut ();
+ };
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Copy, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Copy ();
+ };
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Paste, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ Paste (menuItem);
+ };
+ item = new Gtk.ImageMenuItem (Gtk.Stock.Delete, null);
+ m.Add (item);
+ item.Activated += delegate (object s, EventArgs a) {
+ menuItem.Delete ();
+ };
+ m.ShowAll ();
+ m.Popup ();
+ }
+
+ public object SaveStatus ()
+ {
+ for (int n=0; n<toolItems.Count; n++)
+ if (((ActionToolItem)toolItems[n]).IsSelected)
+ return n;
+ return null;
+ }
+
+ public void RestoreStatus (object stat)
+ {
+ if (stat == null)
+ return;
+ int n = (int) stat;
+ if (n < toolItems.Count)
+ ((ActionToolItem)toolItems[n]).Select ();
+ }
+
+ ActionToolItem LocateWidget (int x, int y)
+ {
+ foreach (ActionToolItem mi in toolItems) {
+ if (mi.Allocation.Contains (x, y))
+ return mi;
+ }
+ return null;
+ }
+
+ ActionToolItem FindMenuItem (ActionTreeNode node)
+ {
+ foreach (ActionToolItem mi in toolItems) {
+ if (mi.Node == node)
+ return mi;
+ }
+ return null;
+ }
+ }
+
+ class CustomToolbarItem: Gtk.ToolItem
+ {
+ public override void Dispose ()
+ {
+ ActionToolItem.Destroy ();
+ base.Dispose ();
+ }
+
+ public ActionToolItem ActionToolItem;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Boolean.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Boolean.cs
new file mode 100644
index 0000000000..26d4a12c55
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Boolean.cs
@@ -0,0 +1,67 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class Boolean : PropertyEditorCell
+ {
+ static int indicatorSize;
+ static int indicatorSpacing;
+
+ static Boolean ()
+ {
+ Gtk.CheckButton cb = new Gtk.CheckButton ();
+ indicatorSize = (int) cb.StyleGetProperty ("indicator-size");
+ indicatorSpacing = (int) cb.StyleGetProperty ("indicator-spacing");
+ }
+
+ public override void GetSize (int availableWidth, out int width, out int height)
+ {
+ width = 20;
+ height = 20;
+ }
+
+ public override void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state)
+ {
+ Gtk.ShadowType sh = (bool) Value ? Gtk.ShadowType.In : Gtk.ShadowType.Out;
+ int s = indicatorSize - 1;
+ if (s > bounds.Height)
+ s = bounds.Height;
+ if (s > bounds.Width)
+ s = bounds.Width;
+ Gtk.Style.PaintCheck (Container.Style, window, state, sh, bounds, Container, "checkbutton", bounds.X + indicatorSpacing - 1, bounds.Y + (bounds.Height - s)/2, s, s);
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new BooleanEditor ();
+ }
+ }
+
+ [PropertyEditor ("Active", "Toggled")]
+ public class BooleanEditor : Gtk.CheckButton, IPropertyEditor
+ {
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(bool))
+ throw new ApplicationException ("Boolean editor does not support editing values of type " + descriptor.PropertyType);
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ public object Value {
+ get { return Active; }
+ set { Active = (bool) value; }
+ }
+
+ protected override void OnToggled ()
+ {
+ base.OnToggled ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/CellRendererComboBox.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/CellRendererComboBox.cs
new file mode 100644
index 0000000000..186f446729
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/CellRendererComboBox.cs
@@ -0,0 +1,111 @@
+//
+// CellRendererComboBox.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Gtk;
+using Gdk;
+
+namespace Stetic.Editor
+{
+ public class CellRendererComboBox: CellRendererText
+ {
+ string[] values;
+ string path;
+ int rowHeight;
+
+ public CellRendererComboBox ()
+ {
+ Mode |= Gtk.CellRendererMode.Editable;
+ Entry dummyEntry = new Gtk.Entry ();
+ rowHeight = dummyEntry.SizeRequest ().Height;
+ }
+
+ public string[] Values {
+ get { return values; }
+ set { values = value; }
+ }
+
+ public override void GetSize (Widget widget, ref Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
+ {
+ base.GetSize (widget, ref cell_area, out x_offset, out y_offset, out width, out height);
+ if (height < rowHeight)
+ height = rowHeight;
+ }
+
+ public override CellEditable StartEditing (Gdk.Event ev, Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, CellRendererState flags)
+ {
+ this.path = path;
+
+ Gtk.ComboBox combo = Gtk.ComboBox.NewText ();
+ foreach (string s in values)
+ combo.AppendText (s);
+
+ combo.Active = Array.IndexOf (values, Text);
+ combo.Changed += new EventHandler (SelectionChanged);
+ return new TreeViewCellContainer (combo);
+ }
+
+ void SelectionChanged (object s, EventArgs a)
+ {
+ Gtk.ComboBox combo = (Gtk.ComboBox) s;
+ if (Changed != null)
+ Changed (this, new ComboSelectionChangedArgs (path, combo.Active, (combo.Active != -1 ? values [combo.Active] : null)));
+ }
+
+ // Fired when the selection changes
+ public event ComboSelectionChangedHandler Changed;
+ }
+
+ public delegate void ComboSelectionChangedHandler (object sender, ComboSelectionChangedArgs args);
+
+ public class ComboSelectionChangedArgs: EventArgs
+ {
+ string path;
+ int active;
+ string activeText;
+
+ internal ComboSelectionChangedArgs (string path, int active, string activeText)
+ {
+ this.path = path;
+ this.active = active;
+ this.activeText = activeText;
+ }
+
+ public string Path {
+ get { return path; }
+ }
+
+ public int Active {
+ get { return active; }
+ }
+
+ public string ActiveText {
+ get { return activeText; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ChangeLog
new file mode 100644
index 0000000000..35c0dbd643
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ChangeLog
@@ -0,0 +1,16 @@
+2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * SelectIconDialog.cs: Remove setting Project.Modified property
+ * EditIconFactoryDialog.cs: Remove setting Project.Modified property
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ActionMenu.cs: Pass root wrapper as an argument for ObjectWrapper.Create
+ * ActionToolbar.cs:
+ * ActionMenuBar.cs:
+ * ActionGroupEditor.cs:
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * SelectImageDialog.cs:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Char.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Char.cs
new file mode 100644
index 0000000000..e27b1b7662
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Char.cs
@@ -0,0 +1,45 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class Char : Gtk.Entry, IPropertyEditor {
+
+ public Char ()
+ {
+ MaxLength = 1;
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(char))
+ throw new ApplicationException ("Char editor does not support editing values of type " + descriptor.PropertyType);
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ char last;
+
+ public object Value {
+ get {
+ if (Text.Length == 0)
+ return last;
+ else
+ return Text[0];
+ }
+ set {
+ Text = value.ToString ();
+ last = (char) value;
+ }
+ }
+
+ protected override void OnChanged ()
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Color.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Color.cs
new file mode 100644
index 0000000000..b771521aad
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Color.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class Color: PropertyEditorCell
+ {
+ public override void GetSize (int availableWidth, out int width, out int height)
+ {
+ width = 16;
+ height = 16;
+ }
+
+ public override void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state)
+ {
+ Gdk.GC gc = new Gdk.GC (window);
+ gc.RgbFgColor = (Gdk.Color) Value;
+ window.DrawRectangle (gc, true, bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
+ window.DrawRectangle (Container.Style.BlackGC, false, bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new ColorEditor ();
+ }
+ }
+
+ [PropertyEditor ("Color", "ColorSet")]
+ public class ColorEditor : Gtk.ColorButton, IPropertyEditor
+ {
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(Gdk.Color))
+ throw new ApplicationException ("Color editor does not support editing values of type " + descriptor.PropertyType);
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ public object Value {
+ get { return Color; }
+ set { Color = (Gdk.Color) value; }
+ }
+
+ protected override void OnColorSet ()
+ {
+ base.OnColorSet ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/DateTimeEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/DateTimeEditor.cs
new file mode 100644
index 0000000000..f338b8c54e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/DateTimeEditor.cs
@@ -0,0 +1,72 @@
+
+using System;
+using Gtk;
+using Gdk;
+using System.Text;
+
+namespace Stetic.Editor
+{
+ public class DateTimeEditorCell: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ return ((DateTime)Value).ToLongDateString ();
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new DateTimeEditor ();
+ }
+ }
+
+ public class DateTimeEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Entry entry;
+ DateTime time;
+
+ public DateTimeEditor()
+ {
+ entry = new Gtk.Entry ();
+ entry.Changed += OnChanged;
+ PackStart (entry, true, true, 0);
+ ShowAll ();
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ public object Value {
+ get { return time; }
+ set {
+ time = (DateTime) value;
+ entry.Changed -= OnChanged;
+ entry.Text = time.ToString ("G");
+ entry.Changed += OnChanged;
+ }
+ }
+
+ void OnChanged (object o, EventArgs a)
+ {
+ string s = entry.Text;
+
+ foreach (string form in formats) {
+ try {
+ time = DateTime.ParseExact (s, form, null);
+ if (ValueChanged != null)
+ ValueChanged (this, a);
+ break;
+ } catch {
+ }
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ static string[] formats = {"u", "G", "g", "d", "T", "t"};
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconDialog.cs
new file mode 100644
index 0000000000..d5ea4d8678
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconDialog.cs
@@ -0,0 +1,284 @@
+
+using System;
+using System.Collections;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class EditIconDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.Entry nameEntry;
+ [Glade.Widget] Gtk.TreeView sourceList;
+ [Glade.Widget] Gtk.RadioButton radioSingle;
+ [Glade.Widget] Gtk.RadioButton radioMultiple;
+ [Glade.Widget] Gtk.Label imageLabel;
+ [Glade.Widget] Gtk.Image imageImage;
+ [Glade.Widget] Gtk.Button okButton;
+ [Glade.Widget] Gtk.HBox hboxSingle;
+ [Glade.Widget] Gtk.HBox hboxMultiple;
+ [Glade.Widget ("EditIconDialog")] Gtk.Dialog dialog;
+
+ Gtk.ListStore sourceListStore;
+
+ ProjectIconSet iconSet;
+ IProject project;
+
+ ImageInfo singleIcon;
+
+ string[] sizes = { Catalog.GetString ("All Sizes"), "Menu", "SmallToolbar", "LargeToolbar", "Button", "Dnd", "Dialog" };
+ string[] states = { Catalog.GetString ("All States"), "Normal", "Active", "Prelight", "Selected", "Insensitive" };
+ string[] directions = { Catalog.GetString ("All Directions"), "Ltr", "Rtl" };
+
+ public EditIconDialog (IProject project, ProjectIconSet iconSet)
+ {
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "EditIconDialog", null);
+ xml.Autoconnect (this);
+ dialog.Response += OnResponse;
+
+ this.project = project;
+ this.iconSet = iconSet;
+
+ nameEntry.Text = iconSet.Name;
+
+ if (iconSet.Sources.Count == 0) {
+ radioSingle.Active = true;
+ imageLabel.Text = "";
+ }
+ else if (iconSet.Sources.Count == 1 && iconSet.Sources[0].AllWildcarded) {
+ radioSingle.Active = true;
+ singleIcon = iconSet.Sources[0].Image;
+ if (singleIcon != null) {
+ imageLabel.Text = singleIcon.Label;
+ imageImage.Pixbuf = singleIcon.GetThumbnail (project, 16);
+ } else
+ imageLabel.Text = "";
+ } else {
+ radioMultiple.Active = true;
+ }
+
+ hboxSingle.Sensitive = radioSingle.Active;
+ hboxMultiple.Sensitive = !radioSingle.Active;
+
+ // Build the tree
+
+ sourceListStore = new Gtk.ListStore (typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string), typeof(string), typeof(object));
+ sourceList.Model = sourceListStore;
+
+ Gtk.TreeViewColumn col = new Gtk.TreeViewColumn ();
+
+ Gtk.CellRendererPixbuf pr = new Gtk.CellRendererPixbuf ();
+ col.Title = Catalog.GetString ("Image");
+ col.PackStart (pr, false);
+ col.AddAttribute (pr, "pixbuf", 0);
+
+ Gtk.CellRendererText crt = new Gtk.CellRendererText ();
+ col.PackStart (crt, true);
+ col.AddAttribute (crt, "text", 1);
+ sourceList.AppendColumn (col);
+
+ col = new Gtk.TreeViewColumn ();
+ col.Expand = true;
+ col.Title = Catalog.GetString ("Size");
+ CellRendererComboBox crtb = new CellRendererComboBox ();
+ crtb.Changed += new ComboSelectionChangedHandler (OnSizeComboChanged);
+ crtb.Values = sizes;
+ col.PackStart (crtb, true);
+ col.AddAttribute (crtb, "text", 2);
+ sourceList.AppendColumn (col);
+
+ col = new Gtk.TreeViewColumn ();
+ col.Expand = true;
+ col.Title = Catalog.GetString ("State");
+ crtb = new CellRendererComboBox ();
+ crtb.Changed += new ComboSelectionChangedHandler (OnStateComboChanged);
+ crtb.Values = states;
+ col.PackStart (crtb, true);
+ col.AddAttribute (crtb, "text", 3);
+ sourceList.AppendColumn (col);
+
+ col = new Gtk.TreeViewColumn ();
+ col.Expand = true;
+ col.Title = Catalog.GetString ("Direction");
+ crtb = new CellRendererComboBox ();
+ crtb.Changed += new ComboSelectionChangedHandler (OnDirComboChanged);
+ crtb.Values = directions;
+ col.PackStart (crtb, true);
+ col.AddAttribute (crtb, "text", 4);
+ sourceList.AppendColumn (col);
+
+ foreach (ProjectIconSource source in iconSet.Sources)
+ AddSource (source);
+
+ UpdateButtons ();
+ }
+
+ public Gtk.Window TransientFor {
+ set { dialog.TransientFor = value; }
+ }
+
+ public int Run ()
+ {
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ void AddSource (ProjectIconSource source)
+ {
+ string size = source.SizeWildcarded ? sizes[0] : source.Size.ToString ();
+ string state = source.StateWildcarded ? states[0] : source.State.ToString ();
+ string dir = source.DirectionWildcarded ? directions[0] : source.Direction.ToString ();
+ sourceListStore.AppendValues (source.Image.GetThumbnail (project, 16), source.Image.Label, size, state, dir, source.Image);
+ }
+
+ ProjectIconSource GetSource (Gtk.TreeIter iter)
+ {
+ ProjectIconSource src = new ProjectIconSource ();
+ src.Image = (ImageInfo) sourceListStore.GetValue (iter, 5);
+ string s = (string) sourceListStore.GetValue (iter, 2);
+ if (s == sizes[0])
+ src.SizeWildcarded = true;
+ else {
+ src.SizeWildcarded = false;
+ src.Size = (Gtk.IconSize) Enum.Parse (typeof(Gtk.IconSize), s);
+ }
+
+ s = (string) sourceListStore.GetValue (iter, 3);
+ if (s == states[0])
+ src.StateWildcarded = true;
+ else {
+ src.StateWildcarded = false;
+ src.State = (Gtk.StateType) Enum.Parse (typeof(Gtk.StateType), s);
+ }
+
+ s = (string) sourceListStore.GetValue (iter, 4);
+ if (s == directions[0])
+ src.DirectionWildcarded = true;
+ else {
+ src.DirectionWildcarded = false;
+ src.Direction = (Gtk.TextDirection) Enum.Parse (typeof(Gtk.TextDirection), s);
+ }
+
+ return src;
+ }
+
+ void Save ()
+ {
+ iconSet.Name = nameEntry.Text;
+ iconSet.Sources.Clear ();
+
+ if (radioSingle.Active) {
+ ProjectIconSource src = new ProjectIconSource ();
+ src.AllWildcarded = true;
+ src.Image = singleIcon;
+ iconSet.Sources.Add (src);
+ } else {
+ Gtk.TreeIter iter;
+ if (sourceListStore.GetIterFirst (out iter)) {
+ do {
+ iconSet.Sources.Add (GetSource (iter));
+ }
+ while (sourceListStore.IterNext (ref iter));
+ }
+ }
+ }
+
+ void OnResponse (object o, Gtk.ResponseArgs args)
+ {
+ if (args.ResponseId == Gtk.ResponseType.Ok)
+ Save ();
+ }
+
+ protected void OnSelectImage (object s, EventArgs args)
+ {
+ using (SelectImageDialog dlg = new SelectImageDialog (dialog, project)) {
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ singleIcon = dlg.Icon;
+ imageLabel.Text = singleIcon.Label;
+ imageImage.Pixbuf = singleIcon.GetThumbnail (project, 16);
+ UpdateButtons ();
+ }
+ }
+ }
+
+ protected void OnAddSource (object s, EventArgs args)
+ {
+ using (SelectImageDialog dlg = new SelectImageDialog (dialog, project)) {
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ ProjectIconSource src = new ProjectIconSource ();
+ src.Image = dlg.Icon;
+ src.AllWildcarded = true;
+ AddSource (src);
+ UpdateButtons ();
+ }
+ }
+ }
+
+ protected void OnRemoveSource (object s, EventArgs args)
+ {
+ Gtk.TreeIter iter;
+ Gtk.TreeModel model;
+ if (sourceList.Selection.GetSelected (out model, out iter)) {
+ sourceListStore.Remove (ref iter);
+ UpdateButtons ();
+ }
+ }
+
+ protected void OnSingleClicked (object s, EventArgs args)
+ {
+ hboxSingle.Sensitive = true;
+ hboxMultiple.Sensitive = false;
+ UpdateButtons ();
+ }
+
+ protected void OnMultipleClicked (object s, EventArgs args)
+ {
+ hboxSingle.Sensitive = false;
+ hboxMultiple.Sensitive = true;
+ UpdateButtons ();
+ }
+
+ protected void OnNameChanged (object s, EventArgs args)
+ {
+ UpdateButtons ();
+ }
+
+ void OnSizeComboChanged (object s, ComboSelectionChangedArgs args)
+ {
+ UpdateComboValue (args.Path, 2, args.ActiveText);
+ }
+
+ void OnStateComboChanged (object s, ComboSelectionChangedArgs args)
+ {
+ UpdateComboValue (args.Path, 3, args.ActiveText);
+ }
+
+ void OnDirComboChanged (object s, ComboSelectionChangedArgs args)
+ {
+ UpdateComboValue (args.Path, 4, args.ActiveText);
+ }
+
+ void UpdateComboValue (string path, int col, string activeText)
+ {
+ Gtk.TreeIter iter;
+ if (sourceListStore.GetIter (out iter, new Gtk.TreePath (path))) {
+ sourceListStore.SetValue (iter, col, activeText);
+ }
+ }
+
+ void UpdateButtons ()
+ {
+ if (nameEntry.Text.Length == 0) {
+ okButton.Sensitive = false;
+ } else if (radioSingle.Active) {
+ okButton.Sensitive = singleIcon != null;
+ } else {
+ Gtk.TreeIter iter;
+ okButton.Sensitive = sourceListStore != null && sourceListStore.GetIterFirst (out iter);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconFactoryDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconFactoryDialog.cs
new file mode 100644
index 0000000000..ee4f5c29ec
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/EditIconFactoryDialog.cs
@@ -0,0 +1,95 @@
+
+using System;
+using System.Collections;
+using System.IO;
+using Gtk;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class EditIconFactoryDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.ScrolledWindow iconListScrolledwindow;
+ [Glade.Widget ("EditIconFactoryDialog")] Gtk.Dialog dialog;
+
+ ProjectIconList customIconList;
+
+ Gtk.Window parent;
+ Stetic.IProject project;
+ ProjectIconFactory iconFactory;
+
+ public EditIconFactoryDialog (Gtk.Window parent, Stetic.IProject project, ProjectIconFactory iconFactory)
+ {
+ this.iconFactory = iconFactory;
+ this.parent = parent;
+ this.project = project;
+
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "EditIconFactoryDialog", null);
+ xml.Autoconnect (this);
+
+ customIconList = new ProjectIconList (project, iconFactory);
+ iconListScrolledwindow.AddWithViewport (customIconList);
+ }
+
+ public int Run ()
+ {
+ dialog.ShowAll ();
+ dialog.TransientFor = parent;
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ protected void OnAddIcon (object ob, EventArgs args)
+ {
+ ProjectIconSet icon = new ProjectIconSet ();
+ using (EditIconDialog dlg = new EditIconDialog (project, icon)) {
+ if (parent != null)
+ dlg.TransientFor = parent.Toplevel as Gtk.Window;
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ iconFactory.Icons.Add (icon);
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+// project.Modified = true;
+ }
+ }
+ }
+
+ protected void OnRemoveIcon (object ob, EventArgs args)
+ {
+ string name = customIconList.Selection;
+ ProjectIconSet icon = iconFactory.GetIcon (name);
+ if (icon != null) {
+ Gtk.MessageDialog md = new Gtk.MessageDialog (dialog, Gtk.DialogFlags.Modal, Gtk.MessageType.Question, Gtk.ButtonsType.YesNo, string.Format (Catalog.GetString ("Are you sure you want to delete the icon '{0}'"), icon.Name));
+ if (parent != null)
+ md.TransientFor = parent.Toplevel as Gtk.Window;
+ if (md.Run () == (int) Gtk.ResponseType.Yes) {
+ iconFactory.Icons.Remove (icon);
+ customIconList.Refresh ();
+// project.Modified = true;
+ }
+ md.Destroy ();
+ }
+ }
+
+ protected void OnEditIcon (object ob, EventArgs args)
+ {
+ string name = customIconList.Selection;
+ ProjectIconSet icon = iconFactory.GetIcon (name);
+ if (icon != null) {
+ using (EditIconDialog dlg = new EditIconDialog (project, icon)) {
+ if (parent != null)
+ dlg.TransientFor = parent.Toplevel as Gtk.Window;
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+// project.Modified = true;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Enumeration.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Enumeration.cs
new file mode 100644
index 0000000000..fd2237d02a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Enumeration.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections;
+
+namespace Stetic.Editor {
+
+ public class Enumeration: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ if (Value == null)
+ return "";
+
+ EnumDescriptor enm = Registry.LookupEnum (Property.PropertyType.FullName);
+ EnumValue ev = enm [(Enum)Value];
+ if (ev != null)
+ return ev.Label;
+ else
+ return "";
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new EnumerationEditor ();
+ }
+ }
+
+ public class EnumerationEditor : Gtk.HBox, IPropertyEditor {
+
+ Gtk.EventBox ebox;
+ Gtk.ComboBoxEntry combo;
+ EnumDescriptor enm;
+
+ public EnumerationEditor () : base (false, 0)
+ {
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (!prop.PropertyType.IsEnum)
+ throw new ApplicationException ("Enumeration editor does not support editing values of type " + prop.PropertyType);
+
+ ebox = new Gtk.EventBox ();
+ ebox.Show ();
+ PackStart (ebox, true, true, 0);
+
+ combo = Gtk.ComboBoxEntry.NewText ();
+ combo.Changed += combo_Changed;
+ combo.Entry.IsEditable = false;
+ combo.Entry.HasFrame = false;
+ combo.Entry.HeightRequest = combo.SizeRequest ().Height; // The combo does not set the entry to the correct size when it does not have a frame
+ combo.Show ();
+ ebox.Add (combo);
+
+ enm = Registry.LookupEnum (prop.PropertyType.FullName);
+ foreach (Enum value in enm.Values)
+ combo.AppendText (enm[value].Label);
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ public object Value {
+ get {
+ return enm.Values[combo.Active];
+ }
+ set {
+ int i = Array.IndexOf (enm.Values, (Enum)value);
+ if (i != -1)
+ combo.Active = i;
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ void combo_Changed (object o, EventArgs args)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ EnumValue value = enm[(Enum)Value];
+ if (value != null)
+ ebox.TooltipText = value.Description;
+ else
+ ebox.TooltipText = string.Empty;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Flags.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Flags.cs
new file mode 100644
index 0000000000..031d7a1319
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Flags.cs
@@ -0,0 +1,174 @@
+using Gtk;
+using System;
+using System.Collections;
+
+namespace Stetic.Editor {
+
+ public class Flags: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ if (Value == null)
+ return "";
+
+ uint value = (uint)(int)Value;
+ EnumDescriptor enm = Registry.LookupEnum (Property.PropertyType.FullName);
+ string txt = "";
+ foreach (Enum val in enm.Values) {
+ EnumValue eval = enm[val];
+ if (eval.Label == "")
+ continue;
+
+ if ((value & (uint) Convert.ToInt32 (eval.Value)) != 0) {
+ if (txt.Length > 0) txt += ", ";
+ txt += eval.Label;
+ }
+ }
+ return txt;
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new FlagsEditor ();
+ }
+ }
+
+ public class FlagsEditor : Gtk.HBox, IPropertyEditor {
+
+ EnumDescriptor enm;
+ Hashtable flags;
+ Gtk.Entry flagsLabel;
+ string property;
+
+ public FlagsEditor ()
+ {
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (!prop.PropertyType.IsEnum)
+ throw new ApplicationException ("Flags editor does not support editing values of type " + prop.PropertyType);
+
+ property = prop.Label;
+ Spacing = 3;
+
+ // For small enums, the editor is a list of checkboxes inside a frame
+ // For large enums (>5), use a selector dialog.
+
+ enm = Registry.LookupEnum (prop.PropertyType.FullName);
+
+ if (enm.Values.Length < 6)
+ {
+ Gtk.VBox vbox = new Gtk.VBox (true, 3);
+
+ flags = new Hashtable ();
+
+ foreach (Enum value in enm.Values) {
+ EnumValue eval = enm[value];
+ if (eval.Label == "")
+ continue;
+
+ Gtk.CheckButton check = new Gtk.CheckButton (eval.Label);
+ check.TooltipText = eval.Description;
+ uint uintVal = (uint) Convert.ToInt32 (eval.Value);
+ flags[check] = uintVal;
+ flags[uintVal] = check;
+
+ check.Toggled += FlagToggled;
+ vbox.PackStart (check, false, false, 0);
+ }
+
+ Gtk.Frame frame = new Gtk.Frame ();
+ frame.Add (vbox);
+ frame.ShowAll ();
+ PackStart (frame, true, true, 0);
+ }
+ else
+ {
+ flagsLabel = new Gtk.Entry ();
+ flagsLabel.IsEditable = false;
+ flagsLabel.HasFrame = false;
+ flagsLabel.ShowAll ();
+ PackStart (flagsLabel, true, true, 0);
+
+ Gtk.Button but = new Gtk.Button ("...");
+ but.Clicked += OnSelectFlags;
+ but.ShowAll ();
+ PackStart (but, false, false, 0);
+ }
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ public object Value {
+ get {
+ return Enum.ToObject (enm.EnumType, UIntValue);
+ }
+ set {
+ uint newVal = (uint)(int)value;
+ if (flagsLabel != null) {
+ string txt = "";
+ foreach (Enum val in enm.Values) {
+ EnumValue eval = enm[val];
+ if (eval.Label == "")
+ continue;
+
+ if ((newVal & (uint) Convert.ToInt32 (eval.Value)) != 0) {
+ if (txt.Length > 0) txt += ", ";
+ txt += eval.Label;
+ }
+ }
+ flagsLabel.Text = txt;
+ UIntValue = newVal;
+ }
+ else {
+ for (uint i = 1; i <= uintValue || i <= newVal; i = i << 1) {
+ if ((uintValue & i) != (newVal & i)) {
+ Gtk.CheckButton check = (Gtk.CheckButton)flags[i];
+ if (check != null)
+ check.Active = !check.Active;
+ }
+ }
+ }
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ uint uintValue;
+ uint UIntValue {
+ get {
+ return uintValue;
+ }
+ set {
+ if (uintValue != value) {
+ uintValue = value;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+ }
+
+ void FlagToggled (object o, EventArgs args)
+ {
+ Gtk.CheckButton check = (Gtk.CheckButton)o;
+ uint val = (uint)flags[o];
+
+ if (check.Active)
+ UIntValue |= val;
+ else
+ UIntValue &= ~val;
+ }
+
+ void OnSelectFlags (object o, EventArgs args)
+ {
+ using (FlagsSelectorDialog dialog = new FlagsSelectorDialog (null, enm, UIntValue, property)) {
+ if (dialog.Run () == (int) ResponseType.Ok) {
+ Value = Enum.ToObject (enm.EnumType, dialog.Value);
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FlagsSelectorDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FlagsSelectorDialog.cs
new file mode 100644
index 0000000000..f2d8ca75e7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FlagsSelectorDialog.cs
@@ -0,0 +1,79 @@
+
+using System;
+
+namespace Stetic.Editor
+{
+ public class FlagsSelectorDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.TreeView treeView;
+ [Glade.Widget ("FlagsSelectorDialog")] Gtk.Dialog dialog;
+ Gtk.ListStore store;
+ Gtk.Window parent;
+ uint flags;
+
+ public FlagsSelectorDialog (Gtk.Window parent, EnumDescriptor enumDesc, uint flags, string title)
+ {
+ this.flags = flags;
+ this.parent = parent;
+
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "FlagsSelectorDialog", null);
+ xml.Autoconnect (this);
+
+ store = new Gtk.ListStore (typeof(bool), typeof(string), typeof(uint));
+ treeView.Model = store;
+
+ Gtk.TreeViewColumn col = new Gtk.TreeViewColumn ();
+
+ Gtk.CellRendererToggle tog = new Gtk.CellRendererToggle ();
+ tog.Toggled += new Gtk.ToggledHandler (OnToggled);
+ col.PackStart (tog, false);
+ col.AddAttribute (tog, "active", 0);
+
+ Gtk.CellRendererText crt = new Gtk.CellRendererText ();
+ col.PackStart (crt, true);
+ col.AddAttribute (crt, "text", 1);
+
+ treeView.AppendColumn (col);
+
+ foreach (Enum value in enumDesc.Values) {
+ EnumValue eval = enumDesc[value];
+ if (eval.Label == "")
+ continue;
+ uint val = (uint) Convert.ToInt32 (eval.Value);
+ store.AppendValues (((flags & val) != 0), eval.Label, val);
+ }
+ }
+
+ public int Run ()
+ {
+ dialog.ShowAll ();
+ dialog.TransientFor = parent;
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ void OnToggled (object s, Gtk.ToggledArgs args)
+ {
+ Gtk.TreeIter iter;
+ if (!store.GetIterFromString (out iter, args.Path))
+ return;
+
+ bool oldValue = (bool) store.GetValue (iter, 0);
+ uint flag = (uint) store.GetValue (iter, 2);
+ store.SetValue (iter, 0, !oldValue);
+
+ if (oldValue)
+ flags &= ~flag;
+ else
+ flags |= flag;
+ }
+
+ public uint Value {
+ get { return flags; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FloatRange.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FloatRange.cs
new file mode 100644
index 0000000000..2b8894dbf3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/FloatRange.cs
@@ -0,0 +1,47 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class FloatRange : Gtk.SpinButton, IPropertyEditor
+ {
+ Type propType;
+
+ public FloatRange (): base (0, 0, 0.01)
+ {
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ propType = prop.PropertyType;
+
+ double min, max;
+
+ if (propType == typeof(double)) {
+ min = Double.MinValue;
+ max = Double.MaxValue;
+ } else if (propType == typeof(float)) {
+ min = float.MinValue;
+ max = float.MaxValue;
+ } else
+ throw new ApplicationException ("FloatRange editor does not support editing values of type " + propType);
+
+ if (prop.Minimum != null)
+ min = (double) Convert.ChangeType (prop.Minimum, typeof(double));
+ if (prop.Maximum != null)
+ max = (double) Convert.ChangeType (prop.Maximum, typeof(double));
+
+ SetRange (min, max);
+
+ Digits = 2;
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ object IPropertyEditor.Value {
+ get { return Convert.ChangeType (base.Value, propType); }
+ set { base.Value = (double) Convert.ChangeType (value, typeof(double)); }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/GroupPicker.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/GroupPicker.cs
new file mode 100644
index 0000000000..fd9d4b24cc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/GroupPicker.cs
@@ -0,0 +1,175 @@
+using Gtk;
+using Gdk;
+using GLib;
+using System;
+using System.Collections;
+using System.Reflection;
+using Mono.Unix;
+
+namespace Stetic.Editor {
+
+ [PropertyEditor ("Group", "Changed")]
+ class GroupPicker : Gtk.HBox, IPropertyEditor {
+
+ Gtk.ComboBox combo;
+ IRadioGroupManager manager;
+ ArrayList values;
+ string group;
+
+ const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
+
+ public GroupPicker () : base (false, 0)
+ {
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ }
+
+ public void AttachObject (object ob)
+ {
+ ob = ObjectWrapper.Lookup (ob);
+
+ IRadioGroupManagerProvider provider = ob as IRadioGroupManagerProvider;
+
+ if (provider == null)
+ throw new ArgumentException ("The class " + ob.GetType() + " does not implement IRadioGroupManagerProvider");
+
+ manager = provider.GetGroupManager ();
+ manager.GroupsChanged += GroupsChanged;
+ GroupsChanged ();
+ }
+
+ public override void Dispose ()
+ {
+ manager.GroupsChanged -= GroupsChanged;
+ base.Dispose ();
+ }
+
+ void GroupsChanged ()
+ {
+ if (combo != null) {
+ combo.Changed -= combo_Changed;
+ Remove (combo);
+ }
+
+ combo = Gtk.ComboBox.NewText ();
+ combo.Changed += combo_Changed;
+#if GTK_SHARP_2_6
+ combo.RowSeparatorFunc = RowSeparatorFunc;
+#endif
+ combo.Show ();
+ PackStart (combo, true, true, 0);
+
+ values = new ArrayList ();
+ int i = 0;
+ foreach (string name in manager.GroupNames) {
+ values.Add (name);
+ combo.AppendText (name);
+ if (name == group)
+ combo.Active = i;
+ i++;
+ }
+
+#if GTK_SHARP_2_6
+ combo.AppendText ("");
+#endif
+
+ combo.AppendText (Catalog.GetString ("Rename Group..."));
+ combo.AppendText (Catalog.GetString ("New Group..."));
+ }
+
+#if GTK_SHARP_2_6
+ bool RowSeparatorFunc (Gtk.TreeModel model, Gtk.TreeIter iter)
+ {
+ GLib.Value val = new GLib.Value ();
+ model.GetValue (iter, 0, ref val);
+ bool sep = ((string)val) == "";
+ val.Dispose ();
+ return sep;
+ }
+#endif
+
+ public object Value {
+ get {
+ return group;
+ }
+ set {
+ int index = values.IndexOf ((string) value);
+ if (index != -1) {
+ combo.Active = index;
+ group = values[index] as string;
+ }
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ void combo_Changed (object o, EventArgs args)
+ {
+ if (combo.Active >= values.Count) {
+ doDialog ();
+ return;
+ }
+
+ group = values[combo.Active] as string;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ void doDialog ()
+ {
+#if GTK_SHARP_2_6
+ bool rename = combo.Active == values.Count + 1;
+#else
+ bool rename = combo.Active == values.Count;
+#endif
+ Gtk.Dialog dialog = new Gtk.Dialog (
+ rename ? Catalog.GetString ("Rename Group") : Catalog.GetString ("New Group"),
+ combo.Toplevel as Gtk.Window,
+ Gtk.DialogFlags.Modal | Gtk.DialogFlags.NoSeparator,
+ Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
+ Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+ dialog.DefaultResponse = Gtk.ResponseType.Ok;
+ dialog.HasSeparator = false;
+ dialog.BorderWidth = 12;
+ dialog.VBox.Spacing = 18;
+ dialog.VBox.BorderWidth = 0;
+
+ Gtk.HBox hbox = new Gtk.HBox (false, 12);
+ Gtk.Label label = new Gtk.Label (rename ? Catalog.GetString ("_New name:") : Catalog.GetString ("_Name:"));
+ Gtk.Entry entry = new Gtk.Entry ();
+ label.MnemonicWidget = entry;
+ hbox.PackStart (label, false, false, 0);
+ entry.ActivatesDefault = true;
+ if (rename)
+ entry.Text = group;
+ hbox.PackStart (entry, true, true, 0);
+ dialog.VBox.PackStart (hbox, false, false, 0);
+
+ dialog.ShowAll ();
+ // Have to set this *after* ShowAll
+ dialog.ActionArea.BorderWidth = 0;
+ dialog.TransientFor = this.Toplevel as Gtk.Window;
+ Gtk.ResponseType response = (Gtk.ResponseType)dialog.Run ();
+ if (response == Gtk.ResponseType.Cancel || entry.Text.Length == 0) {
+ dialog.Destroy ();
+ Value = group; // reset combo.Active
+ return;
+ }
+
+ string oldname = group;
+ group = entry.Text;
+ dialog.Destroy ();
+
+ // FIXME: check that the new name doesn't already exist
+
+ // This will trigger a GroupsChanged, which will eventually
+ // update combo.Active
+ if (rename)
+ manager.Rename (oldname, group);
+ else
+ manager.Add (group);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconList.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconList.cs
new file mode 100644
index 0000000000..0803726b23
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconList.cs
@@ -0,0 +1,205 @@
+
+using System;
+using System.Collections;
+using Gtk;
+
+namespace Stetic.Editor
+{
+ // This is the internal class the represents the actual two-column
+ // icon list. This can't just be handled as an HBox inside the main
+ // window, because we need to override SetScrollAdjustments.
+ class IconList : Gtk.HBox
+ {
+ ThemedIconColumn left, right;
+ ArrayList IconNames = new ArrayList ();
+
+ public event EventHandler Activated;
+
+ protected IconList ()
+ {
+ left = new ThemedIconColumn ();
+ PackStart (left);
+ right = new ThemedIconColumn ();
+ PackStart (right);
+
+ left.Selection.Changed += LeftSelectionChanged;
+ right.Selection.Changed += RightSelectionChanged;
+ left.RowActivated += RowActivated;
+ right.RowActivated += RowActivated;
+ left.KeyPressEvent += ColumnKeyPressEvent;
+ right.KeyPressEvent += ColumnKeyPressEvent;
+ }
+
+ protected void AddIcon (string name, Gdk.Pixbuf pixbuf, string label)
+ {
+ int i = IconNames.Count;
+ IconNames.Add (name);
+
+ if (i % 2 == 0)
+ left.Append (pixbuf, name);
+ else
+ right.Append (pixbuf, name);
+ }
+
+ protected void Clear ()
+ {
+ IconNames.Clear ();
+ left.Clear ();
+ right.Clear ();
+ }
+
+ void RowActivated (object obj, RowActivatedArgs args)
+ {
+ if (Activated != null)
+ Activated (this, EventArgs.Empty);
+ }
+
+ public int SelectionIndex {
+ get {
+ Gtk.TreePath[] selection;
+ selection = left.Selection.GetSelectedRows ();
+ if (selection.Length > 0)
+ return selection[0].Indices[0] * 2;
+ selection = right.Selection.GetSelectedRows ();
+ if (selection.Length > 0)
+ return selection[0].Indices[0] * 2 + 1;
+ return -1;
+ }
+ set {
+ if (value != -1) {
+ if (value % 2 == 0)
+ left.SelectRow (value / 2);
+ else
+ right.SelectRow (value / 2);
+ } else {
+ left.Selection.UnselectAll ();
+ right.Selection.UnselectAll ();
+ }
+ }
+ }
+
+ public string Selection {
+ get {
+ int i = SelectionIndex;
+ if (i != -1)
+ return (string) IconNames [i];
+ else
+ return null;
+ }
+ set {
+ if (value != null)
+ SelectionIndex = IconNames.IndexOf (value);
+ else
+ SelectionIndex = -1;
+ }
+ }
+
+ public event EventHandler SelectionChanged;
+
+ public void Find (string text)
+ {
+ int selection = SelectionIndex;
+ for (int i = (selection + 1) % IconNames.Count; i != selection; i = (i + 1) % IconNames.Count) {
+ if (((string)IconNames[i]).IndexOf (text) != -1) {
+ SelectionIndex = i;
+ return;
+ }
+ }
+ SelectionIndex = -1;
+ }
+
+ void LeftSelectionChanged (object obj, EventArgs args)
+ {
+ if (left.Selection.GetSelectedRows().Length != 0)
+ right.Selection.UnselectAll ();
+ if (SelectionChanged != null)
+ SelectionChanged (this, EventArgs.Empty);
+ }
+
+ void RightSelectionChanged (object obj, EventArgs args)
+ {
+ if (right.Selection.GetSelectedRows().Length != 0)
+ left.Selection.UnselectAll ();
+ if (SelectionChanged != null)
+ SelectionChanged (this, EventArgs.Empty);
+ }
+
+ [GLib.ConnectBefore]
+ void ColumnKeyPressEvent (object obj, KeyPressEventArgs args)
+ {
+ if (args.Event.Key == Gdk.Key.Right) {
+ if (obj == (object)left) {
+ SelectionIndex++;
+ right.GrabFocus ();
+ }
+ args.RetVal = true;
+ } else if (args.Event.Key == Gdk.Key.Left) {
+ if (obj == (object)right) {
+ SelectionIndex--;
+ left.GrabFocus ();
+ }
+ args.RetVal = true;
+ }
+ }
+
+ protected override void OnSetScrollAdjustments (Gtk.Adjustment hadj, Gtk.Adjustment vadj)
+ {
+ left.SetScrollAdjustments (null, vadj);
+ right.SetScrollAdjustments (null, vadj);
+ }
+ }
+
+ // Another internal class. This is a single column of the ThemedIconList
+ class ThemedIconColumn : Gtk.TreeView
+ {
+ public ThemedIconColumn ()
+ {
+ Model = store = new Gtk.ListStore (typeof (Gdk.Pixbuf),
+ typeof (string));
+ HeadersVisible = false;
+ EnableSearch = false;
+
+ TreeViewColumn col;
+ CellRenderer renderer;
+
+ col = new TreeViewColumn ();
+ renderer = new CellRendererPixbuf ();
+ col.PackStart (renderer, false);
+ col.AddAttribute (renderer, "pixbuf", 0);
+ renderer = new CellRendererText ();
+ col.PackStart (renderer, false);
+ col.AddAttribute (renderer, "text", 1);
+ AppendColumn (col);
+ }
+
+ Gtk.ListStore store;
+
+ public void Append (Gdk.Pixbuf pixbuf, string name)
+ {
+ if (name.Length > 30)
+ name = name.Substring (0, 30) + "...";
+ store.AppendValues (pixbuf, name);
+ }
+
+ public void SelectRow (int row)
+ {
+ Gtk.TreeIter iter;
+ if (store.IterNthChild (out iter, row)) {
+ Gtk.TreePath path = store.GetPath (iter);
+
+ SetCursor (path, null, false);
+
+ // We want the initial selection to be centered
+ if (!IsRealized)
+ ScrollToCell (path, null, true, 0.5f, 0.0f);
+ }
+ }
+
+ public void Clear ()
+ {
+ store.Clear ();
+ }
+ }
+}
+
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorItem.cs
new file mode 100644
index 0000000000..9c5980ce04
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorItem.cs
@@ -0,0 +1,285 @@
+
+using System;
+using System.Reflection;
+using System.Collections;
+
+namespace Stetic.Editor
+{
+ public class IconSelectorItem: Gtk.EventBox
+ {
+ ArrayList icons = new ArrayList ();
+ ArrayList labels = new ArrayList ();
+ ArrayList names = new ArrayList ();
+ int columns = 12;
+ int iconSize = 16;
+ int spacing = 3;
+ int selIndex = -1;
+ int sectionGap = 10;
+ int lastSel = -1;
+ int xmax;
+ int ymax;
+ string title;
+ Gtk.Window tipWindow;
+ bool inited;
+
+ public IconSelectorItem (IntPtr ptr): base (ptr)
+ {
+ }
+
+ public IconSelectorItem (string title)
+ {
+ this.title = title;
+
+ int w, h;
+ Gtk.Icon.SizeLookup (Gtk.IconSize.Menu, out w, out h);
+ iconSize = w;
+
+ this.Events |= Gdk.EventMask.PointerMotionMask;
+ }
+
+ protected override void OnSizeRequested (ref Gtk.Requisition req)
+ {
+ if (!inited) {
+ CreateIcons ();
+ inited = true;
+ }
+
+ base.OnSizeRequested (ref req);
+ CalcSize ();
+
+ Gtk.Requisition nr = new Gtk.Requisition ();
+ nr.Width = xmax;
+ nr.Height = ymax;
+ req = nr;
+ }
+
+ protected virtual void CreateIcons ()
+ {
+ }
+
+ public int SelectedIndex {
+ get { return selIndex; }
+ }
+
+ public string SelectedIcon {
+ get {
+ if (selIndex != -1)
+ return (string) names [selIndex];
+ else
+ return null;
+ }
+ }
+
+ protected void AddIcon (string name, Gdk.Pixbuf pix, string label)
+ {
+ icons.Add (pix);
+ labels.Add (label);
+ names.Add (name);
+ }
+
+ protected void AddSeparator (string separator)
+ {
+ icons.Add (null);
+ labels.Add (null);
+ names.Add (separator);
+ }
+
+ protected override bool OnMotionNotifyEvent (Gdk.EventMotion ev)
+ {
+ ProcessMotionEvent ((int) ev.X, (int) ev.Y);
+ return true;
+ }
+
+ internal void ProcessMotionEvent (int x, int y)
+ {
+ int ix, iy;
+ GetIconIndex (x, y, out selIndex, out ix, out iy);
+ if (selIndex != -1) {
+ string name = labels [selIndex] as string;
+ if (name == null || name.Length == 0)
+ name = names [selIndex] as string;
+ if (selIndex != lastSel) {
+ HideTip ();
+ ShowTip (ix, iy + iconSize + spacing*2, name);
+ }
+ } else
+ HideTip ();
+
+ lastSel = selIndex;
+
+ QueueDraw ();
+ }
+
+ void ShowTip (int x, int y, string text)
+ {
+ if (GdkWindow == null)
+ return;
+ if (tipWindow == null) {
+ tipWindow = new TipWindow ();
+ Gtk.Label lab = new Gtk.Label (text);
+ lab.Xalign = 0;
+ lab.Xpad = 3;
+ lab.Ypad = 3;
+ tipWindow.Add (lab);
+ }
+ ((Gtk.Label)tipWindow.Child).Text = text;
+ int w = tipWindow.Child.SizeRequest().Width;
+ int ox, oy;
+ GdkWindow.GetOrigin (out ox, out oy);
+ tipWindow.Move (ox + x - (w/2) + (iconSize/2), oy + y);
+ tipWindow.ShowAll ();
+ }
+
+ void HideTip ()
+ {
+ if (tipWindow != null) {
+ tipWindow.Destroy ();
+ tipWindow = null;
+ }
+ }
+
+ public override void Dispose ()
+ {
+ HideTip ();
+ base.Dispose ();
+ }
+
+ protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing ev)
+ {
+ HideTip ();
+ return base.OnLeaveNotifyEvent (ev);
+ }
+
+ internal void ProcessLeaveNotifyEvent (Gdk.EventCrossing ev)
+ {
+ HideTip ();
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ Draw ();
+ return true;
+ }
+
+ void Draw ()
+ {
+ int a,b;
+ Expose (true, -1, -1, out a, out b);
+ }
+
+ void CalcSize ()
+ {
+ int a,b;
+ Expose (false, -1, -1, out a, out b);
+ }
+
+ void GetIconIndex (int x, int y, out int index, out int ix, out int iy)
+ {
+ index = Expose (false, x, y, out ix, out iy);
+ }
+
+ int Expose (bool draw, int testx, int testy, out int ix, out int iy)
+ {
+ int x = spacing;
+ int y = spacing;
+ int sx = spacing;
+ int maxx = columns * (iconSize + spacing) + spacing;
+ bool calcSize = (testx == -1);
+
+ Pango.Layout layout = new Pango.Layout (this.PangoContext);
+ Pango.FontDescription des = this.Style.FontDescription.Copy();
+ des.Size = 10 * (int) Pango.Scale.PangoScale;
+ layout.FontDescription = des;
+ layout.SetMarkup (title);
+ layout.Width = -1;
+ int w, h;
+ int tborder = 1;
+ layout.GetPixelSize (out w, out h);
+ if (draw) {
+ GdkWindow.DrawRectangle (this.Style.DarkGC (Gtk.StateType.Normal), true, x, y, Allocation.Width + tborder*2, h + tborder*2);
+ GdkWindow.DrawLayout (this.Style.ForegroundGC (Gtk.StateType.Normal), x + tborder + 2, y + tborder, layout);
+ }
+
+ if (calcSize)
+ xmax = 0;
+
+ y += h + spacing*2 + tborder*2;
+
+ for (int n=0; n<icons.Count; n++) {
+ string cmd = names [n] as string;
+ Gdk.Pixbuf pix = icons [n] as Gdk.Pixbuf;
+
+ if (cmd == "-") {
+ if (x > sx) {
+ y += iconSize + spacing;
+ }
+ x = sx;
+ y -= spacing;
+ if (draw) {
+ Gdk.Rectangle rect = new Gdk.Rectangle (0, y+(sectionGap/2), Allocation.Width - x, 1);
+ Gtk.Style.PaintHline (this.Style, this.GdkWindow, Gtk.StateType.Normal, rect, this, "", rect.X, rect.Right, rect.Y);
+ }
+ y += sectionGap;
+ continue;
+ }
+
+ if (cmd == "|") {
+ if (x == sx)
+ continue;
+ x += spacing;
+ if (draw) {
+ Gdk.Rectangle rect = new Gdk.Rectangle (x, y, 1, iconSize);
+ Gtk.Style.PaintVline (this.Style, this.GdkWindow, Gtk.StateType.Normal, rect, this, "", rect.Y, rect.Bottom, rect.X);
+ }
+ x += spacing*2;
+ continue;
+ }
+
+ if (testx != -1 && testx >= (x - spacing/2) && testx < (x + iconSize + spacing) && testy >= (y - spacing/2) && testy < (y + iconSize + spacing)) {
+ ix = x;
+ iy = y;
+ return n;
+ }
+
+ if (draw) {
+ Gtk.StateType state = (n == selIndex) ? Gtk.StateType.Selected : Gtk.StateType.Normal;
+ if (n == selIndex)
+ GdkWindow.DrawRectangle (this.Style.BackgroundGC (state), true, x-spacing, y-spacing, iconSize + spacing*2, iconSize + spacing*2);
+ GdkWindow.DrawPixbuf (this.Style.ForegroundGC (state), pix, 0, 0, x, y, pix.Width, pix.Height, Gdk.RgbDither.None, 0, 0);
+ }
+
+ x += (iconSize + spacing);
+ if (calcSize && x > xmax)
+ xmax = x;
+
+ if (x >= maxx) {
+ x = sx;
+ y += iconSize + spacing;
+ }
+ }
+ if (calcSize) {
+ if (x > sx)
+ y += iconSize + spacing;
+ ymax = y;
+ }
+
+ ix = iy = 0;
+ return -1;
+ }
+ }
+
+ class TipWindow: Gtk.Window
+ {
+ public TipWindow (): base (Gtk.WindowType.Popup)
+ {
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ base.OnExposeEvent (ev);
+ Gtk.Requisition req = SizeRequest ();
+ Gtk.Style.PaintFlatBox (this.Style, this.GdkWindow, Gtk.StateType.Normal, Gtk.ShadowType.Out, Gdk.Rectangle.Zero, this, "tooltip", 0, 0, req.Width, req.Height);
+ return true;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenu.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenu.cs
new file mode 100644
index 0000000000..ab6af38d28
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenu.cs
@@ -0,0 +1,56 @@
+
+using System;
+using System.Reflection;
+using System.Collections;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class IconSelectorMenu: Gtk.Menu
+ {
+ IProject project;
+
+ public event IconEventHandler IconSelected;
+
+ public IconSelectorMenu (IProject project)
+ {
+ this.project = project;
+
+ // Stock icon selector
+ IconSelectorMenuItem selStock = new IconSelectorMenuItem (new StockIconSelectorItem ());
+ selStock.IconSelected += OnStockSelected;
+ Insert (selStock, -1);
+
+ // Project icon selector
+ if (project != null && project.IconFactory.Icons.Count > 0) {
+ IconSelectorMenuItem selProject = new IconSelectorMenuItem (new ProjectIconSelectorItem (project));
+ selProject.IconSelected += OnStockSelected;
+ Insert (selProject, -1);
+ }
+
+ Insert (new Gtk.SeparatorMenuItem (), -1);
+
+ Gtk.MenuItem it = new Gtk.MenuItem (Catalog.GetString ("More..."));
+ it.Activated += OnSetStockActionType;
+ Insert (it, -1);
+ }
+
+ void OnStockSelected (object s, IconEventArgs args)
+ {
+ if (IconSelected != null)
+ IconSelected (this, args);
+ }
+
+ void OnSetStockActionType (object ob, EventArgs args)
+ {
+ Stetic.Editor.SelectIconDialog dialog = new Stetic.Editor.SelectIconDialog (this.Toplevel as Gtk.Window, project);
+ using (dialog)
+ {
+ if (dialog.Run () != (int) Gtk.ResponseType.Ok)
+ return;
+ if (IconSelected != null)
+ IconSelected (this, new IconEventArgs (dialog.Icon));
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenuItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenuItem.cs
new file mode 100644
index 0000000000..5ac94883eb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IconSelectorMenuItem.cs
@@ -0,0 +1,59 @@
+
+using System;
+
+namespace Stetic.Editor
+{
+ public class IconSelectorMenuItem: Gtk.MenuItem
+ {
+ IconSelectorItem selector;
+
+ public event IconEventHandler IconSelected;
+
+ public IconSelectorMenuItem (IconSelectorItem item)
+ {
+ selector = item;
+ Add (selector);
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ if (IconSelected != null)
+ IconSelected (this, new IconEventArgs (selector.SelectedIcon));
+ selector.Destroy ();
+ return base.OnButtonPressEvent (ev);
+ }
+
+ protected override bool OnEnterNotifyEvent (Gdk.EventCrossing ev)
+ {
+ return true;
+ }
+
+ protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing ev)
+ {
+ selector.ProcessLeaveNotifyEvent (ev);
+ return true;
+ }
+
+ protected override bool OnMotionNotifyEvent (Gdk.EventMotion ev)
+ {
+ selector.ProcessMotionEvent ((int)ev.X - selector.Allocation.X + Allocation.X, (int)ev.Y - selector.Allocation.Y + Allocation.Y);
+ return true;
+ }
+ }
+
+ public delegate void IconEventHandler (object s, IconEventArgs args);
+
+ public class IconEventArgs: EventArgs
+ {
+ string iconId;
+
+ public IconEventArgs (string iconId)
+ {
+ this.iconId = iconId;
+ }
+
+ public string IconId {
+ get { return iconId; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Identifier.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Identifier.cs
new file mode 100644
index 0000000000..6b7c42101e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Identifier.cs
@@ -0,0 +1,78 @@
+
+using System;
+using System.Text;
+using Gtk;
+using Gdk;
+
+namespace Stetic.Editor
+{
+ public class Identifier: Gtk.Entry, IPropertyEditor
+ {
+ string id;
+ int min = -1;
+ int max = -1;
+
+ public Identifier()
+ {
+ ShowAll ();
+ HasFrame = false;
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(string))
+ throw new InvalidOperationException ("TextEditor only can edit string properties");
+
+ try {
+ if (descriptor.Minimum != null)
+ min = Convert.ToInt32 (descriptor.Minimum);
+ } catch {}
+
+ try {
+ if (descriptor.Maximum != null)
+ max = Convert.ToInt32 (descriptor.Maximum);
+ } catch {}
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ protected override bool OnFocusOutEvent (Gdk.EventFocus e)
+ {
+ DoChanged ();
+ return base.OnFocusOutEvent (e);
+ }
+
+ void DoChanged ()
+ {
+ StringBuilder sb = new StringBuilder ();
+ foreach (char c in Text) {
+ if (char.IsLetterOrDigit (c) || c == '_')
+ sb.Append (c);
+ }
+
+ string s = sb.ToString ();
+ if (min != -1 && s.Length < min)
+ return;
+ if (max != -1 && s.Length > max)
+ return;
+
+ if (s == Text) {
+ id = Text;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ } else {
+ Text = s;
+ }
+ }
+
+ public object Value {
+ get { return id; }
+ set { id = Text = (value != null ? (string) value : ""); }
+ }
+
+ // To be fired when the edited value changes.
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Image.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Image.cs
new file mode 100644
index 0000000000..0dbd5ed7e0
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Image.cs
@@ -0,0 +1,265 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using Mono.Unix;
+
+namespace Stetic.Editor {
+
+ [PropertyEditor ("Value", "Changed")]
+ public class Image : Gtk.HBox, IPropertyEditor {
+ Gtk.Image image;
+ Gtk.ComboBoxEntry combo;
+ Gtk.Entry entry;
+ Gtk.Button button;
+ Gtk.ListStore store;
+
+ const int IconColumn = 0;
+ const int LabelColumn = 1;
+
+ static string[] stockIds, stockLabels;
+ static int imgWidth, imgHeight;
+
+ static Image ()
+ {
+ ArrayList tmpIds = new ArrayList ();
+
+ // We can't use Gtk.Stock.ListIds, because that returns different
+ // values depending on what version of libgtk you have installed...
+ foreach (PropertyInfo info in typeof (Gtk.Stock).GetProperties (BindingFlags.Public | BindingFlags.Static)) {
+ if (info.CanRead && info.PropertyType == typeof (string))
+ tmpIds.Add (info.GetValue (null, null));
+ }
+ foreach (PropertyInfo info in GnomeStock.Properties) {
+ if (info.CanRead && info.PropertyType == typeof (string))
+ tmpIds.Add (info.GetValue (null, null));
+ }
+
+ ArrayList items = new ArrayList (), nonItems = new ArrayList ();
+ foreach (string id in tmpIds) {
+ Gtk.StockItem item = Gtk.Stock.Lookup (id);
+ if (item.StockId == null)
+ nonItems.Add (id);
+ else {
+ item.Label = item.Label.Replace ("_", "");
+ items.Add (item);
+ }
+ }
+ items.Sort (new StockItemSorter ());
+ nonItems.Sort ();
+
+ stockIds = new string[items.Count + nonItems.Count];
+ stockLabels = new string[items.Count + nonItems.Count];
+ for (int i = 0; i < items.Count; i++) {
+ stockIds[i] = ((Gtk.StockItem)items[i]).StockId;
+ stockLabels[i] = ((Gtk.StockItem)items[i]).Label;
+ }
+ for (int i = 0; i < nonItems.Count; i++) {
+ stockIds[i + items.Count] = nonItems[i] as string;
+ stockLabels[i + items.Count] = nonItems[i] as string;
+ }
+
+ Gtk.Icon.SizeLookup (Gtk.IconSize.Button, out imgWidth, out imgHeight);
+ }
+
+ class StockItemSorter : IComparer {
+ public int Compare (object itemx, object itemy)
+ {
+ Gtk.StockItem x = (Gtk.StockItem)itemx;
+ Gtk.StockItem y = (Gtk.StockItem)itemy;
+
+ return string.Compare (x.Label, y.Label);
+ }
+ }
+
+ public Image () : this (true, true) {}
+
+ public Image (bool allowStock, bool allowFile) : base (false, 6)
+ {
+ image = new Gtk.Image (GnomeStock.Blank, Gtk.IconSize.Button);
+ PackStart (image, false, false, 0);
+
+ if (allowStock) {
+ store = new Gtk.ListStore (typeof (string), typeof (string));
+ store.AppendValues (GnomeStock.Blank, Catalog.GetString ("(None)"));
+ for (int i = 0; i < stockIds.Length; i++)
+ store.AppendValues (stockIds[i], stockLabels[i]);
+
+ combo = new Gtk.ComboBoxEntry (store, LabelColumn);
+ Gtk.CellRendererPixbuf iconRenderer = new Gtk.CellRendererPixbuf ();
+ iconRenderer.StockSize = (uint)Gtk.IconSize.Menu;
+ combo.PackStart (iconRenderer, false);
+ combo.Reorder (iconRenderer, 0);
+ combo.AddAttribute (iconRenderer, "stock-id", IconColumn);
+ combo.Changed += combo_Changed;
+
+ // Pack the combo non-expandily into a VBox so it doesn't
+ // get stretched to the file button's height
+ Gtk.VBox vbox = new Gtk.VBox (false, 0);
+ vbox.PackStart (combo, true, false, 0);
+ PackStart (vbox, true, true, 0);
+
+ entry = (Gtk.Entry)combo.Child;
+ entry.Changed += entry_Changed;
+
+ useStock = true;
+ }
+
+ if (allowFile) {
+ if (!allowStock) {
+ entry = new Gtk.Entry ();
+ PackStart (entry, true, true, 0);
+ entry.Changed += entry_Changed;
+ }
+
+ button = new Gtk.Button ();
+ Gtk.Image icon = new Gtk.Image (Gtk.Stock.Open, Gtk.IconSize.Button);
+ button.Add (icon);
+ PackStart (button, false, false, 0);
+ button.Clicked += button_Clicked;
+ }
+ ShowAll ();
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(string))
+ throw new ApplicationException ("Image editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ public event EventHandler ValueChanged;
+
+ bool syncing;
+
+ void combo_Changed (object obj, EventArgs args)
+ {
+ if (syncing)
+ return;
+
+ useStock = true;
+ syncing = true;
+ if (combo.Active > 0)
+ StockId = stockIds[combo.Active - 1];
+ else
+ StockId = null;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ syncing = false;
+ }
+
+ void entry_Changed (object obj, EventArgs args)
+ {
+ if (syncing)
+ return;
+
+ useStock = true;
+ syncing = true;
+ StockId = entry.Text;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ syncing = false;
+ }
+
+ void button_Clicked (object obj, EventArgs args)
+ {
+ Gtk.FileChooserDialog dialog =
+ new Gtk.FileChooserDialog (Catalog.GetString ("Image"), null, Gtk.FileChooserAction.Open,
+ Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
+ Gtk.Stock.Open, Gtk.ResponseType.Ok);
+ dialog.TransientFor = this.Toplevel as Gtk.Window;
+ int response = dialog.Run ();
+ string file = dialog.Filename;
+ dialog.Destroy ();
+
+ if (response == (int)Gtk.ResponseType.Ok) {
+ syncing = true;
+ useStock = false;
+ entry.Text = file;
+ File = file;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ syncing = false;
+ }
+ }
+
+ bool useStock;
+
+ string stockId;
+ public string StockId {
+ get {
+ return stockId;
+ }
+ set {
+ useStock = true;
+ stockId = value;
+ file = null;
+
+ image.SetFromStock (stockId, Gtk.IconSize.Button);
+
+ if (!syncing) {
+ int id = Array.IndexOf (stockIds, value);
+ if (id != -1) {
+ syncing = true;
+ combo.Active = id + 1;
+ syncing = false;
+ }
+ }
+ }
+ }
+
+ string file;
+ public string File {
+ get {
+ return file;
+ }
+ set {
+ useStock = false;
+ stockId = null;
+ file = value;
+
+ if (value == null)
+ value = "";
+
+ try {
+ image.Pixbuf = new Gdk.Pixbuf (value, imgWidth, imgHeight);
+ } catch {
+ image.SetFromStock (GnomeStock.Blank, Gtk.IconSize.Button);
+ }
+
+ if (!syncing) {
+ syncing = true;
+ entry.Text = value;
+ syncing = false;
+ }
+ }
+ }
+
+ public virtual object Value {
+ get {
+ if (useStock) {
+ if (StockId != null)
+ return "stock:" + StockId;
+ else
+ return null;
+ } else {
+ if (File != null)
+ return "file:" + File;
+ else
+ return null;
+ }
+ }
+ set {
+ string val = value as string;
+ if (val == null)
+ File = null;
+ else if (val.StartsWith ("stock:"))
+ StockId = val.Substring (6);
+ else if (val.StartsWith ("file:"))
+ File = val.Substring (5);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageFile.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageFile.cs
new file mode 100644
index 0000000000..4d9ad3211a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageFile.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Stetic.Editor {
+
+ [PropertyEditor ("File", "Changed")]
+ public class ImageFile : Image {
+
+ public ImageFile () : base (false, true) { }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageSelector.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageSelector.cs
new file mode 100644
index 0000000000..d983c521ec
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ImageSelector.cs
@@ -0,0 +1,177 @@
+
+using System;
+
+namespace Stetic.Editor
+{
+ public class BaseImageCell: PropertyEditorCell
+ {
+ const int imgSize = 24;
+ const int imgPad = 2;
+ const int spacing = 5;
+ Gdk.Pixbuf image;
+
+ protected Gdk.Pixbuf Image {
+ get { return image; }
+ set { image = value; }
+ }
+
+ protected int ImageSize {
+ get { return 16; }//imgSize - imgPad*2; }
+ }
+
+ public override void GetSize (int availableWidth, out int width, out int height)
+ {
+ base.GetSize (availableWidth, out width, out height);
+ width += imgSize + spacing;
+ height = Math.Max (imgSize, height);
+ }
+
+ public override void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state)
+ {
+ int iy = bounds.Y + (bounds.Height - imgSize) / 2;
+
+ if (image != null) {
+ int dy = (imgSize - image.Height) / 2;
+ int dx = (imgSize - image.Width) / 2;
+ window.DrawPixbuf (Container.Style.BackgroundGC (state), image, 0, 0, bounds.X + dx, iy + dy, -1, -1, Gdk.RgbDither.None, 0, 0);
+ }
+
+ window.DrawRectangle (Container.Style.DarkGC (state), false, bounds.X, iy, imgSize - 1, imgSize - 1);
+
+ bounds.X += imgSize + spacing;
+ base.Render (window, bounds, state);
+ }
+ }
+
+ public class ImageSelector: BaseImageCell
+ {
+ IProject project;
+ ImageInfo imageInfo;
+
+ protected override void Initialize ()
+ {
+ base.Initialize ();
+
+ if (Property.PropertyType != typeof(ImageInfo))
+ throw new ApplicationException ("ImageSelector editor does not support editing values of type " + Property.PropertyType);
+
+ if (Instance == null)
+ return;
+
+ Stetic.ObjectWrapper w = Stetic.ObjectWrapper.Lookup (Instance);
+ project = w.Project;
+ imageInfo = (ImageInfo)Value;
+ if (imageInfo != null)
+ Image = imageInfo.GetThumbnail (project, ImageSize);
+ else
+ Image = null;
+ }
+
+ protected override string GetValueText ()
+ {
+ if (imageInfo == null)
+ return "";
+ return imageInfo.Label;
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new ImageSelectorEditor ();
+ }
+ }
+
+ public class ImageSelectorEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Image image;
+ Gtk.Label entry;
+ Gtk.Button button;
+ Gtk.Button clearButton;
+ ImageInfo icon;
+ IProject project;
+ Gtk.Frame imageFrame;
+
+ public ImageSelectorEditor()
+ {
+ Spacing = 3;
+ imageFrame = new Gtk.Frame ();
+ imageFrame.Shadow = Gtk.ShadowType.In;
+ imageFrame.BorderWidth = 2;
+ PackStart (imageFrame, false, false, 0);
+
+ image = new Gtk.Image (GnomeStock.Blank, Gtk.IconSize.Button);
+ imageFrame.Add (image);
+
+ Gtk.Frame frame = new Gtk.Frame ();
+ entry = new Gtk.Label ();
+ entry.Xalign = 0;
+ frame.Shadow = Gtk.ShadowType.In;
+ frame.BorderWidth = 2;
+ frame.Add (entry);
+ PackStart (frame, true, true, 0);
+
+ clearButton = new Gtk.Button (new Gtk.Image (Gtk.Stock.Clear, Gtk.IconSize.Menu));
+ clearButton.Clicked += OnClearImage;
+ PackStart (clearButton, false, false, 0);
+
+ button = new Gtk.Button ("...");
+ PackStart (button, false, false, 0);
+ button.Clicked += button_Clicked;
+ ShowAll ();
+ }
+
+ void button_Clicked (object obj, EventArgs args)
+ {
+ Gtk.Window parent = (Gtk.Window)GetAncestor (Gtk.Window.GType);
+ using (SelectImageDialog dlg = new SelectImageDialog (parent, project)) {
+ dlg.Icon = (ImageInfo) Value;
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok)
+ Value = dlg.Icon;
+ }
+ }
+
+ void OnClearImage (object obj, EventArgs args)
+ {
+ Value = null;
+ }
+
+ // Called once to initialize the editor.
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(ImageInfo))
+ throw new ApplicationException ("ImageSelector editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ // Called when the object to be edited changes.
+ public void AttachObject (object obj)
+ {
+ Stetic.ObjectWrapper w = Stetic.ObjectWrapper.Lookup (obj);
+ project = w.Project;
+ }
+
+ // Gets/Sets the value of the editor. If the editor supports
+ // several value types, it is the responsibility of the editor
+ // to return values with the expected type.
+ public object Value {
+ get { return icon; }
+ set {
+ icon = (ImageInfo) value;
+ if (icon != null) {
+ entry.Text = icon.Label;
+ image.Pixbuf = icon.GetThumbnail (project, 16);
+ imageFrame.Show ();
+ clearButton.Show ();
+ } else {
+ imageFrame.Hide ();
+ clearButton.Hide ();
+ entry.Text = "";
+ }
+
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+
+ // To be fired when the edited value changes.
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IntRange.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IntRange.cs
new file mode 100644
index 0000000000..415becc0dc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/IntRange.cs
@@ -0,0 +1,120 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class IntRange : PropertyEditorCell
+ {
+ bool optInteger;
+
+ bool HasValue {
+ get {
+ if (!optInteger) return true;
+ int val = (int) Convert.ChangeType (Value, typeof(int));
+ return (val != -1);
+ }
+ }
+
+ protected override void Initialize ()
+ {
+ base.Initialize ();
+
+ if (Property.Minimum != null && Property.PropertyType == typeof(int)) {
+ int min = (int) Convert.ChangeType (Property.Minimum, typeof(int));
+ optInteger = (min == -1);
+ } else
+ optInteger = false;
+ }
+
+ public override void GetSize (int availableWidth, out int width, out int height)
+ {
+ if (HasValue)
+ base.GetSize (availableWidth, out width, out height);
+ else
+ width = height = 0;
+ }
+
+ public override void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state)
+ {
+ if (HasValue)
+ base.Render (window, bounds, state);
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ if (optInteger)
+ return new OptIntRange (0, null);
+ else
+ return new IntRangeEditor ();
+ }
+ }
+
+ public class IntRangeEditor : Gtk.SpinButton, IPropertyEditor {
+
+ Type propType;
+
+ public IntRangeEditor () : base (0, 0, 1.0)
+ {
+ this.HasFrame = false;
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ propType = prop.PropertyType;
+
+ double min, max;
+
+ switch (Type.GetTypeCode (propType)) {
+ case TypeCode.Int16:
+ min = (double) Int16.MinValue;
+ max = (double) Int16.MaxValue;
+ break;
+ case TypeCode.UInt16:
+ min = (double) UInt16.MinValue;
+ max = (double) UInt16.MaxValue;
+ break;
+ case TypeCode.Int32:
+ min = (double) Int32.MinValue;
+ max = (double) Int32.MaxValue;
+ break;
+ case TypeCode.UInt32:
+ min = (double) UInt32.MinValue;
+ max = (double) UInt32.MaxValue;
+ break;
+ case TypeCode.Int64:
+ min = (double) Int64.MinValue;
+ max = (double) Int64.MaxValue;
+ break;
+ case TypeCode.UInt64:
+ min = (double) UInt64.MinValue;
+ max = (double) UInt64.MaxValue;
+ break;
+ case TypeCode.Byte:
+ min = (double) Byte.MinValue;
+ max = (double) Byte.MaxValue;
+ break;
+ case TypeCode.SByte:
+ min = (double) SByte.MinValue;
+ max = (double) SByte.MaxValue;
+ break;
+ default:
+ throw new ApplicationException ("IntRange editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ if (prop.Minimum != null)
+ min = (double) Convert.ChangeType (prop.Minimum, typeof(double));
+ if (prop.Maximum != null)
+ max = (double) Convert.ChangeType (prop.Maximum, typeof(double));
+
+ SetRange (min, max);
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ object IPropertyEditor.Value {
+ get { return Convert.ChangeType (base.Value, propType); }
+ set { base.Value = (double) Convert.ChangeType (value, typeof(double)); }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/NonContainerWarningDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/NonContainerWarningDialog.cs
new file mode 100644
index 0000000000..3b212baa52
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/NonContainerWarningDialog.cs
@@ -0,0 +1,51 @@
+
+using System;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public delegate void ShowUrlDelegate (string url);
+
+ public class NonContainerWarningDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.CheckButton showCheck;
+ [Glade.Widget] Gtk.Button linkButton;
+ [Glade.Widget] Gtk.Button okbutton;
+ [Glade.Widget ("AddNonContainerDialog")] Gtk.Dialog dialog;
+
+ public static ShowUrlDelegate ShowUrl;
+
+ public NonContainerWarningDialog()
+ {
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "AddNonContainerDialog", null);
+ xml.Autoconnect (this);
+
+ ((Gtk.Label)linkButton.Child).Markup = "<u><span foreground='blue'>" + Catalog.GetString ("GTK# Widget Layout and Packing") + "</span></u>";
+
+ linkButton.Clicked += delegate {
+ if (ShowUrl != null)
+ ShowUrl ("http://www.mono-project.com/GtkSharp:_Widget_Layout_and_Packing");
+ };
+ okbutton.HasFocus = true;
+ }
+
+ public bool ShowAgain {
+ get { return !showCheck.Active; }
+ set { showCheck.Active = !value; }
+ }
+
+ public Gtk.Window TransientFor {
+ set { dialog.TransientFor = value; }
+ }
+
+ public int Run ()
+ {
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/OptIntRange.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/OptIntRange.cs
new file mode 100644
index 0000000000..784c41f33b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/OptIntRange.cs
@@ -0,0 +1,90 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class OptIntRange : Gtk.HBox, IPropertyEditor {
+
+ Gtk.CheckButton check;
+ Gtk.SpinButton spin;
+ object omin, omax;
+
+ public OptIntRange () : base (false, 6)
+ {
+ }
+
+ public OptIntRange (object omin, object omax) : base (false, 6)
+ {
+ this.omin = omin;
+ this.omax = omax;
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(int))
+ throw new ApplicationException ("OptIntRange editor does not support editing values of type " + prop.PropertyType);
+
+ double min = (double) Int32.MinValue;
+ double max = (double) Int32.MaxValue;
+
+ if (omin == null)
+ omin = prop.Minimum;
+ if (omax == null)
+ omax = prop.Maximum;
+
+ if (omin != null)
+ min = (double) Convert.ChangeType (omin, typeof(double));
+ if (omax != null)
+ max = (double) Convert.ChangeType (omax, typeof(double));
+
+ check = new Gtk.CheckButton ();
+ check.Show ();
+ check.Toggled += check_Toggled;
+ PackStart (check, false, false, 0);
+
+ spin = new Gtk.SpinButton (min, max, 1.0);
+ spin.Show ();
+ spin.HasFrame = false;
+ spin.ValueChanged += spin_ValueChanged;
+ PackStart (spin, true, true, 0);
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ void check_Toggled (object o, EventArgs args)
+ {
+ spin.Sensitive = check.Active;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ void spin_ValueChanged (object o, EventArgs args)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public object Value {
+ get {
+ if (check.Active)
+ return (int)spin.Value;
+ else
+ return -1;
+ }
+ set {
+ int val = (int) value;
+ if (val == -1) {
+ check.Active = false;
+ spin.Sensitive = false;
+ } else {
+ check.Active = true;
+ spin.Sensitive = true;
+ spin.Value = (double)val;
+ }
+ }
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconList.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconList.cs
new file mode 100644
index 0000000000..ff6a2fcce9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconList.cs
@@ -0,0 +1,29 @@
+
+using System;
+using System.Collections;
+using Gtk;
+
+namespace Stetic.Editor
+{
+ class ProjectIconList : IconList
+ {
+ IProject project;
+ ProjectIconFactory icons;
+
+ public ProjectIconList (IProject project, ProjectIconFactory icons)
+ {
+ this.project = project;
+ this.icons = icons;
+ Refresh ();
+ }
+
+ public void Refresh ()
+ {
+ Clear ();
+ foreach (ProjectIconSet icon in icons.Icons)
+ AddIcon (icon.Name, icon.Sources [0].Image.GetThumbnail (project, 16), icon.Name);
+ }
+ }
+}
+
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconSelectorItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconSelectorItem.cs
new file mode 100644
index 0000000000..fe5683918c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ProjectIconSelectorItem.cs
@@ -0,0 +1,21 @@
+
+using System;
+
+namespace Stetic.Editor
+{
+ public class ProjectIconSelectorItem: IconSelectorItem
+ {
+ IProject project;
+
+ public ProjectIconSelectorItem (IProject project): base ("Project Icons")
+ {
+ this.project = project;
+ }
+
+ protected override void CreateIcons ()
+ {
+ foreach (ProjectIconSet icon in project.IconFactory.Icons)
+ AddIcon (icon.Name, icon.Sources [0].Image.GetScaledImage (project, Gtk.IconSize.Menu), icon.Name);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ResponseId.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ResponseId.cs
new file mode 100644
index 0000000000..bc7ef54bab
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ResponseId.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections;
+using System.Reflection;
+
+namespace Stetic.Editor
+{
+ public class ResponseId: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ if (Value == null)
+ return "";
+
+ int val = (int) Value;
+ EnumDescriptor enm = Registry.LookupEnum ("Gtk.ResponseType");
+ foreach (Enum value in enm.Values) {
+ if (Convert.ToInt32 (enm[value].Value) == val) {
+ return enm[value].Label;
+ }
+ }
+ return val.ToString ();
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new ResponseIdEditor ();
+ }
+ }
+
+ public class ResponseIdEditor : Gtk.HBox, IPropertyEditor {
+
+ Gtk.ComboBoxEntry combo;
+ Gtk.Entry entry;
+ EnumDescriptor enm;
+ ArrayList values;
+
+ public ResponseIdEditor ()
+ {
+ combo = Gtk.ComboBoxEntry.NewText ();
+ combo.Changed += combo_Changed;
+ combo.Show ();
+ PackStart (combo, true, true, 0);
+
+ entry = combo.Child as Gtk.Entry;
+ entry.Changed += entry_Changed;
+
+ enm = Registry.LookupEnum ("Gtk.ResponseType");
+ values = new ArrayList ();
+ foreach (Enum value in enm.Values) {
+ if (enm[value].Label != "") {
+ combo.AppendText (enm[value].Label);
+ values.Add (Convert.ToInt32 (enm[value].Value));
+ }
+ }
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(int))
+ throw new ApplicationException ("ResponseId editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ public object Value {
+ get {
+ if (combo.Active != -1)
+ return (int)values[combo.Active];
+ else {
+ try {
+ return Int32.Parse (entry.Text);
+ } catch {
+ return 0;
+ }
+ }
+ }
+ set {
+ combo.Active = values.IndexOf ((int)value);
+ if (combo.Active == -1)
+ entry.Text = value.ToString ();
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ void combo_Changed (object o, EventArgs args)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ void entry_Changed (object o, EventArgs args)
+ {
+ if (combo.Active == -1 && ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectIconDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectIconDialog.cs
new file mode 100644
index 0000000000..1d9c3b220d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectIconDialog.cs
@@ -0,0 +1,179 @@
+
+using System;
+using System.Collections;
+using System.IO;
+using Gtk;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class SelectIconDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.Entry stockIconEntry;
+ [Glade.Widget] Gtk.Notebook notebook;
+ [Glade.Widget] Gtk.ScrolledWindow iconScrolledwindow;
+ [Glade.Widget] Gtk.ScrolledWindow customIconScrolledwindow;
+ [Glade.Widget] Gtk.Image previewIcon;
+ [Glade.Widget] Gtk.Button okButton;
+ [Glade.Widget] Gtk.Widget labelWarningIcon;
+ [Glade.Widget ("SelectIconDialog")] Gtk.Dialog dialog;
+
+ StockIconList iconList;
+ ProjectIconList customIconList;
+
+ Gtk.Window parent;
+ Stetic.IProject project;
+
+ public SelectIconDialog (Gtk.Window parent, Stetic.IProject project)
+ {
+ this.parent = parent;
+ this.project = project;
+
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "SelectIconDialog", null);
+ xml.Autoconnect (this);
+
+ // Stock icon list
+
+ iconList = new StockIconList ();
+ iconList.SelectionChanged += new EventHandler (OnIconSelectionChanged);
+ iconScrolledwindow.AddWithViewport (iconList);
+
+ // Custom icon list
+
+ customIconList = new ProjectIconList (project, project.IconFactory);
+ customIconList.SelectionChanged += new EventHandler (OnCustomIconSelectionChanged);
+ customIconScrolledwindow.AddWithViewport (customIconList);
+ dialog.ShowAll ();
+
+ UpdateIconSelection ();
+ UpdateButtons ();
+ }
+
+ public int Run ()
+ {
+ dialog.Show ();
+ dialog.TransientFor = parent;
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ public string Icon {
+ get {
+ if (notebook.Page == 0) {
+ if (stockIconEntry.Text.Length == 0)
+ return null;
+ return stockIconEntry.Text;
+ } else {
+ return customIconList.Selection;
+ }
+ }
+ set {
+ if (value == null)
+ return;
+
+ if (project.IconFactory.GetIcon (value) != null) {
+ notebook.Page = 1;
+ customIconList.Selection = value;
+ } else {
+ stockIconEntry.Text = value;
+ iconList.Selection = value;
+ notebook.Page = 0;
+ }
+ }
+ }
+
+ void UpdateButtons ()
+ {
+ okButton.Sensitive = Icon != null;
+ }
+
+ protected void OnCurrentPageChanged (object s, Gtk.SwitchPageArgs args)
+ {
+ UpdateButtons ();
+ }
+
+ void OnIconSelectionChanged (object s, EventArgs args)
+ {
+ if (iconList.Selection != null) {
+ stockIconEntry.Text = iconList.Selection;
+ }
+ }
+
+ void OnCustomIconSelectionChanged (object s, EventArgs args)
+ {
+ UpdateButtons ();
+ }
+
+ void UpdateIconSelection ()
+ {
+ labelWarningIcon.Visible = stockIconEntry.Text.Length > 0 && (!stockIconEntry.Text.StartsWith ("gtk-"));
+
+ Gdk.Pixbuf icon = null;
+ if (stockIconEntry.Text.Length > 0) {
+ icon = WidgetUtils.LoadIcon (stockIconEntry.Text, Gtk.IconSize.Menu);
+ }
+ if (icon == null)
+ icon = WidgetUtils.MissingIcon;
+ previewIcon.Pixbuf = icon;
+ }
+
+ protected void OnIconNameChanged (object ob, EventArgs args)
+ {
+ UpdateIconSelection ();
+ UpdateButtons ();
+ }
+
+ protected void OnAddIcon (object ob, EventArgs args)
+ {
+ ProjectIconSet icon = new ProjectIconSet ();
+ using (EditIconDialog dlg = new EditIconDialog (project, icon)) {
+ if (parent != null)
+ dlg.TransientFor = parent.Toplevel as Gtk.Window;
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ project.IconFactory.Icons.Add (icon);
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+// project.Modified = true;
+ }
+ }
+ }
+
+ protected void OnRemoveIcon (object ob, EventArgs args)
+ {
+ string name = customIconList.Selection;
+ ProjectIconSet icon = project.IconFactory.GetIcon (name);
+ if (icon != null) {
+ Gtk.MessageDialog md = new Gtk.MessageDialog (dialog, Gtk.DialogFlags.Modal, Gtk.MessageType.Question, Gtk.ButtonsType.YesNo, string.Format (Catalog.GetString ("Are you sure you want to delete the icon '{0}'"), icon.Name));
+ if (parent != null)
+ md.TransientFor = parent.Toplevel as Gtk.Window;
+ if (md.Run () == (int) Gtk.ResponseType.Yes) {
+ project.IconFactory.Icons.Remove (icon);
+ customIconList.Refresh ();
+// project.Modified = true;
+ }
+ md.Destroy ();
+ }
+ }
+
+ protected void OnEditIcon (object ob, EventArgs args)
+ {
+ string name = customIconList.Selection;
+ ProjectIconSet icon = project.IconFactory.GetIcon (name);
+ if (icon != null) {
+ using (EditIconDialog dlg = new EditIconDialog (project, icon)) {
+ if (parent != null)
+ dlg.TransientFor = parent.Toplevel as Gtk.Window;
+ if (dlg.Run () == (int) Gtk.ResponseType.Ok) {
+ customIconList.Refresh ();
+ customIconList.Selection = icon.Name;
+// project.Modified = true;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectImageDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectImageDialog.cs
new file mode 100644
index 0000000000..1ab23740aa
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/SelectImageDialog.cs
@@ -0,0 +1,314 @@
+
+using System;
+using System.Collections;
+using System.IO;
+using Gtk;
+
+namespace Stetic.Editor
+{
+ public class SelectImageDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.TreeView resourceList;
+ [Glade.Widget] Gtk.FileChooserWidget fileChooser;
+ [Glade.Widget] Gtk.Entry iconNameEntry;
+ [Glade.Widget] Gtk.Notebook notebook;
+ [Glade.Widget] Gtk.ScrolledWindow iconScrolledwindow;
+ [Glade.Widget] Gtk.Image previewIcon;
+ [Glade.Widget] Gtk.Image previewResource;
+ [Glade.Widget] Gtk.ComboBox iconSizeCombo;
+ [Glade.Widget] Gtk.Entry resourceNameEntry;
+ [Glade.Widget] Gtk.Button okButton;
+ [Glade.Widget] Gtk.Button buttonAdd;
+ [Glade.Widget] Gtk.Button buttonRemove;
+ [Glade.Widget ("SelectImageDialog")] Gtk.Dialog dialog;
+
+ ThemedIconList iconList;
+
+ Gtk.ListStore resourceListStore;
+ Gtk.Window parent;
+
+ int thumbnailSize = 30;
+ Hashtable resources = new Hashtable (); // Stores resourceName -> thumbnail pixbuf
+ Gdk.Pixbuf missingThumbnail;
+ IResourceProvider resourceProvider;
+ string importedImageFile;
+ Stetic.IProject project;
+
+ public SelectImageDialog (Gtk.Window parent, Stetic.IProject project)
+ {
+ this.parent = parent;
+ this.project = project;
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "SelectImageDialog", null);
+ xml.Autoconnect (this);
+
+ // Stock icon list
+
+ iconList = new ThemedIconList ();
+ iconList.SelectionChanged += new EventHandler (OnIconSelectionChanged);
+ iconScrolledwindow.AddWithViewport (iconList);
+
+ // Icon Sizes
+
+ foreach (IconSize s in Enum.GetValues (typeof(Gtk.IconSize))) {
+ if (s != IconSize.Invalid)
+ iconSizeCombo.AppendText (s.ToString ());
+ }
+ iconSizeCombo.Active = 0;
+
+ // Resource list
+
+ resourceListStore = new Gtk.ListStore (typeof(Gdk.Pixbuf), typeof(string), typeof(string));
+ resourceList.Model = resourceListStore;
+
+ Gtk.TreeViewColumn col = new Gtk.TreeViewColumn ();
+
+ Gtk.CellRendererPixbuf pr = new Gtk.CellRendererPixbuf ();
+ pr.Xpad = 3;
+ col.PackStart (pr, false);
+ col.AddAttribute (pr, "pixbuf", 0);
+
+ Gtk.CellRendererText crt = new Gtk.CellRendererText ();
+ col.PackStart (crt, true);
+ col.AddAttribute (crt, "markup", 1);
+
+ resourceList.AppendColumn (col);
+ resourceProvider = project.ResourceProvider;
+ if (resourceProvider == null) {
+ buttonAdd.Sensitive = false;
+ buttonRemove.Sensitive = false;
+ }
+ FillResources ();
+ resourceList.Selection.Changed += OnResourceSelectionChanged;
+
+ if (project.FolderName != null)
+ fileChooser.SetCurrentFolder (project.ImagesRootPath);
+
+ fileChooser.SelectionChanged += delegate (object s, EventArgs a) {
+ UpdateButtons ();
+ };
+
+ fileChooser.FileActivated += delegate (object s, EventArgs a) {
+ if (Icon != null) {
+ if (Validate ())
+ dialog.Respond (Gtk.ResponseType.Ok);
+ }
+ };
+
+ okButton.Clicked += OnOkClicked;
+
+ UpdateButtons ();
+ }
+
+ public int Run ()
+ {
+ dialog.ShowAll ();
+ dialog.TransientFor = parent;
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ public ImageInfo Icon {
+ get {
+ if (notebook.Page == 0) {
+ if (iconNameEntry.Text.Length == 0)
+ return null;
+ return ImageInfo.FromTheme (iconNameEntry.Text, SelectedIconSize);
+ } else if (notebook.Page == 1) {
+ if (resourceNameEntry.Text.Length == 0)
+ return null;
+ return ImageInfo.FromResource (resourceNameEntry.Text);
+ } else {
+ if (importedImageFile != null)
+ return ImageInfo.FromFile (importedImageFile);
+ if (fileChooser.Filename == null || fileChooser.Filename.Length == 0 || !File.Exists (fileChooser.Filename))
+ return null;
+ return ImageInfo.FromFile (fileChooser.Filename);
+ }
+ }
+ set {
+ if (value == null)
+ return;
+ if (value.Source == ImageSource.Theme) {
+ iconNameEntry.Text = value.Name;
+ SelectedIconSize = value.ThemeIconSize;
+ notebook.Page = 0;
+ } else if (value.Source == ImageSource.Resource) {
+ notebook.Page = 1;
+ resourceNameEntry.Text = value.Name;
+ } else {
+ fileChooser.SetFilename (value.Name);
+ notebook.Page = 2;
+ }
+ }
+ }
+
+ Gtk.IconSize SelectedIconSize {
+ get { return (IconSize) iconSizeCombo.Active + 1; }
+ set { iconSizeCombo.Active = ((int) value) - 1; }
+ }
+
+ void UpdateButtons ()
+ {
+ okButton.Sensitive = Icon != null;
+ }
+
+ protected void OnCurrentPageChanged (object s, Gtk.SwitchPageArgs args)
+ {
+ UpdateButtons ();
+ }
+
+ void OnIconSelectionChanged (object s, EventArgs args)
+ {
+ if (iconList.Selection != null) {
+ iconNameEntry.Text = iconList.Selection;
+ }
+ }
+
+ void UpdateIconSelection ()
+ {
+ Gdk.Pixbuf icon = null;
+ if (iconNameEntry.Text.Length > 0) {
+ icon = WidgetUtils.LoadIcon (iconNameEntry.Text, SelectedIconSize);
+ }
+ if (icon == null)
+ icon = WidgetUtils.MissingIcon;
+ previewIcon.Pixbuf = icon;
+ }
+
+ protected void OnIconSizeChanged (object ob, EventArgs args)
+ {
+ UpdateIconSelection ();
+ }
+
+ protected void OnIconNameChanged (object ob, EventArgs args)
+ {
+ UpdateIconSelection ();
+ UpdateButtons ();
+ }
+
+ void FillResources ()
+ {
+ resourceListStore.Clear ();
+ resources.Clear ();
+ if (resourceProvider != null) {
+ foreach (ResourceInfo res in resourceProvider.GetResources ()) {
+ if (res.MimeType.StartsWith ("image/")) {
+ AppendResource (resourceProvider.GetResourceStream (res.Name), res.Name);
+ }
+ }
+ }
+ }
+
+ void AppendResource (Stream stream, string name)
+ {
+ try {
+ Gdk.Pixbuf pix = new Gdk.Pixbuf (stream);
+ stream.Close ();
+ string txt = name + "\n<span foreground='darkgrey' size='x-small'>" + pix.Width + " x " + pix.Height + "</span>";
+ pix = GetThumbnail (pix);
+ resourceListStore.AppendValues (pix, txt, name);
+ resources [name] = pix;
+ } catch {
+ // Doesn't look like a valid image. Just ignore it.
+ }
+ }
+
+ Gdk.Pixbuf GetThumbnail (Gdk.Pixbuf pix)
+ {
+ if (pix.Width > pix.Height) {
+ if (pix.Width > thumbnailSize) {
+ float prop = (float) pix.Height / (float) pix.Width;
+ return pix.ScaleSimple (thumbnailSize, (int)(thumbnailSize * prop), Gdk.InterpType.Bilinear);
+ }
+ } else {
+ if (pix.Height > thumbnailSize) {
+ float prop = (float) pix.Width / (float) pix.Height;
+ return pix.ScaleSimple ((int)(thumbnailSize * prop), thumbnailSize, Gdk.InterpType.Bilinear);
+ }
+ }
+ return pix;
+ }
+
+ void OnResourceSelectionChanged (object obj, EventArgs args)
+ {
+ Gtk.TreeIter iter;
+ Gtk.TreeModel model;
+ if (!resourceList.Selection.GetSelected (out model, out iter)) {
+ resourceNameEntry.Text = "";
+ } else {
+ resourceNameEntry.Text = (string) resourceListStore.GetValue (iter, 2);
+ }
+ }
+
+ protected void OnResourceNameChanged (object ob, EventArgs args)
+ {
+ Gdk.Pixbuf pix = (Gdk.Pixbuf) resources [resourceNameEntry.Text];
+ if (pix != null)
+ previewResource.Pixbuf = pix;
+ else {
+ if (missingThumbnail == null)
+ missingThumbnail = WidgetUtils.MissingIcon;
+ previewResource.Pixbuf = missingThumbnail;
+ }
+ UpdateButtons ();
+ }
+
+ protected void OnAddResource (object ob, EventArgs args)
+ {
+ FileChooserDialog dialog =
+ new FileChooserDialog ("Open File", null, FileChooserAction.Open,
+ Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
+ Gtk.Stock.Open, Gtk.ResponseType.Ok);
+ if (parent != null)
+ dialog.TransientFor = parent.Toplevel as Gtk.Window;
+ int response = dialog.Run ();
+ if (response == (int)Gtk.ResponseType.Ok) {
+ ResourceInfo rinfo = resourceProvider.AddResource (dialog.Filename);
+ AppendResource (resourceProvider.GetResourceStream (rinfo.Name), rinfo.Name);
+ resourceNameEntry.Text = rinfo.Name;
+ }
+ dialog.Destroy ();
+ }
+
+ protected void OnRemoveResource (object ob, EventArgs args)
+ {
+ Gtk.TreeIter iter;
+ Gtk.TreeModel model;
+ if (resourceList.Selection.GetSelected (out model, out iter)) {
+ string res = (string) resourceListStore.GetValue (iter, 2);
+ Gtk.MessageDialog msg = new Gtk.MessageDialog (dialog, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, "Are you sure you want to delete the resource '{0}'?", res);
+ if (parent != null)
+ msg.TransientFor = parent.Toplevel as Gtk.Window;
+ if (msg.Run () == (int) ResponseType.Yes) {
+ resourceProvider.RemoveResource (res);
+ resourceListStore.Remove (ref iter);
+ }
+ msg.Destroy ();
+ }
+ }
+
+ bool Validate ()
+ {
+ if (notebook.Page == 2) {
+ if (fileChooser.Filename == null || fileChooser.Filename.Length == 0 || !File.Exists (fileChooser.Filename))
+ return true;
+
+ importedImageFile = project.ImportFile (fileChooser.Filename);
+ if (importedImageFile != null)
+ importedImageFile = WidgetUtils.AbsoluteToRelativePath (project.ImagesRootPath, importedImageFile);
+ return importedImageFile != null;
+ }
+ return true;
+ }
+
+ void OnOkClicked (object s, EventArgs args)
+ {
+ if (Validate ())
+ dialog.Respond (Gtk.ResponseType.Ok);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconList.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconList.cs
new file mode 100644
index 0000000000..b8c5676990
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconList.cs
@@ -0,0 +1,27 @@
+
+using System;
+using System.Reflection;
+using System.Collections;
+using Gtk;
+
+namespace Stetic.Editor
+{
+ class StockIconList : IconList
+ {
+ public StockIconList ()
+ {
+ foreach (PropertyInfo info in typeof (Gtk.Stock).GetProperties (BindingFlags.Public | BindingFlags.Static)) {
+ if (info.CanRead && info.PropertyType == typeof (string)) {
+ string name = (string) info.GetValue (null, null);
+ AddIcon (name, WidgetUtils.LoadIcon (name, Gtk.IconSize.Menu), name);
+ }
+ }
+ foreach (PropertyInfo info in GnomeStock.Properties) {
+ if (info.CanRead && info.PropertyType == typeof (string)) {
+ string name = (string) info.GetValue (null, null);
+ AddIcon (name, WidgetUtils.LoadIcon (name, Gtk.IconSize.Menu), name);
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconSelectorItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconSelectorItem.cs
new file mode 100644
index 0000000000..bf18e604f4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockIconSelectorItem.cs
@@ -0,0 +1,134 @@
+
+using System;
+using Mono.Unix;
+
+namespace Stetic.Editor
+{
+ public class StockIconSelectorItem: IconSelectorItem
+ {
+ public StockIconSelectorItem (IntPtr ptr): base (ptr)
+ {
+ }
+
+ public StockIconSelectorItem (): base (Catalog.GetString ("Stock Icons"))
+ {
+ }
+
+ protected override void CreateIcons ()
+ {
+ foreach (string s in StockIconHelper.StockIcons) {
+ if (s != "-" && s != "|") {
+ Gdk.Pixbuf pix = WidgetUtils.LoadIcon (s, Gtk.IconSize.Menu);
+ if (pix != null) AddIcon (s, pix, s);
+ }
+ else
+ AddSeparator (s);
+ }
+ }
+ }
+
+ class StockIconHelper
+ {
+ public static string[] StockIcons = {
+ // Commands
+ "gtk-new",
+ "gtk-open",
+ "gtk-save",
+ "gtk-save-as",
+ "gtk-revert-to-saved",
+ "gtk-quit",
+ "gtk-print",
+ "gtk-print-preview",
+ "gtk-properties",
+ "|",
+ "gtk-cut",
+ "gtk-copy",
+ "gtk-paste",
+ "gtk-delete",
+ "gtk-undelete",
+ "gtk-undo",
+ "gtk-redo",
+ "gtk-preferences",
+ "|",
+ "gtk-execute",
+ "gtk-stop",
+ "gtk-refresh",
+ "gtk-find",
+ "gtk-find-and-replace",
+ "|",
+ "gtk-spell-check",
+ "gtk-convert",
+ "gtk-help",
+ "|",
+ "gtk-add",
+ "gtk-remove",
+ "gtk-clear",
+ "-",
+
+ // Formatting
+ "gtk-bold",
+ "gtk-italic",
+ "gtk-underline",
+ "gtk-strikethrough",
+ "gtk-select-color",
+ "gtk-select-font",
+ "|",
+ "gtk-indent",
+ "gtk-unindent",
+ "gtk-justify-center",
+ "gtk-justify-fill",
+ "gtk-justify-left",
+ "gtk-justify-right",
+ "|",
+ "gtk-sort-ascending",
+ "gtk-sort-descending",
+ "|",
+ "gtk-zoom-100",
+ "gtk-zoom-fit",
+ "gtk-zoom-in",
+ "gtk-zoom-out",
+ "-",
+
+
+ // Dialog
+ "gtk-yes",
+ "gtk-no",
+ "gtk-cancel",
+ "gtk-ok",
+ "gtk-apply",
+ "gtk-close",
+ "|",
+ "gtk-dialog-error",
+ "gtk-dialog-info",
+ "gtk-dialog-question",
+ "gtk-dialog-warning",
+ "-",
+
+ // Navigation
+ "gtk-goto-bottom",
+ "gtk-goto-first",
+ "gtk-goto-last",
+ "gtk-goto-top",
+ "|",
+ "gtk-go-back",
+ "gtk-go-down",
+ "gtk-go-forward",
+ "gtk-go-up",
+ "|",
+ "gtk-home",
+ "gtk-jump-to",
+ "-",
+
+ // Misc
+ "gtk-cdrom",
+ "gtk-floppy",
+ "gtk-harddisk",
+ "gtk-network",
+ "gtk-color-picker",
+ "gtk-dnd",
+ "gtk-dnd-multiple",
+ "gtk-missing-image",
+ "gtk-index"
+ };
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockItem.cs
new file mode 100644
index 0000000000..5d9ed308da
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StockItem.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Stetic.Editor {
+
+ internal static class GnomeStock {
+
+ static string blank;
+ static List<PropertyInfo> props = new List<PropertyInfo> ();
+
+ static GnomeStock ()
+ {
+ try {
+ Assembly assm = Assembly.Load ("gnome-sharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f");
+ if (assm == null)
+ return;
+
+ Type type = assm.GetType ("Gnome.Stock");
+ if (type == null)
+ return;
+
+ foreach (PropertyInfo info in type.GetProperties (BindingFlags.Static | BindingFlags.Public)) {
+ if (info.Name == "Blank")
+ blank = (string) info.GetValue (null, null);
+ props.Add (info);
+ }
+ } catch {
+ }
+ }
+
+ public static string Blank {
+ get { return blank == null ? Gtk.Stock.New : blank; }
+ }
+
+ public static List<PropertyInfo> Properties {
+ get { return props; }
+ }
+ }
+
+ public class StockItem: BaseImageCell
+ {
+ string label;
+
+ protected override void Initialize ()
+ {
+ base.Initialize ();
+ string name = (string)Value;
+ if (name != null) {
+ Stetic.ObjectWrapper w = Stetic.ObjectWrapper.Lookup (Instance);
+ Stetic.IProject project = w.Project;
+ Gdk.Pixbuf px = project.IconFactory.RenderIcon (project, name, ImageSize);
+ if (px != null) {
+ Image = px;
+ label = name;
+ return;
+ }
+
+ Gtk.StockItem item = Gtk.Stock.Lookup (name);
+ label = item.Label != null && item.Label.Length > 0 ? item.Label : name;
+ label = label.Replace ("_", "");
+
+ Gtk.IconSet iset = Gtk.IconFactory.LookupDefault (name);
+ if (iset == null)
+ Image = WidgetUtils.MissingIcon;
+ else
+ Image = iset.RenderIcon (new Gtk.Style (), Gtk.TextDirection.Ltr, Gtk.StateType.Normal, Gtk.IconSize.Menu, null, "");
+ } else {
+ Image = null;
+ label = "";
+ }
+ }
+
+ protected override string GetValueText ()
+ {
+ return label;
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new StockItemEditor ();
+ }
+ }
+
+/* [PropertyEditor ("StockId", "Changed")]
+ public class StockItemEditor : Image {
+
+ public StockItemEditor () : base (true, false) { }
+
+ public override object Value {
+ get { return StockId; }
+ set { StockId = (string) value; }
+ }
+ }
+ */
+
+ public class StockItemEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Image image;
+ Gtk.Entry entry;
+ Gtk.Button button;
+ string icon;
+ IProject project;
+ Gtk.Frame imageFrame;
+
+ public StockItemEditor()
+ {
+ Spacing = 3;
+ imageFrame = new Gtk.Frame ();
+ imageFrame.Shadow = Gtk.ShadowType.In;
+ imageFrame.BorderWidth = 2;
+ PackStart (imageFrame, false, false, 0);
+
+ image = new Gtk.Image (GnomeStock.Blank, Gtk.IconSize.Button);
+ imageFrame.Add (image);
+
+ entry = new Gtk.Entry ();
+ entry.Changed += OnTextChanged;
+ entry.HasFrame = false;
+ PackStart (entry, true, true, 0);
+
+ button = new Gtk.Button ();
+ button.Add (new Gtk.Arrow (Gtk.ArrowType.Down, Gtk.ShadowType.Out));
+ PackStart (button, false, false, 0);
+ button.Clicked += button_Clicked;
+ ShowAll ();
+ }
+
+ void button_Clicked (object obj, EventArgs args)
+ {
+ IconSelectorMenu menu = new IconSelectorMenu (project);
+ menu.IconSelected += OnStockSelected;
+ menu.ShowAll ();
+ menu.Popup (null, null, new Gtk.MenuPositionFunc (OnDropMenuPosition), 3, Gtk.Global.CurrentEventTime);
+ }
+
+ void OnDropMenuPosition (Gtk.Menu menu, out int x, out int y, out bool pushIn)
+ {
+ button.ParentWindow.GetOrigin (out x, out y);
+ x += button.Allocation.X;
+ y += button.Allocation.Y + button.Allocation.Height;
+ pushIn = true;
+ }
+
+ void OnStockSelected (object s, IconEventArgs args)
+ {
+ Value = args.IconId;
+ }
+
+ void OnTextChanged (object s, EventArgs a)
+ {
+ if (entry.Text.Length == 0)
+ Value = null;
+ else
+ Value = entry.Text;
+ }
+
+ // Called once to initialize the editor.
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(string))
+ throw new ApplicationException ("StockItem editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ // Called when the object to be edited changes.
+ public void AttachObject (object obj)
+ {
+ Stetic.ObjectWrapper w = Stetic.ObjectWrapper.Lookup (obj);
+ project = w.Project;
+ }
+
+ // Gets/Sets the value of the editor. If the editor supports
+ // several value types, it is the responsibility of the editor
+ // to return values with the expected type.
+ public object Value {
+ get { return icon; }
+ set {
+ icon = (string) value;
+ if (icon != null && icon.Length > 0) {
+ entry.Text = icon;
+ Gdk.Pixbuf px = project.IconFactory.RenderIcon (project, icon, Gtk.IconSize.Menu);
+ if (px == null)
+ px = WidgetUtils.LoadIcon (icon, Gtk.IconSize.Menu);
+ image.Pixbuf = px;
+ imageFrame.Show ();
+ } else {
+ imageFrame.Hide ();
+ entry.Text = "";
+ }
+
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+
+ // To be fired when the edited value changes.
+ public event EventHandler ValueChanged;
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/String.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/String.cs
new file mode 100644
index 0000000000..dafbb3922a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/String.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace Stetic.Editor {
+
+ [PropertyEditor ("Text", "Changed")]
+ public class String : Translatable {
+
+ Gtk.Entry entry;
+
+ public override void Initialize (PropertyDescriptor prop)
+ {
+ base.Initialize (prop);
+
+ entry = new Gtk.Entry ();
+ entry.HasFrame = false;
+ entry.Show ();
+ entry.Changed += EntryChanged;
+ Add (entry);
+ }
+
+ protected override void CheckType (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(string))
+ throw new ApplicationException ("String editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ public override object Value {
+ get {
+ return entry.Text;
+ }
+ set {
+ if (value == null)
+ entry.Text = "";
+ else
+ entry.Text = (string) value;
+ }
+ }
+
+ void EntryChanged (object obj, EventArgs args)
+ {
+ OnValueChanged ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StringArray.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StringArray.cs
new file mode 100644
index 0000000000..ca8d5bd064
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/StringArray.cs
@@ -0,0 +1,99 @@
+
+using System;
+using Gtk;
+using Gdk;
+using System.Text;
+
+namespace Stetic.Editor
+{
+ public class StringArray: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ string[] val = (string[]) Value;
+ return val == null ? string.Empty : "(Collection)";
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new StringArrayEditor ();
+ }
+ }
+
+ public class StringArrayEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Entry label;
+ Gtk.Button button;
+ PropertyDescriptor prop;
+ object obj;
+ string[] strings;
+
+ public StringArrayEditor()
+ {
+ label = new Gtk.Entry ();
+ label.IsEditable = false;
+ PackStart (label, true, true, 0);
+ button = new Button ("...");
+ PackStart (button, false, false, 3);
+ button.Clicked += ButtonClicked;
+ ShowAll ();
+ }
+
+ void ButtonClicked (object s, EventArgs a)
+ {
+ using (TextEditorDialog dlg = new TextEditorDialog ()) {
+ dlg.Text = strings != null ? string.Join ("\n", strings) : "";
+ dlg.SetTranslatable (prop.Translatable);
+ dlg.TransientFor = this.Toplevel as Gtk.Window;
+ if (prop.Translatable) {
+ dlg.Translated = prop.IsTranslated (obj);
+ dlg.ContextHint = prop.TranslationContext (obj);
+ dlg.Comment = prop.TranslationComment (obj);
+ }
+ if (dlg.Run () == (int) ResponseType.Ok) {
+ if (prop.Translatable) {
+ prop.SetTranslated (obj, dlg.Translated);
+ if (dlg.Translated) {
+ prop.SetTranslationComment (obj, dlg.Comment);
+ prop.SetTranslationContext (obj, dlg.ContextHint);
+ }
+ }
+ if (dlg.Text.Length == 0)
+ strings = null;
+ else
+ strings = dlg.Text.Split ('\n');
+ UpdateLabel ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(string[]))
+ throw new InvalidOperationException ("StringArrayEditor can only edit string[] properties");
+ prop = descriptor;
+ }
+
+ public void AttachObject (object obj)
+ {
+ this.obj = obj;
+ }
+
+ public object Value {
+ get { return strings; }
+ set {
+ strings = (string[]) value;
+ UpdateLabel ();
+ }
+ }
+
+ void UpdateLabel ()
+ {
+ label.Text = strings != null ? "(Collection)" : System.String.Empty;
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Text.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Text.cs
new file mode 100644
index 0000000000..667ccb2537
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Text.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Stetic.Editor
+{
+ public class Text : TextEditor
+ {
+ public Text ()
+ {
+ // Don't allow editing the text in the editor
+ // since there is no room for multiline edit in the grid.
+ entry.Sensitive = false;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextBox.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextBox.cs
new file mode 100644
index 0000000000..6dd84a878c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextBox.cs
@@ -0,0 +1,51 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public class TextBox : Gtk.ScrolledWindow {
+
+ Gtk.TextView textview;
+
+ public TextBox (int nlines)
+ {
+ ShadowType = Gtk.ShadowType.In;
+ SetPolicy (Gtk.PolicyType.Never, Gtk.PolicyType.Automatic);
+
+ textview = new Gtk.TextView ();
+ textview.WrapMode = Gtk.WrapMode.Word;
+ textview.Show ();
+ Add (textview);
+
+ Pango.Context ctx = textview.PangoContext;
+ Pango.FontMetrics metrics = ctx.GetMetrics (textview.Style.FontDescription,
+ ctx.Language);
+ int lineHeight = (metrics.Ascent + metrics.Descent) / (int)Pango.Scale.PangoScale;
+ SetSizeRequest (-1, lineHeight * nlines);
+
+ textview.Buffer.Changed += Buffer_Changed;
+ }
+
+ public Gtk.TextView TextView {
+ get {
+ return textview;
+ }
+ }
+
+ public string Text {
+ get {
+ return textview.Buffer.Text;
+ }
+ set {
+ textview.Buffer.Text = value;
+ }
+ }
+
+ void Buffer_Changed (object obj, EventArgs args)
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+
+ public event EventHandler Changed;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditor.cs
new file mode 100644
index 0000000000..d2c135a2a6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditor.cs
@@ -0,0 +1,83 @@
+
+using System;
+using Gtk;
+using Gdk;
+
+namespace Stetic.Editor
+{
+ public class TextEditor: Gtk.HBox, IPropertyEditor
+ {
+ protected Gtk.Entry entry;
+ protected Gtk.Button button;
+ PropertyDescriptor prop;
+ object obj;
+
+ public TextEditor()
+ {
+ Spacing = 3;
+ entry = new Entry ();
+ entry.HasFrame = false;
+ PackStart (entry, true, true, 0);
+ button = new Button ("...");
+ button.Relief = ReliefStyle.Half;
+ PackStart (button, false, false, 0);
+ button.Clicked += ButtonClicked;
+ entry.Activated += TextChanged;
+ ShowAll ();
+ }
+
+ void ButtonClicked (object s, EventArgs a)
+ {
+ using (TextEditorDialog dlg = new TextEditorDialog ()) {
+ dlg.Text = entry.Text;
+ dlg.SetTranslatable (prop.Translatable);
+ dlg.TransientFor = this.Toplevel as Gtk.Window;
+ if (prop.Translatable) {
+ dlg.Translated = prop.IsTranslated (obj);
+ dlg.ContextHint = prop.TranslationContext (obj);
+ dlg.Comment = prop.TranslationComment (obj);
+ }
+ if (dlg.Run () == (int) ResponseType.Ok) {
+ if (prop.Translatable) {
+ prop.SetTranslated (obj, dlg.Translated);
+ if (dlg.Translated) {
+ prop.SetTranslationComment (obj, dlg.Comment);
+ prop.SetTranslationContext (obj, dlg.ContextHint);
+ }
+ }
+ entry.Text = dlg.Text;
+ TextChanged (null, null);
+ }
+ }
+ }
+
+ void TextChanged (object s, EventArgs a)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, a);
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ if (descriptor.PropertyType != typeof(string))
+ throw new InvalidOperationException ("TextEditor only can edit string properties");
+ prop = descriptor;
+ }
+
+ public void AttachObject (object obj)
+ {
+ this.obj = obj;
+ }
+
+ // Gets/Sets the value of the editor. If the editor supports
+ // several value types, it is the responsibility of the editor
+ // to return values with the expected type.
+ public object Value {
+ get { return entry.Text; }
+ set { entry.Text = value != null ? (string) value : ""; }
+ }
+
+ // To be fired when the edited value changes.
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditorDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditorDialog.cs
new file mode 100644
index 0000000000..b7df291eab
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TextEditorDialog.cs
@@ -0,0 +1,70 @@
+
+using System;
+
+namespace Stetic.Editor
+{
+ public class TextEditorDialog: IDisposable
+ {
+ [Glade.Widget] Gtk.TextView textview;
+ [Glade.Widget] Gtk.CheckButton checkTranslatable;
+ [Glade.Widget] Gtk.Entry entryContext;
+ [Glade.Widget] Gtk.Entry entryComment;
+ [Glade.Widget] Gtk.Table translationTable;
+ [Glade.Widget ("TextEditorDialog")] Gtk.Dialog dialog;
+
+ public TextEditorDialog ()
+ {
+ Glade.XML xml = new Glade.XML (null, "stetic.glade", "TextEditorDialog", null);
+ xml.Autoconnect (this);
+ entryContext.Sensitive = entryComment.Sensitive = false;
+ }
+
+ public string Text {
+ get { return textview.Buffer.Text; }
+ set { textview.Buffer.Text = value; }
+ }
+
+ public string ContextHint {
+ get { return entryContext.Text; }
+ set { entryContext.Text = value != null ? value : ""; }
+ }
+
+ public string Comment {
+ get { return entryComment.Text; }
+ set { entryComment.Text = value != null ? value : ""; }
+ }
+
+ public bool Translated {
+ get { return checkTranslatable.Active; }
+ set { checkTranslatable.Active = value; }
+ }
+
+ public Gtk.Window TransientFor {
+ set { dialog.TransientFor = value; }
+ }
+
+ public void SetTranslatable (bool translatable)
+ {
+ if (!translatable) {
+ translationTable.Visible = false;
+ checkTranslatable.Visible = false;
+ }
+ }
+
+ protected void OnTranslatableToggled (object s, EventArgs a)
+ {
+ entryContext.Sensitive = checkTranslatable.Active;
+ entryComment.Sensitive = checkTranslatable.Active;
+ }
+
+ public int Run ()
+ {
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIcon.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIcon.cs
new file mode 100644
index 0000000000..3da369f94c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIcon.cs
@@ -0,0 +1,162 @@
+using Gtk;
+using System;
+
+namespace Stetic.Editor {
+
+ [PropertyEditor ("Value", "Changed")]
+ public class ThemedIcon : Gtk.HBox, IPropertyEditor {
+ Gtk.Image image;
+ Gtk.Entry entry;
+ Gtk.Button button;
+
+ public ThemedIcon () : base (false, 6)
+ {
+ image = new Gtk.Image (GnomeStock.Blank, Gtk.IconSize.Button);
+ PackStart (image, false, false, 0);
+
+ entry = new Gtk.Entry ();
+ PackStart (entry, true, true, 0);
+ entry.Changed += entry_Changed;
+
+ button = new Gtk.Button ("...");
+ PackStart (button, false, false, 0);
+ button.Clicked += button_Clicked;
+ }
+
+ public void Initialize (PropertyDescriptor prop)
+ {
+ if (prop.PropertyType != typeof(string))
+ throw new ApplicationException ("ThemedIcon editor does not support editing values of type " + prop.PropertyType);
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ public event EventHandler ValueChanged;
+
+ bool syncing;
+
+ void entry_Changed (object obj, EventArgs args)
+ {
+ if (!syncing)
+ Value = entry.Text;
+ }
+
+ void button_Clicked (object obj, EventArgs args)
+ {
+ Gtk.Window parent = (Gtk.Window)GetAncestor (Gtk.Window.GType);
+ Value = ThemedIconBrowser.Browse (parent, (string) Value);
+ }
+
+ string icon;
+ public object Value {
+ get {
+ return icon;
+ }
+ set {
+ string val = (string) value;
+ if (icon == val)
+ return;
+
+ icon = val;
+ Gdk.Pixbuf pix = WidgetUtils.LoadIcon (icon, Gtk.IconSize.Menu);
+ if (pix != null) {
+ image.Pixbuf = pix;
+ } else {
+ image.Stock = GnomeStock.Blank;
+ }
+
+ syncing = true;
+ entry.Text = icon;
+ syncing = false;
+
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+ }
+
+ public class ThemedIconBrowser : Gtk.Dialog {
+
+ public ThemedIconBrowser (Gtk.Window parent) :
+ base ("Select a Themed Icon", parent, Gtk.DialogFlags.Modal,
+ Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
+ Gtk.Stock.Ok, Gtk.ResponseType.Ok)
+ {
+ HasSeparator = false;
+ BorderWidth = 12;
+ VBox.Spacing = 18;
+ VBox.BorderWidth = 0;
+
+ DefaultResponse = Gtk.ResponseType.Ok;
+
+ Gtk.HBox hbox = new Gtk.HBox (false, 12);
+ VBox.PackStart (hbox, false, false, 0);
+
+ entry = new Gtk.Entry ();
+ entry.Activated += DoFind;
+ hbox.PackStart (entry);
+
+ Gtk.Button button = new Gtk.Button (Gtk.Stock.Find);
+ button.Clicked += DoFind;
+ hbox.PackStart (button, false, false, 0);
+
+ ScrolledWindow scwin = new Gtk.ScrolledWindow ();
+ scwin.SizeRequested += ScrolledWindowSizeRequested;
+ VBox.PackStart (scwin, true, true, 0);
+ scwin.SetPolicy (Gtk.PolicyType.Never, Gtk.PolicyType.Automatic);
+ scwin.ShadowType = Gtk.ShadowType.In;
+
+ list = new ThemedIconList ();
+ scwin.Add (list);
+ list.SelectionChanged += ListSelectionChanged;
+ list.Activated += ListActivated;
+ SetResponseSensitive (Gtk.ResponseType.Ok, false);
+
+ VBox.ShowAll ();
+ }
+
+ public static string Browse (Gtk.Window parent, string selection)
+ {
+ ThemedIconBrowser browser = new ThemedIconBrowser (parent);
+ browser.list.Selection = selection;
+ int response = browser.Run ();
+ if (response == (int)Gtk.ResponseType.Ok)
+ selection = browser.list.Selection;
+ browser.Destroy ();
+ return selection;
+ }
+
+ Gtk.Entry entry;
+ ThemedIconList list;
+
+ void ScrolledWindowSizeRequested (object obj, SizeRequestedArgs args)
+ {
+ Gtk.Requisition req = list.SizeRequest ();
+ if (req.Width <= 0)
+ return;
+
+ Gtk.ScrolledWindow scwin = ((Gtk.ScrolledWindow)obj);
+ scwin.SizeRequested -= ScrolledWindowSizeRequested;
+ scwin.SetSizeRequest (req.Width, req.Width * 2 / 3);
+ ActionArea.BorderWidth = 0; // has to happen post-realize
+ }
+
+ void ListSelectionChanged (object obj, EventArgs args)
+ {
+ SetResponseSensitive (Gtk.ResponseType.Ok, list.Selection != null);
+ }
+
+ void ListActivated (object obj, EventArgs args)
+ {
+ Respond (Gtk.ResponseType.Ok);
+ }
+
+ void DoFind (object obj, EventArgs args)
+ {
+ list.Find (entry.Text);
+ }
+
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIconList.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIconList.cs
new file mode 100644
index 0000000000..d3b16aadb9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/ThemedIconList.cs
@@ -0,0 +1,1018 @@
+
+using System;
+using System.Collections;
+using Gtk;
+
+namespace Stetic.Editor
+{
+ class ThemedIconList : IconList
+ {
+ public ThemedIconList ()
+ {
+ Gtk.IconTheme theme = Gtk.IconTheme.Default;
+ foreach (string icon in ThemeIconNames)
+ AddIcon (icon, GetPixbuf (theme, icon), icon);
+ }
+
+ Gdk.Pixbuf GetPixbuf (Gtk.IconTheme theme, string name)
+ {
+ try {
+ return theme.LoadIcon (name, 16, 0);
+ } catch {
+ return RenderIcon (name, Gtk.IconSize.Menu, null);
+ }
+ }
+
+ public static string[] ThemeIconNames = new string[] {
+ // Gtk 2.6 stock icons
+ "gtk-about",
+ "gtk-add",
+ "gtk-apply",
+ "gtk-bold",
+ "gtk-cancel",
+ "gtk-cdrom",
+ "gtk-clear",
+ "gtk-close",
+ "gtk-color-picker",
+ "gtk-connect",
+ "gtk-convert",
+ "gtk-copy",
+ "gtk-cut",
+ "gtk-delete",
+ "gtk-dialog-authentication",
+ "gtk-dialog-error",
+ "gtk-dialog-info",
+ "gtk-dialog-question",
+ "gtk-dialog-warning",
+ "gtk-directory",
+ "gtk-disconnect",
+ "gtk-dnd",
+ "gtk-dnd-multiple",
+ "gtk-edit",
+ "gtk-execute",
+ "gtk-file",
+ "gtk-find",
+ "gtk-find-and-replace",
+ "gtk-floppy",
+ "gtk-go-back",
+ "gtk-go-down",
+ "gtk-go-forward",
+ "gtk-go-up",
+ "gtk-goto-bottom",
+ "gtk-goto-first",
+ "gtk-goto-last",
+ "gtk-goto-top",
+ "gtk-harddisk",
+ "gtk-help",
+ "gtk-home",
+ "gtk-indent",
+ "gtk-index",
+ "gtk-italic",
+ "gtk-jump-to",
+ "gtk-justify-center",
+ "gtk-justify-fill",
+ "gtk-justify-left",
+ "gtk-justify-right",
+ "gtk-media-forward",
+ "gtk-media-next",
+ "gtk-media-pause",
+ "gtk-media-play",
+ "gtk-media-previous",
+ "gtk-media-record",
+ "gtk-media-rewind",
+ "gtk-media-stop",
+ "gtk-missing-image",
+ "gtk-network",
+ "gtk-new",
+ "gtk-no",
+ "gtk-ok",
+ "gtk-open",
+ "gtk-paste",
+ "gtk-preferences",
+ "gtk-print",
+ "gtk-print-preview",
+ "gtk-properties",
+ "gtk-quit",
+ "gtk-redo",
+ "gtk-refresh",
+ "gtk-remove",
+ "gtk-revert-to-saved",
+ "gtk-save",
+ "gtk-save-as",
+ "gtk-select-color",
+ "gtk-select-font",
+ "gtk-sort-ascending",
+ "gtk-sort-descending",
+ "gtk-spell-check",
+ "gtk-stop",
+ "gtk-strikethrough",
+ "gtk-undelete",
+ "gtk-underline",
+ "gtk-undo",
+ "gtk-unindent",
+ "gtk-yes",
+ "gtk-zoom-100",
+ "gtk-zoom-fit",
+ "gtk-zoom-in",
+ "gtk-zoom-out",
+
+ // Themable stock icons
+ "stock_about",
+ "stock_active",
+ "stock_add-bookmark",
+ "stock_add-decimal-place",
+ "stock_addressbook",
+ "stock_advanced-filter",
+ "stock_alarm",
+ "stock_alignment",
+ "stock_alignment-bottom",
+ "stock_alignment-centered",
+ "stock_alignment-centered-vertically",
+ "stock_alignment-left",
+ "stock_alignment-right",
+ "stock_alignment-top",
+ "stock_allow-effects",
+ "stock_anchor",
+ "stock_animation",
+ "stock_appointment-reminder",
+ "stock_appointment-reminder-excl",
+ "stock_arrowstyle",
+ "stock_attach",
+ "stock_auto-contour",
+ "stock_autocompletion",
+ "stock_autofilter",
+ "stock_autoformat",
+ "stock_autopilot",
+ "stock_autopilot-24",
+ "stock_autospellcheck",
+ "stock_autotext",
+ "stock_bell",
+ "stock_bluetooth",
+ "stock_book_blue",
+ "stock_book_green",
+ "stock_book_open",
+ "stock_book_red",
+ "stock_book_yellow",
+ "stock_bookmark",
+ "stock_bottom",
+ "stock_briefcase",
+ "stock_brightness",
+ "stock_bring-backward",
+ "stock_bring-forward",
+ "stock_bucketfill",
+ "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-align-bottom",
+ "stock_cell-align-center",
+ "stock_cell-align-top",
+ "stock_cell-phone",
+ "stock_certificate",
+ "stock_channel",
+ "stock_channel-blue",
+ "stock_channel-green",
+ "stock_channel-red",
+ "stock_chart",
+ "stock_chart-autoformat",
+ "stock_chart-data-in-columns",
+ "stock_chart-data-in-rows",
+ "stock_chart-edit-type",
+ "stock_chart-reorganize",
+ "stock_chart-scale-text",
+ "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_check-filled",
+ "stock_choose-themes",
+ "stock_close",
+ "stock_color",
+ "stock_compile",
+ "stock_connect",
+ "stock_connect-to-url",
+ "stock_contact",
+ "stock_contact-list",
+ "stock_contrast",
+ "stock_copy",
+ "stock_create-with-attributes",
+ "stock_creditcard",
+ "stock_crop",
+ "stock_cut",
+ "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_datapilot",
+ "stock_decrease-font",
+ "stock_default-folder",
+ "stock_delete",
+ "stock_delete-autofilter",
+ "stock_delete-bookmark",
+ "stock_delete-column",
+ "stock_delete-decimal-place",
+ "stock_delete-row",
+ "stock_dialog-error",
+ "stock_dialog-info",
+ "stock_dialog-question",
+ "stock_dialog-warning",
+ "stock_directcursor",
+ "stock_directory-server",
+ "stock_disconnect",
+ "stock_display-grid",
+ "stock_display-guides",
+ "stock_distort",
+ "stock_down",
+ "stock_down-with-subpoints",
+ "stock_drag-mode",
+ "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-text",
+ "stock_draw-text-animation",
+ "stock_draw-text-frame",
+ "stock_draw-torus",
+ "stock_draw-vertical-callouts",
+ "stock_draw-vertical-text",
+ "stock_draw-vertical-text-frame",
+ "stock_edit",
+ "stock_edit-bookmark",
+ "stock_edit-contour",
+ "stock_edit-headers-and-footers",
+ "stock_edit-points",
+ "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_effects-sound",
+ "stock_effects-text",
+ "stock_enter-group",
+ "stock_equals",
+ "stock_error-next",
+ "stock_error-next-16",
+ "stock_error-previous",
+ "stock_error-previous-16",
+ "stock_euro",
+ "stock_example",
+ "stock_exchange-columns",
+ "stock_exchange-connector",
+ "stock_exchange-rows",
+ "stock_exit",
+ "stock_exit-group",
+ "stock_export",
+ "stock_extended-help",
+ "stock_file-properties",
+ "stock_file-with-objects",
+ "stock_filter-data-by-criteria",
+ "stock_filter-navigator",
+ "stock_filters",
+ "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_first",
+ "stock_first-page",
+ "stock_flip",
+ "stock_flip-horizontally",
+ "stock_flip-vertically",
+ "stock_folder",
+ "stock_folder-copy",
+ "stock_folder-move",
+ "stock_folder-properties",
+ "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_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_format-character",
+ "stock_format-default",
+ "stock_format-numbering-bullets",
+ "stock_format-object",
+ "stock_format-page",
+ "stock_format-paragraph",
+ "stock_format-percent",
+ "stock_format-scientific",
+ "stock_formula-cursor",
+ "stock_frame",
+ "stock_fullscreen",
+ "stock_function-autopilot",
+ "stock_gamma",
+ "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_goal-seek",
+ "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_group",
+ "stock_group-cells",
+ "stock_groupwise-connector",
+ "stock_guides",
+ "stock_hand-signed",
+ "stock_handles-big",
+ "stock_handles-simple",
+ "stock_headphones",
+ "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_hyperlink",
+ "stock_hyperlink-internet-search",
+ "stock_hyperlink-target",
+ "stock_hyperlink-toolbar",
+ "stock_id",
+ "stock_imagemap-editor",
+ "stock_inbox",
+ "stock_increase-font",
+ "stock_init",
+ "stock_insert-applet",
+ "stock_insert-caption",
+ "stock_insert-cells",
+ "stock_insert-cells-down",
+ "stock_insert-cells-right",
+ "stock_insert-chart",
+ "stock_insert-columns",
+ "stock_insert-cross-reference",
+ "stock_insert-fields",
+ "stock_insert-fields-author",
+ "stock_insert-fields-subject",
+ "stock_insert-fields-title",
+ "stock_insert-file",
+ "stock_insert-floating-frame",
+ "stock_insert-footer",
+ "stock_insert-form",
+ "stock_insert-gluepoint",
+ "stock_insert-header",
+ "stock_insert-math-object",
+ "stock_insert-names-define",
+ "stock_insert-note",
+ "stock_insert-ole-object",
+ "stock_insert-plugin",
+ "stock_insert-rows",
+ "stock_insert-rule",
+ "stock_insert-single-column-text-frame",
+ "stock_insert-slide",
+ "stock_insert-sound-plugin",
+ "stock_insert-table",
+ "stock_insert-text-frame",
+ "stock_insert-url",
+ "stock_insert-video-plugin",
+ "stock_insert_endnote",
+ "stock_insert_footnote",
+ "stock_insert_graphic",
+ "stock_insert_image",
+ "stock_insert_index_marker",
+ "stock_insert_section",
+ "stock_insert_special_character",
+ "stock_interaction",
+ "stock_internet",
+ "stock_keyring",
+ "stock_landline-phone",
+ "stock_last",
+ "stock_last-page",
+ "stock_left",
+ "stock_left-with-subpoints",
+ "stock_line-spacing-1",
+ "stock_line-spacing-1.5",
+ "stock_line-spacing-2",
+ "stock_line_in",
+ "stock_linepen",
+ "stock_link",
+ "stock_list-insert-unnumbered",
+ "stock_list_bullet",
+ "stock_list_enum",
+ "stock_list_enum-off",
+ "stock_list_enum-restart",
+ "stock_live-mode",
+ "stock_lock",
+ "stock_lock-broken",
+ "stock_lock-ok",
+ "stock_lock-open",
+ "stock_macro-check-brackets",
+ "stock_macro-controls",
+ "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_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_mark",
+ "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_message-display",
+ "stock_mic",
+ "stock_midi",
+ "stock_modify-layout",
+ "stock_music-library",
+ "stock_my-documents",
+ "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_network-printer",
+ "stock_new",
+ "stock_new",
+ "stock_new-24h-appointment",
+ "stock_new-appointment",
+ "stock_new-bcard",
+ "stock_new-dir",
+ "stock_new-drawing",
+ "stock_new-formula",
+ "stock_new-html",
+ "stock_new-labels",
+ "stock_new-master-document",
+ "stock_new-meeting",
+ "stock_new-presentation",
+ "stock_new-spreadsheet",
+ "stock_new-tab",
+ "stock_new-template",
+ "stock_new-text",
+ "stock_new-window",
+ "stock_news",
+ "stock_next",
+ "stock_next-page",
+ "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_nonprinting-chars",
+ "stock_not",
+ "stock_not-spam",
+ "stock_notebook",
+ "stock_notes",
+ "stock_object-behind",
+ "stock_object-infront",
+ "stock_online-layout",
+ "stock_open",
+ "stock_open-read-only",
+ "stock_openoffice",
+ "stock_opensave",
+ "stock_outbox",
+ "stock_page-number",
+ "stock_page-total-number",
+ "stock_paragraph-spacing-decrease",
+ "stock_paragraph-spacing-increase",
+ "stock_paste",
+ "stock_people",
+ "stock_person",
+ "stock_pin",
+ "stock_placeholder-graphic",
+ "stock_placeholder-line-contour",
+ "stock_placeholder-picture",
+ "stock_placeholder-text",
+ "stock_playlist",
+ "stock_position-size",
+ "stock_post-message",
+ "stock_presentation-box",
+ "stock_presentation-styles",
+ "stock_preview-four-pages",
+ "stock_preview-two-pages",
+ "stock_previous",
+ "stock_previous-page",
+ "stock_print",
+ "stock_print-driver",
+ "stock_print-duplex",
+ "stock_print-duplex-no-tumble",
+ "stock_print-duplex-tumble",
+ "stock_print-layout",
+ "stock_print-non-duplex",
+ "stock_print-options",
+ "stock_print-preview",
+ "stock_print-preview-print",
+ "stock_print-resolution",
+ "stock_print-setup",
+ "stock_printers",
+ "stock_properties",
+ "stock_proxy",
+ "stock_quickmask",
+ "stock_record-macro",
+ "stock_record-number",
+ "stock_redo",
+ "stock_refresh",
+ "stock_reload",
+ "stock_repeat",
+ "stock_reverse-order",
+ "stock_right",
+ "stock_right-with-subpoints",
+ "stock_rotate",
+ "stock_rotate-3d",
+ "stock_rotation-mode",
+ "stock_run-macro",
+ "stock_samples",
+ "stock_save",
+ "stock_save-as",
+ "stock_save-pdf",
+ "stock_save-template",
+ "stock_save_as",
+ "stock_score-high",
+ "stock_score-higher",
+ "stock_score-highest",
+ "stock_score-low",
+ "stock_score-lower",
+ "stock_score-lowest",
+ "stock_score-normal",
+ "stock_scores",
+ "stock_script",
+ "stock_script",
+ "stock_scripts",
+ "stock_search",
+ "stock_search-and-replace",
+ "stock_select-all",
+ "stock_select-cell",
+ "stock_select-column",
+ "stock_select-row",
+ "stock_select-table",
+ "stock_send-fax",
+ "stock_sent-mail",
+ "stock_shadow",
+ "stock_show-all",
+ "stock_show-draw-functions",
+ "stock_show-form-dialog",
+ "stock_show-hidden-controls",
+ "stock_shuffle",
+ "stock_signature",
+ "stock_signature-bad",
+ "stock_signature-ok",
+ "stock_slide-design",
+ "stock_slide-duplicate",
+ "stock_slide-expand",
+ "stock_slide-reherse-timings",
+ "stock_slide-show",
+ "stock_slide-showhide",
+ "stock_smart-playlist",
+ "stock_smiley-1",
+ "stock_smiley-2",
+ "stock_smiley-3",
+ "stock_smiley-4",
+ "stock_smiley-5",
+ "stock_smiley-6",
+ "stock_smiley-7",
+ "stock_smiley-8",
+ "stock_smiley-9",
+ "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-20",
+ "stock_smiley-21",
+ "stock_smiley-22",
+ "stock_smiley-23",
+ "stock_smiley-24",
+ "stock_smiley-25",
+ "stock_smiley-26",
+ "stock_snap-grid",
+ "stock_snap-guides",
+ "stock_snap-margins",
+ "stock_snap-object",
+ "stock_snap-object-points",
+ "stock_sort-ascending",
+ "stock_sort-column-ascending",
+ "stock_sort-criteria",
+ "stock_sort-descending",
+ "stock_sort-row-ascending",
+ "stock_sort-table-column-ascending",
+ "stock_sort-table-row-ascending",
+ "stock_sound",
+ "stock_spam",
+ "stock_spellcheck",
+ "stock_standard-filter",
+ "stock_stop",
+ "stock_styles",
+ "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_sum",
+ "stock_summary",
+ "stock_superscript",
+ "stock_symbol-selection",
+ "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_task",
+ "stock_task-assigned",
+ "stock_task-assigned-to",
+ "stock_task-recurring",
+ "stock_test-mode",
+ "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_3d-3d-attributes-only",
+ "stock_3d-all-attributes",
+ "stock_3d-color-picker",
+ "stock_3d-colors",
+ "stock_3d-custom-color",
+ "stock_3d-effects",
+ "stock_3d-favourites",
+ "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_3dsound",
+ "stock_timer",
+ "stock_timer_stopped",
+ "stock_timezone",
+ "stock_to-3d",
+ "stock_to-3d-rotation-object",
+ "stock_to-background",
+ "stock_to-bottom",
+ "stock_to-curve",
+ "stock_to-foreground",
+ "stock_to-polygon",
+ "stock_to-top",
+ "stock_todo",
+ "stock_toggle-graphics",
+ "stock_toggle-info",
+ "stock_toggle-preview",
+ "stock_toilet-paper",
+ "stock_tools-hyphenation",
+ "stock_tools-macro",
+ "stock_top",
+ "stock_transform-circle-perspective",
+ "stock_transform-circle-slant",
+ "stock_transparency",
+ "stock_trash_full",
+ "stock_undelete",
+ "stock_undo",
+ "stock_undo-history",
+ "stock_ungroup",
+ "stock_ungroup-cells",
+ "stock_unknown",
+ "stock_unlink",
+ "stock_up",
+ "stock_up-one-dir",
+ "stock_up-with-subpoints",
+ "stock_update-data",
+ "stock_update-fields",
+ "stock_video-conferencing",
+ "stock_view-details",
+ "stock_view-field-shadings",
+ "stock_view-fields",
+ "stock_view-function-selection",
+ "stock_view-html-source",
+ "stock_volume",
+ "stock_wallpaper-center",
+ "stock_wallpaper-fill",
+ "stock_wallpaper-scale",
+ "stock_wallpaper-tile",
+ "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_wrap-around",
+ "stock_wrap-behind",
+ "stock_wrap-contour",
+ "stock_wrap-interrupt",
+ "stock_wrap-left",
+ "stock_wrap-optimal",
+ "stock_wrap-right",
+ "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",
+ };
+ }
+}
+
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TimeSpanEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TimeSpanEditor.cs
new file mode 100644
index 0000000000..fb40194da3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TimeSpanEditor.cs
@@ -0,0 +1,67 @@
+
+using System;
+using Gtk;
+using Gdk;
+using System.Text;
+
+namespace Stetic.Editor
+{
+ public class TimeSpanEditorCell: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ return ((TimeSpan)Value).ToString ();
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new TimeSpanEditor ();
+ }
+ }
+
+ public class TimeSpanEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Entry entry;
+ TimeSpan time;
+
+ public TimeSpanEditor()
+ {
+ entry = new Gtk.Entry ();
+ entry.Changed += OnChanged;
+ PackStart (entry, true, true, 0);
+ ShowAll ();
+ }
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ }
+
+ public void AttachObject (object ob)
+ {
+ }
+
+ public object Value {
+ get { return time; }
+ set {
+ time = (TimeSpan) value;
+ entry.Changed -= OnChanged;
+ entry.Text = time.ToString ();
+ entry.Changed += OnChanged;
+ }
+ }
+
+ void OnChanged (object o, EventArgs a)
+ {
+ string s = entry.Text;
+
+ try {
+ time = TimeSpan.Parse (s);
+ if (ValueChanged != null)
+ ValueChanged (this, a);
+ } catch {
+ }
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Translatable.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Translatable.cs
new file mode 100644
index 0000000000..c04192620f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/Translatable.cs
@@ -0,0 +1,233 @@
+using System;
+
+namespace Stetic.Editor {
+
+ public abstract class Translatable : Gtk.VBox, IPropertyEditor {
+
+ PropertyDescriptor prop;
+ object obj;
+
+ Gtk.Box mainHBox, contextBox, commentBox;
+ Gtk.Button button;
+ Gdk.Pixbuf globe, globe_not;
+ Gtk.Image image;
+ Gtk.Menu menu;
+ Gtk.CheckMenuItem markItem;
+ Gtk.MenuItem addContextItem, remContextItem, addCommentItem, remCommentItem;
+ Gtk.Entry contextEntry;
+ TextBox commentText;
+ bool initializing;
+
+ public virtual void Initialize (PropertyDescriptor prop)
+ {
+ CheckType (prop);
+
+ this.prop = prop;
+
+ mainHBox = new Gtk.HBox (false, 6);
+ PackStart (mainHBox, false, false, 0);
+
+ if (!prop.Translatable)
+ return;
+
+ button = new Gtk.Button ();
+ try {
+ globe = Gdk.Pixbuf.LoadFromResource ("globe.png");
+ globe_not = Gdk.Pixbuf.LoadFromResource ("globe-not.png");
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf: " + e);
+ }
+ image = new Gtk.Image (globe);
+ button.Add (image);
+ button.ButtonPressEvent += ButtonPressed;
+ mainHBox.PackEnd (button, false, false, 0);
+ mainHBox.ShowAll ();
+
+ menu = new Gtk.Menu ();
+
+ markItem = new Gtk.CheckMenuItem ("Mark for Translation");
+ markItem.Toggled += ToggleMark;
+ markItem.Show ();
+ menu.Add (markItem);
+
+ addContextItem = new Gtk.MenuItem ("Add Translation Context Hint");
+ addContextItem.Activated += AddContext;
+ menu.Add (addContextItem);
+ remContextItem = new Gtk.MenuItem ("Remove Translation Context Hint");
+ remContextItem.Activated += RemoveContext;
+ menu.Add (remContextItem);
+
+ addCommentItem = new Gtk.MenuItem ("Add Comment for Translators");
+ addCommentItem.Activated += AddComment;
+ menu.Add (addCommentItem);
+ remCommentItem = new Gtk.MenuItem ("Remove Comment for Translators");
+ remCommentItem.Activated += RemoveComment;
+ menu.Add (remCommentItem);
+
+ contextBox = new Gtk.HBox (false, 6);
+ Gtk.Label contextLabel = new Gtk.Label ("Translation context");
+ contextLabel.Xalign = 0.0f;
+ contextBox.PackStart (contextLabel, false, false, 0);
+ contextEntry = new Gtk.Entry ();
+ contextEntry.WidthChars = 8;
+ contextBox.PackStart (contextEntry, true, true, 0);
+ contextBox.ShowAll ();
+ contextEntry.Changed += ContextChanged;
+
+ commentBox = new Gtk.VBox (false, 3);
+ Gtk.Label commentLabel = new Gtk.Label ("Comment for Translators:");
+ commentLabel.Xalign = 0.0f;
+ commentBox.PackStart (commentLabel, false, false, 0);
+ commentText = new TextBox (3);
+ commentBox.PackStart (commentText, false, false, 0);
+ commentBox.ShowAll ();
+ commentText.Changed += CommentChanged;
+ }
+
+ protected virtual void CheckType (PropertyDescriptor prop)
+ {
+ }
+
+ public virtual void AttachObject (object ob)
+ {
+ this.obj = ob;
+
+ if (!prop.Translatable)
+ return;
+
+ initializing = true;
+
+ if (contextBox.Parent != null)
+ Remove (contextBox);
+ if (commentBox.Parent != null)
+ Remove (commentBox);
+
+ markItem.Active = prop.IsTranslated (obj);
+ image.Pixbuf = markItem.Active ? globe : globe_not;
+
+ if (prop.IsTranslated (obj)) {
+ if (prop.TranslationContext (obj) != null) {
+ remContextItem.Show ();
+ PackStart (contextBox, false, false, 0);
+ contextEntry.Text = prop.TranslationContext (obj);
+ } else
+ addContextItem.Show ();
+ } else {
+ addContextItem.Show ();
+ addContextItem.Sensitive = false;
+ }
+
+ if (prop.IsTranslated (obj)) {
+ if (prop.TranslationComment (obj) != null) {
+ remCommentItem.Show ();
+ PackEnd (commentBox, false, false, 0);
+ commentText.Text = prop.TranslationComment (obj);
+ } else
+ addCommentItem.Show ();
+ } else {
+ addCommentItem.Show ();
+ addCommentItem.Sensitive = false;
+ }
+
+ initializing = false;
+ }
+
+
+ public abstract object Value { get; set; }
+
+ public event EventHandler ValueChanged;
+
+ protected virtual void OnValueChanged ()
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ protected override void OnAdded (Gtk.Widget child)
+ {
+ mainHBox.PackStart (child, true, true, 0);
+ }
+
+ void MenuPosition (Gtk.Menu menu, out int x, out int y, out bool push_in)
+ {
+ button.GdkWindow.GetOrigin (out x, out y);
+ Gdk.Rectangle alloc = button.Allocation;
+ x += alloc.X;
+ y += alloc.Y + alloc.Height;
+ push_in = true;
+ }
+
+ [GLib.ConnectBefore]
+ void ButtonPressed (object o, Gtk.ButtonPressEventArgs args)
+ {
+ menu.Popup (null, null, MenuPosition, 1, args.Event.Time);
+ args.RetVal = true;
+ }
+
+ void ToggleMark (object o, EventArgs args)
+ {
+ if (initializing) return;
+ if (!markItem.Active) {
+ // Make sure we're showing the "Add" menu items
+ // rather than the "Remove" ones
+ if (prop.TranslationContext (obj) != null)
+ RemoveContext (remContextItem, EventArgs.Empty);
+ if (prop.TranslationComment (obj) != null)
+ RemoveComment (remCommentItem, EventArgs.Empty);
+ }
+
+ prop.SetTranslated (obj, markItem.Active);
+ image.Pixbuf = markItem.Active ? globe : globe_not;
+ addContextItem.Sensitive = markItem.Active;
+ addCommentItem.Sensitive = markItem.Active;
+ }
+
+ void AddContext (object o, EventArgs args)
+ {
+ prop.SetTranslationContext (obj, contextEntry.Text);
+ PackStart (contextBox, false, false, 0);
+
+ addContextItem.Hide ();
+ remContextItem.Show ();
+ }
+
+ void RemoveContext (object o, EventArgs args)
+ {
+ prop.SetTranslationContext (obj, null);
+ Remove (contextBox);
+
+ remContextItem.Hide ();
+ addContextItem.Show ();
+ }
+
+ void ContextChanged (object o, EventArgs args)
+ {
+ if (initializing) return;
+ prop.SetTranslationContext (obj, contextEntry.Text);
+ }
+
+ void AddComment (object o, EventArgs args)
+ {
+ prop.SetTranslationComment (obj, commentText.Text);
+ PackEnd (commentBox, false, false, 0);
+
+ addCommentItem.Hide ();
+ remCommentItem.Show ();
+ }
+
+ void RemoveComment (object o, EventArgs args)
+ {
+ prop.SetTranslationComment (obj, null);
+ Remove (commentBox);
+
+ remCommentItem.Hide ();
+ addCommentItem.Show ();
+ }
+
+ void CommentChanged (object o, EventArgs args)
+ {
+ if (initializing) return;
+ prop.SetTranslationComment (obj, commentText.Text);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TreeViewCellContainer.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TreeViewCellContainer.cs
new file mode 100644
index 0000000000..c027a02986
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/TreeViewCellContainer.cs
@@ -0,0 +1,82 @@
+//
+// TreeViewCellContainer.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using Gtk;
+using Gdk;
+
+namespace Stetic.Editor
+{
+ class TreeViewCellContainer: Entry
+ {
+ EventBox box;
+
+ public TreeViewCellContainer (Gtk.Widget child)
+ {
+ box = new EventBox ();
+ box.ButtonPressEvent += new ButtonPressEventHandler (OnClickBox);
+ box.ModifyBg (StateType.Normal, Style.White);
+ box.Add (child);
+ child.Show ();
+ Show ();
+ }
+
+ [GLib.ConnectBefore]
+ void OnClickBox (object s, ButtonPressEventArgs args)
+ {
+ // Avoid forwarding the button press event to the
+ // tree, since it would hide the cell editor.
+ args.RetVal = true;
+ }
+
+ protected override void OnParentSet (Gtk.Widget parent)
+ {
+ base.OnParentSet (parent);
+
+ if (Parent != null) {
+ if (ParentWindow != null)
+ box.ParentWindow = ParentWindow;
+ box.Parent = Parent;
+ box.Show ();
+ }
+ else
+ box.Unparent ();
+ }
+
+ protected override void OnShown ()
+ {
+ // Do nothing.
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+ {
+ base.OnSizeAllocated (allocation);
+ box.SizeRequest ();
+ box.Allocation = allocation;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/WidgetSelector.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/WidgetSelector.cs
new file mode 100644
index 0000000000..68991a32e6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/editor/WidgetSelector.cs
@@ -0,0 +1,98 @@
+
+using System;
+using System.Collections;
+using Gtk;
+using Gdk;
+
+namespace Stetic.Editor
+{
+ public class WidgetSelector: ComboBox, IPropertyEditor
+ {
+ Gtk.Widget obj;
+ ListStore store;
+ Hashtable widgets = new Hashtable ();
+
+ public void Initialize (PropertyDescriptor descriptor)
+ {
+ store = new ListStore (typeof(Pixbuf), typeof(string));
+ Model = store;
+ store.SetSortColumnId (1, SortType.Ascending);
+ CellRendererPixbuf crp = new CellRendererPixbuf ();
+ CellRendererText crt = new CellRendererText ();
+ PackStart (crp, false);
+ PackStart (crt, true);
+ SetAttributes (crp, "pixbuf", 0);
+ SetAttributes (crt, "text", 1);
+ }
+
+ public void AttachObject (object obj)
+ {
+ this.obj = obj as Gtk.Widget;
+ FillWidgets ();
+ }
+
+ void FillWidgets ()
+ {
+ store.Clear ();
+ widgets.Clear ();
+
+ Stetic.Wrapper.Widget widget = Stetic.Wrapper.Widget.Lookup (obj);
+ if (widget == null)
+ return;
+
+ while (!widget.IsTopLevel)
+ widget = widget.ParentWrapper;
+
+ store.AppendValues (null, "(None)");
+ FillWidgets (widget, 0);
+ }
+
+ void FillWidgets (Stetic.Wrapper.Widget widget, int level)
+ {
+ if (!widget.Unselectable) {
+ TreeIter iter = store.AppendValues (widget.ClassDescriptor.Icon, widget.Wrapped.Name);
+ widgets [widget.Wrapped.Name] = iter;
+ }
+ Gtk.Container cont = widget.Wrapped as Gtk.Container;
+ if (cont != null && widget.ClassDescriptor.AllowChildren) {
+ foreach (Gtk.Widget child in cont.AllChildren) {
+ Stetic.Wrapper.Widget cwidget = Stetic.Wrapper.Widget.Lookup (child);
+ if (cwidget != null)
+ FillWidgets (cwidget, level+1);
+ }
+ }
+ }
+
+
+ public object Value {
+ get {
+ if (Active <= 0)
+ return null;
+ else {
+ TreeIter iter;
+ if (!GetActiveIter (out iter))
+ return null;
+ return (string) store.GetValue (iter, 1);
+ }
+ }
+ set {
+ if (value == null)
+ Active = 0;
+ else if (widgets.Contains ((string) value)) {
+ TreeIter iter = (TreeIter) widgets [value];
+ SetActiveIter (iter);
+ }
+ }
+ }
+
+ protected override void OnChanged ()
+ {
+ base.OnChanged ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ // To be fired when the edited value changes.
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.csproj b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.csproj
new file mode 100644
index 0000000000..96142a024c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.csproj
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AssemblyName>libstetic2</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <RootNamespace>Stetic</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\..\..\build\AddIns\MonoDevelop.GtkCore2</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Mono.Posix" />
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="Mono.Cairo" />
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ClassDescriptor.cs" />
+ <Compile Include="Clipboard.cs" />
+ <Compile Include="CommandDescriptor.cs" />
+ <Compile Include="CustomWidget.cs" />
+ <Compile Include="DND.cs" />
+ <Compile Include="editor\Accelerator.cs" />
+ <Compile Include="editor\ActionGroupEditor.cs" />
+ <Compile Include="editor\ActionItem.cs" />
+ <Compile Include="editor\ActionMenu.cs" />
+ <Compile Include="editor\ActionMenuBar.cs" />
+ <Compile Include="editor\ActionMenuItem.cs" />
+ <Compile Include="editor\ActionToolbar.cs" />
+ <Compile Include="editor\ActionToolItem.cs" />
+ <Compile Include="editor\Boolean.cs" />
+ <Compile Include="editor\CellRendererComboBox.cs" />
+ <Compile Include="editor\Char.cs" />
+ <Compile Include="editor\Color.cs" />
+ <Compile Include="editor\DateTimeEditor.cs" />
+ <Compile Include="editor\EditIconDialog.cs" />
+ <Compile Include="editor\EditIconFactoryDialog.cs" />
+ <Compile Include="editor\Enumeration.cs" />
+ <Compile Include="editor\Flags.cs" />
+ <Compile Include="editor\FlagsSelectorDialog.cs" />
+ <Compile Include="editor\FloatRange.cs" />
+ <Compile Include="editor\GroupPicker.cs" />
+ <Compile Include="editor\IconList.cs" />
+ <Compile Include="editor\IconSelectorItem.cs" />
+ <Compile Include="editor\IconSelectorMenu.cs" />
+ <Compile Include="editor\IconSelectorMenuItem.cs" />
+ <Compile Include="editor\Identifier.cs" />
+ <Compile Include="editor\Image.cs" />
+ <Compile Include="editor\ImageFile.cs" />
+ <Compile Include="editor\ImageSelector.cs" />
+ <Compile Include="editor\IntRange.cs" />
+ <Compile Include="editor\NonContainerWarningDialog.cs" />
+ <Compile Include="editor\OptIntRange.cs" />
+ <Compile Include="editor\ProjectIconList.cs" />
+ <Compile Include="editor\ProjectIconSelectorItem.cs" />
+ <Compile Include="editor\ResponseId.cs" />
+ <Compile Include="editor\SelectIconDialog.cs" />
+ <Compile Include="editor\SelectImageDialog.cs" />
+ <Compile Include="editor\StockIconList.cs" />
+ <Compile Include="editor\StockIconSelectorItem.cs" />
+ <Compile Include="editor\StockItem.cs" />
+ <Compile Include="editor\String.cs" />
+ <Compile Include="editor\StringArray.cs" />
+ <Compile Include="editor\Text.cs" />
+ <Compile Include="editor\TextBox.cs" />
+ <Compile Include="editor\TextEditor.cs" />
+ <Compile Include="editor\TextEditorDialog.cs" />
+ <Compile Include="editor\ThemedIcon.cs" />
+ <Compile Include="editor\ThemedIconList.cs" />
+ <Compile Include="editor\TimeSpanEditor.cs" />
+ <Compile Include="editor\Translatable.cs" />
+ <Compile Include="editor\TreeViewCellContainer.cs" />
+ <Compile Include="editor\WidgetSelector.cs" />
+ <Compile Include="EnumDescriptor.cs" />
+ <Compile Include="ErrorWidget.cs" />
+ <Compile Include="GeneratorContext.cs" />
+ <Compile Include="GladeException.cs" />
+ <Compile Include="GladeUtils.cs" />
+ <Compile Include="IDesignArea.cs" />
+ <Compile Include="IEditableObject.cs" />
+ <Compile Include="ImageInfo.cs" />
+ <Compile Include="IProject.cs" />
+ <Compile Include="IPropertyEditor.cs" />
+ <Compile Include="IRadioGroupManager.cs" />
+ <Compile Include="IResourceProvider.cs" />
+ <Compile Include="ItemDescriptor.cs" />
+ <Compile Include="ItemGroup.cs" />
+ <Compile Include="ItemGroupCollection.cs" />
+ <Compile Include="NoGuiDispatchAttribute.cs" />
+ <Compile Include="ObjectReader.cs" />
+ <Compile Include="ObjectWrapper.cs" />
+ <Compile Include="ObjectWrapperEventHandler.cs" />
+ <Compile Include="ObjectWriter.cs" />
+ <Compile Include="ParamSpec.cs" />
+ <Compile Include="Placeholder.cs" />
+ <Compile Include="ProjectIconFactory.cs" />
+ <Compile Include="PropertyDescriptor.cs" />
+ <Compile Include="PropertyEditorAttribute.cs" />
+ <Compile Include="PropertyEditorCell.cs" />
+ <Compile Include="RadioGroupManager.cs" />
+ <Compile Include="Registry.cs" />
+ <Compile Include="Set.cs" />
+ <Compile Include="SignalDescriptor.cs" />
+ <Compile Include="TranslatableAttribute.cs" />
+ <Compile Include="TypedClassDescriptor.cs" />
+ <Compile Include="TypedPropertyDescriptor.cs" />
+ <Compile Include="TypedSignalDescriptor.cs" />
+ <Compile Include="undo\ActionDiffAdaptor.cs" />
+ <Compile Include="undo\DiffGenerator.cs" />
+ <Compile Include="undo\IDiffAdaptor.cs" />
+ <Compile Include="undo\UndoManager.cs" />
+ <Compile Include="undo\XmlDiffAdaptor.cs" />
+ <Compile Include="WidgetLibrary.cs" />
+ <Compile Include="WidgetUtils.cs" />
+ <Compile Include="wrapper\Action.cs" />
+ <Compile Include="wrapper\ActionGroup.cs" />
+ <Compile Include="wrapper\ActionToolbarWrapper.cs" />
+ <Compile Include="wrapper\ActionTree.cs" />
+ <Compile Include="wrapper\Bin.cs" />
+ <Compile Include="wrapper\Box.cs" />
+ <Compile Include="wrapper\Button.cs" />
+ <Compile Include="wrapper\ButtonBox.cs" />
+ <Compile Include="wrapper\CheckButton.cs" />
+ <Compile Include="wrapper\ColorButton.cs" />
+ <Compile Include="wrapper\ComboBox.cs" />
+ <Compile Include="wrapper\ComboBoxEntry.cs" />
+ <Compile Include="wrapper\Container.cs" />
+ <Compile Include="wrapper\Custom.cs" />
+ <Compile Include="wrapper\Dialog.cs" />
+ <Compile Include="wrapper\Entry.cs" />
+ <Compile Include="wrapper\Expander.cs" />
+ <Compile Include="wrapper\Fixed.cs" />
+ <Compile Include="wrapper\FontButton.cs" />
+ <Compile Include="wrapper\FontSelectionDialog.cs" />
+ <Compile Include="wrapper\Frame.cs" />
+ <Compile Include="wrapper\HScale.cs" />
+ <Compile Include="wrapper\HScrollbar.cs" />
+ <Compile Include="wrapper\IconView.cs" />
+ <Compile Include="wrapper\Image.cs" />
+ <Compile Include="wrapper\ImageMenuItem.cs" />
+ <Compile Include="wrapper\Label.cs" />
+ <Compile Include="wrapper\MenuBar.cs" />
+ <Compile Include="wrapper\MenuItem.cs" />
+ <Compile Include="wrapper\MessageDialog.cs" />
+ <Compile Include="wrapper\Misc.cs" />
+ <Compile Include="wrapper\Notebook.cs" />
+ <Compile Include="wrapper\Object.cs" />
+ <Compile Include="wrapper\OptionMenu.cs" />
+ <Compile Include="wrapper\Paned.cs" />
+ <Compile Include="wrapper\RadioActionGroupManager.cs" />
+ <Compile Include="wrapper\RadioButton.cs" />
+ <Compile Include="wrapper\RadioMenuItem.cs" />
+ <Compile Include="wrapper\RadioToolButton.cs" />
+ <Compile Include="wrapper\Range.cs" />
+ <Compile Include="wrapper\Scale.cs" />
+ <Compile Include="wrapper\ScrolledWindow.cs" />
+ <Compile Include="wrapper\Signal.cs" />
+ <Compile Include="wrapper\SignalChangedEventHandler.cs" />
+ <Compile Include="wrapper\SignalCollection.cs" />
+ <Compile Include="wrapper\SignalEventHandler.cs" />
+ <Compile Include="wrapper\SpinButton.cs" />
+ <Compile Include="wrapper\Table.cs" />
+ <Compile Include="wrapper\TextView.cs" />
+ <Compile Include="wrapper\ToggleToolButton.cs" />
+ <Compile Include="wrapper\Toolbar.cs" />
+ <Compile Include="wrapper\ToolButton.cs" />
+ <Compile Include="wrapper\TreeView.cs" />
+ <Compile Include="wrapper\Viewport.cs" />
+ <Compile Include="wrapper\VScale.cs" />
+ <Compile Include="wrapper\VScrollbar.cs" />
+ <Compile Include="wrapper\Widget.cs" />
+ <Compile Include="wrapper\WidgetEventHandler.cs" />
+ <Compile Include="wrapper\WidgetNameChangedHandler.cs" />
+ <Compile Include="wrapper\Window.cs" />
+ <Compile Include="TopLevelDialog.cs" />
+ <Compile Include="TopLevelWindow.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="stetic.glade">
+ <LogicalName>stetic.glade</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\objects.xml">
+ <LogicalName>objects.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\accellabel.png">
+ <LogicalName>accellabel.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\actiongroup.png">
+ <LogicalName>actiongroup.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\add-check-label.png">
+ <LogicalName>add-check-label.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\add-menu.png">
+ <LogicalName>add-menu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\alignment.png">
+ <LogicalName>alignment.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\arrow.png">
+ <LogicalName>arrow.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\box-expand.png">
+ <LogicalName>box-expand.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\box-fill.png">
+ <LogicalName>box-fill.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\button.png">
+ <LogicalName>button.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\calendar.png">
+ <LogicalName>calendar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-expand-h.png">
+ <LogicalName>cell-expand-h.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-expand-v.png">
+ <LogicalName>cell-expand-v.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-fill-h.png">
+ <LogicalName>cell-fill-h.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-fill-v.png">
+ <LogicalName>cell-fill-v.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\checkbutton.png">
+ <LogicalName>checkbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\colorbutton.png">
+ <LogicalName>colorbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\colorselection.png">
+ <LogicalName>colorselection.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\colorselectiondialog.png">
+ <LogicalName>colorselectiondialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\combo.png">
+ <LogicalName>combo.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\comboentry.png">
+ <LogicalName>comboentry.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\custom.png">
+ <LogicalName>custom.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\dec-border.png">
+ <LogicalName>dec-border.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\dialog.png">
+ <LogicalName>dialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\drawingarea.png">
+ <LogicalName>drawingarea.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\entry.png">
+ <LogicalName>entry.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\eventbox.png">
+ <LogicalName>eventbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\expander.png">
+ <LogicalName>expander.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fileselection.png">
+ <LogicalName>fileselection.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fixed.png">
+ <LogicalName>fixed.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fontbutton.png">
+ <LogicalName>fontbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fontselection.png">
+ <LogicalName>fontselection.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fontselectiondialog.png">
+ <LogicalName>fontselectiondialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\frame.png">
+ <LogicalName>frame.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\globe.png">
+ <LogicalName>globe.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\globe-not.png">
+ <LogicalName>globe-not.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\handlebox.png">
+ <LogicalName>handlebox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hbox.png">
+ <LogicalName>hbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hbuttonbox.png">
+ <LogicalName>hbuttonbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hpaned.png">
+ <LogicalName>hpaned.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hscale.png">
+ <LogicalName>hscale.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hscrollbar.png">
+ <LogicalName>hscrollbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hseparator.png">
+ <LogicalName>hseparator.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\iconview.png">
+ <LogicalName>iconview.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\image.png">
+ <LogicalName>image.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\inc-border.png">
+ <LogicalName>inc-border.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\label.png">
+ <LogicalName>label.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\menu.png">
+ <LogicalName>menu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\menubar.png">
+ <LogicalName>menubar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\messagedialog.png">
+ <LogicalName>messagedialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\missing.png">
+ <LogicalName>missing.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\notebook.png">
+ <LogicalName>notebook.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\optionmenu.png">
+ <LogicalName>optionmenu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\progressbar.png">
+ <LogicalName>progressbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\radiobutton.png">
+ <LogicalName>radiobutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\remove-check-label.png">
+ <LogicalName>remove-check-label.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\remove-menu.png">
+ <LogicalName>remove-menu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\scrolledwindow.png">
+ <LogicalName>scrolledwindow.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\spinbutton.png">
+ <LogicalName>spinbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\statusbar.png">
+ <LogicalName>statusbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\table.png">
+ <LogicalName>table.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\textview.png">
+ <LogicalName>textview.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\togglebutton.png">
+ <LogicalName>togglebutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\toolbar.png">
+ <LogicalName>toolbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\treeview.png">
+ <LogicalName>treeview.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vbox.png">
+ <LogicalName>vbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vbuttonbox.png">
+ <LogicalName>vbuttonbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\viewport.png">
+ <LogicalName>viewport.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vpaned.png">
+ <LogicalName>vpaned.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vscale.png">
+ <LogicalName>vscale.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vscrollbar.png">
+ <LogicalName>vscrollbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vseparator.png">
+ <LogicalName>vseparator.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\widget.png">
+ <LogicalName>widget.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\window.png">
+ <LogicalName>window.png</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="libstetic.dll.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../../../..">
+ <BuildFilesVar Sync="true" Name="FILES" />
+ <DeployFilesVar />
+ <ResourcesVar Sync="true" Name="RES" />
+ <OthersVar />
+ <GacRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <AsmRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <ProjectRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ </MonoDevelop.Autotools.MakefileInfo>
+ </Properties>
+ </MonoDevelop>
+ <VisualStudio />
+ </ProjectExtensions>
+</Project>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.csproj b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.csproj
new file mode 100644
index 0000000000..195aeed1d7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.csproj
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AssemblyName>libstetic2</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <RootNamespace>Stetic</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\..\..\build\AddIns\MonoDevelop.GtkCore2</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Mono.Posix" />
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="Mono.Cairo" />
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ClassDescriptor.cs" />
+ <Compile Include="Clipboard.cs" />
+ <Compile Include="CommandDescriptor.cs" />
+ <Compile Include="CustomWidget.cs" />
+ <Compile Include="DND.cs" />
+ <Compile Include="editor\Accelerator.cs" />
+ <Compile Include="editor\ActionGroupEditor.cs" />
+ <Compile Include="editor\ActionItem.cs" />
+ <Compile Include="editor\ActionMenu.cs" />
+ <Compile Include="editor\ActionMenuBar.cs" />
+ <Compile Include="editor\ActionMenuItem.cs" />
+ <Compile Include="editor\ActionToolbar.cs" />
+ <Compile Include="editor\ActionToolItem.cs" />
+ <Compile Include="editor\Boolean.cs" />
+ <Compile Include="editor\CellRendererComboBox.cs" />
+ <Compile Include="editor\Char.cs" />
+ <Compile Include="editor\Color.cs" />
+ <Compile Include="editor\DateTimeEditor.cs" />
+ <Compile Include="editor\EditIconDialog.cs" />
+ <Compile Include="editor\EditIconFactoryDialog.cs" />
+ <Compile Include="editor\Enumeration.cs" />
+ <Compile Include="editor\Flags.cs" />
+ <Compile Include="editor\FlagsSelectorDialog.cs" />
+ <Compile Include="editor\FloatRange.cs" />
+ <Compile Include="editor\GroupPicker.cs" />
+ <Compile Include="editor\IconList.cs" />
+ <Compile Include="editor\IconSelectorItem.cs" />
+ <Compile Include="editor\IconSelectorMenu.cs" />
+ <Compile Include="editor\IconSelectorMenuItem.cs" />
+ <Compile Include="editor\Identifier.cs" />
+ <Compile Include="editor\Image.cs" />
+ <Compile Include="editor\ImageFile.cs" />
+ <Compile Include="editor\ImageSelector.cs" />
+ <Compile Include="editor\IntRange.cs" />
+ <Compile Include="editor\NonContainerWarningDialog.cs" />
+ <Compile Include="editor\OptIntRange.cs" />
+ <Compile Include="editor\ProjectIconList.cs" />
+ <Compile Include="editor\ProjectIconSelectorItem.cs" />
+ <Compile Include="editor\ResponseId.cs" />
+ <Compile Include="editor\SelectIconDialog.cs" />
+ <Compile Include="editor\SelectImageDialog.cs" />
+ <Compile Include="editor\StockIconList.cs" />
+ <Compile Include="editor\StockIconSelectorItem.cs" />
+ <Compile Include="editor\StockItem.cs" />
+ <Compile Include="editor\String.cs" />
+ <Compile Include="editor\StringArray.cs" />
+ <Compile Include="editor\Text.cs" />
+ <Compile Include="editor\TextBox.cs" />
+ <Compile Include="editor\TextEditor.cs" />
+ <Compile Include="editor\TextEditorDialog.cs" />
+ <Compile Include="editor\ThemedIcon.cs" />
+ <Compile Include="editor\ThemedIconList.cs" />
+ <Compile Include="editor\TimeSpanEditor.cs" />
+ <Compile Include="editor\Translatable.cs" />
+ <Compile Include="editor\TreeViewCellContainer.cs" />
+ <Compile Include="editor\WidgetSelector.cs" />
+ <Compile Include="EnumDescriptor.cs" />
+ <Compile Include="ErrorWidget.cs" />
+ <Compile Include="GeneratorContext.cs" />
+ <Compile Include="GladeException.cs" />
+ <Compile Include="GladeUtils.cs" />
+ <Compile Include="IDesignArea.cs" />
+ <Compile Include="IEditableObject.cs" />
+ <Compile Include="ImageInfo.cs" />
+ <Compile Include="IProject.cs" />
+ <Compile Include="IPropertyEditor.cs" />
+ <Compile Include="IRadioGroupManager.cs" />
+ <Compile Include="IResourceProvider.cs" />
+ <Compile Include="ItemDescriptor.cs" />
+ <Compile Include="ItemGroup.cs" />
+ <Compile Include="ItemGroupCollection.cs" />
+ <Compile Include="NoGuiDispatchAttribute.cs" />
+ <Compile Include="ObjectReader.cs" />
+ <Compile Include="ObjectWrapper.cs" />
+ <Compile Include="ObjectWrapperEventHandler.cs" />
+ <Compile Include="ObjectWriter.cs" />
+ <Compile Include="ParamSpec.cs" />
+ <Compile Include="Placeholder.cs" />
+ <Compile Include="ProjectIconFactory.cs" />
+ <Compile Include="PropertyDescriptor.cs" />
+ <Compile Include="PropertyEditorAttribute.cs" />
+ <Compile Include="PropertyEditorCell.cs" />
+ <Compile Include="RadioGroupManager.cs" />
+ <Compile Include="Registry.cs" />
+ <Compile Include="Set.cs" />
+ <Compile Include="SignalDescriptor.cs" />
+ <Compile Include="TranslatableAttribute.cs" />
+ <Compile Include="TypedClassDescriptor.cs" />
+ <Compile Include="TypedPropertyDescriptor.cs" />
+ <Compile Include="TypedSignalDescriptor.cs" />
+ <Compile Include="undo\ActionDiffAdaptor.cs" />
+ <Compile Include="undo\DiffGenerator.cs" />
+ <Compile Include="undo\IDiffAdaptor.cs" />
+ <Compile Include="undo\UndoManager.cs" />
+ <Compile Include="undo\XmlDiffAdaptor.cs" />
+ <Compile Include="WidgetLibrary.cs" />
+ <Compile Include="WidgetUtils.cs" />
+ <Compile Include="wrapper\Action.cs" />
+ <Compile Include="wrapper\ActionGroup.cs" />
+ <Compile Include="wrapper\ActionToolbarWrapper.cs" />
+ <Compile Include="wrapper\ActionTree.cs" />
+ <Compile Include="wrapper\Bin.cs" />
+ <Compile Include="wrapper\Box.cs" />
+ <Compile Include="wrapper\Button.cs" />
+ <Compile Include="wrapper\ButtonBox.cs" />
+ <Compile Include="wrapper\CheckButton.cs" />
+ <Compile Include="wrapper\ColorButton.cs" />
+ <Compile Include="wrapper\ComboBox.cs" />
+ <Compile Include="wrapper\ComboBoxEntry.cs" />
+ <Compile Include="wrapper\Container.cs" />
+ <Compile Include="wrapper\Custom.cs" />
+ <Compile Include="wrapper\Dialog.cs" />
+ <Compile Include="wrapper\Entry.cs" />
+ <Compile Include="wrapper\Expander.cs" />
+ <Compile Include="wrapper\Fixed.cs" />
+ <Compile Include="wrapper\FontButton.cs" />
+ <Compile Include="wrapper\FontSelectionDialog.cs" />
+ <Compile Include="wrapper\Frame.cs" />
+ <Compile Include="wrapper\HScale.cs" />
+ <Compile Include="wrapper\HScrollbar.cs" />
+ <Compile Include="wrapper\IconView.cs" />
+ <Compile Include="wrapper\Image.cs" />
+ <Compile Include="wrapper\ImageMenuItem.cs" />
+ <Compile Include="wrapper\Label.cs" />
+ <Compile Include="wrapper\MenuBar.cs" />
+ <Compile Include="wrapper\MenuItem.cs" />
+ <Compile Include="wrapper\MessageDialog.cs" />
+ <Compile Include="wrapper\Misc.cs" />
+ <Compile Include="wrapper\Notebook.cs" />
+ <Compile Include="wrapper\Object.cs" />
+ <Compile Include="wrapper\OptionMenu.cs" />
+ <Compile Include="wrapper\Paned.cs" />
+ <Compile Include="wrapper\RadioActionGroupManager.cs" />
+ <Compile Include="wrapper\RadioButton.cs" />
+ <Compile Include="wrapper\RadioMenuItem.cs" />
+ <Compile Include="wrapper\RadioToolButton.cs" />
+ <Compile Include="wrapper\Range.cs" />
+ <Compile Include="wrapper\Scale.cs" />
+ <Compile Include="wrapper\ScrolledWindow.cs" />
+ <Compile Include="wrapper\Signal.cs" />
+ <Compile Include="wrapper\SignalChangedEventHandler.cs" />
+ <Compile Include="wrapper\SignalCollection.cs" />
+ <Compile Include="wrapper\SignalEventHandler.cs" />
+ <Compile Include="wrapper\SpinButton.cs" />
+ <Compile Include="wrapper\Table.cs" />
+ <Compile Include="wrapper\TextView.cs" />
+ <Compile Include="wrapper\ToggleToolButton.cs" />
+ <Compile Include="wrapper\Toolbar.cs" />
+ <Compile Include="wrapper\ToolButton.cs" />
+ <Compile Include="wrapper\TreeView.cs" />
+ <Compile Include="wrapper\Viewport.cs" />
+ <Compile Include="wrapper\VScale.cs" />
+ <Compile Include="wrapper\VScrollbar.cs" />
+ <Compile Include="wrapper\Widget.cs" />
+ <Compile Include="wrapper\WidgetEventHandler.cs" />
+ <Compile Include="wrapper\WidgetNameChangedHandler.cs" />
+ <Compile Include="wrapper\Window.cs" />
+ <Compile Include="TopLevelDialog.cs" />
+ <Compile Include="TopLevelWindow.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="stetic.glade">
+ <LogicalName>stetic.glade</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\objects.xml">
+ <LogicalName>objects.xml</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\accellabel.png">
+ <LogicalName>accellabel.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\actiongroup.png">
+ <LogicalName>actiongroup.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\add-check-label.png">
+ <LogicalName>add-check-label.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\add-menu.png">
+ <LogicalName>add-menu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\alignment.png">
+ <LogicalName>alignment.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\arrow.png">
+ <LogicalName>arrow.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\box-expand.png">
+ <LogicalName>box-expand.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\box-fill.png">
+ <LogicalName>box-fill.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\button.png">
+ <LogicalName>button.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\calendar.png">
+ <LogicalName>calendar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-expand-h.png">
+ <LogicalName>cell-expand-h.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-expand-v.png">
+ <LogicalName>cell-expand-v.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-fill-h.png">
+ <LogicalName>cell-fill-h.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\cell-fill-v.png">
+ <LogicalName>cell-fill-v.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\checkbutton.png">
+ <LogicalName>checkbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\colorbutton.png">
+ <LogicalName>colorbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\colorselection.png">
+ <LogicalName>colorselection.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\colorselectiondialog.png">
+ <LogicalName>colorselectiondialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\combo.png">
+ <LogicalName>combo.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\comboentry.png">
+ <LogicalName>comboentry.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\custom.png">
+ <LogicalName>custom.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\dec-border.png">
+ <LogicalName>dec-border.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\dialog.png">
+ <LogicalName>dialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\drawingarea.png">
+ <LogicalName>drawingarea.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\entry.png">
+ <LogicalName>entry.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\eventbox.png">
+ <LogicalName>eventbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\expander.png">
+ <LogicalName>expander.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fileselection.png">
+ <LogicalName>fileselection.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fixed.png">
+ <LogicalName>fixed.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fontbutton.png">
+ <LogicalName>fontbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fontselection.png">
+ <LogicalName>fontselection.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\fontselectiondialog.png">
+ <LogicalName>fontselectiondialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\frame.png">
+ <LogicalName>frame.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\globe.png">
+ <LogicalName>globe.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\globe-not.png">
+ <LogicalName>globe-not.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\handlebox.png">
+ <LogicalName>handlebox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hbox.png">
+ <LogicalName>hbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hbuttonbox.png">
+ <LogicalName>hbuttonbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hpaned.png">
+ <LogicalName>hpaned.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hscale.png">
+ <LogicalName>hscale.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hscrollbar.png">
+ <LogicalName>hscrollbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\hseparator.png">
+ <LogicalName>hseparator.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\iconview.png">
+ <LogicalName>iconview.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\image.png">
+ <LogicalName>image.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\inc-border.png">
+ <LogicalName>inc-border.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\label.png">
+ <LogicalName>label.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\menu.png">
+ <LogicalName>menu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\menubar.png">
+ <LogicalName>menubar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\messagedialog.png">
+ <LogicalName>messagedialog.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\missing.png">
+ <LogicalName>missing.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\notebook.png">
+ <LogicalName>notebook.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\optionmenu.png">
+ <LogicalName>optionmenu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\progressbar.png">
+ <LogicalName>progressbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\radiobutton.png">
+ <LogicalName>radiobutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\remove-check-label.png">
+ <LogicalName>remove-check-label.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\remove-menu.png">
+ <LogicalName>remove-menu.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\scrolledwindow.png">
+ <LogicalName>scrolledwindow.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\spinbutton.png">
+ <LogicalName>spinbutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\statusbar.png">
+ <LogicalName>statusbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\table.png">
+ <LogicalName>table.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\textview.png">
+ <LogicalName>textview.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\togglebutton.png">
+ <LogicalName>togglebutton.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\toolbar.png">
+ <LogicalName>toolbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\treeview.png">
+ <LogicalName>treeview.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vbox.png">
+ <LogicalName>vbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vbuttonbox.png">
+ <LogicalName>vbuttonbox.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\viewport.png">
+ <LogicalName>viewport.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vpaned.png">
+ <LogicalName>vpaned.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vscale.png">
+ <LogicalName>vscale.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vscrollbar.png">
+ <LogicalName>vscrollbar.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\vseparator.png">
+ <LogicalName>vseparator.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\widget.png">
+ <LogicalName>widget.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="wrapper\pixmaps\window.png">
+ <LogicalName>window.png</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="libstetic2.dll.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../../../..">
+ <BuildFilesVar Sync="true" Name="FILES" />
+ <DeployFilesVar />
+ <ResourcesVar Sync="true" Name="RES" />
+ <OthersVar />
+ <GacRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <AsmRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <ProjectRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ </MonoDevelop.Autotools.MakefileInfo>
+ </Properties>
+ </MonoDevelop>
+ <VisualStudio />
+ </ProjectExtensions>
+</Project>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/libstetic2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/stetic.glade b/main/src/addins/MonoDevelop.GtkCore2/libstetic/stetic.glade
new file mode 100644
index 0000000000..9f58816ce1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/stetic.glade
@@ -0,0 +1,2107 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="SelectImageDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Select Image</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">650</property>
+ <property name="default_height">450</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkNotebook" id="notebook">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+ <signal name="switch_page" handler="OnCurrentPageChanged" last_modification_time="Thu, 18 May 2006 12:07:20 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="iconScrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkImage" id="previewIcon">
+ <property name="visible">True</property>
+ <property name="icon_size">4</property>
+ <property name="icon_name">gtk-missing-image</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">3</property>
+ <property name="ypad">3</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Icon Name:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">iconNameEntry</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="iconNameEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnIconNameChanged" last_modification_time="Fri, 10 Mar 2006 13:48:39 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="iconSizeCombo">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="OnIconSizeChanged" last_modification_time="Fri, 10 Mar 2006 13:50:33 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Themed Icons</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow7">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="resourceList">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkButton" id="buttonAdd">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnAddResource" last_modification_time="Fri, 10 Mar 2006 11:17:29 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="buttonRemove">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-delete</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnRemoveResource" last_modification_time="Fri, 10 Mar 2006 11:17:42 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkImage" id="previewResource">
+ <property name="width_request">30</property>
+ <property name="height_request">30</property>
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Resource Name:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="resourceNameEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnResourceNameChanged" last_modification_time="Fri, 10 Mar 2006 16:31:30 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Resources</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFileChooserWidget" id="fileChooser">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="action">GTK_FILE_CHOOSER_ACTION_OPEN</property>
+ <property name="local_only">True</property>
+ <property name="select_multiple">False</property>
+ <property name="show_hidden">False</property>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Files</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="FlagsSelectorDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Flags</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">500</property>
+ <property name="default_height">450</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area2">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow8">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="treeView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="TextEditorDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Text</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">600</property>
+ <property name="default_height">350</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area3">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton3">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow9">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTextView" id="textview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">True</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_CHAR</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">0</property>
+ <property name="right_margin">0</property>
+ <property name="indent">0</property>
+ <property name="text" translatable="yes"></property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="checkTranslatable">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Translatable</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnTranslatableToggled" last_modification_time="Fri, 17 Mar 2006 16:37:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="translationTable">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Translation Context Hint:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Comment for Translators</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entryContext">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entryComment">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="SelectIconDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Select Image</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">650</property>
+ <property name="default_height">450</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkNotebook" id="notebook">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+ <signal name="switch_page" handler="OnCurrentPageChanged" last_modification_time="Thu, 18 May 2006 12:05:33 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox6">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="iconScrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkImage" id="previewIcon">
+ <property name="visible">True</property>
+ <property name="icon_size">4</property>
+ <property name="icon_name">gtk-missing-image</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0</property>
+ <property name="xpad">3</property>
+ <property name="ypad">3</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox7">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Icon Name:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">stockIconEntry</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="stockIconEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnIconNameChanged" last_modification_time="Fri, 10 Mar 2006 13:48:39 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="labelWarningIcon">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHSeparator" id="hseparator2">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox11">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">3</property>
+
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="labelWarning">
+ <property name="width_request">513</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">The selected icon may not show at run time if the required icon factory is not properly initialized.</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Stock Icons</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox8">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="customIconScrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox2">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkButton" id="button3">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnAddIcon" last_modification_time="Wed, 17 May 2006 11:25:29 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button4">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-edit</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnEditIcon" last_modification_time="Wed, 17 May 2006 11:24:58 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button5">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-delete</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnRemoveIcon" last_modification_time="Wed, 17 May 2006 11:25:18 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Project Icons</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="EditIconDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Edit Icon</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">650</property>
+ <property name="default_height">400</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area4">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton4">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox12">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox15">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Icon name:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="nameEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">20</property>
+ <signal name="changed" handler="OnNameChanged" last_modification_time="Wed, 17 May 2006 15:53:15 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="radioSingle">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Single source icon</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="OnSingleClicked" last_modification_time="Wed, 17 May 2006 12:17:45 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hboxSingle">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label20">
+ <property name="width_request">12</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Image:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox14">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkImage" id="imageImage">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="imageLabel">
+ <property name="visible">True</property>
+ <property name="label">image name</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button9">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Select Image...</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnSelectImage" last_modification_time="Wed, 17 May 2006 12:11:57 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="radioMultiple">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Multiple source icon</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radioSingle</property>
+ <signal name="clicked" handler="OnMultipleClicked" last_modification_time="Wed, 17 May 2006 12:18:00 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox12">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label19">
+ <property name="width_request">12</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hboxMultiple">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow13">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="sourceList">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox3">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">3</property>
+
+ <child>
+ <widget class="GtkButton" id="button10">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnAddSource" last_modification_time="Wed, 17 May 2006 12:12:11 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button11">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-delete</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnRemoveSource" last_modification_time="Wed, 17 May 2006 12:12:21 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="EditIconFactoryDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Edit Icon Factory</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">450</property>
+ <property name="default_height">460</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="vbox14">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="hbuttonbox2">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button17">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-7</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox22">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="iconListScrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox4">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkButton" id="button18">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnAddIcon" last_modification_time="Wed, 17 May 2006 11:25:29 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button19">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-edit</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnEditIcon" last_modification_time="Wed, 17 May 2006 11:24:58 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button20">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-delete</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="OnRemoveIcon" last_modification_time="Wed, 17 May 2006 11:25:18 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="AddNonContainerDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Widget Designer</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area5">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton5">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox23">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ <property name="icon_size">6</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="mainBox">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label22">
+ <property name="width_request">449</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">You are trying to add a non-container widget into the main window. In &lt;b&gt;GTK#&lt;/b&gt;, widget positioning is controlled by a special type of widgets called &lt;b&gt;Container&lt;/b&gt; widgets. If you don't place the widget into a container, it will fill the all the available space in the window. Are you sure you want to continue?</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox24">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label23">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">To know more about this topic see the article:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="linkButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">GTK# Widget Layout and Packing</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="showCheck">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Don't show this message again</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/ActionDiffAdaptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/ActionDiffAdaptor.cs
new file mode 100644
index 0000000000..880aaea21a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/ActionDiffAdaptor.cs
@@ -0,0 +1,273 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+using Stetic.Wrapper;
+
+namespace Stetic.Undo
+{
+ class ActionDiffAdaptor: IDiffAdaptor
+ {
+ IProject project;
+
+ public ActionDiffAdaptor (IProject project)
+ {
+ this.project = project;
+ }
+
+ public IEnumerable GetChildren (object parent)
+ {
+ if (parent is Wrapper.Action)
+ yield break;
+ else if (parent is ActionGroup) {
+ foreach (Wrapper.Action ac in ((ActionGroup)parent).Actions)
+ if (ac.Name.Length > 0)
+ yield return ac;
+ }
+ else if (parent is ActionGroupCollection) {
+ foreach (ActionGroup ag in (ActionGroupCollection) parent)
+ yield return ag;
+ }
+ else
+ throw new NotImplementedException ();
+ }
+
+ public string GetUndoId (object childObject)
+ {
+ if (childObject is ActionGroup)
+ return ((ActionGroup)childObject).UndoId;
+ if (childObject is Wrapper.Action)
+ return ((Wrapper.Action)childObject).UndoId;
+
+ throw new NotImplementedException ();
+ }
+
+ public object FindChild (object parent, string undoId)
+ {
+ foreach (object ob in GetChildren (parent))
+ if (GetUndoId (ob) == undoId) {
+ if ((ob is Wrapper.Action) && ((Wrapper.Action)ob).Name.Length == 0)
+ continue;
+ return ob;
+ }
+ return null;
+ }
+
+ public void RemoveChild (object parent, string undoId)
+ {
+ object child = FindChild (parent, undoId);
+ if (child == null)
+ return;
+ if (parent is ActionGroup) {
+ ((ActionGroup)parent).Actions.Remove ((Wrapper.Action)child);
+ } else if (parent is ActionGroupCollection) {
+ ((ActionGroupCollection)parent).Remove ((ActionGroup)child);
+ } else
+ throw new NotImplementedException ();
+ }
+
+ public void AddChild (object parent, XmlElement node, string insertAfter)
+ {
+ object data = DeserializeChild (node);
+ if (parent is ActionGroup) {
+ ActionGroup group = (ActionGroup) parent;
+ if (insertAfter == null)
+ group.Actions.Insert (0, (Wrapper.Action) data);
+ else {
+ for (int n=0; n<group.Actions.Count; n++) {
+ if (group.Actions [n].UndoId == insertAfter) {
+ group.Actions.Insert (n+1, (Wrapper.Action) data);
+ return;
+ }
+ }
+ group.Actions.Add ((Wrapper.Action) data);
+ }
+ }
+ if (parent is ActionGroupCollection) {
+ ActionGroupCollection col = (ActionGroupCollection) parent;
+ if (insertAfter == null)
+ col.Insert (0, (ActionGroup) data);
+ else {
+ for (int n=0; n<col.Count; n++) {
+ if (col [n].UndoId == insertAfter) {
+ col.Insert (n+1, (ActionGroup) data);
+ return;
+ }
+ }
+ col.Add ((ActionGroup) data);
+ }
+ }
+ }
+
+ public IEnumerable GetProperties (object obj)
+ {
+ Wrapper.Action action = obj as Wrapper.Action;
+ if (action != null) {
+ foreach (ItemGroup iset in action.ClassDescriptor.ItemGroups) {
+ foreach (ItemDescriptor it in iset) {
+ PropertyDescriptor prop = it as PropertyDescriptor;
+
+ if (!prop.VisibleFor (action.Wrapped) || !prop.CanWrite)
+ continue;
+
+ object value = prop.GetValue (action.Wrapped);
+
+ // If the property has its default value, we don't need to check it
+ if (value == null || (prop.HasDefault && prop.IsDefaultValue (value)))
+ continue;
+
+ yield return it;
+ }
+ }
+ }
+ else if (obj is ActionGroup)
+ yield return "name"; // ActionGroup only has one property, the name
+ else
+ yield break;
+ }
+
+ public XmlElement SerializeChild (object child)
+ {
+ XmlDocument doc = new XmlDocument ();
+ ObjectWriter ow = new ObjectWriter (doc, FileFormat.Native);
+
+ if (child is Wrapper.Action) {
+ return ((Wrapper.Action)child).Write (ow);
+ } else if (child is ActionGroup) {
+ return ((ActionGroup)child).Write (ow);
+ }
+ throw new NotImplementedException ();
+ }
+
+ public object DeserializeChild (XmlElement data)
+ {
+ ObjectReader or = new ObjectReader (project, FileFormat.Native);
+ if (data.LocalName == "action") {
+ Wrapper.Action ac = new Wrapper.Action ();
+ ac.Read (or, data);
+ return ac;
+ } else if (data.LocalName == "action-group") {
+ ActionGroup ac = new ActionGroup ();
+ ac.Read (or, data);
+ return ac;
+ }
+ throw new NotImplementedException ();
+ }
+
+ public IDiffAdaptor GetChildAdaptor (object child)
+ {
+ return this;
+ }
+
+ public object GetPropertyByName (object obj, string name)
+ {
+ if (obj is Wrapper.Action) {
+ if (name == "id") name = "Name";
+ return ((Wrapper.Action)obj).ClassDescriptor [name];
+ }
+ else if (obj is ActionGroup) {
+ if (name == "name") return name;
+ }
+ throw new NotImplementedException ();
+ }
+
+ public string GetPropertyName (object property)
+ {
+ if (property is PropertyDescriptor) {
+ PropertyDescriptor prop = (PropertyDescriptor) property;
+ if (prop.Name == "Name") return "id";
+ return prop.Name;
+ }
+ else if (property is string)
+ return (string) property;
+
+ throw new NotImplementedException ();
+ }
+
+ public string GetPropertyValue (object obj, object property)
+ {
+ if (obj is Wrapper.Action) {
+ PropertyDescriptor prop = (PropertyDescriptor) property;
+ object val = prop.GetValue (((Wrapper.Action)obj).Wrapped);
+ return prop.ValueToString (val);
+ }
+ else if (obj is ActionGroup) {
+ if (((string)property) == "name")
+ return ((ActionGroup)obj).Name;
+ }
+ throw new NotImplementedException ();
+ }
+
+ public void SetPropertyValue (object obj, string name, string value)
+ {
+ if (obj is Wrapper.Action) {
+ if (name == "id") name = "Name";
+ PropertyDescriptor prop = (PropertyDescriptor) GetPropertyByName (obj, name);
+ if (prop == null)
+ throw new InvalidOperationException ("Property '" + name + "' not found in object of type: " + obj.GetType ());
+ prop.SetValue (((Wrapper.Action)obj).Wrapped, prop.StringToValue (value));
+ return;
+ }
+ else if (obj is ActionGroup) {
+ if (name == "name") {
+ ((ActionGroup)obj).Name = value;
+ return;
+ }
+ }
+ throw new NotImplementedException ();
+ }
+
+ public void ResetPropertyValue (object obj, string name)
+ {
+ if (obj is Wrapper.Action) {
+ if (name == "id") name = "Name";
+ PropertyDescriptor prop = (PropertyDescriptor) GetPropertyByName (obj, name);
+ prop.ResetValue (((Wrapper.Action)obj).Wrapped);
+ }
+ }
+
+ public IEnumerable GetSignals (object obj)
+ {
+ if (obj is Wrapper.Action) {
+ foreach (Signal s in ((Wrapper.Action)obj).Signals)
+ yield return s;
+ }
+ else
+ yield break;
+ }
+
+ public object GetSignal (object obj, string name, string handler)
+ {
+ foreach (Signal s in ((Wrapper.Action)obj).Signals) {
+ if (s.SignalDescriptor.Name == name && s.Handler == handler)
+ return s;
+ }
+ return null;
+ }
+
+ public void GetSignalInfo (object signal, out string name, out string handler)
+ {
+ Signal s = (Signal) signal;
+ name = s.SignalDescriptor.Name;
+ handler = s.Handler;
+ }
+
+ public void AddSignal (object obj, string name, string handler)
+ {
+ SignalDescriptor sd = (SignalDescriptor) ((Wrapper.Action)obj).ClassDescriptor.SignalGroups.GetItem (name);
+ Signal sig = new Signal (sd);
+ sig.Handler = handler;
+ ((Wrapper.Action)obj).Signals.Add (sig);
+ }
+
+ public void RemoveSignal (object obj, string name, string handler)
+ {
+ foreach (Signal sig in ((Wrapper.Action)obj).Signals) {
+ if (sig.SignalDescriptor.Name == name && sig.Handler == handler) {
+ ((Wrapper.Action)obj).Signals.Remove (sig);
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/DiffGenerator.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/DiffGenerator.cs
new file mode 100644
index 0000000000..3db856c08b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/DiffGenerator.cs
@@ -0,0 +1,319 @@
+
+using System;
+using System.Collections;
+using System.Xml;
+using Stetic.Wrapper;
+
+namespace Stetic.Undo
+{
+ class DiffGenerator
+ {
+ IDiffAdaptor currentStatusAdaptor;
+ IDiffAdaptor newStatusAdaptor;
+
+ public DiffGenerator ()
+ {
+ }
+
+ public DiffGenerator (IDiffAdaptor currentStatusAdaptor, IDiffAdaptor newStatusAdaptor)
+ {
+ this.currentStatusAdaptor = currentStatusAdaptor;
+ this.newStatusAdaptor = newStatusAdaptor;
+ }
+
+ public IDiffAdaptor CurrentStatusAdaptor {
+ get { return currentStatusAdaptor; }
+ set { currentStatusAdaptor = value; }
+ }
+
+ public IDiffAdaptor NewStatusAdaptor {
+ get { return newStatusAdaptor; }
+ set { newStatusAdaptor = value; }
+ }
+
+ internal ObjectDiff GetDiff (object oldStatus, object newStatus)
+ {
+ PropertyDiff[] propChanges = GetPropertyDiff (currentStatusAdaptor, oldStatus, newStatusAdaptor, newStatus);
+ PropertyDiff[] signalChanges = GetSignalDiff (currentStatusAdaptor, oldStatus, newStatusAdaptor, newStatus);
+
+ ArrayList changes = new ArrayList ();
+ Hashtable foundChildren = new Hashtable ();
+
+ // Register changed and deleted child elements
+ foreach (object oldChild in currentStatusAdaptor.GetChildren (oldStatus)) {
+ string cid = currentStatusAdaptor.GetUndoId (oldChild);
+ if (cid != null && cid.Length > 0) {
+ object newChild = newStatusAdaptor.FindChild (newStatus, cid);
+ if (newChild != null) {
+ // ChildCreate will work even if the packing element is null
+ ObjectDiff odiff = GetChildDiff (oldChild, newChild);
+ if (odiff != null) {
+ ChildDiff cdiff = new ChildDiff ();
+ cdiff.Id = cid;
+ cdiff.Operation = DiffOperation.Update;
+ cdiff.Diff = odiff;
+ changes.Add (cdiff);
+ }
+ foundChildren [cid] = cid;
+ } else {
+ ChildDiff cdiff = new ChildDiff ();
+ cdiff.Id = cid;
+ cdiff.Operation = DiffOperation.Remove;
+ changes.Add (cdiff);
+ }
+ } else {
+ throw new InvalidOperationException ("Found an element of type '" + oldChild.GetType () + "' without ID");
+ }
+ }
+
+ // Register new elements
+
+ string lastWidgetId = null;
+ foreach (object newChildElem in newStatusAdaptor.GetChildren (newStatus)) {
+ string cid = newStatusAdaptor.GetUndoId (newChildElem);
+ if (cid.Length > 0) {
+ if (!foundChildren.ContainsKey (cid)) {
+ ChildDiff cdiff = new ChildDiff ();
+ cdiff.Id = cid;
+ cdiff.Operation = DiffOperation.Add;
+ cdiff.AddContent = newStatusAdaptor.SerializeChild (newChildElem);
+ cdiff.InsertAfter = lastWidgetId;
+ changes.Add (cdiff);
+ }
+ } else
+ throw new InvalidOperationException ("Found an element of type '" + newChildElem.GetType () + "' without ID");
+
+ lastWidgetId = cid;
+ }
+
+ ChildDiff[] childChanges = null;
+ if (changes.Count > 0)
+ childChanges = (ChildDiff[]) changes.ToArray (typeof(ChildDiff));
+
+ if (childChanges != null || propChanges != null || signalChanges != null) {
+ ObjectDiff dif = new ObjectDiff ();
+ dif.PropertyChanges = propChanges;
+ dif.SignalChanges = signalChanges;
+ dif.ChildChanges = childChanges;
+ return dif;
+ }
+ else
+ return null;
+ }
+
+ public void ApplyDiff (object status, ObjectDiff diff)
+ {
+ if (diff.PropertyChanges != null)
+ ApplyPropertyChanges (diff.PropertyChanges, currentStatusAdaptor, status);
+
+ if (diff.SignalChanges != null)
+ ApplySignalChanges (diff.SignalChanges, currentStatusAdaptor, status);
+
+ if (diff.ChildChanges != null) {
+ foreach (ChildDiff cdiff in diff.ChildChanges) {
+ if (cdiff.Operation == DiffOperation.Update) {
+ object statusChild = currentStatusAdaptor.FindChild (status, cdiff.Id);
+ ApplyChildDiff (statusChild, cdiff.Diff);
+ } else if (cdiff.Operation == DiffOperation.Remove) {
+ // Remove the child
+ currentStatusAdaptor.RemoveChild (status, cdiff.Id);
+ } else {
+ // Add the child at the correct position
+ currentStatusAdaptor.AddChild (status, cdiff.AddContent, cdiff.InsertAfter);
+ }
+ }
+ }
+ }
+
+ protected virtual ObjectDiff GetChildDiff (object oldChild, object newChild)
+ {
+ DiffGenerator childGenerator = new DiffGenerator ();
+ childGenerator.CurrentStatusAdaptor = currentStatusAdaptor.GetChildAdaptor (oldChild);
+ childGenerator.NewStatusAdaptor = newStatusAdaptor.GetChildAdaptor (newChild);
+
+ return childGenerator.GetDiff (oldChild, newChild);
+ }
+
+ protected virtual void ApplyChildDiff (object child, ObjectDiff cdiff)
+ {
+ DiffGenerator childGenerator = new DiffGenerator ();
+ childGenerator.CurrentStatusAdaptor = currentStatusAdaptor.GetChildAdaptor (child);
+ childGenerator.ApplyDiff (child, cdiff);
+ }
+
+ protected virtual PropertyDiff[] GetPropertyDiff (IDiffAdaptor currentAdaptor, object currentObject, IDiffAdaptor newAdaptor, object newObject)
+ {
+ ArrayList changes = new ArrayList ();
+ Hashtable found = new Hashtable ();
+
+ // Look for modified and deleted elements
+ if (currentObject != null) {
+ foreach (object oldProp in currentAdaptor.GetProperties (currentObject)) {
+ string name = currentAdaptor.GetPropertyName (oldProp);
+ object newProp = newObject != null ? newAdaptor.GetPropertyByName (newObject, name) : null;
+ if (newProp == null)
+ changes.Add (new PropertyDiff (DiffOperation.Remove, name, null));
+ else {
+ found [name] = found;
+ string newValue = newAdaptor.GetPropertyValue (newObject, newProp);
+ if (newValue != currentAdaptor.GetPropertyValue (currentObject, oldProp))
+ changes.Add (new PropertyDiff (DiffOperation.Update, name, newValue));
+ }
+ }
+ }
+
+ // Look for new elements
+ if (newObject != null) {
+ foreach (object newProp in newAdaptor.GetProperties (newObject)) {
+ string name = newAdaptor.GetPropertyName (newProp);
+ if (!found.ContainsKey (name))
+ changes.Add (new PropertyDiff (DiffOperation.Add, name, newAdaptor.GetPropertyValue (newObject, newProp)));
+ }
+ }
+
+ if (changes.Count == 0)
+ return null;
+ return (PropertyDiff[]) changes.ToArray (typeof(PropertyDiff));
+ }
+
+ protected virtual PropertyDiff[] GetSignalDiff (IDiffAdaptor currentAdaptor, object currentObject, IDiffAdaptor newAdaptor, object newObject)
+ {
+ ArrayList changes = new ArrayList ();
+ Hashtable found = new Hashtable ();
+
+ // Look for modified and deleted elements
+ if (currentObject != null) {
+ foreach (object oldProp in currentAdaptor.GetSignals (currentObject)) {
+ string name;
+ string handler;
+ currentAdaptor.GetSignalInfo (oldProp, out name, out handler);
+ object newProp = newObject != null ? newAdaptor.GetSignal (newObject, name, handler) : null;
+ if (newProp == null)
+ changes.Add (new PropertyDiff (DiffOperation.Remove, name, handler));
+ found [name + " " + handler] = found;
+ }
+ }
+
+ // Look for new elements
+ if (newObject != null) {
+ foreach (object newProp in newAdaptor.GetSignals (newObject)) {
+ string name;
+ string handler;
+ newAdaptor.GetSignalInfo (newProp, out name, out handler);
+ if (!found.ContainsKey (name + " " + handler))
+ changes.Add (new PropertyDiff (DiffOperation.Add, name, handler));
+ }
+ }
+
+ if (changes.Count == 0)
+ return null;
+ return (PropertyDiff[]) changes.ToArray (typeof(PropertyDiff));
+ }
+
+ public virtual void ApplyPropertyChanges (PropertyDiff[] changes, IDiffAdaptor adaptor, object obj)
+ {
+ foreach (PropertyDiff pdif in changes) {
+ if (pdif.Operation == DiffOperation.Add || pdif.Operation == DiffOperation.Update)
+ adaptor.SetPropertyValue (obj, pdif.Name, pdif.Text);
+ else
+ adaptor.ResetPropertyValue (obj, pdif.Name);
+ }
+ }
+
+ public virtual void ApplySignalChanges (PropertyDiff[] changes, IDiffAdaptor adaptor, object obj)
+ {
+ foreach (PropertyDiff pdif in changes) {
+ if (pdif.Operation == DiffOperation.Add)
+ adaptor.AddSignal (obj, pdif.Name, pdif.Text);
+ else
+ adaptor.RemoveSignal (obj, pdif.Name, pdif.Text);
+ }
+ }
+ }
+
+
+ class PropertyDiff
+ {
+ public PropertyDiff (DiffOperation Operation, string Name, string Text)
+ {
+ this.Operation = Operation;
+ this.Name = Name;
+ this.Text = Text;
+ }
+
+ public DiffOperation Operation;
+ public string Name;
+ public string Text;
+ }
+
+ enum DiffOperation
+ {
+ Add,
+ Remove,
+ Update
+ }
+
+ class ChildDiff
+ {
+ public string Id;
+ public DiffOperation Operation;
+ public XmlElement AddContent;
+ public string InsertAfter;
+ public ObjectDiff Diff;
+
+ public string ToString (int indent)
+ {
+ string ind = new string (' ', indent);
+ string s = ind + Operation + " id:" + Id + "\n";
+ if (Operation == DiffOperation.Update)
+ s += Diff.ToString (indent + 2) + "\n";
+ if (Operation == DiffOperation.Add) {
+ s += ind + " InsertAfter: " + InsertAfter + "\n";
+ s += ind + " Content: " + AddContent.OuterXml + "\n";
+ }
+ return s;
+ }
+ }
+
+ class ObjectDiff
+ {
+ public PropertyDiff[] PropertyChanges;
+ public PropertyDiff[] SignalChanges;
+ public ChildDiff[] ChildChanges;
+
+ public override string ToString ()
+ {
+ return ToString (0);
+ }
+
+ internal string ToString (int indent)
+ {
+ string ind = new string (' ', indent);
+ string s = ind + "ObjectDiff:\n";
+
+ if (PropertyChanges != null) {
+ s += ind + " Properties:\n";
+ foreach (PropertyDiff d in PropertyChanges) {
+ s += ind + " " + d.Operation + ": " + d.Name;
+ if (d.Operation != DiffOperation.Remove)
+ s += " = " + d.Text;
+ s += "\n";
+ }
+ }
+
+ if (SignalChanges != null) {
+ s += ind + " Signals:\n";
+ foreach (PropertyDiff d in SignalChanges)
+ s += ind + " " + d.Operation + ": " + d.Name + " - " + d.Text + "\n";
+ }
+
+ if (ChildChanges != null) {
+ s += ind + " Children:\n";
+ foreach (ChildDiff cd in ChildChanges)
+ s += cd.ToString (indent + 4);
+ }
+
+ return s;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/IDiffAdaptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/IDiffAdaptor.cs
new file mode 100644
index 0000000000..aab6567c81
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/IDiffAdaptor.cs
@@ -0,0 +1,31 @@
+
+using System;
+using System.Collections;
+using System.Xml;
+
+namespace Stetic.Undo
+{
+ interface IDiffAdaptor
+ {
+ IEnumerable GetChildren (object parent);
+ string GetUndoId (object childObject);
+ object FindChild (object parent, string undoId);
+ void RemoveChild (object parent, string undoId);
+ void AddChild (object parent, XmlElement data, string insertAfter);
+ XmlElement SerializeChild (object child);
+ IDiffAdaptor GetChildAdaptor (object child);
+
+ IEnumerable GetProperties (object obj);
+ object GetPropertyByName (object obj, string name);
+ string GetPropertyName (object property);
+ string GetPropertyValue (object obj, object property);
+ void SetPropertyValue (object obj, string name, string value);
+ void ResetPropertyValue (object obj, string name);
+
+ IEnumerable GetSignals (object obj);
+ object GetSignal (object obj, string name, string handler);
+ void GetSignalInfo (object signal, out string name, out string handler);
+ void AddSignal (object obj, string name, string handler);
+ void RemoveSignal (object obj, string name, string handler);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/UndoManager.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/UndoManager.cs
new file mode 100644
index 0000000000..12e5f14d84
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/UndoManager.cs
@@ -0,0 +1,315 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+using Stetic.Wrapper;
+
+namespace Stetic
+{
+ // This class holds an xml tree which describes the whole widget structure being designed.
+ // It is used by the Undo/Redo infrastructure to keep track of changes in widgets.
+ public class UndoManager
+ {
+ Hashtable elements = new Hashtable ();
+ XmlDocument doc;
+ ObjectWrapper root;
+ AtomicChangeTracker atomicChangeTracker;
+ bool isDefaultManager;
+
+ public event UndoCheckpointHandler UndoCheckpoint;
+
+ public UndoManager ()
+ {
+ atomicChangeTracker = new AtomicChangeTracker ();
+ atomicChangeTracker.undoManager = this;
+ }
+
+ internal UndoManager (bool isDefaultManager): this ()
+ {
+ this.isDefaultManager = isDefaultManager;
+ }
+
+ public void SetRoot (ObjectWrapper wrapper)
+ {
+ root = wrapper;
+ wrapper.UndoManager = this;
+ elements.Clear ();
+
+ doc = new XmlDocument ();
+ UndoWriter writer = new UndoWriter (doc, this);
+ writer.WriteObject (wrapper);
+ }
+
+ internal bool CanNotifyChanged (ObjectWrapper wrapper)
+ {
+ if (!InAtomicChange) {
+ if (IsRegistered (wrapper) && UndoCheckpoint != null)
+ UndoCheckpoint (this, new UndoCheckpointEventArgs (new ObjectWrapper[] { wrapper }));
+ return true;
+ } else
+ return atomicChangeTracker.ProcessChange (wrapper);
+ }
+
+ public IAtomicChange AtomicChange {
+ get {
+ atomicChangeTracker.Count++;
+ return atomicChangeTracker;
+ }
+ }
+
+ public bool InAtomicChange {
+ get { return atomicChangeTracker.InAtomicChange; }
+ }
+
+ // This method can be called by containers to register new objects in the tree.
+ // Unless an object is registered in this way, no status will be tracked for it.
+ // The provided status element must be a direct or indirect child of the parent status.
+ internal void RegisterObject (ObjectWrapper w, XmlElement status)
+ {
+ VerifyManager ();
+
+ if (IsRegistered (w))
+ throw new InvalidOperationException ("Object already registered: " + w.GetType ());
+
+ elements [w] = GetLocalElement (status);
+
+ w.Disposed += OnObjectDisposed;
+ }
+
+ void OnObjectDisposed (object s, EventArgs a)
+ {
+ ObjectWrapper w = (ObjectWrapper) s;
+ UnregisterObject (w);
+ w.Disposed -= OnObjectDisposed;
+ }
+
+ // This method can be called to update the xml tree, for example when a change in the
+ // object is detected.
+ internal void UpdateObjectStatus (ObjectWrapper w, XmlElement status)
+ {
+ VerifyManager ();
+
+ XmlElement oldElem = (XmlElement) elements [w];
+ if (oldElem == null)
+ throw new InvalidOperationException ("Could not update unregistered object of type " + w.GetType ());
+
+ if (oldElem != status) {
+ XmlElement newElem = GetLocalElement (status);
+ if (oldElem.ParentNode != null) {
+ oldElem.ParentNode.ReplaceChild (newElem, oldElem);
+ elements [w] = newElem;
+ } else {
+ if (w != root)
+ throw new InvalidOperationException ("Root element does not match the root widget: " + w.GetType ());
+ elements [w] = newElem;
+ }
+ }
+ }
+
+ // Returns the xml that describes the specified widget (including information for all
+ // children of the widget).
+ internal XmlElement GetObjectStatus (ObjectWrapper w)
+ {
+ VerifyManager ();
+
+ XmlElement elem = (XmlElement) elements [w];
+ if (elem == null)
+ throw new InvalidOperationException ("No status found for object of type " + w.GetType ());
+ return elem;
+ }
+
+ internal bool IsRegistered (ObjectWrapper w)
+ {
+ return elements.ContainsKey (w);
+ }
+
+ internal void UnregisterObject (ObjectWrapper w)
+ {
+ VerifyManager ();
+ elements.Remove (w);
+ }
+
+ void VerifyManager ()
+ {
+ if (isDefaultManager)
+ throw new InvalidOperationException ("The default UndoManager can't track changes in objects.");
+ }
+
+ XmlElement GetLocalElement (XmlElement elem)
+ {
+ if (elem.OwnerDocument != doc)
+ throw new InvalidOperationException ("Invalid document owner.");
+ return elem;
+ }
+
+ internal void NotifyUndoCheckpoint (ObjectWrapper[] obs)
+ {
+ if (UndoCheckpoint != null)
+ UndoCheckpoint (this, new UndoCheckpointEventArgs (obs));
+ }
+
+ internal void Dump ()
+ {
+ Console.WriteLine ("--------------------------------------");
+ Console.WriteLine ("UNDO STATUS:");
+ Console.WriteLine (GetObjectStatus (root).OuterXml);
+ Console.WriteLine ("--------------------------------------");
+ }
+ }
+
+ public delegate void UndoCheckpointHandler (object sender, UndoCheckpointEventArgs args);
+
+ public class UndoCheckpointEventArgs: EventArgs
+ {
+ ObjectWrapper[] objects;
+
+ internal UndoCheckpointEventArgs (ObjectWrapper[] objects)
+ {
+ this.objects = objects;
+ }
+
+ public ObjectWrapper[] ModifiedObjects {
+ get { return objects; }
+ }
+ }
+
+ // This is a special writer use to generate status info from widgets.
+ // This writer won't recurse through objects which are already registered
+ // in the provided UndoManager.
+ class UndoWriter: ObjectWriter
+ {
+ UndoManager undoManager;
+ bool allowMarkers = true;
+
+ public UndoWriter (XmlDocument doc, UndoManager undoManager): base (doc, FileFormat.Native)
+ {
+ this.undoManager = undoManager;
+ CreateUndoInfo = true;
+ }
+
+ public override XmlElement WriteObject (ObjectWrapper wrapper)
+ {
+ Wrapper.Widget ww = wrapper as Wrapper.Widget;
+
+ // If the object is already registered, skip it (just create a dummy object)
+ if (allowMarkers && ww != null && undoManager.IsRegistered (ww) && !ww.RequiresUndoStatusUpdate) {
+ XmlElement marker = XmlDocument.CreateElement ("widget");
+ marker.SetAttribute ("unchanged_marker","yes");
+ return marker;
+ }
+
+ // Don't allow markers in indirect children, since those are not checked
+ // when creating the diff
+ bool oldAllow = allowMarkers;
+ allowMarkers = false;
+ XmlElement elem = base.WriteObject (wrapper);
+ allowMarkers = oldAllow;
+
+ if (ww != null) {
+ ww.RequiresUndoStatusUpdate = false;
+ }
+
+ // Register the object, so it is correctly bound to this xml element
+ if (undoManager.IsRegistered (wrapper))
+ undoManager.UnregisterObject (wrapper);
+ undoManager.RegisterObject (wrapper, elem);
+
+ return elem;
+ }
+ }
+
+ class UndoReader: ObjectReader
+ {
+ UndoManager undoManager;
+
+ public UndoReader (IProject proj, FileFormat format, UndoManager undoManager): base (proj, format)
+ {
+ this.undoManager = undoManager;
+ }
+
+ public override ObjectWrapper ReadObject (XmlElement elem, ObjectWrapper root)
+ {
+ ObjectWrapper ww = base.ReadObject (elem, root);
+ if (ww is Widget)
+ undoManager.RegisterObject ((Widget)ww, elem);
+ return ww;
+ }
+
+ public override void ReadExistingObject (ObjectWrapper wrapper, XmlElement elem)
+ {
+ base.ReadExistingObject (wrapper, elem);
+ if (wrapper is Widget)
+ undoManager.RegisterObject ((Widget)wrapper, elem);
+ }
+ }
+
+ public interface IAtomicChange: IDisposable
+ {
+ void Delay ();
+ }
+
+ class AtomicChangeTracker: IAtomicChange
+ {
+ public int Count;
+ public ArrayList ChangeEventPending = new ArrayList ();
+ public UndoManager undoManager;
+ bool delayed;
+
+ public bool InAtomicChange {
+ get { return Count > 0; }
+ }
+
+ public bool ProcessChange (ObjectWrapper wrapper)
+ {
+ if (!ChangeEventPending.Contains (wrapper)) {
+ ChangeEventPending.Add (wrapper);
+ delayed = false;
+ }
+ return false;
+ }
+
+ public void Delay ()
+ {
+ delayed = true;
+ }
+
+ public void Dispose ()
+ {
+ if (Count == 0)
+ return;
+
+ if (Count == 1) {
+ // The change events fired here may generate changes in other
+ // objects. Those changes will also be included in the transaction.
+ // So, the ChangeEventPending array may grow while calling NotifyChanged,
+ // and that's ok.
+
+ for (int n=0; n < ChangeEventPending.Count; n++) {
+ ((ObjectWrapper)ChangeEventPending[n]).FireObjectChangedEvent ();
+ }
+
+ // Remove from the list the widgets that have been disposed. It means that
+ // they have been deleted. That change will be recorded by their parents.
+ // Remove as well wrappers that are not registered, since there won't be
+ // status information for them.
+ for (int n=0; n<ChangeEventPending.Count; n++) {
+ ObjectWrapper w = (ObjectWrapper)ChangeEventPending[n];
+ if (w.IsDisposed || !undoManager.IsRegistered (w)) {
+ ChangeEventPending.RemoveAt (n);
+ n--;
+ }
+ }
+
+ ObjectWrapper[] obs = (ObjectWrapper[]) ChangeEventPending.ToArray (typeof(ObjectWrapper));
+ ChangeEventPending.Clear ();
+ Count = 0;
+
+ if (!delayed)
+ undoManager.NotifyUndoCheckpoint (obs);
+ delayed = false;
+ }
+ else
+ Count--;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/XmlDiffAdaptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/XmlDiffAdaptor.cs
new file mode 100644
index 0000000000..5d30c15078
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/undo/XmlDiffAdaptor.cs
@@ -0,0 +1,230 @@
+
+using System;
+using System.Collections;
+using System.Xml;
+
+namespace Stetic.Undo
+{
+ class XmlDiffAdaptor: IDiffAdaptor
+ {
+ string childElementName;
+ string propsElementName;
+ bool processProperties = true;
+ XmlDiffAdaptor childAdaptor;
+
+ public XmlDiffAdaptor ChildAdaptor {
+ get { return childAdaptor; }
+ set { childAdaptor = value; }
+ }
+
+ public string ChildElementName {
+ get { return childElementName; }
+ set { childElementName = value; }
+ }
+
+ public string PropsElementName {
+ get { return propsElementName; }
+ set { propsElementName = value; }
+ }
+
+ public bool ProcessProperties {
+ get { return processProperties; }
+ set { processProperties = value; }
+ }
+
+ public IEnumerable GetChildren (object parent)
+ {
+ if (childElementName != null)
+ return ((XmlElement)parent).SelectNodes (childElementName);
+ else
+ return new object[0];
+ }
+
+ public string GetUndoId (object childObject)
+ {
+ return ((XmlElement)childObject).GetAttribute ("undoId");
+ }
+
+ public object FindChild (object parent, string undoId)
+ {
+ return ((XmlElement) parent).SelectSingleNode (childElementName + "[@undoId='" + undoId + "']");
+ }
+
+ public void RemoveChild (object parent, string undoId)
+ {
+ XmlElement elem = (XmlElement) parent;
+ XmlElement child = (XmlElement) elem.SelectSingleNode (childElementName + "[@undoId='" + undoId + "']");
+ if (child != null)
+ elem.RemoveChild (child);
+ }
+
+ public void AddChild (object parent, XmlElement newNode, string insertAfter)
+ {
+ XmlElement status = (XmlElement) parent;
+ if (newNode.OwnerDocument != status.OwnerDocument)
+ newNode = (XmlElement) status.OwnerDocument.ImportNode (newNode, true);
+
+ if (insertAfter != null) {
+ XmlElement statusChild = (XmlElement) status.SelectSingleNode (childElementName + "[@undoId='" + insertAfter + "']");
+ if (statusChild != null)
+ status.InsertAfter (newNode, statusChild);
+ else
+ status.AppendChild (newNode);
+ } else {
+ if (status.FirstChild != null)
+ status.InsertBefore (newNode, status.FirstChild);
+ else
+ status.AppendChild (newNode);
+ }
+ }
+
+ public XmlElement SerializeChild (object child)
+ {
+ return (XmlElement) child;
+ }
+
+ public object DeserializeChild (XmlElement data)
+ {
+ return data;
+ }
+
+ public IDiffAdaptor GetChildAdaptor (object child)
+ {
+ if (childAdaptor != null)
+ return childAdaptor;
+ else
+ return this;
+ }
+
+ XmlElement GetPropsElem (object obj, bool create)
+ {
+ if (propsElementName != null) {
+ XmlElement elem = ((XmlElement)obj) [propsElementName];
+ if (elem == null && create) {
+ elem = ((XmlElement)obj).OwnerDocument.CreateElement (propsElementName);
+ ((XmlElement)obj).AppendChild (elem);
+ }
+ return elem;
+ }
+ else
+ return (XmlElement) obj;
+ }
+
+ public IEnumerable GetProperties (object obj)
+ {
+ XmlElement elem = GetPropsElem (obj, false);
+ if (elem != null && processProperties) {
+ XmlAttribute at = elem.Attributes ["name"];
+ if (at != null)
+ yield return at;
+ at = elem.Attributes ["id"];
+ if (at != null)
+ yield return at;
+ foreach (XmlElement e in elem.SelectNodes ("property"))
+ yield return e;
+ } else
+ yield break;
+ }
+
+ public object GetPropertyByName (object obj, string name)
+ {
+ XmlElement elem = GetPropsElem (obj, false);
+ if (elem == null)
+ return null;
+ XmlElement prop = (XmlElement) elem.SelectSingleNode ("property[@name='" + name + "']");
+ if (prop != null)
+ return prop;
+ return elem.Attributes [name];
+ }
+
+ public string GetPropertyName (object property)
+ {
+ if (property is XmlElement)
+ return ((XmlElement)property).GetAttribute ("name");
+ else
+ return ((XmlAttribute)property).LocalName;
+ }
+
+ public string GetPropertyValue (object obj, object property)
+ {
+ if (property is XmlElement)
+ return ((XmlElement)property).InnerText;
+ else
+ return ((XmlAttribute)property).Value;
+ }
+
+ public void SetPropertyValue (object obj, string name, string value)
+ {
+ XmlElement elem = GetPropsElem (obj, true);
+ if (name == "id" || name == "name") {
+ elem.SetAttribute (name, value);
+ } else {
+ XmlElement prop = (XmlElement) elem.SelectSingleNode ("property[@name='" + name + "']");
+ if (prop == null) {
+ prop = elem.OwnerDocument.CreateElement ("property");
+ prop.SetAttribute ("name", name);
+ elem.AppendChild (prop);
+ }
+ prop.InnerText = value;
+ }
+ }
+
+ public void ResetPropertyValue (object obj, string name)
+ {
+ XmlElement elem = GetPropsElem (obj, false);
+ if (elem == null)
+ return;
+ XmlElement prop = (XmlElement) elem.SelectSingleNode ("property[@name='" + name + "']");
+ if (prop != null)
+ elem.RemoveChild (prop);
+ else {
+ XmlAttribute at = elem.Attributes [name];
+ if (at != null)
+ elem.Attributes.Remove (at);
+ }
+ }
+
+ public IEnumerable GetSignals (object obj)
+ {
+ XmlElement elem = GetPropsElem (obj, false);
+ if (elem != null && processProperties)
+ return elem.SelectNodes ("signal");
+ else
+ return Type.EmptyTypes;
+ }
+
+ public object GetSignal (object obj, string name, string handler)
+ {
+ XmlElement elem = GetPropsElem (obj, false);
+ if (elem == null)
+ return null;
+ return elem.SelectSingleNode ("signal[@name='" + name + "' and @handler='" + handler + "']");
+ }
+
+ public void GetSignalInfo (object signal, out string name, out string handler)
+ {
+ XmlElement elem = (XmlElement) signal;
+ name = elem.GetAttribute ("name");
+ handler = elem.GetAttribute ("handler");
+ }
+
+ public void AddSignal (object obj, string name, string handler)
+ {
+ XmlElement elem = GetPropsElem (obj, true);
+ XmlElement signal = elem.OwnerDocument.CreateElement ("signal");
+ signal.SetAttribute ("name", name);
+ signal.SetAttribute ("handler", handler);
+ elem.AppendChild (signal);
+ }
+
+ public void RemoveSignal (object obj, string name, string handler)
+ {
+ XmlElement elem = GetPropsElem (obj, false);
+ if (elem == null)
+ return;
+ XmlElement prop = (XmlElement) elem.SelectSingleNode ("signal[@name='" + name + "' && @handler='" + handler + "']");
+ if (prop != null)
+ elem.RemoveChild (prop);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/AboutDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/AboutDialog.cs
new file mode 100644
index 0000000000..52da310dbf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/AboutDialog.cs
@@ -0,0 +1,75 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public class AboutDialog : Window {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ if (!initialized) {
+ // FIXME; set from Project eventually
+ about.Name = "My Application";
+ }
+ }
+
+ Gtk.AboutDialog about {
+ get {
+ return (Gtk.AboutDialog)Wrapped;
+ }
+ }
+
+ string logo;
+ public string Logo {
+ get {
+ return logo;
+ }
+ set {
+ logo = value;
+ about.Logo = new Gdk.Pixbuf (logo);
+ }
+ }
+
+ // In the underlying representation, WebsiteLabel is always set
+ // if Website is; if you set Website to something, and WebsiteLabel
+ // is null, then WebsiteLabel gets set to match Website. There are
+ // two problems with this for us:
+ //
+ // 1. If you type "http..." into Website while WebsiteLabel is
+ // blank, WebsiteLabel ends up being forcibly set to just "h".
+ //
+ // 2. If the user decides s/he wants to get rid of WebsiteLabel,
+ // they have to actually copy the URL from Website over it.
+ //
+ // In Stetic's representation, WebsiteLabel is always "what to show
+ // *instead of* Website", and if it's empty, then you see the raw URL.
+
+ public string Website {
+ get {
+ return about.Website;
+ }
+ set {
+ if (website_label == null)
+ about.WebsiteLabel = value;
+ about.Website = value;
+ }
+ }
+
+ string website_label;
+ public string WebsiteLabel {
+ get {
+ return website_label;
+ }
+ set {
+ if (value == "" || value == null) {
+ about.WebsiteLabel = about.Website;
+ website_label = null;
+ } else {
+ about.WebsiteLabel = value;
+ website_label = value;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Action.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Action.cs
new file mode 100644
index 0000000000..bc6dd51c91
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Action.cs
@@ -0,0 +1,504 @@
+
+using System;
+using System.Text;
+using System.Xml;
+using System.CodeDom;
+using System.Collections;
+using Stetic.Undo;
+
+namespace Stetic.Wrapper
+{
+ public sealed class Action: Stetic.Wrapper.Object, IRadioGroupManagerProvider
+ {
+ ActionType type;
+ bool drawAsRadio;
+ int radioValue;
+ bool active;
+ string name;
+ string accelerator;
+ ActionGroup group;
+
+ string oldDefaultName;
+ string nameRoot;
+
+ static RadioActionGroupManager GroupManager = new RadioActionGroupManager ();
+
+ public enum ActionType {
+ Action,
+ Toggle,
+ Radio
+ }
+
+ public event EventHandler Activated;
+ public event EventHandler Toggled;
+ public event Gtk.ChangedHandler Changed;
+ public event EventHandler Deleted;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ }
+
+ public Gtk.Action GtkAction {
+ get { return (Gtk.Action) Wrapped; }
+ }
+
+ public override string Name {
+ get {
+ if (name == null || name.Length == 0) {
+ name = nameRoot = oldDefaultName = GetDefaultName ();
+ if (group != null)
+ name = group.GetValidName (this, name);
+ }
+ return name;
+ }
+ set {
+ name = nameRoot = value;
+ if (group != null)
+ name = group.GetValidName (this, name);
+ EmitNotify ("Name");
+ }
+ }
+
+ public string Label {
+ get { return GtkAction.Label; }
+ set { GtkAction.Label = value; EmitNotify ("Label"); }
+ }
+
+ public string StockId {
+ get { return GtkAction.StockId; }
+ set { GtkAction.StockId = value; EmitNotify ("StockId"); }
+ }
+
+ public override string WrappedTypeName {
+ get {
+ if (type == ActionType.Action)
+ return "Gtk.Action";
+ else if (type == ActionType.Toggle)
+ return "Gtk.ToggleAction";
+ else
+ return "Gtk.RadioAction";
+ }
+ }
+
+ IRadioGroupManager IRadioGroupManagerProvider.GetGroupManager ()
+ {
+ return GroupManager;
+ }
+
+ internal void UpdateNameIndex ()
+ {
+ // Adds a number to the action name if the current name already
+ // exists in the action group.
+
+ string vname = group.GetValidName (this, Name);
+ if (vname != Name) {
+ name = vname;
+ EmitNotify ("Name");
+ }
+ }
+
+ string GetDefaultName ()
+ {
+ // Don't use the label for stock actions, since it depends on the current locale
+ if (!string.IsNullOrEmpty (GtkAction.StockId)) {
+ if (GtkAction.StockId.StartsWith ("gtk-"))
+ return GetIdentifier (GtkAction.StockId.Substring (4));
+ if (GtkAction.StockId.StartsWith ("gnome-stock-"))
+ return GetIdentifier (GtkAction.StockId.Substring (12));
+ }
+
+ if (!string.IsNullOrEmpty (GtkAction.Label))
+ return GetIdentifier (GtkAction.Label);
+
+ if (!string.IsNullOrEmpty (GtkAction.StockId))
+ return GetIdentifier (GtkAction.StockId);
+
+ return "Action";
+ }
+
+ public ActionType Type {
+ get { return type; }
+ set {
+ if (type == value)
+ return;
+ type = value;
+ if (type == ActionType.Radio)
+ Group = GroupManager.LastGroup;
+ else
+ Group = null;
+
+ EmitNotify ("Type");
+ }
+ }
+
+ public bool DrawAsRadio {
+ get { return drawAsRadio; }
+ set { drawAsRadio = value; EmitNotify ("DrawAsRadio"); }
+ }
+
+ public int Value {
+ get { return radioValue; }
+ set { radioValue = value; EmitNotify ("Value"); }
+ }
+
+ public string Accelerator {
+ get { return accelerator; }
+ set { accelerator = value; EmitNotify ("Accelerator"); }
+ }
+
+ public bool Active {
+ get { return active; }
+ set {
+ active = value;
+ if (Activated != null)
+ Activated (this, EventArgs.Empty);
+ if (Toggled != null)
+ Toggled (this, EventArgs.Empty);
+ if (Changed != null)
+ Changed (this, new Gtk.ChangedArgs ());
+ }
+ }
+
+ public string MenuLabel {
+ get {
+ if (GtkAction.Label != null && GtkAction.Label.Length > 0)
+ return GtkAction.Label;
+
+ if (GtkAction.StockId == null)
+ return "";
+
+ Gtk.StockItem item = Gtk.Stock.Lookup (GtkAction.StockId);
+ if (item.Label != null)
+ return item.Label;
+
+ return "";
+ }
+ }
+
+ public string ToolLabel {
+ get {
+ if (GtkAction.ShortLabel != null && GtkAction.ShortLabel.Length > 0)
+ return GtkAction.ShortLabel;
+ else
+ return MenuLabel;
+ }
+ }
+
+ public ActionGroup ActionGroup {
+ get { return group; }
+ }
+
+ public string Group {
+ get {
+ return GroupManager.GetGroup (this);
+ }
+ set {
+ if (value != null && value.Length > 0)
+ Type = ActionType.Radio;
+ GroupManager.SetGroup (this, value);
+ EmitNotify ("Group");
+ }
+ }
+
+ public void Delete ()
+ {
+ if (group != null)
+ group.Actions.Remove (this);
+ if (Deleted != null)
+ Deleted (this, EventArgs.Empty);
+ Dispose ();
+ }
+
+ protected override void EmitNotify (string propertyName)
+ {
+ if (propertyName == "Label" || propertyName == "StockId") {
+ // If the current name is a name generated from label or stockid,
+ // we update here the name again
+ if (nameRoot == oldDefaultName)
+ Name = GetDefaultName ();
+ oldDefaultName = GetDefaultName ();
+ }
+ base.EmitNotify (propertyName);
+ }
+
+ public override XmlElement Write (ObjectWriter writer)
+ {
+ XmlElement elem = writer.XmlDocument.CreateElement ("action");
+ elem.SetAttribute ("id", Name);
+ WidgetUtils.GetProps (this, elem);
+ WidgetUtils.GetSignals (this, elem);
+ if (writer.CreateUndoInfo)
+ elem.SetAttribute ("undoId", UndoId);
+ return elem;
+ }
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ Gtk.Action ac = new Gtk.Action ("", "");
+
+ ClassDescriptor klass = Registry.LookupClassByName ("Gtk.Action");
+ ObjectWrapper.Bind (reader.Project, klass, this, ac, true);
+
+ WidgetUtils.ReadMembers (klass, this, ac, elem);
+ name = nameRoot = oldDefaultName = elem.GetAttribute ("id");
+
+ string uid = elem.GetAttribute ("undoId");
+ if (uid.Length > 0)
+ UndoId = uid;
+ }
+
+ public Action Clone ()
+ {
+ Action a = (Action) ObjectWrapper.Create (Project, new Gtk.Action ("", ""), this);
+ a.CopyFrom (this);
+ return a;
+ }
+
+ public void CopyFrom (Action action)
+ {
+ type = action.type;
+ drawAsRadio = action.drawAsRadio;
+ radioValue = action.radioValue;
+ active = action.active;
+ name = action.name;
+ GtkAction.HideIfEmpty = action.GtkAction.HideIfEmpty;
+ GtkAction.IsImportant = action.GtkAction.IsImportant;
+ GtkAction.Label = action.GtkAction.Label;
+ GtkAction.Sensitive = action.GtkAction.Sensitive;
+ GtkAction.ShortLabel = action.GtkAction.ShortLabel;
+ GtkAction.StockId = action.GtkAction.StockId;
+ GtkAction.Tooltip = action.GtkAction.Tooltip;
+ GtkAction.Visible = action.GtkAction.Visible;
+ GtkAction.VisibleHorizontal = action.GtkAction.VisibleHorizontal;
+ GtkAction.VisibleVertical = action.GtkAction.VisibleVertical;
+
+ Signals.Clear ();
+ foreach (Signal s in action.Signals)
+ Signals.Add (new Signal (s.SignalDescriptor, s.Handler, s.After));
+
+ NotifyChanged ();
+ }
+
+ public Gtk.Widget CreateIcon (Gtk.IconSize size)
+ {
+ if (GtkAction.StockId == null)
+ return null;
+
+ Gdk.Pixbuf px = Project.IconFactory.RenderIcon (Project, GtkAction.StockId, size);
+ if (px != null)
+ return new Gtk.Image (px);
+ else
+ return GtkAction.CreateIcon (size);
+ }
+
+ public Gdk.Pixbuf RenderIcon (Gtk.IconSize size)
+ {
+ if (GtkAction.StockId == null)
+ return null;
+
+ Gdk.Pixbuf px = Project.IconFactory.RenderIcon (Project, GtkAction.StockId, size);
+ if (px != null)
+ return px;
+
+ Gtk.IconSet iset = Gtk.IconFactory.LookupDefault (GtkAction.StockId);
+ if (iset == null)
+ return WidgetUtils.MissingIcon;
+ else
+ return iset.RenderIcon (new Gtk.Style (), Gtk.TextDirection.Ltr, Gtk.StateType.Normal, size, null, "");
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ CodeObjectCreateExpression exp = new CodeObjectCreateExpression ();
+
+ PropertyDescriptor prop = (PropertyDescriptor) ClassDescriptor ["Name"];
+ exp.Parameters.Add (ctx.GenerateValue (prop.GetValue (Wrapped), prop.RuntimePropertyType));
+
+ prop = (PropertyDescriptor) ClassDescriptor ["Label"];
+ string lab = (string) prop.GetValue (Wrapped);
+ if (lab == "") lab = null;
+ exp.Parameters.Add (ctx.GenerateValue (lab, prop.RuntimePropertyType, prop.Translatable));
+
+ prop = (PropertyDescriptor) ClassDescriptor ["Tooltip"];
+ exp.Parameters.Add (ctx.GenerateValue (prop.GetValue (Wrapped), prop.RuntimePropertyType, prop.Translatable));
+
+ prop = (PropertyDescriptor) ClassDescriptor ["StockId"];
+ exp.Parameters.Add (ctx.GenerateValue (prop.GetValue (Wrapped), prop.RuntimePropertyType, prop.Translatable));
+
+ if (type == ActionType.Action)
+ exp.CreateType = new CodeTypeReference ("Gtk.Action", CodeTypeReferenceOptions.GlobalReference);
+ else if (type == ActionType.Toggle)
+ exp.CreateType = new CodeTypeReference ("Gtk.ToggleAction", CodeTypeReferenceOptions.GlobalReference);
+ else {
+ exp.CreateType = new CodeTypeReference ("Gtk.RadioAction", CodeTypeReferenceOptions.GlobalReference);
+ prop = (PropertyDescriptor) ClassDescriptor ["Value"];
+ exp.Parameters.Add (ctx.GenerateValue (prop.GetValue (Wrapped), typeof(int)));
+ }
+ return exp;
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ if (Type == ActionType.Radio) {
+ CodeExpression groupExp = GroupManager.GenerateGroupExpression (ctx, this);
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Group"),
+ groupExp)
+ );
+ }
+ else if (type == ActionType.Toggle) {
+ if (Active) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Active"),
+ new CodePrimitiveExpression (true))
+ );
+ }
+ if (DrawAsRadio) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "DrawAsRadio"),
+ new CodePrimitiveExpression (true))
+ );
+ }
+ }
+ base.GenerateBuildCode (ctx, var);
+ }
+
+ internal void SetActionGroup (ActionGroup g)
+ {
+ group = g;
+ }
+
+ string GetIdentifier (string name)
+ {
+ StringBuilder sb = new StringBuilder ();
+
+ bool wstart = false;
+ foreach (char c in name) {
+ if (c == '_' || (int)c > 127) // No underline, no unicode
+ continue;
+ if (c == '-' || c == ' ' || !char.IsLetterOrDigit (c)) {
+ wstart = true;
+ continue;
+ }
+ if (wstart) {
+ sb.Append (char.ToUpper (c));
+ wstart = false;
+ } else
+ sb.Append (c);
+ }
+ return sb.ToString () + "Action";
+ }
+
+ internal override UndoManager GetUndoManagerInternal ()
+ {
+ if (group != null)
+ return group.GetUndoManagerInternal ();
+ else
+ return base.GetUndoManagerInternal ();
+ }
+
+ DiffGenerator GetDiffGenerator ()
+ {
+ DiffGenerator gen = new DiffGenerator ();
+ gen.CurrentStatusAdaptor = new ActionDiffAdaptor (Project);
+ gen.NewStatusAdaptor = new XmlDiffAdaptor ();
+ return gen;
+ }
+
+ public override object GetUndoDiff ()
+ {
+ XmlElement oldElem = UndoManager.GetObjectStatus (this);
+ UndoWriter writer = new UndoWriter (oldElem.OwnerDocument, UndoManager);
+ XmlElement newElem = Write (writer);
+ ObjectDiff actionsDiff = GetDiffGenerator().GetDiff (this, oldElem);
+ UndoManager.UpdateObjectStatus (this, newElem);
+ return actionsDiff;
+ }
+
+ public override object ApplyUndoRedoDiff (object diff)
+ {
+ ObjectDiff actionsDiff = (ObjectDiff) diff;
+
+ XmlElement status = UndoManager.GetObjectStatus (this);
+
+ DiffGenerator differ = GetDiffGenerator();
+ differ.ApplyDiff (this, actionsDiff);
+ actionsDiff = differ.GetDiff (this, status);
+
+ UndoWriter writer = new UndoWriter (status.OwnerDocument, UndoManager);
+ XmlElement newElem = Write (writer);
+ UndoManager.UpdateObjectStatus (this, newElem);
+
+ return actionsDiff;
+ }
+ }
+
+ [Serializable]
+ public class ActionCollection: CollectionBase
+ {
+ [NonSerialized]
+ ActionGroup group;
+
+ public ActionCollection ()
+ {
+ }
+
+ internal ActionCollection (ActionGroup group)
+ {
+ this.group = group;
+ }
+
+ public void Add (Action action)
+ {
+ List.Add (action);
+ }
+
+ public void Insert (int i, Action action)
+ {
+ List.Insert (i, action);
+ }
+
+ public Action this [int n] {
+ get { return (Action) List [n]; }
+ }
+
+ public void Remove (Action action)
+ {
+ List.Remove (action);
+ }
+
+ public bool Contains (Action action)
+ {
+ return List.Contains (action);
+ }
+
+ public void CopyTo (Action[] array, int index)
+ {
+ List.CopyTo (array, index);
+ }
+
+ protected override void OnInsertComplete (int index, object val)
+ {
+ if (group != null)
+ group.NotifyActionAdded ((Action) val);
+ }
+
+ protected override void OnRemoveComplete (int index, object val)
+ {
+ if (group != null)
+ group.NotifyActionRemoved ((Action)val);
+ }
+
+ protected override void OnSetComplete (int index, object oldv, object newv)
+ {
+ if (group != null) {
+ group.NotifyActionRemoved ((Action) oldv);
+ group.NotifyActionAdded ((Action) newv);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionGroup.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionGroup.cs
new file mode 100644
index 0000000000..1e3c7dbf1b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionGroup.cs
@@ -0,0 +1,425 @@
+
+using System;
+using System.CodeDom;
+using System.Xml;
+using System.Collections;
+using Stetic.Undo;
+
+namespace Stetic.Wrapper
+{
+ public sealed class ActionGroup: ObjectWrapper
+ {
+ string name;
+ ActionCollection actions;
+ ObjectWrapper owner;
+ bool generatePublic = true;
+
+ public event ActionEventHandler ActionAdded;
+ public event ActionEventHandler ActionRemoved;
+ public event ActionEventHandler ActionChanged;
+
+ public ActionGroup ()
+ {
+ actions = new ActionCollection (this);
+ }
+
+ public ActionGroup (string name): this ()
+ {
+ this.name = name;
+ }
+
+ public override void Dispose ()
+ {
+ foreach (Action a in actions)
+ a.Dispose ();
+ base.Dispose ();
+ }
+
+ public ActionCollection Actions {
+ get { return actions; }
+ }
+
+ public override string Name {
+ get { return name; }
+ set {
+ name = value;
+ NotifyChanged ();
+ }
+ }
+
+ public bool GeneratePublic {
+ get { return generatePublic; }
+ set { generatePublic = value; }
+ }
+
+ public Action GetAction (string name)
+ {
+ foreach (Action ac in actions)
+ if (ac.Name == name)
+ return ac;
+ return null;
+ }
+
+ internal string GetValidName (Action reqAction, string name)
+ {
+ int max = 0;
+ bool found = false;
+ foreach (Action ac in Actions) {
+ if (ac == reqAction)
+ continue;
+
+ string bname;
+ int index;
+ WidgetUtils.ParseWidgetName (ac.Name, out bname, out index);
+
+ if (name == ac.Name)
+ found = true;
+ if (name == bname && index > max)
+ max = index;
+ }
+ if (found)
+ return name + (max+1);
+ else
+ return name;
+ }
+
+ public override XmlElement Write (ObjectWriter writer)
+ {
+ XmlElement group = writer.XmlDocument.CreateElement ("action-group");
+ group.SetAttribute ("name", name);
+ if (writer.CreateUndoInfo)
+ group.SetAttribute ("undoId", UndoId);
+ foreach (Action ac in actions) {
+ if (ac.Name.Length > 0)
+ group.AppendChild (writer.WriteObject (ac));
+ }
+ return group;
+ }
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ name = elem.GetAttribute ("name");
+ string uid = elem.GetAttribute ("undoId");
+ if (uid.Length > 0)
+ UndoId = uid;
+ foreach (XmlElement child in elem.SelectNodes ("action")) {
+ Action ac = new Action ();
+ ac.Read (reader, child);
+ actions.Add (ac);
+ }
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (
+ typeof(Gtk.ActionGroup).ToGlobalTypeRef (),
+ new CodePrimitiveExpression (Name)
+ );
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ foreach (Action action in Actions) {
+ // Create the action
+ CodeExpression acVarExp = ctx.GenerateInstanceExpression (action, action.GenerateObjectCreation (ctx));
+ ctx.GenerateBuildCode (action, acVarExp);
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ var,
+ "Add",
+ acVarExp,
+ new CodePrimitiveExpression (action.Accelerator)
+ )
+ );
+ }
+ }
+
+ internal void SetOwner (ObjectWrapper owner)
+ {
+ this.owner = owner;
+ }
+
+ internal override UndoManager GetUndoManagerInternal ()
+ {
+ if (owner != null)
+ return owner.UndoManager;
+ else
+ return base.GetUndoManagerInternal ();
+ }
+
+ public override ObjectWrapper FindObjectByUndoId (string id)
+ {
+ ObjectWrapper ow = base.FindObjectByUndoId (id);
+ if (ow != null) return ow;
+
+ foreach (Action ac in Actions) {
+ ow = ac.FindObjectByUndoId (id);
+ if (ow != null)
+ return ow;
+ }
+ return null;
+ }
+
+ DiffGenerator GetDiffGenerator ()
+ {
+ DiffGenerator gen = new DiffGenerator ();
+ gen.CurrentStatusAdaptor = new ActionDiffAdaptor (Project);
+ XmlDiffAdaptor xad = new XmlDiffAdaptor ();
+ xad.ChildElementName = "action";
+ gen.NewStatusAdaptor = xad;
+ return gen;
+ }
+
+ public override object GetUndoDiff ()
+ {
+ XmlElement oldElem = UndoManager.GetObjectStatus (this);
+ UndoWriter writer = new UndoWriter (oldElem.OwnerDocument, UndoManager);
+
+ XmlElement newElem = Write (writer);
+ ObjectDiff actionsDiff = GetDiffGenerator().GetDiff (this, oldElem);
+ UndoManager.UpdateObjectStatus (this, newElem);
+ return actionsDiff;
+ }
+
+ public override object ApplyUndoRedoDiff (object diff)
+ {
+ ObjectDiff actionsDiff = (ObjectDiff) diff;
+
+ XmlElement status = UndoManager.GetObjectStatus (this);
+
+ DiffGenerator differ = GetDiffGenerator();
+ differ.ApplyDiff (this, actionsDiff);
+ actionsDiff = differ.GetDiff (this, status);
+
+ UndoWriter writer = new UndoWriter (status.OwnerDocument, UndoManager);
+ XmlElement newElem = Write (writer);
+ UndoManager.UpdateObjectStatus (this, newElem);
+
+ return actionsDiff;
+ }
+
+ internal void NotifyActionAdded (Action ac)
+ {
+ ac.SetActionGroup (this);
+ ac.ObjectChanged += OnActionChanged;
+ ac.SignalAdded += OnSignalAdded;
+ ac.SignalRemoved += OnSignalRemoved;
+ ac.SignalChanged += OnSignalChanged;
+
+ ac.UpdateNameIndex ();
+
+ NotifyChanged ();
+
+ if (ActionAdded != null)
+ ActionAdded (this, new ActionEventArgs (ac));
+ }
+
+ internal void NotifyActionRemoved (Action ac)
+ {
+ ac.SetActionGroup (null);
+ ac.ObjectChanged -= OnActionChanged;
+ ac.SignalAdded -= OnSignalAdded;
+ ac.SignalRemoved -= OnSignalRemoved;
+ ac.SignalChanged -= OnSignalChanged;
+
+ NotifyChanged ();
+
+ if (ActionRemoved != null)
+ ActionRemoved (this, new ActionEventArgs (ac));
+ }
+
+ void OnActionChanged (object s, ObjectWrapperEventArgs args)
+ {
+ NotifyChanged ();
+ if (ActionChanged != null)
+ ActionChanged (this, new ActionEventArgs ((Action) args.Wrapper));
+ }
+
+ void OnSignalAdded (object s, SignalEventArgs args)
+ {
+ OnSignalAdded (args);
+ }
+
+ void OnSignalRemoved (object s, SignalEventArgs args)
+ {
+ OnSignalRemoved (args);
+ }
+
+ void OnSignalChanged (object s, SignalChangedEventArgs args)
+ {
+ OnSignalChanged (args);
+ }
+ }
+
+ public class ActionGroupCollection: CollectionBase
+ {
+ ActionGroup[] toClear;
+ ObjectWrapper owner;
+
+ internal void SetOwner (ObjectWrapper owner)
+ {
+ this.owner = owner;
+ }
+
+ public void Add (ActionGroup group)
+ {
+ List.Add (group);
+ }
+
+ public void Insert (int n, ActionGroup group)
+ {
+ List.Insert (n, group);
+ }
+
+ public ActionGroup this [int n] {
+ get { return (ActionGroup) List [n]; }
+ }
+
+ public ActionGroup this [string name] {
+ get {
+ foreach (ActionGroup grp in List)
+ if (grp.Name == name)
+ return grp;
+ return null;
+ }
+ }
+
+ internal ObjectWrapper FindObjectByUndoId (string id)
+ {
+ foreach (ActionGroup ag in List) {
+ ObjectWrapper ow = ag.FindObjectByUndoId (id);
+ if (ow != null)
+ return ow;
+ }
+ return null;
+ }
+
+ DiffGenerator GetDiffGenerator (IProject prj)
+ {
+ DiffGenerator gen = new DiffGenerator ();
+ gen.CurrentStatusAdaptor = new ActionDiffAdaptor (prj);
+ XmlDiffAdaptor xad = new XmlDiffAdaptor ();
+ xad.ChildElementName = "action-group";
+ xad.ProcessProperties = false;
+ xad.ChildAdaptor = new XmlDiffAdaptor ();
+ xad.ChildAdaptor.ChildElementName = "action";
+ gen.NewStatusAdaptor = xad;
+ return gen;
+ }
+
+ internal ObjectDiff GetDiff (IProject prj, XmlElement elem)
+ {
+ return GetDiffGenerator (prj).GetDiff (this, elem);
+ }
+
+ internal void ApplyDiff (IProject prj, ObjectDiff diff)
+ {
+ GetDiffGenerator (prj).ApplyDiff (this, diff);
+ }
+
+ public int IndexOf (ActionGroup group)
+ {
+ return List.IndexOf (group);
+ }
+
+ public void Remove (ActionGroup group)
+ {
+ List.Remove (group);
+ }
+
+ protected override void OnInsertComplete (int index, object val)
+ {
+ NotifyGroupAdded ((ActionGroup) val);
+ }
+
+ protected override void OnRemoveComplete (int index, object val)
+ {
+ NotifyGroupRemoved ((ActionGroup)val);
+ }
+
+ protected override void OnSetComplete (int index, object oldv, object newv)
+ {
+ NotifyGroupRemoved ((ActionGroup) oldv);
+ NotifyGroupAdded ((ActionGroup) newv);
+ }
+
+ protected override void OnClear ()
+ {
+ toClear = new ActionGroup [Count];
+ List.CopyTo (toClear, 0);
+ }
+
+ protected override void OnClearComplete ()
+ {
+ foreach (ActionGroup a in toClear)
+ NotifyGroupRemoved (a);
+ toClear = null;
+ }
+
+ void NotifyGroupAdded (ActionGroup grp)
+ {
+ grp.SetOwner (owner);
+ grp.ObjectChanged += OnGroupChanged;
+ if (ActionGroupAdded != null)
+ ActionGroupAdded (this, new ActionGroupEventArgs (grp));
+ }
+
+ void NotifyGroupRemoved (ActionGroup grp)
+ {
+ grp.SetOwner (null);
+ grp.ObjectChanged -= OnGroupChanged;
+ if (ActionGroupRemoved != null)
+ ActionGroupRemoved (this, new ActionGroupEventArgs (grp));
+ }
+
+ void OnGroupChanged (object s, ObjectWrapperEventArgs a)
+ {
+ if (ActionGroupChanged != null)
+ ActionGroupChanged (this, new ActionGroupEventArgs ((ActionGroup)s));
+ }
+
+ public ActionGroup[] ToArray ()
+ {
+ ActionGroup[] groups = new ActionGroup [Count];
+ List.CopyTo (groups, 0);
+ return groups;
+ }
+
+ public event ActionGroupEventHandler ActionGroupAdded;
+ public event ActionGroupEventHandler ActionGroupRemoved;
+ public event ActionGroupEventHandler ActionGroupChanged;
+ }
+
+
+ public delegate void ActionEventHandler (object sender, ActionEventArgs args);
+
+ public class ActionEventArgs: EventArgs
+ {
+ readonly Action action;
+
+ public ActionEventArgs (Action ac)
+ {
+ action = ac;
+ }
+
+ public Action Action {
+ get { return action; }
+ }
+ }
+
+ public delegate void ActionGroupEventHandler (object sender, ActionGroupEventArgs args);
+
+ public class ActionGroupEventArgs: EventArgs
+ {
+ readonly ActionGroup action;
+
+ public ActionGroupEventArgs (ActionGroup ac)
+ {
+ action = ac;
+ }
+
+ public ActionGroup ActionGroup {
+ get { return action; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionToolbarWrapper.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionToolbarWrapper.cs
new file mode 100644
index 0000000000..1b973b8660
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionToolbarWrapper.cs
@@ -0,0 +1,294 @@
+
+using System;
+using System.CodeDom;
+using System.Xml;
+using System.Collections;
+using Stetic.Editor;
+
+namespace Stetic.Wrapper
+{
+ public class ActionToolbarWrapper: Container
+ {
+ ActionTree actionTree;
+ XmlElement toolbarInfo;
+ ToolbarStyle toolbarStyle;
+ bool treeChanged;
+ static Gtk.ToolbarStyle defaultStyle;
+ static bool gotDefault;
+
+ public enum ToolbarStyle {
+ Icons,
+ Text,
+ Both,
+ BothHoriz,
+ Default
+ }
+
+ public ActionToolbarWrapper()
+ {
+ }
+
+ public override void Dispose ()
+ {
+ DisposeTree ();
+ base.Dispose ();
+ }
+
+ public static Gtk.Toolbar CreateInstance ()
+ {
+ ActionToolbar t = new ActionToolbar ();
+ return t;
+ }
+
+ ActionToolbar toolbar {
+ get { return (ActionToolbar) Wrapped; }
+ }
+
+ protected override bool AllowPlaceholders {
+ get { return false; }
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ CreateTree ();
+ toolbar.FillMenu (actionTree);
+ }
+
+ public override bool HExpandable {
+ get {
+ return toolbar.Orientation == Gtk.Orientation.Horizontal;
+ }
+ }
+
+ public override bool VExpandable {
+ get {
+ return toolbar.Orientation == Gtk.Orientation.Vertical;
+ }
+ }
+
+ public Gtk.Orientation Orientation {
+ get {
+ return toolbar.Orientation;
+ }
+ set {
+ toolbar.Orientation = value;
+ EmitContentsChanged ();
+ }
+ }
+
+ public Gtk.IconSize IconSize {
+ get { return toolbar.IconSize; }
+ set { toolbar.IconSize = value; EmitNotify ("IconSize"); }
+ }
+
+ public ToolbarStyle ButtonStyle {
+ get { return toolbarStyle; }
+ set {
+ toolbarStyle = value;
+ if (value == ToolbarStyle.Default) {
+ if (!gotDefault) {
+ // Is there a better way of getting the default?
+ Gtk.Window d = new Gtk.Window ("");
+ Gtk.Toolbar t = new Gtk.Toolbar ();
+ d.Add (t);
+ defaultStyle = t.ToolbarStyle;
+ d.Destroy ();
+ gotDefault = true;
+ }
+ toolbar.ToolbarStyle = defaultStyle;
+ } else {
+ toolbar.ToolbarStyle = (Gtk.ToolbarStyle) ((int)value);
+ }
+ EmitNotify ("ButtonStyle");
+ }
+ }
+
+ internal protected override void OnSelected ()
+ {
+ Loading = true;
+ toolbar.ShowInsertPlaceholder = true;
+ Loading = false;
+ }
+
+ internal protected override void OnUnselected ()
+ {
+ base.OnUnselected ();
+ Loading = true;
+ toolbar.ShowInsertPlaceholder = false;
+ toolbar.Unselect ();
+ Loading = false;
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ if (writer.Format == FileFormat.Native) {
+ // The style is already stored in ButtonStyle
+ GladeUtils.ExtractProperty (elem, "ToolbarStyle", "");
+ if (toolbarInfo != null)
+ elem.AppendChild (writer.XmlDocument.ImportNode (toolbarInfo, true));
+ else
+ elem.AppendChild (actionTree.Write (writer.XmlDocument, writer.Format));
+ }
+ return elem;
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ base.ReadProperties (reader, elem);
+ toolbarInfo = elem ["node"];
+ }
+
+ protected override void OnNameChanged (WidgetNameChangedArgs args)
+ {
+ base.OnNameChanged (args);
+ if (actionTree != null)
+ actionTree.Name = Name;
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ BuildTree ();
+ actionTree.Type = Gtk.UIManagerItemType.Toolbar;
+ actionTree.Name = Name;
+
+ CodeExpression exp = GenerateUiManagerElement (ctx, actionTree);
+ if (exp != null)
+ return new CodeCastExpression (typeof(Gtk.Toolbar).ToGlobalTypeRef (), exp);
+ else
+ return base.GenerateObjectCreation (ctx);
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (toolbarStyle == ToolbarStyle.Default && prop.Name == "ToolbarStyle")
+ return;
+ else
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+
+ internal protected override void OnDesignerAttach (IDesignArea designer)
+ {
+ base.OnDesignerAttach (designer);
+ BuildTree ();
+
+ Loading = true;
+ toolbar.FillMenu (actionTree);
+ Loading = false;
+
+ if (LocalActionGroups.Count == 0)
+ LocalActionGroups.Add (new ActionGroup ("Default"));
+ }
+
+ protected override void EmitNotify (string propertyName)
+ {
+ base.EmitNotify (propertyName);
+ toolbar.FillMenu (actionTree);
+ }
+
+ public override object GetUndoDiff ()
+ {
+ XmlElement oldElem = treeChanged ? UndoManager.GetObjectStatus (this) ["node"] : null;
+ if (oldElem != null)
+ oldElem = (XmlElement) oldElem.CloneNode (true);
+
+ treeChanged = false;
+ object baseDiff = base.GetUndoDiff ();
+
+ if (oldElem != null) {
+ XmlElement newElem = UndoManager.GetObjectStatus (this) ["node"];
+ if (newElem != null && oldElem.OuterXml == newElem.OuterXml)
+ oldElem = null;
+ }
+
+ if (baseDiff == null && oldElem == null)
+ return null;
+ else {
+ object stat = toolbar.SaveStatus ();
+ return new object[] { baseDiff, oldElem, stat };
+ }
+ }
+
+ public override object ApplyUndoRedoDiff (object diff)
+ {
+ object[] data = (object[]) diff;
+ object retBaseDiff;
+ XmlElement oldNode = null;
+
+ if (actionTree != null) {
+ XmlElement status = UndoManager.GetObjectStatus (this);
+ oldNode = status ["node"];
+ if (oldNode != null)
+ oldNode = (XmlElement) oldNode.CloneNode (true);
+ }
+ object oldStat = toolbar.SaveStatus ();
+
+ if (data [0] != null)
+ retBaseDiff = base.ApplyUndoRedoDiff (data [0]);
+ else
+ retBaseDiff = null;
+
+ XmlElement xdiff = (XmlElement) data [1];
+
+ if (xdiff != null) {
+ XmlElement status = UndoManager.GetObjectStatus (this);
+ XmlElement prevNode = status ["node"];
+ if (prevNode != null)
+ status.RemoveChild (prevNode);
+ status.AppendChild (xdiff);
+
+ if (actionTree != null) {
+ Loading = true;
+ DisposeTree ();
+ CreateTree ();
+ actionTree.Read (this, xdiff);
+ toolbar.FillMenu (actionTree);
+ Loading = false;
+ }
+ }
+
+ // Restore the status after all menu structure has been properly built
+ GLib.Timeout.Add (50, delegate {
+ toolbar.RestoreStatus (data[2]);
+ return false;
+ });
+
+ return new object [] { retBaseDiff, oldNode, oldStat };
+ }
+
+
+ void BuildTree ()
+ {
+ if (toolbarInfo != null) {
+ DisposeTree ();
+ CreateTree ();
+ actionTree.Read (this, toolbarInfo);
+ toolbarInfo = null;
+ }
+ }
+
+ void CreateTree ()
+ {
+ actionTree = new ActionTree ();
+ actionTree.Name = Name;
+ actionTree.Type = Gtk.UIManagerItemType.Toolbar;
+ actionTree.Changed += OnTreeChanged;
+ }
+
+ void DisposeTree ()
+ {
+ if (actionTree != null) {
+ actionTree.Dispose ();
+ actionTree.Changed -= OnTreeChanged;
+ actionTree = null;
+ }
+ }
+
+ void OnTreeChanged (object s, EventArgs a)
+ {
+ treeChanged = true;
+ NotifyChanged ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionTree.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionTree.cs
new file mode 100644
index 0000000000..82eae3e23d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ActionTree.cs
@@ -0,0 +1,351 @@
+
+using System;
+using System.Text;
+using System.Xml;
+using System.CodeDom;
+using System.Collections;
+
+namespace Stetic.Wrapper
+{
+
+ public class ActionTree: ActionTreeNode
+ {
+ public event EventHandler Changed;
+
+ public ActionTree()
+ {
+ }
+
+ public void GenerateBuildCode (GeneratorContext ctx, CodeFieldReferenceExpression uiManager)
+ {
+ StringBuilder sb = new StringBuilder ();
+ sb.Append ("<ui>");
+ GenerateUiString (sb);
+ sb.Append ("</ui>");
+
+ CodeMethodInvokeExpression exp = new CodeMethodInvokeExpression (
+ uiManager,
+ "AddUiFromString",
+ new CodePrimitiveExpression (sb.ToString ())
+ );
+ ctx.Statements.Add (exp);
+ }
+
+ public ActionGroup[] GetRequiredGroups ()
+ {
+ ArrayList list = new ArrayList ();
+ GetRequiredGroups (list);
+ return (ActionGroup[]) list.ToArray (typeof(ActionGroup));
+ }
+
+ internal override void NotifyChanged ()
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+ }
+
+ public class ActionTreeNode: IDisposable
+ {
+ Gtk.UIManagerItemType type;
+ string name;
+ Action action;
+ ActionTreeNodeCollection children;
+ ActionTreeNode parentNode;
+ bool loading;
+ string lastActionName;
+
+ public ActionTreeNode ()
+ {
+ }
+
+ public ActionTreeNode Clone ()
+ {
+ return new ActionTreeNode (type, name, action);
+ }
+
+ public ActionTreeNode (Gtk.UIManagerItemType type, string name, Action action)
+ {
+ this.type = type;
+ this.name = name;
+ this.action = action;
+ if (this.action != null) {
+ lastActionName = this.action.Name;
+ this.action.Deleted += OnActionDeleted;
+ this.action.ObjectChanged += OnActionChanged;
+ }
+ }
+
+ public virtual void Dispose ()
+ {
+ if (action != null) {
+ action.Deleted -= OnActionDeleted;
+ action.ObjectChanged -= OnActionChanged;
+ }
+ if (children != null)
+ foreach (ActionTreeNode node in children)
+ node.Dispose ();
+ }
+
+ void OnActionDeleted (object s, EventArgs args)
+ {
+ if (parentNode != null)
+ parentNode.Children.Remove (this);
+ }
+
+ void OnActionChanged (object s, ObjectWrapperEventArgs args)
+ {
+ // If the name of the action changes, consider it a change in
+ // the node, since the generated xml will be different
+
+ Action ac = (Action) args.Wrapper;
+ if (ac.Name != lastActionName) {
+ lastActionName = ac.Name;
+ NotifyChanged ();
+ }
+ }
+
+ internal virtual void NotifyChanged ()
+ {
+ if (parentNode != null)
+ parentNode.NotifyChanged ();
+ }
+
+ public XmlElement Write (XmlDocument doc, FileFormat format)
+ {
+ XmlElement elem = doc.CreateElement ("node");
+ if (name != null && name.Length > 0)
+ elem.SetAttribute ("name", name);
+ elem.SetAttribute ("type", type.ToString ());
+ if (action != null)
+ elem.SetAttribute ("action", action.Name);
+
+ if (children != null) {
+ foreach (ActionTreeNode child in children) {
+ if (child.Action != null && child.Action.Name.Length == 0)
+ continue;
+ elem.AppendChild (child.Write (doc, format));
+ }
+ }
+ return elem;
+ }
+
+ public void Read (Wrapper.Widget baseWidget, XmlElement elem)
+ {
+ name = elem.GetAttribute ("name");
+ if (elem.HasAttribute ("type"))
+ type = (Gtk.UIManagerItemType) Enum.Parse (typeof(Gtk.UIManagerItemType), elem.GetAttribute ("type"));
+
+ // The name of an action may be empty in some situations (e.g. when adding a new action but before entering the name)
+ XmlAttribute actionAt = elem.Attributes ["action"];
+ if (actionAt != null) {
+ string aname = actionAt.Value;
+ foreach (ActionGroup grp in baseWidget.LocalActionGroups) {
+ action = grp.GetAction (aname);
+ if (action != null)
+ break;
+ }
+ if (action == null) {
+ foreach (ActionGroup group in baseWidget.Project.ActionGroups) {
+ action = group.GetAction (aname);
+ if (action != null)
+ break;
+ }
+ }
+ if (action != null) {
+ lastActionName = action.Name;
+ action.Deleted += OnActionDeleted;
+ action.ObjectChanged += OnActionChanged;
+ }
+ }
+
+ try {
+ loading = true;
+ foreach (XmlElement child in elem.SelectNodes ("node")) {
+ ActionTreeNode node = new ActionTreeNode ();
+ node.Read (baseWidget, child);
+ Children.Add (node);
+ }
+ } finally {
+ loading = false;
+ }
+ }
+
+ public virtual void GenerateBuildCode (GeneratorContext ctx, CodeVariableReferenceExpression uiManager, string path)
+ {
+ CodeMethodInvokeExpression exp = new CodeMethodInvokeExpression (
+ uiManager,
+ "AddUi",
+ new CodePrimitiveExpression (0),
+ new CodePrimitiveExpression (path),
+ new CodePrimitiveExpression (name),
+ new CodePrimitiveExpression (action != null ? action.Name : null),
+ new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (typeof(Gtk.UIManagerItemType), CodeTypeReferenceOptions.GlobalReference)),
+ type.ToString()
+ ),
+ new CodePrimitiveExpression (false)
+ );
+ ctx.Statements.Add (exp);
+
+ string localName = (name != null && name.Length > 0 ? name : (action != null ? action.Name : null));
+ if (localName != null) {
+ if (path != "/")
+ path = path + "/" + localName;
+ else
+ path += localName;
+ }
+
+ foreach (ActionTreeNode node in Children)
+ node.GenerateBuildCode (ctx, uiManager, path);
+ }
+
+ public void GenerateUiString (StringBuilder sb)
+ {
+ sb.Append ('<').Append (type.ToString().ToLower());
+
+ string name = this.name;
+ if (String.IsNullOrEmpty (name) && action != null)
+ name = action.Name;
+
+ if (!String.IsNullOrEmpty (name))
+ sb.Append (' ').Append ("name='").Append (name).Append ("'");
+ if (action != null)
+ sb.Append (' ').Append ("action='").Append (action.Name).Append ("'");
+
+ if (Children.Count > 0) {
+ sb.Append ('>');
+ foreach (ActionTreeNode node in Children)
+ node.GenerateUiString (sb);
+ sb.Append ("</").Append (type.ToString().ToLower()).Append ('>');
+ } else
+ sb.Append ("/>");
+ }
+
+ protected void GetRequiredGroups (ArrayList list)
+ {
+ if (action != null && action.ActionGroup != null && !list.Contains (action.ActionGroup))
+ list.Add (action.ActionGroup);
+ foreach (ActionTreeNode node in Children)
+ node.GetRequiredGroups (list);
+ }
+
+ public Gtk.UIManagerItemType Type {
+ get { return type; }
+ set { type = value; NotifyChanged (); }
+ }
+
+ public string Name {
+ get { return name; }
+ set { name = value; NotifyChanged (); }
+ }
+
+ public Action Action {
+ get { return action; }
+ }
+
+ public ActionTreeNode ParentNode {
+ get { return parentNode; }
+ }
+
+ public ActionTreeNodeCollection Children {
+ get {
+ if (children == null)
+ children = new ActionTreeNodeCollection (this);
+ return children;
+ }
+ }
+
+ internal void NotifyChildAdded (ActionTreeNode node)
+ {
+ node.parentNode = this;
+ if (!loading) {
+ NotifyChanged ();
+ if (ChildNodeAdded != null)
+ ChildNodeAdded (this, new ActionTreeNodeArgs (node));
+ }
+ }
+
+ internal void NotifyChildRemoved (ActionTreeNode node)
+ {
+ node.parentNode = null;
+ if (!loading) {
+ NotifyChanged ();
+ if (ChildNodeRemoved != null)
+ ChildNodeRemoved (this, new ActionTreeNodeArgs (node));
+ }
+ }
+
+ public event ActionTreeNodeHanlder ChildNodeAdded;
+ public event ActionTreeNodeHanlder ChildNodeRemoved;
+ }
+
+ public class ActionTreeNodeCollection: CollectionBase
+ {
+ ActionTreeNode parent;
+
+ public ActionTreeNodeCollection (ActionTreeNode parent)
+ {
+ this.parent = parent;
+ }
+
+ public void Add (ActionTreeNode node)
+ {
+ List.Add (node);
+ }
+
+ public void Insert (int index, ActionTreeNode node)
+ {
+ List.Insert (index, node);
+ }
+
+ public int IndexOf (ActionTreeNode node)
+ {
+ return List.IndexOf (node);
+ }
+
+ public void Remove (ActionTreeNode node)
+ {
+ if (List.Contains (node))
+ List.Remove (node);
+ }
+
+ public ActionTreeNode this [int n] {
+ get { return (ActionTreeNode) List [n]; }
+ set { List [n] = value; }
+ }
+
+ protected override void OnInsertComplete (int index, object val)
+ {
+ parent.NotifyChildAdded ((ActionTreeNode) val);
+ }
+
+ protected override void OnRemoveComplete (int index, object val)
+ {
+ parent.NotifyChildRemoved ((ActionTreeNode)val);
+ }
+
+ protected override void OnSetComplete (int index, object oldv, object newv)
+ {
+ parent.NotifyChildRemoved ((ActionTreeNode) oldv);
+ parent.NotifyChildAdded ((ActionTreeNode) newv);
+ }
+ }
+
+ public delegate void ActionTreeNodeHanlder (object ob, ActionTreeNodeArgs args);
+
+ public class ActionTreeNodeArgs: EventArgs
+ {
+ readonly ActionTreeNode node;
+
+ public ActionTreeNodeArgs (ActionTreeNode node)
+ {
+ this.node = node;
+ }
+
+ public ActionTreeNode Node {
+ get { return node; }
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Bin.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Bin.cs
new file mode 100644
index 0000000000..4fd3ab2bee
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Bin.cs
@@ -0,0 +1,388 @@
+using System;
+using System.CodeDom;
+using System.Reflection;
+
+namespace Stetic.Wrapper
+{
+ public class Bin: Container
+ {
+ public static Gtk.Bin CreateInstance (ClassDescriptor klass)
+ {
+ if (klass.Name == "Gtk.Bin")
+ return new CustomWidget ();
+ else
+ return null;
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ if (ClassDescriptor.WrappedTypeName == "Gtk.Bin") {
+
+ // Gtk.Bin needs a helper class which handles child allocation.
+ // This class needs to be generated since Stetic won't be linked with
+ // the app.
+
+ bool found = false;
+ foreach (CodeTypeDeclaration dec in ctx.GlobalCodeNamespace.Types) {
+ if (dec.Name == "BinContainer") {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ GenerateHelperClass (ctx);
+
+ CodeMethodInvokeExpression attachExp = new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (ctx.GlobalCodeNamespace.Name + ".BinContainer", CodeTypeReferenceOptions.GlobalReference)),
+ "Attach",
+ var
+ );
+
+ // If the Bin has its own action groups, we need to register
+ // the resulting UIManager in the BinContainer, but it needs to be done
+ // after generating it. Right now, we only keep a reference to
+ // the BinContainer.
+
+ string binContainerVar = null;
+
+ if (IsTopLevel && LocalActionGroups.Count > 0) {
+ binContainerVar = ctx.NewId ();
+ ctx.Statements.Add (
+ new CodeVariableDeclarationStatement (
+ (ctx.GlobalCodeNamespace.Name + ".BinContainer"),
+ binContainerVar,
+ attachExp
+ )
+ );
+ } else {
+ ctx.Statements.Add (attachExp);
+ }
+
+ base.GenerateBuildCode (ctx, var);
+
+ // Register the UIManager, if the Bin has one
+
+ if (binContainerVar != null && UIManagerName != null) {
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ new CodeVariableReferenceExpression (binContainerVar),
+ "SetUiManager",
+ new CodeVariableReferenceExpression (UIManagerName)
+ )
+ );
+ }
+
+ } else
+ base.GenerateBuildCode (ctx, var);
+ }
+
+ void GenerateHelperClass (GeneratorContext ctx)
+ {
+ CodeTypeDeclaration type = new CodeTypeDeclaration ("BinContainer");
+ type.Attributes = MemberAttributes.Private;
+ type.TypeAttributes = TypeAttributes.NestedAssembly;
+ ctx.GlobalCodeNamespace.Types.Add (type);
+
+ CodeMemberField field = new CodeMemberField ("Gtk.Widget", "child");
+ field.Attributes = MemberAttributes.Private;
+ type.Members.Add (field);
+
+ field = new CodeMemberField ("Gtk.UIManager", "uimanager");
+ field.Attributes = MemberAttributes.Private;
+ type.Members.Add (field);
+
+ CodeExpression child = new CodeFieldReferenceExpression (
+ new CodeThisReferenceExpression (),
+ "child"
+ );
+
+ CodeExpression uimanager = new CodeFieldReferenceExpression (
+ new CodeThisReferenceExpression (),
+ "uimanager"
+ );
+
+ // Attach method
+
+ CodeMemberMethod met = new CodeMemberMethod ();
+ type.Members.Add (met);
+ met.Name = "Attach";
+ met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+ met.ReturnType = new CodeTypeReference ("BinContainer");
+ met.Parameters.Add (new CodeParameterDeclarationExpression ("Gtk.Bin", "bin"));
+
+ CodeVariableDeclarationStatement bcDec = new CodeVariableDeclarationStatement ("BinContainer", "bc");
+ bcDec.InitExpression = new CodeObjectCreateExpression ("BinContainer");
+ met.Statements.Add (bcDec);
+ CodeVariableReferenceExpression bc = new CodeVariableReferenceExpression ("bc");
+ CodeArgumentReferenceExpression bin = new CodeArgumentReferenceExpression ("bin");
+
+ met.Statements.Add (
+ new CodeAttachEventStatement (
+ bin,
+ "SizeRequested",
+ new CodeDelegateCreateExpression (
+ new CodeTypeReference ("Gtk.SizeRequestedHandler"), bc, "OnSizeRequested"
+ )
+ )
+ );
+
+ met.Statements.Add (
+ new CodeAttachEventStatement (
+ bin,
+ "SizeAllocated",
+ new CodeDelegateCreateExpression (
+ new CodeTypeReference ("Gtk.SizeAllocatedHandler"), bc, "OnSizeAllocated"
+ )
+ )
+ );
+
+ met.Statements.Add (
+ new CodeAttachEventStatement (
+ bin,
+ "Added",
+ new CodeDelegateCreateExpression (
+ new CodeTypeReference ("Gtk.AddedHandler"), bc, "OnAdded"
+ )
+ )
+ );
+ met.Statements.Add (new CodeMethodReturnStatement (bc));
+
+ // OnSizeRequested override
+
+ met = new CodeMemberMethod ();
+ type.Members.Add (met);
+ met.Name = "OnSizeRequested";
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
+ met.Parameters.Add (new CodeParameterDeclarationExpression ("Gtk.SizeRequestedArgs", "args"));
+
+ CodeConditionStatement cond = new CodeConditionStatement ();
+ cond.Condition = new CodeBinaryOperatorExpression (
+ child,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression (null)
+ );
+ cond.TrueStatements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ new CodeArgumentReferenceExpression ("args"),
+ "Requisition"
+ ),
+ new CodeMethodInvokeExpression (
+ child,
+ "SizeRequest"
+ )
+ )
+ );
+ met.Statements.Add (cond);
+
+ // OnSizeAllocated method
+
+ met = new CodeMemberMethod ();
+ type.Members.Add (met);
+ met.Name = "OnSizeAllocated";
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
+ met.Parameters.Add (new CodeParameterDeclarationExpression ("Gtk.SizeAllocatedArgs", "args"));
+
+ cond = new CodeConditionStatement ();
+ cond.Condition = new CodeBinaryOperatorExpression (
+ child,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression (null)
+ );
+ cond.TrueStatements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ child,
+ "Allocation"
+ ),
+ new CodePropertyReferenceExpression (
+ new CodeArgumentReferenceExpression ("args"),
+ "Allocation"
+ )
+ )
+ );
+ met.Statements.Add (cond);
+
+ // OnAdded method
+
+ met = new CodeMemberMethod ();
+ type.Members.Add (met);
+ met.Name = "OnAdded";
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
+ met.Parameters.Add (new CodeParameterDeclarationExpression ("Gtk.AddedArgs", "args"));
+
+ met.Statements.Add (
+ new CodeAssignStatement (
+ child,
+ new CodePropertyReferenceExpression (
+ new CodeArgumentReferenceExpression ("args"),
+ "Widget"
+ )
+ )
+ );
+
+ // SetUiManager method
+
+ met = new CodeMemberMethod ();
+ type.Members.Add (met);
+ met.Name = "SetUiManager";
+ met.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(Gtk.UIManager), "uim"));
+
+ met.Statements.Add (
+ new CodeAssignStatement (
+ uimanager,
+ new CodeArgumentReferenceExpression ("uim")
+ )
+ );
+ met.Statements.Add (
+ new CodeAttachEventStatement (
+ child,
+ "Realized",
+ new CodeDelegateCreateExpression (
+ new CodeTypeReference ("System.EventHandler"), new CodeThisReferenceExpression(), "OnRealized"
+ )
+ )
+ );
+
+ // OnRealized method
+
+ met = new CodeMemberMethod ();
+ type.Members.Add (met);
+ met.Name = "OnRealized";
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
+ met.Parameters.Add (new CodeParameterDeclarationExpression ("System.EventArgs", "args"));
+
+ cond = new CodeConditionStatement ();
+ cond.Condition = new CodeBinaryOperatorExpression (
+ uimanager,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression (null)
+ );
+
+ cond.TrueStatements.Add (
+ new CodeVariableDeclarationStatement (
+ typeof(Gtk.Widget),
+ "w"
+ )
+ );
+
+ CodeExpression wexp = new CodeVariableReferenceExpression ("w");
+
+ cond.TrueStatements.Add (
+ new CodeAssignStatement (
+ wexp,
+ new CodePropertyReferenceExpression (
+ child,
+ "Toplevel"
+ )
+ )
+ );
+
+ CodeConditionStatement cond2 = new CodeConditionStatement ();
+ cond2.Condition = new CodeBinaryOperatorExpression (
+ new CodeBinaryOperatorExpression (
+ wexp,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression (null)
+ ),
+ CodeBinaryOperatorType.BooleanAnd,
+ new CodeMethodInvokeExpression (
+ new CodeTypeOfExpression ("Gtk.Window"),
+ "IsInstanceOfType",
+ wexp
+ )
+ );
+
+ cond2.TrueStatements.Add (
+ new CodeMethodInvokeExpression (
+ new CodeCastExpression ("Gtk.Window", wexp),
+ "AddAccelGroup",
+ new CodePropertyReferenceExpression (
+ uimanager,
+ "AccelGroup"
+ )
+ )
+ );
+ cond2.TrueStatements.Add (
+ new CodeAssignStatement (
+ uimanager,
+ new CodePrimitiveExpression (null)
+ )
+ );
+ cond.TrueStatements.Add (cond2);
+
+ met.Statements.Add (cond);
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ CustomWidget custom = obj as CustomWidget;
+ if (custom != null) {
+ RootWrapperName = custom.Name;
+ }
+ //during Wrap RootWrapperName will be set in the children widgets
+ base.Wrap (obj, initialized);
+ }
+ }
+
+/*
+ This is a model of what GenerateHelperClass generates:
+
+ class BinContainer
+ {
+ Gtk.Widget child;
+ UIManager uimanager;
+
+ public static BinContainer Attach (Gtk.Bin bin)
+ {
+ BinContainer bc = new BinContainer ();
+ bin.SizeRequested += new Gtk.SizeRequestedHandler (bc.OnSizeRequested);
+ bin.SizeAllocated += new Gtk.SizeAllocatedHandler (bc.OnSizeAllocated);
+ bin.Added += new Gtk.AddedHandler (bc.OnAdded);
+ return bin;
+ }
+
+ void OnSizeRequested (object s, Gtk.SizeRequestedArgs args)
+ {
+ if (child != null)
+ args.Requisition = child.SizeRequest ();
+ }
+
+ void OnSizeAllocated (object s, Gtk.SizeAllocatedArgs args)
+ {
+ if (child != null)
+ child.Allocation = args.Allocation;
+ }
+
+ void OnAdded (object s, Gtk.AddedArgs args)
+ {
+ child = args.Widget;
+ }
+
+ public void SetUiManager (UIManager manager)
+ {
+ uimanager = manager;
+ child.Realized += new System.EventHandler (OnRealized);
+ }
+
+ void OnRealized ()
+ {
+ if (uimanager != null) {
+ Gtk.Widget w = child.Toplevel;
+ if (w != null && w is Gtk.Window) {
+ ((Gtk.Window)w).AddAccelGroup (uimanager.AccelGroup);
+ uimanager = null;
+ }
+ }
+ }
+ }
+*/
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Box.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Box.cs
new file mode 100644
index 0000000000..8e57f4b80f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Box.cs
@@ -0,0 +1,276 @@
+using System;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Box : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized && AllowPlaceholders) {
+ Placeholder ph = CreatePlaceholder ();
+ box.PackStart (ph);
+ NotifyChildAdded (ph);
+ ph = CreatePlaceholder ();
+ box.PackStart (ph);
+ NotifyChildAdded (ph);
+ box.Spacing = 6;
+ }
+ box.SizeAllocated += box_SizeAllocated;
+ ContainerOrientation = obj is Gtk.HBox ? Gtk.Orientation.Horizontal : Gtk.Orientation.Vertical;
+ DND.ClearFaults (this);
+ }
+
+ public override void Dispose ()
+ {
+ box.SizeAllocated -= box_SizeAllocated;
+ base.Dispose ();
+ }
+
+ protected Gtk.Box box {
+ get {
+ return (Gtk.Box)Wrapped;
+ }
+ }
+
+/*
+ FIXME: why was this needed?
+ protected override bool AllowPlaceholders {
+ get {
+ return InternalChildProperty != null;
+ }
+ }
+*/
+ // DoSync() does two things: first, it makes sure that all of the
+ // PackStart widgets have Position numbers less than all of the
+ // PackEnd widgets. Second, it creates faults anywhere two widgets
+ // could be split apart. The fault IDs correspond to the Position
+ // a widget would have to be assigned to end up in that slot
+ // (negated for PackEnd slots).
+ //
+ // Position/PackType: 0S 1S 2S 4E 3E
+ // +----------------------+
+ // | AA BB CC DD EE |
+ // +----------------------+
+ // Fault Id: 0 1 2 3 -5 -4 -3
+
+ protected override void DoSync ()
+ {
+ if (!box.IsRealized)
+ return;
+
+ DND.ClearFaults (this);
+
+ Gtk.Widget[] children = box.Children;
+ if (children.Length == 0)
+ return;
+
+ Gtk.Widget[] sorted = new Gtk.Widget[children.Length];
+ int last_start = -1;
+ bool hbox = ContainerOrientation == Gtk.Orientation.Horizontal;
+
+ foreach (Gtk.Widget child in children) {
+ Gtk.Box.BoxChild bc = box[child] as Gtk.Box.BoxChild;
+ if (AutoSize[child]) {
+ bool exp = hbox ? ChildHExpandable (child) : ChildVExpandable (child);
+ if (bc.Expand != exp)
+ bc.Expand = exp;
+ if (bc.Fill != exp)
+ bc.Fill = exp;
+ }
+
+ // Make sure all of the PackStart widgets are before
+ // any PackEnd widgets in the list.
+ if (bc.PackType == Gtk.PackType.Start) {
+ if (bc.Position != ++last_start) {
+ Array.Copy (sorted, last_start, sorted, last_start + 1, bc.Position - last_start);
+ box.ReorderChild (child, last_start);
+ }
+ }
+
+ if (!(child is Placeholder))
+ sorted[bc.Position] = child;
+ }
+
+ // The orientation of the faults is the opposite of the
+ // orientation of the box
+ Gtk.Orientation orientation = hbox ? Gtk.Orientation.Vertical : Gtk.Orientation.Horizontal;
+ Gtk.SideType before = hbox ? Gtk.SideType.Left : Gtk.SideType.Top;
+ Gtk.SideType after = hbox ? Gtk.SideType.Right : Gtk.SideType.Bottom;
+
+ if (!Unselectable) {
+ // If there are no PackStart widgets, we need a fault at the leading
+ // edge. Otherwise if there's a widget at the leading edge, we need a
+ // fault before it.
+ if (last_start == -1)
+ DND.AddFault (this, 0, before, null);
+ else if (sorted[0] != null)
+ DND.AddFault (this, 0, before, sorted[0]);
+
+ // Add a fault between each pair of (non-placeholder) start widgets
+ for (int i = 1; i <= last_start; i++) {
+ if (sorted[i - 1] != null && sorted[i] != null)
+ DND.AddFault (this, i, orientation, sorted[i - 1], sorted[i]);
+ }
+
+ // If there's a non-placeholder at the end of the PackStart
+ // range, add a fault after it
+ if (last_start > -1 && sorted[last_start] != null)
+ DND.AddFault (this, last_start + 1, after, sorted[last_start]);
+
+ // Now the PackEnd widgets
+ if (last_start == sorted.Length - 1)
+ DND.AddFault (this, -(last_start + 1), after, null);
+ else if (sorted[last_start + 1] != null)
+ DND.AddFault (this, -(last_start + 1), after, sorted[last_start + 1]);
+
+ for (int i = last_start + 2; i < sorted.Length; i++) {
+ if (sorted[i - 1] != null && sorted[i] != null)
+ DND.AddFault (this, -i, orientation, sorted[i - 1], sorted[i]);
+ }
+
+ if (sorted.Length > last_start + 1 && sorted[sorted.Length - 1] != null)
+ DND.AddFault (this, -sorted.Length, before, sorted[sorted.Length - 1]);
+ }
+ }
+
+ internal void InsertBefore (Gtk.Widget context)
+ {
+ int position;
+ Gtk.PackType type;
+
+ if (context == box) {
+ position = 0;
+ type = Gtk.PackType.Start;
+ } else {
+ Gtk.Box.BoxChild bc = (Gtk.Box.BoxChild)ContextChildProps (context);
+ position = bc.Position;
+ type = bc.PackType;
+ }
+
+ Placeholder ph = CreatePlaceholder ();
+ if (type == Gtk.PackType.Start) {
+ box.PackStart (ph);
+ box.ReorderChild (ph, position);
+ } else {
+ box.PackEnd (ph);
+ box.ReorderChild (ph, position + 1);
+ }
+ NotifyChildAdded (ph);
+ }
+
+ internal void InsertAfter (Gtk.Widget context)
+ {
+ int position;
+ Gtk.PackType type;
+
+ if (context == box) {
+ position = 0;
+ type = Gtk.PackType.End;
+ } else {
+ Gtk.Box.BoxChild bc = (Gtk.Box.BoxChild)ContextChildProps (context);
+ position = bc.Position;
+ type = bc.PackType;
+ }
+
+ Placeholder ph = CreatePlaceholder ();
+ if (type == Gtk.PackType.Start) {
+ box.PackStart (ph);
+ box.ReorderChild (ph, position + 1);
+ } else {
+ box.PackEnd (ph);
+ box.ReorderChild (ph, position);
+ }
+ NotifyChildAdded (ph);
+ }
+
+ protected override void ChildContentsChanged (Container child) {
+ Gtk.Widget widget = child.Wrapped;
+
+ if (widget != null && AutoSize[widget]) {
+ Gtk.Box.BoxChild bc = box[widget] as Gtk.Box.BoxChild;
+ bool newExp = (ContainerOrientation == Gtk.Orientation.Horizontal) ? ChildHExpandable (widget) : ChildVExpandable (widget);
+ if (newExp != bc.Expand)
+ bc.Expand = newExp;
+ if (newExp != bc.Fill)
+ bc.Fill = newExp;
+ }
+ base.ChildContentsChanged (child);
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ base.ReplaceChild (oldChild, newChild);
+
+ Container container = Stetic.Wrapper.Container.Lookup (newChild);
+ if (container != null)
+ ChildContentsChanged (container);
+ }
+
+ void box_SizeAllocated (object obj, Gtk.SizeAllocatedArgs args)
+ {
+ Sync ();
+ }
+
+ public override IEnumerable GladeChildren {
+ get {
+ // Return childs using the position order.
+ // This is needed to make sure children are
+ // added in the right order to the box while loading
+ // or building the box.
+ object[] obs = new object [box.Children.Length];
+ foreach (Gtk.Widget child in box.Children) {
+ Gtk.Box.BoxChild bc = (Gtk.Box.BoxChild) box [child];
+ obs [bc.Position] = child;
+ }
+ return obs;
+ }
+ }
+
+ public override void Drop (Gtk.Widget w, object faultId)
+ {
+ AutoSize[w] = true;
+ int pos = (int)faultId;
+
+ Freeze ();
+ if (pos >= 0) {
+ box.Add (w);
+ box.ReorderChild (w, pos);
+ } else {
+ box.Add (w);
+ box.ReorderChild (w, -pos);
+ }
+ EmitContentsChanged ();
+ Thaw ();
+ }
+
+ public class BoxChild : Container.ContainerChild {
+
+ public bool BoxExpand {
+ get { return ((Gtk.Box.BoxChild)Wrapped).Expand; }
+ set {
+ AutoSize = false;
+ ((Gtk.Box.BoxChild)Wrapped).Expand = value;
+ }
+ }
+
+ public bool BoxFill {
+ get { return ((Gtk.Box.BoxChild)Wrapped).Fill; }
+ set {
+ AutoSize = false;
+ ((Gtk.Box.BoxChild)Wrapped).Fill = value;
+ }
+ }
+
+ protected override void EmitNotify (string propertyName)
+ {
+ if (propertyName == "AutoSize") {
+ base.EmitNotify ("Expand");
+ base.EmitNotify ("Fill");
+ }
+ base.EmitNotify (propertyName);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Button.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Button.cs
new file mode 100644
index 0000000000..fc78a59531
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Button.cs
@@ -0,0 +1,339 @@
+using System;
+using System.CodeDom;
+using System.Collections;
+using System.Xml;
+
+namespace Stetic.Wrapper {
+
+ public class Button : Container {
+
+ ImageInfo imageInfo;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ if (!initialized)
+ UseUnderline = true;
+
+ if (button.UseStock) {
+ type = ButtonType.StockItem;
+ StockId = button.Label;
+ } else if (!initialized) {
+ type = ButtonType.TextOnly;
+ Label = button.Name;
+ } else if (button.Child is Gtk.Label) {
+ type = ButtonType.TextOnly;
+ label = button.Label;
+ useUnderline = button.UseUnderline;
+ } else {
+ type = ButtonType.Custom;
+ FixupGladeChildren ();
+ }
+ }
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ base.Read (reader, elem);
+ if (reader.Format == FileFormat.Glade)
+ UseUnderline = true;
+ }
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ ObjectWrapper ret = null;
+ if (Type == ButtonType.Custom || reader.Format == FileFormat.Glade) {
+ if (button.Child != null)
+ button.Remove (button.Child);
+ ret = base.ReadChild (reader, child_elem);
+ FixupGladeChildren ();
+ } else if (Type == ButtonType.TextAndIcon)
+ ConstructContents ();
+ return ret;
+ }
+
+ protected override XmlElement WriteChild (ObjectWriter writer, Widget wrapper)
+ {
+ if (writer.Format == FileFormat.Glade || Type == ButtonType.Custom)
+ return base.WriteChild (writer, wrapper);
+ else
+ return null;
+ }
+
+ void FixupGladeChildren ()
+ {
+ Gtk.Alignment alignment = button.Child as Gtk.Alignment;
+ if (alignment == null)
+ return;
+ Gtk.HBox box = alignment.Child as Gtk.HBox;
+ if (box == null)
+ return;
+
+ Gtk.Widget[] children = box.Children;
+ if (children == null || children.Length != 2)
+ return;
+
+ Gtk.Image image = children[0] as Gtk.Image;
+ Gtk.Label label = children[1] as Gtk.Label;
+ if (image == null || label == null)
+ return;
+ Stetic.Wrapper.Image iwrap = Stetic.ObjectWrapper.Lookup (image) as Stetic.Wrapper.Image;
+ if (iwrap == null)
+ return;
+
+ this.label = label.LabelProp;
+ button.UseUnderline = label.UseUnderline;
+
+ imageInfo = iwrap.Pixbuf;
+ Type = ButtonType.TextAndIcon;
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ if (Type == ButtonType.StockItem)
+ GladeUtils.SetProperty (elem, "label", stockId);
+ return elem;
+ }
+
+ public override IEnumerable RealChildren {
+ get {
+ if (type == ButtonType.Custom)
+ return base.RealChildren;
+ else
+ return new Gtk.Widget[0];
+ }
+ }
+
+ public override IEnumerable GladeChildren {
+ get {
+ if (type == ButtonType.StockItem || type == ButtonType.TextOnly)
+ return new Gtk.Widget[0];
+ else
+ return base.GladeChildren;
+ }
+ }
+
+ private Gtk.Button button {
+ get {
+ return (Gtk.Button)Wrapped;
+ }
+ }
+
+ public enum ButtonType {
+ StockItem,
+ TextOnly,
+ TextAndIcon,
+ Custom
+ };
+
+ ButtonType type;
+ public ButtonType Type {
+ get {
+ return type;
+ }
+ set {
+ type = value;
+ EmitNotify ("Type");
+ switch (type) {
+ case ButtonType.StockItem:
+ button.UseStock = true;
+ StockId = stockId;
+ break;
+ case ButtonType.TextOnly:
+ labelWidget = null;
+ button.UseStock = false;
+ Label = label;
+ UseUnderline = useUnderline;
+ break;
+ case ButtonType.TextAndIcon:
+ button.UseStock = false;
+ Label = label;
+ UseUnderline = useUnderline;
+ Icon = imageInfo;
+ break;
+ case ButtonType.Custom:
+ button.UseStock = false;
+ if (button.Child != null)
+ ReplaceChild (button.Child, CreatePlaceholder (), true);
+ break;
+ }
+ }
+ }
+
+ public ImageInfo Icon {
+ get { return imageInfo; }
+ set {
+ imageInfo = value;
+ if (!Loading) {
+ ConstructContents ();
+ EmitNotify ("Image");
+ }
+ }
+ }
+
+ Gtk.Label labelWidget;
+
+ protected override void OnEndRead (FileFormat format)
+ {
+ base.OnEndRead (format);
+ if (format == FileFormat.Native && Type == ButtonType.TextAndIcon) {
+ Loading = true;
+ ConstructContents ();
+ Loading = false;
+ }
+ }
+
+ void ConstructContents ()
+ {
+ if (button.Child != null)
+ button.Remove (button.Child);
+
+ if (useUnderline) {
+ labelWidget = new Gtk.Label (label);
+ labelWidget.MnemonicWidget = button;
+ } else
+ labelWidget = Gtk.Label.New (label);
+
+ Gtk.Image imageWidget = (Gtk.Image)Registry.NewInstance ("Gtk.Image", proj);
+ Image imageWrapper = (Image)Widget.Lookup (imageWidget);
+ imageWrapper.Unselectable = true;
+ if (type != ButtonType.StockItem) {
+ imageWrapper.Pixbuf = imageInfo;
+ }
+
+ Gtk.HBox box = new Gtk.HBox (false, 2);
+ box.PackStart (imageWidget, false, false, 0);
+ box.PackEnd (labelWidget, false, false, 0);
+
+ Gtk.Alignment alignment = new Gtk.Alignment (button.Xalign, button.Yalign, 0.0f, 0.0f);
+ alignment.Add (box);
+
+ ObjectWrapper buttonWrapper = ObjectWrapper.Lookup (this);
+ Widget wrapper = (Widget)ObjectWrapper.Create (proj, labelWidget, buttonWrapper);
+ wrapper.Unselectable = true;
+ wrapper = (Widget)ObjectWrapper.Create (proj, box, buttonWrapper);
+ wrapper.Unselectable = true;
+ wrapper = (Widget)ObjectWrapper.Create (proj, alignment, buttonWrapper);
+ wrapper.Unselectable = true;
+
+ alignment.ShowAll ();
+ button.Add (alignment);
+ }
+
+ string stockId = Gtk.Stock.Ok;
+ public string StockId {
+ get {
+ return stockId;
+ }
+ set {
+ if (responseId == ResponseIdForStockId (stockId))
+ responseId = 0;
+
+ if (value != null) {
+ string sid = value;
+ if (sid.StartsWith ("stock:"))
+ sid = sid.Substring (6);
+ button.Label = stockId = sid;
+ button.UseStock = true;
+ Gtk.StockItem item = Gtk.Stock.Lookup (sid);
+ if (item.StockId == sid) {
+ label = item.Label;
+ useUnderline = true;
+ }
+ } else {
+ stockId = value;
+ }
+
+ EmitNotify ("StockId");
+
+ if (responseId == 0)
+ ResponseId = ResponseIdForStockId (stockId);
+ }
+ }
+
+ string label;
+ public string Label {
+ get {
+ return label;
+ }
+ set {
+ label = value;
+ if (labelWidget != null)
+ labelWidget.LabelProp = value;
+ else
+ button.Label = value;
+ }
+ }
+
+ bool useUnderline;
+ public bool UseUnderline {
+ get {
+ return useUnderline;
+ }
+ set {
+ useUnderline = value;
+ if (labelWidget != null)
+ labelWidget.UseUnderline = value;
+ else
+ button.UseUnderline = value;
+ }
+ }
+
+ public bool IsDialogButton {
+ get {
+ ButtonBox box = this.ParentWrapper as ButtonBox;
+ return (box != null && box.InternalChildProperty != null && box.InternalChildProperty.Name == "ActionArea");
+ }
+ }
+
+ int responseId;
+ public int ResponseId {
+ get {
+ return responseId;
+ }
+ set {
+ responseId = value;
+ EmitNotify ("ResponseId");
+ }
+ }
+
+ int ResponseIdForStockId (string stockId)
+ {
+ if (stockId == Gtk.Stock.Ok)
+ return (int)Gtk.ResponseType.Ok;
+ else if (stockId == Gtk.Stock.Cancel)
+ return (int)Gtk.ResponseType.Cancel;
+ else if (stockId == Gtk.Stock.Close)
+ return (int)Gtk.ResponseType.Close;
+ else if (stockId == Gtk.Stock.Yes)
+ return (int)Gtk.ResponseType.Yes;
+ else if (stockId == Gtk.Stock.No)
+ return (int)Gtk.ResponseType.No;
+ else if (stockId == Gtk.Stock.Apply)
+ return (int)Gtk.ResponseType.Apply;
+ else if (stockId == Gtk.Stock.Help)
+ return (int)Gtk.ResponseType.Help;
+ else
+ return 0;
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ base.GenerateBuildCode (ctx, var);
+
+ if (Type != ButtonType.TextAndIcon) {
+ CodePropertyReferenceExpression cprop = new CodePropertyReferenceExpression (var, "Label");
+ PropertyDescriptor prop = (PropertyDescriptor) this.ClassDescriptor ["Label"];
+ bool trans = Type != ButtonType.StockItem && prop.IsTranslated (Wrapped);
+ CodeExpression val = ctx.GenerateValue (button.Label, typeof(string), trans);
+ ctx.Statements.Add (new CodeAssignStatement (cprop, val));
+ }
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name != "Label")
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ButtonBox.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ButtonBox.cs
new file mode 100644
index 0000000000..37b8b60e7f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ButtonBox.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Xml;
+using System.Collections;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class ButtonBox : Box {
+
+ Dialog actionDialog;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ foreach (Gtk.Widget child in buttonbox.Children) {
+ if (child is Placeholder)
+ ReplaceChild (child, NewButton (), true);
+ }
+ }
+
+ public void SetActionDialog (Dialog dialog)
+ {
+ actionDialog = dialog;
+ }
+
+ Gtk.Button NewButton ()
+ {
+ Gtk.Button button = (Gtk.Button)Registry.NewInstance ("Gtk.Button", proj);
+ button.CanDefault = true;
+ return button;
+ }
+
+ protected Gtk.ButtonBox buttonbox {
+ get {
+ return (Gtk.ButtonBox)Wrapped;
+ }
+ }
+
+ protected override bool AllowPlaceholders {
+ get {
+ return false;
+ }
+ }
+ internal new void InsertBefore (Gtk.Widget context)
+ {
+ int position;
+ bool secondary;
+
+ if (context == buttonbox) {
+ position = 0;
+ secondary = false;
+ } else {
+ Gtk.ButtonBox.ButtonBoxChild bbc = (Gtk.ButtonBox.ButtonBoxChild)ContextChildProps (context);
+ position = bbc.Position;
+ secondary = bbc.Secondary;
+ }
+
+ Gtk.Button button = NewButton ();
+ buttonbox.PackStart (button, false, false, 0);
+ buttonbox.ReorderChild (button, position);
+ buttonbox.SetChildSecondary (button, secondary);
+ EmitContentsChanged ();
+ }
+
+ internal new void InsertAfter (Gtk.Widget context)
+ {
+ int position;
+ bool secondary;
+
+ if (context == buttonbox) {
+ position = buttonbox.Children.Length - 1;
+ secondary = false;
+ } else {
+ Gtk.ButtonBox.ButtonBoxChild bbc = (Gtk.ButtonBox.ButtonBoxChild)ContextChildProps (context);
+ position = bbc.Position;
+ secondary = bbc.Secondary;
+ }
+
+ Gtk.Button button = NewButton ();
+ buttonbox.PackStart (button, false, false, 0);
+ buttonbox.ReorderChild (button, position + 1);
+ buttonbox.SetChildSecondary (button, secondary);
+ EmitContentsChanged ();
+ }
+
+ public int Size {
+ get {
+ return buttonbox.Children.Length;
+ }
+ set {
+ Gtk.Widget[] children = buttonbox.Children;
+ int cursize = children.Length;
+
+ while (cursize > value) {
+ Gtk.Widget w = children[--cursize];
+ buttonbox.Remove (w);
+ w.Destroy ();
+ }
+ while (cursize < value) {
+ buttonbox.PackStart (NewButton (), false, false, 0);
+ cursize++;
+ }
+ }
+ }
+
+ protected override void ReadChildren (ObjectReader reader, XmlElement elem)
+ {
+ // Reset the button count
+ Size = 0;
+ base.ReadChildren (reader, elem);
+ }
+
+ protected override void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentVar, Widget wrapper)
+ {
+ if (actionDialog != null && wrapper is Button) {
+
+ // If this is the action area of a dialog, buttons must be added using AddActionWidget,
+ // so they are properly registered.
+
+ ObjectWrapper childwrapper = ChildWrapper (wrapper);
+ Button button = wrapper as Button;
+
+ if (childwrapper != null) {
+ CodeExpression dialogVar = ctx.WidgetMap.GetWidgetExp (actionDialog);
+ ctx.Statements.Add (new CodeCommentStatement ("Container child " + Wrapped.Name + "." + childwrapper.Wrapped.GetType ()));
+ CodeExpression var = ctx.GenerateNewInstanceCode (wrapper);
+ if (button.ResponseId != (int) Gtk.ResponseType.None) {
+ CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (
+ dialogVar,
+ "AddActionWidget",
+ var,
+ new CodePrimitiveExpression (button.ResponseId)
+ );
+ ctx.Statements.Add (invoke);
+ }
+ else {
+ CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (
+ parentVar,
+ "Add",
+ var
+ );
+ ctx.Statements.Add (invoke);
+ }
+ GenerateSetPacking (ctx, parentVar, var, childwrapper);
+ }
+ } else
+ base.GenerateChildBuildCode (ctx, parentVar, wrapper);
+ }
+
+ public class ButtonBoxChild : Box.BoxChild {
+
+ public bool InDialog {
+ get {
+ if (ParentWrapper == null)
+ return false;
+ return ParentWrapper.InternalChildProperty != null && ParentWrapper.InternalChildProperty.Name == "ActionArea";
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ChangeLog
new file mode 100644
index 0000000000..b9ccf74b8f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ChangeLog
@@ -0,0 +1,12 @@
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Frame.cs: Pass root wrapper as an argument for ObjectWrapper.Create
+ * Action.cs:
+ * Window.cs:
+ * Button.cs:
+ * Widget.cs:
+ * Expander.cs:
+ * Container.cs:
+ * ActionGroup.cs:
+ * ScrolledWindow.cs:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/CheckButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/CheckButton.cs
new file mode 100644
index 0000000000..cd2fd6e88b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/CheckButton.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Xml;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class CheckButton : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized)
+ checkbutton.UseUnderline = true;
+ }
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ base.Read (reader, elem);
+ if (reader.Format == FileFormat.Glade)
+ checkbutton.UseUnderline = true;
+ }
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ hasLabel = false;
+ if (checkbutton.Child != null)
+ checkbutton.Remove (checkbutton.Child);
+ return base.ReadChild (reader, child_elem);
+ }
+
+ public Gtk.CheckButton checkbutton {
+ get {
+ return (Gtk.CheckButton)Wrapped;
+ }
+ }
+
+ bool hasLabel = true;
+ public bool HasLabel {
+ get {
+ return hasLabel;
+ }
+ set {
+ hasLabel = value;
+ EmitNotify ("HasLabel");
+ }
+ }
+
+ internal void RemoveLabel ()
+ {
+ AddPlaceholder ();
+ HasLabel = false;
+ }
+
+ public override Placeholder AddPlaceholder ()
+ {
+ if (checkbutton.Child != null)
+ checkbutton.Remove (checkbutton.Child);
+ return base.AddPlaceholder ();
+ }
+
+ internal void RestoreLabel ()
+ {
+ checkbutton.Label = checkbutton.Name;
+ HasLabel = true;
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ base.ReplaceChild (oldChild, newChild);
+ EmitNotify ("HasContents");
+ }
+
+ protected override void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentVar, Widget wrapper)
+ {
+ if (!HasLabel) {
+ // CheckButton generates a label by default. Remove it if it is not required.
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ parentVar,
+ "Remove",
+ new CodePropertyReferenceExpression (
+ parentVar,
+ "Child"
+ )
+ )
+ );
+ }
+ base.GenerateChildBuildCode (ctx, parentVar, wrapper);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ColorButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ColorButton.cs
new file mode 100644
index 0000000000..1cf71351aa
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ColorButton.cs
@@ -0,0 +1,37 @@
+using System;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class ColorButton : Container {
+
+ public int Alpha {
+ get {
+ Gtk.ColorButton cb = (Gtk.ColorButton)Wrapped;
+
+ if (cb.UseAlpha)
+ return cb.Alpha;
+ else
+ return -1;
+ }
+ set {
+ Gtk.ColorButton cb = (Gtk.ColorButton)Wrapped;
+
+ if (value == -1)
+ cb.UseAlpha = false;
+ else {
+ cb.UseAlpha = true;
+ cb.Alpha = (ushort)value;
+ }
+ }
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name == "Alpha" && Alpha == -1)
+ return;
+ else
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBox.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBox.cs
new file mode 100644
index 0000000000..5d196c5bc4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBox.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Xml;
+using System.CodeDom;
+using System.Runtime.InteropServices;
+
+namespace Stetic.Wrapper {
+
+ public class ComboBox : Container {
+
+ public static Gtk.ComboBox CreateInstance ()
+ {
+ Gtk.ComboBox c = Gtk.ComboBox.NewText ();
+ // Make sure all children are created, so the mouse events can be
+ // bound and the widget can be selected.
+ c.EnsureStyle ();
+ try {
+ FixSensitivity (c);
+ } catch {
+ }
+ return c;
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized)
+ textCombo = true;
+ }
+
+
+ string[] items = new string[0];
+ bool textCombo;
+
+ public string[] Items {
+ get { return items; }
+ set {
+ Gtk.ComboBox combobox = (Gtk.ComboBox)Wrapped;
+ int active = combobox.Active;
+
+ int row = 0, oi = 0, ni = 0;
+ while (value != null && oi < items.Length && ni < value.Length) {
+ if (items [oi] == value [ni]) {
+ oi++;
+ ni++;
+ row++;
+ } else if (ni < value.Length - 1 &&
+ items [oi] == value [ni + 1]) {
+ combobox.InsertText (row++, value [ni++]);
+ if (active > row)
+ active++;
+ } else {
+ combobox.RemoveText (row);
+ if (active > row)
+ active--;
+ oi++;
+ }
+ }
+
+ while (oi < items.Length) {
+ combobox.RemoveText (row);
+ oi++;
+ }
+
+ while (value != null && ni < value.Length)
+ combobox.InsertText (row++, value [ni++]);
+
+ items = value == null ? new string [0] : value;
+ combobox.Active = active;
+
+ EmitNotify ("Items");
+ }
+ }
+
+ public bool IsTextCombo {
+ get { return textCombo; }
+ set { textCombo = value; EmitNotify ("IsTextCombo"); }
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ if (textCombo) {
+ return new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference ("Gtk.ComboBox", CodeTypeReferenceOptions.GlobalReference)),
+ "NewText"
+ );
+ } else
+ return base.GenerateObjectCreation (ctx);
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ if (textCombo && Items != null && Items.Length > 0) {
+ foreach (string str in Items) {
+ ctx.Statements.Add (new CodeMethodInvokeExpression (
+ var,
+ "AppendText",
+ ctx.GenerateValue (str, typeof(string), true)
+ ));
+ }
+ }
+
+ base.GenerateBuildCode (ctx, var);
+ }
+
+ public override void Read (ObjectReader reader, XmlElement element)
+ {
+ base.Read (reader, element);
+ if (reader.Format == FileFormat.Glade && items.Length > 0)
+ IsTextCombo = true;
+ }
+
+ internal static void FixSensitivity (Gtk.ComboBox c)
+ {
+ // Since gtk+ 2.14, empty combos are disabled by default
+ // This method disables this behavior
+ gtk_combo_box_set_button_sensitivity (c.Handle, 1);
+ }
+
+ [DllImport("libgtk-win32-2.0-0.dll")]
+ extern static void gtk_combo_box_set_button_sensitivity (IntPtr combo, int mode);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBoxEntry.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBoxEntry.cs
new file mode 100644
index 0000000000..9461b7422f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ComboBoxEntry.cs
@@ -0,0 +1,32 @@
+using System;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class ComboBoxEntry : ComboBox {
+
+ public static new Gtk.ComboBoxEntry CreateInstance ()
+ {
+ Gtk.ComboBoxEntry c = Gtk.ComboBoxEntry.NewText ();
+ // Make sure all children are created, so the mouse events can be
+ // bound and the widget can be selected.
+ c.EnsureStyle ();
+ try {
+ FixSensitivity (c);
+ } catch {
+ }
+ return c;
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ if (IsTextCombo) {
+ return new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference ("Gtk.ComboBoxEntry", CodeTypeReferenceOptions.GlobalReference)),
+ "NewText"
+ );
+ } else
+ return base.GenerateObjectCreation (ctx);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Container.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Container.cs
new file mode 100644
index 0000000000..8fd16191ef
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Container.cs
@@ -0,0 +1,1456 @@
+using System;
+using System.CodeDom;
+using System.Collections;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Xml;
+using Stetic.Undo;
+using Stetic.Editor;
+
+namespace Stetic.Wrapper
+{
+ public class Container : Widget
+ {
+ int designWidth;
+ int designHeight;
+ IDesignArea designer;
+ CodeExpression generatedTooltips;
+ bool internalAdd;
+
+ static DiffGenerator containerDiffGenerator;
+ static bool showNonContainerWarning = true;
+
+ static Container ()
+ {
+ XmlDiffAdaptor adaptor = new XmlDiffAdaptor ();
+ adaptor.ChildElementName = "child";
+ adaptor.ChildAdaptor = new XmlDiffAdaptor ();
+ adaptor.ChildAdaptor.PropsElementName = "packing";
+
+ containerDiffGenerator = new DiffGenerator ();
+ containerDiffGenerator.CurrentStatusAdaptor = adaptor;
+ containerDiffGenerator.NewStatusAdaptor = adaptor;
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ ClassDescriptor klass = this.ClassDescriptor;
+ foreach (PropertyDescriptor prop in klass.InternalChildren) {
+ Gtk.Widget child = prop.GetValue (container) as Gtk.Widget;
+ if (child == null)
+ continue;
+ Widget wrapper = ObjectWrapper.Create (proj, child, this) as Stetic.Wrapper.Widget;
+ wrapper.InternalChildProperty = prop;
+ if (child.Name == ((GLib.GType)child.GetType ()).ToString ())
+ child.Name = container.Name + "_" + prop.Name;
+ }
+
+ container.Removed += ChildRemoved;
+ container.Added += OnChildAdded;
+
+ if (!initialized && container.Children.Length == 0 && AllowPlaceholders)
+ AddPlaceholder ();
+
+ if (Wrapped.GetType ().ToString ()[0] == 'H')
+ ContainerOrientation = Gtk.Orientation.Horizontal;
+ else
+ ContainerOrientation = Gtk.Orientation.Vertical;
+
+ if (!Loading)
+ ValidateChildNames (Wrapped);
+ }
+
+ public override void Dispose ()
+ {
+ container.Removed -= ChildRemoved;
+ container.Added -= OnChildAdded;
+ AutoSize.Clear ();
+ base.Dispose ();
+ }
+
+ void OnChildAdded (object o, Gtk.AddedArgs args)
+ {
+ if (!internalAdd)
+ HandleNewChild (args.Widget);
+ }
+
+ protected void NotifyChildAdded (Gtk.Widget child)
+ {
+ HandleNewChild (child);
+ EmitContentsChanged ();
+ }
+
+ void HandleNewChild (Gtk.Widget child)
+ {
+ // Make sure children's IDs don't conflict with other widgets
+ // in the parent container.
+ if (!Loading)
+ ValidateChildNames (child);
+
+ Widget w = Widget.Lookup (child);
+ if (w != null) {
+ w.RequiresUndoStatusUpdate = true;
+ if (designer != null)
+ w.OnDesignerAttach (designer);
+
+ // If the ShowScrollbars flag is set, make sure the scrolled window is created.
+ if (w.ShowScrollbars)
+ w.UpdateScrolledWindow ();
+ }
+
+ Placeholder ph = child as Placeholder;
+ if (ph != null) {
+ ph.DragDrop += PlaceholderDragDrop;
+ ph.DragDataReceived += PlaceholderDragDataReceived;
+ ph.ButtonPressEvent += PlaceholderButtonPress;
+ AutoSize[ph] = true;
+ }
+ }
+
+ Gtk.Container container {
+ get {
+ return (Gtk.Container)Wrapped;
+ }
+ }
+
+ protected virtual bool AllowPlaceholders {
+ get {
+ return true && this.ClassDescriptor.AllowChildren;
+ }
+ }
+
+ public int DesignWidth {
+ get { return designWidth; }
+ set { designWidth = value; NotifyChanged (); }
+ }
+
+ public int DesignHeight {
+ get { return designHeight; }
+ set { designHeight = value; NotifyChanged (); }
+ }
+
+ public void IncreaseBorderWidth ()
+ {
+ container.BorderWidth += 3;
+ }
+
+ public void DecreaseBorderWidth ()
+ {
+ if (container.BorderWidth >= 3)
+ container.BorderWidth -= 3;
+ else
+ container.BorderWidth = 0;
+ }
+
+ internal bool ChildrenAllowed ()
+ {
+ return this.ClassDescriptor.AllowChildren;
+ }
+
+ int freeze;
+ protected void Freeze ()
+ {
+ freeze++;
+ }
+
+ protected void Thaw ()
+ {
+ if (--freeze == 0)
+ Sync ();
+ }
+
+ protected virtual void DoSync ()
+ {
+ ;
+ }
+
+ protected void Sync ()
+ {
+ if (freeze > 0 || Loading)
+ return;
+ freeze = 1;
+ DoSync ();
+ freeze = 0;
+ }
+
+ public override object GetUndoDiff ()
+ {
+ XmlElement oldElem = UndoManager.GetObjectStatus (this);
+
+// Console.WriteLine ("UNDO status: ");
+// Console.WriteLine (oldElem.OuterXml);
+
+ // Write the new status of the object. This is going to replace the old status in undoManager.
+ // In the process, register new objects found.
+
+ UndoWriter writer = new UndoWriter (oldElem.OwnerDocument, UndoManager);
+ XmlElement newElem = Write (writer);
+
+// Console.WriteLine ("CURRENT status: ");
+// Console.WriteLine (newElem.OuterXml);
+
+ // Get the changes since the last undo checkpoint
+
+ ObjectDiff actionsDiff = null;
+ ObjectDiff objectDiff = containerDiffGenerator.GetDiff (newElem, oldElem);
+
+ // If there are child changes there is no need to look for changes in the
+ // actions, since the whole widget will be read again
+
+ if (IsTopLevel && (objectDiff == null || objectDiff.ChildChanges == null))
+ actionsDiff = LocalActionGroups.GetDiff (Project, oldElem);
+
+ // The undo writer skips children which are already registered in the undo manager
+ // to avoid writing information we already have. Now it's the moment to fill the gaps
+
+ foreach (XmlElement newChild in newElem.SelectNodes ("child[widget/@unchanged_marker='yes']")) {
+ string cid = newChild.GetAttribute ("undoId");
+ XmlElement oldChild = (XmlElement) oldElem.SelectSingleNode ("child[@undoId='" + cid + "']");
+ if (oldChild == null)
+ throw new InvalidOperationException ("Child not found when filling widget info gaps.");
+
+ XmlElement oldWidgetChild = oldChild ["widget"];
+ XmlElement newWidgetChild = newChild ["widget"];
+
+ oldChild.RemoveChild (oldWidgetChild);
+ if (newWidgetChild != null)
+ newChild.ReplaceChild (oldWidgetChild, newWidgetChild);
+ }
+
+ // Update the status tree
+
+ UndoManager.UpdateObjectStatus (this, newElem);
+
+// UndoManager.Dump ();
+
+ if (objectDiff != null || actionsDiff != null)
+ return new ObjectDiff[] { objectDiff, actionsDiff };
+ else
+ return null;
+ }
+
+ public override object ApplyUndoRedoDiff (object data)
+ {
+ ObjectDiff diff = ((ObjectDiff[]) data)[0];
+ ObjectDiff actionsDiff = ((ObjectDiff[]) data)[1];
+
+ ObjectDiff reverseDiff = null;
+ ObjectDiff reverseActionsDiff = null;
+
+ XmlElement status = UndoManager.GetObjectStatus (this);
+ XmlElement oldStatus = (XmlElement) status.CloneNode (true);
+ UndoReader reader = new UndoReader (Project, FileFormat.Native, UndoManager);
+
+ // Only apply the actions diff if the widget has not been completely reloaded
+ if (actionsDiff != null && !(diff != null && diff.ChildChanges != null)) {
+ // Apply the patch
+ LocalActionGroups.ApplyDiff (Project, actionsDiff);
+
+ // Get the redo patch
+ reverseActionsDiff = LocalActionGroups.GetDiff (Project, oldStatus);
+
+ // Update the status of the action group list in the undo status tree.
+ // It has to remove all action groups and then write them again
+ foreach (XmlElement group in status.SelectNodes ("action-group"))
+ status.RemoveChild (group);
+
+ UndoWriter writer = new UndoWriter (status.OwnerDocument, UndoManager);
+ foreach (ActionGroup actionGroup in LocalActionGroups)
+ status.InsertBefore (actionGroup.Write (writer), status.FirstChild);
+ }
+
+ if (diff != null) {
+ containerDiffGenerator.ApplyDiff (status, diff);
+ reverseDiff = containerDiffGenerator.GetDiff (status, oldStatus);
+
+ // Avoid reading the whole widget tree if only the properties have changed.
+ if (diff.ChildChanges == null) {
+ ReadProperties (reader, status);
+ } else {
+// Console.WriteLine ("BEFORE PATCH: " + status.OuterXml);
+ Read (reader, status);
+// Console.WriteLine ("\nAFTER PATCH:");
+// UndoManager.Dump ();
+ EmitContentsChanged ();
+ }
+ }
+
+ if (reverseDiff != null || reverseActionsDiff != null)
+ return new ObjectDiff[] { reverseDiff, reverseActionsDiff };
+ else
+ return null;
+ }
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ // Remove all existing children
+ if (ClassDescriptor.AllowChildren && Wrapped != null) {
+ foreach (Gtk.Widget child in GladeChildren) {
+ Widget wrapper = Widget.Lookup (child);
+
+ if (wrapper != null) {
+ if (wrapper.InternalChildProperty != null)
+ continue;
+ container.Remove (child);
+ child.Destroy ();
+ } else if (child is Stetic.Placeholder) {
+ container.Remove (child);
+ child.Destroy ();
+ }
+ }
+ }
+
+ try {
+ Loading = true;
+ ReadActionGroups (reader, elem);
+ ReadProperties (reader, elem);
+ ReadChildren (reader, elem);
+ DoSync ();
+ } finally {
+ Loading = false;
+ }
+ }
+
+ protected virtual void ReadChildren (ObjectReader reader, XmlElement elem)
+ {
+ int gladeChildStackPos = reader.GladeChildStack.Count;
+
+ foreach (XmlElement child_elem in elem.SelectNodes ("./child")) {
+ try {
+ if (child_elem.HasAttribute ("internal-child"))
+ ReadInternalChild (reader, child_elem);
+ else if (child_elem["widget"] == null)
+ ReadPlaceholder (reader, child_elem);
+ else {
+ ObjectWrapper cw = ReadChild (reader, child_elem);
+
+ // Set a temporary id used for the undo/redo operations
+ ObjectWrapper ccw = ChildWrapper ((Widget)cw);
+ if (ccw != null) {
+ string cid = child_elem.GetAttribute ("undoId");
+ if (cid.Length > 0)
+ ChildWrapper ((Widget)cw).UndoId = cid;
+ else
+ child_elem.SetAttribute ("undoId", ChildWrapper ((Widget)cw).UndoId);
+ }
+ }
+ } catch (GladeException ge) {
+ Console.Error.WriteLine (ge.Message);
+ }
+ }
+
+ if (reader.Format == FileFormat.Glade) {
+ for (int n = reader.GladeChildStack.Count - 1; n >= gladeChildStackPos; n--) {
+ ObjectWrapper ob = ReadInternalChild (reader, (XmlElement) reader.GladeChildStack [n]);
+ if (ob != null)
+ reader.GladeChildStack.RemoveAt (n);
+ }
+ }
+
+ string ds = elem.GetAttribute ("design-size");
+ if (ds.Length > 0) {
+ int i = ds.IndexOf (' ');
+ DesignWidth = int.Parse (ds.Substring (0, i));
+ DesignHeight = int.Parse (ds.Substring (i+1));
+ }
+
+ Sync ();
+ }
+
+ protected virtual ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ Container.ContainerChild childwrapper = null;
+
+ try {
+ wrapper.Loading = true;
+
+ Gtk.Widget child = (Gtk.Widget)wrapper.Wrapped;
+
+ AutoSize[child] = false;
+ container.Add (child);
+
+ childwrapper = ChildWrapper ((Widget)wrapper);
+ if (childwrapper != null)
+ childwrapper.Loading = true;
+
+ if (reader.Format == FileFormat.Glade)
+ GladeUtils.SetPacking (childwrapper, child_elem);
+ else
+ WidgetUtils.SetPacking (childwrapper, child_elem);
+ return wrapper;
+ } finally {
+ wrapper.Loading = false;
+ if (childwrapper != null)
+ childwrapper.Loading = false;
+ }
+ }
+
+ void ReadPlaceholder (ObjectReader reader, XmlElement child_elem)
+ {
+ Placeholder ph = AddPlaceholder ();
+ if (ph != null) {
+ string cid = child_elem.GetAttribute ("undoId");
+ if (cid.Length > 0)
+ ph.UndoId = cid;
+ else
+ child_elem.SetAttribute ("undoId", ph.UndoId);
+ }
+ }
+
+ protected virtual ObjectWrapper ReadInternalChild (ObjectReader reader, XmlElement child_elem)
+ {
+ ClassDescriptor klass = base.ClassDescriptor;
+ string childId = child_elem.GetAttribute ("internal-child");
+
+ foreach (PropertyDescriptor prop in klass.InternalChildren) {
+ if (reader.Format == FileFormat.Glade && ((TypedPropertyDescriptor)prop).GladeName != childId)
+ continue;
+ else if (reader.Format == FileFormat.Native && prop.Name != childId)
+ continue;
+
+ Gtk.Widget child = prop.GetValue (container) as Gtk.Widget;
+ Widget wrapper = Widget.Lookup (child);
+ if (wrapper != null) {
+ reader.ReadExistingObject (wrapper, child_elem["widget"]);
+ if (reader.Format == FileFormat.Glade)
+ GladeUtils.SetPacking (ChildWrapper (wrapper), child_elem);
+ else
+ WidgetUtils.SetPacking (ChildWrapper (wrapper), child_elem);
+ return wrapper;
+ }
+ }
+
+ // In Glade, internal children may not be direct children of the root container. This is handled in a special way.
+ if (reader.Format == FileFormat.Glade) {
+ if (!reader.GladeChildStack.Contains (child_elem))
+ reader.GladeChildStack.Add (child_elem);
+ return null;
+ }
+ else
+ throw new GladeException ("Unrecognized internal child name", Wrapped.GetType ().FullName, false, "internal-child", childId);
+ }
+
+ public override XmlElement Write (ObjectWriter writer)
+ {
+ XmlElement elem = WriteProperties (writer);
+ WriteActionGroups (writer, elem);
+ XmlElement child_elem;
+
+ if (ClassDescriptor.AllowChildren) {
+ foreach (Gtk.Widget child in GladeChildren) {
+ Widget wrapper = Widget.Lookup (child);
+
+ if (wrapper != null) {
+ // Iternal children are written later
+ if (wrapper.InternalChildProperty != null)
+ continue;
+ child_elem = WriteChild (writer, wrapper);
+ if (child_elem != null)
+ elem.AppendChild (child_elem);
+ } else if (child is Stetic.Placeholder) {
+ child_elem = writer.XmlDocument.CreateElement ("child");
+ if (writer.CreateUndoInfo)
+ child_elem.SetAttribute ("undoId", ((Stetic.Placeholder)child).UndoId);
+ child_elem.AppendChild (writer.XmlDocument.CreateElement ("placeholder"));
+ elem.AppendChild (child_elem);
+ }
+ }
+ }
+
+ foreach (PropertyDescriptor prop in this.ClassDescriptor.InternalChildren) {
+ Gtk.Widget child = prop.GetValue (Wrapped) as Gtk.Widget;
+ if (child == null)
+ continue;
+
+ child_elem = writer.XmlDocument.CreateElement ("child");
+ Widget wrapper = Widget.Lookup (child);
+ if (wrapper == null) {
+ child_elem.AppendChild (writer.XmlDocument.CreateElement ("placeholder"));
+ elem.AppendChild (child_elem);
+ continue;
+ }
+
+ string cid = writer.Format == FileFormat.Glade ? prop.InternalChildId : prop.Name;
+
+ XmlElement widget_elem = writer.WriteObject (wrapper);
+ child_elem.SetAttribute ("internal-child", cid);
+ // Sets the child Id to be used in undo/redo operations
+ if (writer.CreateUndoInfo)
+ child_elem.SetAttribute ("undoId", cid);
+
+ child_elem.AppendChild (widget_elem);
+ elem.AppendChild (child_elem);
+ }
+
+ if (DesignWidth != 0 || DesignHeight != 0)
+ elem.SetAttribute ("design-size", DesignWidth + " " + DesignHeight);
+
+ return elem;
+ }
+
+ protected virtual XmlElement WriteChild (ObjectWriter writer, Widget wrapper)
+ {
+ XmlElement child_elem = writer.XmlDocument.CreateElement ("child");
+ XmlElement widget_elem = writer.WriteObject (wrapper);
+ child_elem.AppendChild (widget_elem);
+
+ Container.ContainerChild childwrapper = ChildWrapper (wrapper);
+ if (childwrapper != null) {
+ XmlElement packing_elem;
+
+ if (writer.Format == FileFormat.Glade)
+ packing_elem = GladeUtils.CreatePacking (writer.XmlDocument, childwrapper);
+ else
+ packing_elem = WidgetUtils.CreatePacking (writer.XmlDocument, childwrapper);
+
+ // Sets the child Id to be used in undo/redo operations
+ if (writer.CreateUndoInfo)
+ child_elem.SetAttribute ("undoId", childwrapper.UndoId);
+
+ if (packing_elem.HasChildNodes)
+ child_elem.AppendChild (packing_elem);
+ } else {
+ // There is no container child, so make up an id.
+ if (writer.CreateUndoInfo)
+ child_elem.SetAttribute ("undoId", "0");
+ }
+
+ return child_elem;
+ }
+
+ public XmlElement WriteContainerChild (ObjectWriter writer, Widget wrapper)
+ {
+ return WriteChild (writer, wrapper);
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ generatedTooltips = null;
+
+ base.GenerateBuildCode (ctx, var);
+
+ if (ClassDescriptor.AllowChildren) {
+ foreach (Gtk.Widget child in GladeChildren) {
+ Widget wrapper = Widget.Lookup (child);
+
+ if (wrapper != null && wrapper.InternalChildProperty == null)
+ // Iternal children are written later
+ GenerateChildBuildCode (ctx, var, wrapper);
+ }
+ }
+
+ foreach (TypedPropertyDescriptor prop in this.ClassDescriptor.InternalChildren) {
+ GenerateSetInternalChild (ctx, var, prop);
+ }
+
+
+ if (IsTopLevel && Wrapped is Gtk.Bin) {
+ CodeExpression childExp = new CodePropertyReferenceExpression (var, "Child");
+ CodeConditionStatement cond = new CodeConditionStatement ();
+ cond.Condition =
+ new CodeBinaryOperatorExpression (
+ childExp,
+ CodeBinaryOperatorType.IdentityInequality,
+ new CodePrimitiveExpression (null)
+ );
+ cond.TrueStatements.Add (
+ new CodeMethodInvokeExpression (
+ childExp,
+ "ShowAll"
+ )
+ );
+ ctx.Statements.Add (cond);
+ }
+ }
+
+ protected virtual void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentVar, Widget wrapper)
+ {
+ ObjectWrapper childwrapper = ChildWrapper (wrapper);
+ if (childwrapper != null) {
+ ctx.Statements.Add (new CodeCommentStatement ("Container child " + Wrapped.Name + "." + childwrapper.Wrapped.GetType ()));
+ CodeExpression var = ctx.GenerateNewInstanceCode (wrapper);
+ CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (
+ parentVar,
+ "Add",
+ var
+ );
+ ctx.Statements.Add (invoke);
+
+ GenerateSetPacking (ctx, parentVar, var, childwrapper);
+ }
+ }
+
+ void GenerateSetInternalChild (GeneratorContext ctx, CodeExpression parentVar, TypedPropertyDescriptor prop)
+ {
+ Gtk.Widget child = prop.GetValue (container) as Gtk.Widget;
+ Widget cwrapper = Widget.Lookup (child);
+ if (cwrapper != null) {
+ ctx.Statements.Add (new CodeCommentStatement ("Internal child " + Wrapped.Name + "." + prop.Name));
+ string childVar = ctx.NewId ();
+ CodeVariableDeclarationStatement varDec = new CodeVariableDeclarationStatement (child.GetType().ToGlobalTypeRef (), childVar);
+ ctx.Statements.Add (varDec);
+ varDec.InitExpression = new CodePropertyReferenceExpression (parentVar, prop.Name);
+
+ ctx.GenerateBuildCode (cwrapper, new CodeVariableReferenceExpression (childVar));
+ return;
+ }
+ }
+
+ protected void GenerateSetPacking (GeneratorContext ctx, CodeExpression parentVar, CodeExpression childVar, ObjectWrapper containerChildWrapper)
+ {
+ Gtk.Container.ContainerChild cc = containerChildWrapper.Wrapped as Gtk.Container.ContainerChild;
+ ClassDescriptor klass = containerChildWrapper.ClassDescriptor;
+
+ // Generate a variable that holds the container child
+
+ string contChildVar = ctx.NewId ();
+ CodeVariableDeclarationStatement varDec = new CodeVariableDeclarationStatement (cc.GetType().ToGlobalTypeRef (), contChildVar);
+ varDec.InitExpression = new CodeCastExpression (
+ cc.GetType ().ToGlobalTypeRef (),
+ new CodeIndexerExpression (parentVar, childVar)
+ );
+
+ CodeVariableReferenceExpression var = new CodeVariableReferenceExpression (contChildVar);
+
+ // Set the container child properties
+
+ ctx.Statements.Add (varDec);
+ int count = ctx.Statements.Count;
+
+ foreach (ItemGroup group in klass.ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ PropertyDescriptor prop = item as PropertyDescriptor;
+ if (prop == null || !prop.IsRuntimeProperty)
+ continue;
+ GenerateChildPropertySet (ctx, var, klass, prop, cc);
+ }
+ }
+
+ if (ctx.Statements.Count == count) {
+ ctx.Statements.Remove (varDec);
+ }
+ }
+
+ protected virtual void GenerateChildPropertySet (GeneratorContext ctx, CodeVariableReferenceExpression var, ClassDescriptor containerChildClass, PropertyDescriptor prop, object child)
+ {
+ if (containerChildClass.InitializationProperties != null && Array.IndexOf (containerChildClass.InitializationProperties, prop) != -1)
+ return;
+
+ // Design time
+ if (prop.Name == "AutoSize")
+ return;
+
+ object oval = prop.GetValue (child);
+ if (oval == null || (prop.HasDefault && prop.IsDefaultValue (oval)))
+ return;
+
+ CodePropertyReferenceExpression cprop = new CodePropertyReferenceExpression (var, prop.Name);
+ CodeExpression val = ctx.GenerateValue (oval, prop.RuntimePropertyType, prop.Translatable);
+ ctx.Statements.Add (new CodeAssignStatement (cprop, val));
+ }
+
+ internal protected override void GeneratePostBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ base.GeneratePostBuildCode (ctx, var);
+
+ if (IsTopLevel && (Wrapped is Gtk.Bin) && Visible) {
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ var,
+ "Show"
+ )
+ );
+ }
+ }
+
+ internal void GenerateTooltip (GeneratorContext ctx, Widget widget)
+ {
+ if (WidgetUtils.CompareVersions (Project.TargetGtkVersion, "2.12") <= 0) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (ctx.WidgetMap.GetWidgetExp (widget), "TooltipMarkup"),
+ new CodePrimitiveExpression (widget.Tooltip)
+ )
+ );
+ return;
+ }
+
+ if (generatedTooltips == null) {
+ string tid = ctx.NewId ();
+ Type t = typeof(Gtk.Widget).Assembly.GetType ("Gtk.Tooltips");
+ CodeVariableDeclarationStatement vardec = new CodeVariableDeclarationStatement (
+ t.ToGlobalTypeRef (), tid, new CodeObjectCreateExpression (t)
+ );
+ ctx.Statements.Add (vardec);
+ generatedTooltips = new CodeVariableReferenceExpression (tid);
+ }
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ generatedTooltips,
+ "SetTip",
+ ctx.WidgetMap.GetWidgetExp (widget),
+ new CodePrimitiveExpression (widget.Tooltip),
+ new CodePrimitiveExpression (widget.Tooltip)
+ )
+ );
+ }
+
+ internal protected override void OnDesignerAttach (IDesignArea designer)
+ {
+ base.OnDesignerAttach (designer);
+ this.designer = designer;
+ foreach (Gtk.Widget w in RealChildren) {
+ ObjectWrapper wr = ObjectWrapper.Lookup (w);
+ if (wr != null)
+ wr.OnDesignerAttach (designer);
+ }
+ }
+
+ internal protected override void OnDesignerDetach (IDesignArea designer)
+ {
+ base.OnDesignerDetach (designer);
+ foreach (Gtk.Widget w in RealChildren) {
+ ObjectWrapper wr = ObjectWrapper.Lookup (w);
+ if (wr != null)
+ wr.OnDesignerDetach (designer);
+ }
+ this.designer = null;
+ }
+
+ public virtual Placeholder AddPlaceholder ()
+ {
+ Placeholder ph = CreatePlaceholder ();
+ container.Add (ph);
+ return ph;
+ }
+
+ public virtual void Add (Gtk.Widget child)
+ {
+ container.Add (child);
+ }
+
+ public static new Container Lookup (GLib.Object obj)
+ {
+ return Stetic.ObjectWrapper.Lookup (obj) as Stetic.Wrapper.Container;
+ }
+
+ public static Container LookupParent (Gtk.Widget widget)
+ {
+ if (widget == null)
+ return null;
+ Gtk.Widget parent = widget.Parent;
+ Container wrapper = null;
+ while ((wrapper == null || wrapper.Unselectable) && parent != null) {
+ wrapper = Lookup (parent);
+ parent = parent.Parent;
+ }
+ return wrapper;
+ }
+
+ public static Stetic.Wrapper.Container.ContainerChild ChildWrapper (Stetic.Wrapper.Widget wrapper) {
+ Stetic.Wrapper.Container parentWrapper = wrapper.ParentWrapper;
+ if (parentWrapper == null)
+ return null;
+
+ Gtk.Container parent = parentWrapper.Wrapped as Gtk.Container;
+ if (parent == null)
+ return null;
+
+ Gtk.Widget child = (Gtk.Widget)wrapper.Wrapped;
+ while (child != null && child.Parent != parent)
+ child = child.Parent;
+ if (child == null)
+ return null;
+
+ Gtk.Container.ContainerChild cc = parent[child];
+ Container.ContainerChild cwrap = ObjectWrapper.Lookup (cc) as Container.ContainerChild;
+ if (cwrap != null)
+ return cwrap;
+ else
+ return Stetic.ObjectWrapper.Create (parentWrapper.proj, cc, parentWrapper) as ContainerChild;
+ }
+
+ protected Gtk.Container.ContainerChild ContextChildProps (Gtk.Widget context)
+ {
+ if (context == container)
+ return null;
+
+ do {
+ if (context.Parent == container)
+ return container[context];
+ context = context.Parent;
+ } while (context != null);
+
+ return null;
+ }
+
+ public delegate void ContentsChangedHandler (Container container);
+ public event ContentsChangedHandler ContentsChanged;
+
+ protected void EmitContentsChanged ()
+ {
+ if (Loading)
+ return;
+ if (ContentsChanged != null)
+ ContentsChanged (this);
+ if (ParentWrapper != null)
+ ParentWrapper.ChildContentsChanged (this);
+ if (Project != null)
+ Project.NotifyWidgetContentsChanged (this);
+ NotifyChanged ();
+ }
+
+ protected Set AutoSize = new Set ();
+
+ protected virtual Placeholder CreatePlaceholder ()
+ {
+ Placeholder ph = new Placeholder ();
+ ph.Show ();
+ return ph;
+ }
+
+ void PlaceholderButtonPress (object obj, Gtk.ButtonPressEventArgs args)
+ {
+ if (args.Event.Type != Gdk.EventType.ButtonPress)
+ return;
+
+ Placeholder ph = obj as Placeholder;
+
+ if (args.Event.Button == 1) {
+ proj.Selection = ph;
+ args.RetVal = true;
+ } else if (args.Event.Button == 3) {
+ proj.PopupContextMenu (ph);
+ args.RetVal = true;
+ }
+ }
+
+ public static bool ShowNonContainerWarning {
+ get { return showNonContainerWarning; }
+ set { showNonContainerWarning = value; }
+ }
+
+ static IList nonContainers = new string[] {
+ "Gtk.Button", "Gtk.Entry", "Gtk.Label", "Gtk.Arrow", "Gtk.Calendar", "Gtk.CheckButton",
+ "Gtk.ColorButton", "Gtk.ComboBox", "Gtk.ComboBoxEntry", "Gtk.Entry", "Gtk.FontButton",
+ "Gtk.HScale", "Gtk.VScale", "Gtk.Image", "Gtk.MenuBar", "Gtk.Toolbar", "Gtk.RadioButton",
+ "Gtk.ProgressBar", "Stetic.Editor.ActionToolbar", "Stetic.Editor.ActionMenuBar",
+ "Gtk.ToggleButton", "Gtk.TextView", "Gtk.VScrollbar", "Gtk.HScrollbar", "Gtk.SpinButton",
+ "Gtk.Statusbar", "Gtk.HSeparator", "Gtk.VSeparator"
+ };
+
+ void PlaceholderDrop (Placeholder ph, Stetic.Wrapper.Widget wrapper)
+ {
+ Gtk.Dialog parentDialog = Wrapped.Parent as Gtk.Dialog;
+ if (showNonContainerWarning && (IsTopLevel || (parentDialog != null && parentDialog.VBox == Wrapped))) {
+ if (nonContainers.Contains (wrapper.Wrapped.GetType ().ToString ())) {
+ using (NonContainerWarningDialog dlg = new NonContainerWarningDialog ()) {
+ int res = dlg.Run ();
+ showNonContainerWarning = dlg.ShowAgain;
+ if (res != (int) Gtk.ResponseType.Ok)
+ return;
+ }
+ }
+ }
+ using (UndoManager.AtomicChange) {
+ ReplaceChild (ph, wrapper.Wrapped, true);
+ wrapper.Select ();
+ }
+ }
+
+ void PlaceholderDragDrop (object obj, Gtk.DragDropArgs args)
+ {
+ Placeholder ph = (Placeholder)obj;
+ // This Drop call will end calling DropObject()
+ DND.Drop (args.Context, args.Time, this, ph.UndoId);
+ args.RetVal = true;
+ }
+
+ internal protected override void DropObject (string data, Gtk.Widget w)
+ {
+ Placeholder ph = FindPlaceholder (container, data);
+ if (ph != null) {
+ Widget dropped = Stetic.Wrapper.Widget.Lookup (w);
+ if (dropped != null)
+ PlaceholderDrop (ph, dropped);
+ }
+ }
+
+ Placeholder FindPlaceholder (Gtk.Container c, string pid)
+ {
+ foreach (Gtk.Widget cw in c.AllChildren) {
+ Placeholder ph = cw as Placeholder;
+ if (ph != null && ph.UndoId == pid)
+ return ph;
+ Gtk.Container cc = cw as Gtk.Container;
+ if (cc != null) {
+ ph = FindPlaceholder (cc, pid);
+ if (ph != null)
+ return ph;
+ }
+ }
+ return null;
+ }
+
+ void PlaceholderDragDataReceived (object obj, Gtk.DragDataReceivedArgs args)
+ {
+ Widget dropped = WidgetUtils.Paste (proj, args.SelectionData);
+ Gtk.Drag.Finish (args.Context, dropped != null,
+ dropped != null, args.Time);
+ if (dropped != null) {
+ dropped.RequiresUndoStatusUpdate = true;
+ PlaceholderDrop ((Placeholder)obj, dropped);
+ }
+ }
+
+ protected virtual void ChildContentsChanged (Container child)
+ {
+ }
+
+ void ChildRemoved (object obj, Gtk.RemovedArgs args)
+ {
+ NotifyChildRemoved (args.Widget);
+ }
+
+ protected void NotifyChildRemoved (Gtk.Widget child)
+ {
+ if (Loading)
+ return;
+
+ ObjectWrapper w = ObjectWrapper.Lookup (child);
+ if (w != null) {
+ if (w.Loading)
+ return;
+ if (designer != null)
+ w.OnDesignerDetach (designer);
+ }
+ ChildRemoved (child);
+ }
+
+ protected virtual void ChildRemoved (Gtk.Widget w)
+ {
+ AutoSize[w] = false;
+ EmitContentsChanged ();
+ }
+
+ public virtual IEnumerable RealChildren {
+ get {
+ ArrayList children = new ArrayList ();
+ foreach (Gtk.Widget widget in container.AllChildren) {
+ if (!(widget is Placeholder))
+ children.Add (widget);
+ }
+ return children;
+ }
+ }
+
+ public virtual IEnumerable GladeChildren {
+ get {
+ return container.AllChildren;
+ }
+ }
+
+ public void PasteChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ using (UndoManager.AtomicChange) {
+ Widget w = Widget.Lookup (newChild);
+ w.RequiresUndoStatusUpdate = true;
+ ReplaceChild (oldChild, newChild, true);
+ }
+ }
+
+ internal protected void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild, bool destroyOld)
+ {
+ ReplaceChild (oldChild, newChild);
+ if (destroyOld)
+ oldChild.Destroy ();
+ }
+
+ protected virtual void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ using (UndoManager.AtomicChange)
+ {
+ Gtk.Container.ContainerChild cc;
+ Hashtable props = new Hashtable ();
+
+ cc = container[oldChild];
+ foreach (PropertyInfo pinfo in cc.GetType ().GetProperties ()) {
+ if (!pinfo.IsDefined (typeof (Gtk.ChildPropertyAttribute), true))
+ continue;
+ props[pinfo] = pinfo.GetValue (cc, null);
+ }
+
+ container.Remove (oldChild);
+ AutoSize[oldChild] = false;
+ AutoSize[newChild] = true;
+
+ try {
+ // Don't fire the child added event until the packing info is set
+ internalAdd = true;
+ container.Add (newChild);
+ } finally {
+ internalAdd = false;
+ }
+
+ cc = container[newChild];
+ foreach (PropertyInfo pinfo in props.Keys)
+ pinfo.SetValue (cc, props[pinfo], null);
+
+ Sync ();
+ NotifyChildAdded (newChild);
+ if (Project != null)
+ Project.Selection = newChild;
+ }
+ }
+
+ Gtk.Widget selection;
+
+ public virtual void Select (Gtk.Widget widget)
+ {
+ if (widget == null) {
+ Select (null, false);
+ } else {
+ Widget wrapper = Widget.Lookup (widget);
+ bool allowDrag = wrapper != null && wrapper.InternalChildProperty == null && !wrapper.IsTopLevel;
+ Select (widget, allowDrag);
+ }
+ }
+
+ public virtual void UnSelect (Gtk.Widget widget)
+ {
+ if (selection == widget)
+ Select (null, false);
+ }
+
+ void Select (Gtk.Widget widget, bool dragHandles)
+ {
+ if (widget == selection)
+ return;
+
+ Gtk.Window win = GetParentWindow ();
+
+ if (selection != null) {
+ selection.Destroyed -= SelectionDestroyed;
+ HideSelectionBox (selection);
+ Widget wr = Widget.Lookup (selection);
+ if (wr != null)
+ wr.OnUnselected ();
+ }
+
+ selection = widget;
+ if (win != null) {
+ if (widget != null) {
+ if (widget.CanFocus)
+ win.Focus = widget;
+ else {
+ // Look for a focusable parent container
+ Widget wr = GetTopLevel ();
+ Gtk.Widget w = wr.Wrapped;
+ while (w != null && !w.CanFocus)
+ w = w.Parent;
+
+ // If the widget is not focusable,
+ // remove the focus from the window. In this way we ensure
+ // that the current selected widget will lose the focus,
+ // even if the new selection is not focusable.
+ win.Focus = w;
+ }
+ } else {
+ if (designer != null)
+ designer.ResetSelection (null);
+ }
+ }
+
+ if (selection != null) {
+ selection.Destroyed += SelectionDestroyed;
+
+ // FIXME: if the selection isn't mapped, we should try to force it
+ // to be. (Eg, if you select a widget in a hidden window, the window
+ // should map. If you select a widget on a non-current notebook
+ // page, the notebook should switch pages, etc.)
+ if (selection.IsDrawable && selection.Visible) {
+ ShowSelectionBox (selection, dragHandles);
+ }
+
+ Widget wr = Widget.Lookup (selection);
+ if (wr != null)
+ wr.OnSelected ();
+ }
+ }
+
+ void ShowSelectionBox (Gtk.Widget widget, bool dragHandles)
+ {
+ HideSelectionBox (selection);
+
+ IDesignArea designArea = GetDesignArea (widget);
+ if (designArea != null) {
+ IObjectSelection sel = designArea.SetSelection (widget, widget, dragHandles);
+ sel.Drag += HandleWindowDrag;
+ return;
+ }
+ }
+
+ void HideSelectionBox (Gtk.Widget widget)
+ {
+ if (widget != null) {
+ IDesignArea designArea = GetDesignArea (widget);
+ if (designArea != null)
+ designArea.ResetSelection (widget);
+ }
+ }
+
+ Gtk.Window GetParentWindow ()
+ {
+ Gtk.Container cc = Wrapped as Gtk.Container;
+ while (cc.Parent != null)
+ cc = cc.Parent as Gtk.Container;
+ return cc as Gtk.Window;
+ }
+
+ void SelectionDestroyed (object obj, EventArgs args)
+ {
+ if (!IsDisposed)
+ UnSelect (selection);
+ }
+
+ Gtk.Widget dragSource;
+
+ void HandleWindowDrag (Gdk.EventMotion evt, int dx, int dy)
+ {
+ Gtk.Widget dragWidget = selection;
+
+ Project.Selection = null;
+
+ using (UndoManager.AtomicChange) {
+ dragSource = CreateDragSource (dragWidget);
+ }
+
+ DND.Drag (dragSource, evt, dragWidget);
+ }
+
+ protected virtual Gtk.Widget CreateDragSource (Gtk.Widget dragWidget)
+ {
+ Placeholder ph = CreatePlaceholder ();
+ Gdk.Rectangle alloc = dragWidget.Allocation;
+ ph.SetSizeRequest (alloc.Width, alloc.Height);
+ ph.DragEnd += DragEnd;
+ ReplaceChild (dragWidget, ph, false);
+ return ph;
+ }
+
+ void DragEnd (object obj, Gtk.DragEndArgs args)
+ {
+ using (UndoManager.AtomicChange) {
+ Placeholder ph = obj as Placeholder;
+ ph.DragEnd -= DragEnd;
+
+ dragSource = null;
+ if (DND.DragWidget == null) {
+ if (AllowPlaceholders)
+ ph.SetSizeRequest (-1, -1);
+ else
+ container.Remove (ph);
+ Sync ();
+ } else
+ ReplaceChild (ph, DND.Cancel (), true);
+ }
+ }
+
+ public virtual void Delete (Stetic.Wrapper.Widget wrapper)
+ {
+ using (UndoManager.AtomicChange) {
+ if (AllowPlaceholders)
+ ReplaceChild (wrapper.Wrapped, CreatePlaceholder (), true);
+ else {
+ container.Remove (wrapper.Wrapped);
+ wrapper.Wrapped.Destroy ();
+ }
+ }
+ }
+
+ public virtual void Delete (Stetic.Placeholder ph)
+ {
+ if (AllowPlaceholders) {
+ // Don't allow deleting the only placeholder of a top level container
+ if (IsTopLevel && container.Children.Length == 1)
+ return;
+ using (UndoManager.AtomicChange) {
+ container.Remove (ph);
+ ph.Destroy ();
+ // If there aren't more placeholders in this container, just delete the container
+ if (container.Children.Length == 0)
+ Delete ();
+ }
+ }
+ }
+
+ protected bool ChildHExpandable (Gtk.Widget child)
+ {
+ if (child == dragSource)
+ child = DND.DragWidget;
+ else if (child is Placeholder)
+ return true;
+
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (child);
+ if (wrapper != null)
+ return wrapper.HExpandable;
+ else
+ return false;
+ }
+
+ protected bool ChildVExpandable (Gtk.Widget child)
+ {
+ if (child == dragSource)
+ child = DND.DragWidget;
+ else if (child is Placeholder)
+ return true;
+
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (child);
+ if (wrapper != null)
+ return wrapper.VExpandable;
+ else
+ return false;
+ }
+
+ // Note that this will be invalid/random for non-H/V-paired classes
+ protected Gtk.Orientation ContainerOrientation;
+
+ public override bool HExpandable {
+ get {
+ if (base.HExpandable)
+ return true;
+
+ // A horizontally-oriented container is HExpandable if any
+ // child is. A vertically-oriented container is HExpandable
+ // if *every* child is.
+
+ foreach (Gtk.Widget w in container) {
+ if (ChildHExpandable (w)) {
+ if (ContainerOrientation == Gtk.Orientation.Horizontal)
+ return true;
+ } else if (ContainerOrientation == Gtk.Orientation.Vertical)
+ return false;
+ }
+ return (ContainerOrientation == Gtk.Orientation.Vertical);
+ }
+ }
+
+ public override bool VExpandable {
+ get {
+ if (base.VExpandable)
+ return true;
+
+ // Opposite of above
+
+ foreach (Gtk.Widget w in container) {
+ if (ChildVExpandable (w)) {
+ if (ContainerOrientation == Gtk.Orientation.Vertical)
+ return true;
+ } else if (ContainerOrientation == Gtk.Orientation.Horizontal)
+ return false;
+ }
+ return (ContainerOrientation == Gtk.Orientation.Horizontal);
+ }
+ }
+
+ void ValidateChildNames (Gtk.Widget newWidget)
+ {
+ // newWidget is the widget which triggered the name check.
+ // It will be the last widget to check, so if there are
+ // name conflicts, the name to change to avoid the conflict
+ // will be the name of that widget.
+
+ if (!IsTopLevel) {
+ ParentWrapper.ValidateChildNames (newWidget);
+ return;
+ }
+
+ Hashtable names = new Hashtable ();
+
+ // Validate all names excluding the new widget
+ ValidateChildName (names, container, newWidget);
+
+ if (newWidget != null) {
+ // Now validate names in the new widget.
+ ValidateChildName (names, newWidget, null);
+ }
+ }
+
+ void ValidateChildName (Hashtable names, Gtk.Widget w, Gtk.Widget newWidget)
+ {
+ if (w == newWidget)
+ return;
+
+ if (names.Contains (w.Name)) {
+ // There is a widget with the same name. If the widget
+ // has a numeric suffix, just increase it.
+ string name; int idx;
+ WidgetUtils.ParseWidgetName (w.Name, out name, out idx);
+
+ string compName = idx != 0 ? name + idx : name;
+ while (names.Contains (compName)) {
+ idx++;
+ compName = name + idx;
+ }
+ w.Name = compName;
+ Widget ww = Widget.Lookup (w);
+ if (ww != null)
+ ww.InitializeName (compName);
+ else
+ w.Name = compName;
+
+ }
+
+ names [w.Name] = w;
+
+ if (w is Gtk.Container) {
+ foreach (Gtk.Widget cw in ((Gtk.Container)w).AllChildren)
+ ValidateChildName (names, cw, newWidget);
+ }
+ }
+
+ internal string GetValidWidgetName (Gtk.Widget widget)
+ {
+ // Get a valid name for a widget (a name that doesn't
+ // exist in the parent container.
+
+ if (!IsTopLevel)
+ return ParentWrapper.GetValidWidgetName (widget);
+
+ string name;
+ int idx;
+
+ WidgetUtils.ParseWidgetName (widget.Name, out name, out idx);
+
+ string compName = idx != 0 ? name + idx : name;
+
+ Gtk.Widget fw = FindWidget (compName, widget);
+ while (fw != null) {
+ idx++;
+ compName = name + idx;
+ fw = FindWidget (compName, widget);
+ }
+
+ return compName;
+ }
+
+ public Widget FindChild (string name)
+ {
+ Gtk.Widget w = FindWidget (name, null);
+ return Widget.Lookup (w);
+ }
+
+ Gtk.Widget FindWidget (string name, Gtk.Widget skipwidget)
+ {
+ if (Wrapped != skipwidget && Wrapped.Name == name)
+ return Wrapped;
+ else
+ return FindWidget ((Gtk.Container)Wrapped, name, skipwidget);
+ }
+
+ Gtk.Widget FindWidget (Gtk.Container parent, string name, Gtk.Widget skipwidget)
+ {
+ foreach (Gtk.Widget w in parent.AllChildren) {
+ if (w.Name == name && w != skipwidget)
+ return w;
+ if (w is Gtk.Container) {
+ Gtk.Widget res = FindWidget ((Gtk.Container)w, name, skipwidget);
+ if (res != null)
+ return res;
+ }
+ }
+ return null;
+ }
+
+ public override ObjectWrapper FindObjectByUndoId (string id)
+ {
+ ObjectWrapper c = base.FindObjectByUndoId (id);
+ if (c != null)
+ return c;
+
+ foreach (Gtk.Widget w in container.AllChildren) {
+ Widget ww = Widget.Lookup (w);
+ if (ww == null)
+ continue;
+ ObjectWrapper ow = ww.FindObjectByUndoId (id);
+ if (ow != null)
+ return ow;
+ }
+ return null;
+ }
+
+
+
+ public class ContainerChild : Stetic.ObjectWrapper
+ {
+ internal static void Register ()
+ {
+ // FIXME?
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ cc.Child.ChildNotified += ChildNotifyHandler;
+ cc.Child.ParentSet += OnParentSet;
+ }
+
+ [GLib.ConnectBefore]
+ void OnParentSet (object ob, Gtk.ParentSetArgs args)
+ {
+ // Dispose the wrapper if the child is removed from the parent
+ Gtk.Widget w = (Gtk.Widget)ob;
+ if (w.Parent == null) {
+ Dispose ();
+ w.ParentSet -= OnParentSet;
+ }
+ }
+
+ public override void Dispose ()
+ {
+ cc.Child.ChildNotified -= ChildNotifyHandler;
+ base.Dispose ();
+ }
+
+ protected virtual void ChildNotifyHandler (object obj, Gtk.ChildNotifiedArgs args)
+ {
+ ParamSpec pspec = new ParamSpec (args.Pspec);
+ EmitNotify (pspec.Name);
+ }
+
+ protected override void EmitNotify (string propertyName)
+ {
+ base.EmitNotify (propertyName);
+ ParentWrapper.Sync ();
+ ParentWrapper.NotifyChanged ();
+ }
+
+ Gtk.Container.ContainerChild cc {
+ get {
+ return (Gtk.Container.ContainerChild)Wrapped;
+ }
+ }
+
+ protected Stetic.Wrapper.Container ParentWrapper {
+ get {
+ return Stetic.Wrapper.Container.Lookup (cc.Parent);
+ }
+ }
+
+ public bool AutoSize {
+ get {
+ return ParentWrapper.AutoSize[cc.Child];
+ }
+ set {
+ ParentWrapper.AutoSize[cc.Child] = value;
+ EmitNotify ("AutoSize");
+ }
+ }
+
+ public override string Name { get; set; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Custom.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Custom.cs
new file mode 100644
index 0000000000..5f73164b8e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Custom.cs
@@ -0,0 +1,123 @@
+using System;
+using Gtk;
+
+namespace Stetic
+{
+ public class Custom : Gtk.DrawingArea
+ {
+ public Custom () {}
+
+ public Custom (IntPtr raw) : base (raw) {}
+
+ // from glade
+ static private string[] custom_bg_xpm = {
+ "8 8 4 1",
+ " c None",
+ ". c #BBBBBB",
+ "+ c #D6D6D6",
+ "@ c #6B5EFF",
+ ".+..+...",
+ "+..@@@..",
+ "..@...++",
+ "..@...++",
+ "+.@..+..",
+ ".++@@@..",
+ "..++....",
+ "..++...."
+ };
+
+ Gdk.Pixmap pixmap;
+
+ protected override void OnRealized ()
+ {
+ base.OnRealized ();
+
+ Gdk.Pixmap mask;
+ pixmap = Gdk.Pixmap.CreateFromXpmD (GdkWindow, out mask, new Gdk.Color (99, 99, 99), custom_bg_xpm);
+ }
+
+ string creationFunction, string1, string2;
+ int int1, int2;
+
+ public string CreationFunction {
+ get {
+ return creationFunction;
+ }
+ set {
+ creationFunction = value;
+ }
+ }
+
+ public string LastModificationTime {
+ get {
+ return null;
+ }
+ set {
+ ;
+ }
+ }
+
+ public string String1 {
+ get {
+ return string1;
+ }
+ set {
+ string1 = value;
+ }
+ }
+
+ public string String2 {
+ get {
+ return string2;
+ }
+ set {
+ string2 = value;
+ }
+ }
+
+ public int Int1 {
+ get {
+ return int1;
+ }
+ set {
+ int1 = value;
+ }
+ }
+
+ public int Int2 {
+ get {
+ return int2;
+ }
+ set {
+ int2 = value;
+ }
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose evt)
+ {
+ if (!IsDrawable)
+ return false;
+
+ int width, height;
+ GdkWindow.GetSize (out width, out height);
+
+ Gdk.GC light, dark;
+ light = Style.LightGC (StateType.Normal);
+ dark = Style.DarkGC (StateType.Normal);
+
+ // Looks like GdkWindow.SetBackPixmap doesn't work very well,
+ // so draw the pixmap manually.
+ light.Fill = Gdk.Fill.Tiled;
+ light.Tile = pixmap;
+ GdkWindow.DrawRectangle (light, true, 0, 0, width, height);
+ light.Fill = Gdk.Fill.Solid;
+
+ GdkWindow.DrawLine (light, 0, 0, width - 1, 0);
+ GdkWindow.DrawLine (light, 0, 0, 0, height - 1);
+ GdkWindow.DrawLine (dark, 0, height - 1, width - 1, height - 1);
+ GdkWindow.DrawLine (dark, width - 1, 0, width - 1, height - 1);
+
+ return base.OnExposeEvent (evt);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Dialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Dialog.cs
new file mode 100644
index 0000000000..82312cfd4d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Dialog.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Xml;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Dialog : Window {
+
+ Stetic.Wrapper.ButtonBox actionArea;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ actionArea = (ButtonBox)Container.Lookup (dialog.ActionArea);
+ actionArea.SetActionDialog (this);
+
+ if (!initialized) {
+ dialog.HasSeparator = false;
+ if (!initialized && dialog.VBox.Children.Length == 1) {
+ Container vbox = Container.Lookup (dialog.VBox);
+ Placeholder ph = vbox.AddPlaceholder ();
+ ph.SetSizeRequest (200, 200);
+ Buttons = 1;
+ }
+ } else
+ ButtonsChanged (actionArea);
+
+ actionArea.ContentsChanged += ButtonsChanged;
+ }
+
+ internal static new TopLevelDialog CreateInstance ( )
+ {
+ return new TopLevelDialog ();
+ }
+
+ public override void Dispose ( )
+ {
+ actionArea.ContentsChanged -= ButtonsChanged;
+ actionArea.SetActionDialog (null);
+ base.Dispose ();
+ }
+
+ protected override void ReadChildren (ObjectReader reader, XmlElement elem)
+ {
+ // Ignore changes in the buttons while loading
+ actionArea.ContentsChanged -= ButtonsChanged;
+ base.ReadChildren (reader, elem);
+ actionArea.ContentsChanged += ButtonsChanged;
+ actionArea.SetActionDialog (this);
+ }
+
+ TopLevelDialog dialog {
+ get {
+ return (TopLevelDialog) Wrapped;
+ }
+ }
+
+ public Gtk.HButtonBox ActionArea {
+ get { return dialog.ActionArea; }
+ }
+
+ public Gtk.VBox VBox
+ {
+ get { return dialog.VBox; }
+ }
+
+ public bool HasSeparator {
+ get { return dialog.HasSeparator; }
+ set { dialog.HasSeparator = value; EmitNotify ("HasSeparator"); }
+ }
+
+ public int Buttons
+ {
+ get {
+ return actionArea.Size - ExtraButtons;
+ }
+ set {
+ actionArea.Size = value + ExtraButtons;
+ EmitNotify ("Buttons");
+ }
+ }
+
+ int ExtraButtons {
+ get {
+ return helpButton == null ? 0 : 1;
+ }
+ }
+
+ Gtk.Button helpButton;
+
+ public bool HelpButton {
+ get {
+ return helpButton != null;
+ }
+ set {
+ if (HelpButton == value)
+ return;
+
+ if (value) {
+ helpButton = AddButton (Gtk.Stock.Help, Gtk.ResponseType.Help, false);
+ // Make it the first child, so that decreasing
+ // Buttons won't delete it
+ dialog.ActionArea.ReorderChild (helpButton, 0);
+ } else {
+ helpButton.Destroy ();
+ helpButton = null;
+ }
+
+ EmitNotify ("HelpButton");
+ }
+ }
+
+ // Check that a button is the Help button
+ bool ButtonIsHelp (Gtk.Button button)
+ {
+ return (button.UseStock &&
+ button.Label == Gtk.Stock.Help &&
+ dialog.ActionArea.GetChildSecondary (button));
+ }
+
+ Gtk.Button AddButton (string stockId, Gtk.ResponseType response, bool hasDefault)
+ {
+ Stetic.Wrapper.Button wrapper;
+ Gtk.Button button;
+
+ button = (Gtk.Button)Registry.NewInstance ("Gtk.Button", proj);
+ wrapper = (Stetic.Wrapper.Button) ObjectWrapper.Lookup (button);
+ if (stockId != null) {
+ wrapper.Type = Button.ButtonType.StockItem;
+ wrapper.StockId = stockId;
+ } else {
+ wrapper.Type = Button.ButtonType.TextOnly;
+ wrapper.Label = button.Name;
+ }
+ wrapper.ResponseId = (int)response;
+
+ Stetic.Wrapper.Container actionArea = Stetic.Wrapper.Container.Lookup (dialog.ActionArea);
+ actionArea.Add (button);
+
+ button.CanDefault = true;
+ wrapper.HasDefault = hasDefault;
+
+ if (stockId == Gtk.Stock.Help)
+ ((Gtk.ButtonBox)actionArea.Wrapped).SetChildSecondary (button, true);
+
+ return button;
+ }
+
+ void ButtonsChanged (Container container)
+ {
+ Gtk.Widget[] children = dialog.ActionArea.Children;
+
+ // If the user manually removes (or breaks) the Help button,
+ // uncheck the corresponding property
+ if (helpButton != null) {
+ if (Array.IndexOf (children, helpButton) == -1 ||
+ !ButtonIsHelp (helpButton)) {
+ helpButton = null;
+ EmitNotify ("HelpButton");
+ }
+ }
+
+ // If the user manually creates a Help button, set the property
+ if (helpButton == null) {
+ foreach (Gtk.Widget w in children) {
+ Gtk.Button button = w as Gtk.Button;
+ if (button != null && ButtonIsHelp (button)) {
+ helpButton = button;
+ dialog.ActionArea.ReorderChild (helpButton, 0);
+ EmitNotify ("HelpButton");
+ break;
+ }
+ }
+ }
+
+ // If the user removed all (non-Secondary) buttons, add back a
+ // single custom button
+ if (Buttons == 0)
+ Buttons = 1;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Entry.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Entry.cs
new file mode 100644
index 0000000000..64a9b068b2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Entry.cs
@@ -0,0 +1,15 @@
+using System;
+using System.ComponentModel;
+
+namespace Stetic.Wrapper
+{
+ public class Entry: Widget
+ {
+ [DefaultValue ('*')]
+ public char InvisibleChar {
+ get { return ((Gtk.Entry)Wrapped).InvisibleChar; }
+ set { ((Gtk.Entry)Wrapped).InvisibleChar = value; }
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Expander.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Expander.cs
new file mode 100644
index 0000000000..7ea5d73acf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Expander.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class Expander : Container {
+
+ public static Gtk.Expander CreateInstance ()
+ {
+ return new Gtk.Expander ("");
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized) {
+ expander.Label = expander.Name;
+ if (AllowPlaceholders)
+ AddPlaceholder ();
+ }
+ if (expander.LabelWidget != null)
+ ObjectWrapper.Create (proj, expander.LabelWidget, this);
+ }
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if ((string)GladeUtils.GetChildProperty (child_elem, "type", "") == "label_item") {
+ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ expander.LabelWidget = (Gtk.Widget)wrapper.Wrapped;
+ return wrapper;
+ } else
+ return base.ReadChild (reader, child_elem);
+ }
+
+ protected override XmlElement WriteChild (ObjectWriter writer, Widget wrapper)
+ {
+ XmlElement child_elem = base.WriteChild (writer, wrapper);
+ if (wrapper.Wrapped == expander.LabelWidget)
+ GladeUtils.SetChildProperty (child_elem, "type", "label_item");
+ return child_elem;
+ }
+
+ Gtk.Expander expander {
+ get {
+ return (Gtk.Expander)Wrapped;
+ }
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ if (oldChild == expander.LabelWidget)
+ expander.LabelWidget = newChild;
+ else
+ base.ReplaceChild (oldChild, newChild);
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (ClassDescriptor.WrappedTypeName.ToGlobalTypeRef (), new CodePrimitiveExpression (null));
+ }
+
+ protected override void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentVar, Widget wrapper)
+ {
+ if (wrapper.Wrapped == expander.LabelWidget) {
+ CodeExpression var = ctx.GenerateNewInstanceCode (wrapper);
+ CodeAssignStatement assign = new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ parentVar,
+ "LabelWidget"
+ ),
+ var
+ );
+ ctx.Statements.Add (assign);
+ } else
+ base.GenerateChildBuildCode (ctx, parentVar, wrapper);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Fixed.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Fixed.cs
new file mode 100644
index 0000000000..840c050dcc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Fixed.cs
@@ -0,0 +1,91 @@
+
+using System;
+
+namespace Stetic.Wrapper
+{
+ public class Fixed: Container
+ {
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ DND.DestSet (gtkfixed, true);
+ gtkfixed.DragDrop += FixedDragDrop;
+ gtkfixed.DragDataReceived += FixedDragDataReceived;
+ }
+
+ public override void Dispose ()
+ {
+ gtkfixed.DragDrop -= FixedDragDrop;
+ gtkfixed.DragDataReceived -= FixedDragDataReceived;
+ }
+
+ Gtk.Fixed gtkfixed {
+ get {
+ return (Gtk.Fixed)Wrapped;
+ }
+ }
+
+ protected override bool AllowPlaceholders {
+ get {
+ return false;
+ }
+ }
+
+ void FixedDragDrop (object obj, Gtk.DragDropArgs args)
+ {
+ Gtk.Widget w = DND.Drop (args.Context, gtkfixed, args.Time);
+ Widget ww = Widget.Lookup (w);
+ if (ww != null) {
+ gtkfixed.Put (w, args.X - DND.DragHotX, args.Y - DND.DragHotY);
+ NotifyChildAdded (w);
+ args.RetVal = true;
+ ww.Select ();
+ }
+ }
+
+ void FixedDragDataReceived (object obj, Gtk.DragDataReceivedArgs args)
+ {
+ Widget dropped = WidgetUtils.Paste (proj, args.SelectionData);
+ Gtk.Drag.Finish (args.Context, dropped != null, dropped != null, args.Time);
+ if (dropped != null) {
+ gtkfixed.Put (dropped.Wrapped, 0, 0);
+ NotifyChildAdded (dropped.Wrapped);
+ dropped.Select ();
+ }
+ }
+
+ int dragX, dragY;
+
+ protected override Gtk.Widget CreateDragSource (Gtk.Widget dragWidget)
+ {
+ Gtk.Fixed.FixedChild fc = (Gtk.Fixed.FixedChild) gtkfixed [dragWidget];
+ if (fc == null)
+ return null;
+
+ dragX = fc.X;
+ dragY = fc.Y;
+
+ gtkfixed.Remove (dragWidget);
+ gtkfixed.DragEnd += DragEnd;
+ return gtkfixed;
+ }
+
+ void DragEnd (object obj, Gtk.DragEndArgs args)
+ {
+ using (UndoManager.AtomicChange) {
+ gtkfixed.DragEnd -= DragEnd;
+ if (DND.DragWidget != null) {
+ DND.DragWidget.Unparent ();
+ gtkfixed.Put (DND.DragWidget, dragX, dragY);
+ NotifyChildAdded (DND.DragWidget);
+ Widget ww = Widget.Lookup (DND.DragWidget);
+ ww.Select ();
+ }
+ }
+ }
+
+ public class FixedChild : Container.ContainerChild {
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontButton.cs
new file mode 100644
index 0000000000..c005e23e4e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontButton.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public class FontButton : Widget {
+
+ public bool UseFont {
+ get {
+ return ((Gtk.FontButton)Wrapped).UseFont;
+ }
+ set {
+ Gtk.FontButton fb = (Gtk.FontButton)Wrapped;
+
+ fb.UseFont = value;
+
+ // Force it to update
+ fb.ShowSize = !fb.ShowSize;
+ fb.ShowSize = !fb.ShowSize;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontSelectionDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontSelectionDialog.cs
new file mode 100644
index 0000000000..f0b1cf000e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/FontSelectionDialog.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public class FontSelectionDialog : Dialog {
+
+ public Gtk.FontSelection FontSelection {
+ get {
+ Gtk.Dialog dialog = (Gtk.Dialog)Wrapped;
+
+ foreach (Gtk.Widget w in dialog.VBox) {
+ if (w is Gtk.FontSelection)
+ return (Gtk.FontSelection)w;
+ }
+ return null;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Frame.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Frame.cs
new file mode 100644
index 0000000000..4478c0ff36
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Frame.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class Frame : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized) {
+ frame.Label = "<b>" + frame.Name + "</b>";
+ ((Gtk.Label)frame.LabelWidget).UseMarkup = true;
+ frame.Shadow = Gtk.ShadowType.None;
+ if (AllowPlaceholders) {
+ Gtk.Alignment align = new Gtk.Alignment (0, 0, 1, 1);
+ align.LeftPadding = 12;
+ Container align_wrapper = (Container)ObjectWrapper.Create (proj, align, this);
+ align_wrapper.AddPlaceholder ();
+ ReplaceChild (frame.Child, (Gtk.Widget)align_wrapper.Wrapped, true);
+ }
+ }
+
+ if (frame.LabelWidget != null)
+ ObjectWrapper.Create (proj, frame.LabelWidget, this);
+ frame.AddNotification ("label-widget", LabelWidgetChanged);
+ }
+
+ void LabelWidgetChanged (object obj, GLib.NotifyArgs args)
+ {
+ if (!IsDisposed && frame.LabelWidget != null && !(frame.LabelWidget is Stetic.Placeholder))
+ ObjectWrapper.Create (proj, frame.LabelWidget, this);
+ }
+
+ Gtk.Frame frame {
+ get {
+ return (Gtk.Frame)Wrapped;
+ }
+ }
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if ((string)GladeUtils.GetChildProperty (child_elem, "type", "") == "label_item") {
+ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ frame.LabelWidget = (Gtk.Widget)wrapper.Wrapped;
+ return wrapper;
+ } else
+ return base.ReadChild (reader, child_elem);
+ }
+
+ protected override XmlElement WriteChild (ObjectWriter writer, Widget wrapper)
+ {
+ XmlElement child_elem = base.WriteChild (writer, wrapper);
+ if (wrapper.Wrapped == frame.LabelWidget)
+ GladeUtils.SetChildProperty (child_elem, "type", "label_item");
+ return child_elem;
+ }
+
+ protected override void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentVar, Widget wrapper)
+ {
+ if (wrapper.Wrapped == frame.LabelWidget) {
+ CodeExpression var = ctx.GenerateNewInstanceCode (wrapper);
+ CodeAssignStatement assign = new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ parentVar,
+ "LabelWidget"
+ ),
+ var
+ );
+ ctx.Statements.Add (assign);
+ } else
+ base.GenerateChildBuildCode (ctx, parentVar, wrapper);
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ if (oldChild == frame.LabelWidget)
+ frame.LabelWidget = newChild;
+ else
+ base.ReplaceChild (oldChild, newChild);
+ }
+
+ public override void Delete (Stetic.Placeholder ph)
+ {
+ using (UndoManager.AtomicChange) {
+ Delete ();
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScale.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScale.cs
new file mode 100644
index 0000000000..0af92c7a5f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScale.cs
@@ -0,0 +1,18 @@
+using System;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class HScale : Scale {
+
+ public static Gtk.HScale CreateInstance ()
+ {
+ return new Gtk.HScale (0.0, 100.0, 1.0);
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (ClassDescriptor.WrappedTypeName.ToGlobalTypeRef (), new CodePrimitiveExpression (null));
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScrollbar.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScrollbar.cs
new file mode 100644
index 0000000000..696ccee6b8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/HScrollbar.cs
@@ -0,0 +1,18 @@
+using System;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class HScrollbar : Range {
+
+ public static Gtk.HScrollbar CreateInstance ()
+ {
+ return new Gtk.HScrollbar (new Gtk.Adjustment (0.0, 0.0, 100.0, 1.0, 10.0, 10.0));
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (ClassDescriptor.WrappedTypeName.ToGlobalTypeRef (), new CodePrimitiveExpression (null));
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/IconView.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/IconView.cs
new file mode 100644
index 0000000000..592b005e54
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/IconView.cs
@@ -0,0 +1,39 @@
+// IconView.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (c) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+namespace Stetic.Wrapper
+{
+ public class IconView: Container
+ {
+ protected override bool AllowPlaceholders {
+ get {
+ return false;
+ }
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Image.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Image.cs
new file mode 100644
index 0000000000..befbc1c642
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Image.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Xml;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Image : Misc {
+
+ ImageInfo imageInfo;
+
+ public static Gtk.Image CreateInstance ()
+ {
+ return new Gtk.Image (Gtk.Stock.Execute, Gtk.IconSize.Dialog);
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ if (reader.Format == FileFormat.Glade) {
+ string file = (string)GladeUtils.ExtractProperty (elem, "pixbuf", "");
+ string stock = (string)GladeUtils.ExtractProperty (elem, "stock", "");
+ string iconSize = (string)GladeUtils.ExtractProperty (elem, "icon_size", "");
+ base.ReadProperties (reader, elem);
+
+ if (stock != null && stock.Length > 0) {
+ Pixbuf = ImageInfo.FromTheme (stock, (Gtk.IconSize) int.Parse (iconSize));
+ } else if (file != null && file != "") {
+ Pixbuf = ImageInfo.FromFile (file);
+ }
+ } else
+ base.ReadProperties (reader, elem);
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ if (imageInfo != null) {
+ if (writer.Format == FileFormat.Glade) {
+ // The generated pixbuf property doesn't have a valid value, it needs to be replaced.
+ GladeUtils.ExtractProperty (elem, "pixbuf", "");
+ switch (imageInfo.Source) {
+ case ImageSource.File:
+ GladeUtils.SetProperty (elem, "pixbuf", imageInfo.Name);
+ break;
+ case ImageSource.Theme:
+ GladeUtils.SetProperty (elem, "stock", imageInfo.Name);
+ GladeUtils.SetProperty (elem, "icon_size", ((int)imageInfo.ThemeIconSize).ToString ());
+ break;
+ default:
+ throw new System.NotSupportedException ("Image source not supported by Glade.");
+ }
+ }
+ }
+ return elem;
+ }
+
+ Gtk.Image image {
+ get {
+ return (Gtk.Image)Wrapped;
+ }
+ }
+
+ void BreakImage ()
+ {
+ image.IconSize = (int)Gtk.IconSize.Button;
+ image.Stock = Gtk.Stock.MissingImage;
+ }
+
+ public ImageInfo Pixbuf {
+ get { return imageInfo; }
+ set {
+ imageInfo = value;
+ if (imageInfo == null)
+ BreakImage ();
+ else
+ image.Pixbuf = imageInfo.GetImage (Project);
+ EmitNotify ("Pixbuf");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ImageMenuItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ImageMenuItem.cs
new file mode 100644
index 0000000000..24cfd01465
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ImageMenuItem.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Xml;
+
+namespace Stetic.Wrapper {
+
+ public class ImageMenuItem : MenuItem {
+
+ public static new Gtk.ImageMenuItem CreateInstance ()
+ {
+ // Use the ctor that will create an AccelLabel
+ return new Gtk.ImageMenuItem ("");
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ Gtk.StockItem stockItem = Gtk.StockItem.Zero;
+ bool use_stock = (bool)GladeUtils.ExtractProperty (elem, "use_stock", false);
+ if (use_stock) {
+ string label = (string)GladeUtils.GetProperty (elem, "label", "");
+ stockItem = Gtk.Stock.Lookup (label);
+ if (stockItem.Label != null)
+ GladeUtils.ExtractProperty (elem, "label", "");
+ }
+ base.ReadProperties (reader, elem);
+
+ if (stockItem.StockId != null)
+ Image = "stock:" + stockItem.StockId;
+ if (stockItem.Keyval != 0)
+ Accelerator = Gtk.Accelerator.Name (stockItem.Keyval, stockItem.Modifier);
+ }
+
+ string image;
+
+ public string Image {
+ get {
+ return image;
+ }
+ set {
+ image = value;
+
+ Gtk.Widget icon;
+ Gtk.StockItem stockItem = Gtk.StockItem.Zero;
+
+ if (image.StartsWith ("stock:"))
+ stockItem = Gtk.Stock.Lookup (image.Substring (6));
+
+ if (stockItem.StockId != null) {
+ icon = new Gtk.Image (stockItem.StockId, Gtk.IconSize.Menu);
+ Label = stockItem.Label;
+ UseUnderline = true;
+ } else if (image.StartsWith ("file:"))
+ icon = new Gtk.Image (image.Substring (5));
+ else
+ icon = new Gtk.Image (WidgetUtils.MissingIcon);
+
+ ((Gtk.ImageMenuItem)Wrapped).Image = icon;
+
+ EmitNotify ("Image");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Label.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Label.cs
new file mode 100644
index 0000000000..e12944c6f1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Label.cs
@@ -0,0 +1,49 @@
+using System;
+using System.CodeDom;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Label : Misc {
+
+ public Label () {}
+
+ string mnem;
+ public string MnemonicWidget {
+ get {
+ return mnem;
+ }
+ set {
+ mnem = value;
+ }
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name != "MnemonicWidget")
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+
+ internal protected override void GeneratePostBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ if (mnem != null) {
+ Widget targetWidget = GetTopLevel ().FindChild (mnem);
+ if (targetWidget != null) {
+ CodeExpression memVar = ctx.WidgetMap.GetWidgetExp (targetWidget);
+ if (memVar != null) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ var,
+ "MnemonicWidget"
+ ),
+ memVar
+ )
+ );
+ }
+ }
+ }
+ base.GeneratePostBuildCode (ctx, var);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuBar.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuBar.cs
new file mode 100644
index 0000000000..fec2f29509
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuBar.cs
@@ -0,0 +1,261 @@
+
+using System;
+using System.CodeDom;
+using System.Xml;
+using System.Collections;
+using Stetic.Editor;
+
+namespace Stetic.Wrapper
+{
+ public class MenuBar: Container
+ {
+ ActionTree actionTree;
+ XmlElement menuInfo;
+ bool treeChanged;
+
+ public MenuBar()
+ {
+ }
+
+ public override void Dispose ()
+ {
+ DisposeTree ();
+ base.Dispose ();
+ }
+
+ public static Gtk.MenuBar CreateInstance ()
+ {
+ return new ActionMenuBar ();
+ }
+
+ protected override bool AllowPlaceholders {
+ get { return false; }
+ }
+
+ ActionMenuBar menu {
+ get { return (ActionMenuBar) Wrapped; }
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ CreateTree ();
+ }
+
+ internal protected override void OnSelected ()
+ {
+ Loading = true;
+ menu.ShowInsertPlaceholder = true;
+ Loading = false;
+ }
+
+ internal protected override void OnUnselected ()
+ {
+ base.OnUnselected ();
+ Loading = true;
+ menu.ShowInsertPlaceholder = false;
+ menu.Unselect ();
+ Loading = false;
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ if (menuInfo != null)
+ elem.AppendChild (writer.XmlDocument.ImportNode (menuInfo, true));
+ else
+ elem.AppendChild (actionTree.Write (writer.XmlDocument, writer.Format));
+ return elem;
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ base.ReadProperties (reader, elem);
+ menuInfo = elem ["node"];
+ treeChanged = false;
+ }
+
+ public override object GetUndoDiff ()
+ {
+ XmlElement oldElem = treeChanged ? UndoManager.GetObjectStatus (this) ["node"] : null;
+ if (oldElem != null)
+ oldElem = (XmlElement) oldElem.CloneNode (true);
+
+ treeChanged = false;
+ object baseDiff = base.GetUndoDiff ();
+
+ if (oldElem != null) {
+ XmlElement newElem = UndoManager.GetObjectStatus (this) ["node"];
+ if (newElem != null && oldElem.OuterXml == newElem.OuterXml)
+ oldElem = null;
+ }
+
+ if (baseDiff == null && oldElem == null)
+ return null;
+ else {
+ object stat = menu.SaveStatus ();
+ return new object[] { baseDiff, oldElem, stat };
+ }
+ }
+
+ public override object ApplyUndoRedoDiff (object diff)
+ {
+ object[] data = (object[]) diff;
+ object retBaseDiff;
+ XmlElement oldNode = null;
+
+ if (actionTree != null) {
+ XmlElement status = UndoManager.GetObjectStatus (this);
+ oldNode = status ["node"];
+ if (oldNode != null)
+ oldNode = (XmlElement) oldNode.CloneNode (true);
+ }
+ object oldStat = menu.SaveStatus ();
+
+ if (data [0] != null)
+ retBaseDiff = base.ApplyUndoRedoDiff (data [0]);
+ else
+ retBaseDiff = null;
+
+ XmlElement xdiff = (XmlElement) data [1];
+
+ if (xdiff != null) {
+ XmlElement status = UndoManager.GetObjectStatus (this);
+ XmlElement prevNode = status ["node"];
+ if (prevNode != null)
+ status.RemoveChild (prevNode);
+ status.AppendChild (xdiff);
+
+ if (actionTree != null) {
+ Loading = true;
+ menu.OpenSubmenu = null;
+ DisposeTree ();
+ CreateTree ();
+ actionTree.Read (this, xdiff);
+ menu.FillMenu (actionTree);
+ Loading = false;
+ } else
+ menuInfo = xdiff;
+ }
+
+ // Restore the status after all menu structure has been properly built
+ GLib.Timeout.Add (50, delegate {
+ menu.RestoreStatus (data[2]);
+ return false;
+ });
+
+ return new object [] { retBaseDiff, oldNode, oldStat };
+ }
+
+ protected override void OnNameChanged (WidgetNameChangedArgs args)
+ {
+ base.OnNameChanged (args);
+ if (actionTree != null)
+ actionTree.Name = Name;
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ BuildTree ();
+ actionTree.Name = Name;
+ CodeExpression exp = GenerateUiManagerElement (ctx, actionTree);
+ if (exp != null)
+ return new CodeCastExpression (typeof(Gtk.MenuBar).ToGlobalTypeRef (), exp);
+ else
+ return base.GenerateObjectCreation (ctx);
+ }
+
+ internal protected override void OnDesignerAttach (IDesignArea designer)
+ {
+ base.OnDesignerAttach (designer);
+ BuildTree ();
+ Loading = true;
+ menu.FillMenu (actionTree);
+ Loading = false;
+
+ if (LocalActionGroups.Count == 0)
+ LocalActionGroups.Add (new ActionGroup ("Default"));
+ }
+
+ void BuildTree ()
+ {
+ if (menuInfo != null) {
+ DisposeTree ();
+ CreateTree ();
+ actionTree.Read (this, menuInfo);
+ menuInfo = null;
+ }
+ }
+
+ void CreateTree ()
+ {
+ actionTree = new ActionTree ();
+ actionTree.Name = Name;
+ actionTree.Type = Gtk.UIManagerItemType.Menubar;
+ actionTree.Changed += OnTreeChanged;
+ }
+
+ void DisposeTree ()
+ {
+ if (actionTree != null) {
+ actionTree.Dispose ();
+ actionTree.Changed -= OnTreeChanged;
+ actionTree = null;
+ }
+ }
+
+ void OnTreeChanged (object s, EventArgs a)
+ {
+ treeChanged = true;
+ NotifyChanged ();
+ }
+ }
+
+ class CustomMenuBarItem: Gtk.MenuItem
+ {
+ public ActionMenuItem ActionMenuItem;
+// public ActionTreeNode Node;
+ }
+
+ public class ActionPaletteItem: Gtk.HBox
+ {
+ ActionTreeNode node;
+ bool disposeNode;
+
+ public ActionPaletteItem (Gtk.UIManagerItemType type, string name, Action action)
+ : this (new ActionTreeNode (type, name, action))
+ {
+ disposeNode = true;
+ }
+
+ public ActionPaletteItem (ActionTreeNode node)
+ {
+ this.node = node;
+ Spacing = 3;
+ if (node.Type == Gtk.UIManagerItemType.Menu) {
+ PackStart (new Gtk.Label ("Menu"), true, true, 0);
+ } else if (node.Action != null && node.Action.GtkAction != null) {
+ if (node.Action.GtkAction.StockId != null)
+ PackStart (node.Action.CreateIcon (Gtk.IconSize.Menu), true, true, 0);
+ PackStart (new Gtk.Label (node.Action.GtkAction.Label), true, true, 0);
+ } else if (node.Type == Gtk.UIManagerItemType.Separator) {
+ PackStart (new Gtk.Label ("Separator"), true, true, 0);
+ } else {
+ PackStart (new Gtk.Label ("Empty Action"), true, true, 0);
+ }
+ ShowAll ();
+ }
+
+ public ActionTreeNode Node {
+ get { return node; }
+ }
+
+ public override void Dispose ()
+ {
+ if (disposeNode)
+ node.Dispose ();
+ base.Dispose ();
+ }
+
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuItem.cs
new file mode 100644
index 0000000000..4321ce602e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MenuItem.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Xml;
+
+namespace Stetic.Wrapper {
+
+ public class MenuItem : Container {
+
+ public static Gtk.MenuItem CreateInstance ()
+ {
+ // Use the ctor that will create an AccelLabel
+ return new Gtk.MenuItem ("");
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ }
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ menuitem.Submenu = (Gtk.Menu)wrapper.Wrapped;
+ return wrapper;
+ }
+
+ Gtk.MenuItem menuitem {
+ get {
+ return (Gtk.MenuItem)Wrapped;
+ }
+ }
+
+ Gtk.Label label {
+ get {
+ Gtk.AccelLabel label = menuitem.Child as Gtk.AccelLabel;
+ if (label != null)
+ return label;
+
+ if (menuitem.Child != null)
+ menuitem.Child.Destroy ();
+
+ label = new Gtk.AccelLabel ("");
+ label.MnemonicWidget = menuitem;
+ label.AccelWidget = menuitem;
+ label.Xalign = 0.0f;
+ label.Show ();
+ menuitem.Add (label);
+
+ return label;
+ }
+ }
+
+ public bool HasSubmenu {
+ get {
+ return menuitem.Submenu != null;
+ }
+ }
+
+ string labelText;
+
+ public string Label {
+ get {
+ return labelText;
+ }
+ set {
+ label.LabelProp = labelText = value;
+ EmitNotify ("Label");
+ }
+ }
+
+ public bool UseUnderline {
+ get {
+ return label.UseUnderline;
+ }
+ set {
+ label.UseUnderline = value;
+ EmitNotify ("UseUnderline");
+ }
+ }
+
+ Gtk.AccelGroup accelGroup;
+ string accelerator;
+ public string Accelerator {
+ get {
+ return accelerator;
+ }
+ set {
+ uint key;
+ Gdk.ModifierType mods;
+
+ if (accelGroup != null && accelerator != null) {
+ Gtk.Accelerator.Parse (accelerator, out key, out mods);
+ menuitem.RemoveAccelerator (accelGroup, key, mods);
+ }
+
+ accelerator = value;
+
+ if (accelerator != null) {
+ if (accelGroup == null)
+ accelGroup = new Gtk.AccelGroup ();
+
+ Gtk.Accelerator.Parse (accelerator, out key, out mods);
+ menuitem.AddAccelerator ("activate", accelGroup, key, mods,
+ Gtk.AccelFlags.Visible);
+ }
+
+ EmitNotify ("Accelerator");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MessageDialog.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MessageDialog.cs
new file mode 100644
index 0000000000..805b02932c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/MessageDialog.cs
@@ -0,0 +1,141 @@
+using System;
+
+namespace Stetic {
+
+ public class MessageDialog : Gtk.Dialog {
+
+ public MessageDialog ()
+ {
+ Resizable = false;
+ HasSeparator = false;
+ BorderWidth = 12;
+
+ label = new Gtk.Label ();
+ label.LineWrap = true;
+ label.Selectable = true;
+ label.UseMarkup = true;
+ label.SetAlignment (0.0f, 0.0f);
+
+ secondaryLabel = new Gtk.Label ();
+ secondaryLabel.LineWrap = true;
+ secondaryLabel.Selectable = true;
+ secondaryLabel.UseMarkup = true;
+ secondaryLabel.SetAlignment (0.0f, 0.0f);
+
+ icon = new Gtk.Image (Gtk.Stock.DialogInfo, Gtk.IconSize.Dialog);
+ icon.SetAlignment (0.5f, 0.0f);
+
+ Gtk.StockItem item = Gtk.Stock.Lookup (icon.Stock);
+ Title = item.Label;
+
+ Gtk.HBox hbox = new Gtk.HBox (false, 12);
+ Gtk.VBox vbox = new Gtk.VBox (false, 12);
+
+ vbox.PackStart (label, false, false, 0);
+ vbox.PackStart (secondaryLabel, true, true, 0);
+
+ hbox.PackStart (icon, false, false, 0);
+ hbox.PackStart (vbox, true, true, 0);
+
+ VBox.PackStart (hbox, false, false, 0);
+ hbox.ShowAll ();
+
+ Buttons = Gtk.ButtonsType.OkCancel;
+ }
+
+ Gtk.Label label, secondaryLabel;
+ Gtk.Image icon;
+
+ public Gtk.MessageType MessageType {
+ get {
+ if (icon.Stock == Gtk.Stock.DialogInfo)
+ return Gtk.MessageType.Info;
+ else if (icon.Stock == Gtk.Stock.DialogQuestion)
+ return Gtk.MessageType.Question;
+ else if (icon.Stock == Gtk.Stock.DialogWarning)
+ return Gtk.MessageType.Warning;
+ else
+ return Gtk.MessageType.Error;
+ }
+ set {
+ Gtk.StockItem item = Gtk.Stock.Lookup (icon.Stock);
+ bool setTitle = (Title == "") || (Title == item.Label);
+
+ if (value == Gtk.MessageType.Info)
+ icon.Stock = Gtk.Stock.DialogInfo;
+ else if (value == Gtk.MessageType.Question)
+ icon.Stock = Gtk.Stock.DialogQuestion;
+ else if (value == Gtk.MessageType.Warning)
+ icon.Stock = Gtk.Stock.DialogWarning;
+ else
+ icon.Stock = Gtk.Stock.DialogError;
+
+ if (setTitle) {
+ item = Gtk.Stock.Lookup (icon.Stock);
+ Title = item.Label;
+ }
+ }
+ }
+
+ public string primaryText;
+ public string PrimaryText {
+ get {
+ return primaryText;
+ }
+ set {
+ primaryText = value;
+ label.Markup = "<b>" + value + "</b>";
+ }
+ }
+
+ public string SecondaryText {
+ get {
+ return secondaryLabel.Text;
+ }
+ set {
+ secondaryLabel.Markup = value;
+ }
+ }
+
+ Gtk.ButtonsType buttons;
+ public Gtk.ButtonsType Buttons {
+ get {
+ return buttons;
+ }
+ set {
+ Gtk.Widget[] oldButtons = ActionArea.Children;
+ foreach (Gtk.Widget w in oldButtons)
+ ActionArea.Remove (w);
+
+ buttons = value;
+ switch (buttons) {
+ case Gtk.ButtonsType.None:
+ // nothing
+ break;
+
+ case Gtk.ButtonsType.Ok:
+ AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+ break;
+
+ case Gtk.ButtonsType.Close:
+ AddButton (Gtk.Stock.Close, Gtk.ResponseType.Close);
+ break;
+
+ case Gtk.ButtonsType.Cancel:
+ AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+ break;
+
+ case Gtk.ButtonsType.YesNo:
+ AddButton (Gtk.Stock.No, Gtk.ResponseType.No);
+ AddButton (Gtk.Stock.Yes, Gtk.ResponseType.Yes);
+ break;
+
+ case Gtk.ButtonsType.OkCancel:
+ AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+ AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Misc.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Misc.cs
new file mode 100644
index 0000000000..44624a73d6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Misc.cs
@@ -0,0 +1,35 @@
+
+using System;
+
+namespace Stetic.Wrapper
+{
+ public class Misc: Widget
+ {
+ public bool AlignLeft {
+ get {
+ return ((Gtk.Misc)Wrapped).Xalign == 0;
+ }
+ set {
+ ((Gtk.Misc)Wrapped).Xalign = 0;
+ }
+ }
+
+ public bool AlignRight {
+ get {
+ return ((Gtk.Misc)Wrapped).Xalign == 1;
+ }
+ set {
+ ((Gtk.Misc)Wrapped).Xalign = 1;
+ }
+ }
+
+ public bool AlignCenter {
+ get {
+ return ((Gtk.Misc)Wrapped).Xalign == 0.5f;
+ }
+ set {
+ ((Gtk.Misc)Wrapped).Xalign = 0.5f;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Notebook.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Notebook.cs
new file mode 100644
index 0000000000..978aae7502
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Notebook.cs
@@ -0,0 +1,269 @@
+using System;
+using System.CodeDom;
+using System.Collections;
+using System.Xml;
+
+namespace Stetic.Wrapper {
+
+ public class Notebook : Container {
+
+ ArrayList tabs = new ArrayList ();
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized && AllowPlaceholders) {
+ if (notebook.Children.Length != 0) {
+ // Remove the dummy page Container.Wrap added
+ notebook.Remove (notebook.Children[0]);
+ }
+ InsertPage (0);
+ }
+ notebook.SwitchPage += OnPageChanged;
+ }
+
+ public override void Dispose ()
+ {
+ notebook.SwitchPage -= OnPageChanged;
+ base.Dispose ();
+ }
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if ((string)GladeUtils.GetChildProperty (child_elem, "type", "") == "tab") {
+ ObjectWrapper wrapper = reader.ReadObject (child_elem["widget"], this);
+ Gtk.Widget widget = (Gtk.Widget)wrapper.Wrapped;
+ notebook.SetTabLabel (notebook.GetNthPage (notebook.NPages - 1), widget);
+ tabs.Add (widget);
+ return wrapper;
+ } else
+ return base.ReadChild (reader, child_elem);
+ }
+
+ protected override XmlElement WriteChild (ObjectWriter writer, Widget wrapper)
+ {
+ XmlElement child_elem = base.WriteChild (writer, wrapper);
+ if (tabs.Contains (wrapper.Wrapped))
+ GladeUtils.SetChildProperty (child_elem, "type", "tab");
+ return child_elem;
+ }
+ public override void Read (ObjectReader reader, XmlElement element)
+ {
+ object cp = GladeUtils.ExtractProperty (element, "CurrentPage", 0);
+ base.Read (reader, element);
+ notebook.CurrentPage = (int) cp;
+ }
+
+ protected override void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentExp, Widget wrapper)
+ {
+ Gtk.Widget child = (Gtk.Widget) wrapper.Wrapped;
+
+ if (notebook.PageNum (child) == -1) {
+ // It's a tab
+
+ ctx.Statements.Add (new CodeCommentStatement ("Notebook tab"));
+ Gtk.Widget page = null;
+ CodeExpression pageVar;
+
+ // Look for the page widget contained in this tab
+ for (int n=0; n < notebook.NPages; n++) {
+ if (notebook.GetTabLabel (notebook.GetNthPage (n)) == child) {
+ page = notebook.GetNthPage (n);
+ break;
+ }
+ }
+
+ // If the page contains a placeholder, generate a dummy page
+ if (page is Stetic.Placeholder) {
+ CodeVariableDeclarationStatement dvar = new CodeVariableDeclarationStatement (
+ "Gtk.Label".ToGlobalTypeRef (),
+ ctx.NewId (),
+ new CodeObjectCreateExpression ("Gtk.Label".ToGlobalTypeRef ())
+ );
+ ctx.Statements.Add (dvar);
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ new CodeVariableReferenceExpression (dvar.Name),
+ "Visible"
+ ),
+ new CodePrimitiveExpression (true)
+ )
+ );
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ parentExp,
+ "Add",
+ new CodeVariableReferenceExpression (dvar.Name)
+ )
+ );
+ pageVar = new CodeVariableReferenceExpression (dvar.Name);
+ } else
+ pageVar = ctx.WidgetMap.GetWidgetExp (page);
+
+ // Generate code for the tab
+ CodeExpression var = ctx.GenerateNewInstanceCode (wrapper);
+
+ // Assign the tab to the page
+ CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (
+ parentExp,
+ "SetTabLabel",
+ pageVar,
+ var
+ );
+ ctx.Statements.Add (invoke);
+
+ // Workaround for GTK bug. ShowAll is not propagated to tab labels.
+ invoke = new CodeMethodInvokeExpression (
+ var,
+ "ShowAll"
+ );
+ ctx.Statements.Add (invoke);
+ } else
+ base.GenerateChildBuildCode (ctx, parentExp, wrapper);
+ }
+
+
+ private Gtk.Notebook notebook {
+ get {
+ return (Gtk.Notebook)Wrapped;
+ }
+ }
+
+ public override void Select (Gtk.Widget widget)
+ {
+ if (widget != null) {
+ int index = tabs.IndexOf (widget);
+ if (index != -1 && index != notebook.CurrentPage)
+ notebook.CurrentPage = index;
+ }
+ base.Select (widget);
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ int index = tabs.IndexOf (oldChild);
+ if (index != -1) {
+ tabs[index] = newChild;
+ Gtk.Widget page = notebook.GetNthPage (index);
+ notebook.SetTabLabel (page, newChild);
+ } else {
+ Gtk.Widget tab = notebook.GetTabLabel (oldChild);
+ int current = notebook.CurrentPage;
+ int oldPageNum = ((Gtk.Notebook.NotebookChild)notebook [oldChild]).Position;
+ base.ReplaceChild (oldChild, newChild);
+ // Get the widget again because it may have changed (for example, if it is a text view
+ // and has the ShowScrollbars option set.
+ newChild = notebook.GetNthPage (oldPageNum);
+ notebook.CurrentPage = current;
+ notebook.SetTabLabel (newChild, tab);
+ Widget ww = Widget.Lookup (tab);
+ if (ww != null)
+ ww.RequiresUndoStatusUpdate = true;
+ }
+ }
+
+ int InsertPage (int position)
+ {
+ Gtk.Label label = (Gtk.Label)Registry.NewInstance ("Gtk.Label", proj);
+ label.LabelProp = "page" + (notebook.NPages + 1).ToString ();
+ tabs.Insert (position, label);
+
+ Placeholder ph = CreatePlaceholder ();
+ int i = notebook.InsertPage (ph, label, position);
+ NotifyChildAdded (ph);
+ return i;
+ }
+
+ internal void PreviousPage ()
+ {
+ notebook.PrevPage ();
+ }
+
+ internal bool CheckPreviousPage ()
+ {
+ return notebook.CurrentPage > 0;
+ }
+
+ internal void NextPage ()
+ {
+ notebook.NextPage ();
+ }
+
+ internal bool CheckNextPage ()
+ {
+ return notebook.CurrentPage < notebook.NPages - 1;
+ }
+
+ internal void DeletePage ()
+ {
+ tabs.RemoveAt (notebook.CurrentPage);
+ notebook.RemovePage (notebook.CurrentPage);
+ }
+
+ internal bool CheckDeletePage ()
+ {
+ return notebook.NPages > 0;
+ }
+
+ internal void SwapPrevious ()
+ {
+ object ob = tabs [notebook.CurrentPage];
+ tabs [notebook.CurrentPage] = tabs [notebook.CurrentPage - 1];
+ tabs [notebook.CurrentPage - 1] = ob;
+
+ Gtk.Widget cp = notebook.GetNthPage (notebook.CurrentPage);
+ notebook.ReorderChild (cp, notebook.CurrentPage - 1);
+ }
+
+ internal void SwapNext ()
+ {
+ object ob = tabs [notebook.CurrentPage];
+ tabs [notebook.CurrentPage] = tabs [notebook.CurrentPage + 1];
+ tabs [notebook.CurrentPage + 1] = ob;
+
+ Gtk.Widget cp = notebook.GetNthPage (notebook.CurrentPage);
+ notebook.ReorderChild (cp, notebook.CurrentPage + 1);
+ }
+
+ internal void InsertBefore ()
+ {
+ notebook.CurrentPage = InsertPage (notebook.CurrentPage);
+ }
+
+ internal bool CheckInsertBefore ()
+ {
+ return notebook.NPages > 0;
+ }
+
+ internal void InsertAfter ()
+ {
+ notebook.CurrentPage = InsertPage (notebook.CurrentPage + 1);
+ }
+
+ public override bool HExpandable {
+ get {
+ foreach (Gtk.Widget w in notebook) {
+ if (ChildHExpandable (w))
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public override bool VExpandable {
+ get {
+ foreach (Gtk.Widget w in notebook) {
+ if (ChildVExpandable (w))
+ return true;
+ }
+ return false;
+ }
+ }
+
+ void OnPageChanged (object s, Gtk.SwitchPageArgs args)
+ {
+ EmitNotify ("CurrentPage");
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Object.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Object.cs
new file mode 100644
index 0000000000..4d8954c426
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Object.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+ public abstract class Object : Stetic.ObjectWrapper {
+
+ public override void Dispose ()
+ {
+ if (Wrapped == null)
+ return;
+ ((GLib.Object)Wrapped).RemoveNotification (NotifyHandler);
+ base.Dispose ();
+ }
+
+ internal protected override void OnDesignerAttach (IDesignArea designer)
+ {
+ base.OnDesignerAttach (designer);
+ ((GLib.Object)Wrapped).AddNotification (NotifyHandler);
+ }
+
+ internal protected override void OnDesignerDetach (IDesignArea designer)
+ {
+ base.OnDesignerDetach (designer);
+ ((GLib.Object)Wrapped).RemoveNotification (NotifyHandler);
+ }
+
+ public static Object Lookup (GLib.Object obj)
+ {
+ return Stetic.ObjectWrapper.Lookup (obj) as Stetic.Wrapper.Object;
+ }
+
+ void NotifyHandler (object obj, GLib.NotifyArgs args)
+ {
+ if (Loading)
+ return;
+
+ // Translate gtk names into descriptor names.
+ foreach (ItemGroup group in ClassDescriptor.ItemGroups) {
+ foreach (ItemDescriptor item in group) {
+ TypedPropertyDescriptor prop = item as TypedPropertyDescriptor;
+ if (prop != null && prop.GladeName == args.Property) {
+ EmitNotify (prop.Name);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/OptionMenu.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/OptionMenu.cs
new file mode 100644
index 0000000000..8234c595a1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/OptionMenu.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections;
+using System.Xml;
+
+// Don't warn that OptionMenu is deprecated. We know that.
+#pragma warning disable 612
+
+namespace Stetic.Wrapper {
+
+ public class OptionMenu : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ Gtk.OptionMenu omenu = (Gtk.OptionMenu)obj;
+ if (omenu.Menu == null) {
+ Gtk.Menu menu = new Gtk.Menu ();
+ menu.Show ();
+ omenu.Menu = menu;
+ }
+
+ base.Wrap (obj, initialized);
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ int history = (int)GladeUtils.ExtractProperty (elem, "history", -1);
+ base.ReadProperties (reader, elem);
+
+ // Fiddle with things to make the optionmenu resize itself correctly
+ Gtk.Widget menu = optionmenu.Menu;
+ optionmenu.Menu = new Gtk.Menu ();
+ optionmenu.Menu = menu;
+
+ if (history != -1)
+ Active = history;
+ else
+ Active = 0;
+ }
+
+ // Some versions of glade call the menu an internal child, some don't
+
+ protected override ObjectWrapper ReadInternalChild (ObjectReader reader, XmlElement child_elem)
+ {
+ if (child_elem.GetAttribute ("internal-child") == "menu")
+ return ReadChild (reader, child_elem);
+ else
+ return base.ReadInternalChild (reader, child_elem);
+ }
+
+ protected override ObjectWrapper ReadChild (ObjectReader reader, XmlElement child_elem)
+ {
+ Widget wrapper = Stetic.Wrapper.Widget.Lookup (optionmenu.Menu);
+ reader.ReadExistingObject (wrapper, child_elem["widget"]);
+ return wrapper;
+ }
+
+ public override IEnumerable GladeChildren {
+ get {
+ return new Gtk.Widget[] { optionmenu.Menu };
+ }
+ }
+
+ Gtk.OptionMenu optionmenu {
+ get {
+ return (Gtk.OptionMenu)Wrapped;
+ }
+ }
+
+ public int Active {
+ get {
+ return optionmenu.History;
+ }
+ set {
+ optionmenu.SetHistory ((uint)value);
+ EmitNotify ("Active");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Paned.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Paned.cs
new file mode 100644
index 0000000000..477923a27c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Paned.cs
@@ -0,0 +1,73 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public class Paned : Container {
+
+ int position;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized && AllowPlaceholders) {
+ Placeholder ph = CreatePlaceholder ();
+ paned.Pack1 (ph, true, false);
+ NotifyChildAdded (ph);
+ ph = CreatePlaceholder ();
+ paned.Pack2 (ph, true, false);
+ NotifyChildAdded (ph);
+ }
+ position = paned.Position;
+ paned.Realized += PanedRealized;
+ }
+
+ void PanedRealized (object sender, EventArgs e)
+ {
+ // The position may be reset while realizing the object, so
+ // we set it now here. See bug #542227. This seems to be Windows only.
+ bool old = Loading;
+ Loading = true;
+ paned.Position = position;
+ Loading = old;
+ }
+
+ public override void Dispose ()
+ {
+ base.Dispose ();
+ paned.Realized -= PanedRealized;
+ }
+
+ protected Gtk.Paned paned {
+ get {
+ return (Gtk.Paned)Wrapped;
+ }
+ }
+
+ public int Position {
+ get {
+ return paned.Position;
+ }
+ set {
+ position = value;
+ paned.Position = value;
+ }
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ if (oldChild == paned.Child1) {
+ paned.Remove (oldChild);
+ paned.Add1 (newChild);
+ } else if (oldChild == paned.Child2) {
+ paned.Remove (oldChild);
+ paned.Add2 (newChild);
+ }
+ NotifyChildAdded (newChild);
+ }
+
+ public override void Delete (Stetic.Placeholder ph)
+ {
+ // Don't allow deleting placeholders
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioActionGroupManager.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioActionGroupManager.cs
new file mode 100644
index 0000000000..0f67944ce4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioActionGroupManager.cs
@@ -0,0 +1,144 @@
+
+using System;
+using System.Collections;
+using System.CodeDom;
+
+namespace Stetic.Wrapper
+{
+ public class RadioActionGroupManager: IRadioGroupManager
+ {
+ public event GroupsChangedDelegate GroupsChanged;
+ Hashtable actions = new Hashtable ();
+ ArrayList groups = new ArrayList ();
+
+ public IEnumerable GroupNames {
+ get {
+ foreach (string grp in groups)
+ yield return grp;
+ }
+ }
+
+ public void Rename (string oldName, string newName)
+ {
+ int i = groups.IndexOf (oldName);
+ if (i == -1)
+ return;
+
+ groups [i] = newName;
+
+ ArrayList list = new ArrayList ();
+ foreach (Action a in FindActionsInGroup (oldName))
+ list.Add (a);
+
+ foreach (Action a in list)
+ actions [a] = newName;
+
+ EmitGroupsChanged ();
+ }
+
+ public void Add (string name)
+ {
+ groups.Add (name);
+ EmitGroupsChanged ();
+ }
+
+ public RadioGroup FindGroup (string name)
+ {
+ for (int i = 0; i < groups.Count; i++) {
+ RadioGroup group = groups[i] as RadioGroup;
+ if (group.Name == name)
+ return group;
+ }
+ return null;
+ }
+
+ public string GetGroup (Action action)
+ {
+ return actions [action] as string;
+ }
+
+ public void SetGroup (Action action, string group)
+ {
+ if (group == null) {
+ if (actions.Contains (action)) {
+ actions.Remove (action);
+ action.Disposed -= OnActionDisposed;
+ }
+ return;
+ }
+
+ if (!actions.Contains (action))
+ action.Disposed += OnActionDisposed;
+ actions [action] = group;
+ if (!groups.Contains (group))
+ groups.Add (group);
+ }
+
+ void OnActionDisposed (object s, EventArgs a)
+ {
+ Action ac = (Action) s;
+ if (ac != null) {
+ ac.Disposed -= OnActionDisposed;
+ actions.Remove (ac);
+ }
+ }
+
+ public string LastGroup {
+ get {
+ if (groups.Count == 0)
+ Add ("group1");
+ return groups [groups.Count - 1] as string;
+ }
+ }
+
+ void EmitGroupsChanged ()
+ {
+ if (GroupsChanged != null)
+ GroupsChanged ();
+ }
+
+ IEnumerable FindActionsInGroup (string grp)
+ {
+ foreach (DictionaryEntry e in actions)
+ if (((string)e.Value) == grp)
+ yield return e.Key;
+ }
+
+ public CodeExpression GenerateGroupExpression (GeneratorContext ctx, Action action)
+ {
+ // Returns and expression that represents the group to which the radio belongs.
+ // This expression can be an empty SList, if this is the first radio of the
+ // group that has been generated, or an SList taken from previously generated
+ // radios from the same group.
+
+ string group = actions [action] as string;
+ if (group == null)
+ return new CodePrimitiveExpression (null);
+
+ CodeExpression var = null;
+
+ foreach (Action a in FindActionsInGroup (group)) {
+ if (a == action)
+ continue;
+ var = ctx.WidgetMap.GetWidgetExp (a);
+ if (var != null)
+ break;
+ }
+
+ if (var == null) {
+ return new CodeObjectCreateExpression (
+ "GLib.SList".ToGlobalTypeRef (),
+ new CodePropertyReferenceExpression (
+ new CodeTypeReferenceExpression (typeof(IntPtr).ToGlobalTypeRef ()),
+ "Zero"
+ )
+ );
+ } else {
+ return new CodePropertyReferenceExpression (
+ var,
+ "Group"
+ );
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioButton.cs
new file mode 100644
index 0000000000..a58d70f31c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioButton.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class RadioButton : CheckButton, IRadioGroupManagerProvider {
+
+ static RadioGroupManager GroupManager = new RadioGroupManager (typeof (Gtk.RadioButton));
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ Gtk.RadioButton radiobutton = (Gtk.RadioButton)Wrapped;
+ if (!initialized)
+ Group = GroupManager.LastGroup;
+ else if (radiobutton.Group == null)
+ Group = radiobutton.Name;
+ }
+
+ IRadioGroupManager IRadioGroupManagerProvider.GetGroupManager ()
+ {
+ return GroupManager;
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ bool active = (bool)GladeUtils.ExtractProperty (elem, "active", false);
+ string group = (string)GladeUtils.ExtractProperty (elem, "group", "");
+ base.ReadProperties (reader, elem);
+
+ if (reader.Format == FileFormat.Glade) {
+ if (group != "")
+ Group = group;
+ else
+ Group = Wrapped.Name;
+ }
+
+ if (active)
+ ((Gtk.RadioButton)Wrapped).Active = true;
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ if (writer.Format == FileFormat.Glade) {
+ string group = GroupManager.GladeGroupName (Wrapped);
+ if (group != Wrapped.Name)
+ GladeUtils.SetProperty (elem, "group", group);
+ }
+ return elem;
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name == "Group") {
+ CodeExpression groupExp = GroupManager.GenerateGroupExpression (ctx, (Gtk.Widget) Wrapped);
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Group"),
+ groupExp)
+ );
+ }
+ else
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+
+ public string Group {
+ get {
+ return GroupManager[Wrapped];
+ }
+ set {
+ GroupManager[Wrapped] = value;
+ EmitNotify ("Group");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioMenuItem.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioMenuItem.cs
new file mode 100644
index 0000000000..d8a232584b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioMenuItem.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class RadioMenuItem : MenuItem, IRadioGroupManagerProvider {
+
+ static RadioGroupManager GroupManager = new RadioGroupManager (typeof (Gtk.RadioMenuItem));
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ Gtk.RadioMenuItem radio = (Gtk.RadioMenuItem)Wrapped;
+ if (!initialized)
+ Group = GroupManager.LastGroup;
+ else if (radio.Group == null)
+ Group = radio.Name;
+ }
+
+ IRadioGroupManager IRadioGroupManagerProvider.GetGroupManager ()
+ {
+ return GroupManager;
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ string group = (string)GladeUtils.ExtractProperty (elem, "group", "");
+ bool active = (bool)GladeUtils.ExtractProperty (elem, "active", false);
+ base.ReadProperties (reader, elem);
+
+ if (group != "")
+ Group = group;
+ else
+ Group = Wrapped.Name;
+ if (active)
+ ((Gtk.RadioMenuItem)Wrapped).Active = true;
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ string group = GroupManager.GladeGroupName (Wrapped);
+ if (group != Wrapped.Name)
+ GladeUtils.SetProperty (elem, "group", group);
+ return elem;
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name == "Group") {
+ CodeExpression groupExp = GroupManager.GenerateGroupExpression (ctx, (Gtk.Widget) Wrapped);
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Group"),
+ groupExp)
+ );
+ }
+ else
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+
+ public string Group {
+ get {
+ return GroupManager[Wrapped];
+ }
+ set {
+ GroupManager[Wrapped] = value;
+ EmitNotify ("Group");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioToolButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioToolButton.cs
new file mode 100644
index 0000000000..986d2476cc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/RadioToolButton.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class RadioToolButton : ToggleToolButton, IRadioGroupManagerProvider {
+
+ public static new Gtk.ToolButton CreateInstance ()
+ {
+ return new Gtk.RadioToolButton (new GLib.SList (IntPtr.Zero), Gtk.Stock.SortAscending);
+ }
+
+ static RadioGroupManager GroupManager = new RadioGroupManager (typeof (Gtk.RadioToolButton));
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ Gtk.RadioToolButton radio = (Gtk.RadioToolButton)Wrapped;
+ if (!initialized)
+ Group = GroupManager.LastGroup;
+ else if (radio.Group == null)
+ Group = radio.Name;
+ }
+
+ IRadioGroupManager IRadioGroupManagerProvider.GetGroupManager ()
+ {
+ return GroupManager;
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ string group = (string)GladeUtils.ExtractProperty (elem, "group", "");
+ bool active = (bool)GladeUtils.ExtractProperty (elem, "active", false);
+ base.ReadProperties (reader, elem);
+
+ if (group != "")
+ Group = group;
+ else
+ Group = Wrapped.Name;
+ if (active)
+ ((Gtk.RadioToolButton)Wrapped).Active = true;
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ string group = GroupManager.GladeGroupName (Wrapped);
+ if (group != Wrapped.Name)
+ GladeUtils.SetProperty (elem, "group", group);
+ return elem;
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name == "Group") {
+ CodeExpression groupExp = GroupManager.GenerateGroupExpression (ctx, (Gtk.Widget) Wrapped);
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (var, "Group"),
+ groupExp)
+ );
+ }
+ else
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+
+ public string Group {
+ get {
+ return GroupManager[Wrapped];
+ }
+ set {
+ GroupManager[Wrapped] = value;
+ EmitNotify ("Group");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Range.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Range.cs
new file mode 100644
index 0000000000..453e846004
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Range.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public abstract class Range : Widget {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ ((Gtk.Range)Wrapped).Adjustment.AddNotification (AdjustmentNotifyHandler);
+ }
+
+ public override void Dispose ()
+ {
+ ((Gtk.Range)Wrapped).Adjustment.RemoveNotification (AdjustmentNotifyHandler);
+ base.Dispose ();
+ }
+
+ void AdjustmentNotifyHandler (object obj, GLib.NotifyArgs args)
+ {
+ EmitNotify (args.Property);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Scale.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Scale.cs
new file mode 100644
index 0000000000..c43f6609bd
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Scale.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public abstract class Scale : Widget {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ ((Gtk.Scale)Wrapped).Adjustment.AddNotification (AdjustmentNotifyHandler);
+ }
+
+ public override void Dispose ()
+ {
+ ((Gtk.Scale)Wrapped).Adjustment.RemoveNotification (AdjustmentNotifyHandler);
+ base.Dispose ();
+ }
+
+ void AdjustmentNotifyHandler (object obj, GLib.NotifyArgs args)
+ {
+ EmitNotify (args.Property);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ScrolledWindow.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ScrolledWindow.cs
new file mode 100644
index 0000000000..e574d6a726
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ScrolledWindow.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class ScrolledWindow : Container {
+
+ Gtk.PolicyType hpolicy = Gtk.PolicyType.Automatic;
+ Gtk.PolicyType vpolicy = Gtk.PolicyType.Automatic;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized) {
+ if (scrolled.Child == null && AllowPlaceholders)
+ AddPlaceholder ();
+ HscrollbarPolicy = VscrollbarPolicy = Gtk.PolicyType.Automatic;
+ scrolled.ShadowType = Gtk.ShadowType.In;
+ }
+ scrolled.SetPolicy (Gtk.PolicyType.Always, Gtk.PolicyType.Always);
+ }
+
+ public Gtk.ScrolledWindow scrolled {
+ get {
+ return (Gtk.ScrolledWindow)Wrapped;
+ }
+ }
+
+ public Gtk.PolicyType HscrollbarPolicy {
+ get { return hpolicy; }
+ set {
+ hpolicy = value;
+ EmitNotify ("HscrollbarPolicy");
+ }
+ }
+
+ public Gtk.PolicyType VscrollbarPolicy {
+ get { return vpolicy; }
+ set {
+ vpolicy = value;
+ EmitNotify ("VscrollbarPolicy");
+ }
+ }
+
+ public override IEnumerable RealChildren {
+ get {
+ if (scrolled.Child is Gtk.Viewport)
+ return ((Gtk.Viewport)scrolled.Child).Children;
+ else
+ return base.RealChildren;
+ }
+ }
+
+ internal void AddWithViewport (Gtk.Widget child)
+ {
+ Gtk.Viewport viewport = new Gtk.Viewport (scrolled.Hadjustment, scrolled.Vadjustment);
+ ObjectWrapper.Create (proj, viewport, this);
+ viewport.ShadowType = Gtk.ShadowType.None;
+ viewport.Add (child);
+ viewport.Show ();
+ scrolled.Add (viewport);
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ Widget ww = Widget.Lookup (oldChild);
+ if (ww != null && ww.ShowScrollbars && ParentWrapper != null) {
+ // The viewport is bound to the child widget. Remove it together with the child
+ ParentWrapper.ReplaceChild (Wrapped, newChild, false);
+ return;
+ }
+
+ if (scrolled.Child is Gtk.Viewport && oldChild != scrolled.Child) {
+ Gtk.Viewport vp = (Gtk.Viewport)scrolled.Child;
+ vp.Remove (oldChild);
+ scrolled.Remove (vp);
+ vp.Destroy ();
+ }
+ else
+ scrolled.Remove (scrolled.Child);
+
+ if (newChild.SetScrollAdjustments (null, null))
+ scrolled.Add (newChild);
+ else
+ AddWithViewport (newChild);
+
+ NotifyChildAdded (scrolled.Child);
+ }
+
+ public override Placeholder AddPlaceholder ()
+ {
+ Placeholder ph = CreatePlaceholder ();
+ AddWithViewport (ph);
+ return ph;
+ }
+
+ protected override void GenerateChildBuildCode (GeneratorContext ctx, CodeExpression parentVar, Widget wrapper)
+ {
+ Gtk.Viewport vp = wrapper.Wrapped as Gtk.Viewport;
+ if (vp == null || (vp.Child != null && !(vp.Child is Placeholder)))
+ base.GenerateChildBuildCode (ctx, parentVar, wrapper);
+ }
+
+ public override void Delete (Stetic.Placeholder ph)
+ {
+ using (UndoManager.AtomicChange) {
+ Delete ();
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Signal.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Signal.cs
new file mode 100644
index 0000000000..3c1700e805
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Signal.cs
@@ -0,0 +1,60 @@
+
+using System;
+
+namespace Stetic
+{
+ [Serializable]
+ public class Signal
+ {
+ SignalDescriptor descriptor;
+ string handlerName;
+ bool after;
+
+ [NonSerialized]
+ internal ObjectWrapper Owner;
+
+ public Signal (SignalDescriptor descriptor): this (descriptor, null, false)
+ {
+ }
+
+ public Signal (SignalDescriptor descriptor, string handlerName, bool after)
+ {
+ this.descriptor = descriptor;
+ this.handlerName = handlerName;
+ this.after = after;
+ }
+
+ void NotifyChanged (Signal oldData)
+ {
+ if (Owner != null)
+ Owner.OnSignalChanged (new SignalChangedEventArgs (Owner, oldData, this));
+ }
+
+ Signal Clone ()
+ {
+ return new Signal (descriptor, handlerName, after);
+ }
+
+ public SignalDescriptor SignalDescriptor {
+ get { return descriptor; }
+ }
+
+ public string Handler {
+ get { return handlerName; }
+ set {
+ Signal data = Clone ();
+ handlerName = value;
+ NotifyChanged (data);
+ }
+ }
+
+ public bool After {
+ get { return after; }
+ set {
+ Signal data = Clone ();
+ after = value;
+ NotifyChanged (data);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalChangedEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalChangedEventHandler.cs
new file mode 100644
index 0000000000..1c2d138260
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalChangedEventHandler.cs
@@ -0,0 +1,19 @@
+
+namespace Stetic
+{
+ public delegate void SignalChangedEventHandler (object sender, SignalChangedEventArgs args);
+
+ public class SignalChangedEventArgs: SignalEventArgs
+ {
+ Signal oldSignal;
+
+ public SignalChangedEventArgs (ObjectWrapper wrapper, Signal oldSignal, Signal signal): base (wrapper, signal)
+ {
+ this.oldSignal = oldSignal;
+ }
+
+ public Signal OldSignal {
+ get { return oldSignal; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalCollection.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalCollection.cs
new file mode 100644
index 0000000000..c8b04ab33c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalCollection.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections;
+
+namespace Stetic
+{
+ [Serializable]
+ public class SignalCollection: CollectionBase
+ {
+ [NonSerialized]
+ ObjectWrapper owner;
+
+ [NonSerialized]
+ Signal[] clearedData;
+
+ public SignalCollection ()
+ {
+ }
+
+ internal SignalCollection (ObjectWrapper owner)
+ {
+ this.owner = owner;
+ }
+
+ public int Add (Signal signal)
+ {
+ return List.Add (signal);
+ }
+
+ public Signal this [int n] {
+ get { return (Signal) List [n]; }
+ }
+
+ public void Remove (Signal signal)
+ {
+ List.Remove (signal);
+ }
+
+ public void CopyTo (Signal[] signals, int index)
+ {
+ List.CopyTo (signals, index);
+ }
+
+ protected override void OnClear ()
+ {
+ if (owner != null) {
+ clearedData = new Signal [Count];
+ List.CopyTo (clearedData, 0);
+ }
+ }
+
+ protected override void OnClearComplete ()
+ {
+ if (owner != null) {
+ Signal[] data = clearedData;
+ clearedData = null;
+ foreach (Signal s in data) {
+ s.Owner = null;
+ owner.OnSignalRemoved (new SignalEventArgs (owner, s));
+ }
+ }
+ }
+
+ protected override void OnInsertComplete (int index, object value)
+ {
+ if (owner != null) {
+ ((Signal)value).Owner = owner;
+ owner.OnSignalAdded (new SignalEventArgs (owner, (Signal) value));
+ }
+ }
+
+ protected override void OnRemoveComplete (int index, object value)
+ {
+ if (owner != null) {
+ ((Signal)value).Owner = null;
+ owner.OnSignalRemoved (new SignalEventArgs (owner, (Signal) value));
+ }
+ }
+
+ protected override void OnSetComplete (int index, object oldValue, object newValue)
+ {
+ if (owner != null) {
+ ((Signal)oldValue).Owner = null;
+ owner.OnSignalRemoved (new SignalEventArgs (owner, (Signal) oldValue));
+ ((Signal)newValue).Owner = owner;
+ owner.OnSignalAdded (new SignalEventArgs (owner, (Signal) newValue));
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalEventHandler.cs
new file mode 100644
index 0000000000..da56c35156
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SignalEventHandler.cs
@@ -0,0 +1,19 @@
+
+namespace Stetic
+{
+ public delegate void SignalEventHandler (object sender, SignalEventArgs args);
+
+ public class SignalEventArgs: ObjectWrapperEventArgs
+ {
+ Signal signal;
+
+ public SignalEventArgs (ObjectWrapper wrapper, Signal signal): base (wrapper)
+ {
+ this.signal = signal;
+ }
+
+ public Signal Signal {
+ get { return signal; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SpinButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SpinButton.cs
new file mode 100644
index 0000000000..fa9e200f7b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/SpinButton.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public class SpinButton : Widget {
+
+ public static Gtk.SpinButton CreateInstance ()
+ {
+ return new Gtk.SpinButton (0.0, 100.0, 1.0);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Table.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Table.cs
new file mode 100644
index 0000000000..f765aa847d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Table.cs
@@ -0,0 +1,520 @@
+using System;
+using System.Collections;
+using System.Text.RegularExpressions;
+using System.Xml;
+
+namespace Stetic.Wrapper {
+
+ public class Table : Container {
+
+ const Gtk.AttachOptions expandOpts = Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill;
+ const Gtk.AttachOptions fillOpts = Gtk.AttachOptions.Fill;
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized) {
+ table.NRows = 3;
+ table.NColumns = 3;
+ table.RowSpacing = 6;
+ table.ColumnSpacing = 6;
+ }
+ DoSync ();
+ }
+
+ private Gtk.Table table {
+ get {
+ return (Gtk.Table)Wrapped;
+ }
+ }
+
+ public override void Delete (Stetic.Placeholder ph)
+ {
+ // Placeholders are deleted using commands.
+ }
+
+ protected override void DoSync ()
+ {
+ if (!AllowPlaceholders)
+ return;
+ using (UndoManager.AtomicChange) {
+ uint left, right, top, bottom;
+ uint row, col;
+ Gtk.Widget w;
+ Gtk.Widget[,] grid;
+ Gtk.Table.TableChild tc;
+ Gtk.Widget[] children;
+ bool addedPlaceholders = false;
+
+ children = table.Children;
+ grid = new Gtk.Widget[NRows,NColumns];
+
+ // First fill in the placeholders in the grid. If we find any
+ // placeholders covering more than one grid square, remove them.
+ // (New ones will be created below.)
+ foreach (Gtk.Widget child in children) {
+ if (!(child is Placeholder))
+ continue;
+
+ tc = table[child] as Gtk.Table.TableChild;
+ left = tc.LeftAttach;
+ right = tc.RightAttach;
+ top = tc.TopAttach;
+ bottom = tc.BottomAttach;
+
+ if (right == left + 1 && bottom == top + 1)
+ grid[top,left] = child;
+ else {
+ table.Remove (child);
+ child.Destroy ();
+ }
+ }
+
+ // Now fill in the real widgets, knocking out any placeholders
+ // they overlap. (If there are real widgets that overlap
+ // placeholders, neither will be knocked out, and the layout
+ // will probably end up wrong as well. But this situation
+ // happens at least temporarily during glade import.)
+ foreach (Gtk.Widget child in children) {
+ if (child is Placeholder)
+ continue;
+
+ tc = table[child] as Gtk.Table.TableChild;
+ left = tc.LeftAttach;
+ right = tc.RightAttach;
+ top = tc.TopAttach;
+ bottom = tc.BottomAttach;
+
+ for (row = top; row < bottom; row++) {
+ for (col = left; col < right; col++) {
+ w = grid[row,col];
+ if (w is Placeholder) {
+ table.Remove (w);
+ w.Destroy ();
+ }
+ grid[row,col] = child;
+ }
+ }
+ }
+
+ // Scan each row; if there are any empty cells, fill them in
+ // with placeholders. If a row contains only placeholders, then
+ // set them all to expand vertically so the row won't collapse.
+ // OTOH, if the row contains any real widget, set any placeholders
+ // in that row to not expand vertically, so they don't force the
+ // real widgets to expand further than they should. If any row
+ // is vertically expandable, then the table as a whole is.
+ vexpandable = false;
+ for (row = 0; row < NRows; row++) {
+ bool allPlaceholders = true;
+
+ for (col = 0; col < NColumns; col++) {
+ w = grid[row,col];
+ if (w == null) {
+ w = CreatePlaceholder ();
+ table.Attach (w, col, col + 1, row, row + 1);
+ NotifyChildAdded (w);
+ grid[row,col] = w;
+ addedPlaceholders = true;
+ } else if (!ChildVExpandable (w) || !AutoSize[w])
+ allPlaceholders = false;
+ }
+
+ for (col = 0; col < NColumns; col++) {
+ w = grid[row,col];
+ if (!AutoSize[w])
+ continue;
+ tc = table[w] as Gtk.Table.TableChild;
+ // We can't play with the vertical expansion property of
+ // widgets which span more than one row
+ if (tc.BottomAttach != tc.TopAttach + 1)
+ continue;
+ Gtk.AttachOptions opts = allPlaceholders ? expandOpts : fillOpts;
+ if (tc.YOptions != opts)
+ tc.YOptions = opts;
+ }
+
+ if (allPlaceholders)
+ vexpandable = true;
+ }
+
+ // Now do the same for columns and horizontal expansion (but we
+ // don't have to worry about empty cells this time).
+ hexpandable = false;
+ for (col = 0; col < NColumns; col++) {
+ bool allPlaceholders = true;
+
+ for (row = 0; row < NRows; row++) {
+ w = grid[row,col];
+ if (!ChildHExpandable (w) || !AutoSize[w]) {
+ allPlaceholders = false;
+ break;
+ }
+ }
+
+ for (row = 0; row < NRows; row++) {
+ w = grid[row,col];
+ if (!AutoSize[w])
+ continue;
+ tc = table[w] as Gtk.Table.TableChild;
+ // We can't play with the horizontal expansion property of
+ // widgets which span more than one column
+ if (tc.RightAttach != tc.LeftAttach + 1)
+ continue;
+ Gtk.AttachOptions opts = allPlaceholders ? expandOpts : fillOpts;
+ if (tc.XOptions != opts)
+ tc.XOptions = opts;
+ }
+
+ if (allPlaceholders)
+ hexpandable = true;
+ }
+
+ if (addedPlaceholders)
+ EmitContentsChanged ();
+ }
+ }
+
+ public override Placeholder AddPlaceholder ()
+ {
+ // Placeholders are added by Sync ()
+ return null;
+ }
+
+ public uint NRows {
+ get {
+ return table.NRows;
+ }
+ set {
+ using (UndoManager.AtomicChange) {
+ Freeze ();
+ while (value < table.NRows)
+ DeleteRow (table.NRows - 1);
+ table.NRows = value;
+ Thaw ();
+ }
+ }
+ }
+
+ public uint NColumns {
+ get {
+ return table.NColumns;
+ }
+ set {
+ using (UndoManager.AtomicChange) {
+ Freeze ();
+ while (value < table.NColumns)
+ DeleteColumn (table.NColumns - 1);
+ table.NColumns = value;
+ Thaw ();
+ }
+ }
+ }
+
+ void AddRow (uint row)
+ {
+ using (UndoManager.AtomicChange) {
+ Freeze ();
+ table.NRows++;
+ foreach (Gtk.Widget w in table.Children) {
+ Gtk.Table.TableChild tc = table[w] as Gtk.Table.TableChild;
+
+ if (tc.BottomAttach > row)
+ tc.BottomAttach++;
+ if (tc.TopAttach >= row)
+ tc.TopAttach++;
+ }
+ Thaw ();
+ }
+ }
+
+ void DeleteRow (uint row)
+ {
+ Gtk.Widget[] children = table.Children;
+ Gtk.Table.TableChild tc;
+
+ using (UndoManager.AtomicChange) {
+ Freeze ();
+ foreach (Gtk.Widget child in children) {
+ tc = table[child] as Gtk.Table.TableChild;
+
+ if (tc.TopAttach == row) {
+ if (tc.BottomAttach == tc.TopAttach + 1) {
+ table.Remove (child);
+ child.Destroy ();
+ }
+ else
+ tc.BottomAttach--;
+ } else {
+ if (tc.TopAttach > row)
+ tc.TopAttach--;
+ if (tc.BottomAttach > row)
+ tc.BottomAttach--;
+ }
+ }
+ table.NRows--;
+ Thaw ();
+ }
+ }
+
+ void AddColumn (uint col)
+ {
+ using (UndoManager.AtomicChange) {
+ Freeze ();
+ table.NColumns++;
+ foreach (Gtk.Widget w in table.Children) {
+ Gtk.Table.TableChild tc = table[w] as Gtk.Table.TableChild;
+
+ if (tc.RightAttach > col)
+ tc.RightAttach++;
+ if (tc.LeftAttach >= col)
+ tc.LeftAttach++;
+ }
+ Thaw ();
+ }
+ }
+
+ void DeleteColumn (uint col)
+ {
+ using (UndoManager.AtomicChange) {
+ Gtk.Widget[] children = table.Children;
+ Gtk.Table.TableChild tc;
+
+ Freeze ();
+ foreach (Gtk.Widget child in children) {
+ tc = table[child] as Gtk.Table.TableChild;
+
+ if (tc.LeftAttach == col) {
+ if (tc.RightAttach == tc.LeftAttach + 1) {
+ table.Remove (child);
+ child.Destroy ();
+ }
+ else
+ tc.RightAttach--;
+ } else {
+ if (tc.LeftAttach > col)
+ tc.LeftAttach--;
+ if (tc.RightAttach > col)
+ tc.RightAttach--;
+ }
+ }
+ table.NColumns--;
+ Thaw ();
+ }
+ }
+
+ public override IEnumerable GladeChildren {
+ get {
+ ArrayList list = new ArrayList ();
+ foreach (object ob in base.GladeChildren)
+ list.Add (ob);
+ list.Sort (new NameComparer ());
+ return list;
+ }
+ }
+
+ class NameComparer: IComparer
+ {
+ public int Compare (object x, object y)
+ {
+ return string.Compare (((Gtk.Widget)x).Name, ((Gtk.Widget)y).Name);
+ }
+ }
+
+ internal void InsertRowBefore (Gtk.Widget context)
+ {
+ Gtk.Table.TableChild tc = table[context] as Gtk.Table.TableChild;
+ AddRow (tc.TopAttach);
+ }
+
+ internal void InsertRowAfter (Gtk.Widget context)
+ {
+ Gtk.Table.TableChild tc = table[context] as Gtk.Table.TableChild;
+ AddRow (tc.BottomAttach);
+ }
+
+ internal void InsertColumnBefore (Gtk.Widget context)
+ {
+ Gtk.Table.TableChild tc = table[context] as Gtk.Table.TableChild;
+ AddColumn (tc.LeftAttach);
+ }
+
+ internal void InsertColumnAfter (Gtk.Widget context)
+ {
+ Gtk.Table.TableChild tc = table[context] as Gtk.Table.TableChild;
+ AddColumn (tc.RightAttach);
+ }
+
+ internal void DeleteRow (Gtk.Widget context)
+ {
+ Gtk.Table.TableChild tc = table[context] as Gtk.Table.TableChild;
+ DeleteRow (tc.TopAttach);
+ }
+
+ internal void DeleteColumn (Gtk.Widget context)
+ {
+ Gtk.Table.TableChild tc = table[context] as Gtk.Table.TableChild;
+ DeleteColumn (tc.LeftAttach);
+ }
+
+ private bool hexpandable, vexpandable;
+ public override bool HExpandable { get { return hexpandable; } }
+ public override bool VExpandable { get { return vexpandable; } }
+
+ protected override void ChildContentsChanged (Container child)
+ {
+ using (UndoManager.AtomicChange) {
+ Gtk.Widget widget = child.Wrapped;
+ Freeze ();
+ if (AutoSize[widget]) {
+ Gtk.Table.TableChild tc = table[widget] as Gtk.Table.TableChild;
+ tc.XOptions = 0;
+ tc.YOptions = 0;
+ }
+ Thaw ();
+ }
+
+ base.ChildContentsChanged (child);
+ }
+
+ public class TableChild : Container.ContainerChild {
+
+ bool freeze;
+
+ Gtk.Table.TableChild tc {
+ get {
+ return (Gtk.Table.TableChild)Wrapped;
+ }
+ }
+
+ public bool XExpand {
+ get {
+ return (tc.XOptions & Gtk.AttachOptions.Expand) != 0;
+ }
+ set {
+ freeze = true;
+ if (value)
+ tc.XOptions |= Gtk.AttachOptions.Expand;
+ else
+ tc.XOptions &= ~Gtk.AttachOptions.Expand;
+ freeze = false;
+ EmitNotify ("XExpand");
+ }
+ }
+
+ public bool XFill {
+ get {
+ return (tc.XOptions & Gtk.AttachOptions.Fill) != 0;
+ }
+ set {
+ freeze = true;
+ if (value)
+ tc.XOptions |= Gtk.AttachOptions.Fill;
+ else
+ tc.XOptions &= ~Gtk.AttachOptions.Fill;
+ freeze = false;
+ EmitNotify ("XFill");
+ }
+ }
+
+ public bool XShrink {
+ get {
+ return (tc.XOptions & Gtk.AttachOptions.Shrink) != 0;
+ }
+ set {
+ freeze = true;
+ if (value)
+ tc.XOptions |= Gtk.AttachOptions.Shrink;
+ else
+ tc.XOptions &= ~Gtk.AttachOptions.Shrink;
+ freeze = false;
+ EmitNotify ("XShrink");
+ }
+ }
+
+ public bool YExpand {
+ get {
+ return (tc.YOptions & Gtk.AttachOptions.Expand) != 0;
+ }
+ set {
+ freeze = true;
+ if (value)
+ tc.YOptions |= Gtk.AttachOptions.Expand;
+ else
+ tc.YOptions &= ~Gtk.AttachOptions.Expand;
+ freeze = false;
+ EmitNotify ("YExpand");
+ }
+ }
+
+ public bool YFill {
+ get {
+ return (tc.YOptions & Gtk.AttachOptions.Fill) != 0;
+ }
+ set {
+ freeze = true;
+ if (value)
+ tc.YOptions |= Gtk.AttachOptions.Fill;
+ else
+ tc.YOptions &= ~Gtk.AttachOptions.Fill;
+ freeze = false;
+ EmitNotify ("YFill");
+ }
+ }
+
+ public bool YShrink {
+ get {
+ return (tc.YOptions & Gtk.AttachOptions.Shrink) != 0;
+ }
+ set {
+ freeze = true;
+ if (value)
+ tc.YOptions |= Gtk.AttachOptions.Shrink;
+ else
+ tc.YOptions &= ~Gtk.AttachOptions.Shrink;
+ freeze = false;
+ EmitNotify ("YShrink");
+ }
+ }
+
+ protected override void EmitNotify (string propertyName)
+ {
+ if (freeze || Loading) return;
+
+ if (propertyName == "x-options" || propertyName == "AutoSize") {
+ base.EmitNotify ("XExpand");
+ base.EmitNotify ("XFill");
+ base.EmitNotify ("XShrink");
+ }
+ if (propertyName == "y-options" || propertyName == "AutoSize") {
+ base.EmitNotify ("YExpand");
+ base.EmitNotify ("YFill");
+ base.EmitNotify ("YShrink");
+ }
+ base.EmitNotify (propertyName);
+ }
+
+ // Properties to be used by the wrapper commands
+
+ public bool CellXExpand {
+ get { return XExpand; }
+ set { AutoSize = false; XExpand = value; }
+ }
+
+ public bool CellXFill{
+ get { return XFill; }
+ set { AutoSize = false; XFill = value; }
+ }
+
+ public bool CellYExpand {
+ get { return YExpand; }
+ set { AutoSize = false; YExpand = value; }
+ }
+
+ public bool CellYFill{
+ get { return YFill; }
+ set { AutoSize = false; YFill = value; }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TextView.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TextView.cs
new file mode 100644
index 0000000000..1fbc09e0b6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TextView.cs
@@ -0,0 +1,62 @@
+using System;
+using System.CodeDom;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class TextView : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ ((Gtk.TextView)Wrapped).Buffer.Changed += Buffer_Changed;
+ if (!initialized)
+ ShowScrollbars = true;
+ }
+
+ public override void Dispose ()
+ {
+ ((Gtk.TextView)Wrapped).Buffer.Changed -= Buffer_Changed;
+ base.Dispose ();
+ }
+
+ public string Text {
+ get {
+ return ((Gtk.TextView)Wrapped).Buffer.Text;
+ }
+ set {
+ ((Gtk.TextView)Wrapped).Buffer.Text = value;
+ }
+ }
+
+ public void Buffer_Changed (object obj, EventArgs args)
+ {
+ EmitNotify ("Text");
+ }
+
+ protected override bool AllowPlaceholders {
+ get {
+ return false;
+ }
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ if (Text.Length > 0) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ new CodePropertyReferenceExpression (
+ var,
+ "Buffer"
+ ),
+ "Text"
+ ),
+ new CodePrimitiveExpression (Text)
+ )
+ );
+ }
+ base.GenerateBuildCode (ctx, var);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToggleToolButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToggleToolButton.cs
new file mode 100644
index 0000000000..a8a0654f1f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToggleToolButton.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Stetic.Wrapper {
+
+ public class ToggleToolButton : ToolButton {
+
+ public static new Gtk.ToolButton CreateInstance ()
+ {
+ return new Gtk.ToggleToolButton (Gtk.Stock.Bold);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToolButton.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToolButton.cs
new file mode 100644
index 0000000000..76bb51faf7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/ToolButton.cs
@@ -0,0 +1,147 @@
+using System;
+using System.CodeDom;
+using System.Xml;
+
+namespace Stetic.Wrapper {
+
+ public class ToolButton : Widget {
+
+ ButtonType type;
+ string stockId;
+ string label;
+ ImageInfo imageInfo;
+
+ public enum ButtonType {
+ StockItem,
+ TextAndIcon
+ };
+
+ public static Gtk.ToolButton CreateInstance ()
+ {
+ return new Gtk.ToolButton (Gtk.Stock.New);
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ Gtk.ToolButton toolbutton = (Gtk.ToolButton)Wrapped;
+
+ if (toolbutton.StockId != null) {
+ stockId = toolbutton.StockId;
+ type = ButtonType.StockItem;
+ } else {
+ type = ButtonType.TextAndIcon;
+ }
+ }
+
+ protected override void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ if (reader.Format == FileFormat.Glade) {
+ string icon = (string)GladeUtils.ExtractProperty (elem, "icon", "");
+ stockId = (string)GladeUtils.ExtractProperty (elem, "stock_id", "");
+ label = (string)GladeUtils.ExtractProperty (elem, "label", "");
+ base.ReadProperties (reader, elem);
+
+ if (stockId != null && stockId.Length > 0) {
+ Type = ButtonType.StockItem;
+ } else if (icon != null && icon != "") {
+ imageInfo = ImageInfo.FromFile (icon);
+ Type = ButtonType.TextAndIcon;
+ }
+ } else
+ base.ReadProperties (reader, elem);
+ }
+
+ protected override XmlElement WriteProperties (ObjectWriter writer)
+ {
+ XmlElement elem = base.WriteProperties (writer);
+ if (type != ButtonType.StockItem && imageInfo != null) {
+ if (writer.Format == FileFormat.Glade) {
+ switch (imageInfo.Source) {
+ case ImageSource.File:
+ GladeUtils.SetProperty (elem, "icon", imageInfo.Name);
+ break;
+ case ImageSource.Theme:
+ GladeUtils.SetProperty (elem, "stock_id", imageInfo.Name);
+ break;
+ default:
+ throw new System.NotSupportedException ("Image source not supported by Glade.");
+ }
+ }
+ }
+ return elem;
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (
+ ClassDescriptor.WrappedTypeName.ToGlobalTypeRef (),
+ new CodePrimitiveExpression (null),
+ new CodePrimitiveExpression (null)
+ );
+ }
+
+ Gtk.ToolButton button {
+ get { return (Gtk.ToolButton) Wrapped; }
+ }
+
+ public ButtonType Type {
+ get {
+ return type;
+ }
+ set {
+ type = value;
+ switch (type) {
+ case ButtonType.StockItem:
+ button.IconWidget = null;
+ StockId = stockId;
+ Label = label;
+ break;
+ case ButtonType.TextAndIcon:
+ button.StockId = null;
+ Icon = imageInfo;
+ Label = label;
+ break;
+ }
+ EmitNotify ("Type");
+ }
+ }
+
+ public string Label {
+ get { return label; }
+ set {
+ if (type == ButtonType.StockItem && value != null) {
+ label = value.Length == 0 ? null : value;
+ } else
+ label = value;
+
+ button.Label = label;
+ }
+ }
+
+ public string StockId {
+ get { return stockId; }
+ set {
+ stockId = value;
+ if (stockId != null && stockId.StartsWith ("stock:"))
+ stockId = stockId.Substring (6);
+ button.StockId = stockId;
+ button.ShowAll ();
+ }
+ }
+
+ public ImageInfo Icon {
+ get { return imageInfo; }
+ set {
+ imageInfo = value;
+ if (imageInfo != null) {
+ button.IconWidget = new Gtk.Image (imageInfo.GetImage (Project));
+ button.ShowAll ();
+ }
+ else
+ button.IconWidget = null;
+ EmitNotify ("Icon");
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Toolbar.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Toolbar.cs
new file mode 100644
index 0000000000..cc15543888
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Toolbar.cs
@@ -0,0 +1,178 @@
+using System;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Toolbar : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ toolbar.SizeAllocated += toolbar_SizeAllocated;
+ }
+
+ public override void Dispose ()
+ {
+ toolbar.SizeAllocated -= toolbar_SizeAllocated;
+ base.Dispose ();
+ }
+
+ public override IEnumerable RealChildren {
+ get {
+ // Don't return Gtk.ToolItems that are only being used
+ // to hold other non-ToolItem widgets. Just return the
+ // contained widgets themselves.
+
+ Gtk.Widget[] children = toolbar.Children;
+ for (int i = 0; i < children.Length; i++) {
+ if (children[i].GetType () == typeof (Gtk.ToolItem))
+ children[i] = ((Gtk.ToolItem)children[i]).Child;
+ }
+ return children;
+ }
+ }
+
+ Gtk.Toolbar toolbar {
+ get {
+ return (Gtk.Toolbar)Wrapped;
+ }
+ }
+
+ public override bool HExpandable {
+ get {
+ return toolbar.Orientation == Gtk.Orientation.Horizontal;
+ }
+ }
+
+ public override bool VExpandable {
+ get {
+ return toolbar.Orientation == Gtk.Orientation.Vertical;
+ }
+ }
+
+ public Gtk.Orientation Orientation {
+ get {
+ return toolbar.Orientation;
+ }
+ set {
+ toolbar.Orientation = value;
+ EmitContentsChanged ();
+ }
+ }
+
+ protected override void DoSync ()
+ {
+ DND.ClearFaults (this);
+ Gtk.Orientation faultOrientation =
+ Orientation == Gtk.Orientation.Horizontal ? Gtk.Orientation.Vertical : Gtk.Orientation.Horizontal;
+ Gdk.Rectangle tbAlloc = toolbar.Allocation;
+
+ Gtk.Widget[] children = toolbar.Children;
+ if (children.Length == 0) {
+ DND.AddFault (this, 0, faultOrientation, tbAlloc);
+ return;
+ }
+
+ if (faultOrientation == Gtk.Orientation.Horizontal) {
+ DND.AddHFault (this, 0, null, children[0]);
+ DND.AddHFault (this, children.Length, children[children.Length - 1], null);
+ } else {
+ DND.AddVFault (this, 0, null, children[0]);
+ DND.AddVFault (this, children.Length, children[children.Length - 1], null);
+ }
+
+ for (int i = 1; i < children.Length; i++) {
+ if (faultOrientation == Gtk.Orientation.Horizontal)
+ DND.AddHFault (this, i, children[i - 1], children[i]);
+ else
+ DND.AddVFault (this, i, children[i - 1], children[i]);
+ }
+ }
+
+ void toolbar_SizeAllocated (object obj, Gtk.SizeAllocatedArgs args)
+ {
+ Sync ();
+ }
+
+ // Insert widget at index, wrapping a ToolItem around it if needed
+ void ToolItemize (Gtk.Widget widget, int index)
+ {
+ Gtk.ToolItem toolItem = widget as Gtk.ToolItem;
+ if (toolItem == null) {
+ toolItem = new Gtk.ToolItem ();
+ toolItem.Show ();
+ toolItem.Add (widget);
+ }
+ toolbar.Insert (toolItem, index);
+ }
+
+ // Remove widget (or its ToolItem parent), returning its position
+ int ToolDeItemize (Gtk.Widget widget)
+ {
+ Gtk.ToolItem toolItem = widget as Gtk.ToolItem;
+ if (toolItem == null) {
+ toolItem = (Gtk.ToolItem)widget.Parent;
+ toolItem.Remove (widget);
+ }
+
+ int index = toolbar.GetItemIndex (toolItem);
+
+ toolbar.Remove (toolItem);
+ if (toolItem != (widget as Gtk.ToolItem))
+ toolItem.Destroy ();
+
+ return index;
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ ToolItemize (newChild, ToolDeItemize (oldChild));
+ }
+
+ public override Placeholder AddPlaceholder ()
+ {
+ Placeholder ph = CreatePlaceholder ();
+ ToolItemize (ph, 0);
+ return ph;
+ }
+
+ int dragIndex;
+
+ protected override Gtk.Widget CreateDragSource (Gtk.Widget dragWidget)
+ {
+ Gtk.Invisible invis = new Gtk.Invisible ();
+ invis.Show ();
+ invis.DragEnd += DragEnd;
+
+ dragIndex = ToolDeItemize (dragWidget);
+ return invis;
+ }
+
+ void DragEnd (object obj, Gtk.DragEndArgs args)
+ {
+ Gtk.Invisible invis = obj as Gtk.Invisible;
+ invis.DragEnd -= DragEnd;
+ invis.Destroy ();
+
+ if (DND.DragWidget != null)
+ ToolItemize (DND.Cancel (), dragIndex);
+ dragIndex = -1;
+ }
+
+ public override void Drop (Gtk.Widget w, object faultId)
+ {
+ ToolItemize (w, (int)faultId);
+ EmitContentsChanged ();
+ Sync ();
+ }
+
+ public class ToolbarChild : Container.ContainerChild {
+ public Gtk.ToolItem ToolItem {
+ get {
+ Gtk.Container.ContainerChild cc = (Gtk.Container.ContainerChild)Wrapped;
+ return (Gtk.ToolItem)cc.Child;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TreeView.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TreeView.cs
new file mode 100644
index 0000000000..0444f4f4b1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/TreeView.cs
@@ -0,0 +1,21 @@
+
+using System;
+
+namespace Stetic.Wrapper
+{
+ public class TreeView: Container
+ {
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ if (!initialized)
+ ShowScrollbars = true;
+ }
+
+ protected override bool AllowPlaceholders {
+ get {
+ return false;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScale.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScale.cs
new file mode 100644
index 0000000000..e0fb10677c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScale.cs
@@ -0,0 +1,18 @@
+using System;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class VScale : Scale {
+
+ public static Gtk.VScale CreateInstance ()
+ {
+ return new Gtk.VScale (0.0, 100.0, 1.0);
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (ClassDescriptor.WrappedTypeName.ToGlobalTypeRef (), new CodePrimitiveExpression (null));
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScrollbar.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScrollbar.cs
new file mode 100644
index 0000000000..8270c97a4e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/VScrollbar.cs
@@ -0,0 +1,18 @@
+using System;
+using System.CodeDom;
+
+namespace Stetic.Wrapper {
+
+ public class VScrollbar : Range {
+
+ public static Gtk.VScrollbar CreateInstance ()
+ {
+ return new Gtk.VScrollbar (new Gtk.Adjustment (0.0, 0.0, 100.0, 1.0, 10.0, 10.0));
+ }
+
+ internal protected override CodeExpression GenerateObjectCreation (GeneratorContext ctx)
+ {
+ return new CodeObjectCreateExpression (ClassDescriptor.WrappedTypeName.ToGlobalTypeRef (), new CodePrimitiveExpression (null));
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Viewport.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Viewport.cs
new file mode 100644
index 0000000000..41dbacc161
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Viewport.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Viewport : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+ Unselectable = true;
+ }
+
+ protected override void ReplaceChild (Gtk.Widget oldChild, Gtk.Widget newChild)
+ {
+ Widget ww = Widget.Lookup (oldChild);
+ if ((oldChild is Placeholder) && (ParentWrapper is ScrolledWindow) && newChild.SetScrollAdjustments (null, null)) {
+ Widget wrapper = Widget.Lookup (newChild);
+ wrapper.ShowScrollbars = false;
+ ParentWrapper.ReplaceChild (Wrapped, newChild, false);
+ } else if (ww != null && ww.ShowScrollbars && (ParentWrapper is ScrolledWindow) && ParentWrapper.ParentWrapper != null) {
+ // The viewport is bound to the child widget. Remove it together with the child
+ ParentWrapper.ParentWrapper.ReplaceChild (ParentWrapper.Wrapped, newChild, false);
+ } else
+ base.ReplaceChild (oldChild, newChild);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Widget.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Widget.cs
new file mode 100644
index 0000000000..80f5ab8e33
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Widget.cs
@@ -0,0 +1,1094 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.CodeDom;
+using Stetic.Undo;
+
+namespace Stetic.Wrapper {
+
+ public class Widget : Object, IEditableObject
+ {
+ static DiffGenerator propDiffGenerator;
+
+ string oldName;
+ string oldMemberName;
+ bool hexpandable, vexpandable;
+ bool generatePublic = true;
+
+ bool window_visible = true;
+ bool hasDefault;
+ bool canDefault;
+ Gdk.EventMask events;
+ bool canFocus;
+
+ ActionGroupCollection actionGroups;
+ string member;
+ string tooltip;
+
+ bool requiresUndoStatusUpdate;
+
+ // List of groups added to the UIManager
+ ArrayList includedActionGroups;
+
+ bool unselectable;
+ bool boundToScrollWindow;
+
+ public event EventHandler Destroyed;
+
+ // Fired when the name of the widget changes.
+ public event WidgetNameChangedHandler NameChanged;
+ // Fired when the member name of the widget changes.
+ public event WidgetNameChangedHandler MemberNameChanged;
+
+ static Widget ()
+ {
+ propDiffGenerator = new DiffGenerator ();
+ propDiffGenerator.CurrentStatusAdaptor = new XmlDiffAdaptor ();
+ propDiffGenerator.NewStatusAdaptor = propDiffGenerator.CurrentStatusAdaptor;
+ }
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ base.Wrap (obj, initialized);
+
+ oldName = ((Gtk.Widget)obj).Name;
+
+ if (!initialized) {
+ events = Wrapped.Events;
+ canFocus = Wrapped.CanFocus;
+ }
+
+ if (!(Wrapped is Gtk.Window))
+ Wrapped.ShowAll ();
+
+ Wrapped.PopupMenu += PopupMenu;
+ Wrapped.FocusInEvent += OnFocusIn;
+ InterceptClicks (Wrapped);
+
+ hexpandable = this.ClassDescriptor.HExpandable;
+ vexpandable = this.ClassDescriptor.VExpandable;
+
+ if (ParentWrapper != null) {
+ // Make sure the widget's name is not already being used.
+ string nn = ParentWrapper.GetValidWidgetName (Wrapped);
+ if (nn != Wrapped.Name)
+ Wrapped.Name = nn;
+ }
+
+ Wrapped.Destroyed += OnDestroyed;
+
+ if (Wrapped.Parent != null) {
+ // The object was added to the parent before creating the wrapper.
+ // Since it's now a wrapped object, the parent don't need to
+ // intercept clicks for it anymore
+ Widget w = GetInterceptorParent ();
+ if (w != null)
+ w.UninterceptClicks (Wrapped);
+ }
+ }
+
+ void OnDestroyed (object on, EventArgs a)
+ {
+ if (Destroyed != null)
+ Destroyed (this, a);
+ Dispose ();
+ }
+
+ public override void Dispose ()
+ {
+ if (Wrapped == null)
+ return;
+
+ if (Project != null && Project.Selection == Wrapped)
+ Project.Selection = null;
+
+ Wrapped.Destroyed -= OnDestroyed;
+ Wrapped.PopupMenu -= PopupMenu;
+ Wrapped.FocusInEvent -= OnFocusIn;
+ UninterceptClicks (Wrapped);
+
+ if (actionGroups != null) {
+ foreach (ActionGroup ag in actionGroups)
+ ag.Dispose ();
+ actionGroups = null;
+ }
+ base.Dispose ();
+ }
+
+ void OnFocusIn (object s, Gtk.FocusInEventArgs a)
+ {
+ if (!Unselectable)
+ Select ();
+ else if (ParentWrapper != null)
+ ParentWrapper.Select ();
+ }
+
+ internal override UndoManager GetUndoManagerInternal ()
+ {
+ if (ParentWrapper != null)
+ return ParentWrapper.UndoManager;
+ else
+ return base.GetUndoManagerInternal ();
+ }
+
+ public bool GeneratePublic {
+ get { return generatePublic; }
+ set { generatePublic = value; }
+ }
+
+ public bool Unselectable {
+ get {
+ return unselectable;
+ }
+ set {
+ if (value == unselectable)
+ return;
+ unselectable = value;
+ Widget w = GetInterceptorParent ();
+ if (w != null) {
+ // If a widget becomes unselectable, then the parent must intercept
+ // their clicks.
+ if (unselectable)
+ w.InterceptClicks (Wrapped);
+ else
+ w.UninterceptClicks (Wrapped);
+ }
+ }
+ }
+
+ Widget GetInterceptorParent ()
+ {
+ Gtk.Widget wp = Wrapped.Parent;
+ while (wp != null && Lookup (wp) == null)
+ wp = wp.Parent;
+ return Lookup (wp);
+ }
+
+ void InterceptClicks (Gtk.Widget widget)
+ {
+ if (widget is Stetic.Placeholder)
+ return;
+
+ if (!widget.IsRealized)
+ widget.Events |= Gdk.EventMask.ButtonPressMask;
+ widget.WidgetEvent += WidgetEvent;
+
+ Gtk.Container container = widget as Gtk.Container;
+ if (container != null) {
+ container.Added += OnInterceptedChildAdded;
+ container.Removed += OnInterceptedChildRemoved;
+ foreach (Gtk.Widget child in container.AllChildren) {
+ Widget w = Lookup (child);
+ if (w == null || w.Unselectable)
+ InterceptClicks (child);
+ }
+ }
+ }
+
+ [GLib.ConnectBefore]
+ void OnInterceptedChildAdded (object o, Gtk.AddedArgs args)
+ {
+ Widget w = Lookup (args.Widget);
+ if (w == null || w.Unselectable)
+ InterceptClicks (args.Widget);
+ }
+
+ void OnInterceptedChildRemoved (object o, Gtk.RemovedArgs args)
+ {
+ UninterceptClicks (args.Widget);
+ }
+
+ void UninterceptClicks (Gtk.Widget widget)
+ {
+ widget.WidgetEvent -= WidgetEvent;
+
+ Gtk.Container container = widget as Gtk.Container;
+ if (container != null) {
+ container.Added -= OnInterceptedChildAdded;
+ container.Removed -= OnInterceptedChildRemoved;
+ foreach (Gtk.Widget child in container.AllChildren) {
+ if (Lookup (child) == null)
+ UninterceptClicks (child);
+ }
+ }
+ }
+
+ public new Gtk.Widget Wrapped {
+ get {
+ return base.Wrapped as Gtk.Widget;
+ }
+ }
+
+ public Stetic.Wrapper.Container ParentWrapper {
+ get {
+ return Container.LookupParent (Wrapped);
+ }
+ }
+
+ public bool IsTopLevel {
+ get { return Wrapped.Parent == null || Widget.Lookup (Wrapped.Parent) == null; }
+ }
+
+ public string UIManagerName {
+ get {
+ return actionGroups != null && actionGroups.Count > 0 ? "UIManager" : String.Empty;
+ }
+ }
+
+ internal void InitializeName (string name)
+ {
+ oldName = name;
+ Wrapped.Name = name;
+ }
+
+ public override string Name {
+ get { return Wrapped.Name; }
+ set { Wrapped.Name = value; EmitNotify ("Name"); }
+ }
+
+ public string MemberName {
+ get { return member != null ? member : ""; }
+ set { member = value; EmitNotify ("MemberName"); }
+ }
+
+ public Container GetTopLevel ()
+ {
+ Widget c = this;
+ while (!c.IsTopLevel)
+ c = c.ParentWrapper;
+ return c as Container;
+ }
+
+ public ActionGroupCollection LocalActionGroups {
+ get {
+ if (IsTopLevel) {
+ if (actionGroups == null) {
+ actionGroups = new ActionGroupCollection ();
+ actionGroups.SetOwner (this);
+ actionGroups.ActionGroupAdded += OnGroupAdded;
+ actionGroups.ActionGroupRemoved += OnGroupRemoved;
+ actionGroups.ActionGroupChanged += OnGroupChanged;
+ }
+ return actionGroups;
+ } else {
+ return ParentWrapper.LocalActionGroups;
+ }
+ }
+ }
+
+ void OnGroupAdded (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ args.ActionGroup.SignalAdded += OnSignalAdded;
+ args.ActionGroup.SignalRemoved += OnSignalRemoved;
+ args.ActionGroup.SignalChanged += OnSignalChanged;
+ NotifyChanged ();
+ }
+
+ void OnGroupRemoved (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ args.ActionGroup.SignalAdded -= OnSignalAdded;
+ args.ActionGroup.SignalRemoved -= OnSignalRemoved;
+ args.ActionGroup.SignalChanged -= OnSignalChanged;
+ NotifyChanged ();
+ }
+
+ void OnGroupChanged (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ NotifyChanged ();
+ }
+
+ void OnSignalAdded (object sender, SignalEventArgs args)
+ {
+ OnSignalAdded (args);
+ }
+
+ void OnSignalRemoved (object sender, SignalEventArgs args)
+ {
+ OnSignalRemoved (args);
+ }
+
+ void OnSignalChanged (object sender, SignalChangedEventArgs args)
+ {
+ OnSignalChanged (args);
+ }
+
+ [GLib.ConnectBefore]
+ void WidgetEvent (object obj, Gtk.WidgetEventArgs args)
+ {
+ if (args.Event.Type == Gdk.EventType.ButtonPress)
+ args.RetVal = HandleClick ((Gdk.EventButton)args.Event);
+ }
+
+ internal bool HandleClick (Gdk.EventButton evb)
+ {
+ int x = (int)evb.X, y = (int)evb.Y;
+ int erx, ery, wrx, wry;
+
+ // Translate from event window to widget window coords
+ evb.Window.GetOrigin (out erx, out ery);
+ Wrapped.GdkWindow.GetOrigin (out wrx, out wry);
+ x += erx - wrx;
+ y += ery - wry;
+
+ Widget wrapper = FindWrapper (Wrapped, x, y);
+ if (wrapper == null)
+ return false;
+
+ if (wrapper.Wrapped != proj.Selection) {
+ wrapper.Select ();
+ return true;
+ } else if (evb.Button == 3) {
+ proj.PopupContextMenu (wrapper);
+ return true;
+ } else
+ return false;
+ }
+
+ Widget FindWrapper (Gtk.Widget top, int x, int y)
+ {
+ Widget wrapper;
+
+ Gtk.Container container = top as Gtk.Container;
+ if (container != null) {
+ foreach (Gtk.Widget child in container.AllChildren) {
+ if (!child.IsDrawable)
+ continue;
+
+ Gdk.Rectangle alloc = child.Allocation;
+ if (alloc.Contains (x, y)) {
+ if (child.GdkWindow == top.GdkWindow)
+ wrapper = FindWrapper (child, x, y);
+ else
+ wrapper = FindWrapper (child, x - alloc.X, y - alloc.Y);
+ if (wrapper != null)
+ return wrapper;
+ }
+ }
+ }
+
+ wrapper = Lookup (top);
+ if (wrapper == null || wrapper.Unselectable)
+ return null;
+ return wrapper;
+ }
+
+ void PopupMenu (object obj, EventArgs args)
+ {
+ proj.PopupContextMenu (this);
+ }
+
+ public void Select ()
+ {
+ proj.Selection = Wrapped;
+ }
+
+ public void Unselect ()
+ {
+ if (proj.Selection == Wrapped)
+ proj.Selection = null;
+ }
+
+ internal protected virtual void OnSelected ()
+ {
+ }
+
+ internal protected virtual void OnUnselected ()
+ {
+ }
+
+ public void Delete ()
+ {
+ if (Project.Selection == Wrapped)
+ Project.Selection = null;
+
+ if (ParentWrapper != null)
+ ParentWrapper.Delete (this);
+ else
+ Wrapped.Destroy ();
+ }
+
+ internal bool RequiresUndoStatusUpdate {
+ get { return requiresUndoStatusUpdate; }
+ set { requiresUndoStatusUpdate = value; }
+ }
+
+ public override ObjectWrapper FindObjectByUndoId (string id)
+ {
+ ObjectWrapper c = base.FindObjectByUndoId (id);
+ if (c != null)
+ return c;
+
+ if (actionGroups != null)
+ return actionGroups.FindObjectByUndoId (id);
+ else
+ return null;
+ }
+
+ public override object GetUndoDiff ()
+ {
+ XmlElement oldElem = UndoManager.GetObjectStatus (this);
+ XmlElement newElem = WriteProperties (new ObjectWriter (oldElem.OwnerDocument, FileFormat.Native));
+
+ ObjectDiff propsDiff = propDiffGenerator.GetDiff (newElem, oldElem);
+ ObjectDiff actionsDiff = LocalActionGroups.GetDiff (Project, oldElem);
+
+ UndoManager.UpdateObjectStatus (this, newElem);
+
+ if (propsDiff == null && actionsDiff == null)
+ return null;
+ else
+ return new ObjectDiff[] { propsDiff, actionsDiff };
+ }
+
+ public override object ApplyUndoRedoDiff (object diff)
+ {
+ ObjectDiff[] data = (ObjectDiff[]) diff;
+
+ XmlElement status = UndoManager.GetObjectStatus (this);
+ XmlElement oldElem = (XmlElement) status.CloneNode (true);
+
+ ObjectDiff propsDiff = data [0];
+
+ if (propsDiff != null) {
+ propDiffGenerator.ApplyDiff (status, propsDiff);
+ ReadProperties (new ObjectReader (Project, FileFormat.Native), status);
+ data [0] = propDiffGenerator.GetDiff (status, oldElem);
+ }
+
+ ObjectDiff actionsDiff = data [1];
+ if (actionsDiff != null) {
+ LocalActionGroups.ApplyDiff (Project, actionsDiff);
+ data [1] = LocalActionGroups.GetDiff (Project, oldElem);
+ }
+
+ return data;
+ }
+
+ public override void Read (ObjectReader reader, XmlElement elem)
+ {
+ ReadActionGroups (reader, elem);
+ ReadProperties (reader, elem);
+ }
+
+ protected void ReadActionGroups (ObjectReader reader, XmlElement elem)
+ {
+ if (reader.Format == FileFormat.Native) {
+ if (actionGroups == null) {
+ actionGroups = new ActionGroupCollection ();
+ actionGroups.SetOwner (this);
+ actionGroups.ActionGroupAdded += OnGroupAdded;
+ actionGroups.ActionGroupRemoved += OnGroupRemoved;
+ actionGroups.ActionGroupChanged += OnGroupChanged;
+ } else
+ actionGroups.Clear ();
+ foreach (XmlElement groupElem in elem.SelectNodes ("action-group")) {
+ ActionGroup actionGroup = new ActionGroup ();
+ actionGroup.Read (reader, groupElem);
+ actionGroups.Add (actionGroup);
+ }
+ }
+ }
+
+ protected virtual void ReadProperties (ObjectReader reader, XmlElement elem)
+ {
+ if (Wrapped != null) {
+ // There is already an instance. Load the default values.
+ this.ClassDescriptor.ResetInstance (Wrapped);
+ Signals.Clear ();
+ }
+
+ if (reader.Format == FileFormat.Native)
+ WidgetUtils.Read (this, elem);
+ else
+ GladeUtils.ImportWidget (this, elem);
+
+ string uid = elem.GetAttribute ("undoId");
+ if (uid.Length > 0)
+ UndoId = uid;
+ oldName = Wrapped.Name;
+ }
+
+ public override XmlElement Write (ObjectWriter writer)
+ {
+ XmlElement elem = WriteProperties (writer);
+ WriteActionGroups (writer, elem);
+ return elem;
+ }
+
+ protected virtual XmlElement WriteProperties (ObjectWriter writer)
+ {
+ if (writer.Format == FileFormat.Native) {
+ XmlElement elem = WidgetUtils.Write (this, writer.XmlDocument);
+ if (writer.CreateUndoInfo)
+ elem.SetAttribute ("undoId", UndoId);
+ return elem;
+ }
+ else {
+ XmlElement elem = GladeUtils.ExportWidget (this, writer.XmlDocument);
+ GladeUtils.ExtractProperty (elem, "name", "");
+ return elem;
+ }
+ }
+
+ protected void WriteActionGroups (ObjectWriter writer, XmlElement elem)
+ {
+ if (writer.Format == FileFormat.Native) {
+ if (actionGroups != null) {
+ foreach (ActionGroup actionGroup in actionGroups)
+ elem.InsertBefore (actionGroup.Write (writer), elem.FirstChild);
+ }
+ }
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ if (!String.IsNullOrEmpty (UIManagerName)) {
+ // Create an UI manager
+ CodeFieldReferenceExpression uixp = new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), UIManagerName);
+ CodeAssignStatement uim_init = new CodeAssignStatement (uixp, new CodeObjectCreateExpression (typeof (Gtk.UIManager).ToGlobalTypeRef ()));
+ ctx.Statements.Add (uim_init);
+
+ includedActionGroups = new ArrayList ();
+
+ // Generate action group creation
+ foreach (ActionGroup actionGroup in actionGroups) {
+
+ // Create the action group
+ string grpVar = ctx.NewId ();
+ CodeVariableDeclarationStatement uidec = new CodeVariableDeclarationStatement (
+ typeof (Gtk.ActionGroup).ToGlobalTypeRef (),
+ grpVar,
+ actionGroup.GenerateObjectCreation (ctx)
+ );
+ ctx.Statements.Add (uidec);
+ actionGroup.GenerateBuildCode (ctx, new CodeVariableReferenceExpression (grpVar));
+
+ // Insert the action group in the UIManager
+ CodeMethodInvokeExpression mi = new CodeMethodInvokeExpression (
+ uixp,
+ "InsertActionGroup",
+ new CodeVariableReferenceExpression (grpVar),
+ new CodePrimitiveExpression (includedActionGroups.Count)
+ );
+ ctx.Statements.Add (mi);
+
+ includedActionGroups.Add (actionGroup);
+ }
+
+ // Adds the accel group to the window
+ Window w = GetTopLevel () as Window;
+ if (w != null) {
+ CodeMethodInvokeExpression ami = new CodeMethodInvokeExpression (
+ ctx.WidgetMap.GetWidgetExp (w),
+ "AddAccelGroup",
+ new CodePropertyReferenceExpression (
+ uixp,
+ "AccelGroup"
+ )
+ );
+ ctx.Statements.Add (ami);
+ } else {
+ // There is no top level window, this must be a custom widget.
+ // The only option is to register the accel group when
+ // the widget is realized. This is done by the Bin wrapper.
+ }
+ }
+
+ if (tooltip != null && tooltip.Length > 0)
+ GetTopLevel().GenerateTooltip (ctx, this);
+
+ base.GenerateBuildCode (ctx, var);
+ }
+
+ internal protected override void GeneratePostBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ base.GeneratePostBuildCode (ctx, var);
+
+ // The visible property is generated here to ensure that widgets are made visible
+ // after they have been fully built
+
+ PropertyDescriptor prop = ClassDescriptor ["Visible"] as PropertyDescriptor;
+ if (prop != null && prop.PropertyType == typeof(bool) && !(bool) prop.GetValue (Wrapped)) {
+ ctx.Statements.Add (
+ new CodeMethodInvokeExpression (
+ var,
+ "Hide"
+ )
+ );
+ }
+
+ // The HasDefault property can only be assigned when the widget is added to the window
+ prop = ClassDescriptor ["HasDefault"] as PropertyDescriptor;
+ if (prop != null && (bool) prop.GetValue (Wrapped)) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ var,
+ "HasDefault"
+ ),
+ new CodePrimitiveExpression (true)
+ )
+ );
+ }
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ // Those properties are handled in GeneratePostBuildCode
+ if (prop.Name == "Visible" || prop.Name == "HasDefault")
+ return;
+
+ // Don't generate a name for unselectable widgets
+ if (prop.Name == "Name" && Unselectable)
+ return;
+
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+
+ protected CodeExpression GenerateUiManagerElement (GeneratorContext ctx, ActionTree tree)
+ {
+ Widget topLevel = GetTopLevel ();
+ string uiName = topLevel.UIManagerName;
+ if (uiName != null) {
+ CodeFieldReferenceExpression uiManager = new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), uiName);
+ if (topLevel.includedActionGroups == null)
+ topLevel.includedActionGroups = new ArrayList ();
+
+ // Add to the uimanager all action groups required by the
+ // actions of the tree
+
+ foreach (ActionGroup grp in tree.GetRequiredGroups ()) {
+ if (!topLevel.includedActionGroups.Contains (grp)) {
+ // Insert the action group in the UIManager
+ CodeMethodInvokeExpression mi = new CodeMethodInvokeExpression (
+ uiManager,
+ "InsertActionGroup",
+ ctx.GenerateValue (grp, typeof(ActionGroup)),
+ new CodePrimitiveExpression (topLevel.includedActionGroups.Count)
+ );
+ ctx.Statements.Add (mi);
+ topLevel.includedActionGroups.Add (grp);
+ }
+ }
+
+ tree.GenerateBuildCode (ctx, uiManager);
+ return new CodeMethodInvokeExpression (
+ uiManager,
+ "GetWidget",
+ new CodePrimitiveExpression ("/" + Wrapped.Name)
+ );
+ }
+ return null;
+ }
+
+ public static new Widget Lookup (GLib.Object obj)
+ {
+ return Stetic.ObjectWrapper.Lookup (obj) as Stetic.Wrapper.Widget;
+ }
+
+ PropertyDescriptor internalChildProperty;
+ public PropertyDescriptor InternalChildProperty {
+ get {
+ return internalChildProperty;
+ }
+ set {
+ internalChildProperty = value;
+ }
+ }
+
+ public virtual void Drop (Gtk.Widget widget, object faultId)
+ {
+ widget.Destroy ();
+ }
+
+ public virtual bool HExpandable { get { return hexpandable; } }
+ public virtual bool VExpandable { get { return vexpandable; } }
+
+ public bool Visible {
+ get {
+ return window_visible;
+ }
+ set {
+ window_visible = value;
+ EmitNotify ("Visible");
+ }
+ }
+
+ public bool HasDefault {
+ get {
+ return hasDefault;
+ }
+ set {
+ hasDefault = value;
+ EmitNotify ("HasDefault");
+ if (hasDefault && !CanDefault)
+ CanDefault = true;
+ }
+ }
+
+ public bool CanDefault {
+ get {
+ return canDefault;
+ }
+ set {
+ canDefault = value;
+ EmitNotify ("CanDefault");
+ if (!canDefault && HasDefault)
+ HasDefault = false;
+ }
+ }
+
+ public bool Sensitive {
+ get {
+ return Wrapped.Sensitive;
+ }
+ set {
+ if (Wrapped.Sensitive == value)
+ return;
+
+ Wrapped.Sensitive = value;
+ if (Wrapped.Sensitive)
+ InsensitiveManager.Remove (this);
+ else
+ InsensitiveManager.Add (this);
+ EmitNotify ("Sensitive");
+ }
+ }
+
+ public Gdk.EventMask Events {
+ get {
+ return events;
+ }
+ set {
+ events = value;
+ EmitNotify ("Events");
+ }
+ }
+
+ public bool CanFocus {
+ get {
+ return canFocus;
+ }
+ set {
+ canFocus = value;
+ EmitNotify ("CanFocus");
+ }
+ }
+
+ public string Tooltip {
+ get {
+ return tooltip;
+ }
+ set {
+ tooltip = value;
+ }
+ }
+
+ public bool ShowScrollbars {
+ get {
+ return boundToScrollWindow;
+ }
+ set {
+ if (boundToScrollWindow != value) {
+ boundToScrollWindow = value;
+ UpdateScrolledWindow ();
+ EmitNotify ("ShowScrollbars");
+ }
+ }
+ }
+
+ internal void UpdateScrolledWindow ()
+ {
+ if (ParentWrapper == null)
+ return;
+ if (boundToScrollWindow) {
+ if (!(Wrapped.Parent is Gtk.Viewport) && !(Wrapped.Parent is Gtk.ScrolledWindow)) {
+ Gtk.ScrolledWindow scw = new Gtk.ScrolledWindow ();
+ scw.HscrollbarPolicy = scw.VscrollbarPolicy = Gtk.PolicyType.Automatic;
+ scw.ShadowType = Gtk.ShadowType.In;
+ ScrolledWindow wrapper = (ScrolledWindow) ObjectWrapper.Create (Project, scw, ParentWrapper);
+ ParentWrapper.ReplaceChild (Wrapped, scw, false);
+ if (Wrapped.SetScrollAdjustments (null, null))
+ scw.Add (Wrapped);
+ else
+ wrapper.AddWithViewport (Wrapped);
+ Select ();
+ }
+ }
+ else if (((Wrapped.Parent is Gtk.Viewport) || (Wrapped.Parent is Gtk.ScrolledWindow)) && ParentWrapper.ParentWrapper != null) {
+ Gtk.Container parent = (Gtk.Container) Wrapped.Parent;
+ parent.Remove (Wrapped);
+ Container grandParent;
+ if (parent is Gtk.Viewport) {
+ parent = (Gtk.Container) parent.Parent;
+ grandParent = Container.LookupParent (parent);
+ }
+ else
+ grandParent = Container.LookupParent (parent);
+ grandParent.ReplaceChild (parent, Wrapped, true);
+ }
+ }
+
+ public bool InWindow {
+ get {
+ return this.GetTopLevel ().Wrapped is TopLevelWindow;
+ }
+ }
+
+ public bool IsScrollable {
+ get {
+ return !IsTopLevel && !(Wrapped is Gtk.ScrolledWindow);
+ }
+ }
+
+ public override string ToString ()
+ {
+ if (Wrapped == null)
+ return base.ToString ();
+ else if (Wrapped.Name != null)
+ return "[" + Wrapped.GetType ().Name + " '" + Wrapped.Name + "' " + Wrapped.GetHashCode ().ToString () + "]";
+ else
+ return "[" + Wrapped.GetType ().Name + " " + Wrapped.GetHashCode ().ToString () + "]";
+ }
+
+ public IDesignArea GetDesignArea ()
+ {
+ return GetDesignArea (Wrapped);
+ }
+
+ protected IDesignArea GetDesignArea (Gtk.Widget w)
+ {
+ while (w != null && !(w is IDesignArea))
+ w = w.Parent;
+ return w as IDesignArea;
+ }
+
+ protected override void EmitNotify (string propertyName)
+ {
+ // Don't notify parent change for top level widgets.
+ if (propertyName == "parent" || propertyName == "has-focus" ||
+ propertyName == "has-toplevel-focus" || propertyName == "is-active" ||
+ propertyName == "is-focus" || propertyName == "style" ||
+ propertyName == "Visible" || propertyName == "scroll-offset")
+ return;
+
+ if (propertyName == "Name") {
+ if (Wrapped.Name != oldName) {
+ if (ParentWrapper != null) {
+ string nn = ParentWrapper.GetValidWidgetName (Wrapped);
+ if (nn != Wrapped.Name) {
+ // The name was not valid, so it has to be changed again.
+ // Don't fire the changed event now, will be fired after the following change
+ Wrapped.Name = nn;
+ return;
+ }
+ }
+
+ // This fires the changed event
+ base.EmitNotify (propertyName);
+
+ string on = oldName;
+ oldName = Wrapped.Name;
+ if (!Loading)
+ OnNameChanged (new WidgetNameChangedArgs (this, on, Wrapped.Name));
+
+ // Keep the member name in sync with the widget name
+ if (on == MemberName)
+ MemberName = Wrapped.Name;
+ }
+ }
+ else if (propertyName == "MemberName") {
+ if (MemberName != oldMemberName) {
+ base.EmitNotify (propertyName);
+ string on = oldMemberName;
+ oldMemberName = MemberName;
+ if (!Loading)
+ OnMemberNameChanged (new WidgetNameChangedArgs (this, on, MemberName));
+ }
+ }
+ else {
+// Console.WriteLine ("PROP: " + propertyName);
+ base.EmitNotify (propertyName);
+ }
+ }
+
+ protected virtual void OnNameChanged (WidgetNameChangedArgs args)
+ {
+ if (Project != null)
+ Project.NotifyNameChanged (args);
+ if (NameChanged != null)
+ NameChanged (this, args);
+ }
+
+ protected virtual void OnMemberNameChanged (WidgetNameChangedArgs args)
+ {
+ if (MemberNameChanged != null)
+ MemberNameChanged (this, args);
+ }
+
+ bool IEditableObject.CanCopy {
+ get { return ClipboardCanCopy; }
+ }
+
+ bool IEditableObject.CanCut {
+ get { return ClipboardCanCut; }
+ }
+
+ bool IEditableObject.CanPaste {
+ get { return ClipboardCanPaste; }
+ }
+
+ bool IEditableObject.CanDelete {
+ get { return CanDelete; }
+ }
+
+ void IEditableObject.Copy ()
+ {
+ ClipboardCopy ();
+ }
+
+ void IEditableObject.Cut ()
+ {
+ ClipboardCut ();
+ }
+
+ void IEditableObject.Paste ()
+ {
+ ClipboardPaste ();
+ }
+
+ void IEditableObject.Delete ()
+ {
+ Delete ();
+ }
+
+ protected virtual bool ClipboardCanCopy {
+ get { return !IsTopLevel; }
+ }
+
+ protected virtual bool ClipboardCanCut {
+ get { return InternalChildProperty == null && !IsTopLevel; }
+ }
+
+ protected virtual bool ClipboardCanPaste {
+ get { return false; }
+ }
+
+ protected virtual bool CanDelete {
+ get { return ClipboardCanCut; }
+ }
+
+ protected virtual void ClipboardCopy ()
+ {
+ Clipboard.Copy (Wrapped);
+ }
+
+ protected virtual void ClipboardCut ()
+ {
+ Clipboard.Cut (Wrapped);
+ }
+
+ protected virtual void ClipboardPaste ()
+ {
+ }
+ }
+
+ internal static class InsensitiveManager {
+
+ static Gtk.Invisible invis;
+ static Hashtable map;
+
+ static InsensitiveManager ()
+ {
+ map = new Hashtable ();
+ invis = new Gtk.Invisible ();
+ invis.ButtonPressEvent += ButtonPress;
+ }
+
+ static void ButtonPress (object obj, Gtk.ButtonPressEventArgs args)
+ {
+ Gtk.Widget widget = (Gtk.Widget)map[args.Event.Window];
+ if (widget == null)
+ return;
+
+ Widget wrapper = Widget.Lookup (widget);
+ args.RetVal = wrapper.HandleClick (args.Event);
+ }
+
+ public static void Add (Widget wrapper)
+ {
+ Gtk.Widget widget = wrapper.Wrapped;
+
+ widget.SizeAllocated += Insensitive_SizeAllocate;
+ widget.Realized += Insensitive_Realized;
+ widget.Unrealized += Insensitive_Unrealized;
+ widget.Mapped += Insensitive_Mapped;
+ widget.Unmapped += Insensitive_Unmapped;
+
+ if (widget.IsRealized)
+ Insensitive_Realized (widget, EventArgs.Empty);
+ if (widget.IsMapped)
+ Insensitive_Mapped (widget, EventArgs.Empty);
+ }
+
+ public static void Remove (Widget wrapper)
+ {
+ Gtk.Widget widget = wrapper.Wrapped;
+ Gdk.Window win = (Gdk.Window)map[widget];
+ if (win != null) {
+ map.Remove (widget);
+ map.Remove (win);
+ win.Destroy ();
+ }
+ widget.SizeAllocated -= Insensitive_SizeAllocate;
+ widget.Realized -= Insensitive_Realized;
+ widget.Unrealized -= Insensitive_Unrealized;
+ widget.Mapped -= Insensitive_Mapped;
+ widget.Unmapped -= Insensitive_Unmapped;
+ }
+
+ static void Insensitive_SizeAllocate (object obj, Gtk.SizeAllocatedArgs args)
+ {
+ Gdk.Window win = (Gdk.Window)map[obj];
+ if (win != null)
+ win.MoveResize (args.Allocation);
+ }
+
+ static void Insensitive_Realized (object obj, EventArgs args)
+ {
+ Gtk.Widget widget = (Gtk.Widget)obj;
+
+ Gdk.WindowAttr attributes = new Gdk.WindowAttr ();
+ attributes.WindowType = Gdk.WindowType.Child;
+ attributes.Wclass = Gdk.WindowClass.InputOnly;
+ attributes.Mask = Gdk.EventMask.ButtonPressMask;
+
+ Gdk.Window win = new Gdk.Window (widget.GdkWindow, attributes, 0);
+ win.UserData = invis.Handle;
+ win.MoveResize (widget.Allocation);
+
+ map[widget] = win;
+ map[win] = widget;
+ }
+
+ static void Insensitive_Mapped (object obj, EventArgs args)
+ {
+ Gdk.Window win = (Gdk.Window)map[obj];
+ win.Show ();
+ }
+
+ static void Insensitive_Unmapped (object obj, EventArgs args)
+ {
+ Gdk.Window win = (Gdk.Window)map[obj];
+ win.Hide ();
+ }
+
+ static void Insensitive_Unrealized (object obj, EventArgs args)
+ {
+ Gdk.Window win = (Gdk.Window)map[obj];
+ win.Destroy ();
+ map.Remove (obj);
+ map.Remove (win);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetEventHandler.cs
new file mode 100644
index 0000000000..e6af45e1f6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetEventHandler.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Stetic.Wrapper
+{
+ public delegate void WidgetEventHandler (object sender, WidgetEventArgs args);
+
+ public class WidgetEventArgs: EventArgs
+ {
+ Stetic.Wrapper.Widget wrapper;
+ Gtk.Widget widget;
+
+ public WidgetEventArgs (Gtk.Widget widget)
+ {
+ this.widget = widget;
+ wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+ }
+
+ public WidgetEventArgs (Stetic.Wrapper.Widget wrapper)
+ {
+ this.wrapper = wrapper;
+ if (wrapper != null)
+ this.widget = wrapper.Wrapped;
+ }
+
+ public Gtk.Widget Widget {
+ get { return widget; }
+ }
+
+ public Widget WidgetWrapper {
+ get { return wrapper; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetNameChangedHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetNameChangedHandler.cs
new file mode 100644
index 0000000000..0d2df19114
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/WidgetNameChangedHandler.cs
@@ -0,0 +1,25 @@
+
+namespace Stetic.Wrapper
+{
+ public delegate void WidgetNameChangedHandler (object sender, WidgetNameChangedArgs args);
+
+ public class WidgetNameChangedArgs: WidgetEventArgs
+ {
+ string oldName;
+ string newName;
+
+ public WidgetNameChangedArgs (Stetic.Wrapper.Widget widget, string oldName, string newName): base (widget)
+ {
+ this.oldName = oldName;
+ this.newName = newName;
+ }
+
+ public string OldName {
+ get { return oldName; }
+ }
+
+ public string NewName {
+ get { return newName; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Window.cs b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Window.cs
new file mode 100644
index 0000000000..5210e47a42
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/Window.cs
@@ -0,0 +1,223 @@
+using GLib;
+using System;
+using System.CodeDom;
+using System.Collections;
+
+namespace Stetic.Wrapper {
+
+ public class Window : Container {
+
+ public override void Wrap (object obj, bool initialized)
+ {
+ TopLevelWindow window = (TopLevelWindow) obj;
+ RootWrapperName = window.Name;
+
+ //during Wrap RootWrapperName will be set in the children widgets
+ base.Wrap (obj, initialized);
+
+ if (!initialized) {
+ if (window.Child is Placeholder)
+ window.Child.SetSizeRequest (200, 200);
+ }
+
+ window.DeleteEvent += DeleteEvent;
+ }
+
+ public static TopLevelWindow CreateInstance ( )
+ {
+ TopLevelWindow t = new TopLevelWindow ();
+ return t;
+ }
+
+ public override void Dispose ( )
+ {
+ Wrapped.DeleteEvent -= DeleteEvent;
+ base.Dispose ();
+ }
+
+ [ConnectBefore]
+ void DeleteEvent (object obj, Gtk.DeleteEventArgs args)
+ {
+ Wrapped.Hide ();
+ args.RetVal = true;
+ }
+
+ public override bool HExpandable { get { return true; } }
+ public override bool VExpandable { get { return true; } }
+
+ public bool Modal {
+ get {
+ return window.Modal;
+ }
+ set {
+ window.Modal = value;
+ EmitNotify ("Modal");
+ }
+ }
+
+ public Gdk.WindowTypeHint TypeHint {
+ get {
+ return window.TypeHint;
+ }
+ set {
+ window.TypeHint = value;
+ EmitNotify ("TypeHint");
+ }
+ }
+
+ Gtk.WindowType type;
+ public Gtk.WindowType Type {
+ get {
+ return type;
+ }
+ set {
+ type = value;
+ EmitNotify ("Type");
+ }
+ }
+
+ Gtk.WindowPosition windowPosition;
+ public Gtk.WindowPosition WindowPosition {
+ get {
+ return windowPosition;
+ }
+ set {
+ windowPosition = value;
+ EmitNotify ("WindowPosition");
+ }
+ }
+
+ ImageInfo icon;
+ public ImageInfo Icon {
+ get {
+ return icon;
+ }
+ set {
+ icon = value;
+ EmitNotify ("Icon");
+ }
+ }
+
+ TopLevelWindow window {
+ get { return (TopLevelWindow) Wrapped; }
+ }
+
+ public string Title {
+ get { return window.Title; }
+ set { window.Title = value; EmitNotify ("Title"); }
+ }
+
+ public bool Resizable
+ {
+ get { return window.Resizable; }
+ set { window.Resizable = value; EmitNotify ("Resizable"); }
+ }
+
+ bool allowGrow = true;
+ public bool AllowGrow {
+ get { return allowGrow; }
+ set { allowGrow = value; EmitNotify ("AllowGrow"); }
+ }
+
+ bool allowShrink = false;
+ public bool AllowShrink {
+ get { return allowShrink; }
+ set { allowShrink = value; EmitNotify ("AllowShrink"); }
+ }
+
+ int defaultWidth = -1;
+ public int DefaultWidth {
+ get { return defaultWidth; }
+ set { defaultWidth = value; EmitNotify ("DefaultWidth"); }
+ }
+
+ int defaultHeight = -1;
+ public int DefaultHeight {
+ get { return defaultHeight; }
+ set { defaultHeight = value; EmitNotify ("DefaultHeight"); }
+ }
+
+ bool acceptFocus = true;
+ public bool AcceptFocus {
+ get { return acceptFocus; }
+ set { acceptFocus = value; EmitNotify ("AcceptFocus"); }
+ }
+
+ bool decorated = true;
+ public bool Decorated {
+ get { return decorated; }
+ set { decorated = value; EmitNotify ("Decorated"); }
+ }
+
+ bool destroyWithParent;
+ public bool DestroyWithParent {
+ get { return destroyWithParent; }
+ set { destroyWithParent = value; EmitNotify ("DestroyWithParent"); }
+ }
+
+ Gdk.Gravity gravity = Gdk.Gravity.NorthWest;
+ public Gdk.Gravity Gravity {
+ get { return gravity; }
+ set { gravity = value; EmitNotify ("Gravity"); }
+ }
+
+ string role;
+ public string Role {
+ get { return role; }
+ set { role = value; EmitNotify ("Role"); }
+ }
+
+ bool skipPagerHint;
+ public bool SkipPagerHint {
+ get { return skipPagerHint; }
+ set { skipPagerHint = value; EmitNotify ("SkipPagerHint"); }
+ }
+
+ bool skipTaskbarHint;
+ public bool SkipTaskbarHint {
+ get { return skipTaskbarHint; }
+ set { skipTaskbarHint = value; EmitNotify ("SkipTaskbarHint"); }
+ }
+
+ bool focusOnMap = true;
+ public bool FocusOnMap {
+ get { return focusOnMap; }
+ set { focusOnMap = value; EmitNotify ("FocusOnMap"); }
+ }
+
+ internal protected override void GenerateBuildCode (GeneratorContext ctx, CodeExpression var)
+ {
+ base.GenerateBuildCode (ctx, var);
+
+ if (DefaultWidth == -1) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ var,
+ "DefaultWidth"
+ ),
+ new CodePrimitiveExpression (DesignWidth)
+ )
+ );
+ }
+
+ if (DefaultHeight == -1) {
+ ctx.Statements.Add (
+ new CodeAssignStatement (
+ new CodePropertyReferenceExpression (
+ var,
+ "DefaultHeight"
+ ),
+ new CodePrimitiveExpression (DesignHeight)
+ )
+ );
+ }
+ }
+
+ protected override void GeneratePropertySet (GeneratorContext ctx, CodeExpression var, PropertyDescriptor prop)
+ {
+ if (prop.Name != "Type")
+ base.GeneratePropertySet (ctx, var, prop);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/objects.xml b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/objects.xml
new file mode 100644
index 0000000000..9fd1d2a919
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/objects.xml
@@ -0,0 +1,2274 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<objects xmlns:xsl="http://www.w3.org/1999/XSL/Transform" gtk-version="2.4">
+
+ <object type="Gtk.Widget,gtk-sharp" wrapper="Stetic.Wrapper.Widget">
+ <itemgroups>
+ <itemgroup label="Common Widget Properties">
+ <property name="MemberName"
+ editor="Stetic.Editor.Identifier"
+ description="Name of the member to which this widget is bound." />
+ <property name="WidthRequest" min="-1" />
+ <property name="HeightRequest" min="-1" />
+ <property name="Visible" glade-override="true" default="true"/>
+ <property name="Sensitive" glade-override="true" />
+ <property name="Tooltip" label="Tooltip" glade-name="tooltip"
+ description="Tooltip for this widget"
+ translatable="true" />
+ <property name="CanDefault" />
+ <property name="InWindow" internal="true"/>
+ <property name="HasDefault" glade-override="true">
+ <invisible-if name="InWindow" value="false" />
+ </property>
+ <property name="CanFocus" />
+ <property name="Events" default="0"/>
+ <property name="ExtensionEvents" />
+ <property name="IsScrollable" internal="true"/>
+ <property name="ShowScrollbars" label="Show Scrollbars" default="false">
+ <invisible-if name="IsScrollable" value="false" />
+ </property>
+ <property name="GeneratePublic" internal="true" default="true"/>
+ <property name="Name" internal="true"
+ min="1"
+ init-with-name="true"
+ editor="Stetic.Editor.Identifier"/>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Common Widget Signals">
+ <signal name="AccelCanActivate" />
+ <signal name="AccelClosuresChanged" />
+ <signal name="ButtonPressEvent" />
+ <signal name="ButtonReleaseEvent" />
+ <signal name="ChildNotified" />
+ <signal name="ClientEvent" />
+ <signal name="ConfigureEvent" />
+ <signal name="DeleteEvent" />
+ <signal name="DestroyEvent" />
+ <signal name="DirectionChanged" />
+ <signal name="DragBegin" />
+ <signal name="DragDataDelete"/>
+ <signal name="DragDataGet" />
+ <signal name="DragDataReceived" />
+ <signal name="DragDrop" />
+ <signal name="DragEnd" />
+ <signal name="DragLeave" />
+ <signal name="DragMotion" />
+ <signal name="EnterNotifyEvent" />
+ <signal name="ExposeEvent" />
+ <signal name="Focused" />
+ <signal name="FocusGrabbed" />
+ <signal name="FocusInEvent" />
+ <signal name="FocusOutEvent" />
+ <signal name="GrabBrokenEvent" gtk-version="2.8"/>
+ <signal name="GrabNotify" />
+ <signal name="HelpShown" />
+ <signal name="Hidden" />
+ <signal name="HierarchyChanged" />
+ <signal name="KeyPressEvent" />
+ <signal name="KeyReleaseEvent" />
+ <signal name="LeaveNotifyEvent" />
+ <signal name="MapEvent" />
+ <signal name="Mapped" />
+ <signal name="MnemonicActivated" />
+ <signal name="MotionNotifyEvent" />
+ <signal name="NoExposeEvent" />
+ <signal name="ParentSet" />
+ <signal name="PopupMenu" />
+ <signal name="PropertyNotifyEvent" />
+ <signal name="ProximityInEvent" />
+ <signal name="ProximityOutEvent" />
+ <signal name="Realized" />
+ <signal name="ScreenChanged" />
+ <signal name="ScrollEvent" />
+ <signal name="SelectionClearEvent" />
+ <signal name="SelectionGet" />
+ <signal name="SelectionNotifyEvent" />
+ <signal name="SelectionReceived" />
+ <signal name="SelectionRequestEvent" />
+ <signal name="Shown" />
+ <signal name="SizeAllocated" />
+ <signal name="SizeRequested" />
+ <signal name="StateChanged" />
+ <signal name="StyleSet" />
+ <signal name="UnmapEvent" />
+ <signal name="Unmapped" />
+ <signal name="Unrealized" />
+ <signal name="VisibilityNotifyEvent" />
+ <signal name="WidgetEvent" />
+ <signal name="WidgetEventAfter" />
+ <signal name="WindowStateEvent" />
+ </itemgroup>
+ </signals>
+
+ <glade-transform>
+ <!-- "events" property has extra spaces around "|"s -->
+ <import>
+ <xsl:template match="widget/property[@name='events']/text()">
+ <xsl:call-template name="GtkWidget_fixevents2">
+ <xsl:with-param name="string" select="." />
+ </xsl:call-template>
+ </xsl:template>
+ <xsl:template name="GtkWidget_fixevents2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, ' | ')">
+ <xsl:value-of select="substring-before($string, ' | ')"/>
+ <xsl:text>|</xsl:text>
+ <xsl:call-template name="GtkWidget_fixevents2">
+ <xsl:with-param name="string" select="substring-after($string, ' | ')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$string" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ </import>
+ <export>
+ <xsl:template match="widget/property[@name='events']/text()">
+ <xsl:call-template name="GtkWidget_breakevents2">
+ <xsl:with-param name="string" select="." />
+ </xsl:call-template>
+ </xsl:template>
+ <xsl:template name="GtkWidget_breakevents2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '|')">
+ <xsl:value-of select="substring-before($string, '|')"/>
+ <xsl:text> | </xsl:text>
+ <xsl:call-template name="GtkWidget_breakevents2">
+ <xsl:with-param name="string" select="substring-after($string, '|')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$string" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ </export>
+ </glade-transform>
+ </object>
+
+ <object type="Gtk.Container,gtk-sharp" wrapper="Stetic.Wrapper.Container" base-type="Gtk.Widget">
+ <itemgroups>
+ <itemgroup name="Commands">
+ <command name="IncreaseBorderWidth" label="Increase Border Width" icon="res:inc-border.png" />
+ <command name="DecreaseBorderWidth" label="Decrease Border Width" icon="res:dec-border.png" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Container Signals">
+ <signal name="Added" />
+ <signal name="FocusChildSet" />
+ <signal name="Removed" />
+ <signal name="ResizeChecked" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Container+ContainerChild,gtk-sharp" wrapper="Stetic.Wrapper.Container+ContainerChild" />
+
+ <object type="Gtk.Window,gtk-sharp" base-type="Gtk.Container" wrapper="Stetic.Wrapper.Window"
+ label="Window" icon="window.png" palette-category="window" init-properties="Type">
+ <itemgroups>
+ <itemgroup label="Window Properties">
+ <property name="Title" init-with-name="true" translatable="true" />
+ <property name="Icon" />
+ <property name="Type" glade-override="true" internal="true" />
+ <property name="TypeHint" glade-override="true" />
+ <property name="WindowPosition" />
+ <property name="Modal" glade-override="true" default="false" />
+ <property name="BorderWidth" default="0"/>
+ </itemgroup>
+ <itemgroup label="Window Size Properties" name="Size">
+ <property name="Resizable" default="true"/>
+ <property name="AllowGrow" default="true"/>
+ <property name="AllowShrink" default="false"/>
+ <property name="DefaultWidth" min="-1"/>
+ <property name="DefaultHeight" min="-1"/>
+ </itemgroup>
+ <itemgroup label="Miscellaneous Window Properties" name="Misc">
+ <property name="AcceptFocus" default="true"/>
+ <property name="Decorated" default="true"/>
+ <property name="DestroyWithParent" default="false"/>
+ <property name="Gravity" default="NorthWest"/>
+ <property name="Role" />
+ <property name="SkipPagerHint" default="false"/>
+ <property name="SkipTaskbarHint" default="false"/>
+ <property name="FocusOnMap" gtk-version="2.6"/>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Window Signals">
+ <signal name="DefaultActivated" />
+ <signal name="FrameEvent" />
+ <signal name="FocusActivated" />
+ <signal name="KeysChanged" />
+ <signal name="MoveFocus" />
+ <signal name="SetFocus" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Misc,gtk-sharp" wrapper="Stetic.Wrapper.Misc" base-type="Gtk.Widget">
+ <itemgroups>
+ <itemgroup label="Miscellaneous Alignment Properties">
+ <property name="Xpad" />
+ <property name="Ypad" />
+ <property name="Xalign" min="0.0" max="1.0" />
+ <property name="Yalign" min="0.0" max="1.0" />
+ <command name="AlignLeft" label="Align Left" icon="gtk-justify-left" />
+ <command name="AlignCenter" label="Align Center" icon="gtk-justify-center" />
+ <command name="AlignRight" label="Align Right" icon="gtk-justify-right" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Paned,gtk-sharp" wrapper="Stetic.Wrapper.Paned" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Pane Properties">
+ <property name="Position" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Paned Signals">
+ <signal name="CycleChildFocus" />
+ <signal name="ToggleHandleFocus" />
+ <signal name="AcceptPosition" />
+ <signal name="CancelPosition" />
+ <signal name="MoveHandle" />
+ </itemgroup>
+ </signals>
+ </object>
+ <object type="Gtk.Paned+PanedChild,gtk-sharp">
+ <itemgroups>
+ <itemgroup label="Pane Child Layout">
+ <property name="Resize" />
+ <property name="Shrink" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Range,gtk-sharp" wrapper="Stetic.Wrapper.Range" base-type="Gtk.Widget">
+ <itemgroups>
+ <itemgroup label="Range Properties">
+ <property name="UpdatePolicy" />
+ <property name="Inverted" />
+ <property name="Adjustment.Lower" />
+ <property name="Adjustment.Upper" />
+ <property name="Adjustment.PageIncrement" />
+ <property name="Adjustment.PageSize" />
+ <property name="Adjustment.StepIncrement" />
+ <property name="Adjustment.Value" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Range Signals">
+ <signal name="AdjustBounds" />
+ <signal name="ValueChanged" />
+ <signal name="MoveSlider" />
+ <signal name="ChangeValue" gtk-version="2.6"/>
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Scale,gtk-sharp" wrapper="Stetic.Wrapper.Scale" base-type="Gtk.Range">
+ <itemgroups>
+ <itemgroup label="Scale Properties">
+ <property name="DrawValue" ignore-default="true" />
+ <property name="Digits">
+ <disabled-if name="DrawValue" value="false" />
+ </property>
+ <property name="ValuePos" ignore-default="true" >
+ <disabled-if name="DrawValue" value="false" />
+ </property>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Scale Signals">
+ <signal name="FormatValue" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Alignment,gtk-sharp" base-type="Gtk.Container" label="Alignment" icon="alignment.png"
+ init-properties="Xalign Yalign Xscale Yscale" palette-category="container">
+ <itemgroups>
+ <itemgroup label="Alignment Properties">
+ <property name="Xscale" />
+ <property name="Yscale" />
+ <property name="Xalign" />
+ <property name="Yalign" />
+ <property name="LeftPadding" />
+ <property name="TopPadding" />
+ <property name="RightPadding" />
+ <property name="BottomPadding" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Arrow,gtk-sharp" base-type="Gtk.Misc"
+ label="Arrow" icon="arrow.png" palette-category="widget" init-properties="ArrowType ShadowType">
+ <itemgroups>
+ <itemgroup label="Arrow Properties">
+ <property name="ArrowType" />
+ <property name="ShadowType" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Bin,gtk-sharp" base-type="Gtk.Container" wrapper="Stetic.Wrapper.Bin"
+ label="Bin" icon="custom.png">
+ </object>
+
+ <object type="Gtk.Box,gtk-sharp" wrapper="Stetic.Wrapper.Box" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Box Properties">
+ <property name="Homogeneous" />
+ <property name="Spacing" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ <contextmenu>
+ <command name="InsertBefore" label="Insert Before"
+ description="Insert an empty row/column before the selected one">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+
+ <command name="InsertAfter" label="Insert After"
+ description="Insert an empty row/column after the selected one">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ </contextmenu>
+ </object>
+
+ <object type="Gtk.Box+BoxChild,gtk-sharp" wrapper="Stetic.Wrapper.Box+BoxChild">
+ <itemgroups>
+ <itemgroup label="Box Child Layout">
+ <property name="PackType" />
+ <property name="Position" ignore-default="true"/>
+ <property name="AutoSize" label="Auto Size"
+ description="If set, the other packing properties for this cell will be automatically adjusted as other widgets are added to and removed from the container" />
+ <property name="Expand">
+ <disabled-if name="AutoSize" value="true" />
+ </property>
+ <property name="Fill">
+ <disabled-if name="AutoSize" value="true" />
+ <disabled-if name="Expand" value="false" />
+ </property>
+ <property name="Padding" />
+ <command name="BoxExpand" label="Expand" icon="res:box-expand.png" />
+ <command name="BoxFill" label="Fill" icon="res:box-fill.png" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.ButtonBox,gtk-sharp" base-type="Gtk.Box" wrapper="Stetic.Wrapper.ButtonBox">
+ <itemgroups>
+ <itemgroup label="Button Box Properties">
+ <property name="Size" label="Size"
+ description="The number of buttons"
+ min="0" />
+ <property name="LayoutStyle" />
+ </itemgroup>
+ </itemgroups>
+ <contextmenu>
+ <command name="InsertBefore" label="Insert Button Before"
+ description="Insert a new button before the selected one" >
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ <command name="InsertAfter" label="Insert Button After"
+ description="Insert a new button after the selected one">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ </contextmenu>
+ </object>
+ <object type="Gtk.ButtonBox+ButtonBoxChild,gtk-sharp" wrapper="Stetic.Wrapper.ButtonBox+ButtonBoxChild">
+ <itemgroups>
+ <itemgroup label="Button Box Child Layout">
+ <property name="InDialog" internal="true" />
+ <property name="Secondary">
+ <invisible-if name="InDialog" value="true" />
+ </property>
+ <property name="Position" />
+ <property name="Expand" />
+ <property name="Fill">
+ <disabled-if name="Expand" value="false" />
+ </property>
+ <property name="Padding" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Button,gtk-sharp" wrapper="Stetic.Wrapper.Button" base-type="Gtk.Container"
+ label="Button" icon="button.png" palette-category="widget">
+ <itemgroups>
+ <itemgroup label="Button Properties">
+ <property name="UseStock" internal="true" />
+ <property name="Type" label="Button Type"
+ description="The type of button" />
+ <property name="StockId" label="Stock Item"
+ description="The stock button ID"
+ editor="Stetic.Editor.StockItem">
+ <invisible-if name="Type" value="TextOnly" />
+ <invisible-if name="Type" value="TextAndIcon" />
+ <invisible-if name="Type" value="Custom" />
+ </property>
+ <property name="Icon" label="Icon"
+ description="The icon to display in the button"
+ editor="Stetic.Editor.ImageSelector">
+ <invisible-if name="Type" value="StockItem" />
+ <invisible-if name="Type" value="TextOnly" />
+ <invisible-if name="Type" value="Custom" />
+ </property>
+ <property name="Label" translatable="true">
+ <invisible-if name="Type" value="StockItem" />
+ <invisible-if name="Type" value="Custom" />
+ </property>
+ <property name="UseUnderline">
+ <invisible-if name="Type" value="StockItem" />
+ <invisible-if name="Type" value="Custom" />
+ </property>
+ <property name="IsDialogButton" internal="true" />
+ <property name="ResponseId" label="Response Id" glade-name="response_id"
+ description="The response ID to emit when this button is clicked."
+ editor="Stetic.Editor.ResponseId">
+ <invisible-if name="IsDialogButton" value="false" />
+ </property>
+ </itemgroup>
+ <itemgroup label="Extra Button Properties" name="Extra">
+ <property name="FocusOnClick" />
+ <property name="Relief" />
+ <property name="Xalign" />
+ <property name="Yalign" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Button Signals">
+ <signal name="Activated" />
+ <signal name="Clicked" />
+ <signal name="Entered" />
+ <signal name="Left" />
+ <signal name="Pressed" />
+ <signal name="Released" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Calendar,gtk-sharp" base-type="Gtk.Widget"
+ label="Calendar" icon="calendar.png" palette-category="widget">
+ <itemgroups>
+ <itemgroup label="Calendar Properties">
+ <property name="DisplayOptions" glade-name="display_options" internal="true" />
+ <property name="ShowHeading" />
+ <property name="ShowDayNames" />
+ <property name="ShowWeekNumbers" />
+ <property name="NoMonthChange" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Calendar Signals">
+ <signal name="PrevMonth" />
+ <signal name="DaySelected" />
+ <signal name="NextMonth" />
+ <signal name="MonthChanged" />
+ <signal name="PrevYear" />
+ <signal name="DaySelectedDoubleClick" />
+ <signal name="NextYear" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.ToggleButton,gtk-sharp" base-type="Gtk.Button"
+ label="Toggle Button" icon="togglebutton.png" palette-category="widget">
+ <itemgroups>
+ <itemgroup label="Toggle Button Properties">
+ <property name="Active" />
+ <property name="Inconsistent" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Toggle Button Signals">
+ <signal name="Toggled" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Button" />
+ </signals>
+ </object>
+
+ <object type="Gtk.CheckButton,gtk-sharp" wrapper="Stetic.Wrapper.CheckButton"
+ label="Check Box" icon="checkbutton.png" palette-category="widget"
+ hexpandable="true" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Check Box Properties">
+ <property name="Label" init-with-name="true" translatable="true" />
+ <property name="Active" />
+ <property name="Inconsistent" />
+ <property name="DrawIndicator" ignore-default="true"/>
+ <property name="HasLabel" internal="true" />
+ <property name="UseUnderline" />
+ <command name="RestoreLabel" label="Restore Label" icon="res:add-check-label.png"
+ description="Restore the button's label">
+ <disabled-if name="HasLabel" value="true" />
+ </command>
+ <command name="RemoveLabel" label="Remove Label" icon="res:remove-check-label.png"
+ description="Remove the button's label">
+ <disabled-if name="HasLabel" value="false" />
+ </command>
+ </itemgroup>
+ <itemgroup ref="Gtk.Button.Extra" />
+ </itemgroups>
+ <signals>
+ <itemgroup ref="Gtk.Button" />
+ <itemgroup ref="Gtk.ToggleButton" />
+ </signals>
+ <contextmenu>
+ <command ref="RemoveLabel" />
+ <command ref="RestoreLabel" />
+ </contextmenu>
+ </object>
+
+ <object type="Gtk.MenuItem,gtk-sharp" wrapper="Stetic.Wrapper.MenuItem"
+ label="Menu Item">
+ <itemgroups>
+ <itemgroup label="Menu Item Properties">
+ <property name="Label" translatable="true" glade-name="label" label="Label"
+ description="The text of the menu item" />
+ <property name="UseUnderline" glade-name="use_underline" label="Use Underline"
+ description="If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key" />
+ <property name="HasSubmenu" internal="true" />
+ <property name="Accelerator" editor="Stetic.Editor.Accelerator">
+ <disabled-if name="HasSubmenu" value="true" />
+ </property>
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Menu Item Signals">
+ <signal name="Activated" />
+ <signal name="ActivateItem" />
+ <signal name="Deselected" />
+ <signal name="Selected" />
+ <signal name="Toggled" />
+ <signal name="ToggleSizeAllocated" />
+ <signal name="ToggleSizeRequested" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ </signals>
+
+ <glade-transform>
+ <!-- A regular MenuItem with no label is really a SeparatorMenuItem -->
+ <import>
+ <xsl:template match="widget[@class='GtkMenuItem']">
+ <xsl:choose>
+ <xsl:when test="not(property[@name='label']) and not(property[@name='stock_item'])">
+ <widget class="GtkSeparatorMenuItem">
+ <xsl:attribute name="id"><xsl:value-of select="@id" /></xsl:attribute>
+ <xsl:apply-templates select="node()" />
+ </widget>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()" />
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ </import>
+ </glade-transform>
+ </object>
+
+ <object type="Gtk.CheckMenuItem,gtk-sharp" label="Check Menu Item">
+ <itemgroups>
+ <itemgroup label="Check Menu Item Properties">
+ <property ref="Gtk.MenuItem.Label" />
+ <property ref="Gtk.MenuItem.UseUnderline" />
+ <property ref="Gtk.MenuItem.Accelerator" />
+ <property name="Active" />
+ <property name="Inconsistent" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Check Menu Item Signals">
+ <signal name="Toggled" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.MenuItem" />
+ </signals>
+ </object>
+
+ <object type="Gtk.ColorButton,gtk-sharp" wrapper="Stetic.Wrapper.ColorButton"
+ label="Color Button" icon="colorbutton.png" palette-category="widget" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Color Button Properties">
+ <property name="Title" translatable="true" />
+ <property name="UseAlpha" internal="true" />
+ <property name="Alpha" min="-1" max="65535" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Button.Extra" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Color Button Signals">
+ <signal name="ColorSet" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Button" />
+ </signals>
+ </object>
+
+ <object type="Gtk.ComboBox,gtk-sharp" wrapper="Stetic.Wrapper.ComboBox"
+ label="Combo Box" icon="combo.png" palette-category="widget" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Combo Box Properties">
+ <property name="IsTextCombo" label="Text ComboBox"
+ description="Checked if the combo box displays a list of strings" />
+ <property name="Items" translatable="true" label="Items" glade-name="items"
+ description="The items to display in the Combo Box, one per line"
+ editor="Stetic.Editor.StringArray">
+ <disabled-if name="IsTextCombo" value="false" />
+ </property>
+ <property name="Active" min="-1" default="-1"/>
+ <property name="HasFrame" gtk-version="2.6"/>
+ <property name="AddTearoffs" gtk-version="2.6"/>
+ <property name="FocusOnClick" gtk-version="2.6"/>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="ComboBox Signals">
+ <signal name="Changed" />
+ <signal name="EditingDone" gtk-version="2.6"/>
+ <signal name="WidgetRemoved" gtk-version="2.6"/>
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.ComboBoxEntry,gtk-sharp" wrapper="Stetic.Wrapper.ComboBoxEntry" icon="comboentry.png"
+ label="Combo Box Entry" palette-category="widget" base-type="Gtk.ComboBox">
+ </object>
+
+ <object type="Gtk.Dialog,gtk-sharp" wrapper="Stetic.Wrapper.Dialog"
+ label="Dialog Box" icon="dialog.png" palette-category="window" base-type="Gtk.Window">
+ <itemgroups>
+ <itemgroup label="Dialog Properties">
+ <property name="Buttons" label="Number of Buttons"
+ description="The number of buttons"
+ min="1" />
+ <property name="HelpButton" label="Help Button"
+ description="Whether or not to display a 'Help' button" />
+ <property name="HasSeparator" default="true"/>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Dialog Signals">
+ <signal name="Close" />
+ <signal name="Response" />
+ </itemgroup>
+ </signals>
+ <internal-children>
+ <property name="VBox" glade-name="vbox" />
+ <property name="ActionArea" glade-name="action_area" />
+ </internal-children>
+ </object>
+
+ <object type="Gtk.DrawingArea,gtk-sharp" base-type="Gtk.Widget"
+ label="Drawing Area" icon="drawingarea.png" palette-category="widget"
+ hexpandable="true" vexpandable="true">
+ </object>
+
+ <object type="Gtk.Entry,gtk-sharp" base-type="Gtk.Widget"
+ label="Entry" icon="entry.png" palette-category="widget"
+ hexpandable="true" wrapper="Stetic.Wrapper.Entry">
+ <itemgroups>
+ <itemgroup label="Entry Properties">
+ <property name="Text" translatable="true" />
+ <property name="IsEditable" />
+ <property name="WidthChars" min="-1"/>
+ <property name="MaxLength" />
+ <property name="HasFrame" />
+ <property name="ActivatesDefault" />
+ <property name="Visibility" />
+ </itemgroup>
+ <itemgroup label="Extra Entry Properties" name="Extra">
+ <property name="InvisibleChar" />
+ <property name="Xalign" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Entry Signals">
+ <signal name="InsertAtCursor" />
+ <signal name="ToggleOverwrite" />
+ <signal name="PopulatePopup" />
+ <signal name="ClipboardCopied" />
+ <signal name="ClipboardPasted" />
+ <signal name="DeleteFromCursor" />
+ <signal name="Activated" />
+ <signal name="ClipboardCut" />
+ <signal name="MoveCursor" />
+ <signal name="Changed" />
+ <signal name="TextDeleted" />
+ <signal name="TextInserted" />
+ <signal name="EditingDone" />
+ <signal name="WidgetRemoved" />
+ <signal name="Backspace" gtk-version="2.6"/>
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.EventBox,gtk-sharp" base-type="Gtk.Container"
+ label="Event Box" icon="eventbox.png" palette-category="container">
+ <itemgroups>
+ <itemgroup label="Event Box Properties">
+ <property name="AboveChild" />
+ <property name="VisibleWindow" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Expander,gtk-sharp" base-type="Gtk.Container" wrapper="Stetic.Wrapper.Expander"
+ label="Expander" icon="expander.png" palette-category="container">
+ <itemgroups>
+ <itemgroup label="Expander Properties">
+ <property name="Expanded" />
+ <property name="Spacing" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Expander Signals">
+ <signal name="Activated" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Fixed,gtk-sharp" wrapper="Stetic.Wrapper.Fixed" base-type="Gtk.Container"
+ label="Fixed" icon="fixed.png" palette-category="container">
+ <itemgroups>
+ <itemgroup label="Fixed Properties">
+ <property name="HasWindow" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.Fixed+FixedChild,gtk-sharp" wrapper="Stetic.Wrapper.Fixed+FixedChild">
+ <itemgroups>
+ <itemgroup label="Fixed Child Layout">
+ <property name="X" />
+ <property name="Y" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.FontButton,gtk-sharp" wrapper="Stetic.Wrapper.FontButton"
+ label="Font Button" icon="fontbutton.png" palette-category="widget" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Font Button Properties">
+ <property name="Title" translatable="true" />
+ <property name="FontName" />
+ <property name="ShowSize" />
+ <property name="ShowStyle" />
+ <property name="UseFont" />
+ <property name="UseSize">
+ <disabled-if name="UseFont" value="false" />
+ </property>
+ </itemgroup>
+ <itemgroup ref="Gtk.Button.Extra" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Font Button Signals">
+ <signal name="FontSet" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Button" />
+ </signals>
+ </object>
+
+ <object type="Gtk.Frame,gtk-sharp" wrapper="Stetic.Wrapper.Frame" base-type="Gtk.Container"
+ label="Frame" icon="frame.png" palette-category="container">
+ <itemgroups>
+ <itemgroup label="Frame Properties">
+ <property name="ShadowType" />
+ <property name="LabelXalign" />
+ <property name="LabelYalign" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.HBox,gtk-sharp" base-type="Gtk.Box"
+ label="HBox" icon="hbox.png" palette-category="container">
+ </object>
+
+ <object type="Gtk.HButtonBox,gtk-sharp" base-type="Gtk.ButtonBox"
+ label="HButtonBox" icon="hbuttonbox.png" palette-category="container"
+ hexpandable="true">
+ <glade-transform>
+ <!-- If a child has a "response_id" of -11 (GTK_RESPONSE_HELP), it should be packed with the "secondary" property -->
+ <import>
+ <xsl:template match="widget[@class='GtkHButtonBox']/child/widget[@class='GtkButton']">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+ <xsl:if test="number (property[@name='response_id']) = -11">
+ <packing>
+ <property name="secondary">True</property>
+ </packing>
+ </xsl:if>
+ </xsl:template>
+ </import>
+ </glade-transform>
+ </object>
+
+ <object type="Gtk.HPaned,gtk-sharp" base-type="Gtk.Paned"
+ label="HPaned" icon="hpaned.png" palette-category="container"
+ hexpandable="true">
+ </object>
+
+ <object type="Gtk.HScale,gtk-sharp" wrapper="Stetic.Wrapper.HScale"
+ label="Horizontal Scale" icon="hscale.png" palette-category="widget"
+ hexpandable="true" base-type="Gtk.Scale">
+ </object>
+
+ <object type="Gtk.HScrollbar,gtk-sharp" wrapper="Stetic.Wrapper.HScrollbar"
+ label="Horizontal Scrollbar" icon="hscrollbar.png" palette-category="widget"
+ hexpandable="true" base-type="Gtk.Range">
+ </object>
+
+ <object type="Gtk.HSeparator,gtk-sharp" base-type="Gtk.Widget"
+ label="Horizontal Separator" icon="hseparator.png" palette-category="widget"
+ hexpandable="true">
+ </object>
+
+ <object type="Gtk.Image,gtk-sharp" wrapper="Stetic.Wrapper.Image"
+ label="Image" icon="image.png" palette-category="widget" base-type="Gtk.Misc">
+ <itemgroups>
+ <itemgroup label="Image Properties">
+ <property name="Pixbuf" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.ImageMenuItem,gtk-sharp" wrapper="Stetic.Wrapper.ImageMenuItem"
+ label="Image Menu Item">
+ <itemgroups>
+ <itemgroup label="Image Menu Item Properties">
+ <property name="Image" editor="Stetic.Editor.Image" />
+ <property ref="Gtk.MenuItem.Label" />
+ <property ref="Gtk.MenuItem.UseUnderline" />
+ <property ref="Gtk.MenuItem.Accelerator" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.MenuItem" />
+ </signals>
+ </object>
+
+ <object type="Gtk.Label,gtk-sharp" wrapper="Stetic.Wrapper.Label"
+ label="Label" icon="label.png" palette-category="widget" base-type="Gtk.Misc">
+ <itemgroups>
+ <itemgroup label="Label Properties">
+ <property name="LabelProp" init-with-name="true" translatable="true" default=""/>
+ <property name="UseMarkup" />
+ <property name="UseUnderline" />
+ <property name="Wrap" />
+ <property name="MnemonicWidget" glade-override="true" editor="Stetic.Editor.WidgetSelector" default=""/>
+ <property name="Justify" />
+ <property name="Selectable" />
+ <property name="Ellipsize" gtk-version="2.6"/>
+ <property name="WidthChars" min="-1" gtk-version="2.6" />
+ <property name="MaxWidthChars" min="-1" gtk-version="2.6" />
+ <property name="SingleLineMode" gtk-version="2.6" />
+ <property name="Angle" gtk-version="2.6" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Label Signals">
+ <signal name="CopyClipboard" />
+ <signal name="MoveCursor" />
+ <signal name="PopulatePopup" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.MenuBar,gtk-sharp" wrapper="Stetic.Wrapper.MenuBar"
+ label="Menu Bar" icon="menubar.png" palette-category="widget" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="MenuBar Properties">
+ <property name="PackDirection" gtk-version="2.8" />
+ <property name="ChildPackDirection" gtk-version="2.8" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Menu Bar Signals">
+ <signal name="Deactivated" />
+ <signal name="SelectionDone" />
+ <signal name="MoveCurrent" />
+ <signal name="ActivateCurrent" />
+ <signal name="Canceled" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Menu,gtk-sharp" label="Menu" icon="menu.png" base-type="Gtk.Container">
+ <signals>
+ <itemgroup label="Menu Signals">
+ <signal name="Deactivated" />
+ <signal name="SelectionDone" />
+ <signal name="MoveCurrent" />
+ <signal name="ActivateCurrent" />
+ <signal name="Canceled" />
+ </itemgroup>
+ </signals>
+ </object>
+ <object type="Gtk.Menu+MenuChild,gtk-sharp" />
+
+<!-- Code generation not implemented for MessageDialog
+
+ <object type="Stetic.MessageDialog" cname="GtkMessageDialog" wrapper="Stetic.Wrapper.Window"
+ label="Message Dialog" icon="messagedialog.png" palette-category="window">
+ <itemgroups>
+ <itemgroup label="Message Dialog Properties">
+ <property ref="Gtk.Window.Title" />
+ <property name="MessageType" label="Message Type"
+ description="The type of message dialog this is" />
+ <property name="PrimaryText" translatable="true" label="Primary Text"
+ description="The primary message text" />
+ <property name="SecondaryText" translatable="true" label="Secondary Text"
+ description="The secondary message text" />
+ <property name="Buttons" label="Buttons"
+ description="The buttons to offer" />
+ <property ref="Gtk.Window.Icon" />
+ <property ref="Gtk.Window.WindowPosition" />
+ <property ref="Gtk.Window.Modal" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Dialog.Misc" />
+ <itemgroup ref="Gtk.Window.Size" />
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container.Commands" />
+ </itemgroups>
+ <signals>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.Window" />
+ <itemgroup ref="Gtk.Dialog" />
+ </signals>
+ </object>
+-->
+
+ <object type="Gtk.Notebook,gtk-sharp" wrapper="Stetic.Wrapper.Notebook" base-type="Gtk.Container"
+ label="Notebook" icon="notebook.png" palette-category="container">
+ <itemgroups>
+ <itemgroup label="Notebook Properties">
+ <property name="CurrentPage" />
+ <property name="EnablePopup" />
+ <property name="TabPos" />
+ <property name="ShowBorder" />
+ <property name="ShowTabs" />
+ <property name="Scrollable" />
+ <property name="BorderWidth" />
+ <command name="InsertBefore" label="Insert Page Before"
+ description="Insert a blank page before this one">
+ <invisible-if check="ChildrenAllowed" />
+ <disabled-if check="CheckInsertBefore" />
+ </command>
+ <command name="InsertAfter" label="Insert Page After"
+ description="Insert a blank page after this one" >
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Notebook Signals">
+ <signal name="FocusTab" />
+ <signal name="ChangeCurrentPage" />
+ <signal name="MoveFocusOut" />
+ <signal name="SwitchPage" />
+ <signal name="SelectPage" />
+ </itemgroup>
+ </signals>
+ <contextmenu>
+ <command name="PreviousPage" label="Go to Previous Page"
+ description="Show the previous page">
+ <disabled-if check="CheckPreviousPage" />
+ </command>
+ <command name="NextPage" label="Go to Next Page"
+ description="Show the next page">
+ <disabled-if check="CheckNextPage" />
+ </command>
+ <command name="DeletePage" label="Delete Page"
+ description="Delete the current page">
+ <invisible-if check="ChildrenAllowed" />
+ <disabled-if check="CheckDeletePage" />
+ </command>
+ <command name="SwapPrevious" label="Swap with Previous Page"
+ description="Swap the contents of this page with the contents of the previous page">
+ <invisible-if check="ChildrenAllowed" />
+ <disabled-if check="CheckPreviousPage" />
+ </command>
+ <command name="SwapNext" label="Swap with Next Page"
+ description="Swap the contents of this page with the contents of the next page">
+ <invisible-if check="ChildrenAllowed" />
+ <disabled-if check="CheckNextPage" />
+ </command>
+ <command ref="InsertBefore" />
+ <command ref="InsertAfter" />
+ </contextmenu>
+ </object>
+ <object type="Gtk.Notebook+NotebookChild,gtk-sharp">
+ <itemgroups>
+ <itemgroup label="Notebook Child Layout">
+ <property name="Position" />
+ <property name="TabPack" />
+ <property name="TabExpand" />
+ <property name="TabFill" />
+ <property name="MenuLabel" translatable="true" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.OptionMenu,gtk-sharp" wrapper="Stetic.Wrapper.OptionMenu"
+ label="Option Menu" icon="optionmenu.png" deprecated="true" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Option Menu Properties">
+ <property name="Active" glade-name="history" label="Active"
+ description="The active menu item" min="0" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Option Menu Signals">
+ <signal name="Changed" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Button" />
+ </signals>
+ <internal-children>
+ <property name="Menu" glade-name="menu" />
+ </internal-children>
+ </object>
+
+ <object type="Gtk.ProgressBar,gtk-sharp" base-type="Gtk.Widget"
+ label="Progress Bar" icon="progressbar.png" palette-category="widget"
+ hexpandable="true">
+ <itemgroups>
+ <itemgroup label="Progress Bar Properties">
+ <property name="Orientation" />
+ <property name="Text" translatable="true" />
+ <property name="Fraction" />
+ <property name="PulseStep" />
+ <property name="Ellipsize" gtk-version="2.6"/>
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.RadioButton,gtk-sharp" wrapper="Stetic.Wrapper.RadioButton"
+ label="Radio Button" icon="radiobutton.png" palette-category="widget"
+ hexpandable="true" init-properties="Label" base-type="Gtk.CheckButton">
+ <itemgroups>
+ <itemgroup label="Radio Button Properties">
+ <property name="Group" label="Group"
+ description="The name of the radio button group that this button belongs to"
+ editor="Stetic.Editor.GroupPicker" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Radio Button Signals">
+ <signal name="GroupChanged" />
+ </itemgroup>
+ </signals>
+ </object>
+<!--
+ <object type="Gtk.RadioMenuItem,gtk-sharp" wrapper="Stetic.Wrapper.RadioMenuItem"
+ label="Radio Menu Item">
+ <itemgroups>
+ <itemgroup label="Radio Menu Item Properties">
+ <property ref="Gtk.MenuItem.Label" />
+ <property ref="Gtk.MenuItem.UseUnderline" />
+ <property ref="Gtk.MenuItem.Accelerator" />
+ <property name="Group" label="Group"
+ description="The name of the radio menu item group that this menu item belongs to"
+ editor="Stetic.Editor.GroupPicker" />
+ <property name="Active" />
+ <property name="Inconsistent" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Radio Menu Item Signals">
+ <signal name="Toggled" />
+ <signal name="GroupChanged" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.MenuItem" />
+ </signals>
+ </object>
+
+ <object type="Gtk.ToolItem,gtk-sharp" wrapper="Stetic.Wrapper.Widget">
+ <signals>
+ <itemgroup label="Tool Item Signals">
+ <signal name="ToolbarReconfigured" />
+ <signal name="CreateMenuProxy" />
+ <signal name="TooltipSet" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.ToolButton,gtk-sharp" wrapper="Stetic.Wrapper.ToolButton"
+ label="Toolbar Button" icon="button.png" palette-category="toolbaritem">
+ <itemgroups>
+ <itemgroup label="Toolbar Button Properties">
+ <property name="Type" label="Button Type"
+ description="The type of button" />
+ <property name="StockId" label="Stock Item"
+ description="The stock button ID"
+ editor="Stetic.Editor.StockItem">
+ <invisible-if name="Type" value="TextAndIcon" />
+ </property>
+ <property name="Icon" label="Icon"
+ description="The icon to display in the button"
+ editor="Stetic.Editor.ImageSelector">
+ <invisible-if name="Type" value="StockItem" />
+ </property>
+ <property name="Label" translatable="true" />
+ <property name="UseUnderline">
+ <invisible-if name="Type" value="StockItem" />
+ </property>
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Tool Button Signals">
+ <signal name="Clicked" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.ToolItem" />
+ </signals>
+ </object>
+
+ <object type="Gtk.RadioToolButton,gtk-sharp" wrapper="Stetic.Wrapper.RadioToolButton"
+ label="Toolbar Radio Button" icon="radiobutton.png" palette-category="toolbaritem">
+ <itemgroups>
+ <itemgroup label="Toolbar Radio Button Properties">
+ <property ref="Gtk.ToolButton.Icon" />
+ <property ref="Gtk.ToolButton.Label" />
+ <property ref="Gtk.ToolButton.UseUnderline" />
+ <property name="Group" label="Group"
+ description="The name of the radio toolbar item group that this toolbar item belongs to"
+ editor="Stetic.Editor.GroupPicker" />
+ <property name="Active" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Radio Tool Button Signals">
+ <signal name="Toggled" />
+ <signal name="Clicked" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.ToolItem" />
+ </signals>
+ </object>
+-->
+
+ <object type="Gtk.ScrolledWindow,gtk-sharp" wrapper="Stetic.Wrapper.ScrolledWindow"
+ label="Scrolled Window" icon="scrolledwindow.png" palette-category="container"
+ hexpandable="true" vexpandable="true" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Scrolled Window Properties">
+ <property name="VscrollbarPolicy" default="Automatic" />
+ <property name="HscrollbarPolicy" default="Automatic" />
+ <property name="ShadowType" />
+ <property name="WindowPlacement" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Scrolled Window Signals">
+ <signal name="MoveFocusOut" />
+ <signal name="ScrollChild" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.SeparatorMenuItem,gtk-sharp"
+ label="Separator Menu Item" icon="hseparator.png">
+ <itemgroups>
+ <itemgroup ref="Gtk.Widget" important="false" />
+ </itemgroups>
+ <signals>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.MenuItem" />
+ </signals>
+ </object>
+
+<!-- <object type="Gtk.SeparatorToolItem,gtk-sharp"
+ label="Toolbar Separator" icon="vseparator.png" palette-category="toolbaritem">
+ <itemgroups>
+ <itemgroup label="Toolbar Separator Properties">
+ <property name="Draw" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.ToolItem" />
+ </signals>
+ </object>
+-->
+
+ <object type="Gtk.SpinButton,gtk-sharp" wrapper="Stetic.Wrapper.SpinButton" base-type="Gtk.Widget"
+ label="Spin Button" icon="spinbutton.png" palette-category="widget" init-properties="Lower Upper StepIncrement">
+ <itemgroups>
+ <itemgroup label="Range Properties">
+ <property name="Adjustment.Lower" />
+ <property name="Adjustment.Upper" />
+ <property name="Adjustment.PageIncrement" />
+ <property name="Adjustment.PageSize" />
+ <property name="Adjustment.StepIncrement" />
+ </itemgroup>
+ <itemgroup label="Spin Button Properties" important="true">
+ <property name="ClimbRate" />
+ <property name="Digits" />
+ <property name="Numeric" />
+ <property name="SnapToTicks" />
+ <property name="UpdatePolicy" />
+ <property name="Value" />
+ <property name="Wrap" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Spin Button Signals">
+ <signal name="ChangeValue" />
+ <signal name="Input" />
+ <signal name="ValueChanged" />
+ <signal name="Output" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Entry" />
+ </signals>
+ </object>
+
+ <object type="Gtk.Statusbar,gtk-sharp" base-type="Gtk.HBox"
+ label="Statusbar" icon="statusbar.png" palette-category="widget"
+ hexpandable="true">
+ <itemgroups>
+ <itemgroup label="Status Bar Properties">
+ <property name="HasResizeGrip" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Statusbar Signals">
+ <signal name="TextPopped" />
+ <signal name="TextPushed" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.Table,gtk-sharp" wrapper="Stetic.Wrapper.Table" base-type="Gtk.Container"
+ label="Table" icon="table.png" palette-category="container" init-properties="NRows NColumns Homogeneous">
+ <itemgroups>
+ <itemgroup label="Table Properties">
+ <property name="NRows" min="1"/>
+ <property name="NColumns" min="1"/>
+ <property name="Homogeneous" />
+ <property name="RowSpacing" />
+ <property name="ColumnSpacing" />
+ <property name="BorderWidth" />
+ </itemgroup>
+ </itemgroups>
+ <contextmenu>
+ <command name="InsertRowBefore" label="Insert Row Before"
+ description="Insert an empty row above the selected row">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ <command name="InsertRowAfter" label="Insert Row After"
+ description="Insert an empty row below the selected row">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ <command name="InsertColumnBefore" label="Insert Column Before"
+ description="Insert an empty column before the selected column">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ <command name="InsertColumnAfter" label="Insert Column After"
+ description="Insert an empty column after the selected column">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ <command name="DeleteRow" label="Delete Row"
+ description="Delete the selected row">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ <command name="DeleteColumn" label="Delete Column"
+ description="Delete the selected column">
+ <invisible-if check="ChildrenAllowed" />
+ </command>
+ </contextmenu>
+
+ <glade-transform>
+ <!-- Child packing options are non-standard ("expand" instead of "GTK_EXPAND") -->
+ <import>
+ <xsl:template match="widget[@class='GtkTable']/child/packing/property[@name='x_options' or @name='y_options']/text()">
+ <xsl:call-template name="GtkTable_fixoptions2">
+ <xsl:with-param name="string" select="." />
+ </xsl:call-template>
+ </xsl:template>
+ <xsl:template name="GtkTable_fixoptions2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '|')">
+ <xsl:call-template name="GtkTable_fixoptions2">
+ <xsl:with-param name="string" select="substring-before($string, '|')"/>
+ </xsl:call-template>
+ <xsl:text>|</xsl:text>
+ <xsl:call-template name="GtkTable_fixoptions2">
+ <xsl:with-param name="string" select="substring-after($string, '|')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>GTK_</xsl:text>
+ <xsl:value-of select="translate($string,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ </import>
+ <export>
+ <xsl:template match="widget[@class='GtkTable']/child/packing/property[@name='x_options' or @name='y_options']/text()">
+ <xsl:call-template name="GtkTable_breakoptions2">
+ <xsl:with-param name="options" select="." />
+ </xsl:call-template>
+ </xsl:template>
+ <xsl:template name="GtkTable_breakoptions2">
+ <xsl:param name="string"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '|')">
+ <xsl:call-template name="GtkTable_breakoptions2">
+ <xsl:with-param name="string" select="substring-before($string, '|')"/>
+ </xsl:call-template>
+ <xsl:text>|</xsl:text>
+ <xsl:call-template name="GtkTable_breakoptions2">
+ <xsl:with-param name="string" select="substring-after($string, '|')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="translate(substring-after($string, 'GTK_'),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ </export>
+ </glade-transform>
+ </object>
+ <object type="Gtk.Table+TableChild,gtk-sharp" wrapper="Stetic.Wrapper.Table+TableChild">
+ <itemgroups>
+ <itemgroup label="Table Child Layout">
+ <property name="TopAttach" />
+ <property name="BottomAttach" />
+ <property name="LeftAttach" />
+ <property name="RightAttach" />
+ <property name="XPadding" />
+ <property name="YPadding" />
+ <property name="AutoSize" label="Auto Size"
+ description="If set, the other packing properties for this cell will be automatically adjusted as other widgets are added to and removed from the container" />
+ <property name="XOptions" internal="true" />
+ <property name="YOptions" internal="true" />
+ <property name="XExpand" label="Expand Horizontally"
+ description="Whether or not the table cell should expand horizontally">
+ <disabled-if name="AutoSize" value="true" />
+ </property>
+ <property name="XFill" label="Fill Horizontally"
+ description="Whether or not the widget should expand to fill its cell horizontally">
+ <disabled-if name="AutoSize" value="true" />
+ <disabled-if name="XExpand" value="true" />
+ </property>
+ <property name="XShrink" label="Shrink Horizontally"
+ description="Whether or not the table cell should shrink horizontally">
+ <disabled-if name="AutoSize" value="true" />
+ </property>
+ <property name="YExpand" label="Expand Vertically"
+ description="Whether or not the table cell should expand vertically">
+ <disabled-if name="AutoSize" value="true" />
+ </property>
+ <property name="YFill" label="Fill Vertically"
+ description="Whether or not the widget should expand to fill its cell vertically">
+ <disabled-if name="AutoSize" value="true" />
+ <disabled-if name="YExpand" value="true" />
+ </property>
+ <property name="YShrink" label="Shrink Vertically"
+ description="Whether or not the table cell should shrink vertically">
+ <disabled-if name="AutoSize" value="true" />
+ </property>
+ <command name="CellXExpand" label="Expand Horizontally" icon="res:cell-expand-h.png" />
+ <command name="CellXFill" label="Fill Horizontally" icon="res:cell-fill-h.png" />
+ <command name="CellYExpand" label="Expand Vertically" icon="res:cell-expand-v.png" />
+ <command name="CellYFill" label="Fill Vertically" icon="res:cell-fill-v.png" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.TextView,gtk-sharp" wrapper="Stetic.Wrapper.TextView"
+ label="Text View" icon="textview.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Text View Properties">
+ <property name="Editable" />
+ <property name="CursorVisible" />
+ <property name="Overwrite" />
+ <property name="AcceptsTab" />
+ <property name="Tabs" />
+ <property name="Text" translatable="true" label="Text" glade-name="text"
+ description="The initial text to display in the Text View"
+ editor="Stetic.Editor.Text" />
+ <property name="Justification" />
+ <property name="WrapMode" />
+ <property name="PixelsAboveLines" />
+ <property name="PixelsBelowLines" />
+ <property name="PixelsInsideWrap" />
+ <property name="LeftMargin" />
+ <property name="RightMargin" />
+ <property name="Indent" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Text View Signals">
+ <signal name="PasteClipboard" />
+ <signal name="InsertAtCursor" />
+ <signal name="CutClipboard" />
+ <signal name="ToggleOverwrite" />
+ <signal name="PageHorizontally" />
+ <signal name="MoveFocus" />
+ <signal name="CopyClipboard" />
+ <signal name="DeleteFromCursor" />
+ <signal name="PopulatePopup" />
+ <signal name="MoveCursor" />
+ <signal name="SetAnchor" />
+ <signal name="ScrollAdjustmentsSet" />
+ <signal name="Backspace" gtk-version="2.6"/>
+ </itemgroup>
+ </signals>
+ </object>
+
+<!-- <object type="Gtk.ToggleToolButton,gtk-sharp" wrapper="Stetic.Wrapper.ToggleToolButton"
+ label="Toolbar Toggle Button" icon="checkbutton.png" palette-category="toolbaritem">
+ <itemgroups>
+ <itemgroup label="Toolbar Toggle Button Properties">
+ <property ref="Gtk.ToolButton.Icon" />
+ <property ref="Gtk.ToolButton.Label" />
+ <property ref="Gtk.ToolButton.UseUnderline" />
+ <property name="Active" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ <signals>
+ <itemgroup label="Toggle Tool Button Signals">
+ <signal name="Toggled" />
+ <signal name="Clicked" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Widget" />
+ <itemgroup ref="Gtk.Container" />
+ <itemgroup ref="Gtk.ToolItem" />
+ </signals>
+ </object>
+-->
+ <object type="Gtk.Toolbar,gtk-sharp" wrapper="Stetic.Wrapper.ActionToolbarWrapper"
+ label="Toolbar" icon="toolbar.png" palette-category="widget" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Tool Bar Properties">
+ <property name="Orientation" />
+ <property name="ShowArrow" />
+ <property name="Tooltips" />
+ <property name="ButtonStyle" label="Toolbar style"/>
+ <property name="ToolbarStyle" ignore-default="true" internal="true"/>
+ <property name="IconSize" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Toolbar Signals">
+ <signal name="OrientationChanged" />
+ <signal name="PopupContextMenu" />
+ <signal name="StyleChanged" />
+ </itemgroup>
+ </signals>
+ </object>
+<!--
+ <object type="Gtk.Toolbar+ToolbarChild,gtk-sharp" wrapper="Stetic.Wrapper.Toolbar+ToolbarChild">
+ <itemgroups>
+ <itemgroup label="Tool Bar Child Properties">
+ <property name="Homogeneous" />
+ <property name="Expand" />
+ <property name="ToolItem" internal="true" />
+ <property name="ToolItem.IsImportant" />
+ <property name="ToolItem.VisibleHorizontal" />
+ <property name="ToolItem.VisibleVertical" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+-->
+ <object type="Gtk.TreeView,gtk-sharp" wrapper="Stetic.Wrapper.TreeView"
+ label="Tree View" icon="treeview.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Tree View Properties">
+ <property name="EnableSearch" />
+ <property name="FixedHeightMode" />
+ <property name="HeadersVisible" />
+ <property name="Reorderable" />
+ <property name="RulesHint" />
+ <property name="SearchColumn" min="-1"/>
+ <property name="Model" />
+ <property name="HeadersClickable" gtk-version="2.6" default="true"/>
+ <property name="HoverSelection" gtk-version="2.6" />
+ <property name="HoverExpand" gtk-version="2.6" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Tree View Signals">
+ <signal name="CursorChanged" />
+ <signal name="TestCollapseRow" />
+ <signal name="RowActivated" />
+ <signal name="ExpandCollapseCursorRow" />
+ <signal name="ColumnsChanged" />
+ <signal name="UnselectAll" />
+ <signal name="SelectCursorParent" />
+ <signal name="RowCollapsed" />
+ <signal name="SelectAll" />
+ <signal name="SelectCursorRow" />
+ <signal name="TestExpandRow" />
+ <signal name="StartInteractiveSearch" />
+ <signal name="MoveCursor" />
+ <signal name="RowExpanded" />
+ <signal name="ToggleCursorRow" />
+ <signal name="ScrollAdjustmentsSet" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.NodeView,gtk-sharp" wrapper="Stetic.Wrapper.TreeView"
+ label="Node View" icon="treeview.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" base-type="Gtk.TreeView">
+ </object>
+
+ <object type="Gtk.IconView,gtk-sharp" wrapper="Stetic.Wrapper.IconView"
+ label="Icon View" icon="iconview.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" base-type="Gtk.Container" gtk-version="2.6">
+ <itemgroups>
+ <itemgroup label="Icon View Properties">
+ <property name="Columns" />
+ <property name="ColumnSpacing" />
+ <property name="ItemWidth" min="-1" />
+ <property name="Margin" min="0" />
+ <property name="Orientation" />
+ <property name="Reorderable" gtk-version="2.8"/>
+ <property name="RowSpacing" />
+ <property name="SelectionMode" />
+ <property name="Spacing" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Icon View Signals">
+ <signal name="SelectionChanged" />
+ <signal name="AllUnselected" />
+ <signal name="ItemActivated" />
+ <signal name="AllSelected" />
+ <signal name="ToggleCursorItem" />
+ <signal name="MoveCursor" />
+ <signal name="ActivateCursorItem" />
+ <signal name="SelectCursorItem" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.VBox,gtk-sharp" base-type="Gtk.Box"
+ label="VBox" icon="vbox.png" palette-category="container">
+ </object>
+
+ <object type="Gtk.VButtonBox,gtk-sharp" base-type="Gtk.ButtonBox"
+ label="VButtonBox" icon="vbuttonbox.png" palette-category="container"
+ vexpandable="true">
+ </object>
+
+ <object type="Gtk.Viewport,gtk-sharp" wrapper="Stetic.Wrapper.Viewport"
+ label="Viewport" icon="viewport.png" base-type="Gtk.Container">
+ <itemgroups>
+ <itemgroup label="Viewport Properties">
+ <property name="ShadowType" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Viewport Signals">
+ <signal name="ScrollAdjustmentsSet" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.VPaned,gtk-sharp" base-type="Gtk.Paned"
+ label="VPaned" icon="vpaned.png" palette-category="container"
+ vexpandable="true">
+ </object>
+
+ <object type="Gtk.VScale,gtk-sharp" wrapper="Stetic.Wrapper.VScale"
+ label="Vertical Scale" icon="vscale.png" palette-category="widget"
+ vexpandable="true" base-type="Gtk.Scale">
+ </object>
+
+ <object type="Gtk.VScrollbar,gtk-sharp" wrapper="Stetic.Wrapper.VScrollbar"
+ label="Vertical Scrollbar" icon="vscrollbar.png" palette-category="widget"
+ vexpandable="true" base-type="Gtk.Range">
+ </object>
+
+ <object type="Gtk.VSeparator,gtk-sharp" base-type="Gtk.Widget"
+ label="Vertical Separator" icon="vseparator.png" palette-category="widget"
+ vexpandable="true">
+ </object>
+
+ <object type="Stetic.Custom" cname="Custom" base-type="Gtk.Widget"
+ label="Custom Widget" icon="custom.png" palette-category="widget">
+ <itemgroups>
+ <itemgroup label="Custom Widget Properties">
+ <property name="CreationFunction" glade-name="creation_function" />
+ <property name="LastModificationTime" glade-name="last_modification_time" internal="true" />
+ <property name="String1" glade-name="string1" />
+ <property name="String2" glade-name="string2" />
+ <property name="Int1" glade-name="int1" />
+ <property name="Int2" glade-name="int2" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+<!-- 2.6
+ <object type="Gtk.AboutDialog,gtk-sharp" wrapper="Stetic.Wrapper.AboutDialog"
+ label="About Dialog" icon="aboutdialog.png" palette-category="window">
+ <itemgroups>
+ <itemgroup label="About Dialog Properties">
+ <property name="Name" translatable="true" />
+ <property name="Version" translatable="true" />
+ <property name="Logo" glade-override="true"
+ editor="Stetic.Editor.ImageFile" />
+ <property name="Comments" translatable="true" />
+ <property name="Copyright" translatable="true" />
+ <property name="Website" translatable="true" />
+ <property name="WebsiteLabel" translatable="true" />
+ <property name="Authors" translatable="true" />
+ <property name="Documenters" translatable="true" />
+ <property name="Artists" translatable="true" />
+ <property name="TranslatorCredits" translatable="true" />
+ <property name="License" translatable="true" editor="Stetic.Editor.Text" />
+ <property ref="Gtk.Window.Icon" />
+ <property ref="Gtk.Window.WindowPosition" />
+ <property ref="Gtk.Window.Modal" />
+ </itemgroup>
+ <itemgroup ref="Gtk.Dialog.Misc" />
+ <itemgroup ref="Gtk.Window.Size" />
+ <itemgroup ref="Gtk.Widget" />
+ </itemgroups>
+ </object>
+-->
+
+ <object type="Gtk.ColorSelection,gtk-sharp" wrapper="Stetic.Wrapper.Widget"
+ label="Color Selection" icon="colorselection.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" base-type="Gtk.Widget">
+ <itemgroups>
+ <itemgroup label="Color Selection Properties">
+ <property name="HasPalette" />
+ <property name="HasOpacityControl" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Color Selection Signals">
+ <signal name="ColorChanged" />
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.ColorSelectionDialog,gtk-sharp" base-type="Gtk.Dialog" wrapper="Stetic.Wrapper.Dialog"
+ label="Color Selection Dialog" icon="colorselectiondialog.png" palette-category="window">
+ <internal-children>
+ <property name="ColorSelection" glade-name="color_selection" />
+ <property name="OkButton" glade-name="ok_button" />
+ <property name="CancelButton" glade-name="cancel_button" />
+ <property name="HelpButton" glade-name="help_button" />
+ <property name="VBox" glade-name="vbox" />
+ <property name="ActionArea" glade-name="action_area" />
+ </internal-children>
+ </object>
+
+ <object type="Gtk.FileChooserWidget,gtk-sharp" wrapper="Stetic.Wrapper.Widget"
+ label="File Chooser Widget" icon="fileselection.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" init-properties="Action" base-type="Gtk.Widget">
+ <itemgroups>
+ <itemgroup label="File Chooser Widget Properties">
+ <property name="Action" />
+ <property name="LocalOnly" />
+ <property name="SelectMultiple">
+ <disabled-if name="Action" value="Save" />
+ <disabled-if name="Action" value="CreateFolder" />
+ </property>
+ <property name="ShowHidden" gtk-version="2.6"/>
+ <property name="DoOverwriteConfirmation" gtk-version="2.8" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="File Chooser Widget Signals">
+ <signal name="SelectionChanged" />
+ <signal name="FileActivated" />
+ <signal name="UpdatePreview" />
+ <signal name="CurrentFolderChanged" />
+ <signal name="ConfirmOverwrite" gtk-version="2.8"/>
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.FileChooserButton,gtk-sharp" wrapper="Stetic.Wrapper.Container" init-properties="Title Action"
+ label="File Chooser Button" icon="fileselection.png" palette-category="widget"
+ hexpandable="true" base-type="Gtk.Container" gtk-version="2.6">
+ <itemgroups>
+ <itemgroup label="File Chooser Button Properties">
+ <property name="Title" translatable="true" />
+ <property name="Action" />
+ <property name="LocalOnly" />
+ <property name="SelectMultiple">
+ <disabled-if name="Action" value="Save" />
+ <disabled-if name="Action" value="CreateFolder" />
+ </property>
+ <property name="WidthChars" min="-1"/>
+ <property name="ShowHidden" gtk-version="2.6"/>
+ <property name="DoOverwriteConfirmation" gtk-version="2.8" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="File Chooser Button Signals">
+ <signal name="SelectionChanged" />
+ <signal name="FileActivated" />
+ <signal name="UpdatePreview" />
+ <signal name="CurrentFolderChanged" />
+ <signal name="ConfirmOverwrite" gtk-version="2.8"/>
+ </itemgroup>
+ </signals>
+ </object>
+
+ <object type="Gtk.FileChooserDialog,gtk-sharp" base-type="Gtk.Dialog"
+ label="File Chooser Dialog" icon="fileselection.png" palette-category="window">
+ <itemgroups>
+ <itemgroup label="File Chooser Dialog Properties">
+ <property name="Action" />
+ <property name="LocalOnly" />
+ <property name="SelectMultiple">
+ <disabled-if name="Action" value="Save" />
+ <disabled-if name="Action" value="CreateFolder" />
+ </property>
+ <property name="ShowHidden" gtk-version="2.6"/>
+ <property name="DoOverwriteConfirmation" gtk-version="2.8" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="File Chooser Dialog Signals">
+ <signal name="SelectionChanged" />
+ <signal name="FileActivated" />
+ <signal name="UpdatePreview" />
+ <signal name="CurrentFolderChanged" />
+ <signal name="ConfirmOverwrite" gtk-version="2.8"/>
+ </itemgroup>
+ </signals>
+ <internal-children>
+ <property name="VBox" glade-name="vbox" />
+ <property name="ActionArea" glade-name="action_area" />
+ </internal-children>
+ </object>
+
+ <object type="Gtk.FontSelection,gtk-sharp" wrapper="Stetic.Wrapper.Widget"
+ label="Font Selection" icon="fontselection.png" palette-category="widget"
+ hexpandable="true" vexpandable="true" base-type="Gtk.Widget">
+ <itemgroups>
+ <itemgroup label="Font Selection Properties">
+ <property name="FontName" />
+ <property name="PreviewText" translatable="true" />
+ </itemgroup>
+ </itemgroups>
+ </object>
+
+ <object type="Gtk.FontSelectionDialog,gtk-sharp" base-type="Gtk.Dialog" wrapper="Stetic.Wrapper.FontSelectionDialog"
+ label="Font Selection Dialog" icon="fontselectiondialog.png" palette-category="window">
+ <internal-children>
+ <property name="VBox" glade-name="vbox" />
+ <property name="ActionArea" glade-name="action_area" />
+ <property name="FontSelection" glade-name="font_selection" />
+ <property name="OkButton" glade-name="ok_button" />
+ <property name="CancelButton" glade-name="cancel_button" />
+ <property name="ApplyButton" glade-name="help_button" />
+ </internal-children>
+ </object>
+
+ <object type="Stetic.ErrorWidget" wrapper="Stetic.ErrorWidgetWrapper">
+ </object>
+
+ <object type="Gtk.Action,gtk-sharp" label="Action" wrapper="Stetic.Wrapper.Action"
+ init-properties="Name Label Tooltip StockId" >
+ <itemgroups>
+ <itemgroup label="Action Properties">
+ <property name="Name" editor="Stetic.Editor.Identifier" min="1"/>
+ <property name="Type" />
+ <property name="Accelerator" editor="Stetic.Editor.Accelerator" />
+ <property name="HideIfEmpty" />
+ <property name="IsImportant" />
+ <property name="Label" translatable="true"/>
+ <property name="Sensitive" />
+ <property name="ShortLabel" default="" translatable="true"/>
+ <property name="StockId" editor="Stetic.Editor.StockItem"/>
+ <property name="Tooltip" translatable="true"/>
+ <property name="Visible" />
+ <property name="VisibleHorizontal" />
+ <property name="VisibleVertical" />
+ <property name="VisibleOverflown" gtk-version="2.6"/>
+ <property name="DrawAsRadio" label="Draw as radio">
+ <invisible-if name="Type" value="Action" />
+ </property>
+ <property name="Active">
+ <invisible-if name="Type" value="Action" />
+ </property>
+ <property name="Value">
+ <invisible-if name="Type" value="Action" />
+ <invisible-if name="Type" value="Toggle" />
+ </property>
+ <property name="Group" label="Group"
+ description="The name of the radio action group that this action belongs to"
+ editor="Stetic.Editor.GroupPicker">
+ <invisible-if name="Type" value="Action" />
+ <invisible-if name="Type" value="Toggle" />
+ </property>
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="Action Signals">
+ <signal name="Activated" />
+ <signal name="Changed" />
+ <signal name="Toggled" />
+ </itemgroup>
+ </signals>
+ </object>
+
+
+
+ <enum type="Gdk.ExtensionMode,gdk-sharp">
+ <value name="None" label="None"
+ description="No extension events are desired" />
+ <value name="All" label="All"
+ description="All extension events are desired" />
+ <value name="Cursor" label="Only if cursor displayed"
+ description="Extension events are desired only if a cursor will be displayed for the device" />
+ </enum>
+
+ <enum type="Gdk.EventMask,gdk-sharp">
+ <value name="ExposureMask" label="Expose"
+ description="Receive expose events" />
+ <value name="PointerMotionMask" label="All pointer motion"
+ description="Receive all pointer motion events" />
+ <value name="PointerMotionHintMask" label="Requested pointer motion"
+ description="Receive pointer motion events when requested" />
+ <value name="ButtonMotionMask" label="Pointer motion w/ any button"
+ description="Receive pointer motion events while any button is pressed" />
+ <value name="Button1MotionMask" label="Pointer motion w/ button 1"
+ description="Receive pointer motion events while button 1 is pressed" />
+ <value name="Button2MotionMask" label="Pointer motion w/ button 2"
+ description="Receive pointer motion events while button 2 is pressed" />
+ <value name="Button3MotionMask" label="Pointer motion w/ button 3"
+ description="Receive pointer motion events while button 3 is pressed" />
+ <value name="ButtonPressMask" label="Button press"
+ description="Receive button press events" />
+ <value name="ButtonReleaseMask" label="Button release"
+ description="Receive button release events" />
+ <value name="KeyPressMask" label="Key press"
+ description="Receive key press events" />
+ <value name="KeyReleaseMask" label="Key release"
+ description="Receive key release events" />
+ <value name="EnterNotifyMask" label="Window enter"
+ description="Receive window enter events" />
+ <value name="LeaveNotifyMask" label="Window leave"
+ description="Receive window leave events" />
+ <value name="FocusChangeMask" label="Focus change"
+ description="Receive focus change events" />
+ <value name="StructureMask" label="Window structure change"
+ description="Receive events about window configuration change" />
+ <value name="PropertyChangeMask" label="Property change"
+ description="Receive property change events" />
+ <value name="VisibilityNotifyMask" label="Visibility change"
+ description="Receive visibility change events" />
+ <value name="ProximityInMask" label="Proximity in"
+ description="Receive proximity in events" />
+ <value name="ProximityOutMask" label="Proximity out"
+ description="Receive proximity out events" />
+ <value name="SubstructureMask" label="Window substructure change"
+ description="Receive events about window configuration changes of child windows" />
+ <value name="ScrollMask" label="Scroll"
+ description="Receive scroll events" />
+ <value name="AllEventsMask" />
+ </enum>
+
+ <enum type="Gdk.Gravity,gdk-sharp">
+ <value name="NorthWest" label="Northwest"
+ description="The reference point is at the top left corner" />
+ <value name="North" label="North"
+ description="The reference point is at the middle of the top edge" />
+ <value name="NorthEast" label="Northeast"
+ description="The reference point is at the top right corner" />
+ <value name="West" label="West"
+ description="The reference point is at the middle of the left edge" />
+ <value name="Center" label="Center"
+ description="The reference point is at the center of the window" />
+ <value name="East" label="East"
+ description="The reference point is at the middle of the right edge" />
+ <value name="SouthWest" label="Southwest"
+ description="The reference point is at the lower left corner" />
+ <value name="South" label="South"
+ description="The reference point is at the middle of the lower edge" />
+ <value name="SouthEast" label="Southeast"
+ description="The reference point is at the lower right corner" />
+ <value name="Static" label="Static"
+ description="The reference point is at the top left corner of the window itself, ignoring window manager decorations" />
+ </enum>
+
+ <enum type="Gdk.WindowTypeHint,gdk-sharp">
+ <value name="Normal" label="Normal"
+ description="Normal toplevel window" />
+ <value name="Dialog" label="Dialog"
+ description="Dialog window" />
+ <value name="Menu" label="Menu"
+ description="Window used to implement a menu" />
+ <value name="Toolbar" label="Toolbar"
+ description="Window used to implement a toolbar" />
+ <value name="Splashscreen" label="Splash screen"
+ description="Window used to display a splash screen" />
+ <value name="Utility" label="Utility"
+ description="Utility windows which are not detached toolbars or dialogs" />
+ <value name="Dock" label="Dock"
+ description="Used for creating dock or panel windows" />
+ <value name="Desktop" label="Desktop"
+ description="Used for creating the desktop background window" />
+ </enum>
+
+ <enum type="Gtk.ArrowType,gtk-sharp">
+ <value name="Up" label="Up"
+ description="Up" />
+ <value name="Down" label="Down"
+ description="Down" />
+ <value name="Left" label="Left"
+ description="Left" />
+ <value name="Right" label="Right"
+ description="Right" />
+ </enum>
+
+ <enum type="Gtk.AttachOptions,gtk-sharp">
+ <value name="Expand" label="Expand"
+ description="The widget should expand to take up any extra space in its container that has been allocated" />
+ <value name="Shrink" label="Shrink"
+ description="The widget should shrink as and when possible" />
+ <value name="Fill" label="Fill"
+ description="The widget should fill the space allocated to it" />
+ </enum>
+
+ <enum type="Gtk.ButtonBoxStyle,gtk-sharp">
+ <value name="DefaultStyle" label="Default"
+ description="Default packing" />
+ <value name="Spread" label="Spread"
+ description="Buttons are evenly spread across the ButtonBox" />
+ <value name="Edge" label="Edge"
+ description="Buttons are placed at the edges of the ButtonBox" />
+ <value name="Start" label="Start"
+ description="Buttons are grouped towards the start (left or top) of the box" />
+ <value name="End" label="End"
+ description="Buttons are grouped toward the end (right or bottom) of the box" />
+ </enum>
+
+ <enum type="Gtk.ButtonsType,gtk-sharp">
+ <value name="None" label="None"
+ description="No buttons at all" />
+ <value name="Ok" label="OK"
+ description="an OK button" />
+ <value name="Close" label="Close"
+ description="a Close button" />
+ <value name="Cancel" label="Cancel"
+ description="a Cancel button" />
+ <value name="YesNo" label="Yes / No"
+ description="Yes and No buttons" />
+ <value name="OkCancel" label="OK / Cancel"
+ description="OK and Cancel buttons" />
+ </enum>
+
+ <enum type="Gtk.CornerType,gtk-sharp">
+ <value name="TopLeft" label="Top Left"
+ description="Place the scrollbars on the right and bottom of the contents" />
+ <value name="BottomLeft" label="Bottom Left"
+ description="Place the scrollbrs on the top and right of the contents" />
+ <value name="TopRight" label="Top Right"
+ description="Place the scrollbrs on the left and bottom of the contents" />
+ <value name="BottomRight" label="Bottom Right"
+ description="Place the scrollbrs on the top and left of the contents" />
+ </enum>
+
+ <enum type="Gtk.FileChooserAction,gtk-sharp">
+ <value name="Open" label="Open"
+ description="Open mode. The file chooser will only let the user pick an existing file." />
+ <value name="Save" label="Save"
+ description="Save mode. The file chooser will let the user pick an existing file, or type in a new filename." />
+ <value name="SelectFolder" label="Select Folder"
+ description="Open mode for selecting folders. The file chooser will let the user pick an existing folder." />
+ <value name="CreateFolder" label="Create Folder"
+ description="Mode for creating a new folder. The file chooser will let the user name an existing or new folder." />
+ </enum>
+
+ <enum type="Gtk.IconSize,gtk-sharp">
+ <value name="Invalid" label="Invalid"
+ description="Invalid" />
+ <value name="Menu" label="Menu"
+ description="The size of an icon an a menu item" />
+ <value name="SmallToolbar" label="Small Toolbar"
+ description="The size of an icon in a small toolbar" />
+ <value name="LargeToolbar" label="Large Toolbar"
+ description="The size of an icon in a large toolbar" />
+ <value name="Button" label="Button"
+ description="The size of an icon in a button" />
+ <value name="Dnd" label="Drag and Drop"
+ description="The size of an icon in a drag-and-drop operation" />
+ <value name="Dialog" label="Dialog"
+ description="The size of an icon in a dialog box" />
+ </enum>
+
+ <enum type="Gtk.Justification,gtk-sharp">
+ <value name="Left" label="Left"
+ description="The text is placed at the left edge of the label" />
+ <value name="Right" label="Right"
+ description="The text is placed at the right edge of the label" />
+ <value name="Center" label="Center"
+ description="The text is placed in the center of the label" />
+ <value name="Fill" label="Fill"
+ description="The text is distributed across the label" />
+ </enum>
+
+ <enum type="Gtk.MessageType,gtk-sharp">
+ <value name="Info" label="Info"
+ description="Informational message" />
+ <value name="Warning" label="Warning"
+ description="Non-fatal warning message" />
+ <value name="Question" label="Question"
+ description="Question requiring a choice" />
+ <value name="Error" label="Error"
+ description="Fatal error message" />
+ </enum>
+
+ <enum type="Gtk.Orientation,gtk-sharp">
+ <value name="Horizontal" label="Horizontal"
+ description="The widget is in horizontal orientation" />
+ <value name="Vertical" label="Vertical"
+ description="The widget is in vertical orientation" />
+ </enum>
+
+ <enum type="Gtk.PackType,gtk-sharp">
+ <value name="Start" label="Start"
+ description="The child is packed into the start (left or top) of the box" />
+ <value name="End" label="End"
+ description="The child is packed into the end (right or bottom) of the box" />
+ </enum>
+
+ <enum type="Gtk.PolicyType,gtk-sharp">
+ <value name="Always" label="Always"
+ description="The scrollbar is always visible" />
+ <value name="Automatic" label="Automatic"
+ description="The scrollbar will appear and disappear as necessary" />
+ <value name="Never" label="Never"
+ description="The scrollbar will never appear" />
+ </enum>
+
+ <enum type="Gtk.PositionType,gtk-sharp">
+ <value name="Left" label="Left"
+ description="The feature is at the left edge" />
+ <value name="Right" label="Right"
+ description="The feature is at the right edge" />
+ <value name="Top" label="Top"
+ description="The feature is at the top edge" />
+ <value name="Bottom" label="Bottom"
+ description="The feature is at the bottom edge" />
+ </enum>
+
+ <enum type="Gtk.ProgressBarOrientation,gtk-sharp">
+ <value name="LeftToRight" label="Left to right"
+ description="A horizontal progress bar growing from left to right" />
+ <value name="RightToLeft" label="Right to left"
+ description="A horizontal progress bar growing from right to left" />
+ <value name="BottomToTop" label="Bottom to top"
+ description="A vertical progress bar growing from bottom to top" />
+ <value name="TopToBottom" label="Top to bottom"
+ description="A vertical progress bar growing from top to bottom" />
+ </enum>
+
+ <enum type="Gtk.ReliefStyle,gtk-sharp">
+ <value name="Normal" label="Normal"
+ description="Draw a normal relief around the button" />
+ <value name="Half" label="Half"
+ description="Draw a half relief around the button" />
+ <value name="None" label="None"
+ description="Draw no relief around the button" />
+ </enum>
+
+ <enum type="Gtk.ResponseType,gtk-sharp">
+ <value name="None" label="None"
+ description="None" />
+ <value name="Reject" label="Reject"
+ description="Reject" />
+ <value name="Accept" label="Accept"
+ description="Accept" />
+ <value name="DeleteEvent" />
+ <value name="Ok" label="OK"
+ description="OK" />
+ <value name="Cancel" label="Cancel"
+ description="Cancel" />
+ <value name="Close" label="Close"
+ description="Close" />
+ <value name="Yes" label="Yes"
+ description="Yes" />
+ <value name="No" label="No"
+ description="No" />
+ <value name="Apply" label="Apply"
+ description="Apply" />
+ <value name="Help" label="Help"
+ description="Help" />
+ </enum>
+
+ <enum type="Gtk.ShadowType,gtk-sharp">
+ <value name="None" label="None"
+ description="No outline" />
+ <value name="In" label="In"
+ description="The outline is bevelled inwards" />
+ <value name="Out" label="Out"
+ description="The outline is bevelled outwards, like a button" />
+ <value name="EtchedIn" label="Etched in"
+ description="" />
+ <value name="EtchedOut" label="Etched out"
+ description="" />
+ </enum>
+
+ <enum type="Gtk.SpinButtonUpdatePolicy,gtk-sharp">
+ <value name="Always" label="Always"
+ description="When refreshing the SpinButton, the value is always displayed" />
+ <value name="IfValid" label="If valid"
+ description="When refreshing the SpinButton, the value is only displayed if it is within the SpinButton's bounds" />
+ </enum>
+
+ <enum type="Stetic.Wrapper.ActionToolbarWrapper+ToolbarStyle">
+ <value name="Default" label="System Default"
+ description="Use the system default style" />
+ <value name="Icons" label="Icons"
+ description="Buttons display only icons in the toolbar" />
+ <value name="Text" label="Text"
+ description="Buttons display only text labels in the toolbar" />
+ <value name="Both" label="Both"
+ description="Buttons display text and icons in the toolbar" />
+ <value name="BothHoriz" label="Both horizontally"
+ description="Buttons display icons and text alongside each other, rather than vertically stacked" />
+ </enum>
+
+ <enum type="Gtk.UpdateType,gtk-sharp">
+ <value name="Continuous" label="Continuous"
+ description="The range value will change continuously as the slider is moved" />
+ <value name="Discontinuous" label="Discontinuous"
+ description="The range value will change only after the user releases the mouse button" />
+ <value name="Delayed" label="Delayed"
+ description="The range value will change if the user stops sliding the slider for a moment" />
+ </enum>
+
+ <enum type="Gtk.WindowPosition,gtk-sharp">
+ <value name="None" label="Not specified"
+ description="The window can be placed wherever the window manager chooses" />
+ <value name="Center" label="Centered"
+ description="The window should be placed in the center of the screen" />
+ <value name="Mouse" label="At mouse position"
+ description="The window should be placed at the current mouse position" />
+ <value name="CenterAlways" label="Always centered"
+ description="The window should be kept centered even if it changes size" />
+ <value name="CenterOnParent" label="Centered on parent"
+ description="Center the window on the parent window that it is transient for" />
+ </enum>
+
+ <enum type="Gtk.WindowType,gtk-sharp">
+ <value name="Toplevel" label="Toplevel"
+ description="A regular window or dialog" />
+ <value name="Popup" label="Popup"
+ description="A special window such as a tooltip" />
+ </enum>
+
+ <enum type="Gtk.WrapMode,gtk-sharp">
+ <value name="None" label="None"
+ description="Do not wrap lines; just make the text area wider" />
+ <value name="Char" label="Character"
+ description="Wrap text, breaking lines between any characters" />
+ <value name="Word" label="Word"
+ description="Wrap text, breaking lines between words" />
+ <value name="WordChar" label="Word or Character"
+ description="Wrap text, preferably breaking lines between words, but also breaking between characters if needed" />
+ </enum>
+
+ <enum type="Stetic.Wrapper.Button+ButtonType">
+ <value name="StockItem" label="Stock button"
+ description="Button displaying stock icon and text" />
+ <value name="TextOnly" label="Text only"
+ description="Button displaying text only" />
+ <value name="TextAndIcon" label="Text and Icon"
+ description="Button displaying an icon and application-provided text" />
+ <value name="Custom" label="Custom"
+ description="Button with entirely custom contents" />
+ </enum>
+
+ <enum type="Stetic.Wrapper.ToolButton+ButtonType">
+ <value name="StockItem" label="Stock button"
+ description="Button displaying stock icon and text" />
+ <value name="TextAndIcon" label="Text and Icon"
+ description="Button displaying an icon and application-provided text" />
+ </enum>
+
+ <enum type="Stetic.Wrapper.Action+ActionType">
+ <value name="Action" label="Action"
+ description="An normal action" />
+ <value name="Toggle" label="Toggle Action"
+ description="The action can be toggled between two states" />
+ <value name="Radio" label="Radio Action"
+ description="The action is controlled by a radio button" />
+ </enum>
+
+ <enum type="Pango.EllipsizeMode, pango-sharp">
+ <value name="None" label="None"
+ description="No ellipsization" />
+ <value name="Start" label="Start"
+ description="Omit characters at the start of the text" />
+ <value name="Middle" label="Middle"
+ description="Omit characters in the middle of the text" />
+ <value name="End" label="End"
+ description="Omit characters at the end of the text" />
+ </enum>
+
+ <enum type="Gtk.SelectionMode, gtk-sharp">
+ <value name="None" label="None"
+ description="Nothing can be selected" />
+ <value name="Single" label="Single"
+ description="Only one item can be selected at any given moment. Other items can have focus, but will not be marked as selected" />
+ <value name="Browse" label="Browse"
+ description="Only one item can be selected at any given moment. Any item currently having focus will be marked as selected" />
+ <value name="Multiple" label="Multiple"
+ description="Several items may be selected or unselected with a click or using the spacebar. The selection can be done using the Ctrl and Shift modifier keys in the usual way" />
+ </enum>
+
+ <enum type="Gtk.PackDirection, gtk-sharp">
+ <value name="Ttb" label="Top to bottom"
+ description="Top to bottom" />
+ <value name="Btt" label="Bottom to top"
+ description="Bottom to top" />
+ <value name="Rtl" label="Right to left"
+ description="Right to left" />
+ <value name="Ltr" label="Left to right"
+ description="Left to right" />
+ </enum>
+
+</objects>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/COPIED b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/COPIED
new file mode 100644
index 0000000000..d693b81e9a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/COPIED
@@ -0,0 +1 @@
+These were stolen from glade3 and are GPLed. \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/accellabel.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/accellabel.png
new file mode 100644
index 0000000000..6ba42ba220
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/accellabel.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/actiongroup.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/actiongroup.png
new file mode 100644
index 0000000000..de43e0a5c4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/actiongroup.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-check-label.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-check-label.png
new file mode 100644
index 0000000000..cf3ad0c7d9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-check-label.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-menu.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-menu.png
new file mode 100644
index 0000000000..19a98613c2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/add-menu.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/alignment.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/alignment.png
new file mode 100644
index 0000000000..5d7d311d96
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/alignment.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/arrow.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/arrow.png
new file mode 100644
index 0000000000..c9153b6f67
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/arrow.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-expand.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-expand.png
new file mode 100644
index 0000000000..956903992b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-expand.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-fill.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-fill.png
new file mode 100644
index 0000000000..b0d67b54d7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/box-fill.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/button.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/button.png
new file mode 100644
index 0000000000..db816c21dc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/button.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/calendar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/calendar.png
new file mode 100644
index 0000000000..c3cdf73ce8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/calendar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-h.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-h.png
new file mode 100644
index 0000000000..539a6f71b5
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-h.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-v.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-v.png
new file mode 100644
index 0000000000..658e63d82c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-expand-v.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-h.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-h.png
new file mode 100644
index 0000000000..30162bf7ea
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-h.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-v.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-v.png
new file mode 100644
index 0000000000..95a9c1ab32
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/cell-fill-v.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/checkbutton.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/checkbutton.png
new file mode 100644
index 0000000000..71565b0b1f
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/checkbutton.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorbutton.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorbutton.png
new file mode 100644
index 0000000000..281288d7cc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorbutton.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselection.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselection.png
new file mode 100644
index 0000000000..281288d7cc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselection.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselectiondialog.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselectiondialog.png
new file mode 100644
index 0000000000..281288d7cc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/colorselectiondialog.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/combo.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/combo.png
new file mode 100644
index 0000000000..dab25d3c02
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/combo.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/comboentry.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/comboentry.png
new file mode 100644
index 0000000000..13e02c820b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/comboentry.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/custom.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/custom.png
new file mode 100644
index 0000000000..df61924981
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/custom.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dec-border.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dec-border.png
new file mode 100644
index 0000000000..c5e5ae5b9e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dec-border.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dialog.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dialog.png
new file mode 100644
index 0000000000..6e81b2fd60
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/dialog.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/drawingarea.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/drawingarea.png
new file mode 100644
index 0000000000..ee65bba598
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/drawingarea.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/entry.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/entry.png
new file mode 100644
index 0000000000..d97bb9f378
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/entry.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/eventbox.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/eventbox.png
new file mode 100644
index 0000000000..c89d490375
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/eventbox.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/expander.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/expander.png
new file mode 100644
index 0000000000..35d1c41d8b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/expander.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fileselection.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fileselection.png
new file mode 100644
index 0000000000..03bda09484
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fileselection.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fixed.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fixed.png
new file mode 100644
index 0000000000..e6d5ece810
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fixed.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontbutton.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontbutton.png
new file mode 100644
index 0000000000..fe7a790ad4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontbutton.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselection.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselection.png
new file mode 100644
index 0000000000..fe7a790ad4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselection.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselectiondialog.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselectiondialog.png
new file mode 100644
index 0000000000..6936c47c05
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/fontselectiondialog.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/frame.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/frame.png
new file mode 100644
index 0000000000..8a4c1f3a0e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/frame.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe-not.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe-not.png
new file mode 100644
index 0000000000..3b1e292737
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe-not.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe.png
new file mode 100644
index 0000000000..2f25501e49
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/globe.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/handlebox.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/handlebox.png
new file mode 100644
index 0000000000..be064c6f51
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/handlebox.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbox.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbox.png
new file mode 100644
index 0000000000..6971a3322b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbox.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbuttonbox.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbuttonbox.png
new file mode 100644
index 0000000000..e38a4c5eed
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hbuttonbox.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hpaned.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hpaned.png
new file mode 100644
index 0000000000..e2847abd09
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hpaned.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscale.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscale.png
new file mode 100644
index 0000000000..310e01cde2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscale.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscrollbar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscrollbar.png
new file mode 100644
index 0000000000..717b656220
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hscrollbar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hseparator.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hseparator.png
new file mode 100644
index 0000000000..b32843abec
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/hseparator.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/iconview.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/iconview.png
new file mode 100644
index 0000000000..b875d3741b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/iconview.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/image.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/image.png
new file mode 100644
index 0000000000..7f790e56b3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/image.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/inc-border.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/inc-border.png
new file mode 100644
index 0000000000..7f457c3f03
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/inc-border.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/label.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/label.png
new file mode 100644
index 0000000000..9299f0fe24
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/label.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menu.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menu.png
new file mode 100644
index 0000000000..bcfdc9dd50
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menu.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menubar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menubar.png
new file mode 100644
index 0000000000..14298a1b22
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/menubar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/messagedialog.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/messagedialog.png
new file mode 100644
index 0000000000..a5330e2918
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/messagedialog.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/missing.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/missing.png
new file mode 100644
index 0000000000..589da692bb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/missing.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/notebook.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/notebook.png
new file mode 100644
index 0000000000..7d8f7067f4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/notebook.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/optionmenu.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/optionmenu.png
new file mode 100644
index 0000000000..d682108ad8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/optionmenu.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/progressbar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/progressbar.png
new file mode 100644
index 0000000000..f48b47c485
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/progressbar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/radiobutton.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/radiobutton.png
new file mode 100644
index 0000000000..c85d9492ad
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/radiobutton.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-check-label.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-check-label.png
new file mode 100644
index 0000000000..25136e6df9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-check-label.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-menu.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-menu.png
new file mode 100644
index 0000000000..4777667d68
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/remove-menu.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/scrolledwindow.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/scrolledwindow.png
new file mode 100644
index 0000000000..10323740f9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/scrolledwindow.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/spinbutton.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/spinbutton.png
new file mode 100644
index 0000000000..9e98bb0ca3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/spinbutton.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/statusbar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/statusbar.png
new file mode 100644
index 0000000000..26d8c2f7f8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/statusbar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/table.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/table.png
new file mode 100644
index 0000000000..dc5886c9ea
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/table.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/textview.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/textview.png
new file mode 100644
index 0000000000..642be08441
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/textview.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/togglebutton.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/togglebutton.png
new file mode 100644
index 0000000000..62c13fad6e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/togglebutton.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/toolbar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/toolbar.png
new file mode 100644
index 0000000000..27b486a0fa
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/toolbar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/treeview.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/treeview.png
new file mode 100644
index 0000000000..f6fd7d9d4e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/treeview.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbox.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbox.png
new file mode 100644
index 0000000000..fce6eb11e1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbox.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbuttonbox.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbuttonbox.png
new file mode 100644
index 0000000000..68defd767e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vbuttonbox.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/viewport.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/viewport.png
new file mode 100644
index 0000000000..deccf531cb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/viewport.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vpaned.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vpaned.png
new file mode 100644
index 0000000000..60628f46ef
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vpaned.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscale.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscale.png
new file mode 100644
index 0000000000..dbdc71e8ab
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscale.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscrollbar.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscrollbar.png
new file mode 100644
index 0000000000..09f8008ab1
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vscrollbar.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vseparator.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vseparator.png
new file mode 100644
index 0000000000..6904fc2220
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/vseparator.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/widget.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/widget.png
new file mode 100644
index 0000000000..7f5844bbfc
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/widget.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/window.png b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/window.png
new file mode 100644
index 0000000000..8f82250f04
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libstetic/wrapper/pixmaps/window.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionComponent.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionComponent.cs
new file mode 100644
index 0000000000..d5db89c4af
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionComponent.cs
@@ -0,0 +1,75 @@
+
+using System;
+
+namespace Stetic
+{
+ public class ActionComponent: Component
+ {
+ Gdk.Pixbuf icon;
+ string label;
+
+ internal static Gdk.Pixbuf DefaultActionIcon;
+
+ static ActionComponent ()
+ {
+ try {
+ DefaultActionIcon = Gdk.Pixbuf.LoadFromResource ("action.png");
+ } catch (Exception e) {
+ Console.WriteLine ("Error while loading pixbuf 'action.png': " + e);
+ }
+ }
+
+ public ActionComponent (Application owner, object backend, string name): base (owner, backend, name, owner.GetComponentType ("Gtk.Action"))
+ {
+ }
+
+ public override string Name {
+ get {
+ if (name == null)
+ name = ((Wrapper.Action)backend).Name;
+ return name;
+ }
+ set {
+ name = value;
+ ((Wrapper.Action)backend).Name = value;
+ }
+ }
+
+ public string Label {
+ get {
+ if (label == null)
+ label = ((Wrapper.Action)backend).Label;
+ return label;
+ }
+ set {
+ label = value;
+ ((Wrapper.Action)backend).Label = value;
+ }
+ }
+
+ protected override void OnChanged ()
+ {
+ name = null;
+ icon = null;
+ label = null;
+ base.OnChanged ();
+ }
+
+ public Gdk.Pixbuf Icon {
+ get {
+ if (icon == null) {
+ byte[] data = app.Backend.GetActionIcon ((Wrapper.Action)backend);
+ if (data == null)
+ return DefaultActionIcon;
+ else
+ icon = new Gdk.Pixbuf (data);
+ }
+ return icon;
+ }
+ }
+
+ public ActionGroupComponent ActionGroup {
+ get { return (ActionGroupComponent) app.GetComponent (((Wrapper.Action)backend).ActionGroup, null, null); }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupComponent.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupComponent.cs
new file mode 100644
index 0000000000..1b2a871d26
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupComponent.cs
@@ -0,0 +1,58 @@
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+
+namespace Stetic
+{
+ [Serializable]
+ public class ActionGroupComponent: Component
+ {
+ public ActionGroupComponent (Application app, object backend, string name): base (app, backend, name, app.GetComponentType ("Gtk.ActionGroup"))
+ {
+ }
+
+ public override string Name {
+ get {
+ if (name == null)
+ name = ((Wrapper.ActionGroup)backend).Name;
+ return name;
+ }
+ set {
+ name = value;
+ ((Wrapper.ActionGroup)backend).Name = value;
+ }
+ }
+
+ public override bool GeneratePublic {
+ get { return ((Wrapper.ActionGroup)backend).GeneratePublic; }
+ set { ((Wrapper.ActionGroup)backend).GeneratePublic = value; }
+ }
+
+ protected override void OnChanged ()
+ {
+ name = null;
+ base.OnChanged ();
+ }
+
+ public ActionComponent[] GetActions ()
+ {
+ Wrapper.ActionCollection acts = ((Wrapper.ActionGroup)backend).Actions;
+
+ ArrayList comps = new ArrayList (acts.Count);
+
+ for (int n=0; n<acts.Count; n++) {
+ ActionComponent ac = (ActionComponent) app.GetComponent (acts[n], null, null);
+ if (ac != null)
+ comps.Add (ac);
+ }
+
+ return (ActionComponent[]) comps.ToArray (typeof(ActionComponent));
+ }
+
+ public override Component[] GetChildren ()
+ {
+ return GetActions ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesigner.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesigner.cs
new file mode 100644
index 0000000000..473add6802
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesigner.cs
@@ -0,0 +1,278 @@
+
+using System;
+
+namespace Stetic
+{
+ public class ActionGroupDesigner: Designer
+ {
+ ActionGroupEditSession editSession;
+ ActionGroupDesignerFrontend frontend;
+ Project project;
+ string componentName;
+ string actionGroupName;
+ bool autoCommitChanges;
+ WidgetDesigner relatedWidgetDesigner;
+
+ public event EventHandler BindField;
+ public event EventHandler ModifiedChanged;
+ public event EventHandler RootComponentChanged;
+ public event ComponentSignalEventHandler SignalAdded;
+ public event ComponentSignalEventHandler SignalChanged;
+
+ internal ActionGroupDesigner (Project project, string componentName, string actionGroupName, WidgetDesigner relatedWidgetDesigner, bool autoCommitChanges): base (project.App)
+ {
+ this.componentName = componentName;
+ this.relatedWidgetDesigner = relatedWidgetDesigner;
+
+ if (actionGroupName != null)
+ this.actionGroupName = actionGroupName;
+ this.autoCommitChanges = autoCommitChanges;
+ this.project = project;
+
+ frontend = new ActionGroupDesignerFrontend (this);
+
+ CreateSession ();
+ }
+
+ internal override void SetActive ()
+ {
+ app.ActiveProject = project;
+ }
+
+ public override ProjectItemInfo ProjectItem {
+ get { return project.GetWidget (RootComponent.Name); }
+ }
+
+ public Component RootComponent {
+ get { return app.GetComponent (editSession.EditedActionGroup, null, null); }
+ }
+
+ public bool AllowActionBinding {
+ get {
+ return editSession != null && editSession.AllowActionBinding;
+ }
+ set {
+ if (editSession != null)
+ editSession.AllowActionBinding = value;
+ }
+ }
+
+ public UndoQueue UndoQueue {
+ get {
+ if (relatedWidgetDesigner != null)
+ return relatedWidgetDesigner.UndoQueue;
+ else if (editSession != null)
+ return editSession.UndoQueue;
+ else
+ return UndoQueue.Empty;
+ }
+ }
+
+ public ActionComponent SelectedAction {
+ get {
+ if (editSession == null)
+ return null;
+ Wrapper.Action act;
+ string an;
+ editSession.GetSelectedAction (out act, out an);
+ if (act != null)
+ return (ActionComponent) app.GetComponent (act, an, null);
+ else
+ return null;
+ }
+ set {
+ editSession.SetSelectedAction ((Wrapper.Action)value.Backend);
+ }
+ }
+
+ public bool HasData {
+ get { return editSession != null && editSession.HasData; }
+ }
+
+ public bool Modified {
+ get { return editSession != null && editSession.Modified; }
+ set {
+ if (editSession != null)
+ editSession.Modified = value;
+ }
+ }
+
+ public string ActiveGroup {
+ get {
+ if (editSession == null)
+ return null;
+ return editSession.ActiveGroup;
+ }
+ set {
+ if (editSession != null)
+ editSession.ActiveGroup = value;
+ }
+ }
+
+ public void Save ()
+ {
+ if (editSession != null) {
+ editSession.Save ();
+ if (!autoCommitChanges && componentName != null)
+ componentName = editSession.ActiveGroup;
+ }
+ }
+
+ public void CopySelection ()
+ {
+ if (editSession != null)
+ editSession.CopySelection ();
+ }
+
+ public void CutSelection ()
+ {
+ if (editSession != null)
+ editSession.CutSelection ();
+ }
+
+ public void PasteToSelection ()
+ {
+ if (editSession != null)
+ editSession.PasteToSelection ();
+ }
+
+ public void DeleteSelection ()
+ {
+ if (editSession != null)
+ editSession.DeleteSelection ();
+ }
+
+ protected override void OnCreatePlug (uint socketId)
+ {
+ editSession.CreateBackendWidgetPlug (socketId);
+ }
+
+ protected override void OnDestroyPlug (uint socketId)
+ {
+ editSession.DestroyBackendWidgetPlug ();
+ }
+
+ protected override Gtk.Widget OnCreateWidget ()
+ {
+ return editSession.Backend;
+ }
+
+ void CreateSession ()
+ {
+ try {
+ if (actionGroupName != null)
+ editSession = project.ProjectBackend.CreateGlobalActionGroupDesignerSession (frontend, actionGroupName, autoCommitChanges);
+ else
+ editSession = project.ProjectBackend.CreateLocalActionGroupDesignerSession (frontend, componentName, autoCommitChanges);
+ ResetCustomWidget ();
+ } catch (Exception ex) {
+ editSession = null;
+ Console.WriteLine (ex);
+ AddCustomWidget (new Gtk.Label (ex.Message));
+ }
+ }
+
+ protected override void OnDestroyed ()
+ {
+ frontend.disposed = true;
+ System.Runtime.Remoting.RemotingServices.Disconnect (frontend);
+ if (editSession != null)
+ editSession.Dispose ();
+ editSession = null;
+ base.OnDestroyed ();
+ }
+
+ internal override void OnBackendChanged (ApplicationBackend oldBackend)
+ {
+ object[] sessionData = null;
+
+ if (oldBackend != null) {
+ if (!autoCommitChanges)
+ sessionData = editSession.SaveState ();
+ if (editSession != null)
+ editSession.Dispose ();
+ }
+
+ CreateSession ();
+
+ if (sessionData != null && editSession != null)
+ editSession.RestoreState (sessionData);
+
+ base.OnBackendChanged (oldBackend);
+
+ if (RootComponentChanged != null)
+ RootComponentChanged (this, EventArgs.Empty);
+ }
+
+ internal void NotifyBindField ()
+ {
+ if (BindField != null)
+ BindField (this, EventArgs.Empty);
+ }
+
+ internal void NotifyModified ()
+ {
+ if (ModifiedChanged != null)
+ ModifiedChanged (this, EventArgs.Empty);
+ }
+
+ internal void NotifySignalAdded (Wrapper.Action action, string name, Signal signal)
+ {
+ ActionComponent c = (ActionComponent) app.GetComponent (action, name, null);
+ if (c != null && SignalAdded != null)
+ SignalAdded (this, new ComponentSignalEventArgs (project, c, null, signal));
+ }
+
+ internal void NotifySignalChanged (Wrapper.Action action, string name, Signal oldSignal, Signal signal)
+ {
+ ActionComponent c = (ActionComponent) app.GetComponent (action, name, null);
+ if (c != null && SignalChanged != null)
+ SignalChanged (this, new ComponentSignalEventArgs (project, c, oldSignal, signal));
+ }
+ }
+
+ internal class ActionGroupDesignerFrontend: MarshalByRefObject
+ {
+ ActionGroupDesigner designer;
+ internal bool disposed;
+
+ public ActionGroupDesignerFrontend (ActionGroupDesigner designer)
+ {
+ this.designer = designer;
+ }
+
+ public void NotifyBindField ()
+ {
+ Gtk.Application.Invoke (
+ delegate { if (!disposed) designer.NotifyBindField (); }
+ );
+ }
+
+ public void NotifyModified ()
+ {
+ Gtk.Application.Invoke (
+ delegate { if (!disposed) designer.NotifyModified (); }
+ );
+ }
+
+ public void NotifySignalAdded (Wrapper.Action action, string name, Signal signal)
+ {
+ Gtk.Application.Invoke (
+ delegate { if (!disposed) designer.NotifySignalAdded (action, name, signal); }
+ );
+ }
+
+ public void NotifySignalChanged (Wrapper.Action action, string name, Signal oldSignal, Signal signal)
+ {
+ Gtk.Application.Invoke (
+ delegate { if (!disposed) designer.NotifySignalChanged (action, name, oldSignal, signal); }
+ );
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesignerBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesignerBackend.cs
new file mode 100644
index 0000000000..f5e562e12a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupDesignerBackend.cs
@@ -0,0 +1,45 @@
+
+using System;
+
+namespace Stetic
+{
+ internal class ActionGroupDesignerBackend: Gtk.VBox
+ {
+ Editor.ActionGroupEditor editor;
+ ActionGroupToolbar toolbar;
+ WidgetDesignerBackend groupDesign;
+
+ internal ActionGroupDesignerBackend (WidgetDesignerBackend groupDesign, Editor.ActionGroupEditor editor, ActionGroupToolbar toolbar)
+ {
+ this.editor = editor;
+ this.toolbar = toolbar;
+ this.groupDesign = groupDesign;
+
+ BorderWidth = 3;
+ PackStart (toolbar, false, false, 0);
+ PackStart (groupDesign, true, true, 3);
+ }
+
+ public Editor.ActionGroupEditor Editor {
+ get { return editor; }
+ }
+
+ public ActionGroupToolbar Toolbar {
+ get { return toolbar; }
+ }
+
+ public void UpdateObjectViewers ()
+ {
+ groupDesign.UpdateObjectViewers ();
+ }
+
+ public override void Dispose ()
+ {
+ this.editor = null;
+ this.toolbar = null;
+ this.groupDesign = null;
+ base.Dispose ();
+ }
+
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupEditSession.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupEditSession.cs
new file mode 100644
index 0000000000..c7900efe5d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupEditSession.cs
@@ -0,0 +1,355 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+
+namespace Stetic
+{
+ internal class ActionGroupEditSession: MarshalByRefObject, IDisposable
+ {
+ ActionGroupDesignerBackend designer;
+ Gtk.Plug plug;
+ ActionGroupDesignerFrontend frontend;
+ bool autoCommitChanges;
+ string groupToEdit;
+ string containerName;
+ ProjectBackend project;
+ bool modified;
+ bool allowActionBinding;
+ bool designerRequested;
+ ActionGroupToolbar groupToolbar;
+
+ Stetic.Wrapper.ActionGroup groupCopy;
+ Stetic.Wrapper.ActionGroup group;
+ Hashtable actionCopyMap = new Hashtable ();
+
+ UndoRedoManager undoManager;
+ UndoQueue undoQueue;
+
+ public ActionGroupEditSession (ActionGroupDesignerFrontend frontend, ProjectBackend project, string containerName, string groupToEdit, bool autoCommitChanges)
+ {
+ this.groupToEdit = groupToEdit;
+ this.containerName = containerName;
+ this.frontend = frontend;
+ this.project = project;
+ this.autoCommitChanges = autoCommitChanges;
+
+ if (groupToEdit != null) {
+ group = project.ActionGroups [groupToEdit];
+ if (group == null)
+ throw new InvalidOperationException ("Unknown action group: " + groupToEdit);
+ Load (group);
+ undoManager = new UndoRedoManager ();
+ undoQueue = new UndoQueue ();
+ undoManager.UndoQueue = undoQueue;
+ undoManager.RootObject = groupCopy;
+
+ groupToolbar = new ActionGroupToolbar (frontend, groupCopy);
+ }
+ else {
+ if (!autoCommitChanges)
+ throw new System.NotSupportedException ();
+
+ Stetic.Wrapper.Container container = project.GetTopLevelWrapper (containerName, true);
+ groupToolbar = new ActionGroupToolbar (frontend, container.LocalActionGroups);
+ }
+
+ // Don't delay the creation of the designer because when used in combination with the
+ // widget designer, change events are subscribed since the begining
+
+ designer = UserInterface.CreateActionGroupDesigner (project, groupToolbar);
+ designer.Editor.GroupModified += OnModified;
+ designer.Toolbar.AllowActionBinding = allowActionBinding;
+ designer.Destroyed += delegate { designer = null; Dispose (); };
+ }
+
+ public Wrapper.ActionGroup EditedActionGroup {
+ get { return groupCopy; }
+ }
+
+ void Load (Stetic.Wrapper.ActionGroup group)
+ {
+ if (autoCommitChanges) {
+ groupCopy = group;
+ }
+ else {
+ actionCopyMap.Clear ();
+
+ groupCopy = new Stetic.Wrapper.ActionGroup ();
+ groupCopy.Name = group.Name;
+
+ foreach (Stetic.Wrapper.Action action in group.Actions) {
+ Stetic.Wrapper.Action dupaction = action.Clone ();
+ groupCopy.Actions.Add (dupaction);
+ actionCopyMap [dupaction] = action;
+ }
+ groupCopy.SignalAdded += new Stetic.SignalEventHandler (OnSignalAdded);
+ groupCopy.SignalChanged += new Stetic.SignalChangedEventHandler (OnSignalChanged);
+ }
+ }
+
+ public void Save ()
+ {
+ if (autoCommitChanges)
+ return;
+
+ if (group.Name != groupCopy.Name)
+ group.Name = groupCopy.Name;
+
+ foreach (Stetic.Wrapper.Action actionCopy in groupCopy.Actions) {
+ Stetic.Wrapper.Action action = (Stetic.Wrapper.Action) actionCopyMap [actionCopy];
+ if (action != null)
+ action.CopyFrom (actionCopy);
+ else {
+ action = actionCopy.Clone ();
+ actionCopyMap [actionCopy] = action;
+ group.Actions.Add (action);
+ }
+ }
+
+ ArrayList todelete = new ArrayList ();
+ foreach (Stetic.Wrapper.Action actionCopy in actionCopyMap.Keys) {
+ if (!groupCopy.Actions.Contains (actionCopy))
+ todelete.Add (actionCopy);
+ }
+
+ foreach (Stetic.Wrapper.Action actionCopy in todelete) {
+ Stetic.Wrapper.Action action = (Stetic.Wrapper.Action) actionCopyMap [actionCopy];
+ group.Actions.Remove (action);
+ actionCopyMap.Remove (actionCopy);
+ }
+ Modified = false;
+ }
+
+ public UndoQueue UndoQueue {
+ get {
+ if (undoQueue != null)
+ return undoQueue;
+ else
+ return UndoQueue.Empty;
+ }
+ }
+
+ public void CopySelection ()
+ {
+ if (designer != null)
+ designer.Editor.Copy ();
+ }
+
+ public void CutSelection ()
+ {
+ if (designer != null)
+ designer.Editor.Cut ();
+ }
+
+ public void PasteToSelection ()
+ {
+ if (designer != null)
+ designer.Editor.Paste ();
+ }
+
+ public void DeleteSelection ()
+ {
+ if (designer != null)
+ designer.Editor.Delete ();
+ }
+
+ void OnProjectReloaded (object s, EventArgs a)
+ {
+ // Called when the underlying project has changed. Object references need to be updated.
+ if (autoCommitChanges) {
+ if (designer != null) {
+ if (groupToEdit != null) {
+ groupToolbar.ActiveGroup = project.ActionGroups [groupToEdit];
+ } else {
+ Stetic.Wrapper.Container container = project.GetTopLevelWrapper (containerName, true);
+ groupToolbar.ActionGroups = container.LocalActionGroups;
+ }
+ }
+ } else {
+ // We only need to remap the actions
+ group = project.ActionGroups [groupToEdit];
+ actionCopyMap.Clear ();
+ foreach (Wrapper.Action dupac in groupCopy.Actions) {
+ Wrapper.Action ac = group.GetAction (dupac.Name);
+ if (ac != null)
+ actionCopyMap [dupac] = ac;
+ }
+ }
+ }
+
+ void OnModified (object ob, EventArgs args)
+ {
+ modified = true;
+ frontend.NotifyModified ();
+ }
+
+ public bool HasData {
+ get {
+ if (groupToEdit != null)
+ return true;
+ Stetic.Wrapper.Container container = project.GetTopLevelWrapper (containerName, true);
+ return container.LocalActionGroups.Count > 0;
+ }
+ }
+
+ public bool Modified {
+ get { return modified; }
+ set { modified = value; frontend.NotifyModified (); }
+ }
+// public bool Modified {
+// get { return project.WasModified (); }
+// }
+
+ public string ActiveGroup {
+ get {
+ if (designer != null) {
+ Wrapper.ActionGroup grp = designer.Toolbar.ActiveGroup;
+ if (grp != null)
+ return grp.Name;
+ }
+ return null;
+ }
+ set {
+ if (value != null || designer != null) {
+ // No need to create the designer if the active group is being set to null.
+ Wrapper.ActionGroup grp = Backend.Toolbar.ActionGroups [value];
+ Backend.Toolbar.ActiveGroup = grp;
+ }
+ }
+ }
+
+ public void SetSelectedAction (Wrapper.Action action)
+ {
+ // No need to create the designer if the active action is being set to null.
+ if (action != null || designer != null)
+ Backend.Editor.SelectedAction = action;
+ }
+
+ public void GetSelectedAction (out Wrapper.Action action, out string name)
+ {
+ if (designer != null) {
+ action = designer.Editor.SelectedAction;
+ if (action != null)
+ name = action.Name;
+ else
+ name = null;
+ } else {
+ action = null;
+ name = null;
+ }
+ }
+
+ public ActionGroupDesignerBackend Backend {
+ get {
+ designerRequested = true;
+ return designer;
+ }
+ }
+
+ [NoGuiDispatch]
+ public void CreateBackendWidgetPlug (uint socketId)
+ {
+ Gdk.Threads.Enter ();
+ plug = new Gtk.Plug (socketId);
+ plug.Add (Backend);
+ plug.Decorated = false;
+ plug.ShowAll ();
+ Gdk.Threads.Leave ();
+ }
+
+ public void DestroyBackendWidgetPlug ()
+ {
+ if (designer != null) {
+ Gtk.Plug plug = (Gtk.Plug) designer.Parent;
+ plug.Remove (designer);
+ plug.Destroy ();
+ }
+ }
+
+ public bool AllowActionBinding {
+ get {
+ return allowActionBinding;
+ }
+ set {
+ allowActionBinding = value;
+ if (designer != null)
+ designer.Toolbar.AllowActionBinding = value;
+ }
+ }
+
+ public void Dispose ()
+ {
+ if (designer != null) {
+ designer.Editor.GroupModified -= OnModified;
+ if (!designerRequested)
+ designer.Destroy ();
+ }
+
+ project.ProjectReloaded -= OnProjectReloaded;
+
+ if (plug != null) {
+ plug.Destroy ();
+ plug = null;
+ }
+
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+
+ public object[] SaveState ()
+ {
+ if (autoCommitChanges)
+ return null;
+
+ XmlDocument doc = new XmlDocument ();
+ doc.AppendChild (groupCopy.Write (new ObjectWriter (doc, FileFormat.Native)));
+
+ Hashtable nameMap = new Hashtable ();
+ foreach (DictionaryEntry e in actionCopyMap)
+ nameMap [((Wrapper.Action)e.Key).Name] = ((Wrapper.Action)e.Value).Name;
+
+ return new object[] { groupCopy.Name, nameMap, doc.OuterXml };
+ }
+
+ public void RestoreState (object[] data)
+ {
+ if (data == null)
+ return;
+
+ groupCopy = new Stetic.Wrapper.ActionGroup ();
+ groupCopy.Name = (string) data [0];
+
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml ((string) data [2]);
+
+ // Create the map which links edited action with source actions
+ actionCopyMap.Clear ();
+ foreach (DictionaryEntry e in (Hashtable) data [1]) {
+ Wrapper.Action dupaction = groupCopy.GetAction ((string)e.Key);
+ Wrapper.Action action = group.GetAction ((string)e.Value);
+ actionCopyMap [dupaction] = action;
+ }
+
+ groupCopy.SignalAdded += new Stetic.SignalEventHandler (OnSignalAdded);
+ groupCopy.SignalChanged += new Stetic.SignalChangedEventHandler (OnSignalChanged);
+ }
+
+ void OnSignalAdded (object s, Stetic.SignalEventArgs a)
+ {
+ Wrapper.Action action = (Wrapper.Action) a.Wrapper;
+ frontend.NotifySignalAdded (action, action.Name, a.Signal);
+ }
+
+ void OnSignalChanged (object s, Stetic.SignalChangedEventArgs a)
+ {
+ Wrapper.Action action = (Wrapper.Action) a.Wrapper;
+ frontend.NotifySignalChanged (action, action.Name, a.OldSignal, a.Signal);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupToolbar.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupToolbar.cs
new file mode 100644
index 0000000000..c41601509c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ActionGroupToolbar.cs
@@ -0,0 +1,275 @@
+
+using System;
+using System.Collections;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic
+{
+ internal class ActionGroupToolbar: Gtk.Toolbar
+ {
+ Wrapper.ActionGroupCollection actionGroups;
+ Gtk.ComboBox combo;
+ bool updating;
+ ActionGroup currentGroup;
+ ArrayList internalButtons = new ArrayList ();
+ bool singleGroupMode;
+ bool allowBinding;
+ ActionGroupDesignerFrontend frontend;
+ Editor.ActionGroupEditor agroupEditor;
+ Gtk.ToolButton addButton;
+ Gtk.ToolButton removeButton;
+
+ public event ActionGroupEventHandler ActiveGroupChanged;
+ public event ActionGroupEventHandler ActiveGroupCreated;
+
+ public ActionGroupToolbar (ActionGroupDesignerFrontend frontend, bool singleGroupMode)
+ {
+ Initialize (frontend, null, singleGroupMode);
+ }
+
+ public ActionGroupToolbar (ActionGroupDesignerFrontend frontend, Wrapper.ActionGroup actionGroup)
+ {
+ currentGroup = actionGroup;
+ Initialize (frontend, null, true);
+ }
+
+ public ActionGroupToolbar (ActionGroupDesignerFrontend frontend, Wrapper.ActionGroupCollection actionGroups)
+ {
+ Initialize (frontend, actionGroups, false);
+ }
+
+ public bool AllowActionBinding {
+ get { return allowBinding; }
+ set { allowBinding = value; }
+ }
+
+ void Initialize (ActionGroupDesignerFrontend frontend, Wrapper.ActionGroupCollection actionGroups, bool singleGroupMode)
+ {
+ this.frontend = frontend;
+ this.singleGroupMode = singleGroupMode;
+ IconSize = Gtk.IconSize.SmallToolbar;
+ Orientation = Gtk.Orientation.Horizontal;
+ ToolbarStyle = Gtk.ToolbarStyle.BothHoriz;
+
+ combo = Gtk.ComboBox.NewText ();
+
+ if (!singleGroupMode) {
+ combo.Changed += OnActiveChanged;
+
+ Gtk.ToolItem comboItem = new Gtk.ToolItem ();
+ Gtk.HBox cbox = new Gtk.HBox ();
+ cbox.PackStart (new Gtk.Label (Catalog.GetString ("Action Group:") + " "), false, false, 3);
+ cbox.PackStart (combo, true, true, 3);
+ comboItem.Add (cbox);
+ comboItem.ShowAll ();
+ Insert (comboItem, -1);
+ internalButtons.Add (comboItem);
+
+ addButton = new Gtk.ToolButton (Gtk.Stock.Add);
+ addButton.Clicked += OnAddGroup;
+ Insert (addButton, -1);
+ internalButtons.Add (addButton);
+
+ removeButton = new Gtk.ToolButton (Gtk.Stock.Remove);
+ removeButton.Clicked += OnRemoveGroup;
+ Insert (removeButton, -1);
+ internalButtons.Add (removeButton);
+
+ ActionGroups = actionGroups;
+
+ if (actionGroups != null && actionGroups.Count > 0)
+ combo.Active = 0;
+ } else {
+ UpdateActionCommands (null);
+ }
+
+ ShowAll ();
+ }
+
+ public override void Dispose ()
+ {
+ if (combo == null)
+ return;
+
+ combo.Changed -= OnActiveChanged;
+ combo = null;
+ if (addButton != null) {
+ addButton.Clicked -= OnAddGroup;
+ removeButton.Clicked -= OnRemoveGroup;
+ }
+
+ if (agroupEditor != null) {
+ agroupEditor.SelectionChanged -= OnEditorSelectionChanged;
+ agroupEditor = null;
+ }
+
+ if (!singleGroupMode)
+ ActionGroups = null;
+ base.Dispose ();
+ }
+
+ public Wrapper.ActionGroupCollection ActionGroups {
+ get { return actionGroups; }
+ set {
+ if (singleGroupMode)
+ throw new InvalidOperationException ("ActionGroups can't be set in single group mode");
+
+ if (actionGroups != null) {
+ actionGroups.ActionGroupAdded -= OnCollectionChanged;
+ actionGroups.ActionGroupRemoved -= OnCollectionChanged;
+ actionGroups.ActionGroupChanged -= OnCollectionChanged;
+ }
+
+ this.actionGroups = value;
+
+ if (actionGroups != null) {
+ actionGroups.ActionGroupAdded += OnCollectionChanged;
+ actionGroups.ActionGroupRemoved += OnCollectionChanged;
+ actionGroups.ActionGroupChanged += OnCollectionChanged;
+ }
+ Refresh ();
+ }
+ }
+
+ public void Bind (Editor.ActionGroupEditor agroupEditor)
+ {
+ this.agroupEditor = agroupEditor;
+ agroupEditor.SelectionChanged += OnEditorSelectionChanged;
+ agroupEditor.ActionGroup = ActiveGroup;
+ }
+
+ public void OnEditorSelectionChanged (object s, EventArgs a)
+ {
+ UpdateActionCommands (agroupEditor.SelectedAction);
+ }
+
+ public ActionGroup ActiveGroup {
+ get {
+ return currentGroup;
+ }
+ set {
+ if (singleGroupMode) {
+ currentGroup = value;
+ UpdateActionCommands (null);
+ NotifyActiveGroupChanged ();
+ } else {
+ int i = actionGroups.IndexOf (value);
+ if (i != -1)
+ combo.Active = i;
+ }
+ }
+ }
+
+ void Refresh ()
+ {
+ if (singleGroupMode || combo == null)
+ return;
+
+ while (combo.Model.IterNChildren () > 0)
+ combo.RemoveText (0);
+ if (actionGroups != null) {
+ foreach (ActionGroup group in actionGroups)
+ combo.AppendText (group.Name);
+ }
+ }
+
+ void OnCollectionChanged (object s, ActionGroupEventArgs args)
+ {
+ // Avoid firing the selection change event if the selected
+ // group is the same after the refresh
+ ActionGroup oldGroup = currentGroup;
+ updating = true;
+
+ int i = combo.Active;
+ Refresh ();
+ if (actionGroups.Count == 0) {
+ combo.Sensitive = false;
+ currentGroup = null;
+ }
+ else {
+ combo.Sensitive = true;
+ if (i == -1)
+ i = 0;
+ if (i < actionGroups.Count)
+ combo.Active = i;
+ else
+ combo.Active = actionGroups.Count - 1;
+ currentGroup = (ActionGroup) actionGroups [combo.Active];
+ }
+ updating = false;
+ if (currentGroup != oldGroup)
+ OnActiveChanged (null, null);
+ frontend.NotifyModified ();
+ }
+
+ void OnAddGroup (object s, EventArgs args)
+ {
+ ActionGroup group = new ActionGroup ();
+ group.Name = Catalog.GetString ("New Action Group");
+ actionGroups.Add (group);
+ combo.Active = actionGroups.Count - 1;
+ if (ActiveGroupCreated != null)
+ ActiveGroupCreated (this, new ActionGroupEventArgs (ActiveGroup));
+
+ if (agroupEditor != null)
+ agroupEditor.StartEditing ();
+ }
+
+ void OnRemoveGroup (object s, EventArgs args)
+ {
+ if (combo.Active != -1)
+ actionGroups.RemoveAt (combo.Active);
+ }
+
+ void OnActiveChanged (object s, EventArgs args)
+ {
+ if (!updating) {
+ UpdateActionCommands (null);
+ if (combo.Active != -1)
+ currentGroup = (ActionGroup) actionGroups [combo.Active];
+ else
+ currentGroup = null;
+ NotifyActiveGroupChanged ();
+ }
+ }
+
+ void NotifyActiveGroupChanged ()
+ {
+ if (agroupEditor != null)
+ agroupEditor.ActionGroup = ActiveGroup;
+ if (ActiveGroupChanged != null)
+ ActiveGroupChanged (this, new ActionGroupEventArgs (ActiveGroup));
+ }
+
+ void UpdateActionCommands (Wrapper.Action action)
+ {
+ foreach (Gtk.Widget w in Children) {
+ if (!internalButtons.Contains (w)) {
+ Remove (w);
+ w.Destroy ();
+ }
+ }
+ AddActionCommands (action);
+
+ if (internalButtons.Count > 0 && internalButtons.Count != Children.Length) {
+ Insert (new Gtk.SeparatorToolItem (), internalButtons.Count);
+ }
+ ShowAll ();
+ }
+
+ protected virtual void AddActionCommands (Wrapper.Action action)
+ {
+ if (allowBinding) {
+ Gtk.ToolButton bindButton = new Gtk.ToolButton (null, Catalog.GetString ("Bind to Field"));
+ bindButton.IsImportant = true;
+ bindButton.Show ();
+ Insert (bindButton, -1);
+ if (action == null)
+ bindButton.Sensitive = false;
+
+ bindButton.Clicked += delegate { frontend.NotifyBindField (); };
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Application.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Application.cs
new file mode 100644
index 0000000000..afe4a3a00e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Application.cs
@@ -0,0 +1,584 @@
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.IO;
+using System.Xml;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Channels;
+using System.Runtime.Remoting.Channels.Tcp;
+using System.Diagnostics;
+using Mono.Remoting.Channels.Unix;
+using Mono.Cecil;
+
+namespace Stetic
+{
+ public enum IsolationMode
+ {
+ None,
+ ProcessTcp,
+ ProcessUnix
+ }
+
+ public delegate string AssemblyResolverCallback (string assemblyName);
+
+ public static class ApplicationFactory {
+
+ public static Application CreateApplication (IsolationMode mode)
+ {
+ switch (mode) {
+ case IsolationMode.None:
+ return new LocalApplication ();
+ case IsolationMode.ProcessTcp:
+ case IsolationMode.ProcessUnix:
+ return new IsolatedApplication (mode);
+ default:
+ throw new ArgumentException ("mode");
+ }
+ }
+ }
+
+ internal class IsolatedApplication : Application {
+
+ string channelId;
+ ApplicationBackendController backendController;
+
+ string RegisterRemotingChannel (IsolationMode mode)
+ {
+ string remotingChannel;
+ if (mode == IsolationMode.ProcessTcp) {
+ remotingChannel = "tcp";
+ IChannel ch = ChannelServices.GetChannel ("tcp");
+ if (ch == null) {
+ ChannelServices.RegisterChannel (new TcpChannel (0), false);
+ }
+ } else {
+ remotingChannel = "unix";
+ IChannel ch = ChannelServices.GetChannel ("unix");
+ if (ch == null) {
+ string unixRemotingFile = Path.GetTempFileName ();
+ ChannelServices.RegisterChannel (new UnixChannel (unixRemotingFile), false);
+ }
+ }
+ return remotingChannel;
+ }
+
+ public IsolatedApplication (IsolationMode mode)
+ {
+ if (mode == IsolationMode.None)
+ throw new ArgumentException ("mode");
+ channelId = RegisterRemotingChannel (mode);
+ backendController = new ApplicationBackendController (this, channelId);
+ backendController.StartBackend ();
+ OnBackendChanged (false);
+ }
+
+ public override void Dispose ()
+ {
+ base.Dispose ();
+ backendController.StopBackend (true);
+ }
+
+ public event BackendChangingHandler BackendChanging;
+ public event BackendChangedHandler BackendChanged;
+
+ void OnNewBackendStarted (object ob, EventArgs args)
+ {
+ OnBackendChanging ();
+ ApplicationBackendController oldBackend = backendController;
+ backendController = (ApplicationBackendController) ob;
+ OnBackendChanged (true);
+ oldBackend.StopBackend (false);
+ }
+
+ void OnBackendStopped (object ob, EventArgs args)
+ {
+ // The backend process crashed, try to restart it
+ Backend = null;
+ backendController = new ApplicationBackendController (this, channelId);
+ backendController.StartBackend ();
+ OnBackendChanged (true);
+ }
+
+ void OnBackendChanged (bool notify)
+ {
+ ApplicationBackend oldBackend = Backend;
+
+ Backend = backendController.Backend;
+ backendController.Stopped += OnBackendStopped;
+ UpdateWidgetLibraries (false, false);
+ ClearCollections ();
+ if (notify && BackendChanged != null)
+ BackendChanged (oldBackend);
+
+ Backend.ActiveProject = ActiveProject != null ? ActiveProject.ProjectBackend : null;
+ }
+
+ void OnBackendChanging ()
+ {
+ Backend.GlobalWidgetLibraries = widgetLibraries;
+ if (BackendChanging != null)
+ BackendChanging ();
+ }
+
+ internal override void RestartBackend ()
+ {
+ // The backend process needs to be restarted.
+ // This is done in background.
+
+ ThreadPool.QueueUserWorkItem (delegate {
+ try {
+ // Start the new backend
+ ApplicationBackendController newController = new ApplicationBackendController (this, channelId);
+ newController.StartBackend ();
+ Gtk.Application.Invoke (newController, EventArgs.Empty, OnNewBackendStarted);
+ } catch {
+ // FIXME: show an error message
+ }
+ });
+ }
+
+ internal override ComponentType CreateComponentType (string typeName)
+ {
+ string desc = null, className = null, category = null, targetGtkVersion = null, library = null;
+ Gdk.Pixbuf px = null;
+
+ byte[] icon;
+
+ if (Backend.GetClassDescriptorInfo (typeName, out desc, out className, out category, out targetGtkVersion, out library, out icon) && icon != null)
+ px = new Gdk.Pixbuf (icon);
+
+ if (px == null)
+ px = ComponentType.Unknown.Icon;
+
+ if (desc == null)
+ desc = typeName;
+
+ return new ComponentType (this, typeName, desc, className, category, targetGtkVersion, library, px);
+ }
+ }
+
+ internal class LocalApplication : Application {
+
+ public LocalApplication ()
+ {
+ Backend = new ApplicationBackend (this);
+ }
+
+ public override void Dispose ()
+ {
+ base.Dispose ();
+ Backend.Dispose ();
+ }
+
+ internal override ComponentType CreateComponentType (string typeName)
+ {
+ ClassDescriptor cls = Registry.LookupClassByName (typeName);
+ if (cls == null)
+ return null;
+
+ return new ComponentType (this, typeName, cls.Label, cls.WrappedTypeName, cls.Category, cls.TargetGtkVersion, cls.Library.Name, cls.Icon);
+ }
+ }
+
+ public abstract class Application : MarshalByRefObject, IDisposable {
+
+ ApplicationBackend backend;
+
+ Hashtable components = new Hashtable ();
+ Hashtable types = new Hashtable ();
+ internal ArrayList widgetLibraries = new ArrayList ();
+ ArrayList projects = new ArrayList ();
+ Project activeProject;
+ Designer activeDesigner;
+
+ WidgetPropertyTree propertiesWidget;
+ Palette paletteWidget;
+ WidgetTree projectWidget;
+ SignalsEditor signalsWidget;
+ bool allowInProcLibraries = true;
+ bool disposed;
+
+ public AssemblyResolverCallback WidgetLibraryResolver {
+ get { return Backend.WidgetLibraryResolver; }
+ set { Backend.WidgetLibraryResolver = value; }
+ }
+
+ public MimeResolverDelegate MimeResolver {
+ set { Backend.MimeResolver = value; }
+ }
+
+ public Editor.ShowUrlDelegate ShowUrl {
+ set { Backend.ShowUrl = value; }
+ }
+
+ public bool ShowNonContainerWarning {
+ get { return Backend.ShowNonContainerWarning; }
+ set { Backend.ShowNonContainerWarning = value; }
+ }
+
+ // Loads the libraries registered in the projects or in the application.
+ // It will reload the libraries if they have changed. Libraries won't be
+ // unloaded unless forceUnload is set to true
+ public void UpdateWidgetLibraries (bool forceUnload)
+ {
+ UpdateWidgetLibraries (true, forceUnload);
+ }
+
+ internal virtual void RestartBackend ()
+ {
+ }
+
+ protected void ClearCollections ()
+ {
+ lock (types) {
+ types.Clear ();
+ }
+
+ Component[] comps;
+ lock (components) {
+ // All components should have been cleared by the backend,
+ // just make sure it did
+ comps = new Component [components.Count];
+ components.Values.CopyTo (comps, 0);
+ components.Clear ();
+ }
+
+ foreach (Component c in comps) {
+ c.Dispose ();
+ }
+ }
+
+ internal void UpdateWidgetLibraries (bool allowBackendRestart, bool forceUnload)
+ {
+ // Collect libraries from the project and from the application
+
+ ArrayList assemblies = new ArrayList ();
+ assemblies.AddRange (widgetLibraries);
+
+ ArrayList projectBackends = new ArrayList ();
+ foreach (Project p in projects)
+ if (p.IsBackendLoaded)
+ projectBackends.Add (p.ProjectBackend);
+
+ if (!Backend.UpdateLibraries (assemblies, projectBackends, allowBackendRestart, forceUnload))
+ RestartBackend ();
+ }
+
+ public virtual void Dispose ()
+ {
+ if (disposed)
+ return;
+
+ disposed = true;
+ ClearCollections ();
+ ArrayList copy = (ArrayList) projects.Clone ();
+ foreach (Project p in copy)
+ p.Dispose ();
+ if (propertiesWidget != null)
+ propertiesWidget.Destroy ();
+ if (paletteWidget != null)
+ paletteWidget.Destroy ();
+ if (projectWidget != null)
+ projectWidget.Destroy ();
+ if (signalsWidget != null)
+ signalsWidget.Destroy ();
+ widgetLibraries.Clear ();
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+
+ internal ApplicationBackend Backend {
+ get { return backend; }
+ set { backend = value; }
+ }
+
+ void ProjectDisposed (object sender, EventArgs args)
+ {
+ projects.Remove (sender as Project);
+ if (!disposed)
+ UpdateWidgetLibraries (false, false);
+ }
+
+// public Project LoadProject (string path, IProjectDesignInfo info)
+// {
+// Project p = new Project (this, info);
+// p.Load (path);
+// projects.Add (p);
+// p.Disposed += ProjectDisposed;
+// return p;
+// }
+
+ public Project CreateProject (IProjectDesignInfo info)
+ {
+ Project p = new Project (this, info);
+ projects.Add (p);
+ p.Disposed += ProjectDisposed;
+ return p;
+ }
+
+ public ComponentType[] GetComponentTypes (string fileName)
+ {
+ if (IsWidgetLibrary (fileName))
+ return CecilWidgetLibrary.GetComponentTypes (this, fileName).ToArray ();
+ else
+ return new ComponentType [0];
+ }
+
+ public void AddWidgetLibrary (string assemblyPath)
+ {
+ if (!widgetLibraries.Contains (assemblyPath)) {
+ widgetLibraries.Add (assemblyPath);
+ Backend.GlobalWidgetLibraries = widgetLibraries;
+ UpdateWidgetLibraries (false, false);
+ }
+ }
+
+ public void RemoveWidgetLibrary (string assemblyPath)
+ {
+ widgetLibraries.Remove (assemblyPath);
+ Backend.GlobalWidgetLibraries = widgetLibraries;
+ UpdateWidgetLibraries (false, false);
+ }
+
+ public string[] GetWidgetLibraries ()
+ {
+ return (string[]) widgetLibraries.ToArray (typeof(string));
+ }
+
+ public bool IsWidgetLibrary (string assemblyRef)
+ {
+ AssemblyResolver resolver = new AssemblyResolver (Backend);
+ return InternalIsWidgetLibrary (resolver, assemblyRef);
+ }
+
+ internal static bool InternalIsWidgetLibrary (AssemblyResolver resolver, string assemblyRef)
+ {
+ string path;
+
+ if (assemblyRef.EndsWith (".dll") || assemblyRef.EndsWith (".exe")) {
+ if (!File.Exists (assemblyRef))
+ return false;
+ path = assemblyRef;
+ }
+ else {
+ path = resolver.Resolve (assemblyRef, null);
+ if (path == null)
+ return false;
+ }
+
+ return CecilWidgetLibrary.IsWidgetLibrary (path);
+ }
+
+ public CodeGenerationResult GenerateProjectCode (string file, string namespaceName, CodeDomProvider provider, GenerationOptions options, params Project[] projects)
+ {
+ ArrayList files = new ArrayList ();
+ CodeGenerationResult res = GenerateProjectCode (options, projects);
+
+ string basePath = Path.GetDirectoryName (file);
+ string ext = Path.GetExtension (file);
+
+ foreach (SteticCompilationUnit unit in res.Units) {
+ string fname;
+ if (unit.Name.Length == 0)
+ fname = file;
+ else
+ fname = Path.Combine (basePath, unit.Name) + ext;
+ files.Add (fname);
+ unit.Name = fname;
+ StreamWriter fileStream = new StreamWriter (fname);
+ try {
+ provider.GenerateCodeFromCompileUnit (unit, fileStream, new CodeGeneratorOptions ());
+ } finally {
+ fileStream.Close ();
+ }
+ }
+ return res;
+ }
+
+ public CodeGenerationResult GenerateProjectCode (GenerationOptions options, params Project[] projects)
+ {
+ ProjectBackend[] pbs = new ProjectBackend [projects.Length];
+ for (int n=0; n<projects.Length; n++)
+ pbs [n] = projects [n].ProjectBackend;
+
+ return Backend.GenerateProjectCode (options, pbs);
+ }
+
+ public Designer ActiveDesigner {
+ get {
+ return activeDesigner;
+ }
+ set {
+ if (activeDesigner != value) {
+ activeDesigner = value;
+ if (activeDesigner != null)
+ activeDesigner.SetActive ();
+ else
+ ActiveProject = null;
+ }
+ }
+ }
+
+ internal Project ActiveProject {
+ get { return activeProject; }
+ set {
+ activeProject = value;
+ Backend.ActiveProject = value != null ? value.ProjectBackend : null;
+ Backend.SetActiveDesignSession (null);
+ }
+ }
+
+ internal void SetActiveDesignSession (Project p, WidgetEditSession session)
+ {
+ activeProject = p;
+ Backend.ActiveProject = p != null ? p.ProjectBackend : null;
+ Backend.SetActiveDesignSession (session);
+ }
+
+ public WidgetPropertyTree PropertiesWidget {
+ get {
+ if (propertiesWidget == null) {
+ propertiesWidget = new WidgetPropertyTree (this);
+ propertiesWidget.Destroyed += delegate { propertiesWidget = null; };
+ }
+ return propertiesWidget;
+ }
+ }
+
+ public Palette PaletteWidget {
+ get {
+ if (paletteWidget == null) {
+ paletteWidget = new Palette (this);
+ paletteWidget.Destroyed += delegate { paletteWidget = null; };
+ }
+ return paletteWidget;
+ }
+ }
+
+ public WidgetTree WidgetTreeWidget {
+ get {
+ if (projectWidget == null) {
+ projectWidget = new WidgetTree (this);
+ projectWidget.Destroyed += delegate { projectWidget = null; };
+ }
+ return projectWidget;
+ }
+ }
+
+ public SignalsEditor SignalsWidget {
+ get {
+ if (signalsWidget == null) {
+ signalsWidget = new SignalsEditor (this);
+ signalsWidget.Destroyed += delegate { signalsWidget = null; };
+ }
+ return signalsWidget;
+ }
+ }
+
+ public bool AllowInProcLibraries {
+ get { return allowInProcLibraries; }
+ set {
+ allowInProcLibraries = value;
+ if (backend != null)
+ backend.AllowInProcLibraries = value;
+ }
+ }
+
+ internal void NotifyLibraryUnloaded (string name)
+ {
+ // Remove cached types from the unloaded library
+ ArrayList toDelete = new ArrayList ();
+ lock (types) {
+ foreach (ComponentType ct in types.Values) {
+ if (ct.Library == name)
+ toDelete.Add (ct.Name);
+ }
+ foreach (string s in toDelete)
+ types.Remove (s);
+ }
+ }
+
+ internal abstract ComponentType CreateComponentType (string typeName);
+
+ internal ComponentType GetComponentType (string typeName)
+ {
+ lock (types) {
+ ComponentType t = (ComponentType) types [typeName];
+ if (t != null) return t;
+
+ if (typeName == "Gtk.Action" || typeName == "Gtk.ActionGroup") {
+ t = new ComponentType (this, typeName, "", typeName, "Actions", "2.4", null, ComponentType.Unknown.Icon);
+ types [typeName] = t;
+ return t;
+ }
+
+ t = CreateComponentType (typeName);
+ types [typeName] = t;
+ return t;
+ }
+ }
+
+ internal Component GetComponent (object cbackend, string name, string type)
+ {
+ try {
+ lock (components) {
+ if (cbackend == null)
+ return null;
+
+ Component c = (Component) components [cbackend];
+ if (c != null)
+ return c;
+
+ // If the remote object is already disposed, don't try to create a
+ // local component.
+ if (cbackend is ObjectWrapper && ((ObjectWrapper)cbackend).IsDisposed)
+ return null;
+
+ if (cbackend is Wrapper.Action) {
+ c = new ActionComponent (this, cbackend, name);
+ ((ObjectWrapper)cbackend).Frontend = c;
+ } else if (cbackend is Wrapper.ActionGroup) {
+ c = new ActionGroupComponent (this, cbackend, name);
+ ((Wrapper.ActionGroup)cbackend).Frontend = c;
+ } else if (cbackend is ObjectWrapper) {
+ c = new WidgetComponent (this, cbackend, name, type != null ? GetComponentType (type) : null);
+ ((ObjectWrapper)cbackend).Frontend = c;
+ } else if (cbackend == null)
+ throw new System.ArgumentNullException ("cbackend");
+ else
+ throw new System.InvalidOperationException ("Invalid component type: " + cbackend.GetType ());
+
+ components [cbackend] = c;
+ return c;
+ }
+ }
+ catch (System.Runtime.Remoting.RemotingException)
+ {
+ // There may be a remoting exception if the remote wrapper
+ // has already been disconnected when trying to create the
+ // component frontend. This may happen since calls are
+ // dispatched in the GUI thread, so they may be delayed.
+ return null;
+ }
+ }
+
+ internal void DisposeComponent (Component c)
+ {
+ lock (components) {
+ components.Remove (c.Backend);
+ }
+ }
+ }
+
+ internal delegate void BackendChangingHandler ();
+ internal delegate void BackendChangedHandler (ApplicationBackend oldBackend);
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackend.cs
new file mode 100644
index 0000000000..eb738d5642
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackend.cs
@@ -0,0 +1,653 @@
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.CodeDom;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Channels;
+using System.Runtime.Remoting.Channels.Tcp;
+using Mono.Remoting.Channels.Unix;
+
+namespace Stetic
+{
+ internal class ApplicationBackend: MarshalByRefObject, IDisposable, IObjectViewer
+ {
+ PaletteBackend paletteWidget;
+ WidgetPropertyTreeBackend propertiesWidget;
+ SignalsEditorEditSession signalsWidget;
+ ProjectViewBackend projectWidget;
+ ArrayList globalWidgetLibraries = new ArrayList ();
+ AssemblyResolverCallback widgetLibraryResolver;
+ object targetViewerObject;
+ bool allowInProcLibraries = true;
+ Application appFrontend;
+ string coreLibrary;
+
+ ProjectBackend activeProject;
+ WidgetEditSession activeDesignSession;
+ static ApplicationBackendController controller;
+
+ public ApplicationBackend (Application app)
+ {
+ appFrontend = app;
+ coreLibrary = Path.GetFullPath (typeof(Registry).Assembly.Location);
+ Registry.Initialize (new AssemblyWidgetLibrary (coreLibrary, typeof(Registry).Assembly));
+
+ WidgetDesignerBackend.DefaultObjectViewer = this;
+ }
+
+ public static void Main ()
+ {
+ Gdk.Threads.Init ();
+ Gtk.Application.Init ();
+
+ System.Threading.Thread.CurrentThread.Name = "gui-thread";
+
+ // Read the remoting channel to use
+
+ string channel = Console.In.ReadLine ();
+
+ IServerChannelSinkProvider formatterSink = new BinaryServerFormatterSinkProvider ();
+ formatterSink.Next = new GuiDispatchServerSinkProvider ();
+
+ string unixPath = null;
+ if (channel == "unix") {
+ unixPath = System.IO.Path.GetTempFileName ();
+ Hashtable props = new Hashtable ();
+ props ["path"] = unixPath;
+ props ["name"] = "__internal_unix";
+ ChannelServices.RegisterChannel (new UnixChannel (props, null, formatterSink), false);
+ } else {
+ Hashtable props = new Hashtable ();
+ props ["port"] = 0;
+ props ["name"] = "__internal_tcp";
+ ChannelServices.RegisterChannel (new TcpChannel (props, null, formatterSink), false);
+ }
+
+ // Read the reference to the application
+
+ string sref = Console.In.ReadLine ();
+ byte[] data = Convert.FromBase64String (sref);
+ MemoryStream ms = new MemoryStream (data);
+ BinaryFormatter bf = new BinaryFormatter ();
+
+ controller = (ApplicationBackendController) bf.Deserialize (ms);
+ ApplicationBackend backend = new ApplicationBackend (controller.Application);
+
+ controller.Connect (backend);
+
+ Gdk.Threads.Enter ();
+ Gtk.Application.Run ();
+ Gdk.Threads.Leave ();
+
+ controller.Disconnect (backend);
+ }
+
+ public virtual void Dispose ()
+ {
+ if (controller != null) {
+ Gtk.Application.Quit ();
+ }
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+
+ public AssemblyResolverCallback WidgetLibraryResolver {
+ get { return widgetLibraryResolver; }
+ set { widgetLibraryResolver = value; }
+ }
+
+ public MimeResolverDelegate MimeResolver {
+ set { ResourceInfo.MimeResolver = value; }
+ }
+
+ public Editor.ShowUrlDelegate ShowUrl {
+ set { Editor.NonContainerWarningDialog.ShowUrl = value; }
+ }
+
+ public bool ShowNonContainerWarning {
+ get { return Wrapper.Container.ShowNonContainerWarning; }
+ set { Wrapper.Container.ShowNonContainerWarning = value; }
+ }
+
+ public ProjectBackend LoadProject (string path)
+ {
+ ProjectBackend p = new ProjectBackend (this);
+
+ if (System.IO.Path.GetExtension (path) == ".glade") {
+ GladeFiles.Import (p, path);
+ } else {
+ p.Load (path);
+ }
+ return p;
+ }
+
+ public CodeGenerationResult GenerateProjectCode (GenerationOptions options, ProjectBackend[] projects)
+ {
+ return CodeGenerator.GenerateProjectCode (options, projects);
+ }
+
+ public ArrayList GlobalWidgetLibraries {
+ get { return globalWidgetLibraries; }
+ set { globalWidgetLibraries = value; }
+ }
+
+ public bool AllowInProcLibraries {
+ get { return allowInProcLibraries; }
+ set { allowInProcLibraries = value; }
+ }
+
+ public bool UpdateLibraries (ArrayList libraries, ArrayList projects, bool allowBackendRestart, bool forceUnload)
+ {
+ try {
+ Registry.BeginChangeSet ();
+
+ libraries.Add (Registry.CoreWidgetLibrary.Name);
+// libraries.Add (Registry.CoreWidgetLibrary2.Name);
+
+ // Notify libraries that need to be unloaded and loaded again
+ foreach (WidgetLibrary lib in Registry.RegisteredWidgetLibraries) {
+ if (lib.NeedsReload)
+ appFrontend.NotifyLibraryUnloaded (lib.Name);
+ }
+
+ if (!Registry.ReloadWidgetLibraries () && allowBackendRestart)
+ return false;
+
+ // Store a list of registered libraries, used later to know which
+ // ones need to be unloaded
+
+ ArrayList loaded = new ArrayList ();
+ foreach (WidgetLibrary alib in Registry.RegisteredWidgetLibraries)
+ loaded.Add (alib.Name);
+
+ // Load required libraries
+
+ Hashtable visited = new Hashtable ();
+ LoadLibraries (new AssemblyResolver (this), visited, libraries);
+
+ foreach (ProjectBackend project in projects)
+ LoadLibraries (project.Resolver, visited, project.WidgetLibraries);
+
+ // Unload libraries which are not required
+
+ foreach (string name in loaded) {
+ if (!visited.Contains (name)) {
+ if (forceUnload && allowBackendRestart)
+ return false;
+ appFrontend.NotifyLibraryUnloaded (name);
+ Registry.UnregisterWidgetLibrary (Registry.GetWidgetLibrary (name));
+ }
+ }
+
+ return true;
+ }
+ finally {
+ Registry.EndChangeSet ();
+ }
+ }
+
+ internal void LoadLibraries (AssemblyResolver resolver, IEnumerable libraries)
+ {
+ try {
+ Registry.BeginChangeSet ();
+ Hashtable visited = new Hashtable ();
+ LoadLibraries (resolver, visited, libraries);
+ } finally {
+ Registry.EndChangeSet ();
+ }
+ }
+
+ void LoadLibraries (AssemblyResolver resolver, Hashtable visited, IEnumerable libraries)
+ {
+ // Convert all assembly names to assembly paths before registering the libraries.
+ // The registry and the library cache will only handle full paths.
+ foreach (string s in libraries) {
+ string sr = resolver.Resolve (s, null);
+ if (sr != null)
+ AddLibrary (resolver, visited, sr);
+ }
+ Registry.ReloadWidgetLibraries ();
+ }
+
+ WidgetLibrary AddLibrary (AssemblyResolver resolver, Hashtable visited, string s)
+ {
+ if (Registry.IsRegistered (s)) {
+ WidgetLibrary lib = Registry.GetWidgetLibrary (s);
+ CheckDependencies (resolver, visited, lib);
+ return lib;
+ }
+
+ // Avoid registering direct references of libstetic
+ if (Path.GetFileName (s) == "libstetic.dll" && s != coreLibrary)
+ return null;
+
+ WidgetLibrary alib = CreateLibrary (resolver, s);
+ if (alib == null)
+ return null;
+
+ RegisterLibrary (resolver, visited, alib);
+ return alib;
+ }
+
+ void RegisterLibrary (AssemblyResolver resolver, Hashtable visited, WidgetLibrary lib)
+ {
+ if (lib == null || visited.Contains (lib.Name))
+ return;
+
+ visited [lib.Name] = lib;
+
+ foreach (string s in lib.GetLibraryDependencies ()) {
+ if (!Application.InternalIsWidgetLibrary (resolver, s))
+ continue;
+ AddLibrary (resolver, visited, s);
+ }
+
+ try {
+ Registry.RegisterWidgetLibrary (lib);
+ } catch (Exception ex) {
+ // Catch errors when loading a library to avoid aborting
+ // the whole update method. After all, that's not a fatal
+ // error (some widgets just won't be shown).
+ // FIXME: return the error somewhere
+ Console.WriteLine (ex);
+ }
+ }
+
+ WidgetLibrary CreateLibrary (AssemblyResolver resolver, string name)
+ {
+ try {
+ if (allowInProcLibraries)
+ return new AssemblyWidgetLibrary (resolver, name);
+ else
+ return new CecilWidgetLibrary (resolver, name);
+ } catch (Exception) {
+ // FIXME: handle the error, but keep loading.
+ return null;
+ }
+ }
+
+ void CheckDependencies (AssemblyResolver resolver, Hashtable visited, WidgetLibrary lib)
+ {
+ if (visited.Contains (lib.Name))
+ return;
+
+ visited [lib.Name] = lib;
+
+// foreach (string dep in lib.GetLibraryDependencies ()) {
+// WidgetLibrary depLib = Registry.GetWidgetLibrary (dep);
+// if (depLib == null)
+// AddLibrary (resolver, visited, dep);
+// else
+// CheckDependencies (resolver, visited, depLib);
+// }
+ }
+
+ public ProjectBackend ActiveProject {
+ get { return activeProject; }
+ set {
+ if (activeProject == value)
+ return;
+ activeProject = value;
+ if (paletteWidget != null) {
+ paletteWidget.ProjectBackend = activeProject;
+ paletteWidget.WidgetLibraries = GetActiveLibraries ();
+ }
+ if (propertiesWidget != null)
+ propertiesWidget.ProjectBackend = activeProject;
+ if (signalsWidget != null)
+ signalsWidget.ProjectBackend = activeProject;
+ }
+ }
+
+ public void SetActiveDesignSession (WidgetEditSession session)
+ {
+ activeDesignSession = session;
+ if (projectWidget != null)
+ projectWidget.Bind (session);
+ }
+
+ public WidgetLibrary[] GetActiveLibraries ()
+ {
+ return GetProjectLibraries (activeProject);
+ }
+
+ public WidgetLibrary[] GetProjectLibraries (ProjectBackend project)
+ {
+ ArrayList projectLibs = new ArrayList ();
+ if (project != null)
+ projectLibs.AddRange (project.WidgetLibraries);
+
+ ArrayList list = new ArrayList ();
+ list.Add (Registry.CoreWidgetLibrary);
+ foreach (WidgetLibrary alib in Registry.RegisteredWidgetLibraries) {
+ if (project != null && !alib.SupportsGtkVersion (project.TargetGtkVersion))
+ continue;
+ string aname = alib.Name;
+ if (projectLibs.Contains (aname) || globalWidgetLibraries.Contains (aname))
+ list.Add (alib);
+ }
+ return (WidgetLibrary[]) list.ToArray (typeof(WidgetLibrary));
+ }
+
+ public ProjectBackend CreateProject ()
+ {
+ return new ProjectBackend (this);
+ }
+
+ object IObjectViewer.TargetObject {
+ get { return targetViewerObject; }
+ set {
+ targetViewerObject = value;
+ if (propertiesWidget != null)
+ propertiesWidget.TargetObject = targetViewerObject;
+ if (signalsWidget != null)
+ signalsWidget.Editor.TargetObject = targetViewerObject;
+ }
+ }
+
+ public PaletteBackend GetPaletteWidget ()
+ {
+ if (paletteWidget == null) {
+ paletteWidget = new PaletteBackend (this);
+ paletteWidget.ProjectBackend = activeProject;
+ paletteWidget.WidgetLibraries = GetActiveLibraries ();
+ }
+ return paletteWidget;
+ }
+
+ public void CreatePaletteWidgetPlug (uint socketId)
+ {
+ Gtk.Plug plug = new Gtk.Plug (socketId);
+ plug.Decorated = false;
+// Gtk.Window plug = new Gtk.Window ("");
+ plug.Add (GetPaletteWidget ());
+ plug.Show ();
+ }
+
+ public void DestroyPaletteWidgetPlug ()
+ {
+ if (paletteWidget != null) {
+ Gtk.Plug plug = (Gtk.Plug)paletteWidget.Parent;
+ plug.Remove (paletteWidget);
+ plug.Destroy ();
+ }
+ }
+
+ public WidgetPropertyTreeBackend GetPropertiesWidget ()
+ {
+ if (propertiesWidget == null) {
+ propertiesWidget = new WidgetPropertyTreeBackend ();
+ propertiesWidget.ProjectBackend = activeProject;
+ propertiesWidget.TargetObject = targetViewerObject;
+ }
+ return propertiesWidget;
+ }
+
+ public void CreatePropertiesWidgetPlug (uint socketId)
+ {
+ Gtk.Plug plug = new Gtk.Plug (socketId);
+ plug.Decorated = false;
+// Gtk.Window plug = new Gtk.Window ("");
+ plug.Add (GetPropertiesWidget ());
+ plug.Show ();
+ }
+
+ public void DestroyPropertiesWidgetPlug ()
+ {
+ if (propertiesWidget != null) {
+ Gtk.Plug plug = (Gtk.Plug) propertiesWidget.Parent;
+ plug.Remove (propertiesWidget);
+ plug.Destroy ();
+ }
+ }
+
+ public SignalsEditorEditSession GetSignalsWidget (SignalsEditorFrontend frontend)
+ {
+ if (signalsWidget == null) {
+ signalsWidget = new SignalsEditorEditSession (frontend);
+ signalsWidget.ProjectBackend = activeProject;
+ signalsWidget.Editor.TargetObject = targetViewerObject;
+ }
+ return signalsWidget;
+ }
+
+ public SignalsEditorEditSession CreateSignalsWidgetPlug (SignalsEditorFrontend frontend, uint socketId)
+ {
+ Gtk.Plug plug = new Gtk.Plug (socketId);
+ plug.Decorated = false;
+// Gtk.Window plug = new Gtk.Window ("");
+ SignalsEditorEditSession session = GetSignalsWidget (frontend);
+ plug.Add (session.Editor);
+ plug.Show ();
+ return session;
+ }
+
+ public void DestroySignalsWidgetPlug ()
+ {
+ if (signalsWidget != null) {
+ Gtk.Plug plug = (Gtk.Plug) signalsWidget.Editor.Parent;
+ plug.Remove (signalsWidget.Editor);
+ plug.Destroy ();
+ }
+ }
+
+ public ProjectViewBackend GetProjectWidget (ProjectViewFrontend frontend)
+ {
+ if (projectWidget == null) {
+ projectWidget = new ProjectViewBackend (frontend);
+ projectWidget.Bind (activeDesignSession);
+ }
+ return projectWidget;
+ }
+
+ public void CreateProjectWidgetPlug (ProjectViewFrontend frontend, uint socketId)
+ {
+ Gtk.Plug plug = new Gtk.Plug (socketId);
+ plug.Decorated = false;
+// Gtk.Window plug = new Gtk.Window ("");
+ plug.Add (GetProjectWidget (frontend));
+ plug.Show ();
+ }
+
+ public void DestroyProjectWidgetPlug ()
+ {
+ if (projectWidget != null) {
+ Gtk.Plug plug = (Gtk.Plug)projectWidget.Parent;
+ plug.Remove (projectWidget);
+ plug.Destroy ();
+ }
+ }
+
+ public ArrayList GetComponentTypes ()
+ {
+ ArrayList list = new ArrayList ();
+ foreach (ClassDescriptor cd in Registry.AllClasses)
+ list.Add (cd.Name);
+ return list;
+ }
+
+ public bool GetClassDescriptorInfo (string name, out string desc, out string className, out string category, out string targetGtkVersion, out string library, out byte[] icon)
+ {
+ ClassDescriptor cls = Registry.LookupClassByName (name);
+ if (cls == null) {
+ icon = null;
+ desc = null;
+ className = null;
+ category = null;
+ targetGtkVersion = null;
+ library = null;
+ return false;
+ }
+ desc = cls.Label;
+ className = cls.WrappedTypeName;
+ category = cls.Category;
+ targetGtkVersion = cls.TargetGtkVersion;
+ library = cls.Library.Name;
+ icon = cls.Icon != null ? cls.Icon.SaveToBuffer ("png") : null;
+ return true;
+ }
+
+ public object[] GetClassDescriptorInitializationValues (string name)
+ {
+ ClassDescriptor cls = Registry.LookupClassByName (name);
+ ArrayList list = new ArrayList ();
+
+ foreach (Stetic.PropertyDescriptor prop in cls.InitializationProperties)
+ {
+ if (prop.PropertyType.IsValueType) {
+ // Avoid sending to the main process types which should not be loaded there
+ if (prop.PropertyType.Assembly == typeof(object).Assembly ||
+ prop.PropertyType.Assembly == typeof(Gtk.Widget).Assembly ||
+ prop.PropertyType.Assembly == typeof(Gdk.Window).Assembly ||
+ prop.PropertyType.Assembly == typeof(GLib.Object).Assembly) {
+
+ list.Add (Activator.CreateInstance (prop.PropertyType));
+ } else
+ return new object [0];
+ } else
+ list.Add (null);
+ }
+ return list.ToArray ();
+ }
+
+ public void ShowPaletteGroup (string name, string label)
+ {
+ GetPaletteWidget ().ShowGroup (name, label);
+ }
+
+ public void HidePaletteGroup (string name)
+ {
+ GetPaletteWidget ().HideGroup (name);
+ }
+
+ internal void GetClipboardOperations (object obj, out bool canCut, out bool canCopy, out bool canPaste)
+ {
+ Stetic.Wrapper.Widget wrapper = obj as Stetic.Wrapper.Widget;
+ if (wrapper != null) {
+ canCut = wrapper.InternalChildProperty == null && !wrapper.IsTopLevel;
+ canCopy = !wrapper.IsTopLevel;
+ canPaste = false;
+ }
+ else if (obj is Placeholder) {
+ // FIXME: make it work for placeholders
+ canCut = canCopy = false;
+ canPaste = true;
+ }
+ else {
+ canCut = canCopy = canPaste = false;
+ }
+ }
+
+ internal void GetComponentInfo (object obj, out string name, out string type)
+ {
+ Stetic.Wrapper.Widget wrapper = obj as Stetic.Wrapper.Widget;
+ name = wrapper.Wrapped.Name;
+ type = wrapper.ClassDescriptor.Name;
+ }
+
+ internal void RenameWidget (Wrapper.Widget w, string newName)
+ {
+ w.Wrapped.Name = newName;
+ }
+
+ internal byte[] GetActionIcon (Wrapper.Action ac)
+ {
+ Gdk.Pixbuf pix = ac.RenderIcon (Gtk.IconSize.Menu);
+ if (pix == null)
+ return null;
+ return pix.SaveToBuffer ("png");
+ }
+
+ internal ArrayList GetWidgetChildren (Wrapper.Widget ww)
+ {
+ Stetic.Wrapper.Container cw = ww as Stetic.Wrapper.Container;
+ if (cw == null)
+ return null;
+
+ ArrayList list = new ArrayList ();
+ foreach (object ob in cw.RealChildren) {
+ ObjectWrapper ow = ObjectWrapper.Lookup (ob);
+ if (ow != null)
+ list.Add (Component.GetSafeReference (ow));
+ }
+ return list;
+ }
+
+ internal void RemoveWidgetSignal (ObjectWrapper wrapper, Signal signal)
+ {
+ foreach (Signal s in wrapper.Signals) {
+ if (s.Handler == signal.Handler && s.SignalDescriptor.Name == signal.SignalDescriptor.Name) {
+ wrapper.Signals.Remove (s);
+ return;
+ }
+ }
+ }
+
+ internal Wrapper.ActionGroup[] GetActionGroups (Wrapper.Widget widget)
+ {
+ return widget.LocalActionGroups.ToArray ();
+ }
+
+ internal ObjectBindInfo[] GetBoundComponents (ObjectWrapper wrapper)
+ {
+ return CodeGenerator.GetFieldsToBind (wrapper).ToArray ();
+ }
+
+ internal ObjectWrapper GetPropertyTreeTarget ()
+ {
+ return targetViewerObject as ObjectWrapper;
+ }
+
+ internal void BeginComponentDrag (ProjectBackend project, string desc, string className, ObjectWrapper wrapper, Gtk.Widget source, Gdk.DragContext ctx, ComponentDropCallback callback)
+ {
+ if (wrapper != null) {
+ Stetic.Wrapper.ActionPaletteItem it = new Stetic.Wrapper.ActionPaletteItem (Gtk.UIManagerItemType.Menuitem, null, (Wrapper.Action) wrapper);
+ DND.Drag (source, ctx, it);
+ }
+ else if (callback != null) {
+ DND.Drag (source, ctx, delegate () {
+ callback ();
+
+ // If the class name has an assembly name, remove it now
+ int i = className.IndexOf (',');
+ if (i != -1)
+ className = className.Substring (0, i);
+
+ ClassDescriptor cls = Registry.LookupClassByName (className);
+ if (cls != null)
+ return cls.NewInstance (project) as Gtk.Widget;
+ else {
+ // Class not found, show an error
+ string msg = string.Format ("The widget '{0}' could not be found.", className);
+ Gtk.MessageDialog dlg = new Gtk.MessageDialog (null, Gtk.DialogFlags.Modal, Gtk.MessageType.Error, Gtk.ButtonsType.Close, msg);
+ dlg.Run ();
+ dlg.Destroy ();
+ return null;
+ }
+ },
+ (desc != null && desc.Length > 0) ? desc : className
+ );
+ }
+ else {
+ ClassDescriptor cls = Registry.LookupClassByName (className);
+ DND.Drag (source, ctx, cls.NewInstance (project) as Gtk.Widget);
+ }
+ }
+
+ public string ResolveAssembly (string assemblyName)
+ {
+ if (widgetLibraryResolver != null)
+ return widgetLibraryResolver (assemblyName);
+ else
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackendController.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackendController.cs
new file mode 100644
index 0000000000..5fdbbea4d5
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ApplicationBackendController.cs
@@ -0,0 +1,105 @@
+
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Threading;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Channels;
+using System.Runtime.Remoting.Channels.Tcp;
+
+namespace Stetic
+{
+ internal class ApplicationBackendController: MarshalByRefObject
+ {
+ bool stopping;
+ ApplicationBackend backend;
+ string channelId;
+ IsolatedApplication app;
+
+ ManualResetEvent runningEvent = new ManualResetEvent (false);
+
+ public event EventHandler Stopped;
+
+ public ApplicationBackendController (IsolatedApplication app, string channelId)
+ {
+ this.app = app;
+ this.channelId = channelId;
+ }
+
+ public ApplicationBackend Backend {
+ get { return backend; }
+ }
+
+ public Application Application {
+ get { return app; }
+ }
+
+ public void StartBackend ()
+ {
+ runningEvent.Reset ();
+
+ string asm = GetType().Assembly.Location;
+
+ BinaryFormatter bf = new BinaryFormatter ();
+ ObjRef oref = RemotingServices.Marshal (this);
+ MemoryStream ms = new MemoryStream ();
+ bf.Serialize (ms, oref);
+ string sref = Convert.ToBase64String (ms.ToArray ());
+
+ Process process = new Process ();
+ process.StartInfo = new ProcessStartInfo ("sh", "-c \"mono --debug " + asm + "\"");
+ process.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
+ process.StartInfo.UseShellExecute = false;
+ process.StartInfo.RedirectStandardInput = true;
+ process.EnableRaisingEvents = true;
+ process.Start ();
+ process.StandardInput.WriteLine (channelId);
+ process.StandardInput.WriteLine (sref);
+ process.StandardInput.Flush ();
+ process.Exited += OnExited;
+
+ if (!runningEvent.WaitOne (10000, false))
+ throw new ApplicationException ("Couldn't create a remote process.");
+ }
+
+ public void StopBackend (bool waitUntilDone)
+ {
+ stopping = true;
+ runningEvent.Reset ();
+ backend.Dispose ();
+ if (waitUntilDone)
+ runningEvent.WaitOne (9000, false);
+ }
+
+ void OnExited (object o, EventArgs args)
+ {
+ Gtk.Application.Invoke (OnExitedInGui);
+ }
+
+ void OnExitedInGui (object o, EventArgs args)
+ {
+ if (!stopping && Stopped != null)
+ Stopped (this, EventArgs.Empty);
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ internal void Connect (ApplicationBackend backend)
+ {
+ this.backend = backend;
+ runningEvent.Set ();
+ }
+
+ internal void Disconnect (ApplicationBackend backend)
+ {
+ this.backend = null;
+ runningEvent.Set ();
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyResolver.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyResolver.cs
new file mode 100644
index 0000000000..afc8cd6dc6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyResolver.cs
@@ -0,0 +1,242 @@
+//
+// BaseAssemblyResolver.cs
+//
+// Author:
+// Jb Evain (jbevain@gmail.com)
+//
+// (C) 2007 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+// This code is a modified version of the assembly resolver implemented in Cecil.
+// Keep in synch as much as possible.
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Text;
+using Mono.Cecil;
+
+namespace Stetic {
+
+ internal class AssemblyResolver : BaseAssemblyResolver {
+
+ Hashtable _assemblies;
+ ApplicationBackend app;
+
+ public IDictionary AssemblyCache {
+ get { return _assemblies; }
+ }
+
+ public AssemblyResolver (ApplicationBackend app)
+ {
+ this.app = app;
+ _assemblies = new Hashtable ();
+ }
+
+ public StringCollection Directories = new StringCollection ();
+
+ public override AssemblyDefinition Resolve (AssemblyNameReference name)
+ {
+ return Resolve (name, (string)null);
+ }
+
+ public AssemblyDefinition Resolve (AssemblyNameReference name, string basePath)
+ {
+ AssemblyDefinition asm = (AssemblyDefinition) _assemblies [name.FullName];
+ if (asm == null) {
+ if (app != null) {
+ string ares = app.ResolveAssembly (name.Name);
+ if (ares != null) {
+ asm = AssemblyFactory.GetAssembly (ares);
+ asm.Resolver = this;
+ _assemblies [name.FullName] = asm;
+ return asm;
+ }
+ }
+ string file = Resolve (name.FullName, basePath);
+ if (file != null)
+ asm = AssemblyFactory.GetAssembly (file);
+ else
+ asm = base.Resolve (name);
+ asm.Resolver = this;
+ _assemblies [name.FullName] = asm;
+ }
+
+ return asm;
+ }
+
+ public void ClearCache ()
+ {
+ _assemblies.Clear ();
+ }
+
+ public TypeDefinition Resolve (TypeReference type)
+ {
+ if (type is TypeDefinition)
+ return (TypeDefinition) type;
+
+ AssemblyNameReference reference = type.Scope as AssemblyNameReference;
+ if (reference != null) {
+ AssemblyDefinition assembly = Resolve (reference);
+ return assembly.MainModule.Types [type.FullName];
+ }
+
+ ModuleDefinition module = type.Scope as ModuleDefinition;
+ if (module != null)
+ return module.Types [type.FullName];
+
+ throw new NotImplementedException ();
+ }
+
+ public void CacheAssembly (AssemblyDefinition assembly)
+ {
+ _assemblies [assembly.Name.FullName] = assembly;
+ assembly.Resolver = this;
+ }
+
+ public string Resolve (string assemblyName, string basePath)
+ {
+ if (Path.IsPathRooted (assemblyName) && (assemblyName.EndsWith (".dll") || assemblyName.EndsWith (".exe")))
+ return Path.GetFullPath (assemblyName);
+
+ if (app != null) {
+ string ares = app.ResolveAssembly (assemblyName);
+ if (ares != null)
+ return Path.GetFullPath (ares);
+ }
+
+ StringCollection col = new StringCollection ();
+ col.Add (basePath);
+ foreach (string s in Directories)
+ col.Add (s);
+
+ try {
+ return Resolve (AssemblyNameReference.Parse (assemblyName), col);
+ } catch {
+ }
+ return null;
+ }
+
+ public string Resolve (AssemblyNameReference name, StringCollection basePaths)
+ {
+ string [] exts = new string [] { ".dll", ".exe" };
+
+ if (basePaths != null) {
+ foreach (string dir in basePaths) {
+ foreach (string ext in exts) {
+ string file = Path.Combine (dir, name.Name + ext);
+ if (File.Exists (file))
+ return file;
+ }
+ }
+ }
+
+ if (name.Name == "mscorlib")
+ return GetCorlib (name);
+
+ string asm = GetAssemblyInGac (name);
+ if (asm != null)
+ return Path.GetFullPath (asm);
+
+ throw new FileNotFoundException ("Could not resolve: " + name);
+ }
+
+ string GetCorlib (AssemblyNameReference reference)
+ {
+ if (typeof (object).Assembly.GetName ().Version == reference.Version)
+ return typeof (object).Assembly.Location;
+
+ string path = Directory.GetParent (
+ Directory.GetParent (
+ typeof (object).Module.FullyQualifiedName).FullName
+ ).FullName;
+
+ if (OnMono ()) {
+ if (reference.Version.Major == 1)
+ path = Path.Combine (path, "1.0");
+ else if (reference.Version.Major == 2)
+ path = Path.Combine (path, "2.0");
+ else
+ throw new NotSupportedException ("Version not supported: " + reference.Version);
+ } else {
+ if (reference.Version.ToString () == "1.0.3300.0")
+ path = Path.Combine (path, "v1.0.3705");
+ else if (reference.Version.ToString () == "1.0.5000.0")
+ path = Path.Combine (path, "v1.1.4322");
+ else if (reference.Version.ToString () == "2.0.0.0")
+ path = Path.Combine (path, "v2.0.50727");
+ else
+ throw new NotSupportedException ("Version not supported: " + reference.Version);
+ }
+
+ return Path.GetFullPath (Path.Combine (path, "mscorlib.dll"));
+ }
+
+ static string GetAssemblyInGac (AssemblyNameReference reference)
+ {
+ if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
+ return null;
+
+ string currentGac = GetCurrentGacPath ();
+ if (OnMono ()) {
+ string s = GetAssemblyFile (reference, currentGac);
+ if (File.Exists (s))
+ return s;
+ } else {
+ string [] gacs = new string [] {"GAC_MSIL", "GAC_32", "GAC"};
+ for (int i = 0; i < gacs.Length; i++) {
+ string gac = Path.Combine (Directory.GetParent (currentGac).FullName, gacs [i]);
+ string asm = GetAssemblyFile (reference, gac);
+ if (Directory.Exists (gac) && File.Exists (asm))
+ return asm;
+ }
+ }
+
+ return null;
+ }
+
+ static string GetAssemblyFile (AssemblyNameReference reference, string gac)
+ {
+ StringBuilder sb = new StringBuilder ();
+ sb.Append (reference.Version);
+ sb.Append ("__");
+ for (int i = 0; i < reference.PublicKeyToken.Length; i++)
+ sb.Append (reference.PublicKeyToken [i].ToString ("x2"));
+
+ return Path.Combine (
+ Path.Combine (
+ Path.Combine (gac, reference.Name), sb.ToString ()),
+ string.Concat (reference.Name, ".dll"));
+ }
+
+ static string GetCurrentGacPath ()
+ {
+ return Directory.GetParent (
+ Directory.GetParent (
+ Path.GetDirectoryName (
+ typeof (Uri).Module.FullyQualifiedName)
+ ).FullName
+ ).FullName;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyWidgetLibrary.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyWidgetLibrary.cs
new file mode 100644
index 0000000000..f57e43768e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/AssemblyWidgetLibrary.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+using System.IO;
+
+namespace Stetic
+{
+ internal class AssemblyWidgetLibrary: WidgetLibrary
+ {
+ static LibraryCache Cache = LibraryCache.Cache;
+
+ Assembly assembly;
+ string name;
+ AssemblyResolver resolver;
+ LibraryCache.LibraryInfo cache_info;
+
+ public AssemblyWidgetLibrary (string name, Assembly assembly)
+ {
+ this.name = name;
+ this.assembly = assembly;
+ UpdateCache ();
+ }
+
+ public AssemblyWidgetLibrary (AssemblyResolver resolver, string assemblyPath)
+ {
+ this.name = assemblyPath;
+
+ string ares = resolver.Resolve (assemblyPath, null);
+ if (ares != null)
+ assemblyPath = ares;
+
+ this.resolver = resolver;
+ if (assemblyPath.EndsWith (".dll") || assemblyPath.EndsWith (".exe")) {
+ if (File.Exists (assemblyPath))
+ assembly = Assembly.LoadFrom (assemblyPath);
+ } else
+ assembly = Assembly.Load (assemblyPath);
+
+ if (assembly == null)
+ throw new InvalidOperationException ("Couldn't load assembly at " + assemblyPath);
+
+ UpdateCache ();
+ }
+
+ void UpdateCache ()
+ {
+ Cache.Refresh (resolver, assembly.Location);
+ cache_info = Cache [assembly.Location];
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public override bool NeedsReload {
+ get {
+ return File.Exists (assembly.Location) && !Cache.IsCurrent (assembly.Location);
+ }
+ }
+
+ public override bool CanReload {
+ get { return false; }
+ }
+
+ public override void Load ()
+ {
+ Load (cache_info.ObjectsDocument);
+ }
+
+ protected override ClassDescriptor LoadClassDescriptor (XmlElement element)
+ {
+ return new TypedClassDescriptor (assembly, element);
+ }
+
+ public override Type GetType (string typeName)
+ {
+ Type t = assembly.GetType (typeName, false);
+ if (t != null) return t;
+
+ // Look in referenced assemblies
+/*
+ Disabled. The problem is that Assembly.Load tries to load the exact version
+ of the assembly, and loaded references may not have the same exact version.
+
+ foreach (AssemblyName an in assembly.GetReferencedAssemblies ()) {
+ Assembly a = Assembly.Load (an);
+ t = a.GetType (typeName);
+ if (t != null) return t;
+ }
+*/
+ return null;
+ }
+
+ public override System.IO.Stream GetResource (string name)
+ {
+ return assembly.GetManifestResourceStream (name);
+ }
+
+ public override string[] GetLibraryDependencies ()
+ {
+ if (!cache_info.HasWidgets)
+ return new string [0];
+
+ ArrayList list = new ArrayList ();
+ ScanLibraries (list, assembly);
+ return (string[]) list.ToArray (typeof(string));
+ }
+
+ void ScanLibraries (ArrayList list, Assembly asm)
+ {
+ foreach (AssemblyName aname in asm.GetReferencedAssemblies ()) {
+ Assembly depasm = null;
+ try {
+ depasm = Assembly.Load (aname);
+ } catch {
+ }
+
+ if (depasm == null) {
+ string file = resolver.Resolve (aname.FullName, Path.GetDirectoryName (asm.Location));
+ if (file != null)
+ depasm = Assembly.LoadFrom (file);
+ else
+ throw new InvalidOperationException ("Assembly not found: " + aname.FullName);
+ }
+
+ ManifestResourceInfo res = depasm.GetManifestResourceInfo ("objects.xml");
+ if (res != null)
+ list.Add (depasm.Location);
+ }
+ }
+
+ public override void Flush ()
+ {
+ base.Flush ();
+ if (resolver != null)
+ resolver.ClearCache ();
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilClassDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilClassDescriptor.cs
new file mode 100644
index 0000000000..08a3d8cc04
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilClassDescriptor.cs
@@ -0,0 +1,382 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using System.Reflection;
+using Mono.Cecil;
+
+namespace Stetic
+{
+ internal class CecilClassDescriptor: Stetic.ClassDescriptor
+ {
+ string wrappedTypeName;
+ ClassDescriptor typeClassDescriptor;
+ ClassDescriptor wrapperClassDescriptor;
+ Gdk.Pixbuf icon;
+ TypeDefinition type;
+ XmlElement steticDefinition;
+ CecilWidgetLibrary cecilLib;
+ bool useCustomWidgetBox;
+ string widgetId;
+ bool canGenerateCode;
+
+ public CecilClassDescriptor (CecilWidgetLibrary lib, XmlElement element, ClassDescriptor typeClassDescriptor, XmlElement steticDefinition, TypeDefinition cls)
+ {
+ this.cecilLib = lib;
+ this.steticDefinition = steticDefinition;
+ this.typeClassDescriptor = typeClassDescriptor;
+ wrappedTypeName = element.GetAttribute ("type");
+ type = cls;
+ Load (element);
+ type = null;
+ canGenerateCode = true;
+
+ string baseType = element.GetAttribute ("base-type");
+ if (baseType.Length > 0) {
+ wrapperClassDescriptor = Registry.LookupClassByName (baseType);
+ if (wrapperClassDescriptor == null)
+ throw new InvalidOperationException ("Unknown base type: " + baseType);
+ } else {
+ wrapperClassDescriptor = typeClassDescriptor;
+ }
+
+ if (steticDefinition == null && !AllowChildren && NeedsBlackBox (typeClassDescriptor.Name)) {
+ // It is not possible to create instances of that widget, instead we'll have
+ // to create the typical custom widget black box.
+
+ if (!CanCreateWidgetInstance (wrapperClassDescriptor.Name))
+ throw new InvalidOperationException ("Can't load widget type '" + Name + "'. Instances of that type can't be created because the type can't be loaded into the process.");
+
+ useCustomWidgetBox = true;
+ }
+
+ widgetId = Name.ToLower ();
+ int i = widgetId.LastIndexOf ('.');
+ if (i != -1) {
+ if (i != widgetId.Length - 1)
+ widgetId = widgetId.Substring (i+1);
+ else
+ widgetId = widgetId.Replace (".", "");
+ }
+
+ string iconName = element.GetAttribute ("icon");
+ icon = lib.GetEmbeddedIcon (iconName);
+
+ // If the class is a custom widget created using stetic, it means that it has
+ // simple property and there is no custom logic, so it is safe to generate code
+ // for this class.
+ if (steticDefinition != null)
+ canGenerateCode = true;
+
+ // If it has a custom wrapper, then it definitely has custom logic, so it can't generate code
+ if (element.HasAttribute ("wrapper"))
+ canGenerateCode = false;
+ }
+
+ public override string WrappedTypeName {
+ get { return wrappedTypeName; }
+ }
+
+ public override Gdk.Pixbuf Icon {
+ get { return icon; }
+ }
+
+ public bool CanGenerateCode {
+ get { return canGenerateCode; }
+ }
+
+ public override object CreateInstance (Stetic.IProject proj)
+ {
+ Gtk.Widget res;
+
+ if (useCustomWidgetBox) {
+ res = CreateFakeWidget (wrapperClassDescriptor.Name);
+ res.ShowAll ();
+ }
+ else if (steticDefinition != null) {
+ Gtk.Container w = Stetic.WidgetUtils.ImportWidget (proj, steticDefinition) as Gtk.Container;
+ MakeChildrenUnselectable (w);
+ res = w;
+ }
+ else {
+ res = (Gtk.Widget) typeClassDescriptor.CreateInstance (proj);
+
+ // If it is a custom widget and there is no stetic project for it, just
+ // show it as a regular custom widget.
+ Stetic.CustomWidget custom = res as Stetic.CustomWidget;
+ if (custom != null) {
+ Stetic.Custom c = new Stetic.Custom ();
+ // Give it some default size
+ c.WidthRequest = 20;
+ c.HeightRequest = 20;
+ custom.Add (c);
+ custom.ShowAll ();
+ res = custom;
+ }
+ }
+
+ res.Name = widgetId;
+ return res;
+ }
+
+ public override Stetic.ObjectWrapper CreateWrapper ()
+ {
+ return wrapperClassDescriptor.CreateWrapper ();
+ }
+
+ protected override Stetic.ItemDescriptor CreateItemDescriptor (XmlElement elem, Stetic.ItemGroup group)
+ {
+ string mname = elem.GetAttribute ("name");
+ if (elem.Name == "property") {
+ if (type != null) {
+ PropertyDefinition propInfo = FindProperty (type, mname);
+ if (propInfo != null)
+ return new CecilPropertyDescriptor (cecilLib, elem, group, this, propInfo);
+ }
+ else
+ return new CecilPropertyDescriptor (cecilLib, elem, group, this, null);
+ }
+ else if (elem.Name == "signal") {
+ if (type != null) {
+ EventDefinition signalInfo = FindEvent (type, mname);
+ if (signalInfo != null)
+ return new CecilSignalDescriptor (cecilLib, elem, group, this, signalInfo);
+ }
+ else
+ return new CecilSignalDescriptor (cecilLib, elem, group, this, null);
+ }
+ else
+ return base.CreateItemDescriptor (elem, group);
+
+ return null;
+ }
+
+ PropertyDefinition FindProperty (TypeDefinition cls, string name)
+ {
+ foreach (PropertyDefinition propInfo in cls.Properties)
+ if (propInfo.Name == name)
+ return propInfo;
+
+ if (cls.BaseType == null)
+ return null;
+
+ string baseType = cls.BaseType.FullName;
+ Type t = Registry.GetType (baseType, false);
+ if (t != null) {
+ PropertyInfo prop = t.GetProperty (name);
+ if (prop != null) {
+ TypeReference tref = new TypeReference (prop.PropertyType.Name, prop.PropertyType.Namespace, null, prop.PropertyType.IsValueType);
+ PropertyDefinition pdef = new PropertyDefinition (name, tref, (Mono.Cecil.PropertyAttributes) 0);
+ PropertyDefinition.CreateGetMethod (pdef);
+ PropertyDefinition.CreateSetMethod (pdef);
+ return pdef;
+ }
+ }
+
+ TypeDefinition bcls = cecilLib.FindTypeDefinition (baseType);
+ if (bcls != null)
+ return FindProperty (bcls, name);
+ else
+ return null;
+ }
+
+ EventDefinition FindEvent (TypeDefinition cls, string name)
+ {
+ foreach (EventDefinition eventInfo in cls.Events)
+ if (eventInfo.Name == name)
+ return eventInfo;
+
+ if (cls.BaseType == null)
+ return null;
+
+ string baseType = cls.BaseType.FullName;
+ Type t = Registry.GetType (baseType, false);
+ if (t != null) {
+ EventInfo ev = t.GetEvent (name);
+ if (ev != null) {
+ TypeReference tref = new TypeReference (ev.EventHandlerType.Name, ev.EventHandlerType.Namespace, null, ev.EventHandlerType.IsValueType);
+ return new EventDefinition (name, tref, (Mono.Cecil.EventAttributes) 0);
+ }
+ }
+
+ TypeDefinition bcls = cecilLib.FindTypeDefinition (baseType);
+ if (bcls != null)
+ return FindEvent (bcls, name);
+ else
+ return null;
+ }
+
+ void MakeChildrenUnselectable (Gtk.Widget w)
+ {
+ // Remove the registered signals, since those signals are bound
+ // to the custom widget class, not the widget container class.
+ Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (w);
+ if (ww == null)
+ return;
+ ww.Signals.Clear ();
+
+ foreach (Gtk.Widget child in (Gtk.Container)w) {
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (child);
+ if (wrapper != null) {
+ wrapper.Signals.Clear ();
+ wrapper.Unselectable = true;
+ }
+ if (child is Gtk.Container)
+ MakeChildrenUnselectable (child);
+ }
+ }
+
+ bool CanCreateWidgetInstance (string typeName)
+ {
+ switch (typeName) {
+ case "Gtk.Fixed":
+ return false;
+ }
+ return true;
+ }
+
+ bool NeedsBlackBox (string typeName)
+ {
+ switch (typeName) {
+ case "Gtk.Widget":
+ case "Gtk.Container":
+ case "Gtk.Alignment":
+ case "Gtk.Fixed":
+ case "Gtk.Frame":
+ case "Gtk.HBox":
+ case "Gtk.VBox":
+ case "Gtk.Box":
+ case "Gtk.ButtonBox":
+ case "Gtk.Paned":
+ case "Gtk.VPaned":
+ case "Gtk.HPaned":
+ case "Gtk.Notebook":
+ case "Gtk.ScrolledWindow":
+ case "Gtk.Table":
+ case "Gtk.Bin":
+ return true;
+ }
+ return false;
+ }
+
+ Gtk.Widget CreateFakeWidget (string typeName)
+ {
+ Stetic.Custom c = new Stetic.Custom ();
+ // Give it some default size
+ c.WidthRequest = 20;
+ c.HeightRequest = 20;
+
+ Gtk.Container box = null;
+
+ switch (typeClassDescriptor.Name) {
+ case "Gtk.Alignment":
+ box = new Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+ break;
+ case "Gtk.Fixed":
+ box = new Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+ break;
+ case "Gtk.Frame":
+ box = new Gtk.Frame ();
+ break;
+ case "Gtk.Box":
+ case "Gtk.HBox": {
+ Gtk.HBox cc = new Gtk.HBox ();
+ cc.PackStart (c, true, true, 0);
+ return cc;
+ }
+ case "Gtk.VBox": {
+ Gtk.VBox cc = new Gtk.VBox ();
+ cc.PackStart (c, true, true, 0);
+ return cc;
+ }
+ case "Gtk.Paned":
+ case "Gtk.VPaned": {
+ Gtk.VPaned cc = new Gtk.VPaned ();
+ cc.Add1 (c);
+ return cc;
+ }
+ case "Gtk.HPaned": {
+ Gtk.HPaned cc = new Gtk.HPaned ();
+ cc.Add1 (c);
+ return cc;
+ }
+ case "Gtk.Notebook": {
+ Gtk.Notebook nb = new Gtk.Notebook ();
+ nb.ShowTabs = false;
+ nb.AppendPage (c, null);
+ return nb;
+ }
+ case "Gtk.ScrolledWindow": {
+ Gtk.ScrolledWindow cc = new Gtk.ScrolledWindow ();
+ cc.VscrollbarPolicy = Gtk.PolicyType.Never;
+ cc.HscrollbarPolicy = Gtk.PolicyType.Never;
+ cc.AddWithViewport (c);
+ return cc;
+ }
+ case "Gtk.Table": {
+ Gtk.Table t = new Gtk.Table (1, 1, false);
+ t.Attach (c, 0, 1, 0, 1);
+ return t;
+ }
+ case "Gtk.ButtonBox":
+ return new Gtk.HButtonBox ();
+ }
+ if (box != null) {
+ box.Add (c);
+ return box;
+ } else {
+ Stetic.CustomWidget custom = new Stetic.CustomWidget ();
+ if (custom.Child != null)
+ custom.Remove (custom.Child);
+ custom.Add (c);
+ return custom;
+ }
+ }
+ }
+
+ class CustomControlWrapper: Stetic.Wrapper.Container
+ {
+ protected override bool AllowPlaceholders {
+ get {
+ return false;
+ }
+ }
+ }
+
+ class ClassDescriptorWrapper: Stetic.ClassDescriptor
+ {
+ ClassDescriptor wrapped;
+
+ public ClassDescriptorWrapper (ClassDescriptor wrapped)
+ {
+ this.wrapped = wrapped;
+ label = wrapped.Label;
+
+ }
+
+ public override string WrappedTypeName {
+ get { return wrapped.WrappedTypeName; }
+ }
+
+ public override Gdk.Pixbuf Icon {
+ get { return wrapped.Icon; }
+ }
+
+ public override object CreateInstance (Stetic.IProject proj)
+ {
+ CustomWidget custom = new CustomWidget ();
+ Stetic.Custom c = new Stetic.Custom ();
+ // Give it some default size
+ c.WidthRequest = 20;
+ c.HeightRequest = 20;
+ custom.Add (c);
+ return c;
+ }
+
+ public override Stetic.ObjectWrapper CreateWrapper ()
+ {
+ return new Wrapper.Container ();
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilPropertyDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilPropertyDescriptor.cs
new file mode 100644
index 0000000000..292a99b740
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilPropertyDescriptor.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections;
+using System.Xml;
+using Mono.Cecil;
+
+namespace Stetic
+{
+ class CecilPropertyDescriptor: Stetic.PropertyDescriptor
+ {
+ string name;
+ Type type;
+ object initialValue;
+ bool canWrite;
+
+ public CecilPropertyDescriptor (CecilWidgetLibrary lib, XmlElement elem, Stetic.ItemGroup group, Stetic.ClassDescriptor klass, PropertyDefinition pinfo): base (elem, group, klass)
+ {
+ string tname;
+
+ if (pinfo != null) {
+ name = pinfo.Name;
+ tname = pinfo.PropertyType.FullName;
+ canWrite = pinfo.SetMethod != null;
+ }
+ else {
+ name = elem.GetAttribute ("name");
+ tname = elem.GetAttribute ("type");
+ canWrite = elem.Attributes ["canWrite"] == null;
+ }
+
+ Load (elem);
+
+ type = Stetic.Registry.GetType (tname, false);
+
+ if (type == null) {
+ Console.WriteLine ("Could not find type: " + tname);
+ type = typeof(string);
+ }
+ if (type.IsValueType)
+ initialValue = Activator.CreateInstance (type);
+
+ // Consider all properties runtime-properties, since they have been created
+ // from class properties.
+ isRuntimeProperty = true;
+
+ if (pinfo != null)
+ SaveCecilXml (elem);
+ }
+
+ public CecilPropertyDescriptor (XmlElement elem, Stetic.ItemGroup group, Stetic.ClassDescriptor klass, PropertyDescriptor prop): base (elem, group, klass)
+ {
+ this.name = prop.Name;
+ this.type = prop.PropertyType;
+ this.canWrite = prop.CanWrite;
+ if (type.IsValueType)
+ initialValue = Activator.CreateInstance (type);
+ this.label = prop.Label;
+ this.description = prop.Description;
+ this.maximum = prop.Maximum;
+ this.minimum = prop.Minimum;
+ this.initWithName = prop.InitWithName;
+ this.translatable = prop.Translatable;
+ }
+
+ internal void SaveCecilXml (XmlElement elem)
+ {
+ elem.SetAttribute ("name", name);
+ elem.SetAttribute ("type", type.FullName);
+ if (!canWrite)
+ elem.SetAttribute ("canWrite", "false");
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ // The property's type
+ public override Type PropertyType {
+ get { return type; }
+ }
+
+ public override bool IsDefaultValue (object value)
+ {
+ return false;
+ }
+
+ // Gets the value of the property on @obj
+ public override object GetValue (object obj)
+ {
+ Stetic.ObjectWrapper wrapper = (Stetic.ObjectWrapper) Stetic.ObjectWrapper.Lookup (obj);
+ Hashtable props = (Hashtable) wrapper.ExtendedData [typeof(CecilPropertyDescriptor)];
+ object val = props != null ? props [name] : null;
+ if (val == null && initialValue != null)
+ return initialValue;
+ else
+ return val;
+ }
+
+ // Whether or not the property is writable
+ public override bool CanWrite {
+ get { return canWrite; }
+ }
+
+ // Sets the value of the property on @obj
+ public override void SetValue (object obj, object value)
+ {
+ Stetic.ObjectWrapper wrapper = (Stetic.ObjectWrapper) Stetic.ObjectWrapper.Lookup (obj);
+ Hashtable props = (Hashtable) wrapper.ExtendedData [typeof(CecilPropertyDescriptor)];
+ if (props == null) {
+ props = new Hashtable ();
+ wrapper.ExtendedData [typeof(CecilPropertyDescriptor)] = props;
+ }
+
+ props [name] = value;
+ }
+
+ public override object GetRuntimeValue (object obj)
+ {
+ return null;
+ }
+
+ public override void SetRuntimeValue (object obj, object value)
+ {
+ }
+
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilSignalDescriptor.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilSignalDescriptor.cs
new file mode 100644
index 0000000000..defc98e4b3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilSignalDescriptor.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections;
+using System.Xml;
+using System.Reflection;
+using Mono.Cecil;
+
+namespace Stetic
+{
+ class CecilSignalDescriptor: Stetic.SignalDescriptor
+ {
+ public CecilSignalDescriptor (CecilWidgetLibrary lib, XmlElement elem, Stetic.ItemGroup group, Stetic.ClassDescriptor klass, EventDefinition sinfo) : base (elem, group, klass)
+ {
+ if (sinfo != null) {
+ string handler = sinfo.EventType.FullName;
+ handlerTypeName = handler.Replace ('/','+');
+ Type t = Registry.GetType (handler, false);
+ if (t != null) {
+ MethodInfo mi = t.GetMethod ("Invoke");
+ handlerReturnTypeName = mi.ReturnType.FullName;
+ ParameterInfo[] pars = mi.GetParameters ();
+ handlerParameters = new ParameterDescriptor [pars.Length];
+ for (int n=0; n<pars.Length; n++)
+ handlerParameters [n] = new ParameterDescriptor (pars[n].Name, pars[n].ParameterType.FullName);
+ } else {
+ // If the type is generic, the type arguments must be ignored when looking for the type
+ string tn = handler;
+ int i = handler.IndexOf ('<');
+ if (i != -1) {
+ tn = handler.Substring (0, i);
+ // Convert the type name to a type reference
+ handler = handler.Replace ('<', '[');
+ handler = handler.Replace ('>', ']');
+ }
+ TypeDefinition td = lib.FindTypeDefinition (tn);
+ if (td != null) {
+ MethodDefinition mi = null;
+ foreach (MethodDefinition md in td.Methods) {
+ if (md.Name == "Invoke") {
+ mi = md;
+ break;
+ }
+ }
+ if (mi != null) {
+ handlerReturnTypeName = CecilWidgetLibrary.GetInstanceType (td, sinfo.EventType, mi.ReturnType.ReturnType);
+ handlerParameters = new ParameterDescriptor [mi.Parameters.Count];
+ for (int n=0; n<handlerParameters.Length; n++) {
+ ParameterDefinition par = mi.Parameters [n];
+ handlerParameters [n] = new ParameterDescriptor (par.Name, CecilWidgetLibrary.GetInstanceType (td, sinfo.EventType, par.ParameterType));
+ }
+ }
+ } else {
+ handlerParameters = new ParameterDescriptor [0];
+ }
+ }
+ SaveCecilXml (elem);
+ }
+ else {
+ handlerTypeName = elem.GetAttribute ("handlerTypeName");
+ handlerReturnTypeName = elem.GetAttribute ("handlerReturnTypeName");
+
+ ArrayList list = new ArrayList ();
+ foreach (XmlNode npar in elem.ChildNodes) {
+ XmlElement epar = npar as XmlElement;
+ if (epar == null) continue;
+ list.Add (new ParameterDescriptor (epar.GetAttribute ("name"), epar.GetAttribute ("type")));
+ }
+
+ handlerParameters = (ParameterDescriptor[]) list.ToArray (typeof(ParameterDescriptor));
+ }
+
+ Load (elem);
+ }
+
+ internal void SaveCecilXml (XmlElement elem)
+ {
+ elem.SetAttribute ("handlerTypeName", handlerTypeName);
+ elem.SetAttribute ("handlerReturnTypeName", handlerReturnTypeName);
+ if (handlerParameters != null) {
+ foreach (ParameterDescriptor par in handlerParameters) {
+ XmlElement epar = elem.OwnerDocument.CreateElement ("param");
+ epar.SetAttribute ("name", par.Name);
+ epar.SetAttribute ("type", par.TypeName);
+ elem.AppendChild (epar);
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilWidgetLibrary.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilWidgetLibrary.cs
new file mode 100644
index 0000000000..0352d31fc5
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CecilWidgetLibrary.cs
@@ -0,0 +1,368 @@
+// CecilWidgetLibrary.cs
+//
+// Authors:
+// Lluis Sanchez Gual <lluis@novell.com>
+// Mike Kestner <mkestner@novell.com>
+//
+// Copyright (c) 2008 Novell, Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Xml;
+using Mono.Cecil;
+
+namespace Stetic
+{
+ internal class CecilWidgetLibrary: WidgetLibrary
+ {
+ static LibraryCache cache = LibraryCache.Cache;
+
+ string name;
+ string filename;
+ string[] dependencies;
+ AssemblyResolver resolver;
+ bool canGenerateCode;
+ bool info_changed;
+ bool objects_dirty;
+ AssemblyDefinition assembly;
+ LibraryCache.LibraryInfo cache_info;
+
+ public CecilWidgetLibrary (AssemblyResolver resolver, string path)
+ {
+ name = path;
+ this.resolver = resolver;
+
+ if (System.IO.File.Exists (path))
+ filename = path;
+ else if (resolver != null)
+ filename = resolver.Resolve (path, null);
+
+ if (filename == null)
+ filename = path;
+ else
+ filename = System.IO.Path.GetFullPath (filename);
+
+ RefreshFromCache ();
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public override bool NeedsReload {
+ get {
+ cache.Refresh (resolver, filename);
+ return info_changed;
+ }
+ }
+
+ public override bool CanReload {
+ get { return true; }
+ }
+
+ public override bool CanGenerateCode {
+ get { return canGenerateCode; }
+ }
+
+ public override void Load ()
+ {
+ canGenerateCode = true;
+
+ RefreshFromCache ();
+ if (cache_info == null || !File.Exists (filename))
+ return;
+
+ assembly = AssemblyFactory.GetAssembly (filename);
+
+ objects_dirty = false;
+ Load (cache_info.ObjectsDocument);
+ if (objects_dirty)
+ cache_info.WriteObjectsFile ();
+
+ foreach (string dep in GetLibraryDependencies ()) {
+ WidgetLibrary lib = Registry.GetWidgetLibrary (dep);
+ if (lib != null && !lib.CanGenerateCode)
+ canGenerateCode = false;
+ }
+ assembly = null;
+ info_changed = false;
+ }
+
+ void RefreshFromCache ()
+ {
+ LibraryCache.LibraryInfo newInfo = cache.Refresh (resolver, filename);
+ if (newInfo != cache_info) {
+ if (cache_info != null)
+ cache_info.Changed -= OnCacheInfoChanged;
+ cache_info = newInfo;
+ cache_info.Changed += OnCacheInfoChanged;
+ }
+ }
+
+ void OnCacheInfoChanged (object o, EventArgs a)
+ {
+ info_changed = true;
+ }
+
+ public override void Dispose ()
+ {
+ base.Dispose ();
+ if (cache_info != null) {
+ cache_info.Changed -= OnCacheInfoChanged;
+ cache_info = null;
+ }
+ }
+
+
+ protected override ClassDescriptor LoadClassDescriptor (XmlElement element)
+ {
+ string name = element.GetAttribute ("type");
+
+ TypeDefinition cls = null;
+ Stetic.ClassDescriptor typeClassDescriptor = null;
+ string tname;
+
+ if (element.HasAttribute ("baseClassType")) {
+ tname = element.GetAttribute ("baseClassType");
+ typeClassDescriptor = Stetic.Registry.LookupClassByName (tname);
+ } else {
+ cls = assembly.MainModule.Types [name];
+ if (cls != null) {
+ // Find the nearest type that can be loaded
+ typeClassDescriptor = FindType (assembly, cls);
+ tname = cls.Name;
+ if (typeClassDescriptor != null) {
+ element.SetAttribute ("baseClassType", typeClassDescriptor.Name);
+ objects_dirty = true;
+ }
+ }
+ }
+
+ if (typeClassDescriptor == null) {
+ Console.WriteLine ("Descriptor not found: " + name);
+ return null;
+ }
+
+ XmlElement steticDefinition = null;
+
+ XmlDocument gui = cache [filename].GuiDocument;
+ if (gui != null) {
+ string wrappedTypeName = element.GetAttribute ("type");
+ steticDefinition = (XmlElement) gui.DocumentElement.SelectSingleNode ("widget[@id='" + wrappedTypeName + "']");
+ }
+
+ CecilClassDescriptor cd = new CecilClassDescriptor (this, element, typeClassDescriptor, steticDefinition, cls);
+
+ if (canGenerateCode && !cd.CanGenerateCode)
+ canGenerateCode = false;
+ return cd;
+ }
+
+ Stetic.ClassDescriptor FindType (AssemblyDefinition asm, TypeDefinition cls)
+ {
+ if (cls.BaseType == null)
+ return null;
+ Stetic.ClassDescriptor klass = Stetic.Registry.LookupClassByName (cls.BaseType.FullName);
+ if (klass != null) return klass;
+
+ TypeDefinition bcls = FindTypeDefinition (cls.BaseType.FullName);
+ if (bcls == null)
+ return null;
+
+ return FindType (asm, bcls);
+ }
+
+ AssemblyDefinition ResolveAssembly (AssemblyNameReference aref)
+ {
+ return resolver.Resolve (aref, Path.GetDirectoryName (filename));
+ }
+
+ internal TypeDefinition FindTypeDefinition (string fullName)
+ {
+ TypeDefinition t = FindTypeDefinition (new Hashtable (), assembly, fullName);
+ return t;
+ }
+
+ TypeDefinition FindTypeDefinition (Hashtable visited, AssemblyDefinition asm, string fullName)
+ {
+ if (visited.Contains (asm))
+ return null;
+
+ visited [asm] = asm;
+
+ TypeDefinition cls = asm.MainModule.Types [fullName];
+ if (cls != null)
+ return cls;
+
+ foreach (AssemblyNameReference aref in asm.MainModule.AssemblyReferences) {
+ AssemblyDefinition basm = ResolveAssembly (aref);
+ if (basm != null) {
+ cls = basm.MainModule.Types [fullName];
+ if (cls != null)
+ return cls;
+/* cls = FindTypeDefinition (visited, basm, fullName);
+ if (cls != null)
+ return cls;
+*/ }
+ }
+ return null;
+ }
+
+ public override string[] GetLibraryDependencies ()
+ {
+ if (NeedsReload || dependencies == null)
+ LoadDependencies ();
+ return dependencies;
+ }
+
+ void LoadDependencies ()
+ {
+ RefreshFromCache ();
+ if (cache_info == null || cache_info.ObjectsDocument == null) {
+ dependencies = new string[0];
+ return;
+ }
+ XmlElement elem = cache_info.ObjectsDocument.DocumentElement ["dependencies"];
+ if (elem != null) {
+ ArrayList list = new ArrayList ();
+ foreach (XmlElement dep in elem.SelectNodes ("dependency"))
+ list.Add (dep.InnerText);
+ dependencies = (string[]) list.ToArray (typeof(string));
+ } else
+ dependencies = new string[0];
+ }
+
+ public static bool IsWidgetLibrary (string path)
+ {
+ // Info can be null if the library could not be scanned for some reason
+ var info = cache [path];
+ return info != null && info.HasWidgets;
+ }
+
+ public static string GetInstanceType (TypeDefinition td, TypeReference sourceType, TypeReference tref)
+ {
+ string tn = null;
+ if (sourceType is GenericInstanceType) {
+ GenericInstanceType it = (GenericInstanceType) sourceType;
+ foreach (GenericParameter gc in td.GenericParameters) {
+ if (gc.Name == tref.FullName) {
+ tn = it.GenericArguments [gc.Position].FullName;
+ break;
+ }
+ }
+ }
+ if (tn == null)
+ tn = tref.FullName;
+ tn = tn.Replace ('<', '[');
+ tn = tn.Replace ('>', ']');
+ return tn;
+ }
+
+ public static List<ComponentType> GetComponentTypes (Application app, string filename)
+ {
+ List<ComponentType> list = new List<ComponentType> ();
+
+ LibraryCache.LibraryInfo info = cache.Refresh (new AssemblyResolver (app.Backend), filename);
+ if (info.ObjectsDocument == null)
+ return list;
+
+ string defTargetGtkVersion = info.ObjectsDocument.DocumentElement.GetAttribute ("gtk-version");
+ if (defTargetGtkVersion.Length == 0)
+ defTargetGtkVersion = "2.4";
+
+ AssemblyDefinition adef = AssemblyFactory.GetAssembly (filename);
+
+ foreach (XmlElement elem in info.ObjectsDocument.SelectNodes ("objects/object")) {
+ if (elem.GetAttribute ("internal") == "true" || elem.HasAttribute ("deprecated") || !elem.HasAttribute ("palette-category"))
+ continue;
+
+ string iconname = elem.GetAttribute ("icon");
+ Gdk.Pixbuf icon = GetEmbeddedIcon (adef, iconname);
+
+ string targetGtkVersion = elem.GetAttribute ("gtk-version");
+ if (targetGtkVersion.Length == 0)
+ targetGtkVersion = defTargetGtkVersion;
+
+ ComponentType ct = new ComponentType (app,
+ elem.GetAttribute ("type"),
+ elem.GetAttribute ("label"),
+ elem.GetAttribute ("type"),
+ elem.GetAttribute ("palette-category"),
+ targetGtkVersion,
+ filename,
+ icon);
+
+ list.Add (ct);
+ }
+
+ return list;
+ }
+
+ public Gdk.Pixbuf GetEmbeddedIcon (string iconname)
+ {
+ return GetEmbeddedIcon (assembly, iconname);
+ }
+
+ static Gdk.Pixbuf GetEmbeddedIcon (AssemblyDefinition asm, string iconname)
+ {
+ Gdk.Pixbuf icon = null;
+ if (iconname != null && iconname.Length > 0) {
+ try {
+ // Using the pixbuf resource constructor generates a gdk warning.
+ EmbeddedResource res = GetResource (asm, iconname);
+ Gdk.PixbufLoader loader = new Gdk.PixbufLoader (res.Data);
+ icon = loader.Pixbuf;
+ } catch {
+ // Ignore
+ }
+ }
+
+ if (icon == null) {
+ ClassDescriptor cc = Registry.LookupClassByName ("Gtk.Bin");
+ icon = cc.Icon;
+ }
+ return icon;
+ }
+
+ static EmbeddedResource GetResource (AssemblyDefinition asm, string name)
+ {
+ foreach (Resource res in asm.MainModule.Resources) {
+ EmbeddedResource eres = res as EmbeddedResource;
+ if (eres != null && eres.Name == name)
+ return eres;
+ }
+ return null;
+ }
+
+ public override void Flush ()
+ {
+ base.Flush ();
+ if (resolver != null)
+ resolver.ClearCache ();
+ }
+
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ChangeLog
new file mode 100644
index 0000000000..8d924e5e94
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ChangeLog
@@ -0,0 +1,431 @@
+2010-10-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ApplicationBackend.cs:
+
+2010-10-04 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * libsteticui2.csproj:
+ * ApplicationBackend.cs:
+
+2010-09-30 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ApplicationBackend.cs:
+
+2010-09-30 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * libsteticui2.csproj:
+ * ApplicationBackend.cs:
+
+2010-09-22 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Add ReloadComponent method
+ * ProjectBackend.cs:
+
+2010-09-21 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Code cleanup
+ * ProjectBackend.cs:
+
+2010-09-20 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * ProjectBackend.cs:
+
+2010-09-17 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * libsteticui2.csproj:
+
+2010-09-17 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * libsteticui2.csproj:
+
+2010-09-15 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * libsteticui2.csproj:
+
+2010-09-08 Krzysztof Marecki <freefirma@gmail.com>
+
+ * SignalsEditorBackend.cs:
+
+2010-08-17 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Application.cs:
+ * ProjectBackend.cs:
+
+2010-08-16 Krzysztof Marecki <freefirma@gmail.com>
+
+ * ProjectBackend.cs:
+ * WidgetEditSession.cs:
+ * IProjectDesignInfo.cs:
+
+2010-08-15 Krzysztof Marecki <freefirma@gmail.com>
+
+ * CodeGenerator.cs:
+ * ProjectBackend.cs:
+ * WidgetEditSession.cs:
+ * CodeGeneratorPartialClass.cs:
+
+2010-08-13 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Project.cs:
+ * Makefile.am:
+ * CodeGenerator.cs:
+ * libsteticui2.csproj:
+ * ActionGroupEditSession.cs:
+ * CodeGeneratorPartialClass.cs:
+ * CodeGeneratorInternalClass.cs: Remove class
+
+2010-08-09 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Project.cs: Add ComponentNeedsCodeGeneration method
+ * ProjectBackend.cs:
+ * IProjectDesignInfo.cs:
+ * CodeGeneratorPartialClass.cs: Only generate code for components that
+ have been changed
+
+2010-08-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Remove Modifies property
+ * ProjectBackend.cs: Add modifiedTopLevel list, handled on project loading, saving.
+ * libsteticui2.csproj:
+ * WidgetEditSession.cs: Use ProjectBackend.WasModified to determine if it was modified
+
+2010-08-05 Krzysztof Marecki <freefirma@gmail.com>
+
+ * WidgetDesigner.cs:
+ * ProjectBackend.cs:
+
+2010-08-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+ Remove ModifiedChanged event,
+ change Changed event to ProjectChangedEventHandler (pass name of changed widget)
+ * Project.cs:
+ * WidgetDesigner.cs:
+ * ProjectBackend.cs:
+ * WidgetEditSession.cs:
+
+2010-08-04 Krzysztof Marecki <freefirma@gmail.com>
+
+ * Project.cs: Pass root widget name in NotifyChanged
+ * Makefile.am:
+ * ProjectBackend.cs:
+ * libsteticui2.csproj:
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Glade.cs:
+ * Makefile.am:
+ * ProjectBackend.cs:
+
+2010-08-03 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * ProjectBackend.cs: Return empty string when GtktargetVersion
+ is not initialized
+
+2010-07-27 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Remove autoCommit argument
+ * Makefile.am:
+ * WidgetDesigner.cs: Remove temporary project
+ * ProjectBackend.cs: Do not clear libraries on Close
+ * WidgetEditSession.cs: Remove temporary project
+
+2010-07-27 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs:
+ * WidgetDesigner.cs:
+ * ProjectBackend.cs:
+
+2010-07-06 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Add parameter to Convert method for passing
+ a new gtk gui folder name.
+ * ProjectBackend.cs:
+
+2010-07-05 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Glade.cs:
+ * Project.cs: AddComponent method
+ * Makefile.am:
+ * ProjectBackend.cs:
+ * libsteticui2.csproj:
+
+2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Find class name for given .gtkx file
+ * Makefile.am:
+ * ProjectBackend.cs:
+ * IProjectDesignInfo.cs:
+
+2010-06-28 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * ProjectBackend.cs:
+ * libsteticui2.csproj:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * libsteticui2.csproj:
+
+2010-06-23 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * libsteticui2.csproj:
+
+2010-06-22 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+
+2010-06-16 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+
+2010-06-15 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Create backend for Convert
+
+2010-06-09 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * libsteticui2.csproj:
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs: Transition from project file name to project folder.
+ * Makefile.am:
+ * Application.cs:
+ * ProjectBackend.cs:
+ * WidgetEditSession.cs:
+
+2010-06-07 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Project.cs:
+ * Makefile.am:
+ * ProjectBackend.cs:
+ * IProjectDesignInfo.cs:
+
+2010-06-02 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * Makefile.am:
+ * libsteticui2.csproj:
+
+2010-04-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * CecilSignalDescriptor.cs: Cecil uses '/' as separator for
+ inner classes. Convert to the standard '+' separator.
+
+2010-01-18 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * CodeGenerator.cs:
+ * libsteticui.csproj:
+ * CodeGeneratorPartialClass.cs:
+ * CodeGeneratorInternalClass.cs: Use global:: for type
+ references in generated code.
+
+2010-01-15 Mike Krüger <mkrueger@novell.com>
+
+ * libsteticui.csproj: upgraded to v3.5 framework.
+
+2009-12-18 Michael Hutchinson <mhutchinson@novell.com>
+
+ * WidgetDesignerBackend.cs: Disable checkerboard background
+ because redraw is super-inefficient and makes resizing
+ unbearably slow. It needs to do more selective invalidation
+ in resizes (like GTK viewport), and take the exposed area
+ into account in expose events.
+
+2009-11-12 Lluis Sanchez Gual <lluis@novell.com>
+
+ * WidgetDesignerBackend.cs: Don't try to realize the child if
+ the widget is not anchored. Fixes bug #553475 -
+ "Gtk-Critical: gtk_widget_realize: assertion" when running a
+ gtk# app inside MD.
+
+2009-11-05 Mike Kestner <mkestner@novell.com>
+
+ * Application.cs:
+ * ApplicationBackend.cs:
+ * CodeGenerator.cs: some warning cleanup.
+
+2009-10-21 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui.csproj: Flush.
+
+2009-10-16 Mike Krüger <mkrueger@novell.com>
+
+ * ActionComponent.cs: Handled icon loading failures.
+
+2009-10-08 Ankit Jain <jankit@novell.com>
+
+ * libsteticui.csproj: Mark Mono.Cecil project referece
+ as private.
+
+2009-09-10 Christian Hergert <chris@dronelabs.com>
+
+ * libsteticui/libsteticui.dll.config: Use quartz on osx.
+
+2009-09-04 Michael Hutchinson <mhutchinson@novell.com>
+
+ * Metacity/Preview.cs: Use Assembly.LoadWithPartialName. It's
+ obsolete, but at least it works.
+
+2009-08-27 Mike Krüger <mkrueger@novell.com>
+
+ * Metacity/Preview.cs:
+ * WidgetDesignerBackend.cs: Worked on designer decoration.
+
+2009-08-27 Mike Krüger <mkrueger@novell.com>
+
+ * Grid.cs:
+ * LibraryCache.cs:
+ * Windows/Preview.cs:
+ * WidgetActionBar.cs:
+ * ApplicationBackend.cs: Fixed some warnings.
+
+2009-08-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui.csproj: Updated dependencies. We now depend on
+ gtk# 2.12.8, Mono 2.4, and Mono.Addins 0.4.
+
+2009-08-24 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Project.cs:
+ * UndoQueue.cs:
+ * WidgetDesigner.cs:
+ * ProjectBackend.cs:
+ * WidgetEditSession.cs: Added support for saving and restoring
+ the status of the designer, including the undo queue. This
+ allows implenting ISupportsProjectReload.
+
+2009-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Metacity/Preview.cs: Remove debug code.
+
+2009-07-31 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Windows/Preview.cs: Dont try to create a Win32 preview
+ window when not running on Windows.
+
+2009-07-01 Lluis Sanchez Gual <lluis@novell.com>
+
+ * WidgetDesigner.cs:
+ * ActionGroupDesigner.cs:
+ * WidgetDesignerBackend.cs:
+ * ActionGroupEditSession.cs: No more missing IntPtr
+ constructor exceptions.
+
+2009-06-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * WidgetDesignerBackend.cs: Fix rendering of the window
+ decoration.
+
+2009-06-25 Lluis Sanchez Gual <lluis@novell.com>
+
+ * WidgetDesigner.cs:
+ * WidgetDesignerBackend.cs: Dispose is not guaranteed to be
+ called when destroying a widget. Use OnDestroyed instead.
+
+2009-06-25 Mike Krüger <mkrueger@novell.com>
+
+ * WidgetDesignerBackend.cs: Draw dialog background.
+
+2009-06-25 Mike Krüger <mkrueger@novell.com>
+
+ * WidgetDesignerBackend.cs: Draw checkboard background in the
+ gui designer instead of monochrome dialog background.
+
+2009-06-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * PluggableWidget.cs: When replacing the child widget (because
+ of reloading of the project for example), make sure the old
+ one is destroyed.
+
+2009-05-07 Lluis Sanchez Gual <lluis@novell.com>
+
+ * Makefile.am:
+ * libsteticui.csproj: Updated.
+
+ * Metacity/Theme.cs:
+ * Metacity/FrameType.cs:
+ * Metacity/FrameFlags.cs:
+ * Metacity/ButtonLayout.cs:
+ * Metacity/ObjectManager.cs:
+ * Metacity/ButtonFunction.cs: Use a better namespace.
+
+ * Metacity/Preview.cs: Use the new TopLevelWindow class. Track
+ changes in the title of the window.
+
+ * Windows:
+ * Windows/Preview.cs:
+ * Windows/WindowsTheme.cs:
+ * WidgetDesignerBackend.cs: Added support for win32 window
+ decorations.
+
+ * EmbedWindow.cs:
+ * UserInterface.cs: EmbedWindow is not required anymore.
+
+2009-05-04 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui.csproj: Copy the config file to the output dir.
+ Set project type to library.
+
+ * Metacity/Preview.cs:
+ * WidgetDesignerBackend.cs: Avoid exception in the
+ MetacityPreview class constructor, since it crashes MD under
+ ms.net.
+
+2009-04-29 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui.csproj: Don't require a specific gtk# version.
+
+2009-03-03 Lluis Sanchez Gual <lluis@novell.com>
+
+ * LibraryCache.cs: Avoid recursive loading of
+ AssemblyDefinition. Rely on cache info to check if a
+ referenced library contains widget definitions.
+
+ * AssemblyResolver.cs: Make sure the resolver returns full
+ paths.
+
+ * CecilWidgetLibrary.cs: Use the full path to query info from
+ the cache. Properly unsubscribe the Changed event from the
+ cache. Resolve assemblies using the provided assembly
+ resolver.
+
+ * ApplicationBackend.cs:
+ * AssemblyWidgetLibrary.cs: From now on the registry and the
+ library cache only handle libraries with full paths.
+
+ * Project.cs: Make sure unused project backends are properly
+ disposed.
+
+2009-02-26 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui.csproj: Flush.
+
+2009-02-12 Michael Hutchinson <mhutchinson@novell.com>
+
+ * PropertyTree.cs:
+ * WidgetDesignerBackend.cs: Dispose Gdk cursors, else
+ finalisers destroy them outside of the GUI thread and often
+ crash MD due to X asserts resulting in _XCBUnlockDisplay
+ errors.
+
+2009-02-10 Michael Hutchinson <mhutchinson@novell.com>
+
+ * libsteticui.csproj: Don't build with make, since MD can
+ build these just fine.
+
+2009-02-07 Michael Hutchinson <mhutchinson@novell.com>
+
+ * libsteticui.csproj: Allow unsafe code, since Shadow.cs has
+ unsafe code.
+
+2009-02-06 Lluis Sanchez Gual <lluis@novell.com>
+
+ * libsteticui.mdp:
+ * libsteticui.csproj: Migrated to MSBuild file format.
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerationResult.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerationResult.cs
new file mode 100644
index 0000000000..3e2dedcd84
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerationResult.cs
@@ -0,0 +1,26 @@
+
+using System;
+
+namespace Stetic
+{
+ [Serializable]
+ public class CodeGenerationResult
+ {
+ SteticCompilationUnit[] units;
+ string[] warnings;
+
+ internal CodeGenerationResult (SteticCompilationUnit[] units, string[] warnings)
+ {
+ this.units = units;
+ this.warnings = warnings;
+ }
+
+ public SteticCompilationUnit[] Units {
+ get { return units; }
+ }
+
+ public string[] Warnings {
+ get { return warnings; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerator.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerator.cs
new file mode 100644
index 0000000000..7ea4b3d4df
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGenerator.cs
@@ -0,0 +1,432 @@
+using System;
+using System.Reflection;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.IO;
+using System.Collections;
+
+namespace Stetic
+{
+ internal static class CodeGenerator
+ {
+// public static void GenerateProjectCode (string file, CodeDomProvider provider, GenerationOptions options, ProjectBackend[] projects)
+// {
+// CodeGenerationResult res = GenerateProjectCode (options, projects);
+//
+// string basePath = Path.GetDirectoryName (file);
+//
+// foreach (SteticCompilationUnit unit in res.Units) {
+// string fname;
+// if (unit.Name.Length == 0)
+// fname = file;
+// else
+// fname = Path.Combine (basePath, unit.Name);
+// StreamWriter fileStream = new StreamWriter (fname);
+// try {
+// provider.GenerateCodeFromCompileUnit (unit, fileStream, new CodeGeneratorOptions ());
+// } finally {
+// fileStream.Close ();
+// }
+// }
+// }
+
+ public static CodeGenerationResult GenerateProjectCode (GenerationOptions options, ProjectBackend[] projects)
+ {
+ ArrayList warningList = new ArrayList ();
+
+ List<SteticCompilationUnit> units = new List<SteticCompilationUnit> ();
+// SteticCompilationUnit globalUnit = new SteticCompilationUnit ("");
+// units.Add (globalUnit);
+
+ if (options == null)
+ options = new GenerationOptions ();
+ CodeNamespace globalNs = new CodeNamespace (options.GlobalNamespace);
+// globalUnit.Namespaces.Add (globalNs);
+
+ // Global class
+
+ CodeTypeDeclaration globalType = new CodeTypeDeclaration ("Gui");
+ globalType.Attributes = MemberAttributes.Private;
+ globalType.TypeAttributes = TypeAttributes.NestedAssembly;
+ globalNs.Types.Add (globalType);
+
+ // Create the project initialization method
+ // This method will only be added at the end if there
+ // is actually something to initialize
+
+ CodeMemberMethod initMethod = new CodeMemberMethod ();
+ initMethod.Name = "Initialize";
+ initMethod.ReturnType = new CodeTypeReference (typeof(void));
+ initMethod.Attributes = MemberAttributes.Assembly | MemberAttributes.Static;
+ initMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof(Gtk.Widget), "iconRenderer"));
+
+ GeneratorContext initContext = new ProjectGeneratorContext (globalNs, globalType, initMethod.Statements, options);
+ initContext.RootObject = new CodeArgumentReferenceExpression ("iconRenderer");
+
+ // Generate icon factory creation
+
+ foreach (ProjectBackend gp in projects) {
+ if (gp.IconFactory.Icons.Count > 0)
+ gp.IconFactory.GenerateBuildCode (initContext);
+ }
+ warningList.AddRange (initContext.Warnings);
+
+ // Generate the code
+ CodeGeneratorPartialClass.GenerateProjectGuiCode (globalNs, globalType, options, units, projects, warningList);
+
+ GenerateProjectActionsCode (globalNs, options, projects);
+
+ // Final step. If there is some initialization code, add all needed infrastructure
+
+ globalType.Members.Add (initMethod);
+
+ CodeMemberField initField = new CodeMemberField (typeof(bool), "initialized");
+ initField.Attributes = MemberAttributes.Private | MemberAttributes.Static;
+ globalType.Members.Add (initField);
+
+ CodeFieldReferenceExpression initVar = new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (globalNs.Name + ".Gui"),
+ "initialized"
+ );
+
+ CodeConditionStatement initCondition = new CodeConditionStatement ();
+ initCondition.Condition = new CodeBinaryOperatorExpression (
+ initVar,
+ CodeBinaryOperatorType.IdentityEquality,
+ new CodePrimitiveExpression (false)
+ );
+ initCondition.TrueStatements.Add (new CodeAssignStatement (
+ initVar,
+ new CodePrimitiveExpression (true)
+ ));
+ initCondition.TrueStatements.AddRange (initMethod.Statements);
+ initMethod.Statements.Clear ();
+ initMethod.Statements.Add (initCondition);
+
+ //create separate compilation unit for each type in the global namespace
+ //and insert them at the begining of the units list.
+ int index = 0;
+ foreach (CodeTypeDeclaration type in globalNs.Types)
+ {
+ SteticCompilationUnit unit = new SteticCompilationUnit (type.Name);
+ CodeNamespace ns = new CodeNamespace (globalNs.Name);
+
+ ns.Types.Add (type);
+ unit.Namespaces.Add (ns);
+ units.Insert (index++, unit);
+ }
+
+ return new CodeGenerationResult (units.ToArray (), (string[]) warningList.ToArray (typeof(string)));
+ }
+
+ internal static void BindSignalHandlers (CodeExpression targetObjectVar, ObjectWrapper wrapper, Stetic.WidgetMap map, CodeStatementCollection statements, GenerationOptions options)
+ {
+ foreach (Signal signal in wrapper.Signals) {
+ SignalDescriptor descriptor = signal.SignalDescriptor;
+
+ CodeExpression createDelegate = new CodeDelegateCreateExpression (
+ new CodeTypeReference (descriptor.HandlerTypeName, CodeTypeReferenceOptions.GlobalReference),
+ new CodeThisReferenceExpression (),
+ signal.Handler);
+
+ CodeAttachEventStatement cevent = new CodeAttachEventStatement (
+ new CodeEventReferenceExpression (
+ map.GetWidgetExp (wrapper),
+ descriptor.Name),
+ createDelegate);
+
+ statements.Add (cevent);
+ }
+
+ Wrapper.Widget widget = wrapper as Wrapper.Widget;
+ if (widget != null && widget.IsTopLevel) {
+ // Bind local action signals
+ foreach (Wrapper.ActionGroup grp in widget.LocalActionGroups) {
+ foreach (Wrapper.Action ac in grp.Actions)
+ BindSignalHandlers (targetObjectVar, ac, map, statements, options);
+ }
+ }
+
+ Gtk.Container cont = wrapper.Wrapped as Gtk.Container;
+ if (cont != null) {
+ foreach (Gtk.Widget child in cont.AllChildren) {
+ Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (child);
+ if (ww != null)
+ BindSignalHandlers (targetObjectVar, ww, map, statements, options);
+ }
+ }
+
+ }
+
+ static void GenerateProjectActionsCode (CodeNamespace cns, GenerationOptions options, params ProjectBackend[] projects)
+ {
+ bool multiProject = projects.Length > 1;
+
+ CodeTypeDeclaration type = new CodeTypeDeclaration ("ActionGroups");
+ type.Attributes = MemberAttributes.Private;
+ type.TypeAttributes = TypeAttributes.NestedAssembly;
+ cns.Types.Add (type);
+
+ // Generate the global action group getter
+
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = "GetActionGroup";
+ type.Members.Add (met);
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(Type), "type"));
+ if (multiProject)
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "file"));
+ met.ReturnType = new CodeTypeReference (typeof(Gtk.ActionGroup));
+ met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+
+ CodeMethodInvokeExpression call = new CodeMethodInvokeExpression (
+ new CodeMethodReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (cns.Name + ".ActionGroups")),
+ "GetActionGroup"
+ ),
+ new CodePropertyReferenceExpression (
+ new CodeArgumentReferenceExpression ("type"),
+ "FullName"
+ )
+ );
+ if (multiProject)
+ call.Parameters.Add (new CodeArgumentReferenceExpression ("file"));
+
+ met.Statements.Add (new CodeMethodReturnStatement (call));
+
+ // Generate the global action group getter (overload)
+
+ met = new CodeMemberMethod ();
+ met.Name = "GetActionGroup";
+ type.Members.Add (met);
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "name"));
+ if (multiProject)
+ met.Parameters.Add (new CodeParameterDeclarationExpression (typeof(string), "file"));
+ met.ReturnType = new CodeTypeReference (typeof(Gtk.ActionGroup));
+ met.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+
+ CodeArgumentReferenceExpression cfile = new CodeArgumentReferenceExpression ("file");
+ CodeArgumentReferenceExpression cid = new CodeArgumentReferenceExpression ("name");
+
+ CodeStatementCollection projectCol = met.Statements;
+ int n=1;
+
+ foreach (ProjectBackend gp in projects) {
+
+ CodeStatementCollection widgetCol;
+
+ if (multiProject) {
+ CodeConditionStatement pcond = new CodeConditionStatement ();
+ pcond.Condition = new CodeBinaryOperatorExpression (
+ cfile,
+ CodeBinaryOperatorType.IdentityEquality,
+ new CodePrimitiveExpression (gp.Id)
+ );
+ projectCol.Add (pcond);
+
+ widgetCol = pcond.TrueStatements;
+ projectCol = pcond.FalseStatements;
+ } else {
+ widgetCol = projectCol;
+ }
+
+ foreach (Wrapper.ActionGroup grp in gp.ActionGroups) {
+ string fname = "group" + (n++);
+ CodeMemberField grpField = new CodeMemberField (new CodeTypeReference (typeof(Gtk.ActionGroup), CodeTypeReferenceOptions.GlobalReference), fname);
+ grpField.Attributes |= MemberAttributes.Static;
+ type.Members.Add (grpField);
+ CodeFieldReferenceExpression grpVar = new CodeFieldReferenceExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (cns.Name + ".ActionGroups", CodeTypeReferenceOptions.GlobalReference)),
+ fname
+ );
+
+ CodeConditionStatement pcond = new CodeConditionStatement ();
+ pcond.Condition = new CodeBinaryOperatorExpression (
+ cid,
+ CodeBinaryOperatorType.IdentityEquality,
+ new CodePrimitiveExpression (grp.Name)
+ );
+ widgetCol.Add (pcond);
+
+ // If the group has not yet been created, create it
+ CodeConditionStatement pcondGrp = new CodeConditionStatement ();
+ pcondGrp.Condition = new CodeBinaryOperatorExpression (
+ grpVar,
+ CodeBinaryOperatorType.IdentityEquality,
+ new CodePrimitiveExpression (null)
+ );
+
+ pcondGrp.TrueStatements.Add (
+ new CodeAssignStatement (
+ grpVar,
+ new CodeObjectCreateExpression (grp.Name)
+ )
+ );
+
+ pcond.TrueStatements.Add (pcondGrp);
+ pcond.TrueStatements.Add (new CodeMethodReturnStatement (grpVar));
+
+ widgetCol = pcond.FalseStatements;
+ }
+ widgetCol.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (null)));
+ }
+ if (met.Statements.Count == 0)
+ met.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (null)));
+ }
+
+ internal static List<ObjectBindInfo> GetFieldsToBind (ObjectWrapper wrapper)
+ {
+ List<ObjectBindInfo> tobind = new List<ObjectBindInfo> ();
+ GetFieldsToBind (tobind, wrapper);
+ return tobind;
+ }
+
+ static void GetFieldsToBind (List<ObjectBindInfo> tobind, ObjectWrapper wrapper)
+ {
+ string memberName = null;
+
+ if (wrapper is Wrapper.Widget) {
+ Wrapper.Widget ww = wrapper as Wrapper.Widget;
+ if (!String.IsNullOrEmpty (ww.UIManagerName))
+ tobind.Add (new ObjectBindInfo ("Gtk.UIManager", ww.UIManagerName));
+
+ if (!ww.IsTopLevel && ww.InternalChildProperty == null && !ww.Unselectable)
+ memberName = ((Wrapper.Widget) wrapper).Wrapped.Name;
+ }
+ else if (wrapper is Wrapper.Action)
+ memberName = ((Wrapper.Action) wrapper).Name;
+
+ if (memberName != null) {
+ ObjectBindInfo binfo = new ObjectBindInfo (wrapper.WrappedTypeName, memberName);
+ tobind.Add (binfo);
+ }
+
+ Wrapper.ActionGroup agroup = wrapper as Wrapper.ActionGroup;
+ if (agroup != null) {
+ foreach (Wrapper.Action ac in agroup.Actions)
+ GetFieldsToBind (tobind, ac);
+ }
+
+ Wrapper.Widget widget = wrapper as Wrapper.Widget;
+ if (widget != null && widget.IsTopLevel) {
+ // Generate fields for local actions
+ foreach (Wrapper.ActionGroup grp in widget.LocalActionGroups) {
+ GetFieldsToBind (tobind, grp);
+ }
+ }
+
+ Gtk.Container cont = wrapper.Wrapped as Gtk.Container;
+ if (cont != null) {
+ foreach (Gtk.Widget child in cont.AllChildren) {
+ Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (child);
+ if (ww != null)
+ GetFieldsToBind (tobind, ww);
+ }
+ }
+ }
+
+ public static WidgetMap GenerateCreationCode (CodeNamespace cns, CodeTypeDeclaration type, Gtk.Widget w, CodeExpression widgetVarExp, CodeStatementCollection statements, GenerationOptions options, ArrayList warnings)
+ {
+ statements.Add (new CodeCommentStatement ("Widget " + w.Name));
+ GeneratorContext ctx = new ProjectGeneratorContext (cns, type, statements, options);
+ Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (w);
+ ctx.GenerateCreationCode (ww, widgetVarExp);
+ ctx.EndGeneration ();
+ warnings.AddRange (ctx.Warnings);
+ return ctx.WidgetMap;
+ }
+
+ public static WidgetMap GenerateCreationCode (CodeNamespace cns, CodeTypeDeclaration type, Wrapper.ActionGroup grp, CodeExpression groupVarExp, CodeStatementCollection statements, GenerationOptions options, ArrayList warnings)
+ {
+ statements.Add (new CodeCommentStatement ("Action group " + grp.Name));
+ GeneratorContext ctx = new ProjectGeneratorContext (cns, type, statements, options);
+ ctx.GenerateCreationCode (grp, groupVarExp);
+ ctx.EndGeneration ();
+ warnings.AddRange (ctx.Warnings);
+ return ctx.WidgetMap;
+ }
+ }
+
+ class ProjectGeneratorContext: GeneratorContext
+ {
+ CodeTypeDeclaration type;
+
+ public ProjectGeneratorContext (CodeNamespace cns, CodeTypeDeclaration type, CodeStatementCollection statements, GenerationOptions options): base (cns, "w", statements, options)
+ {
+ this.type = type;
+ }
+
+ public override CodeExpression GenerateInstanceExpression (ObjectWrapper wrapper, CodeExpression newObject)
+ {
+ string typeName = wrapper.WrappedTypeName;
+ string memberName = null;
+ if (wrapper is Wrapper.Widget)
+ memberName = ((Wrapper.Widget) wrapper).Wrapped.Name;
+ else if (wrapper is Wrapper.Action)
+ memberName = ((Wrapper.Action) wrapper).Name;
+
+ if (memberName == null)
+ return base.GenerateInstanceExpression (wrapper, newObject);
+
+// if (Options.UsePartialClasses) {
+ // Don't generate fields for top level widgets and for widgets accessible
+ // through other widget's properties
+ Wrapper.Widget ww = wrapper as Wrapper.Widget;
+ if (ww == null || (!ww.IsTopLevel && ww.InternalChildProperty == null && !ww.Unselectable)) {
+ type.Members.Add (
+ new CodeMemberField (
+ new CodeTypeReference (typeName, CodeTypeReferenceOptions.GlobalReference),
+ memberName
+ )
+ );
+ CodeExpression var = new CodeFieldReferenceExpression (
+ new CodeThisReferenceExpression (),
+ memberName
+ );
+
+ Statements.Add (
+ new CodeAssignStatement (
+ var,
+ newObject
+ )
+ );
+ return var;
+ } else
+ return base.GenerateInstanceExpression (wrapper, newObject);
+// } else {
+// CodeExpression var = base.GenerateInstanceExpression (wrapper, newObject);
+// Statements.Add (
+// new CodeAssignStatement (
+// new CodeIndexerExpression (
+// new CodeVariableReferenceExpression ("bindings"),
+// new CodePrimitiveExpression (memberName)
+// ),
+// var
+// )
+// );
+// return var;
+// }
+ }
+ }
+
+ [Serializable]
+ public class SteticCompilationUnit: CodeCompileUnit
+ {
+ string name;
+
+ public SteticCompilationUnit (string name)
+ {
+ this.name = name;
+ }
+
+ public string Name {
+ get { return name; }
+ internal set { name = value; }
+ }
+
+ public CodeNamespace Namespace
+ {
+ get { return (Namespaces.Count > 0) ? Namespaces [0] : null; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGeneratorPartialClass.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGeneratorPartialClass.cs
new file mode 100644
index 0000000000..7371b4892c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/CodeGeneratorPartialClass.cs
@@ -0,0 +1,143 @@
+
+using System;
+using System.Reflection;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.Collections;
+using System.IO;
+
+namespace Stetic
+{
+ internal static class CodeGeneratorPartialClass
+ {
+ public static void GenerateProjectGuiCode (CodeNamespace globalNs, CodeTypeDeclaration globalType, GenerationOptions options, List<SteticCompilationUnit> units, ProjectBackend[] projects, ArrayList warnings)
+ {
+ // Generate code for each project
+ foreach (ProjectBackend gp in projects) {
+
+ // Generate top levels
+ foreach (Gtk.Widget w in gp.Toplevels) {
+ Stetic.Wrapper.Widget wwidget = Stetic.Wrapper.Widget.Lookup (w);
+ string topLevelName = wwidget.Name;
+ if (gp.ComponentNeedsCodeGeneration (topLevelName)) {
+ //designer file for widget could be changed beyond stetic process
+ //and we nead update wrapper before code generation
+ //during reloading wrappered widget w could be changed;
+ Gtk.Widget currentw = w;
+ if (gp.ReloadTopLevel (topLevelName)) {
+ currentw = gp.GetWidget (topLevelName);
+ }
+ GenerateWidgetCode (globalNs, options, units, currentw, warnings);
+ }
+ }
+
+ // Generate global action groups
+ foreach (Wrapper.ActionGroup agroup in gp.ActionGroups) {
+ string groupName = agroup.Name;
+ if (gp.ComponentNeedsCodeGeneration (groupName)) {
+ //designer file for action group could be changed beyond stetic process
+ //and we nead update wrapper
+ gp.ReloadActionGroup (groupName);
+ GenerateGlobalActionGroupCode (globalNs, options, units, agroup, warnings);
+ }
+ }
+ }
+ }
+
+ static CodeTypeDeclaration CreatePartialClass (List<SteticCompilationUnit> units, GenerationOptions options, string name)
+ {
+ SteticCompilationUnit unit;
+
+ unit = new SteticCompilationUnit (name);
+ units.Add (unit);
+
+ string ns = "";
+ int i = name.LastIndexOf ('.');
+ if (i != -1) {
+ ns = name.Substring (0, i);
+ name = name.Substring (i+1);
+ }
+
+ CodeTypeDeclaration type = new CodeTypeDeclaration (name);
+ type.IsPartial = true;
+ type.Attributes = MemberAttributes.Public;
+ type.TypeAttributes = TypeAttributes.Public;
+
+ CodeNamespace cns = new CodeNamespace (ns);
+ cns.Types.Add (type);
+ unit.Namespaces.Add (cns);
+ return type;
+ }
+
+
+ static void GenerateWidgetCode (CodeNamespace globalNs, GenerationOptions options, List<SteticCompilationUnit> units, Gtk.Widget w, ArrayList warnings)
+ {
+ // Generate the build method
+
+ CodeTypeDeclaration type = CreatePartialClass (units, options, w.Name);
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = "Build";
+ type.Members.Add (met);
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Attributes = MemberAttributes.Family;
+
+ Stetic.Wrapper.Widget wwidget = Stetic.Wrapper.Widget.Lookup (w);
+
+ if (options.GenerateEmptyBuildMethod) {
+ GenerateWrapperFields (type, wwidget);
+ return;
+ }
+
+ met.Statements.Add (
+ new CodeMethodInvokeExpression (
+ new CodeTypeReferenceExpression (new CodeTypeReference (globalNs.Name + ".Gui", CodeTypeReferenceOptions.GlobalReference)),
+ "Initialize",
+ new CodeThisReferenceExpression ()
+ )
+ );
+
+ if (wwidget.GeneratePublic)
+ type.TypeAttributes = TypeAttributes.Public;
+ else
+ type.TypeAttributes = TypeAttributes.NotPublic;
+
+ if (!String.IsNullOrEmpty (wwidget.UIManagerName))
+ type.Members.Add (new CodeMemberField (new CodeTypeReference ("Gtk.UIManager", CodeTypeReferenceOptions.GlobalReference), wwidget.UIManagerName));
+
+ Stetic.WidgetMap map = Stetic.CodeGenerator.GenerateCreationCode (globalNs, type, w, new CodeThisReferenceExpression (), met.Statements, options, warnings);
+ CodeGenerator.BindSignalHandlers (new CodeThisReferenceExpression (), wwidget, map, met.Statements, options);
+ }
+
+ static void GenerateWrapperFields (CodeTypeDeclaration type, ObjectWrapper wrapper)
+ {
+ foreach (ObjectBindInfo binfo in CodeGenerator.GetFieldsToBind (wrapper)) {
+ type.Members.Add (
+ new CodeMemberField (
+ new CodeTypeReference (binfo.TypeName, CodeTypeReferenceOptions.GlobalReference),
+ binfo.Name
+ )
+ );
+ }
+ }
+
+
+ static void GenerateGlobalActionGroupCode (CodeNamespace globalNs, GenerationOptions options, List<SteticCompilationUnit> units, Wrapper.ActionGroup agroup, ArrayList warnings)
+ {
+ CodeTypeDeclaration type = CreatePartialClass (units, options, agroup.Name);
+
+ // Generate the build method
+
+ CodeMemberMethod met = new CodeMemberMethod ();
+ met.Name = "Build";
+ type.Members.Add (met);
+ met.ReturnType = new CodeTypeReference (typeof(void));
+ met.Attributes = MemberAttributes.Public;
+
+ Stetic.WidgetMap map = Stetic.CodeGenerator.GenerateCreationCode (globalNs, type, agroup, new CodeThisReferenceExpression (), met.Statements, options, warnings);
+
+ foreach (Wrapper.Action ac in agroup.Actions)
+ CodeGenerator.BindSignalHandlers (new CodeThisReferenceExpression (), ac, map, met.Statements, options);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Component.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Component.cs
new file mode 100644
index 0000000000..1a1d495ccf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Component.cs
@@ -0,0 +1,112 @@
+
+using System;
+using System.Collections;
+
+namespace Stetic
+{
+ public class Component: MarshalByRefObject, IObjectFrontend
+ {
+ protected string name;
+ protected ComponentType type;
+ protected string typeName;
+ protected object backend;
+ protected Application app;
+
+ public event EventHandler Changed;
+
+ internal Component (Application app, object backend, string name, ComponentType type)
+ {
+ this.app = app;
+ this.backend = backend;
+ this.name = name;
+ this.type = type;
+ }
+
+ public virtual void Dispose ()
+ {
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ if (app != null)
+ app.DisposeComponent (this);
+ }
+
+ public SignalCollection GetSignals ()
+ {
+ if (backend is ObjectWrapper)
+ return ((ObjectWrapper)backend).Signals;
+ else
+ return new SignalCollection ();
+ }
+
+ public void RemoveSignal (Signal signal)
+ {
+ if (backend is ObjectWrapper && app != null)
+ app.Backend.RemoveWidgetSignal ((ObjectWrapper) backend, signal);
+ }
+
+ public virtual Component[] GetChildren ()
+ {
+ return new Component [0];
+ }
+
+ void IObjectFrontend.NotifyChanged ()
+ {
+ OnChanged ();
+ }
+
+ protected virtual void OnChanged ()
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+
+ public virtual string Name {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual ComponentType Type {
+ get {
+ return type;
+ }
+ }
+
+ public virtual bool GeneratePublic {
+ get { return true; }
+ set {}
+ }
+
+ internal object Backend {
+ get { return backend; }
+ }
+
+ internal static MarshalByRefObject GetSafeReference (MarshalByRefObject ob)
+ {
+ // Make sure we don't leak the wrapper type to the frontend process
+
+ if (ob is Wrapper.Window) {
+ System.Runtime.Remoting.RemotingServices.Marshal (ob, null, typeof(Wrapper.Window));
+ } else if (ob is Wrapper.Container) {
+ System.Runtime.Remoting.RemotingServices.Marshal (ob, null, typeof(Wrapper.Container));
+ } else if (ob is Wrapper.Widget) {
+ System.Runtime.Remoting.RemotingServices.Marshal (ob, null, typeof(Wrapper.Widget));
+ } else if (ob is ObjectWrapper) {
+ System.Runtime.Remoting.RemotingServices.Marshal (ob, null, typeof(ObjectWrapper));
+ }
+ return ob;
+ }
+
+ public override string ToString ()
+ {
+ return base.ToString() + " " + backend;
+ }
+
+ public ObjectBindInfo[] GetObjectBindInfo ()
+ {
+ ObjectWrapper ww = backend as ObjectWrapper;
+ if (ww != null)
+ return app.Backend.GetBoundComponents (ww);
+ else
+ return new ObjectBindInfo [0];
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentEventHandler.cs
new file mode 100644
index 0000000000..d4226f0da7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentEventHandler.cs
@@ -0,0 +1,67 @@
+
+using System;
+
+namespace Stetic
+{
+ public delegate void ComponentEventHandler (object sender, ComponentEventArgs args);
+ public delegate void ComponentNameEventHandler (object sender, ComponentNameEventArgs args);
+ public delegate void ComponentRemovedEventHandler (object sender, ComponentRemovedEventArgs args);
+
+ public class ComponentEventArgs: EventArgs
+ {
+ Project project;
+ Component component;
+
+ internal ComponentEventArgs (Project p, Component c)
+ {
+ project = p;
+ component = c;
+ }
+
+ public Project Project {
+ get { return project; }
+ }
+
+ public Component Component {
+ get { return component; }
+ }
+ }
+
+ public class ComponentNameEventArgs: ComponentEventArgs
+ {
+ string oldName;
+
+ internal ComponentNameEventArgs (Project p, Component c, string oldName): base (p, c)
+ {
+ this.oldName = oldName;
+ }
+
+ public string OldName {
+ get { return oldName; }
+ }
+
+ public string NewName {
+ get { return Component.Name; }
+ }
+ }
+
+ public class ComponentRemovedEventArgs: EventArgs
+ {
+ Project project;
+ string componentName;
+
+ internal ComponentRemovedEventArgs (Project p, string name)
+ {
+ project = p;
+ componentName = name;
+ }
+
+ public Project Project {
+ get { return project; }
+ }
+
+ public string ComponentName {
+ get { return componentName; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentSignalEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentSignalEventHandler.cs
new file mode 100644
index 0000000000..07c6263a71
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentSignalEventHandler.cs
@@ -0,0 +1,27 @@
+
+using System;
+
+namespace Stetic
+{
+ public delegate void ComponentSignalEventHandler (object sender, ComponentSignalEventArgs args);
+
+ public class ComponentSignalEventArgs: ComponentEventArgs
+ {
+ public Signal oldSignal;
+ public Signal signal;
+
+ public ComponentSignalEventArgs (Project p, Component c, Signal oldSignal, Signal signal): base (p, c)
+ {
+ this.oldSignal = oldSignal;
+ this.signal = signal;
+ }
+
+ public Signal Signal {
+ get { return signal; }
+ }
+
+ public Signal OldSignal {
+ get { return oldSignal; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentType.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentType.cs
new file mode 100644
index 0000000000..47ed725282
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ComponentType.cs
@@ -0,0 +1,94 @@
+
+using System;
+
+namespace Stetic
+{
+ public class ComponentType
+ {
+ Application app;
+ string name;
+ string description;
+ string className;
+ string category;
+ Gdk.Pixbuf icon;
+ ActionComponent action;
+ string targetGtkVersion;
+ string library;
+ static ComponentType unknown;
+
+ internal ComponentType (Application app, string name, string desc, string className, string category, string targetGtkVersion, string library, Gdk.Pixbuf icon)
+ {
+ this.app = app;
+ this.name = name;
+ this.description = desc;
+ this.icon = icon;
+ this.className = className;
+ this.category = category;
+ this.targetGtkVersion = targetGtkVersion;
+ this.library = library;
+ }
+
+ internal ComponentType (Application app, ActionComponent action)
+ {
+ this.action = action;
+ this.app = app;
+ this.name = action.Name;
+ this.description = action.Label != null ? action.Label.Replace ("_", "") : action.Name;
+ this.icon = action.Icon;
+ this.className = "Gtk.Action";
+ this.category = "Actions / " + action.ActionGroup.Name;
+ this.targetGtkVersion = "2.4"; // Not version-specific
+ }
+
+ public string Name {
+ get { return name; }
+ }
+
+ public string ClassName {
+ get { return className; }
+ }
+
+ public string Category {
+ get { return category; }
+ }
+
+ public string Description {
+ get { return description; }
+ }
+
+ public string Library {
+ get { return library; }
+ }
+
+ public Gdk.Pixbuf Icon {
+ get { return icon; }
+ }
+
+ internal ActionComponent Action {
+ get { return action; }
+ }
+
+ internal static ComponentType Unknown {
+ get {
+ if (unknown == null) {
+ unknown = new ComponentType (null, "Unknown", "Unknown", "", "", "2.4", null, WidgetUtils.MissingIcon);
+ }
+ return unknown;
+ }
+ }
+
+ public object[] InitializationValues {
+ get {
+ if (app == null)
+ return new object [0];
+ return app.Backend.GetClassDescriptorInitializationValues (name);
+ }
+ }
+
+ public string TargetGtkVersion {
+ get {
+ return targetGtkVersion;
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContainerUndoRedoManager.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContainerUndoRedoManager.cs
new file mode 100644
index 0000000000..ddfe62d2e7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContainerUndoRedoManager.cs
@@ -0,0 +1,18 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+
+namespace Stetic
+{
+ class ContainerUndoRedoManager: UndoRedoManager
+ {
+ protected override object GetDiff (ObjectWrapper w)
+ {
+ // Only track changes in widgets.
+ Wrapper.Widget widget = w as Wrapper.Widget;
+ if (widget != null) return w.GetUndoDiff ();
+ else return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContextMenu.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContextMenu.cs
new file mode 100644
index 0000000000..3b64a286f5
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ContextMenu.cs
@@ -0,0 +1,174 @@
+using Gtk;
+using System;
+using System.Collections;
+using System.Reflection;
+using Mono.Unix;
+
+namespace Stetic {
+
+ class ContextMenu : Gtk.Menu {
+
+ Gtk.Widget widget;
+ IEditableObject editable;
+
+ public ContextMenu (Placeholder ph)
+ {
+ MenuItem item;
+
+ editable = ph;
+ this.widget = ph;
+
+ item = LabelItem (ph);
+ item.Sensitive = false;
+ Add (item);
+
+ item = new MenuItem (Catalog.GetString ("_Select"));
+ item.Sensitive = false;
+ Add (item);
+
+ BuildContextMenu (Stetic.Wrapper.Container.LookupParent (ph), true, ph);
+ }
+
+ public ContextMenu (Stetic.Wrapper.Widget wrapper) : this (wrapper, wrapper.Wrapped) {}
+
+ public ContextMenu (Stetic.Wrapper.Widget wrapper, Gtk.Widget context)
+ {
+ MenuItem item;
+
+ editable = wrapper;
+ widget = wrapper.Wrapped;
+
+ if (widget == context) {
+ item = LabelItem (widget);
+ item.Sensitive = false;
+ Add (item);
+ }
+
+ item = new MenuItem (Catalog.GetString ("_Select"));
+ item.Activated += DoSelect;
+ Add (item);
+
+ ClassDescriptor klass = wrapper.ClassDescriptor;
+ if (klass != null) {
+ foreach (ItemDescriptor id in klass.ContextMenu) {
+ CommandDescriptor cmd = (CommandDescriptor)id;
+ if (!cmd.VisibleFor (widget))
+ continue;
+ item = new MenuItem (cmd.Label);
+ if (cmd.Enabled (widget, context)) {
+ Gtk.Widget wdup = widget, cdup = context; // FIXME bxc 75689
+ item.Activated += delegate (object o, EventArgs args) {
+ cmd.Run (wdup, cdup);
+ };
+ } else
+ item.Sensitive = false;
+ Add (item);
+ }
+ }
+
+ BuildContextMenu (wrapper.ParentWrapper, widget == context, context);
+ }
+
+ void BuildContextMenu (Stetic.Wrapper.Widget parentWrapper, bool top, Widget context)
+ {
+ MenuItem item;
+
+ item = new ImageMenuItem (Gtk.Stock.Cut, null);
+ if (editable.CanCut)
+ item.Activated += DoCut;
+ else
+ item.Sensitive = false;
+ Add (item);
+
+ item = new ImageMenuItem (Gtk.Stock.Copy, null);
+ if (editable.CanCopy)
+ item.Activated += DoCopy;
+ else
+ item.Sensitive = false;
+ Add (item);
+
+ item = new ImageMenuItem (Gtk.Stock.Paste, null);
+ if (editable.CanPaste)
+ item.Activated += DoPaste;
+ else
+ item.Sensitive = false;
+ Add (item);
+
+ if (editable.CanDelete) {
+ item = new ImageMenuItem (Gtk.Stock.Delete, null);
+ item.Activated += DoDelete;
+ Add (item);
+ }
+
+ if (top) {
+ for (; parentWrapper != null; parentWrapper = parentWrapper.ParentWrapper) {
+ Add (new SeparatorMenuItem ());
+
+ item = LabelItem (parentWrapper.Wrapped);
+ item.Submenu = new ContextMenu (parentWrapper, context);
+ Add (item);
+ }
+ }
+
+ ShowAll ();
+ }
+
+ protected override void OnSelectionDone ()
+ {
+ Destroy ();
+ }
+
+ void DoSelect (object obj, EventArgs args)
+ {
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+ if (wrapper != null)
+ wrapper.Select ();
+ }
+
+ void DoCut (object obj, EventArgs args)
+ {
+ editable.Cut ();
+ }
+
+ void DoCopy (object obj, EventArgs args)
+ {
+ editable.Copy ();
+ }
+
+ void DoPaste (object obj, EventArgs args)
+ {
+ editable.Paste ();
+ }
+
+ void DoDelete (object obj, EventArgs args)
+ {
+ editable.Delete ();
+ }
+
+ static MenuItem LabelItem (Gtk.Widget widget)
+ {
+ ImageMenuItem item;
+ Label label;
+
+ label = new Label (widget is Placeholder ? Catalog.GetString ("Placeholder") : widget.Name);
+ label.UseUnderline = false;
+ label.SetAlignment (0.0f, 0.5f);
+ item = new ImageMenuItem ();
+ item.Add (label);
+
+ Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+
+ if (wrapper != null) {
+ ClassDescriptor klass = wrapper.ClassDescriptor;
+ if (klass != null) {
+ Gdk.Pixbuf pixbuf = klass.Icon;
+ int width, height;
+ Gtk.Icon.SizeLookup (Gtk.IconSize.Menu, out width, out height);
+ item.Image = new Gtk.Image (pixbuf.ScaleSimple (width, height, Gdk.InterpType.Bilinear));
+ }
+ }
+
+ return item;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Designer.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Designer.cs
new file mode 100644
index 0000000000..21aaf500c7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Designer.cs
@@ -0,0 +1,44 @@
+// Designer.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (c) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+using System;
+
+namespace Stetic
+{
+ public abstract class Designer: PluggableWidget
+ {
+ protected Designer (Application app): base (app)
+ {
+ }
+
+ internal virtual void SetActive ()
+ {
+ }
+
+ public abstract ProjectItemInfo ProjectItem { get; }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Glade.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Glade.cs
new file mode 100644
index 0000000000..4fcd4ff76a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Glade.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Xml;
+using System.Collections;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using Mono.Unix;
+
+using Gtk;
+
+namespace Stetic {
+
+ internal static class GladeFiles {
+
+ public static void Import (ProjectBackend project, string filename)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+ doc.XmlResolver = null;
+ doc.Load (filename);
+ project.Id = System.IO.Path.GetFileName (filename);
+ doc = GladeUtils.XslImportTransform (doc);
+
+ XmlNode node = doc.SelectSingleNode ("/glade-interface");
+ if (node == null)
+ throw new ApplicationException (Catalog.GetString ("Not a glade file according to node name."));
+
+ ObjectReader reader = new ObjectReader (project, FileFormat.Glade);
+ foreach (XmlElement toplevel in node.SelectNodes ("widget")) {
+ Wrapper.Container wrapper = Stetic.ObjectWrapper.ReadObject (reader, toplevel, null) as Wrapper.Container;
+ if (wrapper != null)
+ project.AddWidget ((Gtk.Widget)wrapper.Wrapped);
+ }
+ }
+
+ public static void Export (ProjectBackend project, string filename)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+
+ XmlElement toplevel = doc.CreateElement ("glade-interface");
+ doc.AppendChild (toplevel);
+
+ ObjectWriter owriter = new ObjectWriter (doc, FileFormat.Glade);
+ foreach (Widget w in project.Toplevels) {
+ Stetic.Wrapper.Container wrapper = Stetic.Wrapper.Container.Lookup (w);
+ if (wrapper == null)
+ continue;
+
+ XmlElement elem = wrapper.Write (owriter);
+ if (elem != null)
+ toplevel.AppendChild (elem);
+ }
+
+ doc = GladeUtils.XslExportTransform (doc);
+
+ // FIXME; if you use UTF8, it starts with a BOM???
+ XmlTextWriter writer = new XmlTextWriter (filename, System.Text.Encoding.ASCII);
+ writer.Formatting = Formatting.Indented;
+ doc.Save (writer);
+ writer.Close ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Grid.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Grid.cs
new file mode 100644
index 0000000000..5f82fd0253
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Grid.cs
@@ -0,0 +1,347 @@
+using Gtk;
+using System;
+using System.Collections;
+
+namespace Stetic {
+
+ internal class Grid : Gtk.Container {
+
+ public Grid () : base ()
+ {
+ BorderWidth = 2;
+ WidgetFlags |= WidgetFlags.NoWindow;
+ lines = new ArrayList ();
+ group = null;
+ }
+
+ // Padding constants
+ const int groupPad = 6;
+ const int hPad = 6;
+ const int linePad = 3;
+
+ // Theme-based sizes; computed at first SizeRequest
+ static int indent = -1;
+ static int lineHeight = -1;
+
+ Grid[] group;
+ public static void Connect (params Grid[] grids)
+ {
+ for (int i = 0; i < grids.Length; i++) {
+ grids[i].group = new Grid[grids.Length - 1];
+ Array.Copy (grids, 0, grids[i].group, 0, i);
+ Array.Copy (grids, i + 1, grids[i].group, i, grids.Length - i - 1);
+ }
+ }
+
+ class Pair {
+ Gtk.Widget label;
+ Gtk.Widget editor;
+
+ public Pair (Grid grid, string name, Widget editor) : this (grid, name, editor, null) {}
+
+ public Pair (Grid grid, string name, Widget editor, string description)
+ {
+ Gtk.Label l = new Label (name);
+ l.UseMarkup = true;
+ l.Justify = Justification.Left;
+ l.Xalign = 0;
+ l.Show ();
+
+ if (description == null)
+ label = l;
+ else {
+ Gtk.EventBox ebox = new Gtk.EventBox ();
+ ebox.Add (l);
+ ebox.Show ();
+ ebox.TooltipText = description;
+ label = ebox;
+ }
+ label.Parent = grid;
+
+ this.editor = editor;
+ editor.Parent = grid;
+ editor.Show ();
+ }
+
+ public Widget Label {
+ get {
+ return label;
+ }
+ }
+
+ public Widget Editor {
+ get {
+ return editor;
+ }
+ }
+ }
+
+ // list of widgets and Stetic.Grid.Pairs
+ ArrayList lines;
+
+ public void Append (Widget w)
+ {
+ w.Parent = this;
+ w.Show ();
+
+ lines.Add (w);
+ QueueDraw ();
+ }
+
+ public void Append (Widget w, string description)
+ {
+ if ((w.WidgetFlags & WidgetFlags.NoWindow) != 0) {
+ Gtk.EventBox ebox = new Gtk.EventBox ();
+ ebox.Add (w);
+ ebox.Show ();
+ w = ebox;
+ }
+ w.Parent = this;
+ w.Show ();
+ w.TooltipText = description;
+ lines.Add (w);
+ QueueDraw ();
+ }
+
+ public void AppendLabel (string text)
+ {
+ Gtk.Label label = new Label (text);
+ label.UseMarkup = true;
+ label.Justify = Justification.Left;
+ label.Xalign = 0;
+ Append (label);
+ }
+
+ public void AppendGroup (string name, bool expanded)
+ {
+ Gtk.Expander exp = new Expander ("<b>" + name + "</b>");
+ exp.UseMarkup = true;
+ exp.Expanded = expanded;
+ exp.AddNotification ("expanded", ExpansionChanged);
+ Append (exp);
+ }
+
+ public void AppendPair (string label, Widget editor, string description)
+ {
+ Stetic.Grid.Pair pair = new Pair (this, label, editor, description);
+ lines.Add (pair);
+ QueueDraw ();
+ }
+
+ protected override void OnRemoved (Widget w)
+ {
+ w.Unparent ();
+ }
+
+ void ExpansionChanged (object obj, GLib.NotifyArgs args)
+ {
+ Gtk.Expander exp = obj as Gtk.Expander;
+
+ int ind = lines.IndexOf (exp);
+ if (ind == -1)
+ return;
+
+ ind++;
+ while (ind < lines.Count && !(lines[ind] is Gtk.Expander)) {
+ if (lines[ind] is Widget) {
+ Widget w = (Widget)lines[ind];
+ if (exp.Expanded)
+ w.Show ();
+ else
+ w.Hide ();
+ } else if (lines[ind] is Pair) {
+ Pair p = (Pair)lines[ind];
+ if (exp.Expanded) {
+ p.Label.Show ();
+ p.Editor.Show ();
+ } else {
+ p.Label.Hide ();
+ p.Editor.Hide ();
+ }
+ }
+ ind++;
+ }
+
+ QueueDraw ();
+ }
+
+ protected void Clear ()
+ {
+ foreach (object obj in lines) {
+ if (obj is Widget)
+ ((Widget)obj).Destroy ();
+ else if (obj is Pair) {
+ Pair p = (Pair)obj;
+ p.Label.Destroy ();
+ p.Editor.Destroy ();
+ }
+ }
+
+ lines.Clear ();
+ }
+
+ protected override void ForAll (bool include_internals, Gtk.Callback callback)
+ {
+ if (!include_internals)
+ return;
+
+ foreach (object obj in lines) {
+ if (obj is Widget)
+ callback ((Widget)obj);
+ else if (obj is Pair) {
+ Pair p = (Pair)obj;
+ callback (p.Label);
+ callback (p.Editor);
+ }
+ }
+ }
+
+ // These are figured out at requisition time and used again at
+ // allocation time.
+ int lwidth, ewidth;
+
+ void SizeRequestGrid (Grid grid, ref Gtk.Requisition req)
+ {
+ bool visible = true;
+
+ req.Width = req.Height = 0;
+ foreach (object obj in grid.lines) {
+ if (obj is Expander) {
+ Gtk.Widget w = (Gtk.Widget)obj;
+ Gtk.Requisition childreq;
+
+ childreq = w.SizeRequest ();
+ if (req.Width < childreq.Width)
+ req.Width = childreq.Width;
+ req.Height += groupPad + childreq.Height;
+
+ visible = ((Gtk.Expander)obj).Expanded;
+
+ if (indent == -1) {
+ // Seems like there should be an easier way...
+ int focusWidth = (int)w.StyleGetProperty ("focus-line-width");
+ int focusPad = (int)w.StyleGetProperty ("focus-padding");
+ int expanderSize = (int)w.StyleGetProperty ("expander-size");
+ int expanderSpacing = (int)w.StyleGetProperty ("expander-spacing");
+ indent = focusWidth + focusPad + expanderSize + 2 * expanderSpacing;
+ }
+ } else if (obj is Widget) {
+ Gtk.Widget w = (Gtk.Widget)obj;
+ Gtk.Requisition childreq;
+
+ childreq = w.SizeRequest ();
+ if (lwidth < childreq.Width)
+ lwidth = childreq.Width;
+ if (visible)
+ req.Height += linePad + childreq.Height;
+ } else if (obj is Pair) {
+ Pair p = (Pair)obj;
+ Gtk.Requisition lreq, ereq;
+
+ lreq = p.Label.SizeRequest ();
+ ereq = p.Editor.SizeRequest ();
+
+ if (lineHeight == -1)
+ lineHeight = (int)(1.5 * lreq.Height);
+
+ if (lreq.Width > lwidth)
+ lwidth = lreq.Width;
+ if (ereq.Width > ewidth)
+ ewidth = ereq.Width;
+
+ if (visible)
+ req.Height += Math.Max (lineHeight, ereq.Height) + linePad;
+ }
+ }
+
+ req.Width = Math.Max (req.Width, indent + lwidth + hPad + ewidth);
+ req.Height += 2 * (int)BorderWidth;
+ req.Width += 2 * (int)BorderWidth;
+ }
+
+ protected override void OnSizeRequested (ref Gtk.Requisition req)
+ {
+ lwidth = ewidth = 0;
+
+ if (group != null) {
+ foreach (Grid grid in group)
+ SizeRequestGrid (grid, ref req);
+ }
+
+ SizeRequestGrid (this, ref req);
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle alloc)
+ {
+ int xbase = alloc.X + (int)BorderWidth;
+ int ybase = alloc.Y + (int)BorderWidth;
+
+ base.OnSizeAllocated (alloc);
+
+ int y = ybase;
+ bool visible = true;
+
+ foreach (object obj in lines) {
+ if (!visible && !(obj is Expander))
+ continue;
+
+ if (obj is Widget) {
+ Gtk.Widget w = (Gtk.Widget)obj;
+ if (!w.Visible)
+ continue;
+
+ Gdk.Rectangle childalloc;
+ Gtk.Requisition childreq;
+
+ childreq = w.ChildRequisition;
+
+ if (obj is Expander) {
+ childalloc.X = xbase;
+ childalloc.Width = alloc.Width - 2 * (int)BorderWidth;
+ visible = ((Gtk.Expander)obj).Expanded;
+ y += groupPad;
+ } else {
+ childalloc.X = xbase + indent;
+ childalloc.Width = lwidth;
+ y += linePad;
+ }
+ childalloc.Y = y;
+ childalloc.Height = childreq.Height;
+ w.SizeAllocate (childalloc);
+
+ y += childalloc.Height;
+ } else if (obj is Pair) {
+ Pair p = (Pair)obj;
+ if (!p.Editor.Visible) {
+ p.Label.Hide ();
+ continue;
+ } else if (!p.Label.Visible)
+ p.Label.Show ();
+
+ Gtk.Requisition lreq, ereq;
+ Gdk.Rectangle lalloc, ealloc;
+
+ lreq = p.Label.ChildRequisition;
+ ereq = p.Editor.ChildRequisition;
+
+ lalloc.X = xbase + indent;
+ if (ereq.Height < lineHeight * 2)
+ lalloc.Y = y + (ereq.Height - lreq.Height) / 2;
+ else
+ lalloc.Y = y + (lineHeight - lreq.Height) / 2;
+ lalloc.Width = lwidth;
+ lalloc.Height = lreq.Height;
+ p.Label.SizeAllocate (lalloc);
+
+ ealloc.X = lalloc.X + lwidth + hPad;
+ ealloc.Y = y + Math.Max (0, (lineHeight - ereq.Height) / 2);
+ ealloc.Width = Math.Max (ewidth, alloc.Width - 2 * (int)BorderWidth - ealloc.X);
+ ealloc.Height = ereq.Height;
+ p.Editor.SizeAllocate (ealloc);
+
+ y += Math.Max (ereq.Height, lineHeight) + linePad;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSink.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSink.cs
new file mode 100644
index 0000000000..e1262948e4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSink.cs
@@ -0,0 +1,142 @@
+
+using System;
+using System.Threading;
+using System.IO;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Channels;
+using System.Runtime.Remoting.Messaging;
+using System.Collections;
+
+namespace Stetic
+{
+ public class GuiDispatchServerSink: IServerChannelSink, IChannelSinkBase
+ {
+ IServerChannelSink nextSink;
+
+ public GuiDispatchServerSink (IServerChannelSink nextSink, IChannelReceiver receiver)
+ {
+ this.nextSink = nextSink;
+ }
+
+ public IServerChannelSink NextChannelSink {
+ get { return nextSink; }
+ }
+
+ public IDictionary Properties {
+ get { return null; }
+ }
+
+ public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
+ IMessage msg, ITransportHeaders headers, Stream stream)
+
+ {
+ sinkStack.AsyncProcessResponse (msg, headers, stream);
+ }
+
+ public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
+ IMessage msg, ITransportHeaders headers)
+ {
+ // this method shouldn't be called
+ throw new NotSupportedException ();
+ }
+
+ public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
+ IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream,
+ out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
+ {
+ IMethodCallMessage msg = (IMethodCallMessage) requestMsg;
+// Console.WriteLine ("MESSAGE: " + msg.TypeName + " - " + msg.MethodName);
+
+ sinkStack.Push (this, null);
+
+ if (Attribute.IsDefined (msg.MethodBase, typeof(NoGuiDispatchAttribute))) {
+ ServerProcessing ret;
+ try {
+ ret = nextSink.ProcessMessage (sinkStack,
+ requestMsg,
+ requestHeaders,
+ requestStream,
+ out responseMsg,
+ out responseHeaders,
+ out responseStream);
+ } finally {
+ sinkStack.Pop (this);
+ }
+ return ret;
+ }
+ else
+ {
+ Dispatcher d = new Dispatcher ();
+ d.nextSink = nextSink;
+ d.sinkStack = sinkStack;
+ d.requestMsg = requestMsg;
+ d.requestHeaders = requestHeaders;
+ d.requestStream = requestStream;
+
+ Gtk.Application.Invoke (d.Dispatch);
+ responseMsg = null;
+ responseHeaders = null;
+ responseStream = null;
+
+ return ServerProcessing.Async;
+ }
+ }
+
+ class Dispatcher
+ {
+ public IServerChannelSink nextSink;
+
+ public IServerChannelSinkStack sinkStack;
+ public IMessage requestMsg;
+ public ITransportHeaders requestHeaders;
+ public Stream requestStream;
+
+ public void Dispatch (object o, EventArgs a)
+ {
+ IMessage responseMsg;
+ ITransportHeaders responseHeaders = null;
+ Stream responseStream = null;
+
+ try {
+ nextSink.ProcessMessage (sinkStack,
+ requestMsg,
+ requestHeaders,
+ requestStream,
+ out responseMsg,
+ out responseHeaders,
+ out responseStream);
+ }
+ catch (Exception ex) {
+ responseMsg = new ReturnMessage (ex, (IMethodCallMessage)requestMsg);
+ }
+
+ sinkStack.AsyncProcessResponse (responseMsg, responseHeaders, responseStream);
+ }
+ }
+ }
+
+ class GuiDispatch
+ {
+ public static void InvokeSync (EventHandler h)
+ {
+ if (GLib.MainContext.Depth > 0)
+ h (null, null);
+ else {
+ object wo = new object ();
+ lock (wo) {
+ Gtk.Application.Invoke (delegate {
+ try {
+ h (null, null);
+ } finally {
+ lock (wo) {
+ System.Threading.Monitor.PulseAll (wo);
+ }
+ }
+ });
+ System.Threading.Monitor.Wait (wo);
+ }
+ }
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSinkProvider.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSinkProvider.cs
new file mode 100644
index 0000000000..d35c2b3950
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/GuiDispatchServerSinkProvider.cs
@@ -0,0 +1,30 @@
+
+using System;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Channels;
+
+namespace Stetic
+{
+ public class GuiDispatchServerSinkProvider: IServerFormatterSinkProvider, IServerChannelSinkProvider
+ {
+ private IServerChannelSinkProvider next;
+
+ public IServerChannelSinkProvider Next {
+ get { return next; }
+ set { next = value; }
+ }
+
+ public IServerChannelSink CreateSink (IChannelReceiver channel)
+ {
+ IServerChannelSink chain = next.CreateSink (channel);
+ GuiDispatchServerSink sink = new GuiDispatchServerSink (chain, channel);
+ return sink;
+ }
+
+ public void GetChannelData (IChannelDataStore channelData)
+ {
+ if(next != null)
+ next.GetChannelData(channelData);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/IProjectDesignInfo.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/IProjectDesignInfo.cs
new file mode 100644
index 0000000000..903850429a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/IProjectDesignInfo.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Stetic
+{
+ //Provides access to informations managed by ide
+ public interface IProjectDesignInfo
+ {
+ //Returns component source file for given component
+ string GetComponentFile (string componentName);
+ bool HasComponentFile (string componentFile);
+
+ //Returns gtkx file name for given component file
+ string GetDesignerFileFromComponent (string componentFile);
+
+ //Search for all components source file folders
+ string[] GetComponentFolders ();
+
+ // Checks if code generation for a component is needed
+ bool ComponentNeedsCodeGeneration (string componentName);
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/LibraryCache.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/LibraryCache.cs
new file mode 100644
index 0000000000..93301495a3
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/LibraryCache.cs
@@ -0,0 +1,793 @@
+// LibraryCache.cs : Assembly file caching class
+//
+// Author: Mike Kestner <mkestner@novell.com>
+//
+// Copyright (c) 2008 Novell, Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+using ENV = System.Environment;
+using Mono.Cecil;
+
+namespace Stetic {
+
+ public class LibraryCache {
+
+ public class LibraryInfo {
+
+ public LibraryInfo () {}
+
+ string file;
+ Guid guid;
+ DateTime timestamp;
+ XmlDocument gui;
+ XmlDocument objects;
+
+ string CacheDirectory {
+ get { return Path.Combine (dir, Guid.ToString ()); }
+ }
+
+ [XmlAttribute]
+ public string File {
+ get { return file; }
+ set { file = value; }
+ }
+
+ [XmlAttribute]
+ public Guid Guid {
+ get { return guid; }
+ set {
+ string path = Path.Combine (dir, guid.ToString ());
+ if (Directory.Exists (path))
+ Directory.Delete (path, true);
+ guid = value;
+ }
+ }
+
+ public bool IsCurrent {
+ get {
+ return Timestamp == System.IO.File.GetLastWriteTime (file).ToUniversalTime ();
+ }
+ }
+
+ [XmlIgnore]
+ public XmlDocument GuiDocument {
+ get {
+ if (gui == null) {
+ if (System.IO.File.Exists (GuiPath)) {
+ try {
+ gui = new XmlDocument ();
+ using (Stream stream = System.IO.File.Open (GuiPath, FileMode.Open))
+ gui.Load (stream);
+ } catch (Exception) {
+ gui = null;
+ }
+ }
+ }
+ return gui;
+ }
+ set {
+ gui = value;
+ WriteGuiFile ();
+ }
+ }
+
+ string GuiPath {
+ get { return Path.Combine (CacheDirectory, "steticGui"); }
+ }
+
+ public bool HasWidgets {
+ get { return System.IO.File.Exists (ObjectsPath); }
+ }
+
+ [XmlIgnore]
+ public XmlDocument ObjectsDocument {
+ get {
+ if (objects == null) {
+ if (System.IO.File.Exists (ObjectsPath)) {
+ try {
+ objects = new XmlDocument ();
+ using (Stream stream = System.IO.File.Open (ObjectsPath, FileMode.Open))
+ objects.Load (stream);
+ } catch (Exception) {
+ objects = null;
+ }
+ }
+ }
+ return objects;
+ }
+ set {
+ objects = value;
+ WriteObjectsFile ();
+ if (objects == null && gui != null)
+ GuiDocument = null;
+ }
+ }
+
+ internal ToolboxItemInfo GetToolboxItem (string name, string asmName)
+ {
+ XmlDocument doc = ObjectsDocument;
+ if (doc != null) {
+ XmlElement elem = (XmlElement) doc.SelectSingleNode ("/objects/object[@type='" + name + "']");
+ if (elem == null)
+ elem = (XmlElement) doc.SelectSingleNode ("/objects/object[@type='" + name + "," + asmName + "']");
+ if (elem != null) {
+ ToolboxItemInfo info = new ToolboxItemInfo (elem.GetAttribute ("base-type"));
+ info.PaletteCategory = elem.GetAttribute ("palette-category");
+ return info;
+ }
+
+ }
+ return null;
+ }
+
+ string ObjectsPath {
+ get { return Path.Combine (CacheDirectory, "objects"); }
+ }
+
+ [XmlAttribute]
+ public DateTime Timestamp {
+ get { return timestamp; }
+ set { timestamp = value; }
+ }
+
+ void WriteGuiFile ()
+ {
+ if (gui == null) {
+ if (System.IO.File.Exists (GuiPath))
+ System.IO.File.Delete (GuiPath);
+ return;
+ }
+ if (!Directory.Exists (CacheDirectory))
+ Directory.CreateDirectory (CacheDirectory);
+
+ using (Stream stream = System.IO.File.Create (GuiPath))
+ gui.Save (stream);
+ }
+
+ public void WriteObjectsFile ()
+ {
+ if (objects == null) {
+ if (System.IO.File.Exists (ObjectsPath))
+ System.IO.File.Delete (ObjectsPath);
+ return;
+ }
+
+ if (!Directory.Exists (CacheDirectory))
+ Directory.CreateDirectory (CacheDirectory);
+
+ using (Stream stream = System.IO.File.Create (ObjectsPath))
+ objects.Save (stream);
+ }
+
+ public event EventHandler Changed;
+
+ public void OnChanged ()
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+ }
+
+ static string dir = Path.Combine (Path.Combine (ENV.GetFolderPath (ENV.SpecialFolder.ApplicationData), "stetic"), "library-cache");
+
+ public class LibraryInfoCollection : IEnumerable {
+
+ Dictionary<string, LibraryInfo> libs = new Dictionary<string, LibraryInfo> ();
+
+ public LibraryInfo this [string path] {
+ get {
+ path = Path.GetFullPath (path);
+ if (libs.ContainsKey (path))
+ return libs [path];
+ return null;
+ }
+ }
+
+ public void Add (object obj)
+ {
+ Add (obj as LibraryInfo);
+ }
+
+ public void Add (LibraryInfo info)
+ {
+ libs [info.File] = info;
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return libs.Values.GetEnumerator ();
+ }
+
+ public void Remove (string file)
+ {
+ file = Path.GetFullPath (file);
+ libs.Remove (file);
+ }
+ }
+
+ public static LibraryCache Cache = Load ();
+
+ [XmlArray]
+ [XmlArrayItem (ElementName="LibraryInfo", Type=typeof(LibraryInfo))]
+ public LibraryInfoCollection Members = new LibraryInfoCollection ();
+
+ public LibraryCache () {}
+
+ public LibraryInfo this [string file] {
+ get {
+ file = Path.GetFullPath (file);
+ if (IsCurrent (file))
+ return Members [file];
+
+ Refresh (null, file);
+ return Members [file];
+ }
+ }
+
+ public bool IsCurrent (string file)
+ {
+ file = Path.GetFullPath (file);
+ LibraryInfo info = Members [file];
+ return info != null && info.Timestamp == File.GetLastWriteTime (file).ToUniversalTime ();
+ }
+
+ EmbeddedResource GetResource (AssemblyDefinition asm, string name)
+ {
+ foreach (Resource res in asm.MainModule.Resources) {
+ EmbeddedResource eres = res as EmbeddedResource;
+ if (eres != null && eres.Name == name)
+ return eres;
+ }
+ return null;
+ }
+
+ void AddDependencies (XmlElement elem, AssemblyResolver resolver, string filename, AssemblyDefinition asm)
+ {
+ string dir = Path.GetDirectoryName (filename);
+ foreach (AssemblyNameReference aref in asm.MainModule.AssemblyReferences) {
+ LibraryInfo info = GetInfo (resolver, aref.FullName, dir);
+ if (info != null && info.HasWidgets) {
+ XmlElement edep = elem.OwnerDocument.CreateElement ("dependency");
+ edep.InnerText = info.File;
+ elem.AppendChild (edep);
+ }
+ }
+ }
+
+ XmlDocument GetGuiDoc (AssemblyDefinition adef)
+ {
+ XmlDocument doc = null;
+ try {
+ EmbeddedResource res = GetResource (adef, "gui.stetic");
+ if (res != null) {
+ MemoryStream stream = new MemoryStream (res.Data);
+ doc = new XmlDocument ();
+ using (stream)
+ doc.Load (stream);
+ }
+ } catch {
+ doc = null;
+ }
+
+ return doc;
+ }
+
+ bool ReferenceChainContainsGtk (AssemblyResolver resolver, AssemblyNameReference aref, Hashtable visited)
+ {
+ if (aref.Name == "gtk-sharp")
+ return true;
+ else if (visited.Contains (aref.Name))
+ return false;
+
+ visited [aref.Name] = aref;
+
+ AssemblyDefinition adef = resolver.Resolve (aref);
+ if (adef == null)
+ return false;
+
+ foreach (AssemblyNameReference child in adef.MainModule.AssemblyReferences)
+ if (ReferenceChainContainsGtk (resolver, child, visited))
+ return true;
+
+ return false;
+ }
+
+ internal class ToolboxItemInfo {
+
+ public ToolboxItemInfo (string base_type)
+ {
+ BaseType = base_type;
+ }
+
+ public string BaseType;
+ public string PaletteCategory;
+ }
+
+ ToolboxItemInfo GetToolboxItemInfo (AssemblyResolver resolver, string baseDirectory, AssemblyDefinition asm, TypeDefinition tdef, bool checkBaseType)
+ {
+ if (tdef == null)
+ return null;
+
+ ToolboxItemInfo info = null;
+ string category = "General";
+
+ foreach (CustomAttribute attr in tdef.CustomAttributes) {
+ switch (attr.Constructor.DeclaringType.FullName) {
+ case "System.ComponentModel.ToolboxItemAttribute":
+ try {
+ attr.Resolve ();
+ } catch {
+ // Ignore
+ return null;
+ }
+ if (attr.ConstructorParameters.Count > 0) {
+ object param = attr.ConstructorParameters [0];
+ if (param == null)
+ return null;
+ else if (param.GetType () == typeof (bool)) {
+ if ((bool) param)
+ info = new ToolboxItemInfo ("Gtk.Widget");
+ else
+ return null;
+ } else if (param.GetType () == typeof (System.Type))
+ info = new ToolboxItemInfo ("Gtk.Widget");
+ else
+ return null;
+ }
+ break;
+ case "System.ComponentModel.CategoryAttribute":
+ try {
+ attr.Resolve ();
+ } catch {
+ // Ignore
+ return null;
+ }
+ if (attr.ConstructorParameters.Count > 0) {
+ object param = attr.ConstructorParameters [0];
+ if (param.GetType () == typeof (string))
+ category = (string) param;
+ }
+ break;
+ default:
+ continue;
+ }
+ }
+
+ if (info == null && checkBaseType && tdef.BaseType != null) {
+ string baseName = tdef.BaseType.FullName;
+
+ foreach (AssemblyNameReference aref in asm.MainModule.AssemblyReferences) {
+ LibraryInfo libInfo = GetInfo (resolver, aref.FullName, baseDirectory);
+ if (libInfo != null && libInfo.HasWidgets) {
+ ToolboxItemInfo binfo = libInfo.GetToolboxItem (baseName, aref.Name);
+ if (binfo != null) {
+ info = new ToolboxItemInfo (baseName);
+ category = binfo.PaletteCategory;
+ break;
+ }
+ }
+ }
+ }
+
+ if (info != null)
+ info.PaletteCategory = category;
+
+ return info;
+ }
+
+ XmlElement GetItemGroup (XmlElement groups, string cat, string default_label)
+ {
+ XmlElement group;
+
+ if (String.IsNullOrEmpty (cat))
+ group = (XmlElement) groups.SelectSingleNode ("itemgroup[(not(@name) or @name='') and not(@ref)]");
+ else
+ group = (XmlElement) groups.SelectSingleNode ("itemgroup[@name='" + cat + "']");
+
+ if (group == null) {
+ group = groups.OwnerDocument.CreateElement ("itemgroup");
+ if (String.IsNullOrEmpty (cat))
+ group.SetAttribute ("label", default_label);
+ else {
+ group.SetAttribute ("name", cat);
+ group.SetAttribute ("label", cat);
+ }
+ groups.AppendChild (group);
+ }
+ return group;
+ }
+
+ void AddProperty (PropertyDefinition prop, string cat, XmlElement obj)
+ {
+ XmlElement groups = obj ["itemgroups"];
+ if (groups == null) {
+ groups = obj.OwnerDocument.CreateElement ("itemgroups");
+ obj.AppendChild (groups);
+ }
+
+ XmlElement group = GetItemGroup (groups, cat, prop.DeclaringType.Name + " Properties");
+ XmlElement elem = group.OwnerDocument.CreateElement ("property");
+ elem.SetAttribute ("name", prop.Name);
+ group.AppendChild (elem);
+ }
+
+ static string[] supported_types = new string[] {
+ "System.Boolean",
+ "System.Char",
+ "System.SByte",
+ "System.Byte",
+ "System.Int16",
+ "System.UInt16",
+ "System.Int32",
+ "System.UInt32",
+ "System.Int64",
+ "System.UInt64",
+ "System.Decimal",
+ "System.Single",
+ "System.Double",
+ "System.DateTime",
+ "System.String",
+ "System.TimeSpan",
+ "Gtk.Adjustment",
+ };
+
+ void AddProperties (TypeDefinition tdef, XmlElement obj)
+ {
+ foreach (PropertyDefinition prop in tdef.Properties) {
+ if (prop.GetMethod == null || !prop.GetMethod.IsPublic || prop.SetMethod == null || !prop.SetMethod.IsPublic)
+ continue;
+ else if (Array.IndexOf (supported_types, prop.PropertyType.FullName) < 0)
+ continue;
+ bool browsable = true;
+ string category = String.Empty;
+ foreach (CustomAttribute attr in prop.CustomAttributes) {
+ switch (attr.Constructor.DeclaringType.FullName) {
+ case "System.ComponentModel.BrowsableAttribute":
+ attr.Resolve ();
+ if (attr.ConstructorParameters.Count > 0) {
+ object param = attr.ConstructorParameters [0];
+ if (param.GetType () == typeof (bool))
+ browsable = (bool) param;
+ }
+ break;
+ case "System.ComponentModel.CategoryAttribute":
+ attr.Resolve ();
+ if (attr.ConstructorParameters.Count > 0) {
+ object param = attr.ConstructorParameters [0];
+ if (param.GetType () == typeof (string))
+ category = (string) param;
+ }
+ break;
+ default:
+ continue;
+ }
+ if (!browsable)
+ break;
+ }
+ if (browsable)
+ AddProperty (prop, category, obj);
+ }
+ }
+
+ void AddEvent (EventDefinition ev, string cat, XmlElement obj)
+ {
+ XmlElement groups = obj ["signals"];
+ if (groups == null) {
+ groups = obj.OwnerDocument.CreateElement ("signals");
+ obj.AppendChild (groups);
+ }
+
+ XmlElement group = GetItemGroup (groups, cat, ev.DeclaringType.Name + " Signals");
+ XmlElement elem = group.OwnerDocument.CreateElement ("signal");
+ elem.SetAttribute ("name", ev.Name);
+ group.AppendChild (elem);
+ }
+
+ void AddEvents (TypeDefinition tdef, XmlElement obj)
+ {
+
+ foreach (EventDefinition ev in tdef.Events) {
+ if (ev.AddMethod == null || !ev.AddMethod.IsPublic)
+ continue;
+ bool browsable = true;
+ string category = String.Empty;
+ foreach (CustomAttribute attr in ev.CustomAttributes) {
+ switch (attr.Constructor.DeclaringType.FullName) {
+ case "System.ComponentModel.BrowsableAttribute":
+ attr.Resolve ();
+ if (attr.ConstructorParameters.Count > 0) {
+ object param = attr.ConstructorParameters [0];
+ if (param.GetType () == typeof (bool))
+ browsable = (bool) param;
+ }
+ break;
+ case "System.ComponentModel.CategoryAttribute":
+ attr.Resolve ();
+ if (attr.ConstructorParameters.Count > 0) {
+ object param = attr.ConstructorParameters [0];
+ if (param.GetType () == typeof (string))
+ category = (string) param;
+ }
+ break;
+ default:
+ continue;
+ }
+ if (!browsable)
+ break;
+ }
+ if (browsable)
+ AddEvent (ev, category, obj);
+ }
+ }
+
+ void AddObjects (XmlDocument doc, AssemblyResolver resolver, string basePath, AssemblyDefinition adef)
+ {
+ Dictionary<TypeDefinition,ToolboxItemInfo> localObjects = new Dictionary<TypeDefinition, ToolboxItemInfo> ();
+
+ foreach (TypeDefinition tdef in adef.MainModule.Types) {
+ if (tdef.IsAbstract || !tdef.IsClass)
+ continue;
+
+ ToolboxItemInfo tbinfo = GetToolboxItemInfo (resolver, basePath, adef, tdef, true);
+ if (tbinfo == null)
+ continue;
+
+ localObjects [tdef] = tbinfo;
+ }
+
+ foreach (KeyValuePair<TypeDefinition,ToolboxItemInfo> item in localObjects) {
+ TypeDefinition tdef = item.Key;
+ ToolboxItemInfo tbinfo = item.Value;
+ XmlElement elem = doc.CreateElement ("object");
+ elem.SetAttribute ("type", tdef.FullName);
+ elem.SetAttribute ("allow-children", "false");
+ elem.SetAttribute ("palette-category", tbinfo.PaletteCategory);
+ if (tdef.IsNotPublic)
+ elem.SetAttribute ("internal", "true");
+ doc.DocumentElement.AppendChild (elem);
+
+ TypeDefinition curDef = tdef;
+ while (curDef != null && curDef.FullName != tbinfo.BaseType) {
+ if (curDef != tdef && localObjects.ContainsKey (curDef)) {
+ tbinfo.BaseType = curDef.FullName;
+ break;
+ }
+ else if (curDef.Module.Assembly.Name.Name == "gtk-sharp") {
+ tbinfo.BaseType = curDef.FullName;
+ break;
+ }
+ else if (curDef != tdef && GetToolboxItemInfo (resolver, basePath, curDef.Module.Assembly, curDef, false) != null) {
+ tbinfo.BaseType = curDef.FullName;
+ break;
+ }
+ if (curDef.Module.Assembly != adef) {
+
+ LibraryInfo li = Refresh (resolver, curDef.Module.Image.FileInformation.FullName, basePath);
+ if (li.HasWidgets && li.GetToolboxItem (curDef.FullName, curDef.Module.Assembly.Name.Name) != null) {
+ tbinfo.BaseType = curDef.FullName;
+ break;
+ }
+ }
+ AddProperties (curDef, elem);
+ AddEvents (curDef, elem);
+ if (curDef.BaseType != null && curDef.BaseType.FullName != tbinfo.BaseType)
+ curDef = FindTypeDefinition (resolver, adef, basePath, curDef.BaseType.FullName);
+ else
+ curDef = null;
+ }
+
+ elem.SetAttribute ("base-type", tbinfo.BaseType);
+ }
+ }
+
+ XmlDocument GetObjectsDoc (AssemblyResolver resolver, AssemblyDefinition adef, string path, string baseDirectory)
+ {
+ XmlDocument doc = null;
+ bool isMainLib = Path.GetFileName (path) == "libstetic.dll";
+
+ try {
+ EmbeddedResource res = GetResource (adef, "objects.xml");
+ if (res != null) {
+ MemoryStream stream = new MemoryStream (res.Data);
+ doc = new XmlDocument ();
+ using (stream)
+ doc.Load (stream);
+ }
+
+ if (resolver == null)
+ resolver = new AssemblyResolver (null);
+
+ baseDirectory = baseDirectory ?? Path.GetDirectoryName (path);
+
+ if (!isMainLib) {
+ // Make sure all referenced assemblies are up to date.
+ foreach (AssemblyNameReference aref in adef.MainModule.AssemblyReferences) {
+ Refresh (resolver, aref.FullName, baseDirectory);
+ }
+ }
+
+ if (doc == null) {
+// Hashtable visited = new Hashtable ();
+ foreach (AssemblyNameReference aref in adef.MainModule.AssemblyReferences) {
+ if (aref.Name != "gtk-sharp") {
+ LibraryInfo info = GetInfo (resolver, aref.FullName, baseDirectory);
+ if (info == null || !info.HasWidgets)
+ continue;
+ }
+
+ if (doc == null) {
+ doc = new XmlDocument ();
+ doc.AppendChild (doc.CreateElement ("objects"));
+ }
+ AddObjects (doc, resolver, baseDirectory, adef);
+ break;
+ }
+ }
+
+ if (doc != null && !isMainLib) {
+ XmlElement elem = doc.CreateElement ("dependencies");
+ doc.DocumentElement.AppendChild (elem);
+ AddDependencies (elem, resolver, path, adef);
+ }
+ } catch (Exception e) {
+ Console.WriteLine ("Got exception loading objects: " + e);
+ doc = null;
+ }
+
+ return doc;
+ }
+
+ LibraryInfo GetInfo (AssemblyResolver resolver, string assembly, string baseDirectory)
+ {
+ string file = assembly;
+ if (File.Exists (assembly))
+ file = assembly;
+ else {
+ if (resolver == null)
+ resolver = new AssemblyResolver (null);
+ try {
+ string path = resolver.Resolve (assembly, baseDirectory);
+ if (path != null)
+ file = path;
+ else
+ return null;
+ } catch (Exception) {
+ return null;
+ }
+ }
+
+ file = Path.GetFullPath (file);
+
+ LibraryInfo info = Members [file];
+ if (info == null) {
+ info = new LibraryInfo ();
+ info.File = file ?? assembly;
+ Members.Add (info);
+ }
+ return info;
+ }
+
+ internal LibraryInfo Refresh (AssemblyResolver resolver, string assembly)
+ {
+ return Refresh (resolver, assembly, null);
+ }
+
+ LibraryInfo Refresh (AssemblyResolver resolver, string assembly, string baseDirectory)
+ {
+ LibraryInfo info = GetInfo (resolver, assembly, baseDirectory);
+
+ if (info == null || info.IsCurrent || !File.Exists (info.File))
+ return info;
+
+ info.Timestamp = File.GetLastWriteTime (info.File).ToUniversalTime ();
+ info.Guid = Guid.NewGuid ();
+ Save ();
+ AssemblyDefinition adef = AssemblyFactory.GetAssembly (info.File);
+ XmlDocument objects = GetObjectsDoc (resolver, adef, info.File, baseDirectory);
+ if (objects != null) {
+ info.ObjectsDocument = objects;
+ XmlDocument gui = GetGuiDoc (adef);
+ if (gui != null)
+ info.GuiDocument = gui;
+ }
+ info.OnChanged ();
+ return info;
+ }
+
+ void Save ()
+ {
+ if (!Directory.Exists (dir))
+ Directory.CreateDirectory (dir);
+
+ // remove any dead assemblies from the cache
+ StringCollection zombies = new StringCollection ();
+ foreach (LibraryInfo info in Members) {
+ if (File.Exists (info.File))
+ continue;
+ zombies.Add (info.File);
+ string zombie_dir = Path.Combine (dir, info.Guid.ToString ());
+ if (Directory.Exists (zombie_dir))
+ Directory.Delete (Path.Combine (dir, info.Guid.ToString ()), true);
+ }
+
+ foreach (string file in zombies)
+ Members.Remove (file);
+
+ XmlSerializer serializer = new XmlSerializer (typeof (LibraryCache));
+ using (FileStream fs = File.Create (Path.Combine (dir, "index.xml")))
+ serializer.Serialize (fs, this);
+ }
+
+ static LibraryCache Load ()
+ {
+ string index_path = Path.Combine (dir, "index.xml");
+ if (File.Exists (index_path)) {
+ try {
+ LibraryCache result;
+ XmlSerializer serializer = new XmlSerializer (typeof (LibraryCache));
+ using (XmlTextReader rdr = new XmlTextReader (index_path))
+ result = (LibraryCache) serializer.Deserialize (rdr);
+ return result;
+ } catch (Exception e) {
+ Console.WriteLine ("Cache index serialization failed " + e);
+ }
+ }
+
+ return new LibraryCache ();
+ }
+
+ internal TypeDefinition FindTypeDefinition (AssemblyResolver resolver, AssemblyDefinition assembly, string basePath, string fullName)
+ {
+ TypeDefinition t = FindTypeDefinition (new Hashtable (), resolver, basePath, assembly, fullName);
+ return t;
+ }
+
+ TypeDefinition FindTypeDefinition (Hashtable visited, AssemblyResolver resolver, string basePath, AssemblyDefinition asm, string fullName)
+ {
+ if (visited.Contains (asm))
+ return null;
+
+ visited [asm] = asm;
+
+ TypeDefinition cls = asm.MainModule.Types [fullName];
+ if (cls != null)
+ return cls;
+
+ foreach (AssemblyNameReference aref in asm.MainModule.AssemblyReferences) {
+ AssemblyDefinition basm = resolver.Resolve (aref, basePath);
+ if (basm != null) {
+ cls = basm.MainModule.Types [fullName];
+ if (cls != null)
+ return cls;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Makefile.am b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Makefile.am
new file mode 100644
index 0000000000..5128750332
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Makefile.am
@@ -0,0 +1,107 @@
+ADDIN_BUILD = $(top_builddir)/build/AddIns/MonoDevelop.GtkCore
+ASSEMBLY = $(ADDIN_BUILD)/libsteticui.dll
+assemblydir = $(MD_ADDIN_DIR)/MonoDevelop.GtkCore
+assembly_DATA = $(ASSEMBLY) $(ASSEMBLY).mdb $(build_dll_config)
+
+FILES = \
+ ActionComponent.cs \
+ ActionGroupComponent.cs \
+ ActionGroupDesigner.cs \
+ ActionGroupDesignerBackend.cs \
+ ActionGroupEditSession.cs \
+ ActionGroupToolbar.cs \
+ Application.cs \
+ ApplicationBackend.cs \
+ ApplicationBackendController.cs \
+ AssemblyResolver.cs \
+ AssemblyWidgetLibrary.cs \
+ CecilClassDescriptor.cs \
+ CecilPropertyDescriptor.cs \
+ CecilSignalDescriptor.cs \
+ CecilWidgetLibrary.cs \
+ CodeGenerationResult.cs \
+ CodeGenerator.cs \
+ CodeGeneratorPartialClass.cs \
+ Component.cs \
+ ComponentEventHandler.cs \
+ ComponentSignalEventHandler.cs \
+ ComponentType.cs \
+ ContainerUndoRedoManager.cs \
+ ContextMenu.cs \
+ Designer.cs \
+ Glade.cs \
+ Grid.cs \
+ GuiDispatchServerSink.cs \
+ GuiDispatchServerSinkProvider.cs \
+ IProjectDesignInfo.cs \
+ LibraryCache.cs \
+ Metacity/ButtonFunction.cs \
+ Metacity/ButtonLayout.cs \
+ Metacity/FrameFlags.cs \
+ Metacity/FrameType.cs \
+ Metacity/ObjectManager.cs \
+ Metacity/Preview.cs \
+ Metacity/Theme.cs \
+ Palette.cs \
+ PaletteBackend.cs \
+ PluggableWidget.cs \
+ Project.cs \
+ ProjectBackend.cs \
+ ProjectViewBackend.cs \
+ PropertyEditor.cs \
+ PropertyGrid.cs \
+ PropertyTree.cs \
+ Shadow.cs \
+ SignalsEditor.cs \
+ SignalsEditorBackend.cs \
+ UndoQueue.cs \
+ UserInterface.cs \
+ WidgetActionBar.cs \
+ WidgetComponent.cs \
+ WidgetDesigner.cs \
+ WidgetDesignerBackend.cs \
+ WidgetEditSession.cs \
+ WidgetFactory.cs \
+ WidgetInfoEventHandler.cs \
+ WidgetPropertyTree.cs \
+ WidgetPropertyTreeBackend.cs \
+ WidgetTree.cs \
+ WidgetTreeCombo.cs \
+ Windows/Preview.cs \
+ Windows/WindowsTheme.cs
+
+RES = \
+ action.png \
+ missing.png
+
+DEPS = ../../../../build/AddIns/MonoDevelop.GtkCore2/libstetic2.dll
+
+REFS = \
+ $(GLADE_SHARP_LIBS) \
+ $(GLIB_SHARP_LIBS) \
+ $(GTK_SHARP_LIBS) \
+ -pkg:monodevelop \
+ -r:Mono.Posix \
+ -r:System \
+ -r:System.Core \
+ -r:System.Runtime.Remoting \
+ -r:System.Xml
+
+$(ASSEMBLY): $(build_sources) $(build_resources) $(DEPS)
+ mkdir -p $(ADDIN_BUILD)
+ $(CSC) $(CSC_FLAGS) -debug -unsafe -main:Stetic.ApplicationBackend -out:$@ \
+ $(build_resources:%=/resource:%) $(build_sources) $(REFS) $(build_deps)
+
+dll_config = libsteticui.dll.config
+build_dll_config = $(ADDIN_BUILD)/$(dll_config)
+
+$(build_dll_config): $(srcdir)/$(dll_config)
+ mkdir -p $(ADDIN_BUILD)
+ cp $(srcdir)/$(dll_config) $@
+
+EXTRA_DIST = $(FILES) $(RES) $(dll_config)
+
+CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb
+
+include $(top_srcdir)/Makefile.include
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonFunction.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonFunction.cs
new file mode 100644
index 0000000000..9fa8ef4907
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonFunction.cs
@@ -0,0 +1,20 @@
+// This file was generated by the Gtk# code generator.
+// Any changes made will be lost if regenerated.
+
+namespace Stetic.Metacity
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+
+#region Autogenerated code
+ internal enum ButtonFunction {
+
+ Menu,
+ Minimize,
+ Maximize,
+ Close,
+ Last,
+ }
+#endregion
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonLayout.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonLayout.cs
new file mode 100644
index 0000000000..e954c20a3e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ButtonLayout.cs
@@ -0,0 +1,36 @@
+// This file was generated by the Gtk# code generator.
+// Any changes made will be lost if regenerated.
+
+namespace Stetic.Metacity
+{
+
+ using System;
+ using System.Collections;
+ using System.Runtime.InteropServices;
+
+#region Autogenerated code
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct ButtonLayout {
+
+ [MarshalAs (UnmanagedType.ByValArray, SizeConst=4)]
+ public Metacity.ButtonFunction[] LeftButtons;
+ [MarshalAs (UnmanagedType.ByValArray, SizeConst=4)]
+ public Metacity.ButtonFunction[] RightButtons;
+
+ public static Metacity.ButtonLayout Zero = new Metacity.ButtonLayout ();
+
+ public static Metacity.ButtonLayout New(IntPtr raw) {
+ if (raw == IntPtr.Zero) {
+ return Metacity.ButtonLayout.Zero;
+ }
+ Metacity.ButtonLayout self = new Metacity.ButtonLayout();
+ self = (Metacity.ButtonLayout) Marshal.PtrToStructure (raw, self.GetType ());
+ return self;
+ }
+
+ internal static GLib.GType GType {
+ get { return GLib.GType.Pointer; }
+ }
+#endregion
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameFlags.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameFlags.cs
new file mode 100644
index 0000000000..bc6172fbe8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameFlags.cs
@@ -0,0 +1,30 @@
+// This file was generated by the Gtk# code generator.
+// Any changes made will be lost if regenerated.
+
+namespace Stetic.Metacity
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+
+#region Autogenerated code
+ [Flags]
+ internal enum FrameFlags {
+
+ AllowsDelete = 1 << 0,
+ AllowsMenu = 1 << 1,
+ AllowsMinimize = 1 << 2,
+ AllowsMaximize = 1 << 3,
+ AllowsVerticalResize = 1 << 4,
+ AllowsHorizontalResize = 1 << 5,
+ HasFocus = 1 << 6,
+ Shaded = 1 << 7,
+ Stuck = 1 << 8,
+ Maximized = 1 << 9,
+ AllowsShade = 1 << 10,
+ AllowsMove = 1 << 11,
+ Fullscreen = 1 << 12,
+ IsFlashing = 1 << 13,
+ }
+#endregion
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameType.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameType.cs
new file mode 100644
index 0000000000..7ecc08d277
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/FrameType.cs
@@ -0,0 +1,22 @@
+// This file was generated by the Gtk# code generator.
+// Any changes made will be lost if regenerated.
+
+namespace Stetic.Metacity
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+
+#region Autogenerated code
+ internal enum FrameType {
+
+ Normal,
+ Dialog,
+ ModalDialog,
+ Utility,
+ Menu,
+ Border,
+ Last,
+ }
+#endregion
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ObjectManager.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ObjectManager.cs
new file mode 100644
index 0000000000..201c52370e
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/ObjectManager.cs
@@ -0,0 +1,19 @@
+// This file was generated by the Gtk# code generator.
+// Any changes made will be lost if regenerated.
+
+namespace GtkSharp.MetacitySharp {
+
+ class ObjectManager {
+
+ static bool initialized = false;
+ // Call this method from the appropriate module init function.
+ public static void Initialize ()
+ {
+ if (initialized)
+ return;
+
+ initialized = true;
+ GLib.GType.Register (Stetic.Metacity.Preview.GType, typeof (Stetic.Metacity.Preview));
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Preview.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Preview.cs
new file mode 100644
index 0000000000..509beac264
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Preview.cs
@@ -0,0 +1,227 @@
+// This file was generated by the Gtk# code generator.
+// Any changes made will be lost if regenerated.
+
+namespace Stetic.Metacity {
+
+ using System;
+ using System.Reflection;
+ using System.Collections;
+ using System.Runtime.InteropServices;
+
+ internal class Preview : Gtk.Bin
+ {
+ static Theme theme;
+ public static bool ThemeError = false;
+
+ public static Metacity.Preview Create (TopLevelWindow window)
+ {
+ Metacity.Preview metacityPreview;
+
+ try {
+ Metacity.Preview.Init ();
+ metacityPreview = new Metacity.Preview ();
+ }
+ catch {
+ return null;
+ }
+
+ switch (window.TypeHint) {
+ case Gdk.WindowTypeHint.Normal:
+ metacityPreview.FrameType = Metacity.FrameType.Normal;
+ break;
+ case Gdk.WindowTypeHint.Dialog:
+ metacityPreview.FrameType = window.Modal ? Metacity.FrameType.ModalDialog : Metacity.FrameType.Dialog;
+ break;
+ case Gdk.WindowTypeHint.Menu:
+ metacityPreview.FrameType = Metacity.FrameType.Menu;
+ break;
+ case Gdk.WindowTypeHint.Splashscreen:
+ metacityPreview.FrameType = Metacity.FrameType.Border;
+ break;
+ case Gdk.WindowTypeHint.Utility:
+ metacityPreview.FrameType = Metacity.FrameType.Utility;
+ break;
+ default:
+ metacityPreview.FrameType = Metacity.FrameType.Normal;
+ break;
+ }
+
+ Metacity.FrameFlags flags =
+ Metacity.FrameFlags.AllowsDelete |
+ Metacity.FrameFlags.AllowsVerticalResize |
+ Metacity.FrameFlags.AllowsHorizontalResize |
+ Metacity.FrameFlags.AllowsMove |
+ Metacity.FrameFlags.AllowsShade |
+ Metacity.FrameFlags.HasFocus;
+
+ if (window.Resizable)
+ flags = flags | Metacity.FrameFlags.AllowsMaximize;
+
+ metacityPreview.FrameFlags = flags;
+ metacityPreview.ShowAll ();
+ metacityPreview.AddWindow (window);
+
+ metacityPreview.Theme = GetTheme ();
+
+ return metacityPreview;
+ }
+
+ public void AddWindow (TopLevelWindow window)
+ {
+ base.Add (window);
+
+ Title = window.Title ?? string.Empty;
+ window.PropertyChanged += OnWindowPropChange;
+ Destroyed += delegate {
+ window.PropertyChanged -= OnWindowPropChange;
+ };
+ }
+
+ void OnWindowPropChange (object ob, EventArgs e)
+ {
+ Title = ((TopLevelWindow)ob).Title ?? string.Empty;
+ }
+
+ static Theme GetTheme ()
+ {
+ if (theme == null) {
+ try {
+ Assembly assm = Assembly.LoadWithPartialName ("gconf-sharp");
+ Type client_type = assm.GetType ("GConf.Client");
+ MethodInfo method = client_type.GetMethod ("Get", BindingFlags.Instance | BindingFlags.Public);
+ object client = Activator.CreateInstance (client_type, new object[] {
+
+ });
+ string themeName = (string)method.Invoke (client, new object[] { "/apps/metacity/general/theme" });
+ theme = Metacity.Theme.Load (themeName);
+ } catch {
+ // Set theme error flag - in case of a theme error a solid background needs to be drawn.
+ ThemeError = true;
+ // Don't crash if metacity is not available
+ return null;
+ }
+ }
+ return theme;
+ }
+
+ /* static void GConfNotify (object obj, GConf.NotifyEventArgs args)
+ {
+ if (args.Key == "/apps/metacity/general/theme") {
+ theme = Metacity.Theme.Load ((string)args.Value);
+ foreach (Metacity.Preview prev in wrappers.Values)
+ prev.Theme = Theme;
+ }
+ }
+ */
+
+ ~Preview ( )
+ {
+ Dispose();
+ }
+
+ [Obsolete]
+ protected Preview(GLib.GType gtype) : base(gtype) {}
+ public Preview(IntPtr raw) : base(raw) {}
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern IntPtr meta_preview_new();
+
+ public Preview () : base (IntPtr.Zero)
+ {
+ if (GetType () != typeof (Preview)) {
+ CreateNativeObject (new string [0], new GLib.Value[0]);
+ return;
+ }
+ Raw = meta_preview_new();
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern void meta_preview_set_title(IntPtr raw, IntPtr title);
+
+ public string Title {
+ set {
+ IntPtr title_as_native = GLib.Marshaller.StringToPtrGStrdup (value);
+ meta_preview_set_title(Handle, title_as_native);
+ GLib.Marshaller.Free (title_as_native);
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern void meta_preview_set_button_layout(IntPtr raw, ref Stetic.Metacity.ButtonLayout button_layout);
+
+ public Stetic.Metacity.ButtonLayout ButtonLayout
+ {
+ set {
+ meta_preview_set_button_layout(Handle, ref value);
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern void meta_preview_set_theme(IntPtr raw, IntPtr theme);
+
+ public Metacity.Theme Theme {
+ set {
+ meta_preview_set_theme(Handle, (value == null ? IntPtr.Zero : value.Handle));
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern IntPtr meta_preview_get_mini_icon();
+
+ public static Gdk.Pixbuf MiniIcon {
+ get {
+ IntPtr raw_ret = meta_preview_get_mini_icon();
+ Gdk.Pixbuf ret = GLib.Object.GetObject(raw_ret) as Gdk.Pixbuf;
+ return ret;
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern IntPtr meta_preview_get_icon();
+
+ public static Gdk.Pixbuf Icon {
+ get {
+ IntPtr raw_ret = meta_preview_get_icon();
+ Gdk.Pixbuf ret = GLib.Object.GetObject(raw_ret) as Gdk.Pixbuf;
+ return ret;
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern void meta_preview_set_frame_type(IntPtr raw, int type);
+
+ public Stetic.Metacity.FrameType FrameType
+ {
+ set {
+ meta_preview_set_frame_type(Handle, (int) value);
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern IntPtr meta_preview_get_type();
+
+ public static new GLib.GType GType {
+ get {
+ IntPtr raw_ret = meta_preview_get_type();
+ GLib.GType ret = new GLib.GType(raw_ret);
+ return ret;
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern void meta_preview_set_frame_flags(IntPtr raw, int flags);
+
+ public Stetic.Metacity.FrameFlags FrameFlags
+ {
+ set {
+ meta_preview_set_frame_flags(Handle, (int) value);
+ }
+ }
+
+
+ public static void Init()
+ {
+ GtkSharp.MetacitySharp.ObjectManager.Initialize ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Theme.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Theme.cs
new file mode 100644
index 0000000000..b9254d710d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Metacity/Theme.cs
@@ -0,0 +1,41 @@
+
+namespace Stetic.Metacity
+{
+ using System;
+ using System.Runtime.InteropServices;
+
+ internal class Theme : GLib.Opaque {
+
+ public Theme (IntPtr raw) : base (raw) {}
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern IntPtr meta_theme_get_current ();
+
+ public static Theme Current {
+ get {
+ IntPtr raw = meta_theme_get_current ();
+ return (Theme)GetOpaque (raw, typeof (Metacity.Theme), true);
+ }
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern IntPtr meta_theme_load (string theme_name, IntPtr err);
+
+ public static Theme Load (string name)
+ {
+ IntPtr raw = meta_theme_load (name, IntPtr.Zero);
+ if (raw == IntPtr.Zero)
+ return null;
+ else
+ return (Theme)GetOpaque (raw, typeof (Metacity.Theme), true);
+ }
+
+ [DllImport("libmetacity-private.so.0")]
+ static extern void meta_theme_free (IntPtr raw);
+
+ protected override void Free (IntPtr raw)
+ {
+ meta_theme_free (Raw);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Palette.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Palette.cs
new file mode 100644
index 0000000000..3f747df6cf
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Palette.cs
@@ -0,0 +1,46 @@
+
+using System;
+using Gtk;
+
+namespace Stetic
+{
+ public class Palette: PluggableWidget
+ {
+ bool showWindowCategory = true;
+
+ internal Palette (Application app): base (app)
+ {
+ }
+
+ protected override void OnCreatePlug (uint socketId)
+ {
+ app.Backend.CreatePaletteWidgetPlug (socketId);
+ Update ();
+ }
+
+ protected override void OnDestroyPlug (uint socketId)
+ {
+ app.Backend.DestroyPaletteWidgetPlug ();
+ }
+
+ protected override Gtk.Widget OnCreateWidget ()
+ {
+ Update ();
+ return app.Backend.GetPaletteWidget ();
+ }
+
+ public bool ShowWindowCategory {
+ get { return showWindowCategory; }
+ set {
+ showWindowCategory = value;
+ Update ();
+ }
+ }
+
+ void Update ()
+ {
+ if (!showWindowCategory)
+ app.Backend.HidePaletteGroup ("window");
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PaletteBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PaletteBackend.cs
new file mode 100644
index 0000000000..40d6e8050d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PaletteBackend.cs
@@ -0,0 +1,409 @@
+using Gtk;
+using Gdk;
+using System;
+using System.Collections;
+using System.Reflection;
+using Mono.Unix;
+
+namespace Stetic {
+
+ internal class PaletteBackend : Gtk.ScrolledWindow, IComparer {
+
+ Hashtable groups;
+ ProjectBackend project;
+ WidgetLibrary[] libraries;
+ ArrayList visibleGroups = new ArrayList ();
+ Wrapper.Widget selection;
+ ActionGroupBox localActionsBox;
+ ActionGroupBox globalActionsBox;
+ Gtk.VBox box;
+ ApplicationBackend app;
+
+ public PaletteBackend (ApplicationBackend app)
+ {
+ this.app = app;
+ box = new Gtk.VBox (false, 0);
+ AddWithViewport (box);
+ groups = new Hashtable ();
+ Registry.RegistryChanged += OnRegistryChanged;
+
+ ShowGroup ("window", Catalog.GetString ("Windows"));
+ ShowGroup ("widget", Catalog.GetString ("Widgets"));
+ ShowGroup ("container", Catalog.GetString ("Containers"));
+// ShowGroup ("toolbaritem", "Toolbar Items");
+ ShowGroup ("actions", Catalog.GetString ("Actions"));
+ }
+
+ public override void Dispose ()
+ {
+ Registry.RegistryChanged -= OnRegistryChanged;
+
+ foreach (PaletteGroup grp in groups.Values)
+ grp.Destroy ();
+
+ if (localActionsBox != null) {
+ localActionsBox.Destroy ();
+ localActionsBox = null;
+ }
+ if (globalActionsBox != null) {
+ globalActionsBox.Destroy ();
+ globalActionsBox = null;
+ }
+
+ project = null;
+ selection = null;
+ base.Dispose ();
+ }
+
+ public PaletteBackend (ApplicationBackend app, ProjectBackend project): this (app)
+ {
+ this.ProjectBackend = project;
+ }
+
+ public ProjectBackend ProjectBackend {
+ get { return project; }
+ set {
+ if (project != null) {
+ project.SelectionChanged -= OnSelectionChanged;
+ project.ProjectReloaded -= OnProjectReloaded;
+ }
+ project = value;
+ if (project != null) {
+ UpdateSelection (Wrapper.Widget.Lookup (project.Selection));
+ project.SelectionChanged += OnSelectionChanged;
+ project.ProjectReloaded += OnProjectReloaded;
+ } else
+ UpdateSelection (null);
+ LoadWidgets (project);
+ }
+ }
+
+ public WidgetLibrary[] WidgetLibraries {
+ get { return libraries; }
+ set {
+ libraries = value;
+ LoadWidgets (project);
+ }
+ }
+
+ void OnProjectReloaded (object s, EventArgs args)
+ {
+ LoadWidgets (project);
+ }
+
+ void OnSelectionChanged (object ob, Stetic.Wrapper.WidgetEventArgs args)
+ {
+ UpdateSelection (args.WidgetWrapper);
+ }
+
+ void UpdateSelection (Wrapper.Widget sel)
+ {
+ selection = sel;
+ if (localActionsBox != null)
+ localActionsBox.SetActionGroups (selection != null ? selection.LocalActionGroups : null);
+ ShowAll ();
+ }
+
+ public void ShowGroup (string name, string label)
+ {
+ visibleGroups.Add (new string[] { name, label });
+ if (project != null)
+ LoadWidgets (project);
+ }
+
+ public void HideGroup (string name)
+ {
+ for (int n=0; n < visibleGroups.Count; n++) {
+ if (((string[])visibleGroups[n])[0] == name) {
+ visibleGroups.RemoveAt (n);
+ if (project != null)
+ LoadWidgets (project);
+ return;
+ }
+ }
+ }
+
+ void OnRegistryChanged (object o, EventArgs args)
+ {
+ WidgetLibraries = app.GetActiveLibraries ();
+ }
+
+ public void LoadWidgets (ProjectBackend project)
+ {
+ if (project == null) {
+ box.Hide ();
+ return;
+ }
+
+ box.Show ();
+
+ foreach (PaletteGroup g in groups.Values) {
+ box.Remove (g);
+ g.Destroy ();
+ }
+
+ groups.Clear ();
+
+ foreach (string[] grp in visibleGroups)
+ AddOrGetGroup (grp[0], grp[1]);
+
+ ArrayList classes = new ArrayList ();
+ if (libraries == null) {
+ foreach (ClassDescriptor klass in Registry.AllClasses)
+ if (klass.SupportsGtkVersion (project.TargetGtkVersion))
+ classes.Add (klass);
+ } else if (project != null) {
+ foreach (WidgetLibrary lib in libraries) {
+ bool isInternalLib = project.IsInternalLibrary (lib.Name);
+ foreach (ClassDescriptor cd in lib.AllClasses) {
+ if (!cd.Deprecated && cd.Category.Length > 0 && (isInternalLib || !cd.IsInternal) && cd.SupportsGtkVersion (project.TargetGtkVersion))
+ classes.Add (cd);
+ }
+ }
+ }
+
+ classes.Sort (this);
+
+ foreach (ClassDescriptor klass in classes) {
+
+ if (!groups.Contains (klass.Category))
+ continue;
+
+ WidgetFactory factory;
+ if (klass.Category == "window")
+ factory = new WindowFactory (project, klass);
+ else
+ factory = new WidgetFactory (project, klass);
+
+ AddOrGetGroup(klass.Category).Append (factory);
+ }
+
+ if (localActionsBox != null)
+ localActionsBox.Destroy ();
+ if (globalActionsBox != null)
+ globalActionsBox.Destroy ();
+
+ PaletteGroup widgetGroup = AddOrGetGroup ("actions", Catalog.GetString ("Actions"));
+ localActionsBox = new ActionGroupBox ();
+ globalActionsBox = new ActionGroupBox ();
+ widgetGroup.Append (localActionsBox);
+ widgetGroup.Append (globalActionsBox);
+
+ if (project != null) {
+ widgetGroup.Sensitive = true;
+ localActionsBox.SetActionGroups (selection != null ? selection.LocalActionGroups : null);
+ globalActionsBox.SetActionGroups (project.ActionGroups);
+ } else {
+ widgetGroup.Sensitive = false;
+ localActionsBox.SetActionGroups (null);
+ globalActionsBox.SetActionGroups (null);
+ }
+
+ // This is a workaround. In looks like the palette is not correctly
+ // redrawn if it is rebuilt while it is not visible (the dock is hidden in MD).
+ GLib.Idle.Add (delegate {
+ ShowAll ();
+ return false;
+ });
+ }
+
+ int IComparer.Compare (object x, object y)
+ {
+ return string.Compare (((ClassDescriptor)x).Label,
+ ((ClassDescriptor)y).Label);
+ }
+
+ private PaletteGroup AddOrGetGroup (string id, string name)
+ {
+ PaletteGroup group = (PaletteGroup) groups[id];
+
+ if (group == null) {
+ group = new PaletteGroup (name);
+ box.PackStart (group, false, false, 0);
+ groups.Add (id, group);
+ }
+
+ return group;
+ }
+
+ private PaletteGroup AddOrGetGroup (string name)
+ {
+ return AddOrGetGroup (name, name);
+ }
+ }
+
+ class PaletteGroup : Gtk.Expander
+ {
+ private Gtk.Alignment align;
+ private Gtk.VBox vbox;
+ Gtk.Label emptyLabel;
+ bool isEmpty = true;
+
+ public PaletteGroup (string name) : base ("<b>" + name + "</b>")
+ {
+ vbox = new VBox (false, 0);
+ emptyLabel = new Gtk.Label ();
+ emptyLabel.Markup = "<small><i><span foreground='darkgrey'> " + Catalog.GetString ("Empty") + "</span></i></small>";
+ vbox.PackStart (emptyLabel, false, false, 0);
+
+ align = new Gtk.Alignment (0, 0, 0, 0);
+ align.SetPadding (0, 0, 20, 0);
+ align.Child = vbox;
+
+ UseMarkup = true;
+ Expanded = true;
+ Child = align;
+ }
+
+ public void SetName (string name)
+ {
+ Label = "<b>" + name + "</b>";
+ }
+
+ public void Append (Widget w)
+ {
+ if (isEmpty) {
+ vbox.Remove (emptyLabel);
+ isEmpty = false;
+ }
+ vbox.PackStart (w, false, false, 0);
+ }
+
+ public void Clear ()
+ {
+ foreach (Gtk.Widget w in vbox.Children) {
+ vbox.Remove (w);
+ w.Destroy ();
+ }
+
+ isEmpty = true;
+ vbox.PackStart (emptyLabel, false, false, 0);
+ }
+ }
+
+ class ActionPaletteGroup : PaletteGroup
+ {
+ Wrapper.ActionGroup group;
+
+ public ActionPaletteGroup (string name, Wrapper.ActionGroup group): base (name)
+ {
+ DND.DestSet (this, true);
+ this.group = group;
+ group.ActionAdded += OnActionGroupChanged;
+ group.ActionRemoved += OnActionGroupChanged;
+ group.ActionChanged += OnActionGroupChanged;
+ group.ObjectChanged += OnActionGroupChanged;
+ Fill ();
+ }
+
+ public Wrapper.ActionGroup Group {
+ get { return group; }
+ }
+
+ public override void Dispose ()
+ {
+ group.ActionAdded -= OnActionGroupChanged;
+ group.ActionRemoved -= OnActionGroupChanged;
+ group.ActionChanged -= OnActionGroupChanged;
+ group.ObjectChanged -= OnActionGroupChanged;
+ base.Dispose ();
+ }
+
+ public void Fill ()
+ {
+ foreach (Stetic.Wrapper.Action action in group.Actions) {
+ Gdk.Pixbuf icon = action.RenderIcon (Gtk.IconSize.Menu);
+ if (icon == null) icon = ActionComponent.DefaultActionIcon;
+ Stetic.Wrapper.ActionPaletteItem it = new Stetic.Wrapper.ActionPaletteItem (Gtk.UIManagerItemType.Menuitem, null, action);
+ Append (new InstanceWidgetFactory (action.MenuLabel, icon, it));
+ }
+ }
+
+ void OnActionGroupChanged (object s, EventArgs args)
+ {
+ SetName (((Stetic.Wrapper.ActionGroup)s).Name);
+ }
+
+ void OnActionGroupChanged (object s, Stetic.Wrapper.ActionEventArgs args)
+ {
+ Clear ();
+ Fill ();
+ ShowAll ();
+ }
+
+ protected override bool OnDragDrop (Gdk.DragContext context, int x, int y, uint time)
+ {
+ Wrapper.ActionPaletteItem dropped = DND.Drop (context, null, time) as Wrapper.ActionPaletteItem;
+ if (dropped == null)
+ return false;
+
+ if (dropped.Node.Action.ActionGroup != group) {
+ using (dropped.Node.Action.UndoManager.AtomicChange) {
+ dropped.Node.Action.ActionGroup.Actions.Remove (dropped.Node.Action);
+ group.Actions.Add (dropped.Node.Action);
+ }
+ }
+
+ return base.OnDragDrop (context, x, y, time);
+ }
+ }
+
+ class ActionGroupBox: Gtk.VBox
+ {
+ Stetic.Wrapper.ActionGroupCollection groups;
+
+ public void SetActionGroups (Stetic.Wrapper.ActionGroupCollection groups)
+ {
+ if (this.groups != null) {
+ this.groups.ActionGroupAdded -= OnGroupAdded;
+ this.groups.ActionGroupRemoved -= OnGroupRemoved;
+ }
+ this.groups = groups;
+ if (this.groups != null) {
+ this.groups.ActionGroupAdded += OnGroupAdded;
+ this.groups.ActionGroupRemoved += OnGroupRemoved;
+ }
+ Update ();
+ }
+
+ public override void Dispose ()
+ {
+ foreach (ActionPaletteGroup grp in Children)
+ grp.Destroy ();
+ base.Dispose ();
+ }
+
+ public void Update ()
+ {
+ foreach (ActionPaletteGroup grp in Children) {
+ Remove (grp);
+ grp.Destroy ();
+ }
+
+ if (groups != null) {
+ foreach (Stetic.Wrapper.ActionGroup group in groups) {
+ ActionPaletteGroup pg = new ActionPaletteGroup (group.Name, group);
+ PackStart (pg, false, false, 0);
+ }
+ }
+ ShowAll ();
+ }
+
+ void OnGroupAdded (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ ActionPaletteGroup pg = new ActionPaletteGroup (args.ActionGroup.Name, args.ActionGroup);
+ pg.ShowAll ();
+ PackStart (pg, false, false, 0);
+ }
+
+ void OnGroupRemoved (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ foreach (ActionPaletteGroup grp in Children) {
+ if (grp.Group == args.ActionGroup) {
+ Remove (grp);
+ grp.Destroy ();
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PluggableWidget.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PluggableWidget.cs
new file mode 100644
index 0000000000..be70fee7a2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PluggableWidget.cs
@@ -0,0 +1,154 @@
+
+using System;
+
+namespace Stetic
+{
+ public abstract class PluggableWidget: Gtk.EventBox
+ {
+ internal Application app;
+ bool initialized;
+ Gtk.Socket socket;
+ bool customWidget;
+ Gtk.Notebook book;
+
+ public PluggableWidget (Application app)
+ {
+ book = new Gtk.Notebook ();
+ book.ShowTabs = false;
+ book.ShowBorder = false;
+ book.Show ();
+ Add (book);
+
+ this.app = app;
+ if (app is IsolatedApplication) {
+ (app as IsolatedApplication).BackendChanged += OnBackendChanged;
+ (app as IsolatedApplication).BackendChanging += OnBackendChanging;
+ }
+ }
+
+ protected void AddCustomWidget (Gtk.Widget w)
+ {
+ w.ShowAll ();
+ book.AppendPage (w, null);
+ book.Page = book.NPages - 1;
+
+ if (initialized) {
+ Gtk.Widget cw = book.GetNthPage (0);
+ book.RemovePage (0);
+ cw.Destroy ();
+ }
+ else
+ initialized = true;
+ customWidget = true;
+ }
+
+ protected void ResetCustomWidget ()
+ {
+ customWidget = false;
+ }
+
+ protected override void OnRealized ()
+ {
+ base.OnRealized ();
+ if (!initialized) {
+ initialized = true;
+ if (app is IsolatedApplication)
+ ConnectPlug ();
+ else {
+ Gtk.Widget w = OnCreateWidget ();
+ w.Show ();
+ book.AppendPage (w, null);
+ }
+ }
+ }
+
+ protected override void OnUnrealized ()
+ {
+ if (app is IsolatedApplication && initialized) {
+ OnDestroyPlug (socket.Id);
+ initialized = false;
+ }
+ base.OnUnrealized ();
+ }
+
+ protected void PrepareUpdateWidget ()
+ {
+ // This method is called when the child widget is going to be changed.
+ // It takes a 'screenshot' of the widget. This image will be shown until
+ // UpdateWidget is called.
+
+ if (book.NPages == 1) {
+ Gtk.Widget w = book.GetNthPage (0);
+ Gdk.Window win = w.GdkWindow;
+ if (win != null && win.IsViewable) {
+ Gdk.Pixbuf img = Gdk.Pixbuf.FromDrawable (win, win.Colormap, w.Allocation.X, w.Allocation.Y, 0, 0, w.Allocation.Width, w.Allocation.Height);
+ Gtk.Image oldImage = new Gtk.Image (img);
+ oldImage.Show ();
+ book.AppendPage (oldImage, null);
+ book.Page = 1;
+ book.RemovePage (0);
+ }
+ }
+ }
+
+ protected void UpdateWidget ()
+ {
+ if (!initialized)
+ return;
+
+ if (app is LocalApplication) {
+ Gtk.Widget w = OnCreateWidget ();
+ if (w.Parent != book) {
+ book.AppendPage (w, null);
+ w.Show ();
+ }
+ book.Page = book.NPages - 1;
+ if (book.NPages > 1) {
+ Gtk.Widget cw = book.GetNthPage (0);
+ book.Remove (cw);
+ OnDestroyWidget (cw);
+ }
+ }
+ }
+
+ protected abstract void OnCreatePlug (uint socketId);
+ protected abstract void OnDestroyPlug (uint socketId);
+
+ protected abstract Gtk.Widget OnCreateWidget ();
+ protected virtual void OnDestroyWidget (Gtk.Widget w) { w.Destroy (); }
+
+ public override void Dispose ()
+ {
+ if (app is IsolatedApplication) {
+ IsolatedApplication iapp = app as IsolatedApplication;
+ iapp.BackendChanged -= OnBackendChanged;
+ iapp.BackendChanging -= OnBackendChanging;
+ }
+ base.Dispose ();
+ }
+
+ internal virtual void OnBackendChanged (ApplicationBackend oldBackend)
+ {
+ if (!initialized)
+ return;
+
+ Gtk.Widget w = book.GetNthPage (0);
+ book.RemovePage (0);
+ w.Destroy ();
+ socket.Dispose ();
+ ConnectPlug ();
+ }
+
+ internal virtual void OnBackendChanging ()
+ {
+ }
+
+ void ConnectPlug ()
+ {
+ socket = new Gtk.Socket ();
+ socket.Show ();
+ book.AppendPage (socket, null);
+ OnCreatePlug (socket.Id);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Project.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Project.cs
new file mode 100644
index 0000000000..a784aea82d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Project.cs
@@ -0,0 +1,870 @@
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace Stetic
+{
+ public class Project: MarshalByRefObject
+ {
+ Application app;
+ ProjectBackend backend;
+ //string fileName;
+ string folderName;
+ IResourceProvider resourceProvider;
+ Component selection;
+ string tmpProjectFile;
+ bool reloadRequested;
+ List<WidgetInfo> widgets = new List<WidgetInfo> ();
+ List<ActionGroupInfo> groups = new List<ActionGroupInfo> ();
+ ImportFileDelegate importFileDelegate;
+
+ public event WidgetInfoEventHandler WidgetAdded;
+ public event WidgetInfoEventHandler WidgetRemoved;
+ public event ComponentNameEventHandler ComponentNameChanged;
+ public event EventHandler ComponentTypesChanged;
+
+ public event EventHandler ActionGroupsChanged;
+ public event EventHandler ModifiedChanged;
+ public event EventHandler Changed;
+
+
+ // Internal events
+ internal event BackendChangingHandler BackendChanging;
+ internal event BackendChangedHandler BackendChanged;
+ internal event ComponentSignalEventHandler SignalAdded;
+ internal event ComponentSignalEventHandler SignalRemoved;
+ internal event ComponentSignalEventHandler SignalChanged;
+
+ public event EventHandler ProjectReloading;
+ public event EventHandler ProjectReloaded;
+
+ internal Project (Application app, IProjectDesignInfo info): this (app, null, info)
+ {
+ }
+
+ internal Project (Application app, ProjectBackend backend, IProjectDesignInfo info)
+ {
+ this.app = app;
+ if (backend != null) {
+ this.backend = backend;
+ backend.SetFrontend (this);
+ }
+
+ if (app is IsolatedApplication) {
+ IsolatedApplication iapp = app as IsolatedApplication;
+ iapp.BackendChanging += OnBackendChanging;
+ iapp.BackendChanged += OnBackendChanged;
+ }
+
+ DesignInfo = info;
+ }
+
+ internal IProjectDesignInfo DesignInfo { get; private set; }
+
+ internal ProjectBackend ProjectBackend {
+ get {
+ if (backend == null) {
+ backend = app.Backend.CreateProject ();
+ backend.SetFrontend (this);
+ if (resourceProvider != null)
+ backend.ResourceProvider = resourceProvider;
+ if (folderName != null)
+ backend.Load (folderName);
+ }
+ return backend;
+ }
+ }
+
+ internal bool IsBackendLoaded {
+ get { return backend != null; }
+ }
+
+ internal Application App {
+ get { return app; }
+ }
+
+ internal event EventHandler Disposed;
+
+ public void Dispose ()
+ {
+ if (app is IsolatedApplication) {
+ IsolatedApplication iapp = app as IsolatedApplication;
+ iapp.BackendChanging -= OnBackendChanging;
+ iapp.BackendChanged -= OnBackendChanged;
+ }
+
+ if (tmpProjectFile != null && File.Exists (tmpProjectFile)) {
+ File.Delete (tmpProjectFile);
+ tmpProjectFile = null;
+ }
+ if (backend != null)
+ backend.Dispose ();
+ if (Disposed != null)
+ Disposed (this, EventArgs.Empty);
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+
+// public string FileName {
+// get { return fileName; }
+// }
+
+ public IResourceProvider ResourceProvider {
+ get { return resourceProvider; }
+ set {
+ resourceProvider = value;
+ if (backend != null)
+ backend.ResourceProvider = value;
+ }
+ }
+
+ public Stetic.ProjectIconFactory IconFactory {
+ get { return ProjectBackend.IconFactory; }
+ set { backend.IconFactory = value; }
+ }
+
+ public ImportFileDelegate ImportFileCallback {
+ get { return importFileDelegate; }
+ set { importFileDelegate = value; }
+ }
+
+ public bool CanGenerateCode {
+ get { return ProjectBackend.CanGenerateCode; }
+ }
+
+ public Component Selection {
+ get { return selection; }
+ }
+
+ public string ImagesRootPath {
+ get { return ProjectBackend.ImagesRootPath; }
+ set { ProjectBackend.ImagesRootPath = value; }
+ }
+
+ public string TargetGtkVersion {
+ get { return ProjectBackend.TargetGtkVersion; }
+ set { ProjectBackend.TargetGtkVersion = value; }
+ }
+
+ public void Close ()
+ {
+ if (backend != null)
+ backend.Close ();
+ }
+
+ public void Load (string folderName)
+ {
+ this.folderName = folderName;
+ if (backend != null)
+ backend.Load (folderName);
+
+ foreach (string basePath in DesignInfo.GetComponentFolders ()) {
+ if (!Directory.Exists (basePath))
+ continue;
+
+ DirectoryInfo dir = new DirectoryInfo (basePath);
+
+ foreach (FileInfo file in dir.GetFiles ()) {
+ if (file.Extension == ".gtkx") {
+
+ using (StreamReader sr = new StreamReader (file.FullName)) {
+ XmlTextReader reader = new XmlTextReader (sr);
+
+ reader.MoveToContent ();
+ if (reader.IsEmptyElement)
+ return;
+
+ reader.ReadStartElement ("stetic-interface");
+ if (reader.IsEmptyElement)
+ return;
+ while (reader.NodeType != XmlNodeType.EndElement) {
+ if (reader.NodeType == XmlNodeType.Element) {
+ if (reader.LocalName == "widget")
+ ReadWidget (reader);
+ else if (reader.LocalName == "action-group")
+ ReadActionGroup (reader);
+ else
+ reader.Skip ();
+ }
+ else {
+ reader.Skip ();
+ }
+ reader.MoveToContent ();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void ReloadComponent (string componentName)
+ {
+ if (backend != null)
+ backend.ReloadComponent (componentName);
+ }
+
+ void ReadWidget (XmlTextReader reader)
+ {
+ WidgetInfo w = new WidgetInfo (this, reader.GetAttribute ("id"), reader.GetAttribute ("class"));
+ widgets.Add (w);
+ if (reader.IsEmptyElement) {
+ reader.Skip ();
+ return;
+ }
+ reader.ReadStartElement ();
+ reader.MoveToContent ();
+ while (reader.NodeType != XmlNodeType.EndElement) {
+ if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "action-group") {
+ w.AddGroup (reader.GetAttribute ("name"));
+ }
+ reader.Skip ();
+ reader.MoveToContent ();
+ }
+ reader.ReadEndElement ();
+ }
+
+ void ReadActionGroup (XmlTextReader reader)
+ {
+ groups.Add (new ActionGroupInfo (this, reader.GetAttribute ("name")));
+ reader.Skip ();
+ }
+
+ public void ConvertProject (string oldSteticFileName, string newGuiFolderName)
+ {
+ //ProjectBackend property when created invokes Load method which is not valid
+ //for old file layout
+
+ ProjectBackend backend = app.Backend.CreateProject ();
+ backend.SetFrontend (this);
+ backend.ConvertProject (oldSteticFileName, newGuiFolderName);
+ }
+
+ public void Save (string folderName)
+ {
+ this.folderName = folderName;
+ if (backend != null)
+ backend.Save (folderName);
+ }
+
+ public void ImportGlade (string fileName)
+ {
+ ProjectBackend.ImportGlade (fileName);
+ }
+
+ public void ExportGlade (string fileName)
+ {
+ ProjectBackend.ExportGlade (fileName);
+ }
+
+ public IEnumerable<WidgetInfo> Widgets {
+ get { return widgets; }
+ }
+
+ public IEnumerable<ActionGroupInfo> ActionGroups {
+ get { return groups; }
+ }
+
+ public WidgetInfo GetWidget (string name)
+ {
+ foreach (WidgetInfo w in widgets)
+ if (w.Name == name)
+ return w;
+ return null;
+ }
+
+ public ActionGroupInfo GetActionGroup (string name)
+ {
+ foreach (ActionGroupInfo w in groups)
+ if (w.Name == name)
+ return w;
+ return null;
+ }
+
+// public WidgetDesigner CreateWidgetDesigner (WidgetInfo widgetInfo, bool autoCommitChanges)
+// {
+// return new WidgetDesigner (this, widgetInfo.Name, autoCommitChanges);
+// }
+
+ public WidgetDesigner CreateWidgetDesigner (WidgetInfo widgetInfo)
+ {
+ return new WidgetDesigner (this, widgetInfo.Name);
+ }
+
+ public ActionGroupDesigner CreateActionGroupDesigner (ActionGroupInfo actionGroup, bool autoCommitChanges)
+ {
+ return new ActionGroupDesigner (this, null, actionGroup.Name, null, autoCommitChanges);
+ }
+
+ public WidgetInfo AddNewComponent (ComponentType type, string name)
+ {
+ object ob = ProjectBackend.AddNewWidget (type.Name, name);
+ WidgetComponent wc = (WidgetComponent) App.GetComponent (ob, null, null);
+ WidgetInfo wi = GetWidget (wc.Name);
+ if (wi == null) {
+ wi = new WidgetInfo (this, wc);
+ widgets.Add (wi);
+ }
+ return wi;
+ }
+
+ public WidgetInfo AddNewComponent (XmlElement template)
+ {
+ object ob = ProjectBackend.AddNewWidgetFromTemplate (template.OuterXml);
+ WidgetComponent wc = (WidgetComponent) App.GetComponent (ob, null, null);
+ WidgetInfo wi = GetWidget (wc.Name);
+ if (wi == null) {
+ wi = new WidgetInfo (this, wc);
+ widgets.Add (wi);
+ }
+ return wi;
+ }
+
+ public object AddNewComponent (string fileName)
+ {
+ object ob = ProjectBackend.AddNewComponent (fileName);
+ object component = App.GetComponent (ob, null, null);
+
+ if (component is WidgetComponent) {
+ var wc = (WidgetComponent) component;
+ WidgetInfo wi = GetWidget (wc.Name);
+ if (wi == null) {
+ wi = new WidgetInfo (this, wc);
+ widgets.Add (wi);
+ }
+ return wi;
+ }
+
+ if (component is ActionGroupComponent) {
+ var ac = (ActionGroupComponent) component;
+ // Don't wait for the group added event to come to update the groups list since
+ // it may be too late.
+ ActionGroupInfo gi = GetActionGroup (ac.Name);
+ if (gi == null) {
+ gi = new ActionGroupInfo (this, ac.Name);
+ groups.Add (gi);
+ }
+ return gi;
+ }
+
+ return null;
+ }
+
+ public ComponentType[] GetComponentTypes ()
+ {
+ ArrayList types = new ArrayList ();
+
+ ArrayList typeNames = ProjectBackend.GetComponentTypes ();
+ for (int n=0; n<typeNames.Count; n++)
+ types.Add (app.GetComponentType ((string) typeNames [n]));
+
+ // Global action groups
+ foreach (ActionGroupComponent grp in GetActionGroups ()) {
+ foreach (ActionComponent ac in grp.GetActions ())
+ types.Add (new ComponentType (app, ac));
+ }
+
+ return (ComponentType[]) types.ToArray (typeof(ComponentType));
+ }
+
+ // Returns a list of all support widget types (including base classes)
+ public string[] GetWidgetTypes ()
+ {
+ return ProjectBackend.GetWidgetTypes ();
+ }
+
+ public void RemoveComponent (WidgetInfo component)
+ {
+ ProjectBackend.RemoveWidget (component.Name);
+ }
+
+ public WidgetComponent GetComponent (string name)
+ {
+ object ob = ProjectBackend.GetTopLevelWrapper (name, false);
+ if (ob != null)
+ return (WidgetComponent) App.GetComponent (ob, name, null);
+ else
+ return null;
+ }
+
+ public ActionGroupComponent AddNewActionGroup (string id)
+ {
+ object ob = ProjectBackend.AddNewActionGroup (id);
+ ActionGroupComponent ac = (ActionGroupComponent) App.GetComponent (ob, id, null);
+
+ // Don't wait for the group added event to come to update the groups list since
+ // it may be too late.
+ ActionGroupInfo gi = GetActionGroup (ac.Name);
+ if (gi == null) {
+ gi = new ActionGroupInfo (this, ac.Name);
+ groups.Add (gi);
+ }
+ return ac;
+ }
+
+ public ActionGroupComponent AddNewActionGroup (XmlElement template)
+ {
+ object ob = ProjectBackend.AddNewActionGroupFromTemplate (template.OuterXml);
+ ActionGroupComponent ac = (ActionGroupComponent) App.GetComponent (ob, null, null);
+
+ // Don't wait for the group added event to come to update the groups list since
+ // it may be too late.
+ ActionGroupInfo gi = GetActionGroup (ac.Name);
+ if (gi == null) {
+ gi = new ActionGroupInfo (this, ac.Name);
+ groups.Add (gi);
+ }
+ return ac;
+ }
+
+ public void RemoveActionGroup (ActionGroupInfo group)
+ {
+ ActionGroupComponent ac = (ActionGroupComponent) group.Component;
+ ProjectBackend.RemoveActionGroup ((Stetic.Wrapper.ActionGroup) ac.Backend);
+ }
+
+ internal ActionGroupComponent[] GetActionGroups ()
+ {
+ Wrapper.ActionGroup[] acs = ProjectBackend.GetActionGroups ();
+
+ ArrayList comps = new ArrayList (acs.Length);
+ for (int n=0; n<acs.Length; n++) {
+ ActionGroupComponent ag = (ActionGroupComponent) App.GetComponent (acs[n], null, null);
+ if (ag != null)
+ comps.Add (ag);
+ }
+
+ return (ActionGroupComponent[]) comps.ToArray (typeof(ActionGroupComponent));
+ }
+
+ public void AddWidgetLibrary (string assemblyPath)
+ {
+ AddWidgetLibrary (assemblyPath, false);
+ }
+
+ public void AddWidgetLibrary (string assemblyPath, bool isInternal)
+ {
+ reloadRequested = false;
+ ProjectBackend.AddWidgetLibrary (assemblyPath, isInternal);
+ app.UpdateWidgetLibraries (false, false);
+ if (!reloadRequested)
+ ProjectBackend.Reload ();
+ }
+
+ public void RemoveWidgetLibrary (string assemblyPath)
+ {
+ reloadRequested = false;
+ ProjectBackend.RemoveWidgetLibrary (assemblyPath);
+ app.UpdateWidgetLibraries (false, false);
+ if (!reloadRequested)
+ ProjectBackend.Reload ();
+ }
+
+ public string[] WidgetLibraries {
+ get {
+ return (string[]) ProjectBackend.WidgetLibraries.ToArray (typeof(string));
+ }
+ }
+
+ public void SetWidgetLibraries (string[] libraries, string[] internalLibraries)
+ {
+ reloadRequested = false;
+
+ ArrayList libs = new ArrayList ();
+ libs.AddRange (libraries);
+ libs.AddRange (internalLibraries);
+ ProjectBackend.WidgetLibraries = libs;
+
+ libs = new ArrayList ();
+ libs.AddRange (internalLibraries);
+ ProjectBackend.InternalWidgetLibraries = libs;
+
+ app.UpdateWidgetLibraries (false, false);
+ if (!reloadRequested)
+ ProjectBackend.Reload ();
+ }
+
+/* public bool CanCopySelection {
+ get { return Selection != null ? Selection.CanCopy : false; }
+ }
+
+ public bool CanCutSelection {
+ get { return Selection != null ? Selection.CanCut : false; }
+ }
+
+ public bool CanPasteToSelection {
+ get { return Selection != null ? Selection.CanPaste : false; }
+ }
+
+ public void CopySelection ()
+ {
+ if (Selection != null)
+ backend.ClipboardCopySelection ();
+ }
+
+ public void CutSelection ()
+ {
+ if (Selection != null)
+ backend.ClipboardCutSelection ();
+ }
+
+ public void PasteToSelection ()
+ {
+ if (Selection != null)
+ backend.ClipboardPaste ();
+ }
+
+ public void DeleteSelection ()
+ {
+ backend.DeleteSelection ();
+ }
+*/
+
+ public void EditIcons ()
+ {
+ ProjectBackend.EditIcons ();
+ }
+
+ internal void NotifyWidgetAdded (object obj, string name, string typeName)
+ {
+ GuiDispatch.InvokeSync (
+ delegate {
+ Component c = App.GetComponent (obj, name, typeName);
+ if (c != null) {
+ WidgetInfo wi = GetWidget (c.Name);
+ if (wi == null) {
+ wi = new WidgetInfo (this, c);
+ widgets.Add (wi);
+ }
+ if (WidgetAdded != null)
+ WidgetAdded (this, new WidgetInfoEventArgs (this, wi));
+ }
+ }
+ );
+ }
+
+ internal void NotifyWidgetRemoved (string name)
+ {
+ GuiDispatch.InvokeSync (
+ delegate {
+ WidgetInfo wi = GetWidget (name);
+ if (wi != null) {
+ widgets.Remove (wi);
+ if (WidgetRemoved != null)
+ WidgetRemoved (this, new WidgetInfoEventArgs (this, wi));
+ }
+ }
+ );
+ }
+
+ internal void NotifyModifiedChanged ()
+ {
+ GuiDispatch.InvokeSync (
+ delegate {
+ if (ModifiedChanged != null)
+ ModifiedChanged (this, EventArgs.Empty);
+ }
+ );
+ }
+
+ internal void NotifyChanged (string rootWidgetName)
+ {
+ GuiDispatch.InvokeSync (
+ delegate {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+
+ // TODO: Optimize
+ foreach (ProjectItemInfo it in widgets) {
+ if (it.Name == rootWidgetName)
+ it.NotifyChanged ();
+ }
+ foreach (ProjectItemInfo it in groups) {
+ if (it.Name == rootWidgetName)
+ it.NotifyChanged ();
+ }
+ }
+ );
+ }
+
+ internal void NotifyWidgetNameChanged (object obj, string oldName, string newName, bool isRoot)
+ {
+ WidgetComponent c = obj != null ? (WidgetComponent) App.GetComponent (obj, null, null) : null;
+ if (c != null)
+ c.UpdateName (newName);
+
+ if (isRoot) {
+ WidgetInfo wi = GetWidget (oldName);
+ if (wi != null)
+ wi.NotifyNameChanged (newName);
+ }
+
+ GuiDispatch.InvokeSync (
+ delegate {
+ if (c != null) {
+ if (ComponentNameChanged != null)
+ ComponentNameChanged (this, new ComponentNameEventArgs (this, c, oldName));
+ }
+ }
+ );
+ }
+
+ internal void NotifyActionGroupAdded (string group)
+ {
+ GuiDispatch.InvokeSync (delegate {
+ ActionGroupInfo gi = GetActionGroup (group);
+ if (gi == null) {
+ gi = new ActionGroupInfo (this, group);
+ groups.Add (gi);
+ }
+ if (ActionGroupsChanged != null)
+ ActionGroupsChanged (this, EventArgs.Empty);
+ });
+ }
+
+ internal void NotifyActionGroupRemoved (string group)
+ {
+ GuiDispatch.InvokeSync (delegate {
+ ActionGroupInfo gi = GetActionGroup (group);
+ if (gi != null) {
+ groups.Remove (gi);
+ if (ActionGroupsChanged != null)
+ ActionGroupsChanged (this, EventArgs.Empty);
+ }
+ });
+ }
+
+ internal void NotifySignalAdded (object obj, string name, Signal signal)
+ {
+ GuiDispatch.InvokeSync (delegate {
+ if (SignalAdded != null) {
+ Component c = App.GetComponent (obj, name, null);
+ if (c != null)
+ SignalAdded (this, new ComponentSignalEventArgs (this, c, null, signal));
+ }
+ });
+ }
+
+ internal void NotifySignalRemoved (object obj, string name, Signal signal)
+ {
+ GuiDispatch.InvokeSync (delegate {
+ if (SignalRemoved != null) {
+ Component c = App.GetComponent (obj, name, null);
+ if (c != null)
+ SignalRemoved (this, new ComponentSignalEventArgs (this, c, null, signal));
+ }
+ });
+ }
+
+ internal void NotifySignalChanged (object obj, string name, Signal oldSignal, Signal signal)
+ {
+ GuiDispatch.InvokeSync (delegate {
+ if (SignalChanged != null) {
+ Component c = App.GetComponent (obj, name, null);
+ if (c != null)
+ SignalChanged (this, new ComponentSignalEventArgs (this, c, oldSignal, signal));
+ }
+ });
+ }
+
+ internal void NotifyProjectReloaded ()
+ {
+ GuiDispatch.InvokeSync (delegate {
+ if (ProjectReloaded != null)
+ ProjectReloaded (this, EventArgs.Empty);
+ });
+ }
+
+ internal void NotifyProjectReloading ()
+ {
+ GuiDispatch.InvokeSync (delegate {
+ if (ProjectReloading != null)
+ ProjectReloading (this, EventArgs.Empty);
+ });
+ }
+
+ internal void NotifyComponentTypesChanged ()
+ {
+ GuiDispatch.InvokeSync (delegate {
+ if (ComponentTypesChanged != null)
+ ComponentTypesChanged (this, EventArgs.Empty);
+ });
+ }
+
+ internal string ImportFile (string filePath)
+ {
+ if (importFileDelegate != null) {
+ string res = null;
+ GuiDispatch.InvokeSync (delegate {
+ res = importFileDelegate (filePath);
+ });
+ return res;
+ }
+ else
+ return filePath;
+ }
+
+ internal void NotifyUpdateLibraries ()
+ {
+ app.UpdateWidgetLibraries (false, false);
+ }
+
+ void OnBackendChanging ()
+ {
+ selection = null;
+
+ if (BackendChanging != null)
+ BackendChanging ();
+ }
+
+ void OnBackendChanged (ApplicationBackend oldBackend)
+ {
+ if (oldBackend != null) {
+ tmpProjectFile = Path.GetTempFileName ();
+ backend.Save (tmpProjectFile);
+ backend.Dispose ();
+ }
+
+ backend = app.Backend.CreateProject ();
+ backend.SetFrontend (this);
+
+ if (tmpProjectFile != null && File.Exists (tmpProjectFile)) {
+// backend.Load (tmpProjectFile, fileName);
+ throw new NotImplementedException ("OnBackendChanged");
+ File.Delete (tmpProjectFile);
+ tmpProjectFile = null;
+ } else if (folderName != null) {
+ backend.Load (folderName);
+ }
+
+ if (resourceProvider != null)
+ backend.ResourceProvider = resourceProvider;
+
+ if (BackendChanged != null)
+ BackendChanged (oldBackend);
+
+ if (ProjectReloaded != null)
+ ProjectReloaded (this, EventArgs.Empty);
+ }
+ }
+
+ public abstract class ProjectItemInfo
+ {
+ string name;
+ protected Project project;
+
+ public event EventHandler Changed;
+
+ internal ProjectItemInfo (Project project, string name)
+ {
+ this.name = name;
+ this.project = project;
+ }
+
+ public string Name {
+ get { return name; }
+ set { Component.Name = value; name = value; }
+ }
+
+ internal void NotifyNameChanged (string name)
+ {
+ this.name = name;
+ NotifyChanged ();
+ }
+
+ internal void NotifyChanged ()
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+
+ public abstract Component Component { get; }
+ }
+
+ public class WidgetInfo: ProjectItemInfo
+ {
+ string type;
+ List<ActionGroupInfo> groups;
+
+ internal WidgetInfo (Project project, string name, string type): base (project, name)
+ {
+ this.type = type;
+ }
+
+ internal WidgetInfo (Project project, Component c): base (project, c.Name)
+ {
+ type = c.Type.Name;
+ }
+
+ public IEnumerable<ActionGroupInfo> ActionGroups {
+ get {
+ if (groups != null)
+ return groups;
+ else
+ return new ActionGroupInfo [0];
+ }
+ }
+
+ public string Type {
+ get { return type; }
+ }
+
+ public bool IsWindow {
+ get { return type == "Gtk.Dialog" || type == "Gtk.Window"; }
+ }
+
+ public override Component Component {
+ get { return project.GetComponent (Name); }
+ }
+
+ internal void AddGroup (string group)
+ {
+ if (groups == null)
+ groups = new List<ActionGroupInfo> ();
+ groups.Add (new ActionGroupInfo (project, group, Name));
+ }
+ }
+
+ public class ActionGroupInfo: ProjectItemInfo
+ {
+ string widgetName;
+
+ internal ActionGroupInfo (Project project, string name): base (project, name)
+ {
+ }
+
+ internal ActionGroupInfo (Project project, string name, string widgetName): base (project, name)
+ {
+ this.widgetName = widgetName;
+ }
+
+ public override Component Component {
+ get {
+ ActionGroupComponent[] ags;
+ if (widgetName != null) {
+ WidgetComponent c = project.GetComponent (widgetName) as WidgetComponent;
+ if (c == null)
+ return null;
+ ags = c.GetActionGroups ();
+ }
+ else {
+ ags = project.GetActionGroups ();
+ }
+ foreach (ActionGroupComponent ag in ags)
+ if (ag.Name == Name)
+ return ag;
+ return null;
+ }
+ }
+ }
+
+ public delegate string ImportFileDelegate (string fileName);
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectBackend.cs
new file mode 100644
index 0000000000..677c0a4af6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectBackend.cs
@@ -0,0 +1,1237 @@
+using Gtk;
+using System;
+using System.IO;
+using System.Xml;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.CodeDom;
+using Mono.Unix;
+
+namespace Stetic {
+
+ internal class ProjectBackend : MarshalByRefObject, IProject, IDisposable
+ {
+ List<WidgetData> topLevels;
+ bool modified;
+ Gtk.Widget selection;
+ string id;
+ string folderName;
+ XmlDocument tempDoc;
+ bool loading;
+ IResourceProvider resourceProvider;
+
+ // Global action groups of the project
+ Stetic.Wrapper.ActionGroupCollection actionGroups;
+ bool ownedGlobalActionGroups = true; // It may be false when reusing groups from another project
+
+ Stetic.ProjectIconFactory iconFactory;
+ Project frontend;
+ ArrayList widgetLibraries;
+ ArrayList internalLibs;
+ ApplicationBackend app;
+ AssemblyResolver resolver;
+ string imagesRootPath;
+ string targetGtkVersion;
+ List<string> modifiedTopLevels;
+ //During project conversion flag is set
+ bool converting;
+
+ // The action collection of the last selected widget
+ Stetic.Wrapper.ActionGroupCollection oldTopActionCollection;
+
+ public event Wrapper.WidgetNameChangedHandler WidgetNameChanged;
+ public event Wrapper.WidgetEventHandler WidgetAdded;
+ public event Wrapper.WidgetEventHandler WidgetContentsChanged;
+ public event ObjectWrapperEventHandler ObjectChanged;
+ public event EventHandler ComponentTypesChanged;
+
+ public event SignalEventHandler SignalAdded;
+ public event SignalEventHandler SignalRemoved;
+ public event SignalChangedEventHandler SignalChanged;
+
+ public event Wrapper.WidgetEventHandler SelectionChanged;
+ public event ProjectChangedEventHandler Changed;
+
+ // Fired when the project has been reloaded, due for example to
+ // a change in the registry
+ public event EventHandler ProjectReloading;
+ public event EventHandler ProjectReloaded;
+
+ public ProjectBackend (ApplicationBackend app)
+ {
+ this.app = app;
+ topLevels = new List<WidgetData> ();
+
+ ActionGroups = new Stetic.Wrapper.ActionGroupCollection ();
+
+ Registry.RegistryChanging += OnRegistryChanging;
+ Registry.RegistryChanged += OnRegistryChanged;
+
+ iconFactory = new ProjectIconFactory ();
+ widgetLibraries = new ArrayList ();
+ internalLibs = new ArrayList ();
+ modifiedTopLevels = new List<string> ();
+ }
+
+ public void Dispose ()
+ {
+ // First of all, disconnect from the frontend,
+ // to avoid sending notifications while disposing
+ frontend = null;
+
+ if (oldTopActionCollection != null)
+ oldTopActionCollection.ActionGroupChanged -= OnComponentTypesChanged;
+
+ Registry.RegistryChanging -= OnRegistryChanging;
+ Registry.RegistryChanged -= OnRegistryChanged;
+ Close ();
+ iconFactory = null;
+ ActionGroups = null;
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+
+
+ public string FileName {
+ get { throw new Exception("FileName is obsolete"); }
+ set { throw new Exception("FileName is obsolete"); }
+ }
+
+ public string FolderName {
+ get { return folderName; }
+ set {
+ this.folderName = value;
+ if (folderName != null )
+ Id = System.IO.Path.GetFullPath (folderName);
+ else
+ Id = null;
+ }
+ }
+
+ internal ArrayList WidgetLibraries {
+ get { return widgetLibraries; }
+ set { widgetLibraries = value; }
+ }
+
+ internal ArrayList InternalWidgetLibraries {
+ get { return internalLibs; }
+ set { internalLibs = value; }
+ }
+
+ public bool IsInternalLibrary (string lib)
+ {
+ return internalLibs.Contains (lib);
+ }
+
+ public bool CanGenerateCode {
+ get {
+ // It can generate code if all libraries on which depend can generate code
+ foreach (string s in widgetLibraries) {
+ WidgetLibrary lib = Registry.GetWidgetLibrary (s);
+ if (lib != null && !lib.CanGenerateCode)
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public string TargetGtkVersion {
+ get { return targetGtkVersion ?? string.Empty; }
+ set {
+ if (TargetGtkVersion == value)
+ return;
+ targetGtkVersion = value;
+
+// Update the project
+ OnRegistryChanging (null, null);
+ OnRegistryChanged (null, null);
+ }
+ }
+
+ public string ImagesRootPath {
+ get {
+ if (string.IsNullOrEmpty (imagesRootPath)) {
+ if (string.IsNullOrEmpty (folderName))
+ return ".";
+ else
+ return Path.GetFullPath (folderName);
+ }
+ else {
+ if (Path.IsPathRooted (imagesRootPath))
+ return imagesRootPath;
+ else if (!string.IsNullOrEmpty (folderName))
+ return Path.GetFullPath (Path.Combine (folderName, imagesRootPath));
+ else
+ return imagesRootPath;
+ }
+ }
+ set { imagesRootPath = value; }
+ }
+
+
+ public void AddWidgetLibrary (string lib)
+ {
+ AddWidgetLibrary (lib, false);
+ }
+
+ public void AddWidgetLibrary (string lib, bool isInternal)
+ {
+ if (!widgetLibraries.Contains (lib))
+ widgetLibraries.Add (lib);
+ if (isInternal) {
+ if (!internalLibs.Contains (lib))
+ internalLibs.Add (lib);
+ }
+ else {
+ internalLibs.Remove (lib);
+ }
+ }
+
+ public void RemoveWidgetLibrary (string lib)
+ {
+ widgetLibraries.Remove (lib);
+ internalLibs.Remove (lib);
+ }
+
+ public ArrayList GetComponentTypes ()
+ {
+ ArrayList list = new ArrayList ();
+ foreach (WidgetLibrary lib in app.GetProjectLibraries (this)) {
+ // Don't include in the list widgets which are internal (when the library is
+ // not internal to the project), widgets not assigned to any category, and deprecated ones.
+ bool isInternalLib = IsInternalLibrary (lib.Name);
+ if (lib.NeedsReload)
+ lib.Reload ();
+ foreach (ClassDescriptor cd in lib.AllClasses) {
+ if (!cd.Deprecated && cd.Category.Length > 0 && (isInternalLib || !cd.IsInternal) && cd.SupportsGtkVersion (TargetGtkVersion))
+ list.Add (cd.Name);
+ }
+ }
+ return list;
+ }
+
+ public string[] GetWidgetTypes ()
+ {
+ List<string> list = new List<string> ();
+ foreach (WidgetLibrary lib in app.GetProjectLibraries (this)) {
+ // Don't include in the list widgets which are internal (when the library is
+ // not internal to the project) and deprecated ones.
+ bool isInternalLib = IsInternalLibrary (lib.Name);
+ foreach (ClassDescriptor cd in lib.AllClasses) {
+ if (!cd.Deprecated && (isInternalLib || !cd.IsInternal))
+ list.Add (cd.Name);
+ }
+ }
+ return list.ToArray ();
+ }
+
+ public IResourceProvider ResourceProvider {
+ get { return resourceProvider; }
+ set { resourceProvider = value; }
+ }
+
+ public Stetic.Wrapper.ActionGroupCollection ActionGroups {
+ get { return actionGroups; }
+ set {
+ if (actionGroups != null) {
+ actionGroups.ActionGroupAdded -= OnGroupAdded;
+ actionGroups.ActionGroupRemoved -= OnGroupRemoved;
+ actionGroups.ActionGroupChanged -= OnComponentTypesChanged;
+ }
+ actionGroups = value;
+ if (actionGroups != null) {
+ actionGroups.ActionGroupAdded += OnGroupAdded;
+ actionGroups.ActionGroupRemoved += OnGroupRemoved;
+ actionGroups.ActionGroupChanged += OnComponentTypesChanged;
+ }
+ ownedGlobalActionGroups = true;
+ }
+ }
+
+ public void AttachActionGroups (Stetic.Wrapper.ActionGroupCollection groups)
+ {
+ ActionGroups = groups;
+ ownedGlobalActionGroups = false;
+ }
+
+ public Stetic.ProjectIconFactory IconFactory {
+ get { return iconFactory; }
+ set { iconFactory = value; }
+ }
+
+ internal void SetFrontend (Project project)
+ {
+ frontend = project;
+ }
+
+ public void Close ()
+ {
+ if (actionGroups != null && ownedGlobalActionGroups) {
+ foreach (Stetic.Wrapper.ActionGroup ag in actionGroups)
+ ag.Dispose ();
+ actionGroups.Clear ();
+ }
+
+ foreach (WidgetData wd in topLevels) {
+ if (wd.Widget != null)
+ wd.Widget.Destroy ();
+ }
+
+ selection = null;
+ topLevels.Clear ();
+ //widgetLibraries.Clear ();
+
+
+ iconFactory = new ProjectIconFactory ();
+ }
+
+ public void Load (string folderName)
+ {
+ this.folderName = folderName;
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+ XmlElement toplevel = doc.CreateElement ("stetic-interface");
+ doc.AppendChild (toplevel);
+ modifiedTopLevels.Clear ();
+
+ ReadIconFactory (doc);
+ ReadActionGroups (doc);
+ ReadTopLevels (doc);
+ Read (doc);
+
+ Id = System.IO.Path.GetFullPath (folderName);
+ }
+
+ public void LoadOldVersion (string fileName)
+ {
+ if (!File.Exists (fileName))
+ return;
+
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+ doc.Load (fileName);
+
+ Read (doc);
+
+ Id = System.IO.Path.GetFileName (fileName);
+ }
+
+ void ReadIconFactory (XmlDocument doc)
+ {
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ return;
+
+ string basePath = folderName;
+ string xmlfile = Path.Combine(basePath, "IconFactory.gtkx");
+
+ if (File.Exists (xmlfile)) {
+
+ XmlDocument doc2 = new XmlDocument ();
+ doc2.PreserveWhitespace = true;
+ doc2.Load (xmlfile);
+
+ XmlNode ifnode2 = doc2.SelectSingleNode ("/stetic-interface/icon-factory");
+
+ if (ifnode2 != null) {
+ XmlNode ifnode = doc.ImportNode (ifnode2, true);
+ node.AppendChild (ifnode);
+ }
+ }
+ }
+
+ void ReadActionGroups (XmlDocument doc)
+ {
+ ReadSplitFiles (doc, "action-group", "name");
+ }
+
+ void ReadTopLevels (XmlDocument doc)
+ {
+ ReadSplitFiles (doc, "widget", "id");
+ }
+
+ void ReadSplitFiles (XmlDocument doc, string splitElement, string idAttribute)
+ {
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ return;
+
+ foreach (string basePath in frontend.DesignInfo.GetComponentFolders ()) {
+ DirectoryInfo dir = new DirectoryInfo (basePath);
+
+ foreach (FileInfo file in dir.GetFiles ()) {
+ if (file.Extension == ".gtkx") {
+
+ XmlDocument wdoc = new XmlDocument ();
+ wdoc.PreserveWhitespace = true;
+ wdoc.Load (file.FullName);
+
+ XmlNode wnode = wdoc.SelectSingleNode ("/stetic-interface");
+
+ foreach (XmlElement toplevel in wnode.SelectNodes (splitElement)) {
+ string id = toplevel.GetAttribute (idAttribute);
+
+ if (frontend.DesignInfo.HasComponentFile (id)) {
+ XmlNode imported = doc.ImportNode (toplevel, true);
+ node.AppendChild (imported);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void AddActionGroup (XmlElement groupElem)
+ {
+ ObjectReader reader = new ObjectReader (this, FileFormat.Native);
+
+ Wrapper.ActionGroup actionGroup = new Wrapper.ActionGroup ();
+ actionGroup.Read (reader, groupElem);
+ actionGroups.Add (actionGroup);
+ }
+
+ void AddWidget (XmlElement toplevel)
+ {
+ topLevels.Add (new WidgetData (toplevel.GetAttribute ("id"), toplevel, null));
+ }
+
+ void Read (XmlDocument doc)
+ {
+ loading = true;
+
+ try {
+ Close ();
+
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ throw new ApplicationException (Catalog.GetString ("Not a Stetic file according to node name."));
+
+ // Load the assembly directories
+ resolver = new AssemblyResolver (app);
+ app.LoadLibraries (resolver, widgetLibraries);
+
+ if (ownedGlobalActionGroups) {
+ foreach (XmlElement groupElem in node.SelectNodes ("action-group"))
+ AddActionGroup (groupElem);
+ }
+
+ XmlElement iconsElem = node.SelectSingleNode ("icon-factory") as XmlElement;
+ if (iconsElem != null)
+ iconFactory.Read (this, iconsElem);
+
+ foreach (XmlElement toplevel in node.SelectNodes ("widget"))
+ AddWidget (toplevel);
+
+ } finally {
+ loading = false;
+ }
+ }
+
+ public Gtk.Widget GetWidget (WidgetData data)
+ {
+ if (data.Widget == null) {
+ try {
+ loading = true;
+ ObjectReader reader = new ObjectReader (this, FileFormat.Native);
+ Wrapper.Container wrapper = Stetic.ObjectWrapper.ReadObject (reader, data.XmlData, null) as Wrapper.Container;
+ data.Widget = wrapper.Wrapped;
+ data.Widget.Destroyed += (s,e) => data.Widget = null;
+ } finally {
+ loading = false;
+ }
+ }
+
+ return data.Widget;
+ }
+
+ public bool ReloadTopLevel (string topLevelName)
+ {
+ XmlElement topLevelElem = ReadDesignerFile (topLevelName, "widget");
+ if (topLevelName != null) {
+ WidgetData data = GetWidgetData (topLevelName);
+
+ if (data != null) {
+ //Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (data.Widget);
+ data.SetXmlData (topLevelName, topLevelElem);
+ GetWidget (data);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void ReloadComponent (string componentName)
+ {
+ ReloadTopLevel (componentName);
+ //TODO: Make reloading works for action groups
+ }
+
+
+ public void ReloadActionGroup (string groupName)
+ {
+ //TODO : Implement method ReloadActionGroup
+ }
+
+ XmlElement ReadDesignerFile (string componentName, string elementName)
+ {
+ string gtkxFile = GetDesignerFileName (componentName);
+ if (gtkxFile != null) {
+ XmlDocument wdoc = new XmlDocument ();
+ wdoc.PreserveWhitespace = true;
+ wdoc.Load (gtkxFile);
+
+ XmlNode wnode = wdoc.SelectSingleNode ("/stetic-interface");
+ foreach (XmlElement toplevel in wnode.SelectNodes (elementName)) {
+ return toplevel;
+ }
+
+ string msg = string.Format (@"Cannot find /stetic-interface/{0} element in {1} file.",
+ elementName, gtkxFile);
+ throw new InvalidOperationException (msg);
+ }
+
+ return null;
+ }
+
+ public void ConvertProject (string oldSteticFileName, string newGuiFolderName)
+ {
+ converting = true;
+ try {
+ LoadOldVersion (oldSteticFileName);
+ Save (newGuiFolderName);
+ } finally {
+ converting = false;
+ }
+ }
+
+ public void Save (string folderName)
+ {
+ this.folderName = folderName;
+ XmlDocument doc = Write (false);
+
+ XmlTextWriter writer = null;
+ try {
+ WriteIconFactory (doc);
+ WriteActionGroups (doc);
+ WriteTopLevels (doc);
+
+ } finally {
+ if (writer != null)
+ writer.Close ();
+ }
+ }
+
+ private void WriteIconFactory (XmlDocument doc)
+ {
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ return;
+
+ XmlNode ifnode = node.SelectSingleNode ("icon-factory");
+ if (ifnode == null)
+ return;
+
+ XmlDocument doc2 = new XmlDocument ();
+ doc2.PreserveWhitespace = true;
+
+ XmlElement node2 = doc2.CreateElement ("stetic-interface");
+ doc2.AppendChild (node2);
+
+ XmlNode ifnode2 = doc2.ImportNode (ifnode, true);
+ node2.AppendChild (ifnode2);
+
+ string basePath = this.folderName;
+ string xmlFile = Path.Combine (basePath, "IconFactory.gtkx");
+ WriteXmlFile (xmlFile, doc2);
+
+ node.RemoveChild (ifnode);
+ }
+
+ void WriteActionGroups (XmlDocument doc)
+ {
+ WriteSplitFiles (doc, "action-group", "name");
+ }
+
+ void WriteTopLevels (XmlDocument doc)
+ {
+ WriteSplitFiles (doc, "widget", "id");
+ }
+
+ void WriteSplitFiles (XmlDocument doc, string splitElement, string idAttribute)
+ {
+ XmlNode node = doc.SelectSingleNode ("/stetic-interface");
+ if (node == null)
+ return;
+
+ foreach (XmlElement toplevel in node.SelectNodes (splitElement)) {
+
+ string id = toplevel.GetAttribute (idAttribute);
+ if (modifiedTopLevels.Contains (id) || converting) {
+ string xmlFile = GetDesignerFileName (id);
+ if (xmlFile != null) {
+ XmlDocument doc2 = new XmlDocument ();
+ doc2.PreserveWhitespace = true;
+
+ XmlElement node2 = doc2.CreateElement ("stetic-interface");
+ doc2.AppendChild (node2);
+
+ XmlNode wnode2 = doc2.ImportNode (toplevel, true);
+ node2.AppendChild (wnode2);
+
+ WriteXmlFile (xmlFile, doc2);
+ if (modifiedTopLevels.Contains (id))
+ modifiedTopLevels.Remove (id);
+ }
+ }
+ }
+ }
+
+ private string GetDesignerFileName (string componentName)
+ {
+ string componentFile = frontend.DesignInfo.GetComponentFile (componentName);
+ return frontend.DesignInfo.GetDesignerFileFromComponent (componentFile);
+ }
+
+ void WriteXmlFile (string xmlFile, XmlDocument doc)
+ {
+ XmlTextWriter writer = null;
+ try {
+ writer = new XmlTextWriter (xmlFile + "~", System.Text.Encoding.UTF8);
+ writer.Formatting = Formatting.Indented;
+
+ doc.Save (writer);
+ writer.Close ();
+
+ File.Copy (xmlFile + "~", xmlFile, true);
+ File.Delete (xmlFile + "~");
+ } finally {
+ if (writer != null)
+ writer.Close ();
+ }
+ }
+
+ XmlDocument Write (bool includeUndoInfo)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = true;
+
+ XmlElement toplevel = doc.CreateElement ("stetic-interface");
+ doc.AppendChild (toplevel);
+
+ ObjectWriter writer = new ObjectWriter (doc, FileFormat.Native);
+ writer.CreateUndoInfo = includeUndoInfo;
+ if (ownedGlobalActionGroups) {
+ foreach (Wrapper.ActionGroup agroup in actionGroups) {
+ XmlElement elem = agroup.Write (writer);
+ toplevel.AppendChild (elem);
+ }
+ }
+
+ if (iconFactory.Icons.Count > 0)
+ toplevel.AppendChild (iconFactory.Write (doc));
+
+ foreach (WidgetData data in topLevels) {
+ if (data.Widget != null) {
+ Stetic.Wrapper.Container wrapper = Stetic.Wrapper.Container.Lookup (data.Widget);
+ if (wrapper == null)
+ continue;
+
+ XmlElement elem = wrapper.Write (writer);
+ if (elem != null)
+ toplevel.AppendChild (elem);
+ } else {
+ toplevel.AppendChild (doc.ImportNode (data.XmlData, true));
+ }
+ }
+
+ // Remove undo annotations from the xml document
+ if (!includeUndoInfo)
+ CleanUndoData (doc.DocumentElement);
+
+ return doc;
+ }
+
+ public void ImportGlade (string fileName)
+ {
+ GladeFiles.Import (this, fileName);
+ }
+
+ public void ExportGlade (string fileName)
+ {
+ GladeFiles.Export (this, fileName);
+ }
+
+ public void EditIcons ()
+ {
+ using (Stetic.Editor.EditIconFactoryDialog dlg = new Stetic.Editor.EditIconFactoryDialog (null, this, this.IconFactory)) {
+ dlg.Run ();
+ }
+ }
+
+// internal WidgetEditSession CreateWidgetDesignerSession (WidgetDesignerFrontend frontend, string windowName, Stetic.ProjectBackend editingBackend, bool autoCommitChanges)
+// {
+// return new WidgetEditSession (this, frontend, windowName, editingBackend, autoCommitChanges);
+// }
+
+ internal WidgetEditSession CreateWidgetDesignerSession (WidgetDesignerFrontend frontend, string windowName)
+ {
+ return new WidgetEditSession (this, frontend, windowName);
+ }
+
+ internal ActionGroupEditSession CreateGlobalActionGroupDesignerSession (ActionGroupDesignerFrontend frontend, string groupName, bool autoCommitChanges)
+ {
+ return new ActionGroupEditSession (frontend, this, null, groupName, autoCommitChanges);
+ }
+
+ internal ActionGroupEditSession CreateLocalActionGroupDesignerSession (ActionGroupDesignerFrontend frontend, string windowName, bool autoCommitChanges)
+ {
+ return new ActionGroupEditSession (frontend, this, windowName, null, autoCommitChanges);
+ }
+
+ public Wrapper.Container GetTopLevelWrapper (string name, bool throwIfNotFound)
+ {
+ Gtk.Widget w = GetWidget (name);
+ if (w != null) {
+ Wrapper.Container ww = Wrapper.Container.Lookup (w);
+ if (ww != null)
+ return (Wrapper.Container) Component.GetSafeReference (ww);
+ }
+ if (throwIfNotFound)
+ throw new InvalidOperationException ("Component not found: " + name);
+ return null;
+ }
+
+ public object AddNewComponent (string fileName)
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.PreserveWhitespace = true;
+ doc.Load (fileName);
+
+ XmlElement toplevel = (XmlElement)doc.SelectSingleNode ("/stetic-interface/widget");
+ if (toplevel != null)
+ return AddNewWidgetFromTemplate (toplevel.OuterXml);
+
+ XmlElement groupElem = (XmlElement)doc.SelectSingleNode ("/stetic-interface/action-group");
+ if (groupElem != null)
+ return AddNewActionGroupFromTemplate (groupElem.OuterXml);
+
+ return null;
+ }
+
+ public object AddNewWidget (string type, string name)
+ {
+ ClassDescriptor cls = Registry.LookupClassByName (type);
+ Gtk.Widget w = (Gtk.Widget) cls.NewInstance (this);
+ w.Name = name;
+ this.AddWidget (w);
+ return Component.GetSafeReference (ObjectWrapper.Lookup (w));
+ }
+
+ public object AddNewWidgetFromTemplate (string template)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml (template);
+ Gtk.Widget widget = Stetic.WidgetUtils.ImportWidget (this, doc.DocumentElement);
+ AddWidget (widget);
+
+ string name = widget.Name;
+ return Component.GetSafeReference (ObjectWrapper.Lookup (widget));
+ }
+
+ public void RemoveWidget (string name)
+ {
+ WidgetData data = GetWidgetData (name);
+ if (data == null)
+ return;
+
+ if (frontend != null)
+ frontend.NotifyWidgetRemoved (data.Name);
+
+ if (modifiedTopLevels.Contains (name))
+ modifiedTopLevels.Remove (name);
+ }
+
+ public Stetic.Wrapper.ActionGroup AddNewActionGroup (string name)
+ {
+ Stetic.Wrapper.ActionGroup group = new Stetic.Wrapper.ActionGroup ();
+ group.Name = name;
+ ActionGroups.Add (group);
+ this.modifiedTopLevels.Add (name);
+ return group;
+ }
+
+ public Stetic.Wrapper.ActionGroup AddNewActionGroupFromTemplate (string template)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.LoadXml (template);
+ ObjectReader or = new ObjectReader (this, FileFormat.Native);
+ Stetic.Wrapper.ActionGroup group = new Stetic.Wrapper.ActionGroup ();
+ group.Read (or, doc.DocumentElement);
+ ActionGroups.Add (group);
+ this.modifiedTopLevels.Add (group.Name);
+ return group;
+ }
+
+ public void RemoveActionGroup (Stetic.Wrapper.ActionGroup group)
+ {
+ ActionGroups.Remove (group);
+ string name = group.Name;
+ if (modifiedTopLevels.Contains (name))
+ modifiedTopLevels.Remove (name);
+ }
+
+ public Wrapper.ActionGroup[] GetActionGroups ()
+ {
+ // Needed since ActionGroupCollection can't be made serializable
+ return ActionGroups.ToArray ();
+ }
+
+ void CleanUndoData (XmlElement elem)
+ {
+ elem.RemoveAttribute ("undoId");
+ foreach (XmlNode cn in elem.ChildNodes) {
+ XmlElement ce = cn as XmlElement;
+ if (ce != null)
+ CleanUndoData (ce);
+ }
+ }
+
+ void OnRegistryChanging (object o, EventArgs args)
+ {
+ if (loading) return;
+
+ // Store a copy of the current tree. The tree will
+ // be recreated once the registry change is completed.
+
+ tempDoc = Write (true);
+ Selection = null;
+ }
+
+ void OnRegistryChanged (object o, EventArgs args)
+ {
+ if (loading) return;
+
+ if (tempDoc != null)
+ LoadStatus (tempDoc);
+ }
+
+ public object SaveStatus ()
+ {
+ return Write (true);
+ }
+
+ public void LoadStatus (object ob)
+ {
+ if (frontend != null)
+ frontend.NotifyProjectReloading ();
+ if (ProjectReloading != null)
+ ProjectReloading (this, EventArgs.Empty);
+
+ ProjectIconFactory icf = iconFactory;
+
+ Read ((XmlDocument)ob);
+
+ // Reuse the same icon factory, since a registry change has no effect to it
+ // and it may be inherited from another project
+ iconFactory = icf;
+
+ if (frontend != null)
+ frontend.NotifyProjectReloaded ();
+ if (ProjectReloaded != null)
+ ProjectReloaded (this, EventArgs.Empty);
+ NotifyComponentTypesChanged ();
+ }
+
+ bool preserveWidgetLibraries;
+
+ public void Reload ()
+ {
+ try {
+ preserveWidgetLibraries = true;
+ OnRegistryChanging (null, null);
+ OnRegistryChanged (null, null);
+ }
+ finally
+ {
+ preserveWidgetLibraries = false;
+ }
+ }
+
+ public string Id {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public bool WasModified (string topLevel)
+ {
+ return modifiedTopLevels.Contains (topLevel);
+ }
+
+ public bool ComponentNeedsCodeGeneration (string topLevel)
+ {
+ return frontend.DesignInfo.ComponentNeedsCodeGeneration (topLevel);
+ }
+
+ public AssemblyResolver Resolver {
+ get { return resolver; }
+ }
+
+ public string ImportFile (string filePath)
+ {
+ return frontend.ImportFile (filePath);
+ }
+
+ public void AddWindow (Gtk.Window window)
+ {
+ AddWindow (window, false);
+ }
+
+ public void AddWindow (Gtk.Window window, bool select)
+ {
+ AddWidget (window);
+ if (select)
+ Selection = window;
+ }
+
+ public void AddWidget (Gtk.Widget widget)
+ {
+ if (!typeof(Gtk.Container).IsInstanceOfType (widget))
+ throw new System.ArgumentException ("widget", "Only containers can be top level widgets");
+ topLevels.Add (new WidgetData (null, null, widget));
+
+ if (!loading) {
+ Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (widget);
+
+ if (ww == null)
+ throw new InvalidOperationException ("Widget not wrapped");
+ if (frontend != null)
+ frontend.NotifyWidgetAdded (Component.GetSafeReference (ww), widget.Name, ww.ClassDescriptor.Name);
+ OnWidgetAdded (new Stetic.Wrapper.WidgetEventArgs (ww));
+ }
+ }
+
+ void IProject.NotifyObjectChanged (ObjectWrapperEventArgs args)
+ {
+ if (loading)
+ return;
+ NotifyChanged (args.Wrapper.RootWrapperName);
+ if (ObjectChanged != null)
+ ObjectChanged (this, args);
+ }
+
+ void IProject.NotifyNameChanged (Stetic.Wrapper.WidgetNameChangedArgs args)
+ {
+ if (loading)
+ return;
+ NotifyChanged (args.WidgetWrapper.RootWrapperName);
+ OnWidgetNameChanged (args, args.WidgetWrapper.IsTopLevel);
+ }
+
+ void IProject.NotifySignalAdded (SignalEventArgs args)
+ {
+ if (loading)
+ return;
+ if (frontend != null)
+ frontend.NotifySignalAdded (Component.GetSafeReference (args.Wrapper), null, args.Signal);
+ OnSignalAdded (args);
+ }
+
+ void IProject.NotifySignalRemoved (SignalEventArgs args)
+ {
+ if (loading)
+ return;
+ if (frontend != null)
+ frontend.NotifySignalRemoved (Component.GetSafeReference (args.Wrapper), null, args.Signal);
+ OnSignalRemoved (args);
+ }
+
+ void IProject.NotifySignalChanged (SignalChangedEventArgs args)
+ {
+ if (loading)
+ return;
+ OnSignalChanged (args);
+ }
+
+ void IProject.NotifyWidgetContentsChanged (Wrapper.Widget w)
+ {
+ if (loading)
+ return;
+ if (WidgetContentsChanged != null)
+ WidgetContentsChanged (this, new Wrapper.WidgetEventArgs (w));
+ }
+
+ void OnWidgetNameChanged (Stetic.Wrapper.WidgetNameChangedArgs args, bool isTopLevel)
+ {
+ if (frontend != null)
+ frontend.NotifyWidgetNameChanged (Component.GetSafeReference (args.WidgetWrapper), args.OldName, args.NewName, isTopLevel);
+ if (args.WidgetWrapper != null && WidgetNameChanged != null)
+ WidgetNameChanged (this, args);
+
+ if (modifiedTopLevels.Contains (args.OldName))
+ modifiedTopLevels.Remove (args.OldName);
+
+ if (!modifiedTopLevels.Contains (args.NewName))
+ modifiedTopLevels.Add (args.NewName);
+ }
+
+ void OnSignalAdded (object sender, SignalEventArgs args)
+ {
+ if (frontend != null)
+ frontend.NotifySignalAdded (Component.GetSafeReference (args.Wrapper), null, args.Signal);
+ OnSignalAdded (args);
+ }
+
+ protected virtual void OnSignalAdded (SignalEventArgs args)
+ {
+ if (SignalAdded != null)
+ SignalAdded (this, args);
+ }
+
+ void OnSignalRemoved (object sender, SignalEventArgs args)
+ {
+ if (frontend != null)
+ frontend.NotifySignalRemoved (Component.GetSafeReference (args.Wrapper), null, args.Signal);
+ OnSignalRemoved (args);
+ }
+
+ protected virtual void OnSignalRemoved (SignalEventArgs args)
+ {
+ if (SignalRemoved != null)
+ SignalRemoved (this, args);
+ }
+
+ void OnSignalChanged (object sender, SignalChangedEventArgs args)
+ {
+ OnSignalChanged (args);
+ }
+
+ protected virtual void OnSignalChanged (SignalChangedEventArgs args)
+ {
+ if (frontend != null)
+ frontend.NotifySignalChanged (Component.GetSafeReference (args.Wrapper), null, args.OldSignal, args.Signal);
+ if (SignalChanged != null)
+ SignalChanged (this, args);
+ }
+
+ public Gtk.Widget[] Toplevels {
+ get {
+ List<Gtk.Widget> list = new List<Gtk.Widget> ();
+ foreach (WidgetData w in topLevels)
+ list.Add (GetWidget (w));
+ return list.ToArray ();
+ }
+ }
+
+ public Gtk.Widget GetWidget (string name)
+ {
+ WidgetData w = GetWidgetData (name);
+ if (w != null)
+ return GetWidget (w);
+ else
+ return null;
+ }
+
+ public WidgetData GetWidgetData (string name)
+ {
+ foreach (WidgetData w in topLevels) {
+ if (w.Name == name)
+ return w;
+ }
+ return null;
+ }
+
+ // IProject
+
+ public Gtk.Widget Selection {
+ get {
+ return selection;
+ }
+ set {
+ if (selection == value)
+ return;
+
+ Wrapper.ActionGroupCollection newCollection = null;
+
+ // FIXME: should there be an IsDestroyed property?
+ if (selection != null && selection.Handle != IntPtr.Zero) {
+ Stetic.Wrapper.Container parent = Stetic.Wrapper.Container.LookupParent (selection);
+ if (parent == null)
+ parent = Stetic.Wrapper.Container.Lookup (selection);
+ if (parent != null)
+ parent.UnSelect (selection);
+ }
+
+ selection = value;
+
+ if (selection != null && selection.Handle != IntPtr.Zero) {
+ Stetic.Wrapper.Container parent = Stetic.Wrapper.Container.LookupParent (selection);
+ if (parent == null)
+ parent = Stetic.Wrapper.Container.Lookup (selection);
+ if (parent != null)
+ parent.Select (selection);
+ Wrapper.Widget w = Wrapper.Widget.Lookup (selection);
+ if (w != null)
+ newCollection = w.LocalActionGroups;
+ }
+
+ if (SelectionChanged != null)
+ SelectionChanged (this, new Wrapper.WidgetEventArgs (Wrapper.Widget.Lookup (selection)));
+
+ if (oldTopActionCollection != newCollection) {
+ if (oldTopActionCollection != null)
+ oldTopActionCollection.ActionGroupChanged -= OnComponentTypesChanged;
+ if (newCollection != null)
+ newCollection.ActionGroupChanged += OnComponentTypesChanged;
+ oldTopActionCollection = newCollection;
+ OnComponentTypesChanged (null, null);
+ }
+ }
+ }
+
+ public void PopupContextMenu (Stetic.Wrapper.Widget wrapper)
+ {
+ Gtk.Menu m = new ContextMenu (wrapper);
+ m.Popup ();
+ }
+
+ public void PopupContextMenu (Placeholder ph)
+ {
+ Gtk.Menu m = new ContextMenu (ph);
+ m.Popup ();
+ }
+
+ internal static string AbsoluteToRelativePath (string baseDirectoryPath, string absPath)
+ {
+ if (!Path.IsPathRooted (absPath))
+ return absPath;
+
+ absPath = Path.GetFullPath (absPath);
+ baseDirectoryPath = Path.GetFullPath (baseDirectoryPath);
+ char[] separators = { Path.DirectorySeparatorChar, Path.VolumeSeparatorChar, Path.AltDirectorySeparatorChar };
+
+ string[] bPath = baseDirectoryPath.Split (separators);
+ string[] aPath = absPath.Split (separators);
+ int indx = 0;
+ for(; indx < Math.Min(bPath.Length, aPath.Length); ++indx) {
+ if(!bPath[indx].Equals(aPath[indx]))
+ break;
+ }
+
+ if (indx == 0) {
+ return absPath;
+ }
+
+ string erg = "";
+
+ if(indx == bPath.Length) {
+ erg += "." + Path.DirectorySeparatorChar;
+ } else {
+ for (int i = indx; i < bPath.Length; ++i) {
+ erg += ".." + Path.DirectorySeparatorChar;
+ }
+ }
+ erg += String.Join(Path.DirectorySeparatorChar.ToString(), aPath, indx, aPath.Length-indx);
+
+ return erg;
+ }
+
+ void OnComponentTypesChanged (object s, EventArgs a)
+ {
+ if (!loading)
+ NotifyComponentTypesChanged ();
+ }
+
+ public void NotifyComponentTypesChanged ()
+ {
+ if (frontend != null)
+ frontend.NotifyComponentTypesChanged ();
+ if (ComponentTypesChanged != null)
+ ComponentTypesChanged (this, EventArgs.Empty);
+ }
+
+ void OnGroupAdded (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ args.ActionGroup.SignalAdded += OnSignalAdded;
+ args.ActionGroup.SignalRemoved += OnSignalRemoved;
+ args.ActionGroup.SignalChanged += OnSignalChanged;
+ if (frontend != null)
+ frontend.NotifyActionGroupAdded (args.ActionGroup.Name);
+ OnComponentTypesChanged (null, null);
+ }
+
+ void OnGroupRemoved (object s, Stetic.Wrapper.ActionGroupEventArgs args)
+ {
+ args.ActionGroup.SignalAdded -= OnSignalAdded;
+ args.ActionGroup.SignalRemoved -= OnSignalRemoved;
+ args.ActionGroup.SignalChanged -= OnSignalChanged;
+ if (frontend != null)
+ frontend.NotifyActionGroupRemoved (args.ActionGroup.Name);
+ OnComponentTypesChanged (null, null);
+ }
+
+ void NotifyChanged (string rootWidgetName)
+ {
+ if (!modifiedTopLevels.Contains (rootWidgetName))
+ modifiedTopLevels.Add (rootWidgetName);
+ if (frontend != null)
+ frontend.NotifyChanged (rootWidgetName);
+ if (Changed != null)
+ Changed (this, new ProjectChangedEventArgs (rootWidgetName));
+ }
+
+ protected virtual void OnWidgetAdded (Stetic.Wrapper.WidgetEventArgs args)
+ {
+ NotifyChanged (args.WidgetWrapper.RootWrapperName);
+ if (WidgetAdded != null)
+ WidgetAdded (this, args);
+ }
+ }
+
+ class WidgetData
+ {
+ string name;
+
+ public WidgetData (string name, XmlElement data, Gtk.Widget widget)
+ {
+ SetXmlData (name, data);
+ Widget = widget;
+ }
+
+ public void SetXmlData (string name, XmlElement data)
+ {
+ this.name = name;
+ XmlData = data;
+ Widget = null;
+ }
+
+ public XmlElement XmlData;
+ public Gtk.Widget Widget;
+
+ public string Name {
+ get {
+ if (Widget != null)
+ return Widget.Name;
+ else
+ return name;
+ }
+ }
+ }
+
+ public class ProjectChangedEventArgs : EventArgs
+ {
+ public string ChangedTopLevelName { get; private set; }
+
+ public ProjectChangedEventArgs (string changedTopLevel)
+ {
+ ChangedTopLevelName = changedTopLevel;
+ }
+ }
+
+ public delegate void ProjectChangedEventHandler (object sender, ProjectChangedEventArgs args);
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectViewBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectViewBackend.cs
new file mode 100644
index 0000000000..3d93a71e7c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/ProjectViewBackend.cs
@@ -0,0 +1,345 @@
+using Gtk;
+using System;
+using Mono.Unix;
+using System.Collections.Generic;
+
+namespace Stetic {
+
+ internal class ProjectViewBackend : ScrolledWindow
+ {
+ ProjectViewBackendNodeView nodeView;
+
+ public ProjectViewBackend (ProjectViewFrontend frontend)
+ {
+ ShadowType = Gtk.ShadowType.In;
+ nodeView = new ProjectViewBackendNodeView (frontend);
+ Add (nodeView);
+ ShowAll ();
+ }
+
+ public event Wrapper.WidgetEventHandler WidgetActivated {
+ add { nodeView.WidgetActivated += value; }
+ remove { nodeView.WidgetActivated -= value; }
+ }
+
+ public void Bind (WidgetEditSession newSession)
+ {
+ nodeView.Bind (newSession);
+ }
+ }
+
+ internal class ProjectViewBackendNodeView : TreeView
+ {
+ ProjectViewFrontend frontend;
+ TreeStore store;
+ WidgetEditSession editSession;
+
+ const int ColIcon = 0;
+ const int ColName = 1;
+ const int ColWrapper = 2;
+ const int ColFilled = 3;
+
+ public event Wrapper.WidgetEventHandler WidgetActivated;
+
+ public ProjectViewBackendNodeView (ProjectViewFrontend frontend)
+ {
+ this.frontend = frontend;
+ HeadersVisible = false;
+
+ store = new TreeStore (typeof(Gdk.Pixbuf), typeof(string), typeof(ObjectWrapper), typeof(bool));
+ Model = store;
+
+ TreeViewColumn col;
+ CellRenderer renderer;
+
+ col = new TreeViewColumn ();
+
+ renderer = new CellRendererPixbuf ();
+ col.PackStart (renderer, false);
+ col.AddAttribute (renderer, "pixbuf", 0);
+
+ renderer = new CellRendererText ();
+ col.PackStart (renderer, true);
+ col.AddAttribute (renderer, "text", 1);
+
+ AppendColumn (col);
+
+ Selection.Mode = SelectionMode.Single;
+ Selection.Changed += RowSelected;
+ TestExpandRow += OnTestExpandRow;
+ ShowAll ();
+ }
+
+ public void Bind (WidgetEditSession newSession)
+ {
+ if (editSession != null) {
+ editSession.SelectionChanged -= WidgetSelected;
+ editSession.EditingBackend.ProjectReloaded -= OnProjectReloaded;
+ editSession.EditingBackend.WidgetNameChanged -= OnWidgetNameChanged;
+ editSession.EditingBackend.WidgetContentsChanged -= OnContentsChanged;
+ }
+ editSession = newSession;
+ if (editSession != null) {
+ editSession.SelectionChanged += WidgetSelected;
+ editSession.EditingBackend.ProjectReloaded += OnProjectReloaded;
+ editSession.EditingBackend.WidgetNameChanged += OnWidgetNameChanged;
+ editSession.EditingBackend.WidgetContentsChanged += OnContentsChanged;
+ }
+ LoadProject ();
+ }
+
+ public override void Dispose ()
+ {
+ if (editSession != null) {
+ editSession.SelectionChanged -= WidgetSelected;
+ editSession.EditingBackend.ProjectReloaded -= OnProjectReloaded;
+ editSession.EditingBackend.WidgetNameChanged -= OnWidgetNameChanged;
+ editSession.EditingBackend.WidgetContentsChanged -= OnContentsChanged;
+ }
+ base.Dispose ();
+ }
+
+ public void LoadProject ()
+ {
+ Clear ();
+ if (editSession == null || editSession.RootWidget == null)
+ return;
+
+ AddNode (TreeIter.Zero, editSession.RootWidget.Wrapped);
+ }
+
+ public void AddNode (TreeIter iter, Gtk.Widget widget)
+ {
+ Stetic.Wrapper.Widget wrapper = GetVisibleWrapper (widget);
+ if (wrapper == null)
+ return;
+
+ Gdk.Pixbuf icon = wrapper.ClassDescriptor.Icon.ScaleSimple (16, 16, Gdk.InterpType.Bilinear);
+ string txt = widget.Name;
+
+ if (!iter.Equals (TreeIter.Zero))
+ iter = store.AppendValues (iter, icon, txt, wrapper, true);
+ else
+ iter = store.AppendValues (icon, txt, wrapper, true);
+
+ FillChildren (iter, wrapper);
+ }
+
+ void FillChildren (TreeIter it, Wrapper.Widget wrapper)
+ {
+ Stetic.Wrapper.Container container = wrapper as Wrapper.Container;
+ if (container != null) {
+ foreach (Gtk.Widget w in container.RealChildren) {
+ Stetic.Wrapper.Widget ww = GetVisibleWrapper (w);
+ if (ww != null) {
+ // Add a dummy node to allow lazy loading
+ store.SetValue (it, ColFilled, false);
+ store.AppendValues (it, null, "", null, false);
+ return;
+ }
+ }
+ }
+ store.SetValue (it, ColFilled, true);
+ }
+
+ Wrapper.Widget GetVisibleWrapper (Gtk.Widget w)
+ {
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (w);
+ if (wrapper == null || wrapper.Unselectable)
+ return null;
+ else
+ return wrapper;
+ }
+
+ void EnsureFilled (TreeIter it)
+ {
+ bool filled = (bool) store.GetValue (it, ColFilled);
+ if (filled)
+ return;
+
+ // Remove the dummy node
+ TreeIter cit;
+ store.IterChildren (out cit, it);
+ store.Remove (ref cit);
+
+ // Add the real children
+ Stetic.Wrapper.Container container = store.GetValue (it, ColWrapper) as Wrapper.Container;
+ if (container != null) {
+ foreach (Gtk.Widget w in container.RealChildren)
+ AddNode (it, w);
+ }
+
+ store.SetValue (it, ColFilled, true);
+ }
+
+ void OnTestExpandRow (object s, Gtk.TestExpandRowArgs args)
+ {
+ EnsureFilled (args.Iter);
+ args.RetVal = false;
+ }
+
+ public void Clear ()
+ {
+ TreeIter it;
+ while (store.GetIterFirst (out it)) {
+ store.Remove (ref it);
+ }
+ }
+
+ void RefreshNode (TreeIter it)
+ {
+ Wrapper.Widget wrapper = (Wrapper.Widget) store.GetValue (it, ColWrapper);
+ store.SetValue (it, ColName, wrapper.Wrapped.Name);
+ TreeIter cit;
+ while (store.IterChildren (out cit, it)) {
+ store.Remove (ref cit);
+ }
+ FillChildren (it, wrapper);
+ }
+
+ void OnWidgetNameChanged (object s, Wrapper.WidgetNameChangedArgs args)
+ {
+ TreeIter? node = FindNode (args.WidgetWrapper, false);
+ if (node == null)
+ return;
+ store.SetValue (node.Value, ColName, args.NewName);
+ }
+
+ void OnContentsChanged (object s, Wrapper.WidgetEventArgs args)
+ {
+ TreeIter? node = FindNode (args.WidgetWrapper, false);
+ if (node != null)
+ RefreshNode (node.Value);
+ }
+
+ void OnProjectReloaded (object o, EventArgs a)
+ {
+ LoadProject ();
+ }
+
+ Stetic.Wrapper.Widget SelectedWrapper {
+ get {
+ TreeIter iter;
+ if (!Selection.GetSelected (out iter))
+ return null;
+ Wrapper.Widget w = (Wrapper.Widget) store.GetValue (iter, ColWrapper);
+ return w;
+ }
+ }
+
+ bool syncing = false;
+
+ void RowSelected (object obj, EventArgs args)
+ {
+ if (!syncing) {
+ syncing = true;
+ Stetic.Wrapper.Widget selection = SelectedWrapper;
+ if (selection != null)
+ selection.Select ();
+ syncing = false;
+ NotifySelectionChanged (selection);
+ }
+ }
+
+ void WidgetSelected (object s, Wrapper.WidgetEventArgs args)
+ {
+ if (!syncing) {
+ syncing = true;
+ if (args.Widget != null) {
+ Wrapper.Widget w = Wrapper.Widget.Lookup (args.Widget);
+ if (w != null) {
+ TreeIter? it = FindNode (w, true);
+ if (it != null) {
+ ExpandToPath (store.GetPath (it.Value));
+ Selection.SelectIter (it.Value);
+ ScrollToCell (store.GetPath (it.Value), Columns[0], false, 0, 0);
+ NotifySelectionChanged (w);
+ }
+ }
+ }
+ else {
+ Selection.UnselectAll ();
+ NotifySelectionChanged (null);
+ }
+ syncing = false;
+ }
+ }
+
+ TreeIter? FindNode (Wrapper.Widget w, bool loadBranches)
+ {
+ Wrapper.Widget parent = w.ParentWrapper;
+ TreeIter it;
+
+ if (parent == null) {
+ if (!store.GetIterFirst (out it))
+ return null;
+ } else {
+ TreeIter? pi = FindNode (parent, loadBranches);
+ if (pi == null)
+ return null;
+ if (loadBranches)
+ EnsureFilled (pi.Value);
+ if (!store.IterChildren (out it, pi.Value))
+ return null;
+ }
+
+ do {
+ Wrapper.Widget cw = (Wrapper.Widget) store.GetValue (it, ColWrapper);
+ if (cw == w)
+ return it;
+ } while (store.IterNext (ref it));
+
+ return null;
+ }
+
+ void NotifySelectionChanged (Stetic.Wrapper.Widget w)
+ {
+ if (frontend == null)
+ return;
+ if (w != null)
+ frontend.NotifySelectionChanged (Component.GetSafeReference (w), w.Wrapped.Name, w.ClassDescriptor.Name);
+ else
+ frontend.NotifySelectionChanged (null, null, null);
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton evt)
+ {
+ if (evt.Button == 3 && evt.Type == Gdk.EventType.ButtonPress)
+ return OnPopupMenu ();
+ return base.OnButtonPressEvent (evt);
+ }
+
+ protected override bool OnPopupMenu ()
+ {
+ Stetic.Wrapper.Widget selection = SelectedWrapper;
+
+ if (selection != null) {
+ Menu m = new ContextMenu (selection);
+ if (selection.IsTopLevel) {
+ // Allow deleting top levels from the project view
+ ImageMenuItem item = new ImageMenuItem (Gtk.Stock.Delete, null);
+ item.Activated += delegate (object obj, EventArgs args) {
+ selection.Delete ();
+ };
+ item.Show ();
+ m.Add (item);
+ }
+ m.Popup ();
+ return true;
+ } else
+ return base.OnPopupMenu ();
+ }
+
+ protected override void OnRowActivated (TreePath path, TreeViewColumn col)
+ {
+ base.OnRowActivated (path, col);
+ Stetic.Wrapper.Widget w = SelectedWrapper;
+ if (w != null) {
+ if (frontend != null)
+ frontend.NotifyWidgetActivated (Component.GetSafeReference (w), w.Wrapped.Name, w.ClassDescriptor.Name);
+ if (WidgetActivated != null)
+ WidgetActivated (this, new Wrapper.WidgetEventArgs (w));
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyEditor.cs
new file mode 100644
index 0000000000..27656da718
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyEditor.cs
@@ -0,0 +1,64 @@
+using Gtk;
+using System;
+using System.Collections;
+using System.Reflection;
+
+namespace Stetic {
+
+ class PropertyEditor : VBox
+ {
+ IPropertyEditor propEditor;
+ EditSession session;
+
+ public PropertyEditor (PropertyDescriptor prop) : base (false, 0)
+ {
+ propEditor = CreateEditor (prop);
+ Add ((Gtk.Widget) propEditor);
+ }
+
+ public void AttachObject (object ob)
+ {
+ if (session != null)
+ session.AttachObject (ob);
+ }
+
+ public IPropertyEditor CreateEditor (PropertyDescriptor prop)
+ {
+ PropertyEditorCell cell = PropertyEditorCell.GetPropertyCell (prop);
+ cell.Initialize (this, prop, null);
+
+ session = cell.StartEditing (new Gdk.Rectangle (), StateType.Normal);
+ if (session == null)
+ return new DummyEditor ();
+
+ Gtk.Widget w = (Gtk.Widget) session.Editor as Gtk.Widget;
+ w.ShowAll ();
+ return session.Editor;
+ }
+
+ public void Update ()
+ {
+ if (session != null)
+ session.UpdateEditor ();
+ }
+ }
+
+ class DummyEditor: Gtk.Label, IPropertyEditor
+ {
+ public void Initialize (PropertyDescriptor prop)
+ {
+ Text = "(" + prop.PropertyType.Name + ")";
+ }
+
+ public void AttachObject (object obj)
+ {
+ }
+
+ public object Value {
+ get { return null; }
+ set { }
+ }
+
+ public event EventHandler ValueChanged { add {} remove {} }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyGrid.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyGrid.cs
new file mode 100644
index 0000000000..fe8ca717bd
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyGrid.cs
@@ -0,0 +1,275 @@
+using Gtk;
+using GLib;
+using System;
+using System.Collections;
+using System.Reflection;
+
+namespace Stetic {
+
+ internal class PropertyGrid : Gtk.VBox {
+
+ Hashtable cachedGroups = new Hashtable ();
+
+ Stetic.Wrapper.Widget selection;
+ Stetic.Wrapper.Widget newSelection;
+ Stetic.Wrapper.Container.ContainerChild packingSelection;
+
+ PropertyGridHeader header;
+ Gtk.Widget noSelection;
+
+ ProjectBackend project;
+
+ public PropertyGrid ()
+ {
+ header = new PropertyGridHeader ();
+ header.Show ();
+ PackStart (header, false, false, 0);
+
+ Label lab = new Label ();
+ lab.Markup = "<i>No selection</i>";
+ PackStart (lab, false, false, 0);
+ noSelection = lab;
+
+ Stetic.Registry.RegistryChanging += new EventHandler (OnRegistryChanging);
+ }
+
+ public PropertyGrid (ProjectBackend project): this ()
+ {
+ this.ProjectBackend = project;
+ }
+
+ public override void Dispose ()
+ {
+ base.Dispose ();
+ }
+
+ void OnRegistryChanging (object o, EventArgs args)
+ {
+ cachedGroups.Clear ();
+ Clear ();
+ foreach (Gtk.Widget w in Children)
+ if (! (w is PropertyGridHeader))
+ Remove (w);
+ }
+
+ public ProjectBackend ProjectBackend {
+ get { return project; }
+ set {
+ if (project != null)
+ project.SelectionChanged -= Selected;
+
+ project = value;
+ project.SelectionChanged += Selected;
+ Selected (null, null);
+ }
+ }
+
+ void Clear ()
+ {
+ if (selection != null) {
+ selection.Notify -= Notified;
+ selection = null;
+ }
+ foreach (Gtk.Widget w in Children)
+ w.Hide ();
+ }
+
+ void Notified (object wrapper, string propertyName)
+ {
+ foreach (object ob in Children) {
+ PropertyGridGroup grid = ob as PropertyGridGroup;
+ if (grid != null)
+ grid.Notified (propertyName);
+ }
+ }
+
+ void Selected (object s, Wrapper.WidgetEventArgs args)
+ {
+ newSelection = args != null ? args.WidgetWrapper : null;
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (SelectedHandler));
+ }
+
+ bool SelectedHandler ()
+ {
+ ClassDescriptor klass;
+
+ Clear ();
+
+ selection = newSelection;
+
+ if (selection == null || selection.Wrapped is ErrorWidget) {
+ noSelection.Show ();
+ return false;
+ }
+
+ header.Show ();
+
+ selection.Notify += Notified;
+
+ klass = selection.ClassDescriptor;
+
+ header.AttachObject (selection.Wrapped);
+ AppendItemGroups (klass, selection.Wrapped);
+
+ packingSelection = Stetic.Wrapper.Container.ChildWrapper (selection);
+ if (packingSelection != null) {
+ klass = packingSelection.ClassDescriptor;
+ if (klass.ItemGroups.Count > 0) {
+ AppendItemGroups (klass, packingSelection.Wrapped);
+ packingSelection.Notify += Notified;
+ }
+ }
+ return false;
+ }
+
+ void AppendItemGroups (ClassDescriptor klass, object obj)
+ {
+ int n = 1;
+ foreach (ItemGroup igroup in klass.ItemGroups) {
+ PropertyGridGroup grid = (PropertyGridGroup) cachedGroups [igroup];
+ if (grid == null) {
+ grid = new PropertyGridGroup ();
+ grid.AddGroup (igroup);
+ cachedGroups [igroup] = grid;
+ PackStart (grid, false, false, 0);
+ }
+ ReorderChild (grid, n++);
+ grid.ShowAll ();
+ grid.AttachObject (obj);
+ }
+ }
+ }
+
+ class PropertyGridGroup: Stetic.Grid
+ {
+ Hashtable editors;
+ Hashtable sensitives, invisibles;
+ object obj;
+
+ public PropertyGridGroup ()
+ {
+ editors = new Hashtable ();
+ sensitives = new Hashtable ();
+ invisibles = new Hashtable ();
+ }
+
+ public void AddGroup (ItemGroup igroup)
+ {
+ AppendGroup (igroup.Label, true);
+ foreach (ItemDescriptor item in igroup) {
+ if (item.IsInternal)
+ continue;
+ if (item is PropertyDescriptor)
+ AppendProperty ((PropertyDescriptor)item);
+ else if (item is CommandDescriptor)
+ AppendCommand ((CommandDescriptor)item);
+ }
+ }
+
+ public virtual void AttachObject (object ob)
+ {
+ this.obj = ob;
+
+ foreach (object ed in editors.Values) {
+ PropertyEditor pe = ed as PropertyEditor;
+ if (pe != null)
+ pe.AttachObject (ob);
+ }
+ UpdateSensitivity ();
+ }
+
+ protected void AppendProperty (PropertyDescriptor prop)
+ {
+ PropertyEditor rep = new PropertyEditor (prop);
+
+ // FIXME: Make sure all notify events are based on prop names, not propspec
+ editors[prop.Name] = rep;
+
+ AppendPair (prop.Label, rep, prop.Description);
+ rep.ShowAll ();
+
+ if (prop.HasDependencies)
+ sensitives[prop] = prop;
+ if (prop.HasVisibility)
+ invisibles[prop] = prop;
+ }
+
+ void AppendCommand (CommandDescriptor cmd)
+ {
+ Gtk.Button button = new Gtk.Button (cmd.Label);
+ button.Clicked += delegate (object o, EventArgs args) {
+ cmd.Run (this.obj);
+ };
+ button.Show ();
+ Append (button, cmd.Description);
+
+ if (cmd.HasDependencies) {
+ editors[cmd.Name] = button;
+ sensitives[cmd] = cmd;
+ }
+ if (cmd.HasVisibility) {
+ editors[cmd.Name] = button;
+ invisibles[cmd] = cmd;
+ }
+ }
+
+ void UpdateSensitivity ()
+ {
+ foreach (ItemDescriptor item in sensitives.Keys) {
+ Widget w = editors[item.Name] as Widget;
+ if (w != null) {
+ object ob = sensitives.Contains (item) ? obj : null;
+ w.Sensitive = item.EnabledFor (ob);
+ }
+ }
+ foreach (ItemDescriptor item in invisibles.Keys) {
+ Widget w = editors[item.Name] as Widget;
+ if (w != null) {
+ object ob = invisibles.Contains (item) ? obj : null;
+ if (!item.VisibleFor (ob))
+ w.Hide ();
+ else
+ w.Show ();
+ }
+ }
+ }
+
+ public void Notified (string propertyName)
+ {
+ PropertyEditor ed = editors [propertyName] as PropertyEditor;
+ if (ed != null)
+ ed.Update ();
+ UpdateSensitivity ();
+ }
+ }
+
+ class PropertyGridHeader: PropertyGridGroup
+ {
+ PropertyDescriptor name;
+ Gtk.Image image;
+ Gtk.Label label;
+
+ public PropertyGridHeader ()
+ {
+ name = (PropertyDescriptor)Registry.LookupClassByName ("Gtk.Widget") ["Name"];
+ AppendProperty (name);
+
+ Gtk.HBox box = new Gtk.HBox (false, 6);
+ image = new Gtk.Image ();
+ box.PackStart (image, false, false, 0);
+ label = new Gtk.Label ();
+ box.PackStart (label, false, false, 0);
+ box.ShowAll ();
+ AppendPair ("Widget Class", box, null);
+ }
+
+ public override void AttachObject (object ob)
+ {
+ base.AttachObject (ob);
+ Gtk.Widget w = (Gtk.Widget) ob;
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (w);
+ image.Pixbuf = wrapper.ClassDescriptor.Icon;
+ label.Text = wrapper.WrappedTypeName;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyTree.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyTree.cs
new file mode 100644
index 0000000000..c846444392
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/PropertyTree.cs
@@ -0,0 +1,565 @@
+
+using System;
+using System.Collections;
+using Gtk;
+using Gdk;
+using Mono.Unix;
+
+namespace Stetic
+{
+ public class PropertyTree: Gtk.ScrolledWindow
+ {
+ Gtk.TreeStore store;
+ InternalTree tree;
+ TreeViewColumn editorColumn;
+ Hashtable propertyRows;
+ Hashtable sensitives, invisibles;
+ ArrayList expandStatus = new ArrayList ();
+
+ public PropertyTree ()
+ {
+ propertyRows = new Hashtable ();
+ sensitives = new Hashtable ();
+ invisibles = new Hashtable ();
+
+ store = new TreeStore (typeof (string), typeof(PropertyDescriptor), typeof(bool), typeof(InstanceData));
+
+ tree = new InternalTree (this, store);
+
+ CellRendererText crt;
+
+ TreeViewColumn col;
+
+ col = new TreeViewColumn ();
+ col.Title = Catalog.GetString ("Property");
+ crt = new CellRendererPropertyGroup (tree);
+ col.PackStart (crt, true);
+ col.SetCellDataFunc (crt, new TreeCellDataFunc (GroupData));
+ col.Resizable = true;
+ col.Expand = false;
+ col.Sizing = TreeViewColumnSizing.Fixed;
+ col.FixedWidth = 150;
+ tree.AppendColumn (col);
+
+ editorColumn = new TreeViewColumn ();
+ editorColumn.Title = Catalog.GetString ("Value");
+
+ CellRendererProperty crp = new CellRendererProperty (tree);
+
+ editorColumn.PackStart (crp, true);
+ editorColumn.SetCellDataFunc (crp, new TreeCellDataFunc (PropertyData));
+ editorColumn.Sizing = TreeViewColumnSizing.Fixed;
+ editorColumn.Resizable = false;
+ editorColumn.Expand = true;
+ tree.AppendColumn (editorColumn);
+
+ tree.HeadersVisible = false;
+ this.ShadowType = Gtk.ShadowType.In;
+ this.HscrollbarPolicy = Gtk.PolicyType.Never;
+
+ Add (tree);
+ ShowAll ();
+
+ tree.Selection.Changed += OnSelectionChanged;
+ }
+
+ public void AddProperties (ItemGroupCollection itemGroups, object instance, string targetGtkVersion)
+ {
+ foreach (ItemGroup igroup in itemGroups)
+ AddGroup (igroup, instance, targetGtkVersion);
+ }
+
+ public void SaveStatus ()
+ {
+ expandStatus.Clear ();
+
+ TreeIter iter;
+ if (!tree.Model.GetIterFirst (out iter))
+ return;
+
+ do {
+ if (tree.GetRowExpanded (tree.Model.GetPath (iter))) {
+ expandStatus.Add (tree.Model.GetValue (iter, 0));
+ }
+ } while (tree.Model.IterNext (ref iter));
+ }
+
+ public void RestoreStatus ()
+ {
+ TreeIter iter;
+ if (!tree.Model.GetIterFirst (out iter))
+ return;
+
+ // If the tree only has one group, show it always expanded
+ TreeIter iter2 = iter;
+ if (!tree.Model.IterNext (ref iter2)) {
+ tree.ExpandRow (tree.Model.GetPath (iter), true);
+ return;
+ }
+
+ do {
+ object grp = tree.Model.GetValue (iter, 0);
+ if (expandStatus.Contains (grp))
+ tree.ExpandRow (tree.Model.GetPath (iter), true);
+ } while (tree.Model.IterNext (ref iter));
+ }
+
+ public virtual void Clear ()
+ {
+ store.Clear ();
+ propertyRows.Clear ();
+ sensitives.Clear ();
+ invisibles.Clear ();
+ }
+
+ public virtual void Update ()
+ {
+ // Just repaint the cells
+ QueueDraw ();
+ }
+
+ public void AddGroup (ItemGroup igroup, object instance, string targetGtkVersion)
+ {
+ ArrayList props = new ArrayList ();
+ foreach (ItemDescriptor item in igroup) {
+ if (item.IsInternal)
+ continue;
+ if (item is PropertyDescriptor && item.SupportsGtkVersion (targetGtkVersion))
+ props.Add (item);
+ }
+
+ if (props.Count == 0)
+ return;
+
+ InstanceData idata = new InstanceData (instance);
+ TreeIter iter = store.AppendValues (igroup.Label, null, true, idata);
+ foreach (PropertyDescriptor item in props)
+ AppendProperty (iter, (PropertyDescriptor)item, idata);
+ }
+
+ protected void AppendProperty (PropertyDescriptor prop, object instance)
+ {
+ AppendProperty (TreeIter.Zero, prop, new InstanceData (instance));
+ }
+
+ protected void AppendProperty (TreeIter piter, PropertyDescriptor prop, object instance)
+ {
+ AppendProperty (piter, prop, new InstanceData (instance));
+ }
+
+ void AppendProperty (TreeIter piter, PropertyDescriptor prop, InstanceData idata)
+ {
+ TreeIter iter;
+ if (piter.Equals (TreeIter.Zero))
+ iter = store.AppendValues (prop.Label, prop, false, idata);
+ else
+ iter = store.AppendValues (piter, prop.Label, prop, false, idata);
+ if (prop.HasDependencies)
+ sensitives[prop] = prop;
+ if (prop.HasVisibility)
+ invisibles[prop] = prop;
+ propertyRows [prop] = store.GetStringFromIter (iter);
+ }
+
+ protected virtual void OnObjectChanged ()
+ {
+ }
+
+ void OnSelectionChanged (object s, EventArgs a)
+ {
+ TreePath[] rows = tree.Selection.GetSelectedRows ();
+ if (!tree.dragging && rows != null && rows.Length > 0) {
+ tree.SetCursor (rows[0], editorColumn, true);
+ }
+ }
+
+ internal void NotifyChanged ()
+ {
+ OnObjectChanged ();
+ }
+
+ void PropertyData (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
+ {
+ CellRendererProperty rc = (CellRendererProperty) cell;
+ bool group = (bool) model.GetValue (iter, 2);
+ if (group) {
+ rc.SetData (null, null, null);
+ } else {
+ PropertyDescriptor prop = (PropertyDescriptor) model.GetValue (iter, 1);
+ PropertyEditorCell propCell = PropertyEditorCell.GetPropertyCell (prop);
+ InstanceData idata = (InstanceData) model.GetValue (iter, 3);
+ propCell.Initialize (tree, prop, idata.Instance);
+ rc.SetData (idata.Instance, prop, propCell);
+ }
+ }
+
+ void GroupData (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
+ {
+ CellRendererPropertyGroup rc = (CellRendererPropertyGroup) cell;
+ rc.IsGroup = (bool) model.GetValue (iter, 2);
+ rc.Text = (string) model.GetValue (iter, 0);
+
+ PropertyDescriptor prop = (PropertyDescriptor) model.GetValue (iter, 1);
+ if (prop != null) {
+ InstanceData idata = (InstanceData) model.GetValue (iter, 3);
+ rc.SensitiveProperty = prop.EnabledFor (idata.Instance) && prop.VisibleFor (idata.Instance);
+ } else
+ rc.SensitiveProperty = true;
+ }
+ }
+
+ class InternalTree: TreeView
+ {
+ internal ArrayList Groups = new ArrayList ();
+ Pango.Layout layout;
+ bool editing;
+ PropertyTree tree;
+ internal bool dragging;
+ int dragPos;
+ Gdk.Cursor resizeCursor = new Gdk.Cursor (CursorType.SbHDoubleArrow);
+
+ public InternalTree (PropertyTree tree, TreeModel model): base (model)
+ {
+ this.tree = tree;
+ layout = new Pango.Layout (this.PangoContext);
+ layout.Wrap = Pango.WrapMode.Char;
+ Pango.FontDescription des = this.Style.FontDescription.Copy();
+ layout.FontDescription = des;
+ }
+
+ public bool Editing {
+ get { return editing; }
+ set { editing = value; Update (); tree.NotifyChanged (); }
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose e)
+ {
+ Groups.Clear ();
+
+ bool res = base.OnExposeEvent (e);
+
+ foreach (TreeGroup grp in Groups) {
+ layout.SetMarkup ("<b>" + GLib.Markup.EscapeText (grp.Group) + "</b>");
+ e.Window.DrawLayout (this.Style.TextGC (grp.State), grp.X, grp.Y, layout);
+ }
+
+ return res;
+ }
+
+ protected override bool OnMotionNotifyEvent (EventMotion evnt)
+ {
+ if (dragging) {
+ int nw = (int)(evnt.X) + dragPos;
+ if (nw <= 40) nw = 40;
+ GLib.Idle.Add (delegate {
+ Columns[0].FixedWidth = nw;
+ return false;
+ });
+ } else {
+ int w = Columns[0].Width;
+ if (Math.Abs (w - evnt.X) < 5)
+ this.GdkWindow.Cursor = resizeCursor;
+ else
+ this.GdkWindow.Cursor = null;
+ }
+ return base.OnMotionNotifyEvent (evnt);
+ }
+
+ protected override bool OnButtonPressEvent (EventButton evnt)
+ {
+ int w = Columns[0].Width;
+ if (Math.Abs (w - evnt.X) < 5) {
+ TreePath[] rows = Selection.GetSelectedRows ();
+ if (rows != null && rows.Length > 0)
+ SetCursor (rows[0], Columns[0], false);
+ dragging = true;
+ dragPos = w - (int) evnt.X;
+ this.GdkWindow.Cursor = resizeCursor;
+ }
+ return base.OnButtonPressEvent (evnt);
+ }
+
+ protected override bool OnButtonReleaseEvent (EventButton evnt)
+ {
+ if (dragging) {
+ this.GdkWindow.Cursor = null;
+ dragging = false;
+ }
+ return base.OnButtonReleaseEvent (evnt);
+ }
+
+ public virtual void Update ()
+ {
+ }
+
+ protected override void OnDestroyed ()
+ {
+ base.OnDestroyed ();
+ if (resizeCursor != null) {
+ resizeCursor.Dispose ();
+ resizeCursor = null;
+ }
+ }
+
+ }
+
+ class TreeGroup
+ {
+ public string Group;
+ public int X;
+ public int Y;
+ public StateType State;
+ }
+
+ class CellRendererProperty: CellRenderer
+ {
+ PropertyDescriptor property;
+ object instance;
+ int rowHeight;
+ PropertyEditorCell editorCell;
+ bool sensitive;
+ bool visible;
+ TreeView tree;
+
+ public CellRendererProperty (TreeView tree)
+ {
+ this.tree = tree;
+ Xalign = 0;
+ Xpad = 3;
+
+ Mode |= Gtk.CellRendererMode.Editable;
+ Entry dummyEntry = new Gtk.Entry ();
+ dummyEntry.HasFrame = false;
+ rowHeight = dummyEntry.SizeRequest ().Height;
+ }
+
+ public void SetData (object instance, PropertyDescriptor property, PropertyEditorCell editor)
+ {
+ this.instance = instance;
+ this.property = property;
+ if (property == null)
+ this.CellBackgroundGdk = tree.Style.MidColors [(int)Gtk.StateType.Normal];
+ else
+ this.CellBackground = null;
+
+ visible = property != null ? property.VisibleFor (instance): true;
+ sensitive = property != null ? property.EnabledFor (instance) && property.VisibleFor (instance): true;
+ editorCell = editor;
+ }
+
+ public override void GetSize (Widget widget, ref Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
+ {
+ if (editorCell != null)
+ editorCell.GetSize ((int)(cell_area.Width - this.Xpad * 2), out width, out height);
+ else {
+ width = height = 0;
+ }
+
+ width += (int) this.Xpad * 2;
+ height += (int) this.Ypad * 2;
+
+ x_offset = 0;
+ y_offset = 0;
+
+ if (height < rowHeight)
+ height = rowHeight;
+ }
+
+ protected override void Render (Drawable window, Widget widget, Rectangle background_area, Rectangle cell_area, Rectangle expose_area, CellRendererState flags)
+ {
+ if (instance == null || !visible)
+ return;
+ int width = 0, height = 0;
+ int iwidth = cell_area.Width - (int) this.Xpad * 2;
+
+ if (editorCell != null)
+ editorCell.GetSize ((int)(cell_area.Width - this.Xpad * 2), out width, out height);
+
+ Rectangle bounds = new Rectangle ();
+ bounds.Width = width > iwidth ? iwidth : width;
+ bounds.Height = height;
+ bounds.X = (int) (cell_area.X + this.Xpad);
+ bounds.Y = cell_area.Y + (cell_area.Height - height) / 2;
+
+ StateType state = GetState (flags);
+
+ if (editorCell != null)
+ editorCell.Render (window, bounds, state);
+ }
+
+ public override CellEditable StartEditing (Gdk.Event ev, Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, CellRendererState flags)
+ {
+ if (property == null || editorCell == null || !sensitive)
+ return null;
+
+ StateType state = GetState (flags);
+ EditSession session = editorCell.StartEditing (cell_area, state);
+ if (session == null)
+ return null;
+ Gtk.Widget propEditor = (Gtk.Widget) session.Editor;
+ propEditor.Show ();
+ HackEntry e = new HackEntry (propEditor, session);
+ e.Show ();
+ return e;
+ }
+
+ StateType GetState (CellRendererState flags)
+ {
+ if (!sensitive)
+ return StateType.Insensitive;
+ else if ((flags & CellRendererState.Selected) != 0)
+ return StateType.Selected;
+ else
+ return StateType.Normal;
+ }
+ }
+
+ class CellRendererPropertyGroup: CellRendererText
+ {
+ TreeView tree;
+ Pango.Layout layout;
+ bool isGroup;
+ bool sensitive;
+
+ public bool IsGroup {
+ get { return isGroup; }
+ set {
+ isGroup = value;
+ if (value)
+ this.CellBackgroundGdk = tree.Style.MidColors [(int)Gtk.StateType.Normal];
+ else
+ this.CellBackground = null;
+ }
+ }
+
+ public bool SensitiveProperty {
+ get { return sensitive; }
+ set { sensitive = value; }
+ }
+
+ public CellRendererPropertyGroup (TreeView tree)
+ {
+ this.tree = tree;
+ layout = new Pango.Layout (tree.PangoContext);
+ layout.Wrap = Pango.WrapMode.Char;
+
+ Pango.FontDescription des = tree.Style.FontDescription.Copy();
+ layout.FontDescription = des;
+ }
+
+ protected void GetCellSize (Widget widget, int availableWidth, out int width, out int height)
+ {
+ layout.SetMarkup (Text);
+ layout.Width = -1;
+ layout.GetPixelSize (out width, out height);
+ }
+
+ public override void GetSize (Widget widget, ref Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
+ {
+ GetCellSize (widget, (int)(cell_area.Width - this.Xpad * 2), out width, out height);
+ width += (int) this.Xpad * 2;
+ height += (int) this.Ypad * 2;
+
+ x_offset = y_offset = 0;
+
+ if (IsGroup)
+ width = 0;
+ }
+
+ protected override void Render (Drawable window, Widget widget, Rectangle background_area, Rectangle cell_area, Rectangle expose_area, CellRendererState flags)
+ {
+ int width, height;
+ GetCellSize (widget, (int)(cell_area.Width - this.Xpad * 2), out width, out height);
+
+ int x = (int) (cell_area.X + this.Xpad);
+ int y = cell_area.Y + (cell_area.Height - height) / 2;
+
+ StateType state;
+ if (!sensitive)
+ state = StateType.Insensitive;
+ else if ((flags & CellRendererState.Selected) != 0)
+ state = StateType.Selected;
+ else
+ state = StateType.Normal;
+
+ if (IsGroup) {
+ TreeGroup grp = new TreeGroup ();
+ grp.X = x;
+ grp.Y = y;
+ grp.Group = Text;
+ grp.State = state;
+ InternalTree tree = (InternalTree) widget;
+ tree.Groups.Add (grp);
+ } else {
+ window.DrawLayout (widget.Style.TextGC (state), x, y, layout);
+ int bx = background_area.X + background_area.Width - 1;
+ Gdk.GC gc = new Gdk.GC (window);
+ gc.RgbFgColor = tree.Style.MidColors [(int)Gtk.StateType.Normal];
+ window.DrawLine (gc, bx, background_area.Y, bx, background_area.Y + background_area.Height);
+ }
+ }
+ }
+
+ class HackEntry: Entry
+ {
+ EventBox box;
+ EditSession session;
+
+ public HackEntry (Gtk.Widget child, EditSession session)
+ {
+ this.session = session;
+ box = new EventBox ();
+ box.ButtonPressEvent += new ButtonPressEventHandler (OnClickBox);
+ box.ModifyBg (StateType.Normal, Style.White);
+ box.Add (child);
+ }
+
+ [GLib.ConnectBefore]
+ void OnClickBox (object s, ButtonPressEventArgs args)
+ {
+ // Avoid forwarding the button press event to the
+ // tree, since it would hide the cell editor.
+ args.RetVal = true;
+ }
+
+ protected override void OnParentSet (Gtk.Widget parent)
+ {
+ base.OnParentSet (parent);
+
+ if (Parent != null) {
+ if (this.ParentWindow != null)
+ box.ParentWindow = this.ParentWindow;
+ box.Parent = Parent;
+ box.Show ();
+ ((InternalTree)Parent).Editing = true;
+ }
+ else {
+ session.Dispose ();
+ ((InternalTree)parent).Editing = false;
+ box.Unparent ();
+ }
+ }
+
+ protected override void OnShown ()
+ {
+ // Do nothing.
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+ {
+ base.OnSizeAllocated (allocation);
+ box.SizeRequest ();
+ box.Allocation = allocation;
+ }
+ }
+
+ class InstanceData
+ {
+ public InstanceData (object instance)
+ {
+ Instance = instance;
+ }
+
+ public object Instance;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Shadow.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Shadow.cs
new file mode 100644
index 0000000000..45d2a62357
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Shadow.cs
@@ -0,0 +1,116 @@
+/* Shadow code from anders */
+
+using System;
+using Gdk;
+
+class ConvFilter
+{
+ public int size;
+ public double[] data;
+}
+
+class Shadow
+{
+ public const int BLUR_RADIUS = 5;
+ public const int SHADOW_OFFSET = (BLUR_RADIUS * 4 / 5);
+ public const double SHADOW_OPACITY = 0.5;
+
+ static ConvFilter filter;
+
+ static double Gaussian (double x, double y, double r)
+ {
+ return ((1 / (2 * System.Math.PI * r)) *
+ System.Math.Exp ((- (x * x + y * y)) / (2 * r * r)));
+ }
+
+ static ConvFilter CreateBlurFilter (int radius)
+ {
+ ConvFilter filter;
+ int x, y;
+ double sum;
+
+ filter = new ConvFilter ();
+ filter.size = radius * 2 + 1;
+ filter.data = new double [filter.size * filter.size];
+
+ sum = 0.0;
+
+ for (y = 0 ; y < filter.size; y++) {
+ for (x = 0 ; x < filter.size; x++) {
+ sum += filter.data [y * filter.size + x] = Gaussian (x - (filter.size >> 1),
+ y - (filter.size >> 1),
+ radius);
+ }
+ }
+
+ for (y = 0; y < filter.size; y++) {
+ for (x = 0; x < filter.size; x++)
+ filter.data [y * filter.size + x] /= sum;
+ }
+ return filter;
+ }
+
+ unsafe static Pixbuf CreateEffect (int src_width, int src_height, ConvFilter filter, int radius, int offset, double opacity)
+ {
+ Pixbuf dest;
+ int x, y, i, j;
+ int src_x, src_y;
+ int suma;
+ int dest_width, dest_height;
+ int dest_rowstride;
+ byte* dest_pixels;
+
+ dest_width = src_width + 2 * radius + offset;
+ dest_height = src_height + 2 * radius + offset;
+
+ dest = new Pixbuf (Colorspace.Rgb, true, 8, dest_width, dest_height);
+ dest.Fill (0);
+
+ dest_pixels = (byte*) dest.Pixels;
+
+ dest_rowstride = dest.Rowstride;
+
+ for (y = 0; y < dest_height; y++)
+ {
+ for (x = 0; x < dest_width; x++)
+ {
+ suma = 0;
+
+ src_x = x - radius;
+ src_y = y - radius;
+
+ /* We don't need to compute effect here, since this pixel will be
+ * discarded when compositing */
+ if (src_x >= 0 && src_x < src_width && src_y >= 0 && src_y < src_height)
+ continue;
+
+ for (i = 0; i < filter.size; i++)
+ {
+ for (j = 0; j < filter.size; j++)
+ {
+ src_y = -(radius + offset) + y - (filter.size >> 1) + i;
+ src_x = -(radius + offset) + x - (filter.size >> 1) + j;
+
+ if (src_y < 0 || src_y >= src_height ||
+ src_x < 0 || src_x >= src_width)
+ continue;
+
+ suma += (int) (((byte)0xFF) * filter.data [i * filter.size + j]);
+ }
+ }
+
+ byte r = (byte) (suma * opacity);
+ dest_pixels [y * dest_rowstride + x * 4 + 3] = r;
+ }
+ }
+ return dest;
+ }
+
+ public static Pixbuf AddShadow (int width, int height)
+ {
+ if (filter == null)
+ filter = CreateBlurFilter (BLUR_RADIUS);
+
+ return CreateEffect (width, height, filter, BLUR_RADIUS, SHADOW_OFFSET, SHADOW_OPACITY);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditor.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditor.cs
new file mode 100644
index 0000000000..d5aa7dd7c7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditor.cs
@@ -0,0 +1,90 @@
+
+using System;
+
+namespace Stetic
+{
+ public class SignalsEditor: PluggableWidget
+ {
+ SignalsEditorFrontend frontend;
+ SignalsEditorEditSession session;
+
+ public event EventHandler SignalActivated;
+
+ internal SignalsEditor (Application app): base (app)
+ {
+ frontend = new SignalsEditorFrontend (this);
+ }
+
+ public Signal SelectedSignal {
+ get {
+ if (session != null)
+ return session.SelectedSignal;
+ else
+ return null;
+ }
+ }
+
+ protected override void OnCreatePlug (uint socketId)
+ {
+ session = app.Backend.CreateSignalsWidgetPlug (frontend, socketId);
+ }
+
+ protected override void OnDestroyPlug (uint socketId)
+ {
+ app.Backend.DestroySignalsWidgetPlug ();
+ }
+
+ protected override Gtk.Widget OnCreateWidget ()
+ {
+ session = app.Backend.GetSignalsWidget (frontend);
+ return session.Editor;
+ }
+
+ bool disposed = false;
+
+ public override void Dispose ()
+ {
+ if (disposed)
+ return;
+ disposed = true;
+
+ if (session != null)
+ session.Dispose ();
+ frontend.disposed = true;
+ System.Runtime.Remoting.RemotingServices.Disconnect (frontend);
+ base.Dispose ();
+ }
+
+ internal void NotifySignalActivated ()
+ {
+ if (SignalActivated != null)
+ SignalActivated (this, EventArgs.Empty);
+ }
+ }
+
+ internal class SignalsEditorFrontend: MarshalByRefObject
+ {
+ SignalsEditor editor;
+ internal bool disposed;
+
+ public SignalsEditorFrontend (SignalsEditor editor)
+ {
+ this.editor = editor;
+ }
+
+ public void NotifySignalActivated ()
+ {
+ Gtk.Application.Invoke (
+ delegate {
+ if (!disposed) editor.NotifySignalActivated ();
+ }
+ );
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditorBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditorBackend.cs
new file mode 100644
index 0000000000..d675804793
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/SignalsEditorBackend.cs
@@ -0,0 +1,481 @@
+using System;
+using System.Text;
+using System.Collections;
+using Stetic.Wrapper;
+using Mono.Unix;
+
+namespace Stetic
+{
+ internal class SignalsEditorBackend: Gtk.ScrolledWindow, IObjectViewer
+ {
+ Gtk.TreeView tree;
+ Gtk.TreeStore store;
+ SignalsEditorFrontend frontend;
+
+ ProjectBackend project;
+ ObjectWrapper selection;
+ bool internalChange;
+
+ const int ColSignal = 0;
+ const int ColHandler = 1;
+ const int ColAfter = 2;
+ const int ColHasHandler = 3;
+ const int ColIsSignal = 4;
+ const int ColSignalTextWeight = 5;
+
+ public SignalsEditorBackend (SignalsEditorFrontend frontend)
+ {
+ this.frontend = frontend;
+
+ tree = new Gtk.TreeView ();
+ store = new Gtk.TreeStore (typeof(string), typeof(string), typeof(bool), typeof(bool), typeof(bool), typeof(int));
+ tree.Model = store;
+ tree.RowActivated += new Gtk.RowActivatedHandler (OnRowActivated);
+
+ Gtk.CellRendererText crtSignal = new Gtk.CellRendererText ();
+
+ Gtk.CellRendererText crtHandler = new Gtk.CellRendererText ();
+ crtHandler.Editable = true;
+ crtHandler.Edited += new Gtk.EditedHandler (OnHandlerEdited);
+
+ Gtk.CellRendererToggle crtogAfter = new Gtk.CellRendererToggle ();
+ crtogAfter.Activatable = true;
+ crtogAfter.Toggled += new Gtk.ToggledHandler (OnAfterToggled);
+
+ tree.AppendColumn (Catalog.GetString ("Signal"), crtSignal, "text", ColSignal, "weight", ColSignalTextWeight);
+ tree.AppendColumn (Catalog.GetString ("Handler"), crtHandler, "markup", ColHandler, "visible", ColIsSignal);
+ tree.AppendColumn (Catalog.GetString ("After"), crtogAfter, "active", ColAfter, "visible", ColHasHandler);
+ tree.Columns[0].Resizable = true;
+ tree.Columns[1].Resizable = true;
+ tree.Columns[2].Resizable = true;
+ Add (tree);
+ ShowAll ();
+ }
+
+ public SignalsEditorBackend (SignalsEditorFrontend frontend, ProjectBackend project): this (frontend)
+ {
+ ProjectBackend = project;
+ }
+
+ public ProjectBackend ProjectBackend {
+ get { return project; }
+ set {
+ if (project != null) {
+ project.SelectionChanged -= OnWidgetSelected;
+ project.SignalAdded -= new SignalEventHandler (OnSignalAddedOrRemoved);
+ project.SignalRemoved -= new SignalEventHandler (OnSignalAddedOrRemoved);
+ project.SignalChanged -= new SignalChangedEventHandler (OnSignalChanged);
+ project.ProjectReloaded -= new EventHandler (OnProjectReloaded);
+ }
+
+ project = value;
+ if (project != null) {
+ TargetObject = project.Selection;
+ project.SelectionChanged += OnWidgetSelected;
+ project.SignalAdded += new SignalEventHandler (OnSignalAddedOrRemoved);
+ project.SignalRemoved += new SignalEventHandler (OnSignalAddedOrRemoved);
+ project.SignalChanged += new SignalChangedEventHandler (OnSignalChanged);
+ project.ProjectReloaded += new EventHandler (OnProjectReloaded);
+ } else if (selection != null) {
+ selection = null;
+ RefreshTree ();
+ }
+ }
+ }
+
+ void OnProjectReloaded (object s, EventArgs a)
+ {
+ OnWidgetSelected (null, null);
+ }
+
+ public Signal SelectedSignal {
+ get {
+ Gtk.TreeModel foo;
+ Gtk.TreeIter iter;
+ if (!tree.Selection.GetSelected (out foo, out iter))
+ return null;
+ return GetSignal (iter);
+ }
+ }
+
+ public object TargetObject {
+ get {
+ return selection != null ? selection.Wrapped : null;
+ }
+ set {
+ if (project != null) {
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (value);
+ if (wrapper == selection)
+ return;
+ selection = wrapper;
+ RefreshTree ();
+ }
+ }
+ }
+
+ void OnWidgetSelected (object s, Wrapper.WidgetEventArgs args)
+ {
+ ObjectWrapper wrapper = args != null ? args.WidgetWrapper : null;
+ if (wrapper == selection)
+ return;
+ selection = wrapper;
+ RefreshTree ();
+ }
+
+ void OnSignalAddedOrRemoved (object sender, SignalEventArgs args)
+ {
+ if (!internalChange && args.Wrapper == selection)
+ RefreshTree ();
+ }
+
+ void OnSignalChanged (object sender, SignalChangedEventArgs args)
+ {
+ if (!internalChange && args.Wrapper == selection)
+ RefreshTree ();
+ }
+
+ void RefreshTree ()
+ {
+ ArrayList status = SaveStatus ();
+ store.Clear ();
+
+ if (selection == null)
+ return;
+
+ ClassDescriptor klass = selection.ClassDescriptor;
+
+ foreach (ItemGroup group in klass.SignalGroups) {
+ Gtk.TreeIter iter = store.AppendValues (group.Label, null, false, false, false, (int) Pango.Weight.Normal);
+ if (FillGroup (iter, group))
+ store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
+ }
+ RestoreStatus (status);
+ }
+
+ bool FillGroup (Gtk.TreeIter groupIter, ItemGroup group)
+ {
+ bool hasSignals = false;
+ foreach (SignalDescriptor sd in group) {
+ if (!sd.SupportsGtkVersion (project.TargetGtkVersion))
+ continue;
+
+ bool foundSignal = false;
+ Gtk.TreeIter parent = groupIter;
+
+ foreach (Signal signal in selection.Signals) {
+ if (signal.SignalDescriptor != sd) continue;
+
+ Gtk.TreeIter iter = store.AppendValues (parent, null, signal.Handler, false, true, true, (int) Pango.Weight.Normal);
+ if (!foundSignal) {
+ parent = iter;
+ store.SetValue (iter, ColSignal, sd.Name);
+ store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
+ hasSignals = foundSignal = true;
+ }
+ }
+
+ InsertEmptySignalRow (parent, foundSignal ? null : sd.Name);
+ }
+ return hasSignals;
+ }
+
+ void SetSignalData (Gtk.TreeIter iter, Signal signal)
+ {
+ store.SetValue (iter, ColHandler, signal.Handler);
+ store.SetValue (iter, ColAfter, false);
+ store.SetValue (iter, ColHasHandler, true);
+ store.SetValue (iter, ColIsSignal, true);
+ }
+
+ void InsertEmptySignalRow (Gtk.TreeIter parent, string name)
+ {
+ store.AppendValues (parent, name, EmptyHandlerMarkup, false, false, true, (int) Pango.Weight.Normal);
+ }
+
+ void OnRowActivated (object sender, Gtk.RowActivatedArgs args)
+ {
+ Gtk.TreeIter iter;
+ if (!store.GetIter (out iter, args.Path))
+ return;
+
+ SignalDescriptor sd = GetSignalDescriptor (iter);
+ if (sd != null) {
+ if (GetSignal (iter) == null)
+ AddHandler (iter, GetHandlerName (sd.Name));
+ frontend.NotifySignalActivated ();
+ }
+ }
+
+ string GetHandlerName (string signalName)
+ {
+ Wrapper.Widget selWidget = selection as Wrapper.Widget;
+ if (selWidget != null) {
+// if (selWidget.IsTopLevel)
+// return "On" + signalName;
+// else
+// return "On" + GetIdentifier (selWidget.Wrapped.Name) + signalName;
+ return string.Format ("{0}_{1}",
+ GetIdentifier (selWidget.Wrapped.Name), signalName);
+ }
+
+ Wrapper.Action action = selection as Wrapper.Action;
+ if (action != null) {
+ return "On" + GetIdentifier (action.Name) + signalName;
+ }
+
+ return "On" + signalName;
+ }
+
+ string GetIdentifier (string name)
+ {
+ StringBuilder sb = new StringBuilder ();
+
+ bool wstart = true;
+ foreach (char c in name) {
+ if (c == '_' || c == '-' || c == ' ' || !char.IsLetterOrDigit (c)) {
+ wstart = true;
+ continue;
+ }
+ if (wstart) {
+ sb.Append (char.ToUpper (c));
+ wstart = false;
+ } else
+ sb.Append (c);
+ }
+ return sb.ToString ();
+ }
+
+ void OnHandlerEdited (object sender, Gtk.EditedArgs args)
+ {
+ if (args.NewText == EmptyHandlerText)
+ return;
+
+ Gtk.TreeIter iter;
+ if (!store.GetIterFromString (out iter, args.Path))
+ return;
+
+ AddHandler (iter, args.NewText);
+ }
+
+ void AddHandler (Gtk.TreeIter iter, string name)
+ {
+ internalChange = true;
+
+ Gtk.TreeIter piter = iter;
+ while (store.IterDepth (piter) != 0)
+ store.IterParent (out piter, piter);
+
+ Signal signal = GetSignal (iter);
+ if (signal == null) {
+ if (name != "") {
+ SignalDescriptor sd = GetSignalDescriptor (iter);
+ signal = new Signal (sd);
+ signal.Handler = name;
+ selection.Signals.Add (signal);
+ SetSignalData (iter, signal);
+ store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
+ if (store.IterDepth (iter) != 1)
+ store.IterParent (out iter, iter);
+ InsertEmptySignalRow (iter, null);
+ }
+ } else {
+ if (name != "") {
+ signal.Handler = name;
+ store.SetValue (iter, ColHandler, signal.Handler);
+ } else {
+ selection.Signals.Remove (signal);
+ if (store.IterDepth (iter) == 1) {
+ if (store.IterNChildren (iter) == 1) {
+ Gtk.TreeIter parent;
+ store.IterParent (out parent, iter);
+ store.Remove (ref iter);
+ InsertEmptySignalRow (parent, signal.SignalDescriptor.Name);
+ } else {
+ Gtk.TreeIter citer;
+ store.IterChildren (out citer, iter);
+ Signal csignal = GetSignal (citer);
+ store.Remove (ref citer);
+ SetSignalData (iter, csignal);
+ if (store.IterNChildren (iter) == 1)
+ tree.CollapseRow (store.GetPath (iter));
+ }
+ } else
+ store.Remove (ref iter);
+ }
+ }
+ UpdateGroupStatus (piter);
+ internalChange = false;
+ }
+
+ void OnAfterToggled (object o, Gtk.ToggledArgs args)
+ {
+ Gtk.TreeIter it;
+ if (store.GetIterFromString (out it, args.Path)) {
+ Signal signal = GetSignal (it);
+ if (signal != null) {
+ internalChange = true;
+ signal.After = !signal.After;
+ internalChange = false;
+ store.SetValue (it, ColAfter, signal.After);
+ }
+ }
+ }
+
+ void UpdateGroupStatus (Gtk.TreeIter iter)
+ {
+ Gtk.TreeIter signalIter;
+ if (store.IterChildren (out signalIter, iter)) {
+ do {
+ if (store.IterNChildren (signalIter) > 0) {
+ store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
+ return;
+ }
+ } while (store.IterNext (ref signalIter));
+ }
+ store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Normal);
+ }
+
+ Signal GetSignal (Gtk.TreeIter iter)
+ {
+ if (! (bool) store.GetValue (iter, ColHasHandler))
+ return null;
+ string handler = (string) store.GetValue (iter, ColHandler);
+ foreach (Signal sig in selection.Signals)
+ if (sig.Handler == handler)
+ return sig;
+ return null;
+ }
+
+ SignalDescriptor GetSignalDescriptor (Gtk.TreeIter iter)
+ {
+ Gtk.TreeIter group_iter;
+ if (! (bool) store.GetValue (iter, ColIsSignal) || !store.IterParent (out group_iter, iter))
+ return null;
+ string name = (string) store.GetValue (iter, ColSignal);
+ string group_name = (string) store.GetValue (group_iter, ColSignal);
+
+ foreach (ItemGroup igroup in selection.ClassDescriptor.SignalGroups) {
+ if (igroup.Label != group_name)
+ continue;
+ SignalDescriptor desc = (SignalDescriptor) igroup [name];
+ if (desc != null)
+ return desc;
+ }
+
+ return null;
+ }
+
+ ArrayList SaveStatus ()
+ {
+ ArrayList list = new ArrayList ();
+
+ Gtk.TreeIter it;
+ if (!store.GetIterFirst (out it))
+ return list;
+
+ do {
+ SaveStatus (list, "", it);
+ } while (store.IterNext (ref it));
+
+ return list;
+ }
+
+ void SaveStatus (ArrayList list, string path, Gtk.TreeIter iter)
+ {
+ string basePath = path + "/" + store.GetValue (iter, ColSignal);
+
+ if (!tree.GetRowExpanded (store.GetPath (iter)))
+ return;
+
+ list.Add (basePath);
+
+ if (store.IterChildren (out iter, iter)) {
+ do {
+ SaveStatus (list, basePath, iter);
+ } while (store.IterNext (ref iter));
+ }
+ }
+
+ void RestoreStatus (ArrayList list)
+ {
+ foreach (string namePath in list) {
+ string[] names = namePath.Split ('/');
+
+ Gtk.TreeIter iter = Gtk.TreeIter.Zero;
+
+ bool found = true;
+ foreach (string name in names) {
+ if (name == "") continue;
+ if (!FindChildByName (name, ref iter)) {
+ found = false;
+ break;
+ }
+ }
+
+ if (found)
+ tree.ExpandRow (store.GetPath (iter), false);
+ }
+ }
+
+ bool FindChildByName (string name, ref Gtk.TreeIter iter)
+ {
+ if (iter.Equals (Gtk.TreeIter.Zero)) {
+ if (!store.GetIterFirst (out iter))
+ return false;
+ } else if (!store.IterChildren (out iter, iter))
+ return false;
+
+ do {
+ if (name == (string) store.GetValue (iter, ColSignal))
+ return true;
+ }
+ while (store.IterNext (ref iter));
+
+ return false;
+ }
+
+ string EmptyHandlerMarkup {
+ get { return "<i><span foreground=\"grey\">" + EmptyHandlerText + "</span></i>"; }
+ }
+
+ string EmptyHandlerText {
+ get { return Catalog.GetString ("Click here to add a new handler"); }
+ }
+ }
+
+ internal class SignalsEditorEditSession: MarshalByRefObject
+ {
+ SignalsEditorBackend backend;
+
+ public SignalsEditorEditSession (SignalsEditorFrontend frontend)
+ {
+ backend = new SignalsEditorBackend (frontend);
+ }
+
+ public SignalsEditorBackend Editor {
+ get { return backend; }
+ }
+
+ public ProjectBackend ProjectBackend {
+ get { return backend.ProjectBackend; }
+ set { backend.ProjectBackend = value; }
+ }
+
+ public Signal SelectedSignal {
+ get {
+ return backend.SelectedSignal;
+ }
+ }
+
+ public void Dispose ()
+ {
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/UndoQueue.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/UndoQueue.cs
new file mode 100644
index 0000000000..0ae6a6fc02
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/UndoQueue.cs
@@ -0,0 +1,282 @@
+
+using System;
+using System.Xml;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Stetic
+{
+ public class UndoQueue: MarshalByRefObject
+ {
+ List<UndoRedoChange> changeList = new List<UndoRedoChange> ();
+ int undoListCount = 0;
+ static UndoQueue empty = new UndoQueue ();
+
+ public void AddChange (UndoRedoChange change)
+ {
+ if (undoListCount < changeList.Count) {
+ // Destroy all undone changes
+ changeList.RemoveRange (undoListCount, changeList.Count - undoListCount);
+ }
+ changeList.Add (change);
+ undoListCount = changeList.Count;
+ }
+
+ public IEnumerable<UndoRedoChange> Changes {
+ get { return changeList; }
+ }
+
+ public static UndoQueue Empty {
+ get { return empty; }
+ }
+
+ public bool CanUndo {
+ get { return undoListCount > 0; }
+ }
+
+ public bool CanRedo {
+ get { return undoListCount < changeList.Count; }
+ }
+
+ public void Undo ()
+ {
+ if (undoListCount == 0)
+ return;
+
+ UndoRedoChange change = (UndoRedoChange) changeList [--undoListCount];
+ if (change.CheckValid ()) {
+ UndoRedoChange res = change.ApplyChange ();
+ if (res != null)
+ changeList [undoListCount] = res;
+ else
+ // Undo failed
+ changeList.RemoveAt (undoListCount);
+ } else {
+ changeList.RemoveAt (undoListCount);
+ Undo ();
+ }
+ }
+
+ public void Redo ()
+ {
+ if (undoListCount == changeList.Count)
+ return;
+
+ UndoRedoChange change = (UndoRedoChange) changeList [undoListCount++];
+ if (change.CheckValid ()) {
+ UndoRedoChange res = change.ApplyChange ();
+ if (res != null)
+ changeList [undoListCount - 1] = res;
+ else {
+ // Redo failed
+ undoListCount--;
+ changeList.RemoveAt (undoListCount);
+ }
+ }
+ else {
+ changeList.RemoveAt (--undoListCount);
+ Redo ();
+ }
+ }
+
+ public void Purge ()
+ {
+ for (int n=0; n<changeList.Count; n++) {
+ UndoRedoChange change = (UndoRedoChange) changeList [n];
+ if (!change.CheckValid()) {
+ changeList.RemoveAt (n);
+ if (n < undoListCount)
+ undoListCount--;
+ }
+ }
+ }
+ }
+
+ public abstract class UndoRedoChange: MarshalByRefObject
+ {
+ public abstract UndoRedoChange ApplyChange ();
+
+ public virtual bool CheckValid ()
+ {
+ return true;
+ }
+ }
+
+
+ class ObjectWrapperUndoRedoChange: UndoRedoChange
+ {
+ UndoRedoManager manager;
+ public string TargetObject;
+ public object Diff;
+ public ObjectWrapperUndoRedoChange Next;
+
+ public ObjectWrapperUndoRedoChange (UndoRedoManager manager, string targetObject, object diff)
+ {
+ this.manager = manager;
+ this.TargetObject = targetObject;
+ this.Diff = diff;
+ }
+
+ public UndoRedoManager Manager {
+ get { return manager; }
+ set { manager = value; }
+ }
+
+ public override UndoRedoChange ApplyChange ()
+ {
+ return manager.ApplyChange (this);
+ }
+
+ public override bool CheckValid ()
+ {
+ return manager.CheckValid ();
+ }
+ }
+
+ class UndoRedoManager: IDisposable
+ {
+ UndoQueue queue;
+ ObjectWrapper rootObject;
+ bool updating;
+ UndoManager undoManager = new UndoManager ();
+
+ public UndoRedoManager ()
+ {
+ undoManager.UndoCheckpoint += OnUndoCheckpoint;
+ }
+
+ public ObjectWrapper RootObject {
+ get { return rootObject; }
+ set {
+ rootObject = value;
+ undoManager.SetRoot (rootObject);
+ }
+ }
+
+ public UndoQueue UndoQueue {
+ get { return queue; }
+ set { queue = value; }
+ }
+
+ internal UndoManager UndoManager {
+ get { return undoManager; }
+ }
+
+ void OnUndoCheckpoint (object sender, UndoCheckpointEventArgs args)
+ {
+ AddChange (args.ModifiedObjects);
+ }
+
+ void AddChange (ObjectWrapper[] obs)
+ {
+ if (updating || queue == null)
+ return;
+
+ ObjectWrapperUndoRedoChange firstChange = null;
+ ObjectWrapperUndoRedoChange lastChange = null;
+
+// Console.WriteLine ("** UNDO CHECKPOINT: {0} objects", obs.Length);
+
+ foreach (ObjectWrapper ob in obs) {
+
+ // Get the diff for going from the new status to the old status
+ object diff = GetDiff (ob);
+
+ if (diff == null) // No differences
+ continue;
+
+// Console.WriteLine ("ADDCHANGE " + ob + " uid:" + ob.UndoId);
+// PrintPatch (diff);
+
+ if (ob.UndoId == null || ob.UndoId.Length == 0)
+ throw new InvalidOperationException ("Object of type '" + ob.GetType () + "' does not have an undo id.");
+
+ ObjectWrapperUndoRedoChange change = new ObjectWrapperUndoRedoChange (this, ob.UndoId, diff);
+ if (lastChange == null)
+ lastChange = firstChange = change;
+ else {
+ lastChange.Next = change;
+ lastChange = change;
+ }
+ }
+ if (firstChange != null)
+ queue.AddChange (firstChange);
+ }
+
+ protected virtual object GetDiff (ObjectWrapper w)
+ {
+ return w.GetUndoDiff ();
+ }
+
+ public UndoRedoChange ApplyChange (ObjectWrapperUndoRedoChange first)
+ {
+ updating = true;
+
+ try {
+ ObjectWrapperUndoRedoChange change = first;
+ ObjectWrapperUndoRedoChange lastRedo = null;
+ while (change != null) {
+ ObjectWrapperUndoRedoChange redo = ApplyDiff (change.TargetObject, change.Diff);
+ if (redo != null) {
+ redo.Next = lastRedo;
+ lastRedo = redo;
+ }
+ change = change.Next;
+ }
+ return lastRedo;
+ } catch (Exception ex) {
+ Console.WriteLine (ex);
+ return null;
+ } finally {
+ updating = false;
+ }
+ }
+
+ ObjectWrapperUndoRedoChange ApplyDiff (string id, object diff)
+ {
+// Console.WriteLine ("** APPLYING DIFF: uid:" + id);
+// PrintPatch (diff);
+
+ ObjectWrapper ww = rootObject.FindObjectByUndoId (id);
+ if (ww == null) {
+ Console.WriteLine ("Object with undo id '{0}' not found", id);
+ return null;
+ }
+
+ object reverseDiff = ww.ApplyUndoRedoDiff (diff);
+
+ if (reverseDiff != null) {
+// Console.WriteLine ("** REVERSE DIFF:");
+// PrintPatch (reverseDiff);
+
+ ObjectWrapperUndoRedoChange change = new ObjectWrapperUndoRedoChange (this, id, reverseDiff);
+ return change;
+ } else
+ return null;
+ }
+
+ internal bool CheckValid ()
+ {
+ return rootObject != null;
+ }
+
+ public void Dispose ()
+ {
+ rootObject = null;
+ if (queue != null)
+ queue.Purge ();
+ }
+
+ internal void PrintPatch (object diff)
+ {
+ if (diff is Array) {
+ foreach (object ob in (Array)diff)
+ if (ob != null) PrintPatch (ob);
+ } else if (diff is XmlElement)
+ Console.WriteLine (((XmlElement)diff).OuterXml);
+ else
+ Console.WriteLine (diff.ToString ());
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/UserInterface.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/UserInterface.cs
new file mode 100644
index 0000000000..3eab8b8b89
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/UserInterface.cs
@@ -0,0 +1,34 @@
+
+using System;
+
+namespace Stetic
+{
+ internal class UserInterface
+ {
+ UserInterface()
+ {
+ }
+
+ public static WidgetDesignerBackend CreateWidgetDesigner (Gtk.Container widget)
+ {
+ Stetic.Wrapper.Container wc = Stetic.Wrapper.Container.Lookup (widget);
+ return CreateWidgetDesigner (widget, wc.DesignWidth, wc.DesignHeight);
+ }
+
+ public static WidgetDesignerBackend CreateWidgetDesigner (Gtk.Container widget, int designWidth, int designHeight)
+ {
+ return new WidgetDesignerBackend (widget, designWidth, designHeight);
+ }
+
+ public static ActionGroupDesignerBackend CreateActionGroupDesigner (ProjectBackend project, ActionGroupToolbar groupToolbar)
+ {
+ Editor.ActionGroupEditor agroupEditor = new Editor.ActionGroupEditor ();
+ agroupEditor.Project = project;
+ WidgetDesignerBackend groupDesign = new WidgetDesignerBackend (agroupEditor, -1, -1);
+
+ groupToolbar.Bind (agroupEditor);
+
+ return new ActionGroupDesignerBackend (groupDesign, agroupEditor, groupToolbar);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetActionBar.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetActionBar.cs
new file mode 100644
index 0000000000..c9db05dd57
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetActionBar.cs
@@ -0,0 +1,251 @@
+
+using System;
+using System.Collections;
+using Gtk;
+using Mono.Unix;
+
+namespace Stetic
+{
+
+ internal class WidgetActionBar: Gtk.Toolbar
+ {
+ ProjectBackend project;
+ Stetic.Wrapper.Widget rootWidget;
+ WidgetTreeCombo combo;
+ ToolItem comboItem;
+ Stetic.Wrapper.Widget selection;
+ Stetic.Wrapper.Container.ContainerChild packingSelection;
+ Hashtable editors, wrappers;
+ Hashtable sensitives, invisibles;
+ ArrayList toggles;
+ bool disposed;
+ bool updating;
+ bool allowBinding;
+ WidgetDesignerFrontend frontend;
+
+ public WidgetActionBar (WidgetDesignerFrontend frontend, Stetic.Wrapper.Widget rootWidget)
+ {
+ this.frontend = frontend;
+
+ editors = new Hashtable ();
+ wrappers = new Hashtable ();
+ sensitives = new Hashtable ();
+ invisibles = new Hashtable ();
+ toggles = new ArrayList ();
+
+ IconSize = IconSize.Menu;
+ Orientation = Orientation.Horizontal;
+ ToolbarStyle = ToolbarStyle.BothHoriz;
+
+ combo = new WidgetTreeCombo ();
+ comboItem = new ToolItem ();
+ comboItem.Add (combo);
+ comboItem.ShowAll ();
+ Insert (comboItem, -1);
+ ShowAll ();
+ RootWidget = rootWidget;
+ }
+
+ public override void Dispose ()
+ {
+ if (disposed)
+ return;
+ disposed = true;
+ combo.Destroy ();
+ combo = null;
+ RootWidget = null;
+ Clear ();
+ base.Dispose ();
+ }
+
+ public bool AllowWidgetBinding {
+ get { return allowBinding; }
+ set { allowBinding = value; }
+ }
+
+ public Stetic.Wrapper.Widget RootWidget {
+ get { return rootWidget; }
+ set {
+ if (project != null) {
+ project.SelectionChanged -= OnSelectionChanged;
+ project = null;
+ }
+
+ rootWidget = value;
+ if (combo != null)
+ combo.RootWidget = rootWidget;
+
+ if (rootWidget != null) {
+ project = (Stetic.ProjectBackend) rootWidget.Project;
+ UpdateSelection (Wrapper.Widget.Lookup (project.Selection));
+ project.SelectionChanged += OnSelectionChanged;
+ }
+ }
+ }
+
+ void Clear ()
+ {
+ if (selection != null) {
+ selection.Notify -= Notified;
+ if (packingSelection != null)
+ packingSelection.Notify -= Notified;
+ }
+
+ selection = null;
+ packingSelection = null;
+
+ editors.Clear ();
+ wrappers.Clear ();
+ sensitives.Clear ();
+ invisibles.Clear ();
+ toggles.Clear ();
+
+ foreach (Gtk.Widget child in Children)
+ if (child != comboItem) {
+ Remove (child);
+ child.Destroy ();
+ }
+ }
+
+ void OnSelectionChanged (object s, Wrapper.WidgetEventArgs args)
+ {
+ UpdateSelection (args.WidgetWrapper);
+ }
+
+ void UpdateSelection (Wrapper.Widget w)
+ {
+ Clear ();
+ selection = w;
+
+ if (selection == null) {
+ combo.SetSelection (null);
+ return;
+ }
+
+ // Look for the root widget, and only update the bar if the selected
+ // widget is a child of the root widget
+
+ while (w != null && !w.IsTopLevel) {
+ w = Stetic.Wrapper.Container.LookupParent ((Gtk.Widget) w.Wrapped);
+ }
+ if (w == null || w != rootWidget)
+ return;
+
+ combo.SetSelection (selection);
+
+ selection.Notify += Notified;
+ packingSelection = Stetic.Wrapper.Container.ChildWrapper (selection);
+ if (packingSelection != null)
+ packingSelection.Notify += Notified;
+
+ AddWidgetCommands (selection);
+ UpdateSensitivity ();
+ }
+
+ protected virtual void AddWidgetCommands (ObjectWrapper wrapper)
+ {
+ if (allowBinding && wrapper != RootWidget) {
+ // Show the Bind to Field button only for children of the root container.
+ ToolButton bindButton = new ToolButton (null, Catalog.GetString ("Bind to Field"));
+ bindButton.IsImportant = true;
+ bindButton.Clicked += delegate { frontend.NotifyBindField (); };
+ bindButton.Show ();
+ Insert (bindButton, -1);
+ }
+ AddCommands (wrapper);
+ }
+
+ void AddCommands (ObjectWrapper wrapper)
+ {
+ foreach (ItemGroup igroup in wrapper.ClassDescriptor.ItemGroups) {
+ foreach (ItemDescriptor desc in igroup) {
+ if ((desc is CommandDescriptor) && desc.SupportsGtkVersion (project.TargetGtkVersion))
+ AppendCommand ((CommandDescriptor) desc, wrapper);
+ }
+ }
+
+ Stetic.Wrapper.Widget widget = wrapper as Stetic.Wrapper.Widget;
+ if (widget != null) {
+ Stetic.Wrapper.Container.ContainerChild packingSelection = Stetic.Wrapper.Container.ChildWrapper (widget);
+ if (packingSelection != null)
+ AddCommands (packingSelection);
+ }
+ }
+
+ void AppendCommand (CommandDescriptor cmd, ObjectWrapper widget)
+ {
+ Gtk.ToolButton button;
+
+ if (cmd.IsToggleCommand (widget.Wrapped)) {
+ button = new Gtk.ToggleToolButton ();
+ ((Gtk.ToggleToolButton)button).Active = cmd.IsToogled (widget.Wrapped);
+ toggles.Add (cmd);
+ editors[cmd.Name] = button;
+ } else {
+ button = new Gtk.ToolButton (null, null);
+ }
+
+ Gtk.Image img = cmd.GetImage ();
+ if (img != null) {
+ button.IconWidget = img;
+ button.Label = cmd.Label;
+ if (cmd.Label != null && cmd.Label.Length > 0)
+ button.TooltipText = cmd.Label;
+ }
+ else {
+ button.Label = cmd.Label;
+ button.IsImportant = true;
+ }
+ button.Clicked += delegate (object o, EventArgs args) {
+ if (!updating)
+ cmd.Run (widget.Wrapped);
+ };
+ button.ShowAll ();
+ Insert (button, -1);
+
+ if (cmd.HasDependencies) {
+ editors[cmd.Name] = button;
+ sensitives[cmd] = cmd;
+ }
+ if (cmd.HasVisibility) {
+ editors[cmd.Name] = button;
+ invisibles[cmd] = cmd;
+ }
+ wrappers [cmd] = widget;
+ }
+
+ void Notified (object s, string propertyName)
+ {
+ UpdateSensitivity ();
+ }
+
+ void UpdateSensitivity ()
+ {
+ foreach (ItemDescriptor item in sensitives.Keys) {
+ Widget w = editors[item.Name] as Widget;
+ if (w != null) {
+ ObjectWrapper wrapper = wrappers [item] as ObjectWrapper;
+ object ob = sensitives.Contains (item) ? wrapper.Wrapped : null;
+ w.Sensitive = item.EnabledFor (ob);
+ }
+ }
+ foreach (ItemDescriptor item in invisibles.Keys) {
+ Widget w = editors[item.Name] as Widget;
+ if (w != null) {
+ ObjectWrapper wrapper = wrappers [item] as ObjectWrapper;
+ object ob = invisibles.Contains (item) ? wrapper.Wrapped : null;
+ w.Visible = item.VisibleFor (ob);
+ }
+ }
+ foreach (CommandDescriptor cmd in toggles) {
+ ToggleToolButton w = editors[cmd.Name] as ToggleToolButton;
+ if (w != null) {
+ ObjectWrapper wrapper = wrappers [cmd] as ObjectWrapper;
+ updating = true;
+ w.Active = cmd.IsToogled (wrapper.Wrapped);
+ updating = false;
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetComponent.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetComponent.cs
new file mode 100644
index 0000000000..84f63413ca
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetComponent.cs
@@ -0,0 +1,122 @@
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+
+namespace Stetic
+{
+ public class WidgetComponent: Component
+ {
+ static WidgetComponent placeholder;
+
+ public WidgetComponent (Application app, object backend, string name, ComponentType type): base (app, backend, name, type)
+ {
+ }
+
+ public override string Name {
+ get {
+ if (name == null)
+ UpdateComponentInfo ();
+ return name;
+ }
+ set {
+ name = value;
+ if (app != null)
+ app.Backend.RenameWidget ((Wrapper.Widget)backend, value);
+ }
+ }
+
+ public override bool GeneratePublic {
+ get { return ((Wrapper.Widget)backend).GeneratePublic; }
+ set { ((Wrapper.Widget)backend).GeneratePublic = value; }
+ }
+
+ internal void UpdateName (string name)
+ {
+ this.name = name;
+ }
+
+ public override Component[] GetChildren ()
+ {
+ if (app == null)
+ return new Component [0];
+ ArrayList wws = app.Backend.GetWidgetChildren ((Wrapper.Widget)backend);
+ if (wws == null)
+ return new Component [0];
+ ArrayList children = new ArrayList (wws.Count);
+ for (int n=0; n<wws.Count; n++) {
+ Component c = app.GetComponent (wws[n], null, null);
+ if (c != null)
+ children.Add (c);
+ }
+ return (Component[]) children.ToArray (typeof(Component));
+ }
+
+ void UpdateComponentInfo ()
+ {
+ if (app == null)
+ return;
+ string typeName;
+ app.Backend.GetComponentInfo (backend, out name, out typeName);
+ type = app.GetComponentType (typeName);
+ }
+
+ public override ComponentType Type {
+ get {
+ if (type == null)
+ UpdateComponentInfo ();
+ return type;
+ }
+ }
+
+ public ActionGroupComponent[] GetActionGroups ()
+ {
+ if (app == null)
+ return new ActionGroupComponent [0];
+
+ ArrayList comps = new ArrayList ();
+ Wrapper.ActionGroup[] groups = app.Backend.GetActionGroups ((Wrapper.Widget)backend);
+ for (int n=0; n<groups.Length; n++) {
+ ActionGroupComponent ag = (ActionGroupComponent) app.GetComponent (groups[n], null, null);
+ if (ag != null)
+ comps.Add (ag);
+ }
+
+ return (ActionGroupComponent[]) comps.ToArray (typeof(ActionGroupComponent));
+ }
+
+ public bool IsWindow {
+ get { return backend is Wrapper.Window; }
+ }
+
+ internal static WidgetComponent Placeholder {
+ get {
+ if (placeholder == null) {
+ placeholder = new WidgetComponent (null, null, "", ComponentType.Unknown);
+ }
+ return placeholder;
+ }
+ }
+ }
+
+ [Serializable]
+ public class ObjectBindInfo
+ {
+ string typeName;
+ string name;
+
+ public ObjectBindInfo (string typeName, string name)
+ {
+ this.typeName = typeName;
+ this.name = name;
+ }
+
+ public string TypeName {
+ get { return typeName; }
+ }
+
+ public string Name {
+ get { return name; }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesigner.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesigner.cs
new file mode 100644
index 0000000000..cbcbbbb418
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesigner.cs
@@ -0,0 +1,423 @@
+using System;
+using System.Collections;
+
+namespace Stetic
+{
+ public delegate void ComponentDropCallback ();
+
+ public class WidgetDesigner: Designer
+ {
+ WidgetEditSession session;
+ WidgetDesignerFrontend frontend;
+ Component selection;
+ Component rootWidget;
+
+ Project project;
+ int reloadCount;
+
+ string componentName;
+ bool disposed;
+
+ bool canCut, canCopy, canPaste, canDelete;
+
+ public event EventHandler BindField;
+ public event EventHandler Changed;
+ public event EventHandler SelectionChanged;
+ public event EventHandler RootComponentChanged;
+ public event ComponentSignalEventHandler SignalAdded;
+ public event ComponentSignalEventHandler SignalRemoved;
+ public event ComponentSignalEventHandler SignalChanged;
+ public event ComponentNameEventHandler ComponentNameChanged;
+ public event EventHandler ComponentTypesChanged;
+
+ internal WidgetDesigner (Project project, string componentName): base (project.App)
+ {
+ this.componentName = componentName;
+ this.project = project;
+ frontend = new WidgetDesignerFrontend (this);
+
+ project.SignalAdded += OnSignalAdded;
+ project.SignalRemoved += OnSignalRemoved;
+ project.SignalChanged += OnSignalChanged;
+ project.ComponentNameChanged += OnComponentNameChanged;
+ project.ComponentTypesChanged += OnComponentTypesChanged;
+ project.BackendChanged += OnProjectBackendChanged;
+
+ CreateSession ();
+ }
+
+ public Component RootComponent {
+ get { return rootWidget; }
+ }
+
+ public override ProjectItemInfo ProjectItem {
+ get { return project.GetWidget (rootWidget.Name); }
+ }
+
+ public ComponentType[] GetComponentTypes ()
+ {
+ if (!disposed) {
+ ArrayList types = new ArrayList ();
+ types.AddRange (project.GetComponentTypes ());
+
+ // Add actions from the local action groups
+
+ WidgetComponent c = rootWidget as WidgetComponent;
+ if (c != null) {
+ foreach (ActionGroupComponent grp in c.GetActionGroups ()) {
+ foreach (ActionComponent ac in grp.GetActions ())
+ types.Add (new ComponentType (app, ac));
+ }
+ }
+ return (ComponentType[]) types.ToArray (typeof(ComponentType));
+ }
+ else
+ return new ComponentType[0];
+ }
+
+ public void BeginComponentDrag (ComponentType type, Gtk.Widget source, Gdk.DragContext ctx)
+ {
+ Stetic.ObjectWrapper wrapper = type.Action != null ? (Stetic.ObjectWrapper) type.Action.Backend : null;
+ app.Backend.BeginComponentDrag (project.ProjectBackend, type.Description, type.ClassName, wrapper, source, ctx, null);
+
+ }
+
+ public void BeginComponentDrag (string title, string className, Gtk.Widget source, Gdk.DragContext ctx, ComponentDropCallback callback)
+ {
+ app.Backend.BeginComponentDrag (project.ProjectBackend, title, className, null, source, ctx, callback);
+
+ }
+
+ // Creates an action group designer for the widget being edited by this widget designer
+ public ActionGroupDesigner CreateActionGroupDesigner ()
+ {
+ if (disposed)
+ throw new ObjectDisposedException ("WidgetDesigner");
+ return new ActionGroupDesigner (project, componentName, null, this, true);
+
+ }
+
+ public bool Modified {
+ get { return session != null && session.Modified; }
+ }
+
+ internal override void SetActive ()
+ {
+ if (!disposed)
+ project.App.SetActiveDesignSession (project, session);
+ }
+
+ public bool AllowWidgetBinding {
+ get { return session != null && session.AllowWidgetBinding; }
+ set {
+ if (session != null)
+ session.AllowWidgetBinding = value;
+ }
+ }
+
+ public ImportFileDelegate ImportFileCallback {
+ get { return project.ImportFileCallback; }
+ set { project.ImportFileCallback = value; }
+ }
+
+ public object SaveStatus ()
+ {
+ return session.SaveState ();
+ }
+
+ public void LoadStatus (object ob)
+ {
+ session.RestoreState (ob);
+ }
+
+ void CreateSession ()
+ {
+ try {
+ session = project.ProjectBackend.CreateWidgetDesignerSession (frontend, componentName);
+ ResetCustomWidget ();
+ rootWidget = app.GetComponent (session.RootWidget, null, null);
+ } catch (Exception ex) {
+ Console.WriteLine (ex);
+ Gtk.Label lab = new Gtk.Label ();
+ lab.Text = Mono.Unix.Catalog.GetString ("The designer could not be loaded.") + "\n\n" + ex.Message;
+ lab.Wrap = true;
+ lab.WidthRequest = 400;
+ AddCustomWidget (lab);
+ session = null;
+ }
+ }
+
+ protected override void OnCreatePlug (uint socketId)
+ {
+ session.CreateWrapperWidgetPlug (socketId);
+ }
+
+ protected override void OnDestroyPlug (uint socketId)
+ {
+ session.DestroyWrapperWidgetPlug ();
+ }
+
+ protected override Gtk.Widget OnCreateWidget ()
+ {
+ return session.WrapperWidget;
+ }
+
+ public Component Selection {
+ get {
+ return selection;
+ }
+ }
+
+ public void CopySelection ()
+ {
+ if (session != null)
+ session.ClipboardCopySelection ();
+ }
+
+ public void CutSelection ()
+ {
+ if (session != null)
+ session.ClipboardCutSelection ();
+ }
+
+ public void PasteToSelection ()
+ {
+ if (session != null)
+ session.ClipboardPaste ();
+ }
+
+ public void DeleteSelection ()
+ {
+ if (session != null)
+ session.DeleteSelection ();
+ }
+
+ public bool CanDeleteSelection {
+ get { return canDelete; }
+ }
+
+ public bool CanCutSelection {
+ get { return canCut; }
+ }
+
+ public bool CanCopySelection {
+ get { return canCopy; }
+ }
+
+ public bool CanPasteToSelection {
+ get { return canPaste; }
+ }
+
+ public UndoQueue UndoQueue {
+ get {
+ if (session != null)
+ return session.UndoQueue;
+ else
+ return UndoQueue.Empty;
+ }
+ }
+
+ protected override void OnDestroyed ()
+ {
+ try {
+ if (disposed)
+ return;
+
+ if (project.App.ActiveProject == project)
+ project.App.ActiveProject = null;
+
+ disposed = true;
+ frontend.disposed = true;
+ project.SignalAdded -= OnSignalAdded;
+ project.SignalRemoved -= OnSignalRemoved;
+ project.SignalChanged -= OnSignalChanged;
+ project.ComponentNameChanged -= OnComponentNameChanged;
+ project.ComponentTypesChanged -= OnComponentTypesChanged;
+ project.BackendChanged -= OnProjectBackendChanged;
+
+ if (session != null) {
+ session.Dispose ();
+ session = null;
+ }
+
+ System.Runtime.Remoting.RemotingServices.Disconnect (frontend);
+ frontend = null;
+ rootWidget = null;
+ selection = null;
+ } finally {
+ base.OnDestroyed ();
+ }
+ }
+
+ public void Save ()
+ {
+ if (session != null)
+ session.Save ();
+ }
+
+ void OnComponentNameChanged (object s, ComponentNameEventArgs args)
+ {
+ if (!disposed && ComponentNameChanged != null)
+ ComponentNameChanged (this, args);
+ }
+
+ internal void NotifyRootWidgetChanging ()
+ {
+ PrepareUpdateWidget ();
+ }
+
+ internal void NotifyRootWidgetChanged ()
+ {
+ object rw = session.RootWidget;
+ if (rw != null)
+ rootWidget = app.GetComponent (session.RootWidget, null, null);
+ else
+ rootWidget = null;
+
+ UpdateWidget ();
+ if (RootComponentChanged != null)
+ RootComponentChanged (this, EventArgs.Empty);
+ }
+
+ internal override void OnBackendChanging ()
+ {
+ reloadCount = 0;
+ base.OnBackendChanging ();
+ }
+
+ internal override void OnBackendChanged (ApplicationBackend oldBackend)
+ {
+ // Can't do anything until the projects are reloaded
+ // This is checked in OnProjectBackendChanged.
+ }
+
+ void OnProjectBackendChanged (ApplicationBackend oldBackend)
+ {
+ if (++reloadCount == 2) {
+ object sessionData = null;
+
+// if (oldBackend != null && !autoCommitChanges) {
+// sessionData = session.SaveState ();
+// session.DestroyWrapperWidgetPlug ();
+// }
+
+ // Don't dispose the session here, since it will dispose
+ // the underlying project, and we can't do it because
+ // it may need to process the OnBackendChanging event
+ // as well.
+
+ CreateSession ();
+
+ if (sessionData != null && session != null)
+ session.RestoreState (sessionData);
+
+ base.OnBackendChanged (oldBackend);
+ NotifyRootWidgetChanged ();
+ }
+ }
+
+ void OnComponentTypesChanged (object s, EventArgs a)
+ {
+ if (ComponentTypesChanged != null)
+ ComponentTypesChanged (this, a);
+ }
+
+ void OnSignalAdded (object sender, Stetic.ComponentSignalEventArgs args)
+ {
+ if (SignalAdded != null)
+ SignalAdded (this, args);
+ }
+
+ void OnSignalRemoved (object sender, Stetic.ComponentSignalEventArgs args)
+ {
+ if (SignalRemoved != null)
+ SignalRemoved (this, args);
+ }
+
+ void OnSignalChanged (object sender, Stetic.ComponentSignalEventArgs args)
+ {
+ if (SignalChanged != null)
+ SignalChanged (this, args);
+ }
+
+ internal void NotifyBindField ()
+ {
+ if (BindField != null)
+ BindField (this, EventArgs.Empty);
+ }
+
+ internal void NotifyChanged ()
+ {
+ if (Changed != null)
+ Changed (this, EventArgs.Empty);
+ }
+
+ internal void NotifySelectionChanged (object ob, bool canCut, bool canCopy, bool canPaste, bool canDelete)
+ {
+ this.canCut = canCut;
+ this.canCopy = canCopy;
+ this.canPaste = canPaste;
+ this.canDelete = canDelete;
+
+ if (ob != null)
+ selection = app.GetComponent (ob, null, null);
+ else
+ selection = null;
+
+ if (SelectionChanged != null)
+ SelectionChanged (this, EventArgs.Empty);
+ }
+ }
+
+ internal class WidgetDesignerFrontend: MarshalByRefObject
+ {
+ WidgetDesigner designer;
+ internal bool disposed;
+
+ public WidgetDesignerFrontend (WidgetDesigner designer)
+ {
+ this.designer = designer;
+ }
+
+ public void NotifyBindField ()
+ {
+ GuiDispatch.InvokeSync (
+ delegate { if (!disposed) designer.NotifyBindField (); }
+ );
+ }
+
+ public void NotifyChanged ()
+ {
+ GuiDispatch.InvokeSync (
+ delegate { if (!disposed) designer.NotifyChanged (); }
+ );
+ }
+
+ internal void NotifySelectionChanged (object ob, bool canCut, bool canCopy, bool canPaste, bool canDelete)
+ {
+ GuiDispatch.InvokeSync (
+ delegate { if (!disposed) designer.NotifySelectionChanged (ob, canCut, canCopy, canPaste, canDelete); }
+ );
+ }
+
+ public void NotifyRootWidgetChanged ()
+ {
+ GuiDispatch.InvokeSync (
+ delegate { if (!disposed) designer.NotifyRootWidgetChanged (); }
+ );
+ }
+
+ public void NotifyRootWidgetChanging ()
+ {
+ GuiDispatch.InvokeSync (
+ delegate { if (!disposed) designer.NotifyRootWidgetChanging (); }
+ );
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesignerBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesignerBackend.cs
new file mode 100644
index 0000000000..8c85049ccd
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetDesignerBackend.cs
@@ -0,0 +1,961 @@
+//
+// WidgetDesignerBackend.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+using System.Reflection;
+using Gtk;
+using Gdk;
+
+namespace Stetic
+{
+ internal class WidgetDesignerBackend: ScrolledWindow
+ {
+ ObjectWrapper wrapper;
+ Gtk.Widget preview;
+ ResizableFixed resizableFixed;
+
+ static IObjectViewer defaultObjectViewer;
+
+ public event EventHandler SelectionChanged;
+
+ internal static IObjectViewer DefaultObjectViewer {
+ get { return defaultObjectViewer; }
+ set { defaultObjectViewer = value; }
+ }
+
+ public object Selection {
+ get {
+ IObjectSelection sel = resizableFixed.GetSelection ();
+ if (sel != null)
+ return sel.DataObject;
+ else
+ return null;
+ }
+ }
+
+ internal IDesignArea DesignArea {
+ get { return resizableFixed; }
+ }
+
+ internal WidgetDesignerBackend (Gtk.Container container, int designWidth, int designHeight)
+ {
+ ShadowType = ShadowType.None;
+ HscrollbarPolicy = PolicyType.Automatic;
+ VscrollbarPolicy = PolicyType.Automatic;
+
+ resizableFixed = new ResizableFixed ();
+ resizableFixed.ObjectViewer = defaultObjectViewer;
+
+ wrapper = ObjectWrapper.Lookup (container);
+ TopLevelWindow window = container as TopLevelWindow;
+
+ if (window != null) {
+ preview = Stetic.Metacity.Preview.Create (window);
+ if (preview == null)
+ preview = Stetic.Windows.Preview.Create (window);
+ if (preview == null) {
+ // Use a regular box.
+ EventBox eventBox = new EventBox ();
+ eventBox.Add (container);
+ preview = eventBox;
+ }
+ } else {
+ EventBox eventBox = new EventBox ();
+ eventBox.Add (container);
+ preview = eventBox;
+ }
+
+ resizableFixed.Put (preview, container);
+
+ if (designWidth != -1) {
+ preview.WidthRequest = designWidth;
+ preview.HeightRequest = designHeight;
+ resizableFixed.AllowResize = true;
+ } else {
+ resizableFixed.AllowResize = false;
+ }
+
+ preview.SizeAllocated += new Gtk.SizeAllocatedHandler (OnResized);
+
+ AddWithViewport (resizableFixed);
+
+ if (wrapper != null)
+ wrapper.AttachDesigner (resizableFixed);
+
+ resizableFixed.SelectionChanged += OnSelectionChanged;
+ }
+
+ protected override void OnDestroyed ()
+ {
+ if (preview != null) {
+ if (wrapper != null)
+ wrapper.DetachDesigner (resizableFixed);
+ preview.SizeAllocated -= new Gtk.SizeAllocatedHandler (OnResized);
+ resizableFixed.SelectionChanged -= OnSelectionChanged;
+ resizableFixed = null;
+ preview = null;
+ wrapper = null;
+ }
+ base.OnDestroyed ();
+ }
+
+ public IObjectViewer ObjectViewer {
+ get { return resizableFixed.ObjectViewer; }
+ set { resizableFixed.ObjectViewer = value; }
+ }
+
+ public void UpdateObjectViewers ()
+ {
+ // This method has to be called to ensure that the property
+ // and signal viewers show information about the object
+ // selected in this designer.
+ resizableFixed.UpdateObjectViewers ();
+ }
+
+ void OnSelectionChanged (object ob, EventArgs a)
+ {
+ if (SelectionChanged != null)
+ SelectionChanged (this, a);
+ }
+
+ protected override void OnParentSet (Gtk.Widget previousParent)
+ {
+ base.OnParentSet (previousParent);
+
+ if (previousParent != null)
+ previousParent.Realized -= OnParentRealized;
+
+ if (Parent != null)
+ Parent.Realized += OnParentRealized;
+ }
+
+ void OnParentRealized (object s, EventArgs args)
+ {
+ if (Parent != null) {
+ Parent.Realized -= OnParentRealized;
+ ShowAll ();
+
+ // Make sure everything is in place before continuing
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+ }
+ }
+
+ void OnResized (object s, Gtk.SizeAllocatedArgs a)
+ {
+ Stetic.Wrapper.Container cont = wrapper as Stetic.Wrapper.Container;
+ if (cont != null) {
+ if (cont.DesignHeight != DesignHeight)
+ cont.DesignHeight = DesignHeight;
+ if (cont.DesignWidth != DesignWidth)
+ cont.DesignWidth = DesignWidth;
+ }
+
+ if (DesignSizeChanged != null)
+ DesignSizeChanged (this, a);
+ }
+
+ public int DesignWidth {
+ get { return preview.WidthRequest; }
+ }
+
+ public int DesignHeight {
+ get { return preview.HeightRequest; }
+ }
+
+ public event EventHandler DesignSizeChanged;
+ }
+
+ class ResizableFixed: EventBox, IDesignArea
+ {
+ Gtk.Widget child;
+ int difX, difY;
+ bool resizingX;
+ bool resizingY;
+ Fixed fixd;
+ Gtk.Container container;
+
+ Cursor cursorX = new Cursor (CursorType.RightSide);
+ Cursor cursorY = new Cursor (CursorType.BottomSide);
+ Cursor cursorXY = new Cursor (CursorType.BottomRightCorner);
+
+ const int padding = 6;
+ const int selectionBorder = 6;
+
+ Requisition currentSizeRequest;
+
+ SelectionHandleBox selectionBox;
+ Gtk.Widget selectionWidget;
+ ObjectSelection currentObjectSelection;
+ ArrayList topLevels = new ArrayList ();
+ ArrayList trackingSize = new ArrayList ();
+
+ internal IObjectViewer ObjectViewer;
+ internal bool AllowResize;
+
+ public event EventHandler SelectionChanged;
+
+ public ResizableFixed ()
+ {
+ fixd = new Fixed ();
+ Add (fixd);
+ this.CanFocus = true;
+ this.Events = EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.PointerMotionMask | EventMask.KeyPressMask;
+// fixd.ModifyBg (Gtk.StateType.Normal, this.Style.Mid (Gtk.StateType.Normal));
+// VisibleWindow = false;
+ selectionBox = new SelectionHandleBox (this);
+ selectionBox.Show ();
+ }
+
+ public ResizableFixed (IntPtr p): base (p)
+ {
+ }
+
+ protected override void OnDestroyed ()
+ {
+ if (cursorX != null) {
+ cursorX.Dispose ();
+ cursorXY.Dispose ();
+ cursorY.Dispose ();
+ cursorX = cursorXY = cursorY = null;
+ }
+ base.OnDestroyed ();
+ }
+
+ internal void Put (Gtk.Widget child, Gtk.Container container)
+ {
+ this.child = child;
+ this.container = container;
+ fixd.Put (child, selectionBorder + padding, selectionBorder + padding);
+ child.SizeRequested += new SizeRequestedHandler (OnSizeReq);
+ }
+
+ public override void Dispose ()
+ {
+ if (child != null)
+ child.SizeRequested -= new SizeRequestedHandler (OnSizeReq);
+ base.Dispose ();
+ }
+
+ public bool IsSelected (Gtk.Widget widget)
+ {
+ return selectionWidget == widget;
+ }
+
+ public IObjectSelection GetSelection (Gtk.Widget widget)
+ {
+ if (selectionWidget == widget)
+ return currentObjectSelection;
+ else
+ return null;
+ }
+
+ public IObjectSelection GetSelection ()
+ {
+ return currentObjectSelection;
+ }
+
+ public IObjectSelection SetSelection (Gtk.Widget widget, object obj)
+ {
+ return SetSelection (widget, obj, true);
+ }
+
+ public IObjectSelection SetSelection (Gtk.Widget widget, object obj, bool allowDrag)
+ {
+ if (currentObjectSelection != null) {
+ currentObjectSelection.Dispose ();
+ currentObjectSelection = null;
+ }
+
+ if (widget != null) {
+ currentObjectSelection = new ObjectSelection (this, widget, obj);
+ currentObjectSelection.AllowDrag = allowDrag;
+ }
+ else
+ currentObjectSelection = null;
+
+ PlaceSelectionBox (widget);
+ // Make sure the selection box is shown before doing anything else.
+ // The UI looks more responsive in this way.
+// while (Gtk.Application.EventsPending ())
+// Gtk.Application.RunIteration ();
+
+ UpdateObjectViewers ();
+
+ if (SelectionChanged != null)
+ SelectionChanged (this, EventArgs.Empty);
+
+ return currentObjectSelection;
+ }
+
+ void PlaceSelectionBox (Gtk.Widget widget)
+ {
+ if (selectionWidget != null) {
+ foreach (Gtk.Widget sw in trackingSize)
+ sw.SizeAllocated -= SelectionSizeAllocated;
+ selectionWidget.Destroyed -= SelectionDestroyed;
+ trackingSize.Clear ();
+ }
+
+ selectionWidget = widget;
+
+ if (widget != null) {
+ selectionBox.Hide ();
+
+ // This call ensures that the old selection box is removed
+ // before the new one is shown
+// while (Gtk.Application.EventsPending ())
+// Gtk.Application.RunIteration ();
+
+ // The selection may have changed while dispatching events
+// if (selectionWidget != widget)
+// return;
+
+ // Track the size changes of the widget and all its parents
+ Gtk.Widget sw = selectionWidget;
+ while (sw != this && sw != null) {
+ sw.SizeAllocated += SelectionSizeAllocated;
+ trackingSize.Add (sw);
+ sw = sw.Parent;
+ }
+
+ selectionWidget.Destroyed += SelectionDestroyed;
+ PlaceSelectionBoxInternal (selectionWidget);
+ selectionBox.ObjectSelection = currentObjectSelection;
+ selectionBox.Show ();
+ } else {
+ selectionBox.Hide ();
+ }
+ }
+
+ public void ResetSelection (Gtk.Widget widget)
+ {
+ if (selectionWidget == widget || widget == null) {
+ PlaceSelectionBox (null);
+ if (currentObjectSelection != null) {
+ currentObjectSelection.FireDisposed ();
+ currentObjectSelection = null;
+
+ // This makes the property editor to flicker
+ // when changing widget selection
+ // UpdateObjectViewers ();
+ }
+ if (widget == null) {
+ Gtk.Container cc = this as Gtk.Container;
+ while (cc.Parent != null)
+ cc = cc.Parent as Gtk.Container;
+ if (cc is Gtk.Window) {
+ ((Gtk.Window)cc).Focus = this;
+ }
+ }
+ }
+ }
+
+ public void UpdateObjectViewers ()
+ {
+ object obj;
+
+ if (currentObjectSelection == null)
+ obj = null;
+ else
+ obj = currentObjectSelection.DataObject;
+
+ if (ObjectViewer != null)
+ ObjectViewer.TargetObject = obj;
+ }
+
+ public void AddWidget (Gtk.Widget w, int x, int y)
+ {
+ w.Parent = this;
+ TopLevelChild info = new TopLevelChild ();
+ info.X = x;
+ info.Y = y;
+ info.Child = w;
+ topLevels.Add (info);
+ }
+
+ public void RemoveWidget (Gtk.Widget w)
+ {
+ foreach (TopLevelChild info in topLevels) {
+ if (info.Child == w) {
+ w.Unparent ();
+ topLevels.Remove (info);
+ break;
+ }
+ }
+ }
+
+ public void MoveWidget (Gtk.Widget w, int x, int y)
+ {
+ foreach (TopLevelChild info in topLevels) {
+ if (info.Child == w) {
+ info.X = x;
+ info.Y = y;
+ QueueResize ();
+ break;
+ }
+ }
+ }
+
+ public Gdk.Rectangle GetCoordinates (Gtk.Widget w)
+ {
+ int px, py;
+ if (!w.TranslateCoordinates (this, 0, 0, out px, out py))
+ return new Gdk.Rectangle (0,0,0,0);
+
+ Gdk.Rectangle rect = w.Allocation;
+ rect.X = px - Allocation.X;
+ rect.Y = py - Allocation.Y;
+ return rect;
+ }
+
+ void SelectionSizeAllocated (object obj, Gtk.SizeAllocatedArgs args)
+ {
+ PlaceSelectionBoxInternal (selectionWidget);
+ }
+
+ void SelectionDestroyed (object obj, EventArgs args)
+ {
+ ResetSelection ((Gtk.Widget)obj);
+ }
+
+ void PlaceSelectionBoxInternal (Gtk.Widget widget)
+ {
+ int px, py;
+ if (!widget.TranslateCoordinates (this, 0, 0, out px, out py))
+ return;
+
+ Gdk.Rectangle rect = widget.Allocation;
+ rect.X = px;
+ rect.Y = py;
+ selectionBox.Reposition (rect);
+ }
+
+
+ void OnSizeReq (object o, SizeRequestedArgs a)
+ {
+ if (!AllowResize) {
+ a.RetVal = false;
+ QueueDraw ();
+ return;
+ }
+
+ currentSizeRequest = a.Requisition;
+
+ Rectangle alloc = child.Allocation;
+ int nw = alloc.Width;
+ int nh = alloc.Height;
+
+ if (a.Requisition.Width > nw) nw = a.Requisition.Width;
+ if (a.Requisition.Height > nh) nh = a.Requisition.Height;
+
+ if (nw != alloc.Width || nh != alloc.Height) {
+ int ow = child.WidthRequest;
+ int oh = child.HeightRequest;
+ child.SetSizeRequest (nw, nh);
+ if (ow > nw)
+ child.WidthRequest = ow;
+ if (oh > nh)
+ child.HeightRequest = oh;
+ QueueDraw ();
+ }
+ }
+
+ protected override void OnSizeRequested (ref Requisition req)
+ {
+ // The Toplevel check is done to ensure that this widget is anchored,
+ // otherwise the Realize call will fail.
+ if (!child.IsRealized && Toplevel is Gtk.Window)
+ child.Realize ();
+
+ req = child.SizeRequest ();
+ // Make some room for the border
+ req.Width += padding * 2 + selectionBorder * 2;
+ req.Height += padding * 2 + selectionBorder * 2;
+ selectionBox.SizeRequest ();
+ if (selectionBox.Allocation.Width > req.Width)
+ req.Width = selectionBox.Allocation.Width;
+ if (selectionBox.Allocation.Height > req.Height)
+ req.Height = selectionBox.Allocation.Height;
+
+ foreach (TopLevelChild tchild in topLevels) {
+ Gtk.Requisition treq = tchild.Child.SizeRequest ();
+ if (tchild.X + treq.Width > req.Width)
+ req.Width = tchild.X + treq.Width;
+ if (tchild.Y + treq.Height > req.Height)
+ req.Height = tchild.Y + treq.Height;
+ }
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle rect)
+ {
+ base.OnSizeAllocated (rect);
+
+ if (selectionWidget != null)
+ PlaceSelectionBoxInternal (selectionWidget);
+
+ foreach (TopLevelChild child in topLevels) {
+ Gtk.Requisition req = child.Child.SizeRequest ();
+ child.Child.SizeAllocate (new Gdk.Rectangle (rect.X + child.X, rect.Y + child.Y, req.Width, req.Height));
+ }
+ }
+
+ protected override void ForAll (bool include_internals, Gtk.Callback callback)
+ {
+ base.ForAll (include_internals, callback);
+ foreach (TopLevelChild child in topLevels)
+ callback (child.Child);
+ if (include_internals)
+ selectionBox.ForAll (include_internals, callback);
+ }
+
+ protected override bool OnMotionNotifyEvent (Gdk.EventMotion ev)
+ {
+ if (resizingX || resizingY) {
+ if (resizingX) {
+ int nw = (int)(ev.X - difX - padding - selectionBorder);
+ if (nw < currentSizeRequest.Width) nw = currentSizeRequest.Width;
+ child.WidthRequest = nw;
+ }
+
+ if (resizingY) {
+ int nh = (int)(ev.Y - difY - padding - selectionBorder);
+ if (nh < currentSizeRequest.Height) nh = currentSizeRequest.Height;
+ child.HeightRequest = nh;
+ }
+ QueueDraw ();
+ } else if (AllowResize) {
+ if (GetAreaResizeXY ().Contains ((int) ev.X, (int) ev.Y))
+ GdkWindow.Cursor = cursorXY;
+ else if (GetAreaResizeX ().Contains ((int) ev.X, (int) ev.Y))
+ GdkWindow.Cursor = cursorX;
+ else if (GetAreaResizeY ().Contains ((int) ev.X, (int) ev.Y))
+ GdkWindow.Cursor = cursorY;
+ else
+ GdkWindow.Cursor = null;
+ }
+
+ return base.OnMotionNotifyEvent (ev);
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton ev)
+ {
+ Gdk.Rectangle rectArea = child.Allocation;
+ rectArea.Inflate (selectionBorder, selectionBorder);
+
+ if (rectArea.Contains ((int) ev.X, (int) ev.Y)) {
+ Stetic.Wrapper.Widget gw = Stetic.Wrapper.Widget.Lookup (container);
+ if (gw != null)
+ gw.Select ();
+ else
+ ResetSelection (null);
+
+ if (AllowResize) {
+ Rectangle rect = GetAreaResizeXY ();
+ if (rect.Contains ((int) ev.X, (int) ev.Y)) {
+ resizingX = resizingY = true;
+ difX = (int) (ev.X - rect.X);
+ difY = (int) (ev.Y - rect.Y);
+ GdkWindow.Cursor = cursorXY;
+ }
+
+ rect = GetAreaResizeY ();
+ if (rect.Contains ((int) ev.X, (int) ev.Y)) {
+ resizingY = true;
+ difY = (int) (ev.Y - rect.Y);
+ GdkWindow.Cursor = cursorY;
+ }
+
+ rect = GetAreaResizeX ();
+ if (rect.Contains ((int) ev.X, (int) ev.Y)) {
+ resizingX = true;
+ difX = (int) (ev.X - rect.X);
+ GdkWindow.Cursor = cursorX;
+ }
+ }
+ } else {
+ Stetic.Wrapper.Widget gw = Stetic.Wrapper.Widget.Lookup (container);
+ if (gw != null)
+ gw.Project.Selection = null;
+ }
+
+ return base.OnButtonPressEvent (ev);
+ }
+
+ Rectangle GetAreaResizeY ()
+ {
+ Gdk.Rectangle rect = child.Allocation;
+ return new Gdk.Rectangle (rect.X - selectionBorder, rect.Y + rect.Height, rect.Width + selectionBorder, selectionBorder);
+ }
+
+ Rectangle GetAreaResizeX ()
+ {
+ Gdk.Rectangle rect = child.Allocation;
+ return new Gdk.Rectangle (rect.X + rect.Width, rect.Y - selectionBorder, selectionBorder, rect.Height + selectionBorder);
+ }
+
+ Rectangle GetAreaResizeXY ()
+ {
+ Gdk.Rectangle rect = child.Allocation;
+ return new Gdk.Rectangle (rect.X + rect.Width, rect.Y + rect.Height, selectionBorder, selectionBorder);
+ }
+
+ protected override bool OnButtonReleaseEvent (Gdk.EventButton ev)
+ {
+ resizingX = resizingY = false;
+ GdkWindow.Cursor = null;
+ return base.OnButtonReleaseEvent (ev);
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ bool r = base.OnExposeEvent (ev);
+ //FIXME Disabled checkerboard background because it's very inefficient and makes the control *very* slow to resize
+ // It should take the EventExpose area into account, invalidate more selectively during resizes (GTK viewport
+ // code would probably be a good start), and take advantage of the flat block color the parent is rendering.
+ /*
+ int size = 8;
+ bool squareColor = true;
+ bool startsquareColor = true;
+ int x1 = 0;
+ int x2 = Allocation.Width;
+ int y1 = 0;
+ int y2 = Allocation.Height;
+ for (int y = y1; y < y2; y += size) {
+ squareColor = startsquareColor;
+ startsquareColor = !startsquareColor;
+ for (int x = x1; x < x2; x += size) {
+ GdkWindow.DrawRectangle (squareColor ? Style.DarkGC (StateType.Normal) : Style.DarkGC (StateType.Active), true, x, y, size, size);
+ squareColor = !squareColor;
+ }
+ }
+
+ foreach (Widget cw in Children)
+ PropagateExpose (cw, ev);*/
+
+ Gdk.Rectangle rect = child.Allocation;
+ if (Stetic.Metacity.Preview.ThemeError)
+ GdkWindow.DrawRectangle (this.Style.BackgroundGC (StateType.Normal), true, rect.X, rect.Y, rect.Width, rect.Height);
+
+ Pixbuf sh = Shadow.AddShadow (rect.Width, rect.Height);
+ GdkWindow.DrawPixbuf (this.Style.BackgroundGC (StateType.Normal), sh, 0, 0, rect.X - 5, rect.Y - 5, sh.Width, sh.Height, RgbDither.None, 0, 0);
+ return r;
+ }
+
+ protected override bool OnKeyPressEvent (Gdk.EventKey ev)
+ {
+ switch (ev.Key) {
+ case Gdk.Key.Delete:
+ case Gdk.Key.KP_Delete:
+ IObjectSelection sel = GetSelection ();
+ if (sel != null && sel.DataObject != null) {
+ Wrapper.Widget wrapper = Wrapper.Widget.Lookup (sel.DataObject) as Wrapper.Widget;
+ if (wrapper != null)
+ wrapper.Delete ();
+ }
+ return true;
+ default:
+ return base.OnKeyPressEvent (ev);
+ }
+ }
+
+ class TopLevelChild
+ {
+ public int X;
+ public int Y;
+ public Gtk.Widget Child;
+ }
+ }
+
+ enum BoxPos
+ {
+ Start,
+ Center,
+ End,
+ }
+
+ enum BoxFill
+ {
+ Box,
+ VLine,
+ HLine
+ }
+
+ class SelectionHandleBox
+ {
+ const int selectionHandleSize = 4;
+ const int topSelectionHandleSize = 8;
+ public const int selectionLineWidth = 2;
+
+ ArrayList selection = new ArrayList ();
+ Gdk.Rectangle allocation;
+ SelectionHandlePart dragHandlePart;
+ public ObjectSelection ObjectSelection;
+
+ public SelectionHandleBox (Gtk.Widget parent)
+ {
+ // Lines
+ selection.Add (new SelectionHandlePart (BoxFill.HLine, BoxPos.Start, BoxPos.Start, 0, -selectionLineWidth, BoxPos.End, BoxPos.Start, 0, 0));
+ selection.Add (new SelectionHandlePart (BoxFill.HLine, BoxPos.Start, BoxPos.End, 0, 0, BoxPos.End, BoxPos.End, 0, selectionLineWidth));
+ selection.Add (new SelectionHandlePart (BoxFill.VLine, BoxPos.Start, BoxPos.Start, -selectionLineWidth, 0, BoxPos.Start, BoxPos.End, 0, 0));
+ selection.Add (new SelectionHandlePart (BoxFill.VLine, BoxPos.End, BoxPos.Start, 0, 0, BoxPos.End, BoxPos.End, selectionLineWidth, 0));
+
+ // Handles
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.Start, BoxPos.Start, -selectionHandleSize, -selectionHandleSize, BoxPos.Start, BoxPos.Start, 0, 0));
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.End, BoxPos.Start, 0, -selectionHandleSize, BoxPos.End, BoxPos.Start, selectionHandleSize, 0));
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.Start, BoxPos.End, -selectionHandleSize, 0, BoxPos.Start, BoxPos.End, 0, selectionHandleSize));
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.End, BoxPos.End, 0, 0, BoxPos.End, BoxPos.End, selectionHandleSize, selectionHandleSize));
+
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.Center, BoxPos.Start, -selectionHandleSize/2, -selectionHandleSize, BoxPos.Center, BoxPos.Start, selectionHandleSize/2, 0));
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.Center, BoxPos.End, -selectionHandleSize/2, 0, BoxPos.Center, BoxPos.End, selectionHandleSize/2, selectionHandleSize));
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.Start, BoxPos.Center, -selectionHandleSize, -selectionHandleSize/2, BoxPos.Start, BoxPos.Center, 0, selectionHandleSize/2));
+ selection.Add (new SelectionHandlePart (BoxFill.Box, BoxPos.End, BoxPos.Center, 0, -selectionHandleSize/2, BoxPos.End, BoxPos.Center, selectionHandleSize, selectionHandleSize/2));
+
+ dragHandlePart = new SelectionHandlePart (BoxFill.Box, BoxPos.Center, BoxPos.Start, -topSelectionHandleSize/2, -topSelectionHandleSize, BoxPos.Center, BoxPos.Start, topSelectionHandleSize/2, 0);
+ selection.Add (dragHandlePart);
+
+ foreach (SelectionHandlePart s in selection) {
+ s.Parent = parent;
+ s.ParentBox = this;
+ }
+ }
+
+ public void Show ()
+ {
+ foreach (Gtk.Widget s in selection)
+ s.Show ();
+ dragHandlePart.Visible = (ObjectSelection != null && ObjectSelection.AllowDrag);
+ }
+
+ public void Hide ()
+ {
+ foreach (Gtk.Widget s in selection)
+ s.Hide ();
+ }
+
+ public void Reposition (Gdk.Rectangle rect)
+ {
+ bool firstRect = true;
+
+ foreach (SelectionHandlePart s in selection) {
+ s.Reposition (rect);
+ Gdk.Rectangle r = s.Allocation;
+ if (firstRect) {
+ allocation = r;
+ firstRect = false;
+ } else
+ allocation = allocation.Union (r);
+ }
+ }
+
+ public Gdk.Rectangle Allocation {
+ get { return allocation; }
+ }
+
+ public void ForAll (bool include_internals, Gtk.Callback callback)
+ {
+ foreach (Gtk.Widget s in selection)
+ callback (s);
+ }
+
+ public void SizeRequest ()
+ {
+ foreach (Gtk.Widget s in selection)
+ s.SizeRequest ();
+ }
+ }
+
+ class SelectionHandlePart: EventBox
+ {
+ BoxPos hpos, vpos;
+ BoxPos hposEnd, vposEnd;
+ int x, y;
+ int xEnd, yEnd;
+ BoxFill fill;
+ public SelectionHandleBox ParentBox;
+ int clickX, clickY;
+ int localClickX, localClickY;
+ int ox, oy;
+
+ public SelectionHandlePart (BoxFill fill, BoxPos hpos, BoxPos vpos, int x, int y, BoxPos hposEnd, BoxPos vposEnd, int xEnd, int yEnd)
+ {
+ this.fill = fill;
+ this.hpos = hpos;
+ this.vpos = vpos;
+ this.x = x;
+ this.y = y;
+
+ this.hposEnd = hposEnd;
+ this.vposEnd = vposEnd;
+ this.xEnd = xEnd;
+ this.yEnd = yEnd;
+ }
+
+ public void Reposition (Gdk.Rectangle rect)
+ {
+ int px, py;
+ int pxEnd, pyEnd;
+
+ CalcPos (rect, hpos, vpos, out px, out py);
+ px += x;
+ py += y;
+
+ CalcPos (rect, hposEnd, vposEnd, out pxEnd, out pyEnd);
+ pxEnd += xEnd;
+ pyEnd += yEnd;
+
+ Allocation = new Gdk.Rectangle (px, py, pxEnd - px, pyEnd - py);
+ ox = rect.X;
+ oy = rect.Y;
+ }
+
+ void CalcPos (Gdk.Rectangle rect, BoxPos hp, BoxPos vp, out int px, out int py)
+ {
+ if (vp == BoxPos.Start)
+ py = rect.Y;
+ else if (vp == BoxPos.End)
+ py = rect.Bottom;
+ else
+ py = rect.Y + rect.Height / 2;
+
+ if (hp == BoxPos.Start)
+ px = rect.X;
+ else if (hp == BoxPos.End)
+ px = rect.Right;
+ else
+ px = rect.X + rect.Width / 2;
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose ev)
+ {
+ int w, h;
+ this.GdkWindow.GetSize (out w, out h);
+
+ if (fill == BoxFill.Box) {
+ this.GdkWindow.DrawRectangle (this.Style.WhiteGC, true, 0, 0, w, h);
+ this.GdkWindow.DrawRectangle (this.Style.BlackGC, false, 0, 0, w-1, h-1);
+ } else if (fill == BoxFill.HLine) {
+ Gdk.GC gc = new Gdk.GC (this.GdkWindow);
+ gc.SetDashes (0, new sbyte[] {1,1}, 2);
+ gc.SetLineAttributes (SelectionHandleBox.selectionLineWidth, Gdk.LineStyle.OnOffDash, Gdk.CapStyle.NotLast, Gdk.JoinStyle.Miter);
+ gc.Foreground = this.Style.Black;
+ this.GdkWindow.DrawLine (gc, 0, h/2, w, h/2);
+ gc.Foreground = this.Style.White;
+ this.GdkWindow.DrawLine (gc, 1, h/2, w, h/2);
+ } else {
+ Gdk.GC gc = new Gdk.GC (this.GdkWindow);
+ gc.SetDashes (0, new sbyte[] {1,1}, 2);
+ gc.SetLineAttributes (SelectionHandleBox.selectionLineWidth, Gdk.LineStyle.OnOffDash, Gdk.CapStyle.NotLast, Gdk.JoinStyle.Miter);
+ gc.Foreground = this.Style.Black;
+ this.GdkWindow.DrawLine (gc, w/2, 0, w/2, h);
+ gc.Foreground = this.Style.White;
+ this.GdkWindow.DrawLine (gc, w/2, 1, w/2, h);
+ }
+
+ return true;
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton evb)
+ {
+ if (evb.Type == Gdk.EventType.ButtonPress && evb.Button == 1) {
+ clickX = (int)evb.XRoot;
+ clickY = (int)evb.YRoot;
+ localClickX = (int) evb.X;
+ localClickY = (int) evb.Y;
+ }
+ return true;
+ }
+
+ protected override bool OnMotionNotifyEvent (Gdk.EventMotion evm)
+ {
+ if ((evm.State & Gdk.ModifierType.Button1Mask) == 0)
+ return false;
+
+ if (!Gtk.Drag.CheckThreshold (this, clickX, clickY, (int)evm.XRoot, (int)evm.YRoot))
+ return false;
+
+ if (ParentBox.ObjectSelection != null && ParentBox.ObjectSelection.AllowDrag) {
+ int dx = Allocation.X - ox + localClickX;
+ int dy = Allocation.Y - oy + localClickY;
+ ParentBox.ObjectSelection.FireDrag (evm, dx, dy);
+ }
+
+ return true;
+ }
+ }
+
+ class ObjectSelection: IObjectSelection
+ {
+ ResizableFixed box;
+ Gtk.Widget widget;
+ object dataObject;
+ bool allowDrag = true;
+
+ public ObjectSelection (ResizableFixed box, Gtk.Widget widget, object dataObject)
+ {
+ this.box = box;
+ this.widget = widget;
+ this.dataObject = dataObject;
+ }
+
+ public Gtk.Widget Widget {
+ get { return widget; }
+ }
+
+ public object DataObject {
+ get { return dataObject; }
+ }
+
+ public void Dispose ()
+ {
+ box.ResetSelection (widget);
+ }
+
+ internal void FireDisposed ()
+ {
+ if (Disposed != null)
+ Disposed (this, EventArgs.Empty);
+ }
+
+ internal void FireDrag (Gdk.EventMotion evt, int dx, int dy)
+ {
+ if (Drag != null)
+ Drag (evt, dx, dy);
+ }
+
+ public bool AllowDrag {
+ get { return allowDrag; }
+ set { allowDrag = value; }
+ }
+
+ public event DragDelegate Drag;
+ public event EventHandler Disposed;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetEditSession.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetEditSession.cs
new file mode 100644
index 0000000000..a999efe73c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetEditSession.cs
@@ -0,0 +1,368 @@
+//
+// WidgetEditSession.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.Collections;
+using System.CodeDom;
+using Mono.Unix;
+
+namespace Stetic {
+
+ internal class WidgetEditSession: MarshalByRefObject, IDisposable
+ {
+ string sourceWidget;
+ Stetic.ProjectBackend project;
+
+ Stetic.Wrapper.Container rootWidget;
+ Stetic.WidgetDesignerBackend widget;
+ Gtk.VBox designer;
+ Gtk.Plug plug;
+ WidgetActionBar toolbar;
+ WidgetDesignerFrontend frontend;
+ bool allowBinding;
+ bool disposed;
+
+ ContainerUndoRedoManager undoManager;
+ UndoQueue undoQueue;
+
+ public event EventHandler RootWidgetChanged;
+ public event Stetic.Wrapper.WidgetEventHandler SelectionChanged;
+
+ public WidgetEditSession (ProjectBackend sourceProject, WidgetDesignerFrontend frontend, string windowName)
+ {
+ this.frontend = frontend;
+ undoManager = new ContainerUndoRedoManager ();
+ undoQueue = new UndoQueue ();
+ undoManager.UndoQueue = undoQueue;
+
+ sourceWidget = windowName;
+ this.project = sourceProject;
+
+ rootWidget = sourceProject.GetTopLevelWrapper (windowName, true);
+ rootWidget.Select ();
+ undoManager.RootObject = rootWidget;
+
+ this.project.Changed += new ProjectChangedEventHandler (OnChanged);
+ this.project.ProjectReloaded += new EventHandler (OnProjectReloaded);
+ this.project.ProjectReloading += new EventHandler (OnProjectReloading);
+// this.project.WidgetMemberNameChanged += new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
+ }
+
+ public bool AllowWidgetBinding {
+ get { return allowBinding; }
+ set {
+ allowBinding = value;
+ if (toolbar != null)
+ toolbar.AllowWidgetBinding = allowBinding;
+ }
+ }
+
+ public Stetic.Wrapper.Widget GladeWidget {
+ get { return rootWidget; }
+ }
+
+ public Stetic.Wrapper.Container RootWidget {
+ get { return (Wrapper.Container) Component.GetSafeReference (rootWidget); }
+ }
+
+ public Gtk.Widget WrapperWidget {
+ get {
+ if (designer == null) {
+ if (rootWidget == null)
+ return widget;
+ Gtk.Container wc = rootWidget.Wrapped as Gtk.Container;
+ if (widget == null)
+ widget = Stetic.UserInterface.CreateWidgetDesigner (wc, rootWidget.DesignWidth, rootWidget.DesignHeight);
+
+ toolbar = new WidgetActionBar (frontend, rootWidget);
+ toolbar.AllowWidgetBinding = allowBinding;
+ designer = new Gtk.VBox ();
+ designer.BorderWidth = 3;
+ designer.PackStart (toolbar, false, false, 0);
+ designer.PackStart (widget, true, true, 3);
+ widget.DesignArea.SetSelection (project.Selection, project.Selection, false);
+
+ widget.SelectionChanged += OnSelectionChanged;
+
+ }
+ return designer;
+ }
+ }
+
+ [NoGuiDispatch]
+ public void CreateWrapperWidgetPlug (uint socketId)
+ {
+ Gdk.Threads.Enter ();
+ plug = new Gtk.Plug (socketId);
+ plug.Add (WrapperWidget);
+ plug.Decorated = false;
+ plug.ShowAll ();
+ Gdk.Threads.Leave ();
+ }
+
+ public void DestroyWrapperWidgetPlug ()
+ {
+ if (designer != null) {
+ Gtk.Plug plug = (Gtk.Plug) WrapperWidget.Parent;
+ plug.Remove (WrapperWidget);
+ plug.Destroy ();
+ }
+ }
+
+ public void Save ()
+ {
+ }
+
+ public ProjectBackend EditingBackend {
+ get { return project; }
+ }
+
+ public void Dispose ()
+ {
+ project.ComponentTypesChanged -= OnSourceProjectLibsChanged;
+ project.ProjectReloaded -= OnSourceProjectReloaded;
+ project.Changed -= new ProjectChangedEventHandler (OnChanged);
+ project.ProjectReloaded -= OnProjectReloaded;
+ project.ProjectReloading -= OnProjectReloading;
+// project.WidgetMemberNameChanged -= new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
+
+ if (plug != null)
+ plug.Destroy ();
+ rootWidget = null;
+ frontend = null;
+ System.Runtime.Remoting.RemotingServices.Disconnect (this);
+ disposed = true;
+ }
+
+ public bool Disposed {
+ get { return disposed; }
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+
+ public void SetDesignerActive ()
+ {
+ widget.UpdateObjectViewers ();
+ }
+
+ public bool Modified {
+ get {
+ if (project == null || RootWidget == null)
+ return false;
+
+ return project.WasModified (RootWidget.Name);
+ }
+ }
+
+ public UndoQueue UndoQueue {
+ get {
+ if (undoQueue != null)
+ return undoQueue;
+ else
+ return UndoQueue.Empty;
+ }
+ }
+
+ void OnChanged (object s, ProjectChangedEventArgs a)
+ {
+ if (a.ChangedTopLevelName != RootWidget.Name)
+ return;
+
+ if (frontend != null)
+ frontend.NotifyChanged ();
+ }
+
+ void OnSourceProjectReloaded (object s, EventArgs a)
+ {
+
+ }
+
+ void OnSourceProjectLibsChanged (object s, EventArgs a)
+ {
+ }
+
+ void OnProjectReloading (object s, EventArgs a)
+ {
+ if (frontend != null)
+ frontend.NotifyRootWidgetChanging ();
+ }
+
+ void OnProjectReloaded (object s, EventArgs a)
+ {
+ Gtk.Widget topWidget = project.GetWidget (sourceWidget);
+
+ if (topWidget != null) {
+ rootWidget = Stetic.Wrapper.Container.Lookup (topWidget);
+ undoManager.RootObject = rootWidget;
+ if (rootWidget != null) {
+ Gtk.Widget oldWidget = designer;
+ if (widget != null) {
+ widget.SelectionChanged -= OnSelectionChanged;
+ widget = null;
+ }
+ OnRootWidgetChanged ();
+ if (oldWidget != null) {
+ // Delay the destruction of the old widget, so the designer has time to
+ // show the new widget. This avoids flickering.
+ GLib.Timeout.Add (500, delegate {
+ oldWidget.Destroy ();
+ return false;
+ });
+ }
+
+ project.NotifyComponentTypesChanged ();
+ return;
+ }
+ }
+ SetErrorMode ();
+ }
+
+ void SetErrorMode ()
+ {
+ Gtk.Label lab = new Gtk.Label ();
+ lab.Markup = "<b>" + Catalog.GetString ("The form designer could not be loaded") + "</b>";
+ Gtk.EventBox box = new Gtk.EventBox ();
+ box.Add (lab);
+
+ widget = Stetic.UserInterface.CreateWidgetDesigner (box, 100, 100);
+ rootWidget = null;
+
+ OnRootWidgetChanged ();
+ }
+
+ void OnRootWidgetChanged ()
+ {
+ if (designer != null) {
+ if (designer.Parent is Gtk.Plug)
+ ((Gtk.Plug)designer.Parent).Remove (designer);
+ designer = null;
+ }
+
+ if (plug != null) {
+ Gdk.Threads.Enter ();
+ plug.Add (WrapperWidget);
+ plug.ShowAll ();
+ Gdk.Threads.Leave ();
+ }
+
+ if (frontend != null)
+ frontend.NotifyRootWidgetChanged ();
+ if (RootWidgetChanged != null)
+ RootWidgetChanged (this, EventArgs.Empty);
+ }
+
+ void OnSelectionChanged (object ob, EventArgs a)
+ {
+ if (frontend != null) {
+ bool canCut, canCopy, canPaste, canDelete;
+ ObjectWrapper obj = ObjectWrapper.Lookup (widget.Selection);
+ Stetic.Wrapper.Widget wrapper = obj as Stetic.Wrapper.Widget;
+ IEditableObject editable = widget.Selection as IEditableObject;
+ if (editable == null)
+ editable = obj as IEditableObject;
+ if (editable != null) {
+ canCut = editable.CanCut;
+ canCopy = editable.CanCopy;
+ canPaste = editable.CanPaste;
+ canDelete = editable.CanDelete;
+ }
+ else {
+ canCut = canCopy = canPaste = canDelete = false;
+ }
+
+ frontend.NotifySelectionChanged (Component.GetSafeReference (obj), canCut, canCopy, canPaste, canDelete);
+ if (SelectionChanged != null)
+ SelectionChanged (this, new Stetic.Wrapper.WidgetEventArgs (wrapper));
+ }
+ }
+
+ public object SaveState ()
+ {
+ return new object[] {
+ project.SaveStatus (),
+ undoQueue
+ };
+ }
+
+ public void RestoreState (object sessionData)
+ {
+ object[] status = (object[]) sessionData;
+ project.LoadStatus (status [0]);
+ undoQueue = (UndoQueue) status [1];
+ foreach (UndoRedoChange ch in undoQueue.Changes) {
+ ObjectWrapperUndoRedoChange och = ch as ObjectWrapperUndoRedoChange;
+ if (och != null)
+ och.Manager = undoManager;
+ }
+ undoManager.UndoQueue = undoQueue;
+ }
+
+ internal void ClipboardCopySelection ()
+ {
+ IEditableObject editable = widget.Selection as IEditableObject;
+ if (editable == null)
+ editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
+ if (editable != null)
+ editable.Copy ();
+ }
+
+ public void ClipboardCutSelection ()
+ {
+ IEditableObject editable = widget.Selection as IEditableObject;
+ if (editable == null)
+ editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
+ if (editable != null)
+ editable.Cut ();
+ }
+
+ public void ClipboardPaste ()
+ {
+ IEditableObject editable = widget.Selection as IEditableObject;
+ if (editable == null)
+ editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
+ if (editable != null)
+ editable.Paste ();
+ }
+
+ public void DeleteSelection ()
+ {
+ IEditableObject editable = widget.Selection as IEditableObject;
+ if (editable == null)
+ editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
+ if (editable != null)
+ editable.Delete ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetFactory.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetFactory.cs
new file mode 100644
index 0000000000..780b287e16
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetFactory.cs
@@ -0,0 +1,136 @@
+using Gtk;
+using Gdk;
+using System;
+using System.Collections;
+using System.Reflection;
+
+namespace Stetic {
+
+ // This is the base class for palette items. Implements the basic
+ // functionality for showing the icon and label of the item.
+
+ internal class PaletteItemFactory : EventBox
+ {
+ public PaletteItemFactory ()
+ {
+ }
+
+ public virtual void Initialize (string name, Gdk.Pixbuf icon)
+ {
+ DND.SourceSet (this);
+ AboveChild = true;
+
+ Gtk.HBox hbox = new HBox (false, 6);
+ hbox.BorderWidth = 3;
+
+ if (icon != null) {
+ icon = icon.ScaleSimple (16, 16, Gdk.InterpType.Bilinear);
+ hbox.PackStart (new Gtk.Image (icon), false, false, 0);
+ }
+
+ Gtk.Label label = new Gtk.Label ("<small>" + name + "</small>");
+ label.UseMarkup = true;
+ label.Justify = Justification.Left;
+ label.Xalign = 0;
+ hbox.PackEnd (label, true, true, 0);
+
+ Add (hbox);
+ }
+
+ protected override void OnDragBegin (Gdk.DragContext ctx)
+ {
+ Gtk.Widget ob = CreateItemWidget ();
+ if (ob != null)
+ DND.Drag (this, ctx, ob);
+ }
+
+ protected virtual Gtk.Widget CreateItemWidget ()
+ {
+ return null;
+ }
+
+ protected override bool OnEnterNotifyEvent (Gdk.EventCrossing ev)
+ {
+ this.State = Gtk.StateType.Prelight;
+ return base.OnEnterNotifyEvent (ev);
+ }
+
+ protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing ev)
+ {
+ this.State = Gtk.StateType.Normal;
+ return base.OnLeaveNotifyEvent (ev);
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose e)
+ {
+ base.OnExposeEvent (e);
+ if (State == Gtk.StateType.Prelight)
+ Gtk.Style.PaintShadow (this.Style, this.GdkWindow, State, Gtk.ShadowType.Out, e.Area, this, "", e.Area.X, e.Area.Y, e.Area.Width, e.Area.Height);
+ return false;
+ }
+ }
+
+
+ // Palette item factory which creates a widget.
+ internal class WidgetFactory : PaletteItemFactory {
+
+ protected ProjectBackend project;
+ protected ClassDescriptor klass;
+
+ public WidgetFactory (ProjectBackend project, ClassDescriptor klass)
+ {
+ this.project = project;
+ this.klass = klass;
+ Initialize (klass.Label, klass.Icon);
+ if (project == null)
+ Sensitive = false;
+ }
+
+ protected override Gtk.Widget CreateItemWidget ()
+ {
+ return klass.NewInstance (project) as Widget;
+ }
+ }
+
+ internal class WindowFactory : WidgetFactory
+ {
+ public WindowFactory (ProjectBackend project, ClassDescriptor klass) : base (project, klass)
+ {
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton evt)
+ {
+ Gtk.Window win = klass.NewInstance (project) as Gtk.Window;
+ project.AddWindow (win, true);
+ return true;
+ }
+
+ public override void Initialize (string name, Gdk.Pixbuf icon)
+ {
+ base.Initialize (name, icon);
+ DND.SourceUnset (this);
+ }
+ }
+
+ // Palette item factory which allows dragging an already existing object.
+ internal class InstanceWidgetFactory : PaletteItemFactory
+ {
+ Gtk.Widget instance;
+
+ public InstanceWidgetFactory (string name, Gdk.Pixbuf icon, Gtk.Widget instance)
+ {
+ this.instance = instance;
+ Initialize (name, icon);
+ }
+
+ protected override Gtk.Widget CreateItemWidget ()
+ {
+ return instance;
+ }
+
+ public override void Dispose ()
+ {
+ base.Dispose ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetInfoEventHandler.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetInfoEventHandler.cs
new file mode 100644
index 0000000000..1d096dcf2b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetInfoEventHandler.cs
@@ -0,0 +1,41 @@
+
+using System;
+
+namespace Stetic
+{
+ public delegate void WidgetInfoEventHandler (object sender, WidgetInfoEventArgs args);
+
+ public class WidgetInfoEventArgs: EventArgs
+ {
+ Project project;
+ WidgetInfo widget;
+
+ internal WidgetInfoEventArgs (Project p, WidgetInfo w)
+ {
+ project = p;
+ widget = w;
+ }
+
+ public Project Project {
+ get { return project; }
+ }
+
+ public WidgetInfo WidgetInfo {
+ get { return widget; }
+ }
+ }
+
+/* public class ComponentNameEventArgs: ComponentEventArgs
+ {
+ string oldName;
+
+ internal ComponentNameEventArgs (Project p, Component c, string oldName): base (p, c)
+ {
+ this.oldName = oldName;
+ }
+
+ public string OldName {
+ get { return oldName; }
+ }
+ }
+*/}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTree.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTree.cs
new file mode 100644
index 0000000000..3409681428
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTree.cs
@@ -0,0 +1,28 @@
+
+using System;
+using Gtk;
+
+namespace Stetic
+{
+ public class WidgetPropertyTree: PluggableWidget
+ {
+ internal WidgetPropertyTree (Application app): base (app)
+ {
+ }
+
+ protected override void OnCreatePlug (uint socketId)
+ {
+ app.Backend.CreatePropertiesWidgetPlug (socketId);
+ }
+
+ protected override void OnDestroyPlug (uint socketId)
+ {
+ app.Backend.DestroyPropertiesWidgetPlug ();
+ }
+
+ protected override Gtk.Widget OnCreateWidget ()
+ {
+ return app.Backend.GetPropertiesWidget ();
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTreeBackend.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTreeBackend.cs
new file mode 100644
index 0000000000..d4e7d13a5b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetPropertyTreeBackend.cs
@@ -0,0 +1,118 @@
+
+using System;
+
+namespace Stetic
+{
+ internal class WidgetPropertyTreeBackend: PropertyTree, IObjectViewer
+ {
+ ProjectBackend project;
+ Stetic.ObjectWrapper selection;
+ Stetic.ObjectWrapper newSelection;
+ Stetic.Wrapper.Container.ContainerChild packingSelection;
+
+ public WidgetPropertyTreeBackend ()
+ {
+ Stetic.Registry.RegistryChanging += new EventHandler (OnRegistryChanging);
+ }
+
+ public ProjectBackend ProjectBackend {
+ get { return project; }
+ set {
+ if (project != null) {
+ project.SelectionChanged -= Selected;
+ }
+
+ project = value;
+ if (project != null) {
+ TargetObject = project.Selection;
+ project.SelectionChanged += Selected;
+ } else {
+ TargetObject = null;
+ }
+ }
+ }
+
+ public override void Clear ()
+ {
+ base.Clear ();
+ Wrapper.Widget selWidget = selection as Wrapper.Widget;
+ if (selWidget != null)
+ selWidget.Notify -= Notified;
+ if (packingSelection != null)
+ packingSelection.Notify -= Notified;
+ }
+
+ protected override void OnObjectChanged ()
+ {
+ if (selection != null)
+ selection.NotifyChanged ();
+ }
+
+ public object TargetObject {
+ get { return selection.Wrapped; }
+ set {
+ ObjectWrapper wrapper = ObjectWrapper.Lookup (value);
+ if (newSelection == wrapper)
+ return;
+
+ newSelection = wrapper;
+ if (newSelection != null)
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (SelectedHandler));
+ else
+ SelectedHandler ();
+ }
+ }
+
+ void Selected (object s, Wrapper.WidgetEventArgs args)
+ {
+ TargetObject = args != null && args.Widget != null? args.Widget : null;
+ }
+
+ bool SelectedHandler ()
+ {
+ SaveStatus ();
+
+ Clear ();
+
+ selection = newSelection;
+ if (selection == null || selection.Wrapped is ErrorWidget || project == null) {
+ return false;
+ }
+
+ Wrapper.Widget selWidget = selection as Wrapper.Widget;
+ if (selWidget != null) {
+ selWidget.Notify += Notified;
+
+ PropertyDescriptor name = (PropertyDescriptor)Registry.LookupClassByName ("Gtk.Widget") ["Name"];
+ AppendProperty (name, selection.Wrapped);
+ }
+
+ AddProperties (selection.ClassDescriptor.ItemGroups, selection.Wrapped, project.TargetGtkVersion);
+
+ if (selWidget != null) {
+ packingSelection = Stetic.Wrapper.Container.ChildWrapper (selWidget);
+ if (packingSelection != null) {
+ ClassDescriptor childklass = packingSelection.ClassDescriptor;
+ if (childklass.ItemGroups.Count > 0) {
+ AddProperties (childklass.ItemGroups, packingSelection.Wrapped, project.TargetGtkVersion);
+ packingSelection.Notify += Notified;
+ }
+ }
+ }
+
+ RestoreStatus ();
+ return false;
+ }
+
+ void Notified (object wrapper, string propertyName)
+ {
+ Update ();
+ }
+
+ void OnRegistryChanging (object o, EventArgs args)
+ {
+ Clear ();
+ }
+ }
+
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTree.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTree.cs
new file mode 100644
index 0000000000..08e692fb0a
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTree.cs
@@ -0,0 +1,92 @@
+
+using System;
+
+namespace Stetic
+{
+ public class WidgetTree: PluggableWidget
+ {
+ ProjectViewFrontend frontend;
+
+ internal WidgetTree (Application app): base (app)
+ {
+ frontend = new ProjectViewFrontend (app);
+ }
+
+ public event ComponentEventHandler ComponentActivated {
+ add { frontend.ComponentActivated += value; }
+ remove { frontend.ComponentActivated -= value; }
+ }
+
+ public event ComponentEventHandler SelectionChanged {
+ add { frontend.SelectionChanged += value; }
+ remove { frontend.SelectionChanged -= value; }
+ }
+
+ protected override void OnCreatePlug (uint socketId)
+ {
+ app.Backend.CreateProjectWidgetPlug (frontend, socketId);
+ }
+
+ protected override void OnDestroyPlug (uint socketId)
+ {
+ app.Backend.DestroyProjectWidgetPlug ();
+ }
+
+ protected override Gtk.Widget OnCreateWidget ()
+ {
+ return app.Backend.GetProjectWidget (frontend);
+ }
+
+ public override void Dispose ()
+ {
+ frontend.disposed = true;
+ System.Runtime.Remoting.RemotingServices.Disconnect (frontend);
+ base.Dispose ();
+ }
+ }
+
+
+ internal class ProjectViewFrontend: MarshalByRefObject
+ {
+ Application app;
+ internal bool disposed;
+
+ public event ComponentEventHandler ComponentActivated;
+ public event ComponentEventHandler SelectionChanged;
+
+ public ProjectViewFrontend (Application app)
+ {
+ this.app = app;
+ }
+
+ public void NotifyWidgetActivated (object ob, string widgetName, string widgetType)
+ {
+ Gtk.Application.Invoke (
+ delegate {
+ if (disposed) return;
+ Component c = app.GetComponent (ob, widgetName, widgetType);
+ if (c != null && ComponentActivated != null)
+ ComponentActivated (null, new ComponentEventArgs (app.ActiveProject, c));
+ }
+ );
+ }
+
+ public void NotifySelectionChanged (object ob, string widgetName, string widgetType)
+ {
+ Gtk.Application.Invoke (
+ delegate {
+ if (disposed) return;
+ Component c = ob != null ? app.GetComponent (ob, widgetName, widgetType) : null;
+ if (SelectionChanged != null)
+ SelectionChanged (null, new ComponentEventArgs (app.ActiveProject, c));
+ }
+ );
+ }
+
+ public override object InitializeLifetimeService ()
+ {
+ // Will be disconnected when calling Dispose
+ return null;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTreeCombo.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTreeCombo.cs
new file mode 100644
index 0000000000..159f8ec975
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/WidgetTreeCombo.cs
@@ -0,0 +1,213 @@
+
+using System;
+using Gtk;
+
+namespace Stetic
+{
+ internal class WidgetTreeCombo: Button
+ {
+ Label label;
+ Image image;
+ Stetic.Wrapper.Widget rootWidget;
+ Stetic.IProject project;
+ Stetic.Wrapper.Widget selection;
+ WidgetTreePopup popup;
+
+ public WidgetTreeCombo ()
+ {
+ label = new Label ();
+ image = new Gtk.Image ();
+
+ HBox bb = new HBox ();
+ bb.PackStart (image, false, false, 3);
+ bb.PackStart (label, true, true, 3);
+ label.Xalign = 0;
+ label.HeightRequest = 18;
+ bb.PackStart (new VSeparator (), false, false, 1);
+ bb.PackStart (new Arrow (ArrowType.Down, ShadowType.None), false, false, 1);
+ Child = bb;
+ this.WidthRequest = 300;
+ Sensitive = false;
+ }
+
+ public override void Dispose ()
+ {
+ if (popup != null)
+ popup.Destroy ();
+ base.Dispose ();
+ }
+
+
+ public Stetic.Wrapper.Widget RootWidget {
+ get { return rootWidget; }
+ set {
+ rootWidget = value;
+ Sensitive = rootWidget != null;
+ if (rootWidget != null)
+ project = rootWidget.Project;
+ Update ();
+ }
+ }
+
+ public void SetSelection (Stetic.Wrapper.Widget widget)
+ {
+ selection = widget;
+ Update ();
+ }
+
+ void Update ()
+ {
+ if (selection != null) {
+ label.Text = selection.Wrapped.Name;
+ image.Pixbuf = selection.ClassDescriptor.Icon.ScaleSimple (16, 16, Gdk.InterpType.Bilinear);
+ image.Show ();
+ } else {
+ label.Text = " ";
+ image.Hide ();
+ }
+ }
+
+ protected override void OnPressed ()
+ {
+ base.OnPressed ();
+ if (popup == null) {
+ popup = new WidgetTreePopup (project);
+ popup.WidgetActivated += OnPopupActivated;
+ popup.SetDefaultSize (Allocation.Width, 500);
+ }
+ else if (popup.Visible) {
+ popup.Hide ();
+ return;
+ }
+
+ int x, y;
+ ParentWindow.GetOrigin (out x, out y);
+ x += Allocation.X;
+ y += Allocation.Y + Allocation.Height;
+
+ popup.Fill (RootWidget.Wrapped);
+ popup.Move (x, y);
+ popup.ShowAll ();
+ }
+
+ protected override bool OnFocusOutEvent (Gdk.EventFocus evnt)
+ {
+ if (popup != null)
+ popup.Hide ();
+ return base.OnFocusOutEvent (evnt);
+ }
+
+
+ void OnPopupActivated (object s, EventArgs a)
+ {
+ popup.Hide ();
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (popup.Selection);
+ GLib.Timeout.Add (10, delegate {
+ wrapper.Select ();
+ return false;
+ });
+ }
+ }
+
+ class WidgetTreePopup: Window
+ {
+ TreeView tree;
+ TreeStore store;
+ Gtk.Widget selection;
+ Stetic.IProject project;
+
+ public event EventHandler WidgetActivated;
+
+ public WidgetTreePopup (Stetic.IProject project): base (WindowType.Popup)
+ {
+ this.project = project;
+ Gtk.Frame frame = new Frame ();
+ frame.ShadowType = Gtk.ShadowType.Out;
+ Add (frame);
+
+ Gtk.ScrolledWindow sc = new ScrolledWindow ();
+ sc.VscrollbarPolicy = PolicyType.Automatic;
+ sc.HscrollbarPolicy = PolicyType.Automatic;
+ frame.Add (sc);
+
+ tree = new TreeView ();
+ store = new TreeStore (typeof(Gdk.Pixbuf), typeof(string), typeof(Widget));
+ tree.Model = store;
+ tree.HeadersVisible = false;
+
+ TreeViewColumn col = new TreeViewColumn ();
+ CellRendererPixbuf cr = new CellRendererPixbuf ();
+ col.PackStart (cr, false);
+ col.AddAttribute (cr, "pixbuf", 0);
+
+ CellRendererText tr = new CellRendererText ();
+ col.PackStart (tr, true);
+ col.AddAttribute (tr, "markup", 1);
+
+ tree.AppendColumn (col);
+
+ tree.ButtonReleaseEvent += OnButtonRelease;
+ tree.RowActivated += OnButtonRelease;
+ sc.Add (tree);
+ tree.GrabFocus ();
+
+ }
+
+ public void Fill (Gtk.Widget widget)
+ {
+ store.Clear ();
+ Fill (TreeIter.Zero, widget);
+ }
+
+ public void Fill (TreeIter iter, Gtk.Widget widget)
+ {
+ Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
+ if (wrapper == null) return;
+
+ if (!wrapper.Unselectable) {
+
+ Gdk.Pixbuf icon = wrapper.ClassDescriptor.Icon.ScaleSimple (16, 16, Gdk.InterpType.Bilinear);
+ string txt;
+ if (widget == project.Selection)
+ txt = "<b>" + GLib.Markup.EscapeText (widget.Name) + "</b>";
+ else
+ txt = GLib.Markup.EscapeText (widget.Name);
+
+ if (!iter.Equals (TreeIter.Zero))
+ iter = store.AppendValues (iter, icon, txt, widget);
+ else
+ iter = store.AppendValues (icon, txt, widget);
+ }
+
+ Gtk.Container cc = widget as Gtk.Container;
+ if (cc != null && wrapper.ClassDescriptor.AllowChildren) {
+ foreach (Gtk.Widget child in cc.Children)
+ Fill (iter, child);
+ }
+ if (widget == project.Selection) {
+ tree.ExpandToPath (store.GetPath (iter));
+ tree.ExpandRow (store.GetPath (iter), false);
+ tree.Selection.SelectIter (iter);
+ }
+ }
+
+ public Gtk.Widget Selection {
+ get { return selection; }
+ }
+
+ void OnButtonRelease (object s, EventArgs a)
+ {
+ NotifyActivated ();
+ }
+
+ void NotifyActivated ()
+ {
+ TreeIter iter;
+ if (!tree.Selection.GetSelected (out iter))
+ return;
+ selection = (Gtk.Widget) store.GetValue (iter, 2);
+ if (WidgetActivated != null)
+ WidgetActivated (this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/Preview.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/Preview.cs
new file mode 100644
index 0000000000..aee001e559
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/Preview.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Gtk;
+using Gdk;
+
+namespace Stetic.Windows
+{
+ class Preview: Bin
+ {
+ Gtk.Widget child;
+ WindowsTheme wtheme;
+ string caption;
+
+ public Preview ( )
+ {
+ DoubleBuffered = false;
+ AppPaintable = true;
+ }
+
+ public static Preview Create (TopLevelWindow window)
+ {
+ if (System.IO.Path.DirectorySeparatorChar != '\\')
+ return null;
+ try {
+ Preview p = new Preview ();
+ p.Add (window);
+ return p;
+ }
+ catch {
+ return null;
+ }
+ }
+
+ public string Title {
+ get { return caption; }
+ set {
+ caption = value;
+ QueueDraw ();
+ }
+ }
+
+ protected override void OnDestroyed ( )
+ {
+ if (wtheme != null)
+ wtheme.Dipose ();
+ base.OnDestroyed ();
+ }
+
+ protected override void OnAdded (Widget widget)
+ {
+ base.OnAdded (widget);
+ child = widget;
+ if (child is TopLevelWindow) {
+ ((TopLevelWindow) child).PropertyChanged += Preview_TitleChanged;
+ Title = ((TopLevelWindow) child).Title;
+ }
+ }
+
+ void Preview_TitleChanged (object sender, EventArgs e)
+ {
+ Title = ((TopLevelWindow) child).Title;
+ }
+
+ protected override void OnRemoved (Widget widget)
+ {
+ base.OnRemoved (widget);
+ if (widget == child) {
+ if (child is TopLevelWindow)
+ ((TopLevelWindow) child).PropertyChanged -= Preview_TitleChanged;
+ child = null;
+ }
+ }
+
+ protected override void OnSizeRequested (ref Requisition requisition)
+ {
+ if (child != null)
+ requisition = child.SizeRequest ();
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+ {
+ base.OnSizeAllocated (allocation);
+ if (child != null) {
+ if (wtheme != null)
+ child.Allocation = wtheme.GetWindowClientArea (allocation);
+ else
+ child.Allocation = allocation;
+ }
+ }
+
+ protected override void OnRealized ( )
+ {
+ base.OnRealized ();
+ wtheme = new WindowsTheme (GdkWindow);
+ if (child != null)
+ child.Allocation = wtheme.GetWindowClientArea (Allocation);
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose evnt)
+ {
+// Gdk.Rectangle rect = new Gdk.Rectangle (Allocation.X+50, Allocation.Y+50, Allocation.Width - 1, Allocation.Height - 1);
+ wtheme.DrawWindowFrame (this, caption, Allocation.X, Allocation.Y, Allocation.Width, Allocation.Height);
+ foreach (Widget child in Children)
+ PropagateExpose (child, evnt);
+ return false;
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/WindowsTheme.cs b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/WindowsTheme.cs
new file mode 100644
index 0000000000..bdc4a3a1eb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/Windows/WindowsTheme.cs
@@ -0,0 +1,201 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Stetic.Windows
+{
+ class WindowsTheme
+ {
+ IntPtr hWnd;
+ IntPtr hTheme;
+
+ public WindowsTheme (Gdk.Window win)
+ {
+ hWnd = gdk_win32_drawable_get_handle (win.Handle);
+ hTheme = OpenThemeData (hWnd, "WINDOW");
+ }
+
+ public void Dipose ( )
+ {
+ CloseThemeData (hTheme);
+ }
+
+ public void DrawWindowFrame (Gtk.Widget w, string caption, int x, int y, int width, int height)
+ {
+ Gdk.Drawable drawable = w.GdkWindow;
+ Gdk.Pixmap pix = new Gdk.Pixmap (drawable, width, height, drawable.Depth);
+
+ Gdk.GC gcc = new Gdk.GC (pix);
+ gcc.Foreground = w.Style.Backgrounds [(int)Gtk.StateType.Normal];
+ pix.DrawRectangle (gcc, true, 0, 0, width, height);
+
+ IntPtr hdc = gdk_win32_hdc_get (pix.Handle, gcc.Handle, 0);
+
+ RECT r = new RECT (0, 0, width, height);
+ SIZE size;
+ GetThemePartSize (hTheme, hdc, WP_CAPTION, CS_ACTIVE, ref r, 1, out size);
+
+ r.Bottom = size.cy;
+ DrawThemeBackground (hTheme, hdc, WP_CAPTION, CS_ACTIVE, ref r, ref r);
+
+ RECT rf = new RECT (FrameBorder, FrameBorder, width - FrameBorder * 2, size.cy);
+ LOGFONT lf = new LOGFONT ();
+ GetThemeSysFont (hTheme, TMT_CAPTIONFONT, ref lf);
+ IntPtr titleFont = CreateFontIndirect (ref lf);
+ IntPtr oldFont = SelectObject (hdc, titleFont);
+ SetBkMode (hdc, 1 /*TRANSPARENT*/);
+ DrawThemeText (hTheme, hdc, WP_CAPTION, CS_ACTIVE, caption, -1, DT_LEFT | DT_SINGLELINE | DT_WORD_ELLIPSIS, 0, ref rf);
+ SelectObject (hdc, oldFont);
+ DeleteObject (titleFont);
+
+ int ny = r.Bottom;
+ r = new RECT (0, ny, width, height);
+ DrawThemeBackground (hTheme, hdc, WP_FRAMEBOTTOM, 0, ref r, ref r);
+
+ gdk_win32_hdc_release (pix.Handle, gcc.Handle, 0);
+
+ Gdk.Pixbuf img = Gdk.Pixbuf.FromDrawable (pix, pix.Colormap, 0, 0, 0, 0, width, height);
+ drawable.DrawPixbuf (new Gdk.GC (drawable), img, 0, 0, x, y, width, height, Gdk.RgbDither.None, 0, 0);
+ drawable.DrawRectangle (w.Style.BackgroundGC (Gtk.StateType.Normal), true, x + FrameBorder, y + size.cy, width - FrameBorder * 2, height - FrameBorder - size.cy);
+ }
+
+ public Gdk.Rectangle GetWindowClientArea (Gdk.Rectangle allocation)
+ {
+ IntPtr hdc = GetDC (hWnd);
+ RECT r = new RECT (allocation.X, allocation.Y, allocation.X + allocation.Width, allocation.Y + allocation.Height);
+ SIZE size;
+ GetThemePartSize (hTheme, hdc, WP_CAPTION, CS_ACTIVE, ref r, 1, out size);
+ ReleaseDC (hWnd, hdc);
+
+ return new Gdk.Rectangle (allocation.X + FrameBorder, allocation.Y + size.cy, allocation.Width - FrameBorder * 2, allocation.Height - size.cy - FrameBorder);
+ }
+
+ const int FrameBorder = 8;
+
+ const int WP_CAPTION = 1;
+ const int WP_FRAMEBOTTOM = 9;
+ const int CS_ACTIVE = 1;
+ const int TMT_CAPTIONFONT = 801;
+
+ const int DT_LEFT = 0x0;
+ const int DT_WORD_ELLIPSIS = 0x40000;
+ const int DT_SINGLELINE = 0x20;
+
+
+ [DllImport ("uxtheme", ExactSpelling = true)]
+ extern static Int32 DrawThemeBackground (IntPtr hTheme, IntPtr hdc, int iPartId,
+ int iStateId, ref RECT pRect, ref RECT pClipRect);
+
+ [DllImport ("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
+ static extern IntPtr OpenThemeData (IntPtr hWnd, String classList);
+
+ [DllImport ("uxtheme.dll", ExactSpelling = true)]
+ extern static Int32 CloseThemeData (IntPtr hTheme);
+
+ [DllImport ("uxtheme", ExactSpelling = true)]
+ extern static Int32 GetThemePartSize (IntPtr hTheme, IntPtr hdc, int part, int state, ref RECT pRect, int eSize, out SIZE size);
+
+ [DllImport ("uxtheme", ExactSpelling = true)]
+ extern static Int32 GetThemeBackgroundExtent (IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, ref RECT pBoundingRect, out RECT pContentRect);
+
+ [DllImport ("uxtheme", ExactSpelling = true)]
+ extern static Int32 GetThemeMargins (IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, int iPropId, out MARGINS pMargins);
+
+ [DllImport ("uxtheme", ExactSpelling = true, CharSet = CharSet.Unicode)]
+ extern static Int32 DrawThemeText (IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, String text, int textLength, UInt32 textFlags, UInt32 textFlags2, ref RECT pRect);
+
+ [DllImport ("uxtheme", ExactSpelling = true, CharSet = CharSet.Unicode)]
+ extern static Int32 GetThemeSysFont (IntPtr hTheme, int iFontId, ref LOGFONT plf);
+
+ [DllImport ("gdi32.dll")]
+ static extern IntPtr CreateFontIndirect ([In] ref LOGFONT lplf);
+
+ [DllImport ("gdi32.dll")]
+ static extern int SetBkMode (IntPtr hdc, int iBkMode);
+
+ [DllImport ("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
+ static extern IntPtr SelectObject (IntPtr hdc, IntPtr hgdiobj);
+
+ [DllImport ("gdi32.dll")]
+ static extern bool DeleteObject (IntPtr hObject);
+
+ [DllImport ("user32.dll")]
+ static extern IntPtr GetDC (IntPtr hWnd);
+
+ [DllImport ("user32.dll")]
+ static extern int ReleaseDC (IntPtr hWnd, IntPtr hDC);
+
+ [DllImport ("libgdk-win32-2.0-0.dll")]
+ static extern IntPtr gdk_win32_drawable_get_handle (IntPtr raw);
+
+ [DllImport ("libgdk-win32-2.0-0.dll")]
+ static extern IntPtr gdk_win32_hdc_get (IntPtr drawable, IntPtr gc, int usage);
+
+ [DllImport ("libgdk-win32-2.0-0.dll")]
+ static extern void gdk_win32_hdc_release (IntPtr drawable, IntPtr gc, int usage);
+ }
+
+
+ [Serializable, StructLayout (LayoutKind.Sequential)]
+ public struct RECT
+ {
+ public int Left;
+ public int Top;
+ public int Right;
+ public int Bottom;
+
+ public RECT (int left_, int top_, int right_, int bottom_)
+ {
+ Left = left_;
+ Top = top_;
+ Right = right_;
+ Bottom = bottom_;
+ }
+
+ public int Height { get { return Bottom - Top; } }
+ public int Width { get { return Right - Left; } }
+ }
+
+ [StructLayout (LayoutKind.Sequential)]
+ public struct SIZE
+ {
+ public int cx;
+ public int cy;
+
+ public SIZE (int cx, int cy)
+ {
+ this.cx = cx;
+ this.cy = cy;
+ }
+ }
+
+ [StructLayout (LayoutKind.Sequential)]
+ public struct MARGINS
+ {
+ public int leftWidth;
+ public int rightWidth;
+ public int topHeight;
+ public int bottomHeight;
+ }
+
+ [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct LOGFONT
+ {
+ public int lfHeight;
+ public int lfWidth;
+ public int lfEscapement;
+ public int lfOrientation;
+ public int lfWeight;
+ public byte lfItalic;
+ public byte lfUnderline;
+ public byte lfStrikeOut;
+ public byte lfCharSet;
+ public byte lfOutPrecision;
+ public byte lfClipPrecision;
+ public byte lfQuality;
+ public byte lfPitchAndFamily;
+ [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 32)]
+ public string lfFaceName;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/action.png b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/action.png
new file mode 100644
index 0000000000..fa6a6c8a12
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/action.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libstetic2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libstetic2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libstetic2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libsteticui2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libsteticui2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/bin/Release/libsteticui2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.csproj b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.csproj
new file mode 100644
index 0000000000..27b35ca797
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.csproj
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <AssemblyName>libsteticui2</AssemblyName>
+ <RootNamespace>libsteticui</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\..\..\build\AddIns\MonoDevelop.GtkCore2</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <additionalargs>-unsafe</additionalargs>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Mono.Posix" />
+ <Reference Include="System" />
+ <Reference Include="System.Runtime.Remoting" />
+ <Reference Include="System.Xml" />
+ <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\contrib\Mono.Cecil\Mono.Cecil.csproj">
+ <Project>{3EC06433-F168-4C5B-A885-99CE4AB617E1}</Project>
+ <Name>Mono.Cecil</Name>
+ <Private>False</Private>
+ </ProjectReference>
+ <ProjectReference Include="..\..\MonoDevelop.GtkCore2\libstetic\libstetic.csproj">
+ <Project>{F870E2E7-FA64-4B2F-968A-90B36AB7AAA9}</Project>
+ <Name>libstetic2</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ActionComponent.cs" />
+ <Compile Include="ActionGroupComponent.cs" />
+ <Compile Include="ActionGroupDesigner.cs" />
+ <Compile Include="ActionGroupDesignerBackend.cs" />
+ <Compile Include="ActionGroupEditSession.cs" />
+ <Compile Include="ActionGroupToolbar.cs" />
+ <Compile Include="Application.cs" />
+ <Compile Include="ApplicationBackend.cs" />
+ <Compile Include="ApplicationBackendController.cs" />
+ <Compile Include="AssemblyResolver.cs" />
+ <Compile Include="AssemblyWidgetLibrary.cs" />
+ <Compile Include="CecilClassDescriptor.cs" />
+ <Compile Include="CecilPropertyDescriptor.cs" />
+ <Compile Include="CecilSignalDescriptor.cs" />
+ <Compile Include="CecilWidgetLibrary.cs" />
+ <Compile Include="CodeGenerationResult.cs" />
+ <Compile Include="CodeGenerator.cs" />
+ <Compile Include="CodeGeneratorInternalClass.cs" />
+ <Compile Include="CodeGeneratorPartialClass.cs" />
+ <Compile Include="Component.cs" />
+ <Compile Include="ComponentEventHandler.cs" />
+ <Compile Include="ComponentSignalEventHandler.cs" />
+ <Compile Include="ComponentType.cs" />
+ <Compile Include="ContainerUndoRedoManager.cs" />
+ <Compile Include="ContextMenu.cs" />
+ <Compile Include="Designer.cs" />
+ <Compile Include="Glade.cs" />
+ <Compile Include="Grid.cs" />
+ <Compile Include="GuiDispatchServerSink.cs" />
+ <Compile Include="GuiDispatchServerSinkProvider.cs" />
+ <Compile Include="LibraryCache.cs" />
+ <Compile Include="Metacity\ButtonFunction.cs" />
+ <Compile Include="Metacity\ButtonLayout.cs" />
+ <Compile Include="Metacity\FrameFlags.cs" />
+ <Compile Include="Metacity\FrameType.cs" />
+ <Compile Include="Metacity\ObjectManager.cs" />
+ <Compile Include="Metacity\Preview.cs" />
+ <Compile Include="Metacity\Theme.cs" />
+ <Compile Include="Palette.cs" />
+ <Compile Include="PaletteBackend.cs" />
+ <Compile Include="PluggableWidget.cs" />
+ <Compile Include="Project.cs" />
+ <Compile Include="ProjectBackend.cs" />
+ <Compile Include="ProjectViewBackend.cs" />
+ <Compile Include="PropertyEditor.cs" />
+ <Compile Include="PropertyGrid.cs" />
+ <Compile Include="PropertyTree.cs" />
+ <Compile Include="Shadow.cs" />
+ <Compile Include="SignalsEditor.cs" />
+ <Compile Include="SignalsEditorBackend.cs" />
+ <Compile Include="UndoQueue.cs" />
+ <Compile Include="UserInterface.cs" />
+ <Compile Include="WidgetActionBar.cs" />
+ <Compile Include="WidgetComponent.cs" />
+ <Compile Include="WidgetDesigner.cs" />
+ <Compile Include="WidgetDesignerBackend.cs" />
+ <Compile Include="WidgetEditSession.cs" />
+ <Compile Include="WidgetFactory.cs" />
+ <Compile Include="WidgetInfoEventHandler.cs" />
+ <Compile Include="WidgetPropertyTree.cs" />
+ <Compile Include="WidgetPropertyTreeBackend.cs" />
+ <Compile Include="WidgetTree.cs" />
+ <Compile Include="WidgetTreeCombo.cs" />
+ <Compile Include="Windows\Preview.cs" />
+ <Compile Include="Windows\WindowsTheme.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="action.png">
+ <LogicalName>action.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="missing.png">
+ <LogicalName>missing.png</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="libsteticui.dll.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../../../..">
+ <BuildFilesVar Sync="true" Name="FILES" />
+ <DeployFilesVar />
+ <ResourcesVar Sync="true" Name="RES" />
+ <OthersVar />
+ <GacRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <AsmRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <ProjectRefVar Sync="true" Name="DEPS" />
+ </MonoDevelop.Autotools.MakefileInfo>
+ </Properties>
+ </MonoDevelop>
+ <VisualStudio />
+ </ProjectExtensions>
+</Project>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.csproj b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.csproj
new file mode 100644
index 0000000000..6db4c76953
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.csproj
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <AssemblyName>libsteticui2</AssemblyName>
+ <RootNamespace>libsteticui</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\..\..\build\AddIns\MonoDevelop.GtkCore2</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <additionalargs>-unsafe</additionalargs>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Execution>
+ <Execution clr-version="Net_2_0" />
+ </Execution>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Mono.Posix" />
+ <Reference Include="System" />
+ <Reference Include="System.Runtime.Remoting" />
+ <Reference Include="System.Xml" />
+ <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System.Core" />
+ <Reference Include="Mono.Cecil, Version=0.6.9.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="MonoDevelop.Core, Version=2.4.0.0, Culture=neutral">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="MonoDevelop.Ide, Version=2.4.0.0, Culture=neutral">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="NRefactory, Version=2.1.1.0, Culture=neutral, PublicKeyToken=efe927acf176eea2">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.TextEditor, Version=1.0.0.0, Culture=neutral">
+ <Package>monodevelop</Package>
+ </Reference>
+ <Reference Include="Mono.Debugging, Version=0.0.0.0, Culture=neutral, PublicKeyToken=9307d64546e0580d">
+ <Package>monodevelop</Package>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\libstetic\libstetic2.csproj">
+ <Project>{90CBA7FD-CB46-4711-97BB-2420DC01F016}</Project>
+ <Name>libstetic2</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ActionComponent.cs" />
+ <Compile Include="ActionGroupComponent.cs" />
+ <Compile Include="ActionGroupDesigner.cs" />
+ <Compile Include="ActionGroupDesignerBackend.cs" />
+ <Compile Include="ActionGroupEditSession.cs" />
+ <Compile Include="ActionGroupToolbar.cs" />
+ <Compile Include="Application.cs" />
+ <Compile Include="ApplicationBackend.cs" />
+ <Compile Include="ApplicationBackendController.cs" />
+ <Compile Include="AssemblyResolver.cs" />
+ <Compile Include="AssemblyWidgetLibrary.cs" />
+ <Compile Include="CecilClassDescriptor.cs" />
+ <Compile Include="CecilPropertyDescriptor.cs" />
+ <Compile Include="CecilSignalDescriptor.cs" />
+ <Compile Include="CecilWidgetLibrary.cs" />
+ <Compile Include="CodeGenerationResult.cs" />
+ <Compile Include="CodeGenerator.cs" />
+ <Compile Include="CodeGeneratorPartialClass.cs" />
+ <Compile Include="Component.cs" />
+ <Compile Include="ComponentEventHandler.cs" />
+ <Compile Include="ComponentSignalEventHandler.cs" />
+ <Compile Include="ComponentType.cs" />
+ <Compile Include="ContainerUndoRedoManager.cs" />
+ <Compile Include="ContextMenu.cs" />
+ <Compile Include="Designer.cs" />
+ <Compile Include="Glade.cs" />
+ <Compile Include="Grid.cs" />
+ <Compile Include="GuiDispatchServerSink.cs" />
+ <Compile Include="GuiDispatchServerSinkProvider.cs" />
+ <Compile Include="LibraryCache.cs" />
+ <Compile Include="Metacity\ButtonFunction.cs" />
+ <Compile Include="Metacity\ButtonLayout.cs" />
+ <Compile Include="Metacity\FrameFlags.cs" />
+ <Compile Include="Metacity\FrameType.cs" />
+ <Compile Include="Metacity\ObjectManager.cs" />
+ <Compile Include="Metacity\Preview.cs" />
+ <Compile Include="Metacity\Theme.cs" />
+ <Compile Include="Palette.cs" />
+ <Compile Include="PaletteBackend.cs" />
+ <Compile Include="PluggableWidget.cs" />
+ <Compile Include="Project.cs" />
+ <Compile Include="ProjectBackend.cs" />
+ <Compile Include="ProjectViewBackend.cs" />
+ <Compile Include="PropertyEditor.cs" />
+ <Compile Include="PropertyGrid.cs" />
+ <Compile Include="PropertyTree.cs" />
+ <Compile Include="Shadow.cs" />
+ <Compile Include="SignalsEditor.cs" />
+ <Compile Include="SignalsEditorBackend.cs" />
+ <Compile Include="UndoQueue.cs" />
+ <Compile Include="UserInterface.cs" />
+ <Compile Include="WidgetActionBar.cs" />
+ <Compile Include="WidgetComponent.cs" />
+ <Compile Include="WidgetDesigner.cs" />
+ <Compile Include="WidgetDesignerBackend.cs" />
+ <Compile Include="WidgetEditSession.cs" />
+ <Compile Include="WidgetFactory.cs" />
+ <Compile Include="WidgetInfoEventHandler.cs" />
+ <Compile Include="WidgetPropertyTree.cs" />
+ <Compile Include="WidgetPropertyTreeBackend.cs" />
+ <Compile Include="WidgetTree.cs" />
+ <Compile Include="WidgetTreeCombo.cs" />
+ <Compile Include="Windows\Preview.cs" />
+ <Compile Include="Windows\WindowsTheme.cs" />
+ <Compile Include="IProjectDesignInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="action.png">
+ <LogicalName>action.png</LogicalName>
+ </EmbeddedResource>
+ <EmbeddedResource Include="missing.png">
+ <LogicalName>missing.png</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="libsteticui2.dll.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../../../..">
+ <BuildFilesVar Sync="true" Name="FILES" />
+ <DeployFilesVar />
+ <ResourcesVar Sync="true" Name="RES" />
+ <OthersVar />
+ <GacRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <AsmRefVar Sync="true" Name="REFS" Prefix="-r:" />
+ <ProjectRefVar Sync="true" Name="DEPS" />
+ </MonoDevelop.Autotools.MakefileInfo>
+ </Properties>
+ </MonoDevelop>
+ <VisualStudio />
+ </ProjectExtensions>
+ <ItemGroup>
+ <Folder Include="Windows\" />
+ </ItemGroup>
+</Project>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.dll.config b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.dll.config
new file mode 100644
index 0000000000..8c4c6ab9a9
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/libsteticui2.dll.config
@@ -0,0 +1,8 @@
+<configuration>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" os="!osx,windows" />
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.dylib" os="osx" />
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.dylib" os="osx"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-x11-2.0.so.0" os="!osx,windows"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.dylib" os="osx"/>
+</configuration>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/libsteticui/missing.png b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/missing.png
new file mode 100644
index 0000000000..589da692bb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/libsteticui/missing.png
Binary files differ
diff --git a/main/src/addins/MonoDevelop.GtkCore2/monodevelop-slim.sln b/main/src/addins/MonoDevelop.GtkCore2/monodevelop-slim.sln
new file mode 100644
index 0000000000..cf252d90be
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/monodevelop-slim.sln
@@ -0,0 +1,146 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Core", "..\main\src\core\MonoDevelop.Core\MonoDevelop.Core.csproj", "{7525BB88-6142-4A26-93B9-A30C6983390A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Projects.Formats.MSBuild", "..\main\src\core\MonoDevelop.Projects.Formats.MSBuild\MonoDevelop.Projects.Formats.MSBuild.csproj", "{A437F1A3-78DF-4F00-8053-D32A8B1EB679}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "..\main\contrib\Mono.Cecil\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Mdb", "..\main\contrib\Mono.Cecil\Mono.Cecil.Mdb.csproj", "{201F7AC0-D2D5-4F51-85A8-17475DADBED3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.TextEditor", "..\main\src\core\Mono.Texteditor\Mono.TextEditor.csproj", "{A2329308-3751-4DBD-9A75-5F7B8B024625}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Debugging", "..\main\src\core\Mono.Debugging\Mono.Debugging.csproj", "{90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "..\main\contrib\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Ide", "..\main\src\core\MonoDevelop.Ide\MonoDevelop.Ide.csproj", "{27096E7F-C91C-4AC6-B289-6897A701DF21}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Startup", "..\main\src\core\MonoDevelop.Startup\MonoDevelop.Startup.csproj", "{DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.DesignerSupport", "..\main\src\addins\MonoDevelop.DesignerSupport\MonoDevelop.DesignerSupport.csproj", "{2C24D515-4A2C-445C-8419-C09231913CFA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Deployment", "..\main\src\addins\Deployment\MonoDevelop.Deployment\MonoDevelop.Deployment.csproj", "{9BC670A8-1851-40EC-9685-279F4C98433D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "stetic2", "stetic2", "{FA38092D-B853-42E3-B7B7-D88A57F97BE9}"
+ ProjectSection(MonoDevelopProperties) = preProject
+ Policies = $0
+ $0.VersionControlPolicy = $1
+ $1.inheritsSet = Mono
+ $0.ChangeLogPolicy = $2
+ $2.UpdateMode = ProjectRoot
+ $2.MessageStyle = $3
+ $3.LineAlign = 0
+ $2.inheritsSet = Mono
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libstetic2", "..\main\src\addins\MonoDevelop.GtkCore2\libstetic\libstetic2.csproj", "{90CBA7FD-CB46-4711-97BB-2420DC01F016}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libsteticui2", "..\main\src\addins\MonoDevelop.GtkCore2\libsteticui\libsteticui2.csproj", "{8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.GtkCore2", "..\main\src\addins\MonoDevelop.GtkCore2\MonoDevelop.GtkCore2.csproj", "{4F2E994F-E4F5-407A-8D80-80E3377DEF6E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Debugger", "..\main\src\addins\MonoDevelop.Debugger\MonoDevelop.Debugger.csproj", "{2357AABD-08C7-4808-A495-8FF2D3CDFDB0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Refactoring", "..\main\src\addins\MonoDevelop.Refactoring\MonoDevelop.Refactoring.csproj", "{100568FC-F4E8-439B-94AD-41D11724E45B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ Debug|x86 = Debug|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {100568FC-F4E8-439B-94AD-41D11724E45B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {100568FC-F4E8-439B-94AD-41D11724E45B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {100568FC-F4E8-439B-94AD-41D11724E45B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {100568FC-F4E8-439B-94AD-41D11724E45B}.Debug|x86.Build.0 = Debug|Any CPU
+ {100568FC-F4E8-439B-94AD-41D11724E45B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {100568FC-F4E8-439B-94AD-41D11724E45B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {201F7AC0-D2D5-4F51-85A8-17475DADBED3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {201F7AC0-D2D5-4F51-85A8-17475DADBED3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {201F7AC0-D2D5-4F51-85A8-17475DADBED3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {201F7AC0-D2D5-4F51-85A8-17475DADBED3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2357AABD-08C7-4808-A495-8FF2D3CDFDB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2357AABD-08C7-4808-A495-8FF2D3CDFDB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2357AABD-08C7-4808-A495-8FF2D3CDFDB0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2357AABD-08C7-4808-A495-8FF2D3CDFDB0}.Debug|x86.Build.0 = Debug|Any CPU
+ {2357AABD-08C7-4808-A495-8FF2D3CDFDB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2357AABD-08C7-4808-A495-8FF2D3CDFDB0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {27096E7F-C91C-4AC6-B289-6897A701DF21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {27096E7F-C91C-4AC6-B289-6897A701DF21}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {27096E7F-C91C-4AC6-B289-6897A701DF21}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {27096E7F-C91C-4AC6-B289-6897A701DF21}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2C24D515-4A2C-445C-8419-C09231913CFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2C24D515-4A2C-445C-8419-C09231913CFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2C24D515-4A2C-445C-8419-C09231913CFA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2C24D515-4A2C-445C-8419-C09231913CFA}.Debug|x86.Build.0 = Debug|Any CPU
+ {2C24D515-4A2C-445C-8419-C09231913CFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2C24D515-4A2C-445C-8419-C09231913CFA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Debug|x86.Build.0 = Debug|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7525BB88-6142-4A26-93B9-A30C6983390A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7525BB88-6142-4A26-93B9-A30C6983390A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7525BB88-6142-4A26-93B9-A30C6983390A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7525BB88-6142-4A26-93B9-A30C6983390A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Debug|x86.Build.0 = Debug|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Debug|x86.Build.0 = Debug|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Debug|x86.Build.0 = Debug|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9BC670A8-1851-40EC-9685-279F4C98433D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9BC670A8-1851-40EC-9685-279F4C98433D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9BC670A8-1851-40EC-9685-279F4C98433D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9BC670A8-1851-40EC-9685-279F4C98433D}.Debug|x86.Build.0 = Debug|Any CPU
+ {9BC670A8-1851-40EC-9685-279F4C98433D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9BC670A8-1851-40EC-9685-279F4C98433D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A2329308-3751-4DBD-9A75-5F7B8B024625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A2329308-3751-4DBD-9A75-5F7B8B024625}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A2329308-3751-4DBD-9A75-5F7B8B024625}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A2329308-3751-4DBD-9A75-5F7B8B024625}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A437F1A3-78DF-4F00-8053-D32A8B1EB679}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A437F1A3-78DF-4F00-8053-D32A8B1EB679}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A437F1A3-78DF-4F00-8053-D32A8B1EB679}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A437F1A3-78DF-4F00-8053-D32A8B1EB679}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}.Debug|x86.ActiveCfg = Debug|x86
+ {DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}.Debug|x86.Build.0 = Debug|x86
+ {DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA8EDEA6-7DA8-435D-B1A0-F3A0CA07F424}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {90CBA7FD-CB46-4711-97BB-2420DC01F016} = {FA38092D-B853-42E3-B7B7-D88A57F97BE9}
+ {8951D80F-B2D6-4B4E-B119-28FFE3B7B1C0} = {FA38092D-B853-42E3-B7B7-D88A57F97BE9}
+ {4F2E994F-E4F5-407A-8D80-80E3377DEF6E} = {FA38092D-B853-42E3-B7B7-D88A57F97BE9}
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = ..\main\src\core\MonoDevelop.Startup\MonoDevelop.Startup.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroup.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroup.xft.xml
new file mode 100644
index 0000000000..e0214ea640
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroup.xft.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>ActionGroup</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a global Action Group.</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Disabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <action-group name="${FullName}">
+ </action-group>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.ActionGroup" />
+ </BaseTypes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <BaseConstructorArgs>
+ <PrimitiveExpression Value="${FullName}"/>
+ </BaseConstructorArgs>
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <TypeReferenceExpression Type="Stetic.Gui" />
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ThisReferenceExpression/>
+ <TypeOfExpression Type="${FullName}" />
+ </Parameters>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroupPartial.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroupPartial.xft.xml
new file mode 100644
index 0000000000..5f8d81245b
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/ActionGroupPartial.xft.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>ActionGroup</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a global Action Group.</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Enabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <action-group name="${FullName}">
+ </action-group>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true" IsPartial="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.ActionGroup" />
+ </BaseTypes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <BaseConstructorArgs>
+ <PrimitiveExpression Value="${FullName}"/>
+ </BaseConstructorArgs>
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <ThisReferenceExpression/>
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/ChangeLog b/main/src/addins/MonoDevelop.GtkCore2/templates/ChangeLog
new file mode 100644
index 0000000000..01d4fb5ad6
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/ChangeLog
@@ -0,0 +1,4 @@
+2010-09-20 Krzysztof Marecki <marecki.krzysztof@gmail.com>
+
+ * WidgetPartial.xft.xml:
+
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/Dialog.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/Dialog.xft.xml
new file mode 100644
index 0000000000..dd1f056707
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/Dialog.xft.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>Dialog</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a Gtk dialog.</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Disabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <widget class="Gtk.Dialog" id="${FullName}" design-size="400 300">
+ <property name="Events">0</property>
+ <property name="Title" translatable="yes">dialog1</property>
+ <property name="WindowPosition">CenterOnParent</property>
+ <property name="Buttons">2</property>
+ <property name="HelpButton">False</property>
+ <property name="HasSeparator">False</property>
+ <child internal-child="VBox">
+ <widget class="Gtk.VBox" id="dialog1_VBox">
+ <property name="MemberName" />
+ <property name="Events">0</property>
+ <property name="BorderWidth">2</property>
+ <child>
+ <placeholder />
+ </child>
+ </widget>
+ </child>
+ <child internal-child="ActionArea">
+ <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
+ <property name="MemberName" />
+ <property name="Events">0</property>
+ <property name="Spacing">10</property>
+ <property name="BorderWidth">5</property>
+ <property name="Size">2</property>
+ <property name="LayoutStyle">End</property>
+ <child>
+ <widget class="Gtk.Button" id="buttonCancel">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="Events">0</property>
+ <property name="UseStock">True</property>
+ <property name="Type">StockItem</property>
+ <property name="StockId">gtk-cancel</property>
+ <property name="IsDialogButton">True</property>
+ <property name="ResponseId">-6</property>
+ <property name="label">gtk-cancel</property>
+ </widget>
+ <packing>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.Button" id="buttonOk">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="Events">0</property>
+ <property name="UseStock">True</property>
+ <property name="Type">StockItem</property>
+ <property name="StockId">gtk-ok</property>
+ <property name="IsDialogButton">True</property>
+ <property name="ResponseId">-5</property>
+ <property name="label">gtk-ok</property>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.Dialog" />
+ </BaseTypes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <TypeReferenceExpression Type="Stetic.Gui" />
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ThisReferenceExpression/>
+ <TypeOfExpression Type="${FullName}" />
+ </Parameters>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/DialogPartial.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/DialogPartial.xft.xml
new file mode 100644
index 0000000000..3fb9feee35
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/DialogPartial.xft.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>Dialog</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a Gtk dialog.</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Enabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <widget class="Gtk.Dialog" id="${FullName}" design-size="400 300">
+ <property name="Events">0</property>
+ <property name="Title" translatable="yes">dialog1</property>
+ <property name="WindowPosition">CenterOnParent</property>
+ <property name="Buttons">2</property>
+ <property name="HelpButton">False</property>
+ <property name="HasSeparator">False</property>
+ <child internal-child="VBox">
+ <widget class="Gtk.VBox" id="dialog1_VBox">
+ <property name="MemberName" />
+ <property name="Events">0</property>
+ <property name="BorderWidth">2</property>
+ <child>
+ <placeholder />
+ </child>
+ </widget>
+ </child>
+ <child internal-child="ActionArea">
+ <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
+ <property name="MemberName" />
+ <property name="Events">0</property>
+ <property name="Spacing">10</property>
+ <property name="BorderWidth">5</property>
+ <property name="Size">2</property>
+ <property name="LayoutStyle">End</property>
+ <child>
+ <widget class="Gtk.Button" id="buttonCancel">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="Events">0</property>
+ <property name="UseStock">True</property>
+ <property name="Type">StockItem</property>
+ <property name="StockId">gtk-cancel</property>
+ <property name="IsDialogButton">True</property>
+ <property name="ResponseId">-6</property>
+ <property name="label">gtk-cancel</property>
+ </widget>
+ <packing>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.Button" id="buttonOk">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="Events">0</property>
+ <property name="UseStock">True</property>
+ <property name="Type">StockItem</property>
+ <property name="StockId">gtk-ok</property>
+ <property name="IsDialogButton">True</property>
+ <property name="ResponseId">-5</property>
+ <property name="label">gtk-ok</property>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true" IsPartial="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.Dialog" />
+ </BaseTypes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <ThisReferenceExpression />
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/DrawingArea.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/DrawingArea.xft.xml
new file mode 100644
index 0000000000..842ba2aca7
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/DrawingArea.xft.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<Template Originator="Mike Kestner" Created="2/11/2009" LastModified="2/11/2009">
+ <TemplateConfiguration>
+ <_Name>Custom Drawn Widget</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a custom Gtk.DrawingArea subclass.</_Description>
+ </TemplateConfiguration>
+ <TemplateFiles>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.DrawingArea" />
+ </BaseTypes>
+ <CustomAttributes>
+ <AttributeDeclaration Name="System.ComponentModel.ToolboxItem">
+ <Arguments>
+ <AttributeArgument>
+ <Value><PrimitiveExpression Value="True" ValueType="System.Boolean"/></Value>
+ </AttributeArgument>
+ </Arguments>
+ </AttributeDeclaration>
+ </CustomAttributes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <Statements>
+ <CommentStatement>
+ <Comment>
+ <Comment Text="Insert initialization code here." />
+ </Comment>
+ </CommentStatement>
+ </Statements>
+ </Constructor>
+ <MemberMethod Name="OnButtonPressEvent" Attributes="Family, Override">
+ <Parameters>
+ <ParameterDeclarationExpression Name="ev" Type="Gdk.EventButton"/>
+ </Parameters>
+ <ReturnType><TypeReference BaseType="System.Boolean"/></ReturnType>
+ <Statements>
+ <CommentStatement>
+ <Comment>
+ <Comment Text="Insert button press handling code here." />
+ </Comment>
+ </CommentStatement>
+ <MethodReturnStatement>
+ <Expression>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="OnButtonPressEvent">
+ <TargetObject>
+ <BaseReferenceExpression/>
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ArgumentReferenceExpression ParameterName="ev" />
+ </Parameters>
+ </MethodInvokeExpression>
+ </Expression>
+ </MethodReturnStatement>
+ </Statements>
+ </MemberMethod>
+ <MemberMethod Name="OnExposeEvent" Attributes="Family, Override">
+ <Parameters>
+ <ParameterDeclarationExpression Name="ev" Type="Gdk.EventExpose"/>
+ </Parameters>
+ <ReturnType><TypeReference BaseType="System.Boolean"/></ReturnType>
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="OnExposeEvent">
+ <TargetObject>
+ <BaseReferenceExpression/>
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ArgumentReferenceExpression ParameterName="ev" />
+ </Parameters>
+ </MethodInvokeExpression>
+ <CommentStatement>
+ <Comment>
+ <Comment Text="Insert drawing code here." />
+ </Comment>
+ </CommentStatement>
+ <MethodReturnStatement>
+ <Expression>
+ <PrimitiveExpression Value="True" ValueType="System.Boolean"/>
+ </Expression>
+ </MethodReturnStatement>
+ </Statements>
+ </MemberMethod>
+ <MemberMethod Name="OnSizeAllocated" Attributes="Family, Override">
+ <Parameters>
+ <ParameterDeclarationExpression Name="allocation" Type="Gdk.Rectangle" />
+ </Parameters>
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="OnSizeAllocated">
+ <TargetObject>
+ <BaseReferenceExpression/>
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ArgumentReferenceExpression ParameterName="allocation" />
+ </Parameters>
+ </MethodInvokeExpression>
+ <CommentStatement>
+ <Comment>
+ <Comment Text="Insert layout code here." />
+ </Comment>
+ </CommentStatement>
+ </Statements>
+ </MemberMethod>
+ <MemberMethod Name="OnSizeRequested" Attributes="Family, Override">
+ <Parameters>
+ <ParameterDeclarationExpression Name="requisition" Type="Gtk.Requisition" Direction="Ref" />
+ </Parameters>
+ <Statements>
+ <CommentStatement>
+ <Comment>
+ <Comment Text="Calculate desired size here." />
+ </Comment>
+ </CommentStatement>
+ <AssignStatement>
+ <Left>
+ <FieldReferenceExpression FieldName="Height">
+ <TargetObject>
+ <ArgumentReferenceExpression ParameterName="requisition" />
+ </TargetObject>
+ </FieldReferenceExpression>
+ </Left>
+ <Right>
+ <PrimitiveExpression Value="50" ValueType="System.Int32" />
+ </Right>
+ </AssignStatement>
+ <AssignStatement>
+ <Left>
+ <FieldReferenceExpression FieldName="Width">
+ <TargetObject>
+ <ArgumentReferenceExpression ParameterName="requisition" />
+ </TargetObject>
+ </FieldReferenceExpression>
+ </Left>
+ <Right>
+ <PrimitiveExpression Value="50" ValueType="System.Int32" />
+ </Right>
+ </AssignStatement>
+ </Statements>
+ </MemberMethod>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/Widget.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/Widget.xft.xml
new file mode 100644
index 0000000000..e391069234
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/Widget.xft.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>Widget</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a custom Gtk Widget.</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Disabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <widget class="Gtk.Bin" id="${FullName}" design-size="300 300">
+ <property name="Visible">false</property>
+ <child>
+ <placeholder />
+ </child>
+ </widget>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.Bin" />
+ </BaseTypes>
+ <CustomAttributes>
+ <AttributeDeclaration Name="System.ComponentModel.ToolboxItem">
+ <Arguments>
+ <AttributeArgument>
+ <Value><PrimitiveExpression Value="True" ValueType="System.Boolean"/></Value>
+ </AttributeArgument>
+ </Arguments>
+ </AttributeDeclaration>
+ </CustomAttributes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <TypeReferenceExpression Type="Stetic.Gui" />
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ThisReferenceExpression/>
+ <TypeOfExpression Type="${FullName}" />
+ </Parameters>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/WidgetPartial.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/WidgetPartial.xft.xml
new file mode 100644
index 0000000000..1f911a10c4
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/WidgetPartial.xft.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>Widget</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a custom Gtk Widget.</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Enabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <widget class="Gtk.Bin" id="${FullName}" design-size="300 300">
+ <property name="Visible">false</property>
+ <child>
+ <placeholder />
+ </child>
+ </widget>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true" IsPartial="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.Bin" />
+ </BaseTypes>
+ <CustomAttributes>
+ <AttributeDeclaration Name="System.ComponentModel.ToolboxItem">
+ <Arguments>
+ <AttributeArgument>
+ <Value><PrimitiveExpression Value="True" ValueType="System.Boolean"/></Value>
+ </AttributeArgument>
+ </Arguments>
+ </AttributeDeclaration>
+ </CustomAttributes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <ThisReferenceExpression/>
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/Window.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/Window.xft.xml
new file mode 100644
index 0000000000..22fba55176
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/Window.xft.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>Window</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a Gtk Window</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Disabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <widget class="Gtk.Window" id="${FullName}" design-size="400 300">
+ <property name="Title" translatable="yes">${Name}</property>
+ <property name="WindowPosition">CenterOnParent</property>
+ <child>
+ <placeholder />
+ </child>
+ </widget>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.Window" />
+ </BaseTypes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <BaseConstructorArgs>
+ <FieldReferenceExpression FieldName="Toplevel">
+ <TargetObject>
+ <TypeReferenceExpression Type="Gtk.WindowType" />
+ </TargetObject>
+ </FieldReferenceExpression>
+ </BaseConstructorArgs>
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <TypeReferenceExpression Type="Stetic.Gui" />
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ <Parameters>
+ <ThisReferenceExpression/>
+ <TypeOfExpression Type="${FullName}" />
+ </Parameters>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>
diff --git a/main/src/addins/MonoDevelop.GtkCore2/templates/WindowPartial.xft.xml b/main/src/addins/MonoDevelop.GtkCore2/templates/WindowPartial.xft.xml
new file mode 100644
index 0000000000..382113c771
--- /dev/null
+++ b/main/src/addins/MonoDevelop.GtkCore2/templates/WindowPartial.xft.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<Template Originator="Lluis Sanchez" Created="3/09/2001" LastModified="3/09/2001">
+
+ <TemplateConfiguration>
+ <_Name>Window</_Name>
+ <Icon>md-gui-file</Icon>
+ <_Category>Gtk</_Category>
+ <LanguageName>*</LanguageName>
+ <_Description>Creates a Gtk Window</_Description>
+ </TemplateConfiguration>
+
+ <Conditions>
+ <PartialTypeSupport Requirement="Enabled" />
+ </Conditions>
+
+ <TemplateFiles>
+ <Widget DefaultName="${Name}">
+ <SteticTemplate>
+ <widget class="Gtk.Window" id="${FullName}" design-size="400 300">
+ <property name="Title" translatable="yes">${Name}</property>
+ <property name="WindowPosition">CenterOnParent</property>
+ <child>
+ <placeholder />
+ </child>
+ </widget>
+ </SteticTemplate>
+ <CodeDomFile>
+ <CompileUnit>
+ <Namespaces>
+ <Namespace Name="">
+ <Imports>
+ <NamespaceImport Namespace="System" />
+ </Imports>
+ </Namespace>
+ <Namespace Name="${Namespace}">
+ <Types>
+ <TypeDeclaration Name="${Name}" IsClass="true" IsPartial="true">
+ <BaseTypes>
+ <TypeReference BaseType="Gtk.Window" />
+ </BaseTypes>
+ <Members>
+ <Constructor Attributes="Public, Final">
+ <BaseConstructorArgs>
+ <FieldReferenceExpression FieldName="Toplevel">
+ <TargetObject>
+ <TypeReferenceExpression Type="Gtk.WindowType" />
+ </TargetObject>
+ </FieldReferenceExpression>
+ </BaseConstructorArgs>
+ <Statements>
+ <MethodInvokeExpression>
+ <Method>
+ <MethodReferenceExpression MethodName="Build">
+ <TargetObject>
+ <ThisReferenceExpression/>
+ </TargetObject>
+ </MethodReferenceExpression>
+ </Method>
+ </MethodInvokeExpression>
+ </Statements>
+ </Constructor>
+ </Members>
+ </TypeDeclaration>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </CompileUnit>
+ </CodeDomFile>
+ </Widget>
+ </TemplateFiles>
+</Template>