Archive for July, 2010

No News is Good News?

Wednesday, July 21st, 2010

I attended WWDC this year, in part because I knew there was going to be a new iPhone release and it would likely be accompanied by new a new version of the iPhone OS.  Of course there are also lots of tidbits regarding Mac OS/X and Apple’s PC hardware.

I also considered attending Delphi Live this year.  My current project timelines would have made that difficult, but I was prepared to justify it, except for one thing; there was no promise of any information regarding Fulcrum, the 64 bit compiler,  or a preview of either.

I’ve been developing with Delphi for a long time now, so most of the benefit for me is in seeing what’s new.  I’ve collected a lot of resource material over the years, and while I still learn something new all the time (at the expense of forgetting something else - let’s face it; the noggin is full), I value conferences mostly for getting me excited at the prospect of something new and potentially profitable.

I didn’t get the impression that the last Delphi Live was earth shattering, and when I emailed Frank Stepan to get some additional details on the Intellibook offer, because it wasn’t very clear, he informed me that “To receive an Intellibook notebook you are required to register for a minimum of 3 days”.  Suddenly, Delphi Live didn’t look so appealing.

If the organizers of the conference read this, might I suggest a couple of changes to their approach?

1) Always make sure there is as big an announcement as possible at each conference so attendees are the first to know, and if preview editions of upcoming releases are available, make it part of the conference goodies.

2) If you’re going to solicit early bird registrations, at least make sure the conference agendas are full.  When I looked there were a couple TBAs only 3 days prior to the end of early bird registrations (in fact I just checked and there are still 2 TBAs).  I want to know what I’m going to get for my time and money, and need to know so I can decide what days to attend.

3) Publicize any software discounts from third party vendors and exhibitors.

4) Schedule the conference around the same time as other complementary events.  I am thinking specifically of WWDC.  If Delphi Live is only a couple of days, it might make a lot of sense for it to be before WWDC or after.  If EMB is going to produce a development tool that targets Mac OS/X it would make a lot of sense to make it easy for such developers coming from afar to attend.

5) if an Expo is an integral part of the conference, shouldn’t there be at least a listing of Exhibitors?

hcOPF - ReadingWithChildren

Sunday, July 11th, 2010

Yes, you should definitely read with your children, but that’s not what this post is about.

Normally when a root object is read in from the object store, all it’s children are also read.  This is not always desirable from a performance standpoint, and it wasn’t an issue until I introduced complete design-time support for bindings.  Now, in order to bind lists, they must be created and added as children to the root object (I use an AfterConstruction override).  Previously, to get deferred loading, you would just create the list and add it as a child, just prior to loading and consuming the list.  While you can still do so, it’s not nearly as convenient, and it means your code won’t be as consistent.  Thus, I have introduced a new property on ThcObjectList called ReadWithChildren.  The default value is True, so the bahaviour will be the same as it always has, but now you can disable it whenever necessary.

In case you’re wondering when you might ever use it, I will provide one such scenario.  I have an Client object with  list of benefits that I have broken out into categories.  Since ThcObjectList doesn’t currently offer very much in terms of list filtering functionality, I have created two lists that I populate when I call a property getter to populate the complete list of benefits.  An added wrinkle is that benefits can expire,  so after I load the main benefit list, I check each benefit to see if it has expired, and if it has I mark it as such, and remove it from the list.  The remaining benefits are added to each separate category list.  Using three lists may seem like overkill, but they share the same objects, and it also makes it easy to change the contents of the grid in which I display them.  I use a single control, and simply change the list the mediator uses at run-time depending on the filter button that is down.  Here is the code fragment I am using:

  //unbind current objects
  Client.UnBind;

  //change package list displayed in grid
  GridMediator :=  (obClient.Bindings[1].Mediator as ThcTcxGridMediator);
  GridMediator.UnBind;
  if ToHealth then
    GridMediator.ObjectList := Client.HealthBenefits
  else
    GridMediator.ObjectList := Client.FringeBenefits;

  //re-bind to update UI
  obClient.BoundObject := Client;

ReKindling My Delphi Books

Sunday, July 11th, 2010

If you have ever questioned the value of filling out the Embarcadero developer survey, let me assure you it’s well worth your effort.  It provides EMB with valuable feedback, and even if you don’t like what they do with the information, you can’t complain unless you participate. Kind of like voting for your “favourite” politician (but I digress).  If you do participate, there is the chance of an unexpected benefit.

I got an email recently from Deanna Dames at EMB.  Apparently, I won an Amazon Kindle for filling out the developer survey.  Just wanted to say thanks EMB!  Now I can recycle all those Delphi books and put their PDFs on my kindle.

