Data-aware Grid

Hi Mike,

First, I leave today for a conference (in Tampa) then a wedding (in Miami)
so I'll be out of the loop till late Sunday. Lost but not forgotten!

...wxoo propertydescriptors...

Thanks for the extra details. I'm getting there.

I'm strongly considering leaving all of this [multi-table] out of the

core classes

Consider a relationship object that defines the join conditions and
relationships. Relational information may not be available from the database
and may need to derive from some metadata, whether application-level or
database level.

Otherwise, I think the class the plenty helpful enough without multi-table
awareness.

JC

···

-----Original Message-----
From: Mike C. Fletcher [mailto:mcfletch@rogers.com]
Sent: Wednesday, February 19, 2003 6:01 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] Data-aware Grid

propertydescriptor is the exact same class as propertydefinition was in
the earlier versions, the name change was simply to reflect the fact
that the descriptor doesn't define (as in create) a property, rather it
describes a property in a format useful to the grid mechanisms.
Basicproperty's property objects are more properly "definitions", though
I don't think I'll rename them anytime soon.

propertydescriptor is, as you surmise, a wrapper for a field. At the
moment, because of the lack of API for determining the table structure,
there is no conversion to "live" datatypes (everything is still a
string). Will look at writing an abstraction API for getting table
structure across at least PostgreSQL and MySQL (and possibly SQLite).
In the larger context of wxpypropdist, it is normally the
(basic)property which handles type conversion and value checking, though
I am looking at breaking most of that code into a "basictypes" package
(that name being temporary).

A collection is a list-like object holding a set of other objects. For
instance, in the current DBAPIAdapter spike test, there is a collection
DBTable which holds a sequence of RowObjects. The collection also has
an associated set of properties which are accounted based on the
database table structure. The list-like API is manipulated by the
wxoo.sequenceeditor mix-in to generate new items or delete existing
ones. The collectionview also uses the API to retrieve individual
sub-objects for display within the grid. There are classes in
ConflictSolver, for instance, which provide indexed views to object sets
which are also considered "collections" because they follow the same API.

Here is the overall structure of the gridview mechanism:

GridView/CollectionView (provides the public API)
    wxGrid (very minimal sub-class, defers almost everything to ootable)
        ootable (object-and-property(descriptor)-aware wxPyGridTableBase
sub-class)
            adapter (currently DBAPI or wxprop types)
                value (single-or-collection object being edited by the view)
                properties (descriptors of property-like objects for
manipulating value or value's sub-items)

When the grid needs a particular (row, column) value, it makes calls on
the table (this is standard wxGrid functionality). Depending on the
type of the table (single or multiple object), the table retrieves the
appropriate object from the adapter (either value or value[row]). It
then retrieves the appropriate property descriptor from the adapter,
which is generally adapter.properties[ row ] or adapter.properties[ col
] depending on the view type.

Having retrieved the appropriate object and property descriptor, the
table calls the property descriptor's public API to retrieve the
property value from the object. For the DBAPIAdapter, this is where the
conversion to "live" object types would occur (for instance creating
mxDateTime objects instead of simple strings).

The reverse process (when the editing of a cell has completed, and the
value should be updated) operates in exactly the same way, simply
calling the SetValue instead of the GetValue method on the
propertydescriptor.

Multi-table updates:
    Haven't spent any great amount of time worrying about it as of yet,
I'm strongly considering leaving all of this out of the core classes,
and letting the collection objects handle the details of when/how to do
the updating. Unless we can get decent information regarding the
interconnections with introspection, it just seems like you'd wind up
karking the generality of the solution to come up with anything
functional.
    In other words, your row object may include a pseudo-property which
does the work of doing the multi-table updates, but it doesn't seem like
something that the ootable should be dealing with. I'm open to
discussion on the issue, however.

Enjoy,
Mike

Jeff Childers wrote:

Mike,

...

As you use the terminology, is a propertydefinition the same as a
propertydescriptor or is it another object?

Is a propertydescriptor a wrapper for a field? Is this where type
conversions are handled?

Is a "collection" a list of propertydescriptors?

How is the grid bound to the table? Are the columns bound to
propertydescriptors? What event triggers the get/set calls from the grid
cell to the propertydescriptor?

Are you thinking of handling multi-table updates based on some kind of PK
relationship or something else?

How do value objects fit in (i.e. how are they used)? Is it a wrapper to a
set of collections? Or propertydescriptors?

Regards,

Jeff Childers
jchilders_98@yahoo.com

-----Original Message-----
From: Mike C. Fletcher [mailto:mcfletch@rogers.com]
Sent: Tuesday, February 18, 2003 1:08 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] Data-aware Grid

