Tuesday, April 07, 2015

Validating XRC

Overview

If you write your XRC files
by hand (which is probably relatively rare as most people prefer to edit them visually, but it does happen), and if you are human (which is probably not so rare), you are bound to make mistakes in them. Some of these mistakes result in invalid XML which give errors when loading the XRC file, some of them are not a big deal and are just ignored by the XRC parser, but some others can result in the layout mysteriously not working as expected, which can be annoying. Validating XRC files, i.e. verifying that they conform to the scheme describing all the valid XRC elements, allows to avoid all these problems at once, so it is strongly recommended to do it -- and this post will explain how, in details.

Setup

To validate them you need two things: a schema and a tool using it. The schema exists in our repository since October 2013 and is also available at the public URL http://www.wxwidgets.org/wxxrc. As for the tools, anything supporting compact RELAX NG schema syntax can work, but in practice this seems to limit the choices either to the online validator at validator.nu (Edit: this validator can't be used for validating XRC currently as RELAX NG support seems to be broken) or the original command-line validator, written by James Clark, one of the persons behind RELAX NG, called Jing, and the offline version is, unsurprisingly, much more useful as it can be integrated into the build process or used as part of pre-commit hook checks easily, so this is the one we are going to look at.
The latest Jing release is available from Google Code, but as the entire site will be closing soon, it might not work any longer by the time you are reading this, so here is the smaller and more up-to-date version. It is completely standalone and requires just a working Java installation, you can put the JAR file anywhere you want and simply run
$ java -jar /full/path/to/jing/jar
(in spite of the dollar sign indicating the Unix prompt, this works under Windows, too). The basic Jing command line syntax is just the schema file followed by any number of files to validate, however XRC schema uses the compact syntax which has to be explicitly selected by its -c option, so in the simplest case the full command line would look like
$ java -jar jing.jar -c $WXWIN/misc/schema/xrc_schema.rnc myfile.xrc
where WXWIN environment variable is supposed to contain the full path of your wxWidgets installation.
As an aside, it is also possible to avoid hard coding the path to the XRC schema, which may be important to make the validation step work on different machines. The natural way to do it would be to just use the canonical URI instead of the path to the schema, i.e. http://www.wxwidgets.org/wxxrc but currently this doesn't work, seemingly because of a bug in Jing handling HTTP-to-HTTPS redirections. The following command does work:
$ java -jar jing.jar -c https://www.wxwidgets.org/wxxrc myfile.xrc
but still has two problems: first, the URI is, formally speaking, wrong as it should be using "http" schema. Second, and probably more importantly in practice, it can be slow as the file needs to be downloaded from network every time. To fix this problem, an XML catalog mapping the canonical URI to a local file can be used. I won't pretend to know much about XML catalogs (because I don't), but here is a minimal one that can be used to set up the correct redirection:
If you save the above file as catalog.xml and adjust the value of the uri attribute to contain the correct path to xrc_schema.rnc on your machine (notice that triple slashes are needed), you should be able to use
$ java -jar jing.jar -C catalog.xml -c http://www.wxwidgets.org/wxxrc myfile.xrc

Using (or not) Custom XRC Elements

After the setup describe above you can use the standard schema xrc_schema.rnc to validate the contents of all the standard XRC elements, such as <sizeritem> or <object class="wxButton">. However any custom elements are simply ignored by default because the standard schema has no knowledge of them. Of course, you might not have any custom XRC elements at all. In this case, you should use xrc_schema_builtin_only.rnc, located in the same $WXWIN/misc/schema directory of your wxWidgets installation, to forbid any of them from appearing. There is no canonical URI for it, so you should simply pass full path to it on Jing command line.
The more interesting case is when you do define some custom XRC handlers. In this case using xrc_schema_builtin_only.rnc would result in errors about invalid value of attribute "class" for all your custom elements, so you need to define a custom schema describing just them. An example of doing it is shown in misc/schema/README, but here is an even simpler custom schema:
This schema allows appearance of a custom Frobnicator window-like (because of stdWindowProperties inclusion) element which can have one specific (but optional, because of the trailing *) num_times attribute, i.e. would validate the following XRC fragment: if you issue
$ java -jar jing.jar -C catalog.xml -c frob.rnc frob.xrc
command. Of course, the same fragment would also be accepted by the standard schema, the real benefit of using a custom one is that typos in either "Frobnicator" or "num_times" would be detected only by the latter.

TL;DR Summary

Your easy guide to XRC validation:
  1. Download jing.jar
  2. For one-time validation of only standard XRC elements just run
    $ java -jar jing.jar -c https://www.wxwidgets.org/wxxrc myfile.xrc
  3. For repeated use, download XML catalog, edit the file path in it and run
    $ java -jar jing.jar -C catalog.xml -c http://www.wxwidgets.org/wxxrc myfile.xrc
  4. If you use custom XRC elements, consider defining a schema for them too, it is simple to do.

