root/trunk/ChangeLog

Revision 4108, 82.8 kB (checked in by paul, 3 months ago)

Changelog and version bump to 0.8.4.

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