All posts by Theo Neeskens

Do I need to compile this?

Over the years many Uniface developers have created tools on top of the Uniface Repository.

One tool that has been made by many, is one that looks for “dirty” objects: objects that were modified after they were last compiled successfully.

In Uniface 9 such a tool would have been based on comparing the fields UTIMESTAMP (modification date of the source) and UCOMPSTAMP (compilation date of the source) of various Uniface Repository tables.

In Uniface 10 this has changed, mainly to align the repository with the export format that has been optimized for version management:

  • The modification date of a development object source is only found in the main object. And yes, it is also updated when you change a sub-object. So if you change a modeled field, the UTIMESTAMP of the entity is updated.
  • The compilation date of a development object is no longer an attribute of the source code. It does not have much value to know when the source was last compiled, if you can’t be sure that the compiled object was the result of that compilation. Someone may have copied a different compiled object to the output folder. The only real compilation date is that of the compiled object (file on disk or in a UAR).

Uniface 10.3 is the first release of Uniface 10 that is shipped with meta definitions: the new DICT model is published. So now you can re-engineer the tools that you made for Uniface 9.

In order to make it easier to (re)write a tool, the $ude(“exist”) function has been enhanced to return the attributes of the compiled object (file on disk or in a UAR) such as the modification date.

Compiling objects because their source code has changed

It is not just components that require compilation. There are 14 types of development object that require compilation and generate a file in your resources.  I have attached a sample tool that checks whether these objects are “dirty” and therefore require compilation.

The tool gathers the source modification date from main development objects, and the compilation date of the compiled objects. In some cases, one main development object (such as a message library) results in many compiled objects (messages).

The tool uses $ude(“exist”) to check the compilation timestamp of the compiled object and $ude(“compile”) to compile it.

The attached export file contains a full project export, so when you open project WIZ_COMPILE, you will see the whole thing.

You can download the export here: prj_full_wiz_compile.zip Feb 06
And here is a file with some test data for each object type: prj_full_wiz_compile_testdata.zip Feb 06

You will need the Uniface 10.3 DICT model to compile the tool. The new DICT model for Uniface 10.3 is delivered in umeta.xml in the uniface\misc folder of your development installation.

PLEASE NOTE: The sample tool does NOT take into account that a component may require compilation because a modeled entity or an IncludeScript has changed. See below.

Compiling components because a modeled entity has changed

Please note that the attached sample does NOT check if a component requires compilation because a  modeled entity has changed. If you had this check in your Uniface 9 tooling, you also need to implement it in your new tooling. 

A Uniface 9 based example for this issue can be found here:
http://theunifaceuniverse.blogspot.nl/2011/04/change-entity-compile-forms.html
You would need to simplify this for Uniface 10 because the modification date is only on the main development object.

Compiling objects because an IncludeScript has changed

Please note that the attached sample does NOT check if a development object requires compilation because an IncludeScript has changed.

To implement this is quite tricky, as you would have to find the #INCLUDES within the IncludeScript code, and handle the fact that they can be nested. To correctly parse all of that might not be much faster than just compiling everything…

Loading loads of Glyphs

As a software developer, every once in a while you find yourself performing a tedious manual task for some hours. As it seems to be something you need to do only once, it does not seem to be worth automating the task. But then later it turns out that you have to do it again. So you make a quick and dirty tool. And then later a colleague has to do the same thing and asks if you have an efficient way of doing it. So you make your tool a bit nicer so people other than you can use it.

For me this happened for the task “load a very large number of image files into Uniface Glyphs”.

So here I present you my tool.

It allows you to select a folder on your disk, then it presents you all the files that are in the folder. You select the files you want to convert and press the button. Occurrences are created in the Uniface Glyph table. Files in an unsupported format are marked yellow, Glyph names and descriptions that are too long are also marked in yellow. Make your changes and press the next button and all your Glyphs are stored and compiled.

Now we can perform a task that used to take hours in a few minutes. (Admittedly you don’t have to do this very often but it is really boring task when you do need to do it!)

The attached Uniface export is for Uniface 9.7. With some adjustments it should also work with older Uniface 9 versions. You need to have a DICT model in your repository (have umeta.xml imported).

http://unifaceinfo.com/download/6470/

Disclaimer:

This tool is not part of the Uniface product and therefore not in support. It also uses some code that is not officially supported and that is subject to change without notice. Please feel free to change the tool to your own requirements.

Glyphmaster

NB:
Have a look at what I did around the selection of the folder:

  • You can either type the name,
  • Or select it from a dialog when you press the button,
  • or select it from your history using the dropdown.

 

Modernizing Uniface 9.7: The Buttons