Thursday, March 12, 2015

Attributing the contributions

One of the lesser, but still appreciable, benefits of switching to Git is that now we can properly record the author of the commit (e.g. the author of a patch), in addition to the (less important) person who committed it (e.g. me). While we tried to do this manually in the change log before, this couldn't be done for all the changes as the change log only mentions the most important ones and, sometimes, could be forgotten even for those changes for which it should have been done.

With Git, things are much more straightforward and you just need to provide your identity with your patch. The simplest way to do it is to use git format-patch command -- after ensuring that your name and email are correctly configured locally, of course. But you could also just mention them in your Trac ticket or wx-dev email and we'll use them when committing your changes (note for committers: you can always set GIT_AUTHOR_{NAME,EMAIL} for a particular commit to set the authorship information by hand).

Looking forward to your patches -- which will be now properly attributed to you instead of boosting my own commit stats!

Wednesday, December 31, 2014

A year in wx

2014 hasn't been the most exciting year for wxWidgets -- among the recent years this honour certainly belongs to 2013, which finally saw the release of the long, long awaited 3.0 release. However quite a few things still happened during it.

First of all, thanks to Bryan Petty, we now have a new shiny web site which not only looks much better, but is also simpler to update and to contribute to.  And it was duly updated more often, in particular to announce two new releases (3.0.1 and 3.0.2) last year, which is two more than we typically make per year.

Second, after a two year hiatus, wxWidgets was part of Google Summer of Code again this year and we had 6 students working on several interesting projects, admittedly with various degrees of success. But work done by Alexandru Pana on Direct2D support, by Chaobin Zhang on new Windows Vista/7 taskbar features, Sun Boxiang on wxUniv/X11 and Mariano Reingart on wxQt port was already merged into the trunk and we hope to merge Haojian Wu's work on Chromium backend for wxWebView before the next release.

Third, in 2014 we welcomed a new member to wxTeam: Artur Wieczorek has started by submitting many important improvements to wxMSW and then also volunteered to become the maintainer of wxPropertyGrid control and has since improved it as well. Thank you Artur!

Other than that, life continued as normal in 2014 with 1678 commits in master and 375 bugs fixed (compared to 1471 and 332 in the previous year).

What are we looking towards in 2015? Definitely a 3.1.0 release and almost certainly a 3.0.3 one. With luck, 3.1.0 will include a new and reworked AUI version. On infrastructure level, after upgrading the web site, the next long-awaited change is officially migrating to git from svn. Finally, we hope for as many contributions from the community in the next year as in the last one, thanks to all (too numerous to list here, sorry!) who submitted patches or sent us bug reports and please continue to do it!

Thank you and happy New Year!


Saturday, October 25, 2014

Being busy without being ugly

wxBusyInfo is one of the classes that it is actually best not to use at all, because it blocks the program UI without allowing to dismiss it, so it is hardly user-friendly and usually performing the long-running operation in a separate thread and providing some way to display its progress and cancelling it in the main GUI thread is strongly advised.

However sometimes doing it is too difficult or maybe even impossible if you are using third-party libraries and in this case wxBusyInfo provides a very simple way to at least indicate that the program is busy, using it is as easy as creating an object on the stack:


wxBusyInfo wait("Working, please wait...", parent);


Unfortunately, traditionally, it was not just very simple, but very ugly as well, as can be seen on this screenshot:

After the recent changes, you can show to the user something more presentable (especially if you use a decent icon):
and with only slightly more effort:

wxBusyInfo info
(
    wxBusyInfoFlags()
      .Parent(parent)
      .Icon(wxArtProvider::GetIcon(wxART_PRINT))
      .Title("<b>Printing your document</b>")
      .Text("Please wait...")
      .Foreground(*wxWHITE)
      .Background(*wxBLACK)
      .Transparency(4*wxALPHA_OPAQUE/5)
);


As you can see, now it's possible to specify quite a few more attributes than just the unadorned message:
  • There can be an optional icon in the top part of the window.
  • Message is now split in the "text" and "title" parts, with the latter shown in bigger font by default.
  • Both text and title can contain markup.
  • Background and foreground colours can be specified.
  • Finally, the window can be made partly transparent.
To avoid passing all these parameters directly to wxBusyInfo constructor as one unintelligible jumble, a new helper class wxBusyInfoFlags was added to allow specifying them all by names and to make it simple to add more attributes later than needed.

So while the initial advice to avoid the use of wxBusyInfo in the first place remains valid, you can at least make it less ugly now if you do have to use it.

Monday, October 06, 2014

