*********************************************************************** * * Application Notes * ================== * * Module: ClickDate.prg Rev 1.70 10.Jul.2003 * Category: Program, Popup Calendar * * Purpose: To provide a date selection solution satisfying the * return requirements for a date Get or Sle field, or a * date variable. * * Author: Greg Doran, Dublin Ireland * *********************************************************************** * * Copyright (c) Greg J Doran. 2001-2003 e-mail: GDO@eircom.net * * This code is released under the GNU General Public Licence * and is governed by the conditions and protocols setout therein. * * The code is provided "as is", without warranty of any kind, * either expressed, or implied, including, but not limited to, * the implied warranties of merchantability and fitness for a * particular purpose. The entire risk as to the quality of this * software, its use or misuse, modified or otherwise, lies with * you, the recipient. * * *********************************************************************** * * You are free to use this code as you wish but please retain * the copyright and the above text in all program code used. * *********************************************************************** * * Syntax: ClickDate(xDate, oOwner, oDateField, lTopDown) * * xDate can either be Text as in CtoD(date()) or a * dDate value or may be omitted altogether. * * TopDown users should set lTopDown true if using TopDown code * for the date field. * * Usage: * * Return a date to a Date Variable; * --------------------------------- * dDate:= ClickDate([],oOwner) * * Return a date to a date get field; * ------------------------------------ * oGet:lbDblClick := {| MP1, uNIL, o| clickdate(o:editbuffer(),oDlg,@o)} * * Return a date to a date Sle field; * ------------------------------------ * oSle:lbDblClick := {| MP1, uNIL, o| clickdate(o:editbuffer(),oDlg,@o)} * * Top-Down user's Note: * ===================== * You may use Clickdate in a bWhen codeblock in a tdDEget(). * It sets o:editbuffer() and returns the logic value .T. * bWhen:= {|o| clickdate(o:editbuffer(), oDlg, @o, .T.)} * If the get is the only active edit field on the form you * can only activate the calendar once using a bWhen. * (You can't re-trigger the bWhen without exiting the get * and re-entering.) * * Date: ClickDate will accept invalid data from an Sle edit buffer * and ignore the input. It will return a valid date if one * is selected, otherwise on Escape or Close [X] it will * set the Sle edit buffer to " / / ". * * If the input is Character, clickDate performs a validation check * on the data input and uses " / / " if it is invalid. * * Both the Sle and Get are treated identically even though the * editbuffer content is cText in one case and a dDate in the other. * The ClickDate code accepts either, and sets the o:editbuffer() * with the appropriate VarType on selection. * * The date (or empty buffer content) is sent to Clickdate when the * Sle or Get is DoubleClicked. this means you can edit the field * locally without the Calendar activating. * * Owner: Because Clickdate() is using a Modal dialog it is desireable that * you nominate the calling dialog (oDlg) as the Owner of the ClickDate * modal dialog, particularily if it is itself a Modal. * * Do not use a Groupbox or Static or DrawingArea as the owner, it must * be the Dialog. Sure, it will work if you don't nominate the calling * oDlg, but you risk a problem arising and unpredictability. * Anything from the user being able to click the Get/Sle field a * second time while the calendar is active to a total system freeze. * This is not a problem with ClickDate, if you don't handle Modal's * properly you invite trouble. * * oDateField: * For a Get or Sle the Get or Sle object must be passed by * reference. There is minimal checking in this regard so if * you pass a non-Get/Sle oVar you will definitely get an error. * * * lTopDown: * The TopDown Date field shows [01 02 2003] instead of [01/02/2003] * if this is not set True, and, if there is error trapping looking * for a space in o:editbuffer you get an error; otherwise it is ok. * * This is because the TopDown o:editbuffer field looks like a string * buffer but, because it is a date field, it expects a Date Var. * Without lTopDown = .T. a character string is returned. * * For Top-Down users there is a section at the end of this file * that describes how you can modify Top-Down Code to enable the * use of a Down-Arrow Button (Alt+DownArrow) in conjunction with * a Get to invoke the calculator. * *********************************************************************** * * Picture Keys: * ============= * [-] Minimise, just drops to Icon on bottom left of screen. * [x] Close without section * [8] Little calendar - returns/moves to Todays date. * [/] Tick mark - Select this date and exit. * [C] Open circular arrow - 'undo' return to orginal date on entry * [?] Help key, when activated has a / through it (toggle). * * ************************************************************************ * * * Configuration: * ============== * * The Calendar is fully configurable to use multiple languages and or * background colours / bitmaps. See important note below. * * The current default is English. The only difference between English * and US-English is the date formatting. The routine operates using * the Set Date British format and switches the returned value to the * locale set in ClickDate.ch. Do not change the British format in the * routine, unless of course you want to give yourself unnecessary * work going through the entire routine making changes where appropriate. * * Not being an expert in languages, not even my native language!, * the addition of other languages is entirely up to you. The * ClickDate.ch file has a template for you to customise the calendar * to the language of your choice. * ********************************************************************** * * IMPORTANT * ========= * ENTER YOUR LANGUAGE DEFINITIONS IN ClickDate.ch and... * IN ClickDate.PRG make changes as follows: * * AFTER: * ------ * #include "xbp.ch" * #include "Appevent.ch" * #include "Gra.ch" * #include "common.ch" * #include "dll.ch" * * AND BEFORE #INCLUDE CLICKDATE.CH * -------------------------------- * ACTIVATE YOUR LANGUAGE DEFINITION DEFINED IN CLICKDATE.CH * ---------------------------------------------------------- * // #define USENGLISH // USEnglish * #define ENGLISH * //#define GERMAN * // define LANGUAGE: SPANISH, ITALIAN, PORTUGUESE etc. * * ================================================================ * NOTE: ClickDate.CH MUST _FOLLOW_ YOUR LANGUAGE DEFINITION * ================================================================ * #include "ClickDate.ch" * * * * Special Character Sets * ======================= * If you need to display apserated or special characters such as * the umlaut, grav or sina fada you may need to uncomment the * line "SET CHARSET TO ansi" * * Also, some character sets require the use of the * #pragma Library( "XppUi2.lib" ) which needs to be uncommented. * * * ************************* END * TopDown Users only....... ********************************************************************** * * Top-Down: Use of Alt+DownArrow Button on Get. * * Code Modification and Implementation * ********************************************************************** * * Normally Alt+DownArrow is used in Top-Down to access a Dropdown * ListBox attached to a Get. This method makes use of the existing * Alt+DownArrow feature in TopDown code to enable the calendar. * * * In your program code to include a DnArrow button you use code as * follows: * * ***** tdDEget_03 * oDlg:oGetDate := tdDEget(4.0,46.5,fieldWblock("Dated","Datafile"),; * oDlg, oDa,10,cPeriod,bValidDate,bWhenDate,,,,.T., ; * "9.Courier New",.T., 8, , , , ,.F.,6) * * oDlg:oGetDate:setData() * aadd(oDlg:aAllGets,oDlg:oGetDate) * aadd(oDlg:aEditGets,oDlg:oGetDate) * * ***** Create button and send activity to the Get key handler * ***** The Get keyhandler will do what it has to and pass the * ***** nkey back to the local keyhandler here as it is not a ListBox. * oVBttn := tdPshBtn(4.0+0.1,46.5+8,1.6,oDa,chr(54),; * {|| oDlg:oGetDate:Keyboard(xbeK_ALT_DOWN) },,.F.,; * '10.Marlett',,,17) * * ***** If the user clicks on the button while another Get has focus, * ***** the calendar will be shown and receive focus. So we must * ***** notify the DE window that this Get is now the active one. * oVBttn:SetInputFocus := ; * {|| iif(oDlg:oGetDate:editable,oDlg:oActvGet := oDlg:oGetDate,nil)} * * * The 0.1 added to the 4.0 and the 8 added to the 46.5 positions the * DnArrow button centrally at the right side of the get which in this * case is at 4.0,46.5 * *========================================================================= * * * In your Keyhandler code, e.g. DEKeys() add the following: * * * ELSEIF nKey == xbeK_ALT_DOWN // Invoke Calendar * * ClickDate(oDlg:oGetDate:EditBuffer(), oDlg, @oDlg:oGetDate, .T.) * oDlg:oActvGet := oDlg:oGetDate * SetAppFocus(oDlg:oGetDate) * * Obviously if you have more than one date get on a dialog you will need * to set a flag to determine which get is to be activated. * * This will not interfere with a Listbox attached to a Get as the key * xbeK_ALT_DOWN will be trapped by tdcDEGet:keyboard() code and will * never appear in your local Keyhandler. * * ======================================================================== * * For the calendar Get to receive the xbeK_ALT_DOWN key you need to make a * small modification to tdcDEget:Keyboard() in tdcDEget.prg * * * These notes have been taken directly from the revision change block * of a modified tdcDEget.prg * * IN METHOD tdcDEget:Keyboard() * * PLACED THE FOLLOWING CODE BETWEEN * * ENDIF // keys * AND... * ENDIF // useList * * EFFECTIVELY: * * IF ::lUseList * * IF nKey == xbeK_ALT_DOWN * ... * ENDIF // keys * * ****** Begin Addition * ELSE * * ***** Its not a Listbox * IF nKey == xbeK_ALT_DOWN * * ******* Pass this keystroke to the parent dialog key handler * postAppEvent(xbeP_Keyboard,nKey,,::oParentDlg) * * ENDIF * * ***** End Addition * * ENDIF // useList * ************************************** * REASON FOR CHANGE: ************************************** * * In conjuction with Active Get program code, this enables * the use of a DownArrow button bound to a Get which responds * to Alt+DnArrow when a listbox is not the object activated. * In this instance it is a popup calendar on a date get. * **************************************************************************** *