In this final episode of the story about modernizing the Uniface 9.7 IDF in 10 easy steps I will explain how we changed the look of the buttons.

button teaser2

If you want to start reading from the beginning part 1 and 2 of the story can be found here:
The first post was about the changes to the start page.
The second post was about the work that was done to make the screens white.

Again, in theory, it should be possible to do this by just changing a few properties in a configurations file. But as you will see it takes a bit more effort to do it in a nice way in an existing Uniface application. Don’t get me wrong, even with the additional work it still was not much effort to do it.

The small tools that I made to make my life easier are available for download, but:

DISCLAIMER

The tools described in this posting are not supported Uniface software. You can download them and use them, modify to your own taste and use them at your own risk. You need the DICT model to be present in your repository before you can compile and use the tool. Be absolutely sure you have a backup of your dictionary before using any of these tools! You can download them here:

http://unifaceinfo.com/download/5737/

When you make an improvement to these tools that might be useful to the community please share it.

Step 7 Determine types of buttons

Goal

Now that we changed the color of the Forms and fixed what was needed for that, we focused on the Command Buttons. The requirement was to use flat buttons.

In theory you would only need to change the properties for the Command Button in the .ini file for that. But we have different types of buttons in the IDF and we do not want to style them all in the same way. So we wanted to split up the Command Button in five logical widgets.

Logical Widgets

The first step was to split all buttons into groups and create logical widgets for them in the .ini file so they can styled as a group. These are the logical widgets that we used for the buttons:

IDFButtonBottom, for the big text buttons at the bottom of Forms
IDFButtonBottomIDFButtonBottom=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;frame=off;font=IDFButtonText;labelfont=IDFButtonText;backcolor=#01A7E1;backcolorselect=#97D5EC;backcolorhover=#55C1E8;backcolorfocus=#0084CC;forecolor=white;forecolorselect=black;vsize=80;autolabel=F;position=center;valign=center)

 

IDFButtonSide, for the big text buttons at the right-hand side of Forms
IDFButtonSide
IDFButtonSide=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;font=IDFButtonText;labelfont=IDFButtonText;backcolor=#01A7E1;backcolorselect=#97D5EC;backcolorhover=#55C1E8;backcolorfocus=#0084CC;forecolor=white;forecolorselect=black;vsize=80;autolabel=F;position=top)

Nearly the same as the bottom buttons.

 

IDFButtonSpecial, for the buttons that do not fall in any of the other categories
IDFButtonSpecial
IDFButtonSpecial=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;frame=off;font=IDFButtonText;labelfont=IDFButtonText;backcolor=#01A7E1;backcolorselect=#97D5EC;backcolorhover=#55C1E8;backcolorfocus=#0084CC;forecolor=white;forecolorselect=black;vsize=80;POSITION=CENTER)
Most of these buttons are somewhere in the middle of the window and need to look like a Bottom or Side Button. So we set the most common properties here and overrule them in the Forms when needed.

 

IDFButtonImage, for the very small buttons with an image on them, like the >> button
IDFButtonImage
IDFButtonImage=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;frame=off;transparency=T)
Here we make the button disappear, leaving just a clickable image.

 

IDFButtonHeader, for the buttons that form the headers of simulated grids
IDFButtonHeader
IDFButtonHeader=ucmdbutton(representation=Header;cursor=uhand;halign=left;valign=center;font=label)
These buttons are simple Windows header buttons.

Since flat buttons and clickable images may not look clickable to people who are not used to them, we added cursor=uhand to each button so the mouse arrow changes to a hand when you go over a button.
hand_pointer

Tool

Splitting the Command Buttons in these five logical widgets was a lot of work so I made a tool to assist in this mostly-manual step. I used the tool to query for fields with a Command Button widget, and in another window I looked in the IDF what new logical widget it should be. The main advantage of the tool for this step was making sure that I did not miss any buttons.

The tool is called U97_FRMWIDGETS. You can enter a retrieve profile and then work on the properties of the found painted fields. You can delete a property regardless of its value, or only when it has a specific value. You can also Add (or replace) properties in four ways: apply it to all records, do not replace existing values, only replace existing values, only replace a specific existing value. You can also apply a new widget type to all records.
U97_FRMWIDGETS

Step 8 Match modeled widgets with painted widgets

Goal

In the previous step we determined what painted button should get which new logical widget. But the Development Environment also uses buttons that are modeled in dummy entities in the application model. We want to give them a new logical widget too.

Challenge

You would expect that a modeled button is always used for that same purpose. But in an older application, such programming standards have not always been followed. So now one button in the application model needs to be represented by multiple logical widgets. The only affordable solution was to change the logical widget in the model to the one that is most often used for this button in the Forms.

Tool

