From aaca0c1ffe903d16f4be68f6709e983de6faeb14 Mon Sep 17 00:00:00 2001 From: Kevin Ollivier Date: Sun, 25 Sep 2011 06:09:42 +0000 Subject: [PATCH] More work on wxDVC support, including DataViewItem support and GetValue override work, along with a few misc. things, and add a script in etgtools to create new etg files given command line params. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@69197 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- etg/_core.py | 12 +++-- etg/dataobject.py | 47 +++++++++++++++++ etg/dataview.py | 10 ++-- etg/msgdlg.py | 70 +++++++++++++++++++++++++ etg/searchctrl.py | 1 + etgtools/make-new-etg-file.py | 99 +++++++++++++++++++++++++++++++++++ src/dataview_ex.py | 38 ++++++++++++-- src/dataviewhelpers.sip | 62 ++++++++++++---------- src/event_ex.py | 3 ++ 9 files changed, 299 insertions(+), 43 deletions(-) create mode 100644 etg/dataobject.py create mode 100644 etg/msgdlg.py create mode 100644 etgtools/make-new-etg-file.py diff --git a/etg/_core.py b/etg/_core.py index d0bdf5ca..b0799126 100644 --- a/etg/_core.py +++ b/etg/_core.py @@ -48,6 +48,7 @@ INCLUDES = [ 'defs', 'geometry', 'image', + 'dataobject', 'gdiobj', 'bitmap', 'font', @@ -88,9 +89,17 @@ INCLUDES = [ 'defs', 'panel', 'menu', 'menuitem', + + # toplevel and dialogs 'toplevel', 'dialog', + 'dirdlg', + 'filedlg', 'frame', + 'msgdlg', + 'progdlg', + + # controls 'statbmp', 'stattext', 'control', @@ -110,7 +119,6 @@ INCLUDES = [ 'defs', 'accel', 'cursor', 'log', - 'progdlg', 'textctrl', 'combobox', 'checkbox', @@ -119,8 +127,6 @@ INCLUDES = [ 'defs', 'gauge', 'headercol', 'dataobj', - 'filedlg', - 'dirdlg', 'config', 'searchctrl', 'variant', diff --git a/etg/dataobject.py b/etg/dataobject.py new file mode 100644 index 00000000..28afbce3 --- /dev/null +++ b/etg/dataobject.py @@ -0,0 +1,47 @@ +#--------------------------------------------------------------------------- +# Name: etg/dataobject.py +# Author: Kevin Ollivier +# +# Created: 24-Sep-2011 +# Copyright: (c) 2011 by Kevin Ollivier +# License: wxWindows License +#--------------------------------------------------------------------------- + +import etgtools +import etgtools.tweaker_tools as tools + +PACKAGE = "wx" +MODULE = "_core" +NAME = "dataobject" # Base name of the file to generate to for this script +DOCSTRING = "" + +# The classes and/or the basename of the Doxygen XML files to be processed by +# this script. +ITEMS = [ + "wxDataObject", +] + +#--------------------------------------------------------------------------- + +def run(): + # Parse the XML file(s) building a collection of Extractor objects + module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING) + etgtools.parseDoxyXML(module, ITEMS) + + #----------------------------------------------------------------- + # Tweak the parsed meta objects in the module object as needed for + # customizing the generated code and docstrings. + + c = module.find('wxDataObject') + c.abstract = True + + #----------------------------------------------------------------- + tools.doCommonTweaks(module) + tools.addGetterSetterProps(module) + tools.runGenerators(module) + + +#--------------------------------------------------------------------------- +if __name__ == '__main__': + run() + diff --git a/etg/dataview.py b/etg/dataview.py index d89b3569..5c280983 100644 --- a/etg/dataview.py +++ b/etg/dataview.py @@ -20,6 +20,7 @@ DOCSTRING = "" ITEMS = [ 'wxDataViewColumn', 'wxDataViewCtrl', + 'wxDataViewEvent', 'wxDataViewItem', 'wxDataViewItemAttr', 'wxDataViewModel', @@ -32,6 +33,7 @@ ITEMS = [ def run(): # Parse the XML file(s) building a collection of Extractor objects module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING) + #module.items.append(etgtools.TypedefDef(type='void*', name='wxPyLongPtr')) etgtools.parseDoxyXML(module, ITEMS) #----------------------------------------------------------------- @@ -40,12 +42,8 @@ def run(): c = module.find('wxDataViewModel') c.abstract = True - #c.find('GetValue').ignore() - #c.addCppMethod('void', 'GetValue', '(wxVariant &variant, const wxDataViewItem &item, unsigned int col)', """\ - # wxVariant var; - # self->GetValue(var, item, col); - # return var; - #""", isConst=True).isVirtual = True + # Ignore the stock GetValue API, we handle it in src/dataviewhelpers.sip + c.find('GetValue').ignore() c.addDtor() diff --git a/etg/msgdlg.py b/etg/msgdlg.py new file mode 100644 index 00000000..50c12681 --- /dev/null +++ b/etg/msgdlg.py @@ -0,0 +1,70 @@ +#--------------------------------------------------------------------------- +# Name: etg/msgdlg.py +# Author: Kevin Ollivier +# +# Created: 24-Sept-2011 +# Copyright: (c) 2011 by Kevin Ollivier +# License: wxWindows License +#--------------------------------------------------------------------------- + +import etgtools +import etgtools.tweaker_tools as tools + +PACKAGE = "wx" +MODULE = "_core" +NAME = "msgdlg" # Base name of the file to generate to for this script +DOCSTRING = "" + +# The classes and/or the basename of the Doxygen XML files to be processed by +# this script. +ITEMS = [ + 'wxMessageDialog', + ] + +#--------------------------------------------------------------------------- + +def run(): + # Parse the XML file(s) building a collection of Extractor objects + module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING) + etgtools.parseDoxyXML(module, ITEMS) + + #----------------------------------------------------------------- + # Tweak the parsed meta objects in the module object as needed for + # customizing the generated code and docstrings. + + c = module.find('wxMessageDialog') + + # These argument types are actually ButtonLabel, but the class is a private + # helper. We will always be passing in strings, and ButtonLabel will implicitly + # convert. + + c.find('SetHelpLabel.help').type = 'wxString' + c.find('SetOKCancelLabels.ok').type = 'wxString' + c.find('SetOKCancelLabels.cancel').type = 'wxString' + + c.find('SetOKLabel.ok').type = 'wxString' + + c.find('SetYesNoCancelLabels.yes').type = 'wxString' + c.find('SetYesNoCancelLabels.no').type = 'wxString' + c.find('SetYesNoCancelLabels.cancel').type = 'wxString' + + c.find('SetYesNoLabels.yes').type = 'wxString' + c.find('SetYesNoLabels.no').type = 'wxString' + + assert isinstance(c, etgtools.ClassDef) + + #c.find('wxMessageDialog.title').default = 'wxEmptyString' + #c.find('Create.title').default = 'wxEmptyString' + + tools.fixTopLevelWindowClass(c) + + #----------------------------------------------------------------- + tools.doCommonTweaks(module) + tools.addGetterSetterProps(module) + tools.runGenerators(module) + + +#--------------------------------------------------------------------------- +if __name__ == '__main__': + run() + diff --git a/etg/searchctrl.py b/etg/searchctrl.py index c3cc26f3..cad0fabf 100644 --- a/etg/searchctrl.py +++ b/etg/searchctrl.py @@ -31,6 +31,7 @@ def run(): # customizing the generated code and docstrings. c = module.find('wxSearchCtrl') + c.find('SetMenu.menu').transfer = True assert isinstance(c, etgtools.ClassDef) diff --git a/etgtools/make-new-etg-file.py b/etgtools/make-new-etg-file.py new file mode 100644 index 00000000..adfa7f82 --- /dev/null +++ b/etgtools/make-new-etg-file.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +#--------------------------------------------------------------------------- +# Name: etgtools/make-new-etg-file.py +# Author: Kevin Ollivier +# +# Created: 24-Sept-2011 +# Copyright: (c) 2011 by Kevin Ollivier +# License: wxWindows License +#--------------------------------------------------------------------------- + +from datetime import date +from optparse import OptionParser +import os +import sys + +script_dir = os.path.dirname(__file__) +root_dir = os.path.abspath(os.path.join(script_dir, "..")) + +usage = "usage: %prog [options] name module" +parser = OptionParser(usage) +parser.add_option("-a", "--author", dest="author", default="Robin Dunn") +parser.add_option("-c", "--copyright", dest="copyright", default="Total Control Software") +parser.add_option("-i", "--items", dest="items", default="", help="Comma separated list of classes to wrap") + + +etgstub = """#--------------------------------------------------------------------------- +# Name: etg/%(filename)s +# Author: %(author)s +# +# Created: %(date)s +# Copyright: (c) %(year)s by %(copyright)s +# License: wxWindows License +#--------------------------------------------------------------------------- + +import etgtools +import etgtools.tweaker_tools as tools + +PACKAGE = "wx" +MODULE = "%(module)s" +NAME = "%(name)s" # Base name of the file to generate to for this script +DOCSTRING = "" + +# The classes and/or the basename of the Doxygen XML files to be processed by +# this script. +ITEMS = [ + %(items)s +] + +#--------------------------------------------------------------------------- + +def run(): + # Parse the XML file(s) building a collection of Extractor objects + module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING) + etgtools.parseDoxyXML(module, ITEMS) + + #----------------------------------------------------------------- + # Tweak the parsed meta objects in the module object as needed for + # customizing the generated code and docstrings. + + #----------------------------------------------------------------- + tools.doCommonTweaks(module) + tools.addGetterSetterProps(module) + tools.runGenerators(module) + + +#--------------------------------------------------------------------------- +if __name__ == '__main__': + run() + +""" + +(options, args) = parser.parse_args() + +item_str = "" +for item in options.items.split(","): + item_str += '"%s",\n' % item + +arg_dict = { + "author" : options.author, + "copyright" : options.copyright, + "items" : item_str, + "year" : date.today().strftime("%Y"), + "date" : date.today().strftime("%d-%b-%Y"), + "name" : args[0], + "filename" : args[0] + ".py", + "module" : args[1], +} + +output_file = os.path.join(root_dir, "etg", arg_dict["filename"]) + +if os.path.exists(output_file): + print "Bindings with this name already exist. Exiting." + sys.exit(1) + +output = open(output_file, 'w') +output.write(etgstub % arg_dict) +output.close() + diff --git a/src/dataview_ex.py b/src/dataview_ex.py index 668ca95e..d0b27b69 100644 --- a/src/dataview_ex.py +++ b/src/dataview_ex.py @@ -1,3 +1,5 @@ +import wx + class DataViewItemObjectMapper(object): """ This class provides a mechanism for mapping between Python objects and the @@ -32,7 +34,7 @@ class DataViewItemObjectMapper(object): """ Retrieve the object that was used to create an item. """ - oid = item.GetID() + oid = int(item.GetID()) return self.mapper[oid] def UseWeakRefs(self, flag): @@ -51,8 +53,34 @@ class DataViewItemObjectMapper(object): self.mapper = newmap self.usingWeakRefs = flag -class PyDataViewModel(DataViewModelBase, DataViewItemObjectMapper): - def __init__(self, *a, **kw): - super(PyDataViewModel, self).__init__(*a, **kw) +class PyDataViewModel(PyDataViewModelBase, DataViewItemObjectMapper): + def __init__(self): + PyDataViewModelBase.__init__(self) + DataViewItemObjectMapper.__init__(self) + +NullDataViewItem = DataViewItem() + +EVT_DATAVIEW_SELECTION_CHANGED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, 1) + +EVT_DATAVIEW_ITEM_ACTIVATED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, 1) +EVT_DATAVIEW_ITEM_COLLAPSING = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING, 1) +EVT_DATAVIEW_ITEM_COLLAPSED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED, 1) +EVT_DATAVIEW_ITEM_EXPANDING = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, 1) +EVT_DATAVIEW_ITEM_EXPANDED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED, 1) +EVT_DATAVIEW_ITEM_START_EDITING = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING, 1) +EVT_DATAVIEW_ITEM_EDITING_STARTED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED, 1) +EVT_DATAVIEW_ITEM_EDITING_DONE = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE, 1) +EVT_DATAVIEW_ITEM_VALUE_CHANGED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, 1) + +EVT_DATAVIEW_ITEM_CONTEXT_MENU = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, 1) + +EVT_DATAVIEW_COLUMN_HEADER_CLICK = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, 1) +EVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICKED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, 1) +EVT_DATAVIEW_COLUMN_SORTED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, 1) +EVT_DATAVIEW_COLUMN_REORDERED = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, 1) +EVT_DATAVIEW_CACHE_HINT = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_CACHE_HINT, 1) + +EVT_DATAVIEW_ITEM_BEGIN_DRAG = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, 1) +EVT_DATAVIEW_ITEM_DROP_POSSIBLE = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, 1) +EVT_DATAVIEW_ITEM_DROP = wx.PyEventBinder(wxEVT_COMMAND_DATAVIEW_ITEM_DROP, 1) - diff --git a/src/dataviewhelpers.sip b/src/dataviewhelpers.sip index 194e6643..426a8d52 100644 --- a/src/dataviewhelpers.sip +++ b/src/dataviewhelpers.sip @@ -31,10 +31,15 @@ public: return 0; } - - virtual void GetValue( wxVariant &variant, + void GetValue( wxVariant &variant, const wxDataViewItem &item, unsigned int col ) const { + variant = GetValue(item, col); + } + + virtual wxVariant GetValue( const wxDataViewItem &item, unsigned int col ) const + { + return wxVariant(); } virtual bool SetValue( const wxVariant &variant, @@ -50,7 +55,7 @@ public: virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const { - return false; + return true; } virtual unsigned int GetColumnCount() const @@ -84,38 +89,16 @@ public: virtual int Compare (const wxDataViewItem &item1, const wxDataViewItem &item2, unsigned int column, bool ascending) const; + virtual wxVariant GetValue( const wxDataViewItem &item, unsigned int col ) const; - virtual void GetValue( wxVariant &variant, - const wxDataViewItem &item, unsigned int col ) const; - -/* FIXME: This is how we want to implement the method, but when compiling it always wants - the void version of this method, even if we add both. - virtual wxVariant GetValue( wxVariant &variant, + void GetValue( wxVariant &variant, const wxDataViewItem &item, unsigned int col ) const; %MethodCode Py_BEGIN_ALLOW_THREADS - wxVariant result; - sipCpp->wxDataViewModel::GetValue(result, item, col); - sipRes = result; + // call the version that returns a variant so that it will call the Python callback + *variant = sipCpp->GetValue(*item, col); Py_END_ALLOW_THREADS %End - %VirtualCatcherCode - // Convert the 2 element array of integers to the two element - // tuple. - - PyObject *result; - - result = sipCallMethod(&sipIsErr, sipMethod, "Oi", item, col); - - if (result != NULL) - { - // Convert the result to the C++ type. - sipParseResult(&sipIsErr, sipMethod, result, "i", &sipRes); - - Py_DECREF(result); - } - %End -*/ virtual bool SetValue( const wxVariant &variant, const wxDataViewItem &item, unsigned int col ); @@ -133,6 +116,27 @@ public: virtual bool IsContainer(const wxDataViewItem&) const; }; +/* +%MappedType wxPyLongPtr +{ + %ConvertToTypeCode + // Code to test a PyObject for compatibility + if (!sipIsErr) { + return PyLong_Check(sipPy) || PyInt_Check(sipPy); + } + if (PyLong_Check(sipPy) || PyInt_Check(sipPy)) + *sipCppPtrV = (wxPyLongPtr)PyLong_AsVoidPtr(sipPy); + + return sipGetState(sipTransferObj); + %End + + + %ConvertFromTypeCode + return PyLong_FromVoidPtr(sipCpp); + %End + +}; +*/ //-------------------------------------------------------------------------- diff --git a/src/event_ex.py b/src/event_ex.py index 7b548345..5ad9e9a3 100644 --- a/src/event_ex.py +++ b/src/event_ex.py @@ -281,10 +281,13 @@ EVT_UPDATE_UI_RANGE = wx.PyEventBinder( wxEVT_UPDATE_UI, 2) EVT_CONTEXT_MENU = wx.PyEventBinder( wxEVT_CONTEXT_MENU ) +EVT_TEXT = wx.PyEventBinder( wxEVT_COMMAND_TEXT_UPDATED ) EVT_TEXT_CUT = wx.PyEventBinder( wxEVT_COMMAND_TEXT_CUT ) EVT_TEXT_COPY = wx.PyEventBinder( wxEVT_COMMAND_TEXT_COPY ) EVT_TEXT_PASTE = wx.PyEventBinder( wxEVT_COMMAND_TEXT_PASTE ) EVT_THREAD = wx.PyEventBinder( wxEVT_THREAD ) +EVT_WINDOW_MODAL_DIALOG_CLOSED = wx.PyEventBinder( wxEVT_WINDOW_MODAL_DIALOG_CLOSED ) +