I use dispatcher at different levels. It's a multi-consumer
multi-producer mechanism, that is, multiple watchers can register for an
update and _all_ get called for that update. However, the table
mechanism doesn't use dispatcher at the moment. It uses the
property-definition (property-descriptor in the CVS version). This is a
simple property-like API which is used for all interactions with an
object. It goes something like this in the CVS version (I did rather a
lot of refactoring last night to prepare for integrating a DBAPI-based
descriptor-set):

adapter:

   * properties -- set of property descriptors
         o wxprop.propertydescriptor (propertydefinition) includes a
           mechanism for creating these automatically from
           basicproperty properties. A similar mechanism would be
           created for a DBAPI table's description.
   * value -- opaque object pointer, a collection or single object

table (single/multiple):

   * gets value/properties from adapter
   * multiple version de-references objects within the adapter's
     "value" using list semantics
   * calls functions on propertydescriptors to get/update values of
     given objects

view:

   * provides external API
   * creates the grid, table and adapter and binds them together

descriptor:

   * field-like wrapper object that describes a property of an object,
     has get/set/hasattr-like API, as well as APIs for getting grid
     viewers and editors
   * each adapter is responsible for creating compatible descriptors
     for its fields/attributes/columns/properties

collection:

   * basically any list-like object which can deal with standard
     insert/delete/getitem type calls. Would be a wrapper around the
     results of a "fetchall()" call for DBAPI.

Same basic approach in earlier versions, save that the adapter wasn't a
free-standing object, but was instead built into the view.

dispatcher allows you to build change notification directly into
properties. That allows simple property objects to perform notification
while being treated like dumb properties at the API level. You can see
an example of this use OpenGLContext's fields, where the system can
watch for field-changes on nodes to automatically re-compile
display-lists or invalidate caches, but the user just sees the fields as
properties of the nodes (node.transform = (2,3,4) works as expected).

I don't know if there's any reason to use dispatcher in the table-level
APIs. I haven't come up with anything compelling as-of-yet. (Use in
current versions is an artefact of original development with
conflictsolver (which does use dispatcher), and the CVS version is now
not using it in the wxoo.table package). If I do use dispatcher, I'll
probably isolate it similar to the approach in OpenGLContext (i.e. only
one or two classes interact with it and everything else just uses those
classes). Otherwise you wind up with fragile dependencies all through.

HTH,
Mike

Jeff Childers wrote:

Ok, so getting back to the data-aware grid.

1) Are you thinking of using the dispatcher class again? If so, to make
   

sure

I understand it correctly, dispatcher handles passing messages between
objects? You establish a persistent connection between objects and pass
values through the connector object? Is there some kind of event handler
that triggers action when a message is received?

2) If I have the dispatcher functionality correct, then are you thinking

of

passing a message to a data object when the value changes in the grid

cell?

Could the data object have an interface to a SQL API to update, say, a
record when the value changes?

Sorry if these questions are redundant or obvious. I'm just trying to

catch

up to so I can be helpful.

Regards,

Jeff

-----Original Message-----
From: Mike C. Fletcher [mailto:mcfletch@rogers.com]
Sent: Monday, February 17, 2003 2:58 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] Data-aware Grid

Yup, means its an old version of wxprop before I decided to include
dispatcher (Patrick's module) in wxoo. You can find a link to the
module on the installation page:

  http://wxpypropdist.sourceforge.net/documentation/install.html

BTW, you can readily skip the "wxpycolors" package described there, CVS
has moved away from using it.

If you're just looking for a fast setup-and-run/explore version and are
on Win32, you can download ConflictSolver's latest version. It has
later versions of everything, and it sets it all up in a stand-alone
directory that doesn't affect your Python installation. (You can browse
the source-code of the installed version).

  ConflictSolver Room Scheduler - Browse Files at SourceForge.net