Outdated configure in original 3.0.2

Due to my mistake, 3.0.2 source archives contained an out of date version of configure from 3.0.1. The new archives have with the fixed version have been uploaded now, please redownload if you are using Unix (or configure with MSYS or Cygwin under Windows) and had already downloaded one of wxWidgets-3.0.2.{7z,tar.bz2,zip} files.

Sorry for the inconvenience!

3.0.2 Released

We have just released wxWidgets 3.0.2, please see the announcement for the download links. There is nothing particularly exciting about this maintenance release, but it does fix quite a few bugs and so upgrading to it is recommended to all 3.0 users -- there are no drawbacks to it, as the new release remains both API- and ABI-compatible with 3.0.0.

To give slightly more details, the fixes were mostly in wxMSW, quoting from the change log:

  • Fix background of wxRadioBox buttons and wxSlider.
  • Fix appearance of wxToggleButtons with non default colours.
  • Fix drawing on wxDC when using right-to-left layout.
  • Fix wxGrid appearance and behaviour in RTL.
  • Fix creating wxBitmap from monochrome wxIcon or wxCursor.
  • Fix handling of bitmaps with alpha in wxImageList.
  • Add paragraph spacing attributes support to wxTextCtrl.
  • Show new style directory selector even for non existent paths.
  • Fix order of radial gradient stops.
  • Fix font created using wxFont(wxFontInfo()) ctor.
  • Fix wxFileName::GetShortcutTarget() in console applications.
  • Fix wxFileName::MakeRelativeTo() for shortcut files.
  • Fix height of initially empty wxBitmapComboBox.
  • Fix setting label of submenu items.
  • Fix using Esc as accelerator in the menus.
  • Fix wrong initial status bar height in some cases.

And there are also build fixes for Cygwin 1.7, for MinGW 4.8 (we now work around the bugs in its headers) as well as improvements for MSVS projects: the ones for 2005 and 2008 now also include x64 configurations, while the ones for the later versions now reliably build when using parallel build.

In wxGTK, wxSearchCtrl was fixed and doesn't truncate the text and icons inside it any more. There were a few changes in wxOSX as well, including a fix for the use of wxPreferencesEditor.

Finally, in spite of the focus on the bug fixes, there are also a couple of new features in this release:

  • wxDateTime::Format() now support POSIX %V, %G and %g format specifiers for week-number formatting.
  • XRC handler for wxSimplebook was added.
  • It is also now possible to specify the window variant (normal, small, large, ...) in XRC.
  • wxGenericListCtrl::EndEditLabel() was implemented, for consistency with the native wxMSW version.

As always, please let us know about any problems with this release and we hope you will find it useful!

Tuesday, September 23, 2014

GSoC 2014 summary: wxX11/Univ improvement project

The work of Sun Boxiang on improving wxUniv and notably wxX11 port has been merged into the trunk. This was mostly a bug fixing project and as the result of, many more unit tests now pass in wxX11 test suite than before, we're down to "only" 16 failures in 539 tests compared to 80 out of 308 before the project beginning. One new feature also implemented during this project is the new implementation of wxClipboard for X11. See Sun's summary of his work for more details.

Unfortunately there still remains quite a bit of work to be done before wxUniv can really be considered to be ready for general use, but at least know we know better what is missing or broken. In wxX11, there is some major work to be done on event loop code refactoring, to allow reusing the same logic as for the other Unix ports. We should probably also switch to using Cairo instead of the old style X11 drawing functions. And at wxUniv level, we really need a better theme with nicer appearance.

Unfortunately we, the current wxWidgets developers, just don't have any possibility to work on it, so there is no time frame for any of the above, but any contributions from people interested in using wxUniv (e.g. for writing applications with a particular appearance using a custom theme) would be very welcome!

Thursday, September 11, 2014

GSoC 2014 summary: Windows task bar API project

This is the first in a series of posts about wxWidgets GSoC 2014 projects and it is about Chaobin Zhang's work on wrapping Windows taskbar API for the use in wxWidgets. The project was a success and I'd like to congratulate Chaobin and thank him and Bryan Petty, who was the mentor on this project, for their work!

The new API additions and things they allow to do are described in more details in Chaobin's own post here, please read it for more information, but, in short, almost all taskbar features are now accessible via wxWidgets API.

Of course, they still remain unportable and Windows-only and while it's better to provide access to them than not do it at all, the main goal of wxWidgets is to facilitate writing portable applications and so the next target is to build a higher level API which would be available elsewhere. We have made a start with wxAppProgressIndicator and wxGA_PROGRESS style for wxGauge using it, but this is still not implemented for any other platform yet. Any contributions implementing this (simple) class in terms of NSProgress under OS X or ideas about how it could be implemented under Linux would be very welcome.