Community
Participate
Working Groups
The SWT DateTime Widget is not very comfortable and does not support a null value, but provides a nice DatePicker. The Riena DateTextWidget on the other hand supports a null value, but does not have a DatePicker. So It would be nice if we could combine the best of both Widgets and add a DatePicker to the DateTextWidget. To show how this could be accomplished, I will add a patch with a proof of concept.
Created attachment 146277 [details] Snippet to show DatePicker in Riena DateTextWidget Adds a DatePickerComposite to the UIControlsFactory and show some other ways to accomplish a DatePicker Textfield in Riena.
Created attachment 146278 [details] Patch for the DateTextRidget to use with the DatePickerComposite
Created attachment 146871 [details] Patch + Snippet + Example Adds a DatePicker to the DateTextRidget.
Hi Steffen, thanks for the patch. Looks fantastic! I've committed the patch. I've also a few things I'm curious about and would like to discuss: FYI - I've renamed the snippet to SnippetDateTextRidget003. I thought this is more consistent with what we have. (I'm also adding a link to it on the wiki) FYI - I've added a dispose method to the DatePicker class and connected it with the disposal of DatePickerComposite. Normally one does not have to worry much about disposing, as long the widgets are contained in the parent composite or shell. Obviously the DatePicker class falls out of this rule, since it lives in a separate shell. For background information refer here: http://www.eclipse.org/articles/swt-design-2/swt-design-2.html FYI - I've renamed UIControlsFactory.createTextDatePicker(...) to createDatePickerComposite(...). I think it's more consistent, since we also have ChoiceComposite / createChoiceComposite(). I hope you agree. Questions 1. What is the purpose of this code in DateTextRidget$DateVerifyListener line 233 ? // FIXME if (e.text != null && e.text.length() > 1) { forceTextToControl(control, e.text); e.doit = false; return; } 2. What is the purpose of this code in DatePickerComposite line 168 ? (see also #3) // ignore clicks on the header if (e.y < 45) { return; } 3. What is interesting for me on Vista is that I can click on the header a go back, i.e. from day to months, to years, to decades, etc. If I click once inside the picker it goes away immediately instead of going in the reverse direction (i.e. decades, years, months, day). This is different than the standard behavior of DateTime. Was that something you were trying to avoid with the code from #2 ? 4. It seems that DatePicker only supports dd.MM.yyyy while the DateTextRidget can have several formats, for example MM.yyyy or dd.MM.yyyy HH:mm. What happens / should happen in this case (snippet below) ? Do we need support for other locales formats? DatePickerComposite textDatePicker = UIControlsFactory.createDatePickerComposite(shell, "test"); IDateTextRidget datePickerRidget = (IDateTextRidget) SwtRidgetFactory.createRidget(textDatePicker); datePickerRidget.setFormat(IDateTextRidget.FORMAT_MMYYYY); At a minimum I would expect an exception, to alert developers this is not supported. Even better would be to support at least the common date variants (see IDateTextRidget.FORMAT_XXX). Greetings from Portland, Elias.
Hi Elias, #1: Normaly In the DateVerifyListener only one character at a time gets processed, but if I set a String like "01.01.1970" on the Textfield a complete date has to be processed and setText has to be called with the complete DateString. #2: To close the DatePicker every time the User clicks on the DatePicker, I added a MouseListener to the shell. But to ensure that the Shell stays opened, when the User clicks on the header I added this code. This is probably not the best way to solve this problem, but it works. Maybe we will find a cleaner solution in the future. #3: I don't understand what you mean. #2 just ensures that the DatePicker does not closed, when the User clicks on the header. #4: At the moment the DatePicker does not support all available formats from IDateTextRidget. The DatePicker supports the formats: DDMMYY ,DDMMYYYY, DDMMYYYYHHMM. We will need some polishing at this point to support all formats. At the Moment it would be a good idea to throw a Exception, if an unsupported format gets supplied, like you suggested. Best regards, Steffen
Created attachment 147354 [details] Flash movie showing issue #3
Created attachment 147358 [details] Snippet for issue #4
Hi Steffen, thanks for the infos. See my detailed response below. #1: The code beneath the // FIXME introduces a problem, because it accepts ANY text as long as it is longer than 1 character. This violates some assumptions of the DateTextRidget - for example that the text is never longer than the pattern. This happens together with circumstances described in #4 below. I'm suggesting a different approach below. #2: I'm sorry, but I don't yet understand what you mean :-). What is this header? Is it be something XP or MAC specific (I'm on Vista) ? Maybe a screenshot would help. Personally, I see a problem with "e.y < 45" because it will not work for all platforms or even for different themes applied to the same platform (larger / smaller fonts). However I would like to understand what the header is first... :-) #3: See the attached flash movie. The problem is that the regular DateTime allows 'zooming-in/out' of a time range. The DatePickerComposite only allows zooming out but not zooming in. #4: "The DatePicker supports the formats: DDMMYY ,DDMMYYYY, DDMMYYYYHHMM." -- From my POV it seems that only DDMMYYYY works. Here's what I observed using the attached Snippet288354_4: - using DDMMYY on the ridget will throw an ArrayIndexOutOfBoundsException. This would happen after using the picker and then selecting everything and pressing backspace. The issue here is that the text from the DatePicker is DD.MM.YYYY which is longer than DDMMYY. I've checked in an Assert that makes it clearer sooner. - using DDMMYYYYHHMM will leave the hour and minute fields empty. Since this is backed by a Date (i.e. point in time), I would have expected that these are filled out as well. Could you please look at the following: #1 + #4: There are two issues with the current approach: bypassing the ridget validation with the FIXME-code and the DatePicker not being aware about the pattern in the ridget. Here is one idea for fixing this: using a Strategy-Pattern to make the code that get's executed when the user picks a date pluggable. The strategy would have a method like setDateToTextField(Date date). The default strategy would to what is currently done in setDateToTextField(...) - which does not need a ridget at all. The ridget could replace this with another strategy specific to the DateTextRidget: it would take the Date, use a DateToStringConverter(pattern) with the pattern from the ridget and uses ridget.setText(...) to set the text. After this we could remove the FIXME-code and it automatically would support all possible patterns. Let me know what you think or feel free to suggest something else :-) #2: Need more info :-) #3: Can you investigate #3 ? Not sure what can be done. Thanks and kind regards, Elias.
Created attachment 147404 [details] Screenshot showing the DatePicker on Windows XP Shows the DatePicker on Windows XP. The red bordered part on the top is what I call the "header". Every time the user clicks on the calendar it self and not the header, I want to close the DatePicker. Thats why I checked if "e.y < 45" to detect where the user clicked and close the DatePicker. Maybe you have a better idea how to accomplish this.
Created attachment 147434 [details] Patch for Issues #1 and #4 Adds a DateConverterStrategy to the DatePickerComposite to delegate the DateConversion to the DateTextRidget.
Hi Steffen, I've tested the new patch. I like the approach taken, but there are two issues that should be resolved before we can close this bug: 1. Exception with partial format: To reproduce: Enter 01.01 in the second text field. Open picker -> exception. My suggestion is to fill out missing information using the current date. I.e. year missing -> 2009, month missing -> 10, day missing -> today's date. This should also work for hours & minutes. 2. Timezone issue - the conversion results Date being adjusted for the current timezone - it should be neutral (i.e. the same as with dateTime). To reproduce: use SnippetDateTextRidget_TZ -- Note my timezone is UTC-7. Your results will be different. Pick 7. Oct with the first picker -> 7.10.2009 hh:dd (console) Pick 7. Oct with the second picker -> 7.10.2009 hh+7:dd (console) -- in de propably hh-1 Both pickers should give the same result.
Created attachment 149329 [details] Snippet for issue #2
Created attachment 153975 [details] Patch addressing remaining issue Commiting to HEAD. @Christian: request permission to commit this to 1.2.0 as well. It addresses the last issues with the DatePicker: - exception when entering incomplete date before opening picker (i.e. "12. . ") - timezone issues (previously the timezone was added to a date that was already in the current TZ) - closing the widget too soon when using the header (comment #4 issue 3 / .swf movie)
+1 go ahead
Resolved in HEAD + 1.2.0