The tool and the SQL that I used for this step was of such a ‘quick and dirty’ quality that I will not share this one with you. But it did the trick anyway, and you can easily come up with something similar (or better!)

Step 9 Set the properties on the painted buttons

Goal

We have split the buttons in logical groups by using logical widgets. Now we needed to remove the local properties so they do not override those set in the .ini file.

Widget property inheritance

Challenge

It would be simple if we could just delete all properties of all buttons, but that was not feasible as there was a mix of properties that should be the same on each button and of properties that are specific for a certain button.

Tool

I used my tool U97_FRMWIDGETS from step 7 to remove all properties except ROLE and VSIZE from the IDFButtonsBottom. And I removed all properties except TOOLTIP and VSIZE from the small image buttons. This now allows us to control all other properties from the .ini file.

Step 10 Set the properties on the modeled buttons

Goal

For the modeled buttons we also needed to remove many properties. As they often did not have properties on the Form, the properties from the Model took precedence over the .ini file instead.

Widget property inheritance

Challenge

The challenge was to efficiently change the properties of modeled buttons.

Tool

The tool is called U97_MODWIDGETS. It is similar to the tool of step 7, but acts on a different entity of the DICT model. For more details see step 7.

U97_MODWIDGETS

Conclusion

We here at Uniface B.V. have a big Uniface 10 project running to change the architecture of the Uniface Development environment. But we still wanted to do a very small project to freshen up the appearance of Uniface 9 as well. I think we succeeded in that, thereby proving that it is affordable to apply some lipstick to an existing Uniface application.

Wishes

Making the background of all screens white showed up some things in our GUI that can be improved in the future.

  1. The frames and sizes of our widgets are not fully consistent. That was nicely camouflaged by the grey background of the forms, but it shows more clearly on a white background.
  2. The new entity frame properties work fine and allow you to really spice up your application. We will get a blog post up on this soon. But in a multi-occurrence situation, where the entity is made to look like a grid, there is room for further development. There is no room for the frame, causing some visual imperfections.
  3. We have buttons that used to have an image on them in Uniface 7, but not since then. These are still image buttons. In previous Uniface versions that was not a problem as we used a Windows representation for the buttons and that ignores the image. But in Uniface 9.7 we use flat buttons with a Uniface representation and there the image prevents correct centering of the text. We could not find an affordable risk-free solution within the scope of the project so we decided to deliver with this imperfection in place. We will let you know when we have a good approach for this.

These and some smaller issues have been logged during the project and have been put in our backlog for resolution at a later date according to priority.

I hope these posts on how we changed the look of our Uniface application were useful for you. Have fun modernizing your Uniface application!

With kind regards,

Theo Neeskens

Modernizing Uniface 9.7, Part 2

In my previous post, I started explaining what we have done to give the Uniface Development Environment a fresh look.

The previous post was about the changes to the start page.

This post is about the steps that were needed to make screens white. In theory that can be done by changing just one setting in your .ini file. But in real life there are always some small differences between theory and practise.

old_new

The small tools that I made to make my life easier are available for download, but:

DISCLAIMER

The tools described in this posting are not supported Uniface software. You can download them and use them, modify to your own taste and use them at your own risk. You need the DICT model to be present in your repository before you can compile and use the tool. Be absolutely sure you have a backup of your dictionary before using any of these tools! You can download them here:

http://unifaceinfo.com/download/5737/

When you make an improvement to these tools that might be useful to the community please share it.

 

Step 1: Make the background of all Forms white

Goal

Making all Forms white can be accomplished by a simple change in the .ini file. Included in this step is altering the Application Shell, the Menu’s and the Panels so they look nice in combination with the white Forms.

