root/branches/ed-dabo/ChangeLog

Revision 3009, 70.2 kB (checked in by ed, 2 years ago)

Refactored some of the entries into related sections.

  • Property svn:eol-style set to native
Line 
1 See the Subversion log for all the details.
2
3 ===============================================================================
4 Dabo 0.8 (2007-04-01) (Revision 3010):
5
6 Enhancements:
7
8     ===== General Stuff =====
9 + Added datanav2; deprecated datanav. datanav2 no longer supports fieldSpecs,
10   relationSpecs, and other things. The general theme is that the generated
11   code is meant to be taken as boilerplate to be edited by the developer to
12   achieve the desired results.
13
14 + Began work on new unit testing harness, with Nate Lowrie at the helm.
15
16 + Added/enhanced unit tests for dCursor, dBizobj, dTextBox, and dForm.
17
18 + Big fixes and enhancements, as always, to runtime cdxml instantiation,
19   including much better inheritance of properties.
20
21 + General move away from accepting specific keyword arguments to class
22   constructors, in favor of accepting property values instead.
23
24     ===== UI Tier =====
25 + EasyDialogBuilder - minor improvements by Nate Lowrie.
26
27 + Added ensureLineVisible() method in dEditor, which even unfolds if needed.
28
29 + Added WordWrap to dGrid columns while in edit mode.
30
31 + Enhanced dShell to have Dabo property access, including Font properties.
32
33 + Improved dDateTextBox.
34
35 + Coerce dMessageBox messages into strings, which is convenient.
36
37 + dGrid's navigation now traps and responds to business rule violations, with
38   mediation by the form if possible.
39
40 + dTreeView supported in ClassDesigner-designed files.
41
42 + Added Icon property to dApp, which will become the default Icon for all
43   forms and dialogs, if not overridden at the form level.
44
45 + Simplified drag/drop in dabo.ui.
46
47 + Added dabo.ui.getChoice() and getChoices(), which present a list of choices
48   to the user, and return the user's selection(s).
49
50 + Added TextLength property to dTextBox, to limit the number of characters
51   that can be typed in by the user. Courtesy Nate Lowrie.
52
53 + Improved font zooming. Improved handling of resizing fonts for different
54   platforms (Mac), so that you have cross-platform consistency. Thanks to
55   Dj Gilcrease for help in working this out.
56
57 + Added Continuous property to dSlider, which determines whether Hit is
58   raised while the slider is being changed, or only after the user has
59   finished sliding.
60
61 + Improved autocompletion in dEditor.
62
63 + Added AutoAutoCompletion option to dEditor.
64
65     ===== Data Tier =====
66 + dbFirebird - Minor improvements by Uwe Grauer.
67
68 + dbPostgreSQL - Improvements by John Fabiani, including some missing data
69   types and support for schemas.
70
71 + Added support for SQL-JOIN clauses in the sql builder.
72
73 + Added database logging, an optional feature.
74
75 + Improved SQLite by providing DictCursors.
76
77 + Added enclosing of table, field, and other names in the appropriate quote
78   character for the database backend in use. This allows for cases such as
79   spaces in field names. Control whether quoting happens automatically using
80   the dBizobj.AutoQuoteNames property.
81
82     ===== Bizobj Tier =====
83 + Added the concept of VirtualFields to dBizobj, which provides a simple,
84   flexible interface to reference calculated fields on the fly.
85
86 + Improved data binding to bizobjs on a parent form.
87
88 + Added dBizobj.deleteAllChildren()
89
90 + Added ability to set parameters to pass to default values in dBizobj.
91
92 + Added oldVal() method to dBizobj, which takes a field name and returns the
93   value of the field at the time of the last requery.
94
95 + Added moveToPK() method in dBizobj
96
97
98 Bug Fixes:
99 + dRadioList.ButtonSpacing wasn't able to be set from initProperties() or
100   as an argument to the constructor. Fixed.
101
102 + Starting in wxPython 2.7, our dialogs weren't giving focus to the first
103   control. Fixed.
104
105 + More wxPython 2.8 bugfixes in dMenu, dPageFrame
106
107 + Fixed dConnection and dConnectInfo to raise exceptions if improper
108   arguments are passed. Ditto for dSizer*.
109
110 + Fixed dBorderSizer's box to stay in back of the controls contained within it.
111
112 + Fixed ForeColor to work immediately on Gtk.
113
114 + Controls were flushing their value, and raising ValueChanged events, too
115   many times. Fixed.
116
117 + Dialogs and forms weren't able to set things like whether they have a
118   close box, from within initProperties. Fixed.
119
120 + Message dialogs invoked like dabo.ui.areYouSure() weren't getting attached
121   to the appropriate parent form, so that the message displayed wouldn't
122   activate the form that it applied to first. Fixed.
123
124 + Fixed rapid flashing in a sorted dGrid when an editable column was selected.
125
126
127 ===============================================================================
128 Dabo 0.7.2 (2007-01-18) (Revision 2716):
129
130 Additions, all minor, backported to stable only to keep compatibility with the
131 stable versions of daboide and/or dabodemo:
132 + Enhanced the getImagePath() function to work better with Windows pathing.
133 + Refactored dPanel into a common mixin class.
134 + Added getBaseNodeClass() function to dTreeView.
135
136 Bug Fixes:
137 + Fixed the stable branch to work with wxPython 2.7 and 2.8, which was a fairly
138   large backport of relevant changes from the development trunk.
139 + Fixed a form activation problem that would happen in some cases on Windows,
140   particularly with the Class Designer.
141 + Fixed incremental search in dGrid, which was broken by earlier unicode fixes.
142 + dBizobj.onSaveNew() user hook never being called. Fixed.
143 + Fixed but in dUserSettingProvider if setting/retrieving nested settings.
144 + dForm not updating field values after a save(), which is sometimes needed.
145   Fixed.
146 + Fixed dForm to explicitly cancel bizobj changes if the user answers "no" to
147   the "do you wish to save?" message. Otherwise, the application would never
148   finish.
149 + Fixed dGrid and dImage's attProperties.
150 + Fixed bug in dGrid.HeaderHeight resulting in a traceback if you tried to set
151   it in initProperties() or as a kwarg to the constructor.
152 + Fixed dabo.ui.busyInfo() to actually show the specified text instead of just
153   an ugly grey box on Gtk.
154 + Fixed a bug in dbFirebird that was caused by initializing more than once.
155 + Fixed a problem with the date textbox in the datanav select page adding 1
156   to each month, resulting in an incorrect select statement.
157 + Fixed some minor wording and behavior problems with the Quick Report option
158   in AppWizard apps, thanks to Ted Roche.
159 + Fixed htmlAbout to not return the html tags to the clipboard.
160 + Fixed dToggleButton to always flush its data, not just on LostFocus.
161
162
163 ===============================================================================
164 Dabo 0.7.1 (2006-11-21) (Revision 2490):
165
166 Bugfixes:
167 + Segfault in dSplitter when dragging the sash. Fixed.
168 + __init__() of the wx classes happening twice. Fixed.
169 + Setting Caption sometimes required a subsequent refresh(). Fixed.
170
171
172 ===============================================================================
173 Dabo 0.7 (2006-11-16) (Revision 2464):
174
175 It has sure been a while, but we haven't been resting. Lots of new stuff
176 as we move one step forward to Dabo 1.0. Here are the most important
177 things to mention.
178
179 Notable things:
180 + SQLite is now required.
181 + wxPython 2.7 and 2.8 DO NOT WORK yet, but will soon, so stick with 2.6
182   for now.
183 + Dabo preferences are no longer saved in .ini files, but as sqlite databases.
184 + The old shortcut of referencing fields in bizobjs like:
185     fname = biz.first_name
186   no longer works. You need to change all such code to read:
187     fname = biz.Record.first_name
188
189 Known Issues:
190 + FireBird Requery problem (see http://dabodev.com/tracker/0229)
191
192
193 Bug Fixes:
194 + Replace function in dTextBox and dEditBox causing traceback. Fixed.
195 + Incremental search in dGrid now works with unicode data.
196 + Double select page on Mac and Win. Fixed.
197 + Datanav select page scrollbar doesn't show. Fixed.
198 + Ignore Tab and Shift+Tab in grid searching, so they can navigate.
199 + Setting AutoPopulatePK on the bizobj doesn't propagate to cursor. Fixed.
200 + Entering a unicode character in a dTextBox set up with a str value doesn't
201   stick. Fixed.
202 + Fixed unicode problems in dEditor.
203 + Fixed problem where fast cpu's could generate non-unique object names.
204 + Fixed showModal() to reactivate previously deactivated windows accordingly.
205 + dCursor's initProperties() called twice. Fixed.
206 + Spacers not working correctly in class designer generated files. Fixed.
207 + Fixed dabo.ui.getMouseObject() to always return the dabo object, not the
208   wx one. This would happen with grids, for example.
209 + Border sizer caption not showing. Fixed.
210 + Connection information not properly escaped in default.cnxml. Fixed.
211 + Fixed layout of nested sizers.
212 + Fixed running class-within-a-class (class designer generated).
213 + Fixed paged controls to work when generated from the Class Designer.
214 + Grid mouse events duplicated. Fixed.
215 + Can't set RegID from within initProperties(). Fixed.
216 + stderr and stdout not restored if intellisense processing caused exception.
217   Fixed.
218 + Fixed login form to look okay at low resolutions.
219 + Removed old, lingering requirement for mx.DateTime.
220 + dSpinner doesn't work correctly unless initialized to '0'. Fixed.
221 + dForm.ActiveControl would return controls in other forms, if they were the
222   current active control with keyboard focus, when clearly we want the active
223   control of *this* form. Fixed.
224 + Fixed function in dbSQLite to find and set the pk field.
225 + Fixed __version__.py to work outside the expected directory naming
226   structure.
227 + Report writer wasn't initializing report variables before starting the
228   iteration of the cursor, resulting in errors if you referred to the
229   variables from inside the page header, for example. Fixed.
230 + Setting the Value of a data-bound control programatically wasn't propagating
231   to the underlying bizobj. Fixed.
232 + New reportlab can only handle utf-8, causing errors otherwise. Added a
233   friendly message in case this happens to you when running the Quick Report
234   option in AppWizard-generated apps.
235
236 Enhancements:
237 + Added Visible property to grid dColumns.
238 + Added column information to the EventData of grid events.
239 + Removed RequeryOnLoad property from datanav.Form to dabo.ui.dForm.
240 + Can now send kwargs to grid.addColumn(), which get sent to the column's
241   constructor.
242 + Added self.super() to replace cls.doDefault, thanks to Timothy Delaney.
243 + Added exception handling to requerying. If exception happens, the
244   transaction will be rolled back.
245 + Enhanced the process used to determine field types. In addition to better
246   automatic deduction of types, you can now explicitly set the DataStructure
247   property of dBizobj and Dabo will respect that.
248 + Added Alt+Up and Alt+Down to AppWizard Apps, which bring you to first and
249   last records, respectively.
250 + Added properties for getting/setting the selection and insertion point for
251   text controls. These are InsertionPosition, SelectedText, SelectionEnd,
252   SelectionLength, and SelectionStart.
253 + Compound primary keys can now be used.
254 + Dabo icon now has an alpha channel and looks much better. Thanks to Kenneth
255   Ismert for doing a great job of this.
256 + Added Expanded property for treeview nodes.
257 + Can now set PageClass property of dPageFrame to a cdxml file.
258 + Added dRadioList to replace dRadioGroup. Pure Dabo control.
259 + Added ability to set a bizobj LinkField property to a table.field reference.
260 + Added RequeryWithParent property to dBizobj, True by default. Allows for
261   user code to determine when to requery the child, for performance reasons.
262 + Added Selection property to dGrid, which returns the list of selected rows
263   or columns.
264 + Added AutoBizobj, thanks to Echo.
265 + Added Count property to dMenu, to return the number of child menus.
266 + Changed most initial dEditor settings into configurable properties.
267 + Drag/Drop for tree nodes begun.
268 + Added getCurrentRecord() that returns the actual record data.
269 + Added dPref for managing application preferences, and switched the default
270   way to save/restore settings to use this class. Your application can define
271   whatever hierarchy you see fit. See also the new BasePrefKey and
272   PreferenceManager properties of dObject.
273 + Added ForceCase property to dTextBox and dEditBox. Forces to upper, lower,
274   or title case as the user types.
275 + Added getTempCursor() to facilitate ad-hoc data queries.
276 + Added dApp.Encoding property, a single place to get the unicode encoding. To
277   set the default encoding, use dabo.defaultEncoding = "latin-1", for example.
278 + Added clear() method to sizers, to remove all items from the sizer, and to
279   optionally destroy the items as well.
280 + Added Precision property to dColumn, which specifies the number of places to
281   show for float columns.
282 + Added preliminary support for BLOB fields. Works at least with MySQL.
283 + Added GridBeforeSort and GridAfterSort events.
284 + Added itemNode entry to the eventData for Tree events.
285 + dToggleButton now uses GenBitmapTextToggleButton, allowing for text and
286   images.
287 + Added some filtering functions to dDataSet, for selecting which records
288   to return.
289 + Added transparency and drawGradient to drawing objects. Thanks to Andrea
290   Galvana for the gradient code.
291 + Added WordWrap property to dColumn, which will wrap the text appropriately.
292 + Added cut/copy/paste hooks at the grid level.
293 + Added dabo.ui.getFormMousePosition (position relative to active form)
294 + Added DrawMode property, the logical function to use for draw operations.
295 + Added ability for About dialog subclasses to add their own version info.
296 + Added helper functions to dabo.ui: isControlDown(), isShiftDown(),
297   isAltDown(), and isCommandDown() which will return True/False depending
298   on whether the key is down while the call is made.
299 + Added containerCoordinates() and formCoordinates() method, to get the
300   current mouse position relative to the container or form.
301 + Added objectCoordinates(), which is relative to the object.
302 + Made dForm.ActiveForm settable as well as gettable.
303 + Added isContainedBy() function, returning True if the object is contained
304   inside the passed container.
305 + Made dEditor a data-aware control (cool!)
306 + Added Encoding property to dDataSet. Thanks to Simen Haugen.
307 + Can now send extra keyword args to bindKey(), which will get included in
308   the eventData dictionary, just like it works with bindEvent().
309 + Added Dabo data type code "L" for blobs, "G" for longs, and "F" for floats.
310 + Added 'sort none' option to dGrid. Now, the third mouse click on the header
311   will be 'no sort'.
312 + Added accelerator keys to the datanav Actions menu. Added Select All to the
313   Edit menu.
314 + Added dabo/ui/uiwx/concordance.py, which shows a listing of all the Dabo
315   ui classes, and the wx Class from which they descend. Then, it shows the
316   wx classes, and the list of Dabo classes that descend from it. Should help
317   people with questions like "where is wx.TextCtrl in Dabo? (dTextBox).
318 + Added MultipleSelection property to dGrid.
319 + Improved dPageList, allowing setting the spacing of the list items with
320   ListSpacing, and catching right-clicks smartly (the correct item gets
321   referenced).
322 + Added function dabo.lib.getRandomUUID(). Thanks to Ka-Ping Yee.
323 + Added method afterInitAll(), which gets called after all child objects have
324   been initialized and are live.
325 + Added helpful treeFromStructure() method to dTreeView, which takes a
326   hierarchy (in list or tuple form) and constructs the tree nodes accordingly.
327 + Added ability to send sequences of 3-sequences to the ok/cancel dialog to
328   automatically construct labels and controls on the dialog.
329 + Couldn't use the same RegID for objects, even if the prior object was
330   destroyed. Relaxed the requirements to allow for this.
331 + Added dHtmlBox, which wraps wx.html.HtmlWindow, for displaying formatted
332   text simply. Thanks to Nate Lowrie.
333 + Added showContainingPage() method to all ui controls, which will recursively
334   show any pages in any pageframes that contain this control.
335 + Added showCurrentLine() to dEditor. Does what it says.
336 + Datanav forms (AppWizard-generated) now look better as they have a bigger
337   default size. Thanks to Bill Anderson for bringing up lots of such issues.
338 + Added AddChildEditPages property to datanav apps. Set it to False and you
339   stop getting the annoying edit pages for the child bizobjs.
340 + Previously, you could only set page sizes in reports to strings like
341   "letter", "a4", etc. Now, you can also set explicit sizes such as
342   (100, 75) or ("1.75 in", "1 in").
343 + Added preliminary support for Microsoft SQL Server. This isn't usable yet
344   for any but the most tenacious developers, and likely quite buggy. If you
345   want to try it out or help develop it, please post a message to the dabo
346   developer's list (dabo-dev@leafe.com).
347
348
349 ===============================================================================
350 Dabo 0.6 (2006-03-27) (Revision 2043):
351
352 + Fixed a problem when switching to the Browse page of the datanav grid without
353   first running a query. Also, there was an error being thrown if a previous
354   query had results, and a subsequent query had no results.
355
356 + Modified the code in _setCurrentRow() of dGrid so that it wasn't calling
357   SetGridCursor() unless the position had actually changed. I had recorded up to
358   10 calls to this function, all with the exact same values each time I switched
359   to the Browse page.
360
361 + Removed the code that lower-cased field names, as it was preventing the code
362   from working with case-sensitive backends and columns containing capital
363   letters.
364
365   Fixed a problem where str values were not able to be properly converted to
366   unicode.
367
368 + Added a parameter to the promptForFileName() method to specify the default
369   path for the dialog.
370
371 + Added the TreeItemContextMenu event. This differs from the normal
372   ContextMenuEvent in that it returns the itemID of the node that was
373   right-clicked.
374
375 + Added code in the event data gathering code to store the tree item ID for
376   these events in EventData.itemID.
377
378 + Changed all the names '_id' in the dTreeView.py file to the clearer 'itemID'.
379
380 + Fixed an oversight in the dSizerMixin that didn't remove the Box for a
381   dBorderSizer when the sizer was released.
382
383 + The double-Activate on Windows is really getting in the way. I haven't heard
384   anything from my bug report yet, so I added workaround code to ignore the
385   first Activate.
386
387 + Cleaned up the order of releasing child objects for sizers. Also fixed problem
388   with releasing the box for border sizers.
389
390 + Added getFunctionList() method to return a list of all 'class' and 'def'
391   statements in the current file.
392
393 + First pass at integrating the dTable class into the dabo.db framework. Right
394   now, if this works at all, it only works for SQLite.
395
396 + Fixed a bug wherein multiply-nested sizers might not release all of their
397   content when release(True) is called.
398
399 + Added a 'setInactive()' method that will hide the auto-complete popup if one
400   is visible.
401
402 + Disabled the fillGrid()'s setting of focus to the grid, as it causes problems
403   with stealing focus away from another active form, at least on Windows. Also,
404   it seems that such code really doesn't belong inside the function to build the
405   grid, but perhaps we'll find it belongs somewhere else.
406
407 + The xml header wasn't being converted to native line endings. Fixed.
408
409 + No need to explicitly do the unicode conversion in the report fields, as that
410   is done in the report writer.
411
412 + Added a Refresh event. This is raised when dForm.refresh() is called. All
413   dPemMixin classes will receive it, and fire their refresh() hook method.
414
415 + Added dynamic properties to most normal static properties. Example: given a
416   label and a function 'currTime()' in a form that returns the current time,
417   issuing the following:
418     label.DynamicCaption = label.Form.currTime
419   will result in the label's Caption property being updated every time
420   label.Form.refresh() is called.
421
422 + Added two methods to dabo.ui for converting image data back to bitmaps and
423   images. These were necessary because I noticed that when Editor.py was called
424   from locations other than its own directory, the image file for the function
425   button was not found. The solution was to convert the .png file to a data
426   stream using wx.tools.img2py.py, and store that in Editor.py.
427
428 + Can now set dApp.UI=None, and setup() won't try to load a UI. You have to do
429   it explicitly, though, such as:
430     app = dabo.dApp()
431     app.UI = None
432     app.setup()
433   --or--
434     app = dabo.dApp(UI=None)
435     app.setup()
436
437 + First crack at creating a double-buffered drawing surface. The new class,
438   'dDrawPanel', is a subclass of dPanel, but has its repainting handled through
439   the double-buffer techniques outlined on the wxPython wiki.
440
441 + Bookmarks in dEditor now persist when you save the file. If you re-open a
442   saved file with bookmarks, they are restored.
443
444 + Refactored dUserSettingProvider a little bit. Fixed a bug in
445   getUserSettingKeys() that resulted in it always returning an empty list. Added
446   deleteUserSetting() and deleteAllUserSettings(); these do just what you think
447   they would.
448
449 + Changed a couple exec() calls to setattr() calls instead, which may be safer
450   if not faster, but definitely more explicit and easier to understand.
451
452 + Implemented the handling of RowSpan/ColSpan for grid sizers.  Added a
453   GridSizerSpanException class that is raised if an attempt to set the span to a
454   location that is already occupied.
455
456 + Revamped the entire flow for transactions. These changes have been tested on
457   MySQL and SQLite, but still need to be tested with Firebird and PostgreSQL.
458
459 + Changed the default for bizobjs, cursors, etc., to not autocommit. The
460   AutoCommit property of the bizobj is simply a pass-through to the cursor's
461   AutoCommit property.
462
463 + Also cleaned up some inconsistent spacing and method ordering.
464
465 + Modified datanav to allow for manual setups that don't use fieldSpecs or
466   relationSpecs. I'll be committing a change to the AppWizard that allows
467   for this option soon.
468
469 + Moved SelectPageClass, BrowsePageClass, and EditPageClass from PageFrame
470   to Form, since that is a better central location for these properties.
471
472 + Added a splash screen to the Dabo app startup. This is based on Andrea
473   Gavana's AdvancedSplash class, and allows for cool shaped windows, etc.
474
475 + Added the ability to set the DataSource to an object, rather than just a
476   string that can be eval'd to an object.
477
478 + Changed the 'getMaxRow/Col' methods to 'getHighRow/Col' in order to avoid
479   confusion with the MaxRows/Cols props in dGridSizer.
480
481 + Modified both sizer classes to accept windows and not just SizerItems when
482   setting/getting prop values.
483
484 + Added the movePage() method, which takes either a page reference or a page
485   index, and moves the page to the specified position. The page is then
486   selected, unless the third parameter 'selecting' is False.
487
488 + Added a getInt() method to dabo.ui.uiwx.
489
490 + Fixed the splashscreen display on Windows.
491
492 + Added the ability to set the font face and size for the editor.
493
494 + Added the setCheck() method to dMenu. Given a caption, it will check any menus
495   whose captions match. By default it will uncheck any that don't match; you can
496   pass False as the second argument and leave non-matchers alone. Also added
497   clearChecks() to uncheck all menu items in a menu.
498
499 + Exposed the FileName and FilePath properties in dEditor.
500
501 + Added some syntax sugar for referring to fields and variables in reports.
502   Where you used to have to refer to self.Record["clientname"], you can now do
503   self.clientname. Same with self.Variables.
504
505 + Added the 'callEvery' function to dabo.ui. This function accepts an interval
506   (in milliseconds), and callable reference, and optional arguments to that
507   callable. It then creates a timer that fires the callable every <interval>
508   milliseconds, passing along any optionally included arguments. The timer
509   reference is then returned, where it can be controlled by calling stop(),
510   start() or release(). This is based on the dCallEvery class that Brandon
511   Singer proposed. I made it a function in dabo.ui because I felt it was more
512   consistent with the existing functions callAfter() and callAfterInterval().
513
514 + Changed the default for forms to not automatically show "Record 1 of 0" or
515   similar meaningless database information in the status bar. Set it back to
516   True for the datanav Form class, so all datanav apps should remain unchanged.
517   All of the apps in the demo and IDE directories that don't query data, though,
518   no longer show that message.
519
520 + Creating an instance of dApp doesn't automatically create an instance of
521   uiApp. Instead, it now asks dabo.ui to get it a reference, and dabo.ui either
522   returns the current instance if one already exists, or creates one if not.
523   This allows you to run wxPython apps from within wxPython apps.
524
525 + Added some rudimentary support for file drag/drop. Right now, you can call
526   'createFileDropTarget' on an object to make it able to respond to files
527   dropped on it. Pass in an optional handler object reference; otherwise, the
528   handler is set to the object itself. The drop event is passed on to the
529   handler by calling its 'processDroppedFiles' method, which should be
530   overridden in the handler object to do the specific processing of the files.
531
532 + Added a 'Column' property to dEditor; this represents the column position in
533   the current line, and can be changed to move the cursor within the line.
534
535 + Added option in getItemByRowCol() to return the sizer item in the given
536   position instead of the object managed by that sizer item.
537
538 + Added method 'isItemChecked()' to allow you to determine the checked status of
539   any menu item.
540
541 + Added dabo.ui.getMousePosition(), which returns the position of the mouse
542   on the screen. This is in contrast to dPemMixin.getMousePosition(), which
543   gets the position of the mouse inside the client window.
544
545 + Update to allow execution of SQL statements without affecting the current data
546   set. The bizobj has a new pass-through method named 'execute()', which takes a
547   statement understood by the backend database and passes it to its cursor's
548   execute method.
549
550 + The cursor class has been modified to run all statements that don't begin with
551   'select' through its auxiliary cursor, thereby preserving its data set.
552   Preliminary tests that I've run have confirmed that these are working
553   correctly, but there should be a lot more testing done before I am confident
554   that these changes are truly sound and can handle whatever we can toss at them.
555
556 + You can now set the DataSource to an actual object, instead of having to set
557   it to a string that could be resolved to an object.
558
559 + Added basic support for storing lists/tuples in the user settings.
560
561 + Added a simple way of persisting MRU lists in applications. A new dApp
562   property, '_persistentMRUs' is a dict that contains the name of the menu as
563   the key for the entry, and the function to bind the items to as the value. The
564   framework will then handle saving and restoring MRU lists upon app startup and
565   closing.
566
567 + Modified the uiApp to accept just the menu caption as an identifier instead of
568   requiring the actual menu. This is necessary to create MRU lists for context
569   menus, or for restoring menus at app startup.
570
571 + Updated the requirement that a bizobj be found for all data sources. Since
572   that was written, Dabo's use of data binding has expanded to lots of
573   non-bizobj uses.
574
575 + Completed the majority of the work needed to implement saved classes that can
576   be used in other class designs; it was working from the Designer, but not when
577   you ran the form. These changes implement the whole inheritance structure so
578   that if you change the underlying class, any changes not explicitly overridden
579   in the design that uses that class are reflected. This works for both property
580   changes as well as code changes.
581
582 + Switched the default order of arguments in callAfterInterval(). It makes more
583   sense to specify the interval first, followed by the function and its
584   arguments. Sticking the interval between the function and its arguments seems
585   very awkward. I added code to callAfterInterval() to check if it received a
586   call in which the interval is the second argument (i.e., the original style)
587   and switch them around in that event.
588
589 + Removed dDrawPanel as a class. Turns out that adding double-buffering to
590   panels doesn't affect their performance noticeably, so it made sense to turn
591   this on for all dPanel objects by default. However, if you run into a
592   situation where this adversely affects your app, there is a new property named
593   'Buffered' that will turn this behavior off (i.e., make it work like it used
594   to) when set to False.
595
596   *IF YOU USED dDrawPanel IN YOUR CODE, THIS WILL BREAK IT!* You must update by
597   changing all references to dDrawPanel to simply dPanel.
598
599 + Removed the old syntax for begin/commit/rollbackTransaction. The default for
600   these actions in dBackendObject is to call the appropriate method on the
601   connection, not to execute a command on the cursor.
602
603 + Removed the call to cursor.connection.begin() in the beginTransaction()
604   method. This does not seem to be needed for most backends; in fact, it is
605   typically used to override autocommit to create temporary explicit
606   transactions.
607
608 + Table creation now works for MySQL also. The class dAutoBizobj is a bizobj
609   that has a dTable. The function AutoCreateTables() will try to create all the
610   tables that have been setup with dAutoBizobj objects. If it can't create the
611   tables, a message pops up for the user and the db admin. The db admin can
612   enter the username and password for access to create tables or the db admin
613   can manualy execute the queries in the queries.sql.
614
615 + Converted the dTimer from a bitmap to a non-visible control based directly on
616   wx.Timer. This makes it fit in much better with dabo.ui.callEvery(), which is
617   much more convenient to use in many cases.
618
619 + Began coding for the Hover property, which will allow for easier visual coding
620   of MouseOver events. It isn't fully implemented yet, so don't try working with
621   it.
622
623 + Implemented the Hover property in dPemMixin. The reason for this rather than
624   relying on MouseLeave to terminate the effect is that there are many time when
625   it seems that the mouse leaves the area without triggering the MouseLeave
626   event. The Hover mechanism employs a timer to check for mouse position, and
627   fire the MouseLeave code if it detects that the mouse position is outside of
628   the control.
629
630 + Added a CustomSQL property to the datanav form. If set, the settings in the
631   select page will be ignored and the contents of CustomSQL used instead.
632
633 + Added defaults to dGrid.getValue(). If no row or col is specified, it defaults
634   to the current row/column, respectively.
635
636 + Added fontMetricFromDrawObject() to dabo.ui. This enables simple calculation
637   of the width/height of a drawn text object.
638
639 + Added a fitToSizer() method to dPemMixin. This will resize the object to fit
640   the size required by the sizer represented in its Sizer property. You can also
641   pass in extraWidth and extraHeight values to adjust the size further.
642
643 + Added 'Alignment' to the pre-init properties of dCheckBox. Cleaned up the
644   property methods and definitions to make them alphabetized, and to make the
645   strings localized. Also relaxed the values accepted for the Alignment
646   property.
647
648 + Added an option to dEditor.changeFontSize() to accept strings in the format
649   "+n" or "-n". These will increment or decrement the font size by 'n' points.
650
651 + Moved the _addCode() method out of dFormMixin, since it really is more generic
652   than that. It now lives in dObject._addCodeAsMethod(), which takes a dict of
653   method name/code pairs and adds them as methods of the object. dPemMixin now
654   looks for a keyword argument called 'srcCode', and if found, adds it to the
655   object.
656
657 + You can now call addObject() and pass a cdxml file instead of a Dabo class
658   reference, and the class defined in the cdxml will be added to the parent.
659
660 + Cleaned up the dynamic code creation routines in dObject and
661   DesignerXmlConverter.
662
663 + Modified xmltodict to handle property declarations.
664
665 + Added setAfter() and setAfterInterval() to dabo.ui. These work the same as
666   callAfter() and callAfterInterval(), except you use them to set properties to
667   particular values.
668
669 + Added the following properties to dGrid: MovableColumns, ResizableColumns, and
670   ResizableRows. When any of these are set to False, the user cannot move/resize
671   the column or row.
672
673 + Changed the keyboard datanav navigation from Ctrl+, and Ctrl+. to Ctrl+LEFT
674   and Ctrl+RIGHT on Mac, and Alt+LEFT and Alt+RIGHT on Linux and Windows. I've
675   The original configuration, in addition to being nonintuitive, didn't work on
676   Windows.
677
678 + Added the ability to save screenshots in one of several graphics formats.
679   While this was part of the Bubblet demo originally, it could have uses
680   elsewhere. For example, combining this with dabo.ui.callAfterInterval() would
681   enable timed screen shots.
682
683 + Hacked a bit to get getCaptureBitmap() to work well on GTTK, but it's still
684   a bit of a mess. GTK doesn't capture the title bar, menu bar or frame
685   decorations of a window, and I tried to compensate the sizing accordingly.
686   Individual controls don't seem to work at all. I don't have more time to
687   play around with this now, but this is hardly a show-stopper for release.
688
689
690 ===============================================================================
691 Dabo 0.5.1 (2006-01-25) (Revision 1860):
692
693 + Additional MDI/SDI improvements and fixes. By default, dForm on Windows will
694   be a MDI child, which is what most Windows users will expect.
695
696 + Fixed PageFrame background color to take the background color from the form,
697   not unconditional white. Only on Windows - Gtk and Mac do the right thing by
698   default.
699
700 + Fixed various issues with getting icon files and converting them to bitmaps.
701
702 + Set the default grid font to Arial,9 on Windows, as the wx-default was just
703   plain ugly.
704
705 + Added getPositionInSizer() method to sizers, since they may also be contained
706   within sizers.
707
708 + Reworked dShell. Now it appears as a split window, with the standard command
709   area on the top, and the output in the lower pane.
710
711 + Changed dGridSizer to raise an exception if the insert method is called
712   instead of just returning False.
713
714 + Added SashPositionChanged event. Updated dSplitter to raise this event when
715   the sash position changes.
716
717 + Added scrollToBeginning() and scrollToEnd() methods to dEditBox.
718
719 + Added pass-through properties for dSplitForm's splitter's panels.
720
721 + Added the property 'SplitState' to the dShell class. By right-clicking on the
722   shell, you can toggle between the new split behavior and the "traditional"
723   single pane behavior.
724
725 + Added a right-click menu to the output pane. Right now all it can do is clear
726   itself, but we could add other stuff such as font selection, etc.
727
728 + Fixed a bug in uiApp that prevented Cut(), Copy() and Paste() from working in
729   the shell (and other non-Daboized controls that only have wx versions of these
730   methods).
731
732 + Added a menu command to the shell to clear the output window using
733   Ctrl-Backspace.
734
735 + Added the MenuOpen event to dEvents. This allows us to create dynamic menus by
736   intercepting this event and updating the prompts of the menu items as needed.
737   Added the event data code to save the prompt and menu object that triggered
738   the event.
739
740 + Added 'deadObjectException' as an alias to wx._core.PyDeadObjectError to the
741   dabo.ui.uiwx module. This will enable Dabo code to handle this condition
742   without having to use wx code.
743
744 + Added a bunch on internationalization to the dShell script.
745
746 + Made the dMessageBox titles come from Application.getAppInfo(appName) by
747   default.
748
749 + Added handling for situations where a bizobj is used with a data connection.
750
751 + Added a sizeToColumns() method. This will set the width of the grid equal to
752   that of its component Columns.
753
754 + Fixed copy to clipboard in about.py to use CRLF on Windows.
755
756 + Added new properties to grid:
757     HorizontalScrolling
758     VerticalScrolling
759     ShowColumnLables
760     ShowCellBorders
761   The scrolling properties are booleans, and will hide/show the scrollbars.
762
763 + Fixed some problems with setting the column's Width. For a number of reasons,
764   when you created a grid from scratch and then added columns using addColumn,
765   the columns widths you'd specify weren't being respected. Fixed.
766
767 + Moved the code for the dEditor class from ide/dEditor.py into its own
768   uiwx-level class. This will allow other apps (I'm thinking Designer here!) to
769   instantiate code editors where they need.
770
771 + Revamped the layout of the dOkCancelDialog class to create the panel and sizer
772   that is needed in addControls().
773
774 + Cleaned up some of the default spacing so that with AutoSize=True, the form
775   still looks OK.
776
777 + Removed the split sash code from the dEditor. That stuff belongs in the form
778   the editor is located, not in the editor itself.
779
780 + Fixed a bug in dGrid that only seemed to pop up when the grid was located on a
781   form with a bizobj but that wasn't a dForm. The presets dialog in minesweeper
782   fit that description, and it was throwing errors when you navigated through
783   the grid.
784
785 + Added methods for getting/setting the back color of individual items.
786
787 + Added property CellHighlightWidth to dGrid, and used that property in the
788   about dialog.
789
790 + Made dPanel.addControls() better behaved.
791
792 + Reworked/improved the Quick Report dialog in datanav.
793
794 + Updated dPageFrameNoTabs to raise the same events as the 'tabbed' versions do.
795   Added a 'getPageNumber()' method.
796
797 + Added PNG files for rotating images clockwise and counter-clockwise.
798
799 + Improved dImage to support 90 degree rotation in either direction. Added
800   rotation to the the demo.
801
802 + Fixed a bug in dListControl's StringValue prop, and any other place where the
803   framework was trying to call the control's GetString() method, since it
804   doesn't have one.
805
806 + Added SearchDelay property to dApp, which becomes the default SearchDelay for
807   dGrid. The dGrid SearchDelay can get set to any int but that won't override
808   the dApp setting. If dGrid.SearchDelay is set to None (the default), that is
809   when the dApp setting gets used. Set the default SearchDelay to 300 - better
810   than the previous 600 IMO but still not too fast. Eventually, when we provide
811   a default system preference screen, we should expose this property for the
812   user to tweak how they like.
813
814 + Cleaned up and consolidated lots of stuff in dGrid, which shouldn't have any
815   effect on runtime performance. Made SameSizeRows into an actual property.
816
817 + Using the standard button sizer in the okay/cancel dialog is good, because it
818   lets wx handle the platform-convention rules. However, even though it handles
819   rearranging the order of the buttons as needed, it doesn't rearrange tab
820   order. So I added code to do that.
821
822 + Reworked the login dialog to subclass from dOkCancelDialog.
823
824 + Reworked dGrid to sync the rowcount in refresh() calls. Fixed bug in syncing
825   of column counts.
826
827 + The entire populate() cycle was happening every time you entered the browse
828   page in datanav apps, when in reality the only thing you need to do in current
829   dGrids when the dataset has been requeried is a simple refresh().
830
831 + Added an initial call to _clearDocument(), which is where all the defaults are
832   set for the editor. The DesignerEditor would not indent properly without this.
833
834 + Added moveToBeginning() and moveToEnd() methods to position the pointer at the
835   beginning and end of the document, respectively.
836
837 + Added functions to dBizobj, dCursor, and dBackend to get the data structure
838   from the cursor description, instead of querying the backend based on a table
839   name. This is more likely to contain correct information, but will need work
840   for other backends besides MySQL. Also, getting the pkid is still problematic
841   - but IMO it isn't a big deal to just have the user tell us which field to use
842   as the PK.
843
844 + Fixed dGrid's buildFromDataSet() to use the new function so it will work even
845   if the bizobj has no records at the time of creation.
846
847 + Fixed dGrid.sort() to not care if sort is done on an empty bizobj. Added the
848   logic to restore code saved in the Designer so that it functions properly in
849   the re-created form.
850
851 + This is big - really big. For the first time, you can create a form in the
852   Designer, add code to be bound to events, or create custom methods, and that
853   code will work in the form created from the .cdxml file exactly the same as if
854   you had written those methods in a regular .py script.
855
856 + Improved the card deck pictures.
857
858 + Fixed some problems in the Icon setter that would cause errors if None was
859   passed, or if the icon path didn't exist, as would be the case if you were
860   running with py2exe and didn't include the icon files as resources.
861
862 + Added a significant change to eventMixin.py's auto event binding logic. The
863   code now first looks at the object itself before looking up its family tree.
864   This is critical for the event binding when running a cdxml file, where
865   methods are added to the object at runtime, and are not present in the class
866   definition.
867
868 + Cleaned up some spacing in dEvents; also fixed some "appliesToClass" logic
869   that had events 'applying' to incorrect classses. There are still some
870   anomalies, I'm sure; the event listing in the Designer will reveal these.
871
872 + Modified the dynamic code binding to fix the problem with modifying the
873   object's class definition in the current namespace. Also fixed a problem where
874   code for dPage objects was not getting assigned.
875
876 + Fixed a bug in the dListControl's _getValue() method when there were no items
877   in the list.
878
879 + Added alias 'dragging' for 'mouseDown' in the EventData for mouse events.
880
881 + Added method 'getMousePosition()' to dPemMixin. This returns the mouse
882   position in relative coordinates to the object that called it.
883
884 + Added 'drawBitmap()' method to dPemMixin. Like the other wx.DC drawing
885   methods, this wraps the wx.DC.DrawBitmap() method into an object interface
886   that Dabo objects can use.
887
888 + Changed getSQL() so that if no FROM clause has been specified, it defaults to
889   a FROM clause using the cursor's Table.
890
891 + Added properties SettingsFileName and SettingsDirectoryName to the app's
892   UserSettingProvider. The defaults for both come from
893   app.getAppInfo("appShortName"), and determine the name of the directory and
894   file name of the user settings file. The directory name will be lower()'d and
895   have a '.' prepended automatically.
896
897 + Created the dFoldPanel and dFoldPanelBar classes, which wrap the built-in
898   wx.lib.FoldPanel classes. Modified __init__.py to include these, and added
899   some hacks to dPemMixin to enable them to work with the event structure.
900
901 + Added the dCalendar control. This wraps the wx.calendar.CalendarCtrl, making
902   it simpler and more Pythonic to work with.
903
904 + Added a setting 'firstDayOfWeek' to dabo.settings
905
906 + Moved the method _getWxColour() from dFoldPanelBar into dPemMixin, as it is
907   needed in both dFoldPanelBar as well as dCalendar, and possibly other wx
908   controls that expect a wx.Colour object instead of a color tuple.
909
910 + Added the calendar events and their processing.
911
912 + Added a form subclass named 'dBorderlessForm'. This creates a form with no
913   visible border or title bar. Renamed the base form class in dForm.py from
914   'dFormBase' to 'BaseForm'. I felt that the 'd' prefix was misleading, as it
915   isn't meant to be a Dabo base class at all.
916
917 + Updated dDateTextBox to use regular datetime values internally instead of
918   wx.DateTime. Updated the calendar to use the new Dabo dCalendar instead of the
919   raw wx version.
920
921 + Added row and column highlighting to the dGrid class. Default is to only show
922   the selected cell, but that can be changed by setting the SelectionMode
923   property to either "rows" or "columns". The color used to highlight the
924   selected row/col is controlled by the new SelectionBackColor and
925   SelectionForeColor properties; defaults are yellow background and black text.
926
927 + Added a GridRangeSelected event to dEvents, and added the code to raise it to
928   dGrid.
929
930 + Changed the default SelectionMode for the datanav grid to 'row'.
931
932 + Added some additional properties and functionality to the dFoldPanelBar class.
933   First is the 'Singleton' property, which controls a behavior in which one and
934   only one panel is open at any time. Expanding a different panel collapses the
935   currently open one, and attempting to collapse the expanded panel does
936   nothing.
937
938   Second, there is a 'SingleClick' property that controls whether you need to
939   double-click on a panel's caption bar (default behavior) to toggle it, or
940   whether a single click will suffice.
941
942   Finally, the 'CollapseToBottom' property determines whether any collapsed
943   panels are positioned at the bottom of the control, or whether they remain in
944   their natural position.
945
946   I added the FoldPanelCaptionClick and FoldPanelChange events to dEvents in
947   order to implement these features. They are available to instances of the
948   dFoldPanelBar class for hooking additional behaviors to these events.
949
950   I updated the test form for dFoldPanelBar to enable you to play with these
951   settings.
952
953 + Fixed a bug in dGrid's new SelectionMode property. I had previously checked
954   for only 'r' or 'c' at the beginning of the setting, forgetting that 'cells'
955   is a valid setting, so I fixed that to check the first two letters.
956
957 + Added the property 'AlternateRowColoring' to dGrid. When True, rows in the
958   grid will be colored depending on the RowColorOdd and RowColorEven properties.
959
960 + Changed the datanav grid to use alternate row coloring.
961
962 + Added some changes to the column Width setting that were necessary for working
963   correctly in the Designer.
964
965 + Fixed a bug with MultipleSelect in the dTreeView class. Added some navigation
966   methods for returning adjacent nodes. Fixed a selection bug when working with
967   MultipleSelect=True.
968
969 + Added code to properly escape characters that should not be in XML attributes.
970   Also cleaned up some uneven spacing in the created XML.
971
972 + Fixed a bug in dGrid that didn't allow the ColumnCount to be reduced.
973
974 + Fixed a bug in dPage that happened when the page was instantiated separately
975   from the pageframe, since it wasn't yet in the Pages collection.
976
977 + Added 'dEditableList', which is a wrapping of the wx.gizmos.EditableListBox.
978   This control takes a list and allows the user to add/edit/delete items from
979   the list, as well as re-order them. There are properties to enable/disable any
980   of the following: edit, add, delete, order. All are enabled by default.
981
982 + Fixed a bug in dGridSizer. Apparently, calling 'AddGrowableRow/Col' multiple
983   times increments an internal counter, and a subsequent 'RemoveGrowableRow/Col'
984   will only decrement it, and will not set it to be not growable unless the
985   counter has dropped to zero. Now setting a row as growable won't do anything
986   if it already is.
987
988 + Added the drawText() method, along with the text draw objects.
989
990 + Added columns to reportWriter. Added smarter sorting of elements in the xml
991   output, for instance putting the report title up top instead of on bottom, and
992   putting the bands in order that they appear and not alpha order.
993
994 + Changed all the sizer routines to return the SizerItem managing the object
995   that was just added to the sizer.
996
997 + Sizer.Children now modified the SizerItem objects to include a
998   'ControllingSizer' attribute that references the parent sizer.
999
1000 + Modified the dFoldPanelBar class to better time its refreshes. It's still a
1001   bit funky, but does seem to work better.
1002
1003 + Modified dFormMixin to handle the new Spacer panels correctly.
1004
1005 + Added a 'Children' property to dFoldPanelBar that returns the child panels,
1006   instead of the layout panel that it uses to manage the visible panels.
1007
1008 + Added a return value to setItemProp() in the sizers so that we can tell if a
1009   value was successfully applied.
1010
1011 + Fixed the problem with propertyHelperMixin.getPropertyList(): it was caching
1012   the list of properties across the class hierarchy, instead of caching just for
1013   this one class definition. Good catch, Ed!
1014
1015 + Wrapped the wx.CheckListBox for Dabo.
1016
1017 + Changed the parameter to sizer for setting the sides that the Border property
1018   applies to from 'borderFlags' to 'borderSides', as this seems much more
1019   appropriate. Updated the sizers to properly get/set this prop from a list of
1020   values.
1021
1022 + Changed all hard-coded "\n" in dicttoxml to the more crossplatform idiom
1023   "%s" % os.linesep.
1024
1025 + Fixed a problem whereby nested sizers did not get their Parent property set.
1026   Thanks to Casey McGuire for catching this bug.
1027
1028 + Added the GridCellEditBegin event, which is raised when a grid cell editor is
1029   shown. This allows you to record the value of a cell before it is modified by
1030   the user.
1031
1032 + Added StayOnTop property to dFormMixin.
1033
1034 + Added ShowMenuBar property, so I can avoid showing the Dabo menubar on my
1035   property sheet and object tree forms.
1036
1037 + Added groups and variables elements to a newly created report form.
1038
1039 + Changed the default position to (-1, -1), since (0, 0) places the form under
1040   the menu bar when running on OS X.
1041
1042 + Fixed a problem with dGrid on Windows where the propsheet was stealing the
1043   focus
1044
1045 + Added ForegroundColor and BackgroundColor to dColumn. These props apply to all
1046   cells in a column that don't have custom renderers.
1047
1048 + Fleshed out the 'nextNode()' and 'priorNode()' methods to provide true flat
1049   navigation through the tree. Also cleaned up several other methods that dealt
1050   with nodes and their objects.
1051
1052 + Added font properties to treeview nodes.
1053
1054 + Wrapped the wx.Font object into dFont. This breaks the font editing on the
1055   PropSheet, and possibly a few other places that use the font prop, but we'll
1056   have to find those afterwards. All previous references to Font have to be
1057   changed to GetFont() instead; likewise, all assignments to Font must be
1058   replaced with calls to SetFont().
1059
1060 + Revamped the internals of dFont.
1061
1062 + Added 'defaultFontSize' to settings.py
1063
1064 + Updated the font handling in dGrid and dTreeView.
1065
1066 + Cleaned up some spacing in dLabel.
1067
1068 + Added the default wx IDs to the About and Quit menu items so that they appear
1069   in the proper place on OS X.
1070
1071 + Updated the long-neglected BorderSizer class, which wraps the
1072   wx.StaticBoxSizer class. You can now pass either a pre-made dBox object to the
1073   constructor, or pass a parent object, and the constructor will create the box
1074   for you.
1075
1076 + Added a Caption property to dBorderSizer. This will update the caption
1077   displayed on the sizer's box.
1078
1079 + Refactored the getItemProp() method so that dBorderSizer will use the same
1080   functionality.
1081
1082 + Added getAvailableFonts() method. Returns a list of all font faces installed
1083   on the current system.
1084
1085 + Updated dFormMixin to handle dBorderSizer objects in .cdxml files
1086
1087 + Changed the prompt and shortcut for the 'Quit' item in dBaseMenuBar to be
1088   'Quit' and 'Ctrl-Q' on all platforms.
1089
1090 + Added additional properties to dBorderSizer that are basically proxies to the
1091   box's caption.
1092
1093 + Added a Dabo wrapper for wx._core._wxPyDeadObject.
1094
1095 + Added a couple helper functions for converting between 0-255 rgb
1096   format and 0-1 format.
1097
1098 + Added basic MRU (Most Recently Used) capabilities to Dabo. I had looked at the
1099   wx.FileHistory class, but it seemed a bit too rigid to work with our design.
1100   To use MRU in a menu, the menu should be created by passing 'MRU=True' in the
1101   constructor.
1102
1103 + Added Variables, Groups, and Objects as ReportObjectCollections.
1104
1105 + Changed dEvents.ContextMenu to derive from Event instead of MenuEvent, since
1106   the contextmenu event is a request for a context menu to be displayed, and not
1107   generated from any existing menu.
1108
1109 + Added an addObject() function to report objects. Changed the sorting of report
1110   elements so that Variables appears before Groups. Fixed a bug which sometimes
1111   kept variables and groups from getting their xml generated.
1112
1113 + Modified xmltodict to properly escape any internal ampersands.
1114
1115 + Modified the Quick Report (list format) to generate the report form not by
1116   crafting the XML by hand, but by using the object interface and then finally
1117   having the report writer return the XML. This results in quick reports getting
1118   the same XML format as if the Designer were used.
1119
1120 + Added the dHyperLink control. This is a wrapped version of the
1121   wx.lib.hyperlink.HyperLinkCtrl.
1122
1123 + Added a new function to dabo.ui, callAfterInterval(func, interval). It will
1124   call the passed function after the interval has elapsed. Additionally, if
1125   callAfterInterval() is called again with the same function before the original
1126   timer had elapsed, the old timer is destroyed and the new one instantiated,
1127   making the function only run once, after a timer finally reaches the interval.
1128
1129
1130 + Added 'removePage()' and 'cyclePages()' functions to the dPageFrameMixin
1131   class. The former allow for a specific page to be removed, while the latter
1132   accepts an integer value and cycles the selected page forward (positive) or
1133   backwards (negative).
1134
1135 + Added a clear() function to dMenu() for removing all current items.
1136
1137 + Thanks to Brandon Singer, I've fixed a problem where passing kwargs to the
1138   constructor of any dObject subclass would silently pass any unhandled kwargs.
1139   The fix to the base problem was easy, but it turns out lots of our code was
1140   relying on this. I fixed the obvious places (code that gets run from dabo/ui
1141   /uiwx/test.py) but I suspect I've missed a few. If you