Jan Ischebeck (siesel) asked how
is designer improving?
Jason Cater (jcater) said
it requires wx2.6 now - so the first
change was getting it stable on 2.6. Then I stopped using GNUe
Form's ui drivers to draw widgets in real-time on the layout
canvas - I now draw my own objects on my own canvas object -
this gave me a tremendous amount of control over the canvas -
so things "just work" on it now - like rubberband
boxes, etc. I also reworked the property editor - which as it
turns out - was solely responsible for the 2+ second delay
between clicking on a widget, and having designer actually
select that widget. Actually, that will be the extent of the
changes before I declare designer "stable" again -
but there's a lot of under the hood cleaning (comments, better
variable naming, etc)
.
Jan said that he was thinking how
to enable designer to create appserver designs
, alongside
its current role as a designer for Forms and Reports. Jason
said he definantly wanted to tackle that
after I get forms support stable again
but he had not
given much thought to how an Appserver Designer would actually
work yet - it needed to be a tool for end users who were
not programmers but who understood the business process they
were trying to model.
For the current (Forms-related) version of Designer, Jason
was not *that* far away from wanting
alpha testers - if I can get in a couple of solid days of programming,
I think it'd be where I want it at
.
Referring back to
it would be logical if after a commit the
complete result set would be queried again
, but added several
further issues: 1. actually the
starting point was the "undo" function (that we
came up with a different name afterwards), that this function should do the
query again - it was me who extrapolated that to the commit - is this really
desired to after commit see changes done by different users? and 2. doing the
complete query again after commit would mean newly inserted records being
sorted to the place they belong instead of the place they were originally
inserted, so it would look to the user as if the record "jumped"
to a different place
. Also, 3. what
about those records that were inserted or changed in a way that they don't
match the query? would they disappear after the commit?
.
Jason Cater (jcater) noted that the last query
is already saved
since if you press the
"Query" button twice, the previous query is brought back
up
, so users could re-run the query manually to see what had
changed if they wanted to. On the more general issue,
my personal feeling is in several key forms, my
users will get disoriented if the resultset changes on them - but I can
see where it would be useful/desirable too. Certainly it wouldn't be hard
to add a requery-on-commit attribute to datasources or blocks (is there
not one now?). But even then, the question becomes "what is the
default?"
.
James Thompson (jamest) said what's the
advantage to the requery of the whole result set? (other than it would make
our record tracking and removal code go away :)
But Jason was not
sure of this last point - as even on requery,
wouldn't you want it to still try to make a best-effort to go back to the
same record
? Reinhard said that the
advantage would be that you see other records
that other users have added meanwhile - or changes from other users -
(current requery logic only requeries those records that had changes on
commit)
. James wondered if that
shouldn't be a separate feature - like in postgresql's case it allows
you to register for notifications of table updates
.
Reinhard was also interested in what you
think about this "revert" function: should it revert to the
original state of the db, or should it fetch changes from other transactions?
I think new records popping up on revert might not disorient as much as it
would on commit
but worried *sigh*
why does it happen so often that I start implementing something and after
that, I find out that I'm not even sure what exactly I want to
implement...
..
Two
days later, Bajusz Tamás (btami) explained that some of his users
were having problems adjusting to using a legacy application, now
translated to use GNUe Forms, because of the behaviour of the 'Clear'
button. The 'clear' button threw away all changes since the last
commit, not just on the current record. Also, it did not
re-query the data, leaving the user looking at a blank form.
Reinhard Müller (reinhard) noted that
both issues are actually related
to the "undo" function, and not to commit in any
way
. This meant that the behaviour of commit could
stay as it was as of time of writing, avoiding some of the
potential problems previously discussed. The main outstanding
issue was whether the 'undo' function should
revert to the state of the result
set before any change was made - or should it refresh data
from the backend - risking that, for example, the current
record suddenly disappears because another user has just
deleted it - or records "jumping around" because
somebody changed a record in a way relevant for the sort
order
.
Reinhard Müller (reinhard) noted that the <menu> tag
seems to fulfill both fuctions: menu
and menuitem - is that on purpose?
James Thompson
(jamest) confessed not a lot was
done in menus beyond playing around - there is a pretty complete
dynamic menu system in designer fwiw - that I was going to rip out
and put into common to replace the stuff started there
.
Reinhard looked at this, and noted that it seems
to deal with the UI creation for the menu - which leads to the question
- does the menu handling actually belong to common or to forms?
James thought that the toolbar and menu
logic for setting up menus belongs in common
, or even in
his new, proposed, GNUe Application Platform (GAP), as discussed in
as it should be the same code in all
our gui apps
. It had been a while since he had looked at
this code, but i think the addFoo methods
built a in memory representation of a menu - and then the finialize
method mapped it to the UI widget set. what I was hoping for in common
was a set of classes/methods that let us build a logical menu in
memory
. Just like a GNUe form definition, this would not
be specific to any particular user interface. The idea would be that
the UI would register to listen for menu
update events
, thus completely isolating the menu logic from
whatever user interface the user happened to be using.
Reinhard asked whether this would also apply to the 'standard'
menu items that were actually part of the base Forms application, as well
as to additional menu items defined by a forms developer. James
thought so - this would mean that 1) a form
could extend a menu or remove items or hide them via startup triggers
- 2) it may be possible for an application like navigator to adjust
it's menu dynamically based upon the forms loaded in memory
.
Reinhard understood - the issue then was whether to implement this as
UI events or as function calls by the menu code -
my experience
so far is that events add complexity and eat performance
.
James agreed, and although he had been thinking originally in terms
of events, could see no reason not to do this as function calls
instead.
Reinhard liked James' idea of allowing triggers to be switched
on and off. Jason Cater (jcater) wondered what should then
happen if a disabled trigger is called
- does it just not run? - throw an exception?
He felt the
latter option might be better - it represented
a developer error
. James suggested
you could flip optional processing
on/off via a checkbox on a form via a trigger disabling another named
trigger
. Reinhard felt this was bad style - it was better
to keep the trigger active, but make it
check the value of the check box in the
trigger code
and simply do nothing if that was what was
required.
Later, Reinhard added the more I
think about menus and toolbars, the more I see them bound rather
tightly to triggers - they will fire triggers, they will follow
trigger's enabling/disabling ... they might even get label and help
text from triggers (so a menu item and its corresponding toolbar
button will get the same label/tooltip). So I'm starting to think if
implementation of GMenu, GMenuItem and GToolButton would feel well
in the logic/ subdirectory
. Jason noted that
fwiw, this is how designer does it -
and how I was moving forms to do it
. And user interface
systems such as QT did something similar -
except they all have "Events"
instead of "Triggers"
- so
I think having one object that represents any type of such
"action" makes sense
. This would also automatically
handle the different ways of selecting something in a typical graphical
user interface - pressing a hot key, selecting a menu option or
clicking a toolbar icon are all the same
object - my only concern is are we overloading triggers too
much
. In particular, all of the GNUe Tools had the
concept of triggers, but this more specific use of them
for the menu/toolbar/ui stuff
really only made sense in forms (and maybe
navigator)
.
Jason and Reinhard swapped some sample XML to try to clarify
what they each meant. Jason suggested what
I now wish we had done (and might could still do without any
breakage)
was that triggers could just be stand-alone pieces
of python code with a name, which could be called either by another
trigger bound to an object (what GNUe had, up until now, considered a
trigger) or called by an action. This would simplify Reinhard's
suggested treatment of menu items, in that these would just be a
specific type of action.
Reinhard set out the options - either a)
a menu item has an ON-ACTIVATE trigger that is
fired when the item is clicked, and that trigger is just a trigger
like all other triggers, or b) there are <action>s, and a menu
item is bound to an action, and gets info like icon, label, help text
from that action element, and an action is, while in implementation
closely related to a trigger, something completely different in
philosophy. The more I think about it the more it seems to me these
are diametral concepts.
. Jason liked this
second option - it seems like a clean
distiction as far as the definition of our markup
.
Jason Cater (jcater) asked how far are we
featurewise from considering a 1.0 release
for GNUe Forms.
I only ask because I see so many projects
where our 0.6 is comparable to their 1.6 or even 2.6
. This
made no difference to him, but it maybe affected
others' willingness to use GNUe. Reinhard Müller (reinhard)
said there is one psychological thing
here for me - as long as we are 0.x I feel like having the right to
break compatibility - as soon as we are 1.0 I think we morally have
the obligation to stay compatible with every single feature or
misfeature that is in the code. I seriously would like to see a 0.9
or comparable being in use for > 6 months without much happening - so
we know it's stable enough
, both in terms of bugs and in
terms of not needing new features that would break
backward-compatability.
Reinhard Müller (reinhard) noted that
each object in the trigger
namespace has a _parent property - do you make use of that
in any way?
James Thompson (jamest) said that he
did not use this when coding his triggers -
i believe i always use absolute
reference from form
in the format
form.block.field
.
Reinhard also asked I
figure that you also don't make use of the _object property
of trigger objects that let you directly access the GObj
object that should actually be hidden behind it
.
James confirmed this - he personally had never
been keen on this, but it had been added
for papo folks
, as previously discussed in several threads, including
James explained that i see the trigger
namespace as ideally being a restricted python environment with
control over imports
, with code for triggers
having no access to the GObjs, only to
instances of the class that implements the namespace representation
of that object in the trigger
. He added
there is a class that maps a var name
in the trigger to an object - and controlls access to that object
via the exposed properties - methods, etc
. Reinhard
identified this as GObjNamespace -
exactly the class I'm cleaning up
as of time of writing -
thus all these questions
.
The
next day, Reinhard noted that, previously, any
trigger got a copy of the __dict__ of the "self" object into its local
namespace - so for a block trigger, you could do either self.firstRecord() or
just firstRecord(). I removed that as I considered it a bug, but now I'm not
sure if it is wanted behaviour. In any case I don't like it very much as it
allows for sloppy programming - and it will most probably hurt the "support
for self in named triggers" todo item. Anyway, if anybody knows some
background why this was done, I'd be happy to know :)