[application]
shell=ushell(backcolor=#F9FCFF)

window=uwindow(backcolor=white)menu=umenu(backcolor=white;forecolor=black;backcolorselect=#0084CC;forecolorselect=white;backcolorfill=flat)panel=upanel(backcolor=white;backcolorhover=white;backcolorlocked=#55C1E8;backcolorselect=#97D5EC;bordercolorhover=#55C1E8;bordercolorlocked=#0084CC;bordercolorselect=#0084CC)

 

As you can see we made the Application Shell a very light blue for a subtle color difference between the Forms and the Application Shell. The Forms were given a white background. The Menus are now white with a blue selection color and the Panels are white with blue accepts. This was all done with properties that already exist in Uniface 9.6.

Challenge

In theory changing .ini settings should be enough. But unfortunately a small percentage of the Forms had either an index color or a foreground or background color set. That was never noticed before because these were set to the default grey background and black foreground. So after changing the .ini file these Forms remained grey. The challenge is to find all forms with a color and remove the color with minimal effort.

Tool

The tool is called U97_FORMCOLOR. When you press Retrieve it will show all Forms in your dictionary that have an Index color or form property color set. It uses your current settings in the [foreground]/normal and [background]/normal sections of your current .ini file to translate the index color to a foreground and background color.  It will also show what window color you have set in the .ini file. There are buttons to convert RGB to HEX colors and vice versa. It did not add a translation of Web colors as that was too much work and I did not need it. There are buttons to put the Index colors in the Window Properties and remove the Index color. One that only does that when there is no window property color and one that does it always. And there is a button to remove the property color when it is the same as the .ini color. Nothing gets stored until you press the Store button so you can play around a little.

Please feel free to change the tool for your own purposes.
U97_FORMCOLOR

Step 2: Remove the color from the painted entities

Goal

After step 1 we saw strange grey blobs on some of our nice white screens.

grey blob

Some of our painted entities had an index color or foreground or background color set, and were painted as markers for referential integrity or other technical reasons. To be precise these only show up when they are painted three or more character cells wide. We needed to remove these colors as well.

Challenge

The challenge is to find all painted entities on all forms that have a color set and to remove the colors with minimal effort. Using SQL is not an option as the index color for the painted entities is stored in the paint area (FORMPIC).

Tool

I build a small tool to search for a painted entities with a color with a few additional buttons to manipulate or remove the color. Since the Index color of a painted entity is stored in the form paint tableau I had some fun deciphering and manipulating that.
The tool is called U97_ENTCOLORFRM. When your press Retrieve it will retrieve all painted entities that have an index color or an entity property color set. On a large dictionary this can take some time as it have to search the paint areas (FORMPIC) for the index colors. All buttons have the same function as the previous tool.
U97_ENTCOLORFRM

Step 3: Remove the color from the modelled entities

Goal

After step 2 we unfortunately still saw grey blobs.
grey blob
Some entities had a foreground or background color set in the Application Model (no index color there), and were painted as markers for referential integrity or other technical reasons. These colors needed to be removed as well.

Challenge

The challenge is to find all entities in all models that have a color set, and remove it with minimal effort.

Tool

The tool is called U97_ENTCOLORMOD. It searches for modelled entities with a color and has a few additional buttons to manipulate or remove the color. It works very similar to the previous tools. The differences are caused by Entities in the Application Model not having Index colors.
U97_ENTCOLORMOD

Step 4: Visibility of Grids

Goal

A Grid always has a white background and on our now white Forms it was not so clear to see what area a Grid was occupying on a Form.
grid_noborder
We needed borders around the Grids.

In Uniface 9.7 there are new properties that you can use to give the Grid widget a border:
·         BorderType
·         BorderColor
·         BorderWidth

We want to apply BorderType=Flat and BorderColor=Silver to all painted Grids.
grid_border

Challenge

The challenge is to find all painted Grids, and to apply the change with minimal effort.

Tool

The tool is called U97_GRIDBORDER. This one was kept very simple. It just retrieves all entities that are painted as Grids and has a button to add properties to them.
U97_GRIDBORDER

Step 5: Multi-occurrence entities

Goal

This was an issue that was specific for our project but I have included it since in your application you may want to update properties of non-Grid entities too.

Earlier we removed the color from all entities, but in the Development Environment there are multi-occurrence entities that need to look similar to Grids. Since Grids do not follow the background color of the Form but always stay white we had to make these multi-occurrence entities consistent with that.

ent_noborder

Like in Step 4, a white data area on a white form does not look so good without some kind of border. So we wanted to add new properties for the entity frame too.

In Uniface 9.7 there are new properties for the default entity:
·         BorderColor
·         BorderType
·         BorderRadius
·         DropShadowColor
·         BackColorStart
·         BackColorFill
·         GradientStart
·         Attach
·         AttachMargin

We want to set BorderColor=Silver and BorderType=Flat on all non-Grid, multi-occurrence entities.

ent_border

Challenge

Finding the all painted entities that are not using a grid widget and are painted with a vertical repetition of occurrences. This information is stored in the form paint. Apply BorderColor=Silver and BorderType=Flat to those entities.

Tool

The tool is call U97_MULTI_OCC. When you press retrieve it shows all entities that are painted with an occurrence repetition and that is not a Grid. It can be a bit slow on large dictionaries as it needs to look in the paint area of the Form for each painted Entity. The functionality is simple, just a button to add some properties to all painted entities found.

NB: We are aware that in this first release the frame does not look quite right yet when a multi-occurrence entity is painted to look like a grid, as there is no room for the frame.  An alternative for your application could be to give the entities and the form background different colors.

In the next (final) post I will explain what we did with the buttons.

button teaser