hcOPF LookupLists

Wednesday, July 7th, 2010

A common problem that developers have to deal with is validation of input against a lookup table in the database.  Sometimes the “table” isn’t even in the database so a hard coded list of key/value pairs is used instead.  In each case, hcOPF provides a solution to eliminate all the boiler plate code you might use to populate a TComboBox or similar control with such values.

Static Values

If the Key/Value pairs are small in number and static then an array of ThcKeyValue pairs can be declared as such:

MaritalStatusKV :array[1..2] of ThcKeyValuePair = (('S','Single'),('M','Married'));

Then simply use the ThcComboBoxKVMediator in the binding for the TComboBox that displays the MaritalStatus on the form and in the FormCreate event, use the following class method call to populate the control:

ThcTComboBoxKVMediator.LoadItems(cbMaritalStatus.Items,MaritalStatusKV);

In the Database

If the Key/Value pairs you need to use reside in the database, its just as easy.  In a TDatamodule, drop on a ThcLookupList component.  Enter a SQL select statement that would give you the result set you want, and then enter the KeyField and ValueField.  In the form where you need to validate input, use a ThcTComboBoxLookupListMediator.  Choose the LookupList you dropped on the datamodule, the control and the attribute and you’re done.  The control will automatically be populated when the form is streamed in. Remember to choose the ForeignKey attribute for the attribute to bind since hcOPF automatically populates key information prior to saving objects.

The cool thing about this component is that it dynamically creates MetaData from the select statement you enter.  All the columns in the select statement are added to the ThcObjects used to populate the TStringList.Objects, so if you need to use more than a simple Key/Value pair in the object, it’s still a breeze.  For now, if the Key value is Null, the ThcComboBoxLookupListMediator automatically selects the first item in the list.  This may not be the desired behaviour, so a custom mediator may be required.

There still needs to be some design-time work done for this component, but it’s functional and available now in SVN if you want to check it out.  Only D7 projects have been updated with some of the latest changes.  I haven’t checked out how the JEDI deal with syncing multiple projects across Delphi versions yet…

hcOPF - Dynamic Attribute Properties

Tuesday, July 6th, 2010

One pending improvement in hcOPF is that mediators need to take on the responsibility to get the control to indicate in a consistent fashion that an attribute is required, read/write or readonly.  Currently this is handled using RTTI by the ThcUIObjectBinder when the object is bound.

Objects are bound only once when a form is shown, so each control is only ever updated once to reflect the properties of an attribute.  This can be a problem when you have an attribute whose value you generate a default for in new objects, but allow the user to change it, and for existing objects is ReadOnly.  The way to handle this currently in hcOPF is contrary to the way I’ve typically seen it handled in a Delphi application with non-data aware controls.  Normally the developer would interrogate the object or attribute for it’s status and change the UI control appropriately.

In hcOPF the framework does this for you, most of the time, but in this scenario it cannot.  The reason is that ThcAttributeDef.Properties contain the ReadOnly property and they were never designed to be changed dynamically.  The ThcAttributeDef has no knowledge of the attribute to which it’s attached to prevent circular references, and minimize memory usage.  All ThcAttribute instances created from the ThcAttributeDef have a pointer to the ThcAttributeDef so they can defer calls for information contained in the definition to that object, making it a many to one relationship.  I could have added a multicast event in a ThcAttributeDef.SetProperties method to notify all attributes using the ThcAttributeDef that a property change had occured, and then they could call their Modified method, but this would consume more memory and complicate things for essentially an edge case.

What’s the solution?

First of all, the ThcAttributeMediator you’re using must update the state of the control in the UpdateControl method.  None of the current mediators in the framework do so.  That’s about to change.

Then you need to update the ThcAttributeDef.Properties to include or exclude the apReadOnly property and force an update of the UI control attached to the attribute.  You can do this with a call to

hcObject.ObserverIntf.NotifyOfSubjectUpdate;

OR

UIObjectBinder.GetAttributeBinding(’SomeAttribute’).Mediator.UpdateControl;

OR

since Mediators references are stored in the Tag property of each UI control, this would also work:

(TObject(edSomeControl.Tag) as ThcAttributeMediator).UpdateControl;

The last two calls will be more efficient as it will only update a single control, where the former updates all controls attached to the subject.

In addition you will have to toggle the Enabled property of the control (if applicable) since the current implementation of ThcUIObjectBinder toggles it to False for ReadOnly attributes.

Expect some major changes in the ThcUIObjectBinder and mediators soon…