In System Settings / Regional / Date & Time we allow users to customise the Date and Time fomats used throughout KDE, a handy feature. Problem is the configuration is not very user-friendly, have a look at what I mean:
So we have some editable combo's allowing the user to either select from a few standard layouts or to type in their own layout. But what are the valid componants of a layout that the user can type in? It's not immediately obvious, and there's no help available I can find. I had to go look at the source code to find out. OK, we could fix that with some tool-tips and help doco, but it's a process still prone to error, the user is allowed to type in anything no matter how invalid or incomplete and it just gets treated as display text. It's how Windows still does it, surely we can come up with something simpler and more usable?
Well, as you might guess, Apple did. Have a look at their Date format 'editor':
All you do is drag some Elements around (those blue 'bubbles'), type any text you want in between and you're done, no knowledge of format codes required. They have something similar for time formats.
I would love to have a generic widget that does this in KDE for use in the Date and Time formats in System Settings and in the panel clock settings. Where else could we use something like this, any ideas? Problem is, I haven't a clue how to do the gui for this, I'm a plumber, not a painter, if you catch my drift. So anyone want to have a crack, or at least give me some pointers where to start? Anyone know of an existing widget I could adapt? We already have the KWin buttons editor which does something similar, but it lacks the line edit functionality.
The generic widget would combine a special Line Edit widget and a Pallette widget. The Line Edit would allow any text to be entered and edited and validated exactly as a standard KLineEdit. The Line Edit could also be a combo if we wanted standard formats available for easy selection. Element 'Bubbles' can be dragged from the Pallette onto the Line Edit and dropped in position, or dragged off to remove them. Once in place in the Line Edit, the Element Bubble would be treated exactly as any other glyph, i.e the cursor moves around them and they can be deleted or backspaced to remove them. API would allow the client to add Elements to the Pallette as required, setting the Element Label text, Element Example text (as goes in the Bubble), and Element Format text. Calling text() would return the contents of the Line Edit with the Element Bubbles replaced by their Element Format text equivalent. Accessability would require that either each Element has a key shortcut to insert it in-line, or that typing in the Element Format magically changes it into the Element Bubble. This makes me think that what the Line Edit requires is code to recognise when a particular text substring has been entered and replace that textual display with a graphical 'Bubble', and an API to give it the Example and Format text pairs. The drag-and-drop action would then be simply to insert the required format text and the Line Edit would convert it itself. I'm guessing the hard part is displaying the Bubble in place of the text and getting the cursor to treat it has a single entity.
In System Settings and the Clock widget, we could then simply have the current format displayed read-only with a little Wizard button next to it to launch the widget, keeping the config guis nice and clean and simple too.
Any suggestions / volunteers?
Or can someone come up with an even more user-friendly way than Apple?
Little tip I picked up the other day that I've never seen documented elsewhere. If you have a git clone of Qt and you're constantly switching between divergent branches such as master and qt4.6-stable, or following a fast changing branch, you will eventually run into compile issues where it looks like the build is broken because of missing headers or symbols and even a 'make clean' or './configure' doesn't solve it. Try run ./bin/syncqt to see if that solves your problems, this is a script that apparently fixes up all the installed qt headers and stuff like that. It took me a while to discover this, I actually deleted my local repository and re-cloned a couple of times in the mistaken belief that I had horribly corrupted it. Perhaps it could be added to the Qt Gitorious wiki that a 'git pull' or 'git checkout' should always be followed by a './bin/syncqt' to be safe?
Anyone else with any useful tips like this when hacking on Qt?
Hey, I'm actually finally getting my head around all this git stuff...
I promised an update on printing and here it is.
Just to recap, the branch at http://qt.gitorious.org/~odysseus/qt/odysseus-clone/commits/advanced-page-selection contains the Advanced Page Selection features such as Current Page, Odd/Even Pages, Server Side page selection, and non-continuous Page Ranges. The status of this is that it's API complete with just some polishing work required in the Unix dialog, although there are a couple of implementation details I'm reconsidering as being too ugly.
My next step was to add in support for file printing which you can find at http://qt.gitorious.org/~odysseus/qt/odysseus-clone/commits/print-from-file. This is useful for applications such as Okular where they have a high quality source file and don't want to paint it onto a QPainter (and possibly reduce the quality in the process) before printing it. This is a simple API where the application passes in the name of the source file to be printed, and if the filetype is supported by the print system the file gets printed using the settings from the QPrinter (and thus anything the user selected in QPrintDialog). Under CUPS you can print PDF, PS, TXT and various image formats while lpr will support just PS and TXT. It's still a little hacky in places, such as the filetype detection, but it works. And for the more observant of you, yes this will make a new kprinter utility a lot easier for someone to implement.
I've also made a start on adding all the available CUPS options into the Unix QPrintDialog. At the moment KDE adds these as extra aplication-level tabs on the dialog, but they are poorly integrated, e.g. choosing 'Print to File' doesn't disable them. The code for this is still very rough and so still rather ugly, but I've attached screenies below showing some options in a new Pages tab in the main dialog, with others in a new Job tab in the Properties dialog. Yes it looks just like the current KDE stuff as I've recycled the code I wrote for that. I must confess the more I try to mess with the QPrintDialog, the more tempted I am to re-write it from scratch, it shows obvious signs of cruft building up over years of having bits bolted on by several different people.
Last time I mentioned that the Qt 4.6 feature freeze was looming. Well in fact it had already long gone whizzing past with no-one much noticing, so sorry but these changes won't be in Qt 4.6 or KDE 4.4. This whole open Qt development thing is very new and the processes aren't really in place for contributing features (as opposed to bug-fixes) and I guess there's a few lessons to be learnt along the way. I should have been more pro-active in talking to the Trolls about the how and when, so lesson one is if you have a new feature grab your nearest passing troll and don't let go until they let you cross the bridge to graze in the summer pasture, er I mean until your stuff gets merged. From the Qt side I guess there needs to be more structure and documentation around the steps developers need to follow to propose, design and develop new features, who do you talk to first, what are the release schedules and milestones you need to meet, and what you need to include (unit tests, cross-platform support, documentation, etc).
It has been suggested that my patches could be packaged into Qt4.6 by some distros, but this is not going to be possible as I cannot guarantee that the API/ABI will remain unchaged through the Qt review process, or even that they will be merged for Qt 4.7.
However all is not lost as I have been able to re-use some of what I've done to add Odd/Even pages and Server Side page selection for KDE 4.4 using CUPS. Using a very very ugly hack, I've added the Odd/Even selection combo into the QPrintDialog and this gets passed through to CUPS if selected. A less ugly hack has also added Server Side page selection where CUPS will select the page range when the application can't, i.e. Kate and Khtml and all apps that embed them (KMail, Konqi, KWrite, etc) can now print page ranges! The main drawback is this only works under CUPS, and it doesn't intergate well, i.e. the Odd/Even combo doesn't disable when you choose 'Print to File' so we'll get plenty of bug reports that it doesn't work with 'Print to PDF'. However I think the users need for this outways the shortcomings. Also be warned that using them in conjunction with n-up will get unexpected results due to a quirk in CUPS where it applies the page selection to the sheets of paper and not the document pages. Screenie below showing KWrite with Odd/Even selection added and Page Ranges restored.
As an aside, I've been thinking about how to make kate and khtml support page ranges properly. At the moment they just paint the whole document as they don't know where the page breaks will be until after they have actually painted the content onto each page. Trying to calculate this in advance and to pick up the painting mid-stroke is I believe a very tricky proposition. Instead, I was thinking we could have two identical QPrinter's, a dummy QPrinter onto which the first few unwanted pages are painted, then once the first required page is reached a second 'real' QPrinter onto which only the required pages are painted. Not sure if it's feasible, but worth a crack?
Of course, the obvious perfect cross-platform solution would be if QPrinter itself directly supported page selection, i.e. you paint all the pages onto QPrinter then tell it which ones to keep and it deletes the rest internally before passing the document to the native print system. Something else to look into.
[Edit: fixed references to QPainter to be QPrinter]
So, where to from here? There's obviously going to be a bit of time now before these possibly make it into Qt 4.7 (whenever that may be), so I'm going to re-arrange my priorities. We have the KDE 4.4 feature freeze coming up next month, so I'm going to focus for a bit on doing some Calendar and Locale related hacking for that. Then for the Qt 4.6 release I need to work on some bug fixes for the current printing code. After that, and depending on when 4.7 is rumoured to be released, I'll get back onto finishing off all the above and also trying to sort out the situation with saving settings between jobs. And in-between all that, I need to get back in touch with the OpenPrinting guys to work out how KDE can help them in their quest to completely re-architect the way we do printing.
I haven't posted for a while, mainly because I've barely been home and rather busy for someone supposedly unemployed. Just after my last post one of my sisters arrived from back home in NZ to stay for a month, so I spent a week hanging out with her around London, before I went on an archaeological dig for 2 weeks. Archaeology is another passion of mine, I go digging several times a year and study part-time at uni with some thought of merging my digger side with my geek side as a career.
This dig was on an octagonal-shaped Roman bath house in Kent, complete with plunge pool, hypocaust, drains and lead piping (cue plenty of Life of Brian quotes...). It's only the third of it's kind found in the UK, there being only 70 or 80 examples across the rest of Europe. Not as exciting as the cemetary earlier in the year, but it was a real puzzle trying to sort out the different phases. Lots of hard physical labour shifting piles of dirt in the blazing sun, some delicate trowel work, and way too much drinking in the evening made for a great break from the usual geek lifestyle. 3G reception was non-existant so the net addiction abated for a while :-) Below is an aerial shot of the site using a boom mounted camera.
After the dig I took off to join my sister on her holiday in Croatia and Greece, with a couple of quick detours through Bosnia and Italy along the way. The weather was fantastic, sunny and 26-30 degree, and Croatia is a great country to visit. I only got to see Split and Dubrovnik and the coast in-between, places I've dreamt of since reading about them in a Hardy Boys adventure as a kid, so it's somewhere to definately go back to later.
All through this time I was trying to keeping up a training schedule for my first ever half marathon, which I ran last Sunday. Unfortunately things didn't go well and I finished about 30 minutes slower than my training times suggested, which means I'm going to have to figure out what went wrong and try it again in a few months time.
So, life is finally returning to semi-normal and I can get back into the important things, like deciding what I can hack on for KDE before the feature freeze kicks in, and I guess I should do something about finding a job. Thanks to a couple of fellow KDE hackers, I have talked to a couple of FOSS/Qt companies but unfortunately the opportunities didn't really fit. The contract market is still very dead, especially in the financial / mainframe sector I know best and it could be a while before something suitable comes along, so I'm starting to look at other options.
Next posts, I'll fill you all in on the status of printing, and what I've been doing with Calendar Systems and the Plasma Calendar.
I hear that Qt 4.6 goes into feature freeze at the end of this month, so that's like in 1 working days time. Eeep! I'd better get those printing changes pushed upstream then. Is there some official place where such dates are advertised I should have been watching?
I've pushed the latest version of my code to a new Gitorious branch http://qt.gitorious.org/~odysseus/qt/odysseus-clone/commits/advanced-pag..., and I may just have to put in a merge request even though it's not quite done. First the screenie:
As you can see I now have an editable range field that allows you to enter multiple page ranges, in addition to the Page Set and Current Page stuff I'd previously added. This will show up for all applications that enable it, or if you are running Cups as your print system, i.e. 99.99% of you out there. If you don't have Cups, then you get the traditional From/To page range entry. This is not enabled on Win or Mac as yet, but it should be possible and I've designed it so it can be added without altering the API and so it gracefully degardes to the maximum feature set supported by your platform without the app programmer having to do anything.
Status is that I think this is API complete and stable, the only thing missing is the validation of the Page Range input by the user and some other small clean-ups of the dialog layout (yes, that radio button glitch visible in the screenie is proving a pain to solve).
Like I said, I'll probably put in a merge request for this now and worry about patching the remaining issues later. I think I should also have the File Printing under Unix feature done in the next day, so that may also make it. Less likely are the additional Cups features (n-up, banners, job control, etc) depending on how far I get this weekend (but we already add those ourselves), and the rest like saving/restoring settings and virtual printers will have to wait for 4.7 (or the new OpenPrinting dialog, whichever comes first).
So I cloned the Qt master repository on Gitorious as odysseus-clone a few months back, and then cloned odysseus-clone onto my laptop where I've been working away happily. Now I want to make sure my work is still OK against the latest master before doing a merge request, so I think I need to update my odysseus-clone on gitorious first to the latest master, then do a fetch/rebase to update my local clone, then push my changes up to Gitorious.
Thing is, I can't for the life of me figure out how to get my odysseus-clone on Gitorious to update to the current master. Any clues? Or have I got this all wrong? 1am is not the best time to be trying to figure this out :-)
I know, I know, I'm supposed to be working on the Print Dialog, but I've reached a tricky part and while my brain ticks away on that in the background I thought I would do something a little more fun. Seeing as I'm the 'official' maintainer for Calendar Systems (i.e. I was the last person to work on them...), and to be part of the cool crowd hacking on Plasma, I thought I'd have a crack at fixing the Plasma Calendar and Clock widgets to allow the users to select which Calendar System to display, just like you can currently choose which timezone to display. Long story short, here's what I now have:
So that's the four different supported Calendar Systems (Gregorian, Hebrew, Hijri, Jalali) all being displayed at once in separate Calendar widgets. Hmmm, I wonder if we need a label at the top of the widget to show which Calendar System is being displayed?
And again, but this time in four Digital Clock widgets. The left-click pop-up calendar from each obviously also shows the correct Calendar System.
There's a common configuration widget used in both the Digital Clock and Calendar widgets. In 'Use Calendar System' you can choose from Local, Gregorian, Hebrew, Hijri, or Jalali, where Local is the default and will use whatever the Locale setting is. The Holidays settings are the same as currently available in 4.3, but obviously you could choose to have different holiday regions on each Calendar or Clock widget.
Right-click on a Digital Clock widget and you can choose a 'Copy To Clipboard' menu option to which I've added the date in other Calendar Systems.
There's still a little polishing to be done, especially on the Digital Clock to sort out some date format localisation issues on the main widget and the copy menu, but look for this to pop-up on ReviewBoard in the next day or so. I've got some thoughts on other improvements especially for Holidays, and there's a fairly long bug list in bko, but I'll get this sorted first.
Oh, and while I have my official maintainers hat on, could I just remind developers that you can't use most of QDate's methods like formatDate() or addMonths() as these only work on the Gregorian calendar system. To ensure your KDE app localises the Calendar System displayed and performs the right date maths on it you need to use the methods provided by KCalendarSystem through KGlobal::locale() and KGlobal::locale()->calendar(). QDate is essentially only a storage medium that KCalendarSystem then interprets for you. OK, the API is not very friendly and definately longer to type, but that's the way it is until either Qt5 or KDE5 comes along with Calendar System support built directly into QDate / KDate (and yes Trolls, that is an offer to help write it the correct way :-)
[Edit: For some reason comments were turned off, back on now if you want to add soemthing :-)]
With Page Set (Odd/Even) and Selected Page done for X11, I thought I'd skip the OSX/Win stuff for now (it was doing my head in) and get the Advanced Page Range completed on X11 So here's my design for supporting user enterable non-continuous or broken page ranges such as "2,5-9,11".
[Just a reminder SimplePageSelection mode is designed to be 100% compatible with the existing API and apps will use these by default without having to be modified, an app has to be modifed to explicitly set AdvancedPageSelection mode to fully activate the new features and use PageList() to obtain the pages to print].
In SimplePageSelection mode, when CUPS is not available the Range edit will not be displayed but the From/To edit will. The application will generate all pages between From and To and LPR will print all pages sent to it.
In SimplePageSelection mode, when CUPS is available the Range edit will be displayed, but will be validated to only allow strictly ascending non-repeating document page numbers as this is all CUPS supports (we could allow random order as CUPS sorts it first, but that would just mislead the user). The application will generate all pages between From and To which are set to the lowest and highest page in the Range. Qt will then adjust the Range to tell CUPS to ensure the correct pages are printed. (Note that CUPS actually applies the Range on Output Pages, not Document Pages, which is why we need the adjustment, and why applying n-up at the same time produces results other than the user expects).
In AdvancedPageSelection mode the Range edit will be displayed and the user will be allowed to enter the page numbers in random and duplicated order and have those pages printed in exactly that order, e.g. "5,2,9,3-7,11-4". The application will generate only the required pages in the required order and CUPS will print all pages sent to it.
Note that this means a user can enter a Range of "20-10" and have the pages printed in descending order, but if they also select the Reverse option at the same time the pages will come out in ascending order. Slightly confusing but the only consistent way of dealing with it.
For Win, the native dialog does support an editiable Range and will be supported later on.
For OSX, the native dialog does not provide an editable Range and so will always default to the standard From/To range regardless of what mode the app sets.
This scheme provides the user with the maximum amount of functionality available at each level, but I am concerned about the inconsistancy between the Simple/CUPS and Advanced modes combination which users will use side-by-side depending on the app. This is because some apps may never be able to set Advanced mode, for example Kate and Konqueror don't really know about pages so may find it very difficult or inefficient to generate pages out of order by themselves. Users could become confused by this inconsistency between apps without realising why they behave differently, but dropping the Simple/CUPS mode will prevent apps like Kate from printing broken ranges, and restricting the Advanced mode to only ascending pages would remove a useful feature.
So what do people think, which is better, consistency or features?
[Note to self: log and fix bugs in both Kate and Konqi which leave the From/To page range enabled in the print dialog when they in fact always ignore the users input and print the entire document].
Do people also think it would be useful to continue to display the From/To Page Range entry at the same time as the Range edit entry? Or would it just clutter things up?
I plan to use a RegEx with QRexExValidator to validate the users input into the Range line edit, but I haven't written a RegEx in years, so thought I'd ask the experts out there to have a look. The general rules are as follows.
A valid Range is made up of one or more valid Sub-Ranges separated by commas, with no commas allowed at the start or end.
A valid Sub-Range is one of the following (where n is a number from 1 to MAXINT)
- n- [equivalent to n-MAXINT only allowed as final Sub-Range]
- -n [equivalent to 1-n only allowed as first Sub-Range]
And here's my attempt which I've yet to test to see if it even works:
Suggestions welcome, just remember it needs to be maintainable :-) Note I'm using \d for digits so we get support for the different number sets we support, but it means I have to do an additional validation step afterwards for n!=0.
Hey all you GSOC bloggers, I'm really enjoying all your blogs about the really cool stuff you're doing, it's real exciting to see what you're up to, and I'm more than just a little bit jealous. But could an old memory-challenged fogey ask one small favour? Could you just include the title of your GSOC project and the application at the top of your posts, with so many of you about it's a bit of a struggle to remember who's working on what, and it's not always immediately clear from the post contents.
Congrats to all of you for passing the mid-point review, and be sure to stick around afterwards, it's great to see so many new faces making such solid contributions to the community.
So I'm home from a fantastic 8 days at GCDS in Gran Canaria and a cultured but boiling hot weekend in Madrid. There's so much to say about the experience, and so much to do as a result, but those will be for another blog. Since getting home it's been going downhill rapidly. Late flights, work production issues seeing me pulling 13 hour days, then to cap it off I get a call from my agent this morning to say my employer is terminating my contract effective end of this month. It's not a total surprise given the current climate, but what $@%$£% me off is that my coward of a manager who's away on leave today didn't have the guts to tell me himself yesterday when he had ample opportunity. Forget it being unprofessional, you just don't treat other people that way.
So I'm back in the job market again and its not a good time to be looking. If you know of anyone looking for an old-school mainframe programmer / designer / tech lead in the London area with experience in the banking, telco, and energy markets, then drop me a line. Or if you're really really really desperate for a C++ hack (I wouldn't deign to label myself a programmer)...
Then again, this is the same disorganised outfit that rang me at 3pm on 24th December while I was at the pub enjoying my leaving drinks to offer me a contract renewal, so who knows what will happen.
Well, look on the bright side, I'm soon going to have all the time in the world to hack on KDE and Qt printing:-)