Enjoy,
Mike

Jeff Childers wrote:

Hi Mike,

When I run the demo I get the following error:

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "C:\Python22\Lib\site-packages\wxprop\tests\demo.py", line 2, in ?
from wxprop import objectview
File "C:\Python22\Lib\site-packages\wxprop\objectview.py", line 1, in ?
from wxprop import basepropertyview, propertyset, events, propertytable
File "C:\Python22\Lib\site-packages\wxprop\basepropertyview.py", line 7,
in ?
import wxprop.refresh
File "C:\Python22\Lib\site-packages\wxprop\refresh.py", line 1, in ?
import dispatcher
ImportError: No module named dispatcher

Does this mean anything to you?

Regards,

Jeff

-----Original Message-----
From: Mike C. Fletcher [mailto:mcfletch@rogers.com]
Sent: Monday, February 17, 2003 10:04 AM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] Data-aware Grid

wxprop/demo/demo.py or wxprop/tests/demo.py, though the demos don't use
the collection table (which is probably what you're interested in), they
just use the object table. The only code I have that uses the
collection table is in ConflictSolver.

As for where to start, wxprop/propertytable and wxprop/*view will give
you most of the table functionality.

HTH,
Mike

Jeff Childers wrote:

Hi Mike,

I've downloaded and installed the 0.2.4a EXE. I see that the three
    

packages

installed to site-packages OK. Is there a demo script I can run or,

where

should I start looking into this?

Regards,

Jeff Childers

-----Original Message-----
From: Mike C. Fletcher [mailto:mcfletch@rogers.com]
Sent: Sunday, February 16, 2003 3:58 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] Data-aware Grid

Well, there's definitely something to play with already:

http://wxpypropdist.sourceforge.net/

It's been running on Win32 for ~10 months as part of ConflictSolver (in
case you want to see how it's used):

http://conflictsolver.sourceforge.net/

The data-aware-grid gets used daily by the people who asked me to create

ConflictSolver for them (they actually use it in their day-to-day office

work), and hasn't had any remarkable errors. wxpypropdist doesn't have
anything like the final feature-set I'm planning on, so I still consider

it early-alpha, but the data-aware grid has been stable for a while
(modulo fixes for new versions of wxPython as they come out, and a
switch to using Unicode throughout).

Enjoy yourself,
Mike

J. Childers wrote:

Mike,

I'm interested in the data aware grid. Send me something when there's

something to play with and

I'll give you more feedback (right now I'm trying to complete a masked
   

edit

control, but by the

time you've got something to look at I'll be finished with it).

Jeff Childers

...

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

The wxPython Wiki page for wxGrid (http://wiki.wxpython.org/index.cgi/wxGrid_20Manual) has a cool screenshot of custom cell renders showing a clock and color swatch in some of the cells. I poked around looking for any sample source code that would generate those items, but didn't find anything. Does anyone know if it is available (ideally with the renderer code also)? Thanks,

-- Greg
Semper Software, Inc.
www.SemperSoft.com
gbrunet@sempersoft.com

It's from the wxpython properties distribution

    http://wxpypropdist.sourceforge.net/

The renderer code for wxprop is in the sub-packages wxprop.standard and wxprop.ext . The clock is wxprop.ext.mx_datetimeeditor.DateTimeViewer, the colour swatch is wxprop.ext.wx.colour.ColourViewer .

HTH,
Mike

Greg Brunet wrote:

···

The wxPython Wiki page for wxGrid (http://wiki.wxpython.org/index.cgi/wxGrid_20Manual) has a cool screenshot of custom cell renders showing a clock and color swatch in some of the cells. I poked around looking for any sample source code that would generate those items, but didn't find anything. Does anyone know if it is available (ideally with the renderer code also)? Thanks,

-- Greg
Semper Software, Inc.
www.SemperSoft.com
gbrunet@sempersoft.com

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/

Hi Mike:

Thanks for the pointers. I pulled down the install package(s) from the site and tried running a couple of the demo/test programs, but it seems that I am missing a dependency. I generally get a: "Warning: no handler found for image type.", sometimes followed by an "assert "wxAssertFailure" failed: invalid image" (in bitmap.cpp(507)). I am running on Win XP Pro with Python 2.2.2 & wxPython 2.3.4.2 & have mx.DateTime & wxpycolors installed.

Next, I looked at the code, and in wxprop.ext.wx.colour.ColourViewer, saw where it draws a color swatch rectangle followed by the RGB value in text. One question that I have about that is in building rect2 (used for the text). It's:

rect2 = wxRect( rect.x+ (self.swatchSize+(2*self.swatchBorderSize)), rect.y, rect.width, rect.height )

which seems to take into account the offset for the color swatch, but shouldn't the width be shortened by the same amount to avoid going beyond the cell right border?

In looking at the wxprop.ext.mx_datetimeeditor.DateTimeViewer class, I still can't see where the clock faces are being generated. I must be overlooking something, because all that I find is formatting the cell value as a '%Y-%m-%d %a %H:%M' text value. Thanks for your help,

-- Greg

···

----- Original Message -----
From: "Mike C. Fletcher" <mcfletch@rogers.com>
To: <wxPython-users@lists.wxwindows.org>
Sent: Monday, February 24, 2003 12:36 AM
Subject: Re: [wxPython-users] wxGrid Wiki screenshot source

It's from the wxpython properties distribution

    http://wxpypropdist.sourceforge.net/

The renderer code for wxprop is in the sub-packages wxprop.standard and
wxprop.ext . The clock is wxprop.ext.mx_datetimeeditor.DateTimeViewer,
the colour swatch is wxprop.ext.wx.colour.ColourViewer .

HTH,
Mike

In trying to understand wxGrid, I ran the samples provided in the wxPython demo program. When I tried the last one (A wxGrid with dragable rows and columns): 'GridDragable' I noticed that the text would overflow into the cells having a value of 0 in the last three columns. You can first see this by sizing the Platform column down to it's minimum, but dragging any of the last three columns to the right of one of the earlier columns with long text, and sizing down the longer column will show this. I read in the wiki about the overflow situation starting in wxPython 2.4.x, so I added a statement right after the __init__:

        wxGrid.__init__(self, parent, -1)
        self.SetDefaultCellOverflow(0)

(I don't know if this is the right syntax, I got it by trial & error. Another guess that seemed to work was):

        wxGrid.SetDefaultCellOverflow(self, 0)

Anyway, this seems to fix the problem. Now my remaining question is why is this happening. I went to look at grid.py, but it seems to all be wrappers for the c code (not that I'd trust my ability to figure it out there anyway). Since the first row of the last 3 columns had a value of 1, I tried various iterations of replacing the 0's with 1's & the problem goes away when the cell is set to a 1. My guess is that the overflow code is trying to automatically allow overflows when the cell to the right is empty, but is mistaking a cell with a '0' as an empty cell.

-- Greg Brunet

Urgh, sorry, gave you a bum steer on that one, the clock is actually from:
    wxprop.standard.timeofday.TimeOfDayViewer

Regarding the swatch's text, the baseviewer does a clip of the device context to restrict drawing, so there's no overwrite beyond the limits of the original rect.

Regarding the failures, for some reason, wxInitAllImageHanders isn't getting called. if you add a call to the script you're running it'll load the images fine. The problem here is that you don't want to call it more than once (it spams the user with warnings if you do), so having composable sets means remembering to call it everywhere you do a mainloop. I'm considering making it automatically get called whenever you import the wx property types, but then any app that already calls it is going to print the darn warnings.

Good luck,
Mike

Greg Brunet wrote:

···

Hi Mike:

Thanks for the pointers. I pulled down the install package(s) from the site and tried running a couple of the demo/test programs, but it seems that I am missing a dependency. I generally get a: "Warning: no handler found for image type.", sometimes followed by an "assert "wxAssertFailure" failed: invalid image" (in bitmap.cpp(507)). I am running on Win XP Pro with Python 2.2.2 & wxPython 2.3.4.2 & have mx.DateTime & wxpycolors installed.

Next, I looked at the code, and in wxprop.ext.wx.colour.ColourViewer, saw where it draws a color swatch rectangle followed by the RGB value in text. One question that I have about that is in building rect2 (used for the text). It's:

rect2 = wxRect( rect.x+ (self.swatchSize+(2*self.swatchBorderSize)), rect.y, rect.width, rect.height )

which seems to take into account the offset for the color swatch, but shouldn't the width be shortened by the same amount to avoid going beyond the cell right border?

In looking at the wxprop.ext.mx_datetimeeditor.DateTimeViewer class, I still can't see where the clock faces are being generated. I must be overlooking something, because all that I find is formatting the cell value as a '%Y-%m-%d %a %H:%M' text value. Thanks for your help,

-- Greg

----- Original Message ----- From: "Mike C. Fletcher" <mcfletch@rogers.com>
To: <wxPython-users@lists.wxwindows.org>
Sent: Monday, February 24, 2003 12:36 AM
Subject: Re: [wxPython-users] wxGrid Wiki screenshot source

It's from the wxpython properties distribution

   http://wxpypropdist.sourceforge.net/

The renderer code for wxprop is in the sub-packages wxprop.standard and wxprop.ext . The clock is wxprop.ext.mx_datetimeeditor.DateTimeViewer, the colour swatch is wxprop.ext.wx.colour.ColourViewer .

HTH,
Mike
   
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/

Greg Brunet wrote:

In trying to understand wxGrid, I ran the samples provided in the wxPython demo program. When I tried the last one (A wxGrid with dragable rows and columns): 'GridDragable' I noticed that the text would overflow into the cells having a value of 0 in the last three columns. You can first see this by sizing the Platform column down to it's minimum, but dragging any of the last three columns to the right of one of the earlier columns with long text, and sizing down the longer column will show this. I read in the wiki about the overflow situation starting in wxPython 2.4.x, so I added a statement right after the __init__:

        wxGrid.__init__(self, parent, -1)
        self.SetDefaultCellOverflow(0)

(I don't know if this is the right syntax, I got it by trial & error.

Yes.

Anyway, this seems to fix the problem. Now my remaining question is why is this happening. I went to look at grid.py, but it seems to all be wrappers for the c code (not that I'd trust my ability to figure it out there anyway). Since the first row of the last 3 columns had a value of 1, I tried various iterations of replacing the 0's with 1's & the problem goes away when the cell is set to a 1. My guess is that the overflow code is trying to automatically allow overflows when the cell to the right is empty, but is mistaking a cell with a '0' as an empty cell.

The cells are empty, my guess is that the cell renderers for the data type is interpreting empty as zero and so are displaying them that way.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

> Anyway, this seems to fix the problem. Now my remaining question is why is this happening. I went to look at grid.py, but it seems to all be wrappers for the c code (not that I'd trust my ability to figure it out there anyway). Since the first row of the last 3 columns had a value of 1, I tried various iterations of replacing the 0's with 1's & the problem goes away when the cell is set to a 1. My guess is that the overflow code is trying to automatically allow overflows when the cell to the right is empty, but is mistaking a cell with a '0' as an empty cell.

The cells are empty, my guess is that the cell renderers for the data
type is interpreting empty as zero and so are displaying them that way.

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Well, in the GridDragable.py code, the data for the problem cells does have a value of 0. I would not consider that to be empty - and I would expect it to be rendered as a "0". That got me to thinking of another case, so I tried setting on of the values to NULL. That gets rendered as "None", and once again, it gets overwritten by overflow text. Could it be that the Grid overflow code is using an overly broad definition of "Empty" to include anything that evaluates as Null or False as well? It still seems like improper behavior on the overflow code to me. I would think that if it's up to the cell renderer's to decide whether to output a value in their cell (thus translating NULL to "None"), then the overflow code should see if they do, in fact generate any text, and only if they do not should it allow text to overflow to the right. Of course I expect that there may not be a way for the grid code to determine this, in which case, I sure wouldn't expect it to overwrite a cell with a 0 value in it. (Overwriting a cell with a NULL may be arguable either way, but definitely not the 0). BTW, thanks for all of your awesome work,

-- Greg