Subject Re: KMDATEWITHCAL (dUFLP)
From Ken Mayer <dbase@nospam.goldenstag.net>
Date Tue, 20 Mar 2018 13:58:24 -0700
Newsgroups dbase.getting-started
Attachment(s) kmDateWithCal.cc

On 3/20/2018 12:33 PM, Mustansir Ghor wrote:
> Dear Ken Sir
>
>  From below message , can we download again from dUFLP in order to get updated program
>
> I did some tinkering (also the next version, when you click a day, the
> calendar will collapse/close, not sure why I didn't do that in the first
> place).

A slightly cleaner version (when the form closes, the calendar button is
reset ... the version I posted earlier requires two clicks to re-open
the calendar ... d'oh!). No need for a "close" button though, I had
forgotten that the calendar button next to the entryfield polymorphs
into a close button when you first click it.

Ken


--
*Ken Mayer*
Ken's dBASE Page: http://www.goldenstag.net/dbase
The dUFLP: http://www.goldenstag.net/dbase/index.htm#duflp
dBASE Books: http://www.goldenstag.net/dbase/Books/dBASEBooks.htm
dBASE Tutorial: http://www.goldenstag.net/dbase/Tutorial/00_Preface.htm



// Metric: 6 - Pixels only
/*
   File:   kmDateWithCal.cc
   Author: Ken Mayer
   Date:   January 30, 2017
   Updated: February 7, 2017 -- moved the language property to
      the kmDateWithCalendar class (with code to assign the value
      to the subform in the onClick for the pushbutton); and
      added the autoTab property -- if set to true, will tab to
      next control on the form (default is false) when the calendar
      closes.
      
            March 19, 2018 -- added some improvements -- clicking on
            a date, the "Today" button, or the "Cancel" button, and the
            subform closes, rather than leaving it open, with no apparent
            way to close it.

   In dBASE Plus 11 the controls look better on the subform, but this should
   work for earlier versions of dBASE as well. In Plus 11, we use the
   new pushbutton property "themeBackground", in earlier versions we use
   "systemTheme" ...

   There are two primary classes here:
      kmDateWithCalendar
      kmDTWithCalendar
      
   The first is an entryfield/pushbutton combination designed to be dataLinked
   to a date field in a table. The pushbutton opens and closes a calendar,
   which interacts directly with the entryfield (changing the date on the
   calendar updates the entryfield as you go).
  
   The second is the same but for a DateTime (or Timestamp) field. The biggest
   difference is that the DateTime version (kmDTWithCalendar) is that it has
   an option to handle the time part of the field on the calendar.

   The calendar itself is customizable through the use of a header
   file (kmDateWithCal.h). See notes below and in the header file
   itself.

   This file contains a lot of code just to handle entryfields with a
   calendar attached, but that is because the calendar itself takes a lot
   of code to handle what needs to be done. The code for the entryfield
   also takes a bit of work, although most of that is associated with
   the pushbutton.
  
   Usage:
      set procedure to :dUFLP:kmDateWithCal.cc
      
      Two items will appear on the Component Palette (if you have
      not run the setup for the dUFLP, on the "Custom" tab, otherwise
      on the "dUFLP Misc. Controls" tab). The instructions below are for
      both controls -- drag the one you want (kmDateWithCalendar or
      kmDTWithCalendar) to the form, making sure to manipulate the
      position by dragging the underlying container, not the controls
      *on* the container. You may see some other controls appear on the
      Component Palette ("Custom" tab), ignore them -- these will be:
          CalPushbutton and WeekDayText --
      these are not useful as independent controls, but I can't keep
      them off the Component Palette ...
      
      Set the dataLink for the entryfield to the field in the table you
      wish to link it to.
      
      Modifications:
      There are two properties of the control you may wish to change:
      
         language -- change the language -- see details in documentation
              below, and in the file :dUFLP:DateEx.cc.
              Details on the language strings can be found in the code at
              the beginning of :dUFLP:DateEx.cc, in the definition code
              for the associative array: asLang -- this is a long list,
              but you have to have the correct language definition as there
              needs to be an exact match on the text. Example: there are
              quite a few variations of "Arabic" in the list, you
              couldn't just use "Arabic", you would need to use
              the specific version: "Arabic (Saudi Arabia)" or
              "Arabic (Qatar)".
            Default: "English (United States)"  
            
            ***NOTE***
            This property only affects the month and day of week
            headings of the subform /calendar -- for any other language
            changes you would need to modify the file kmDateWithCal.h.
            
         autoTab  -- tab from the DateEF (entryfield) when the calendar
              subform closes, the default is to place focus on the
              entryfield. (This is at the request of Mervyn Bick.)
            Default: false
      
      To change either of these, in the form's onOpen event handler:
      
         function form_onOpen()
            form.kmDateWithCalendar1.language := "German (Standard)"
            form.kmDateWithCalendar1.autoTab  := true
         return
        
      Note: the form sets the form's doubleBufferred property to true,
      due to display issues of controls on containers.
      
      In addition, when the user clicks the CalendarButton, focus is
      set (briefly) to the DateEF control (the entryfield), which means
      if you wish to add some code for validation or an onLostFocus
      event handler, as soon as the Subform with the calendar appears,
      that code will fire. This allows you to hook in and add your own
      customized code. When the Subform is closed (by clicking the
      CalendarButton again), the entryfield regains focus, again
      allowing any additional code you may add to fire.
      
      There is (as noted above) an autoTab property you can set that
      will fire right after setting focus back on the entryfield,
      and tab to the next control on the form. The default setting
      is false.
      
   CONSTANTS:
      The constants used throughout the two primary controls
      are stored in "kmDateWithCal.cc" in the dUFLP, a copy is copied
      when you run the setup routine to whereever it is copied to
      for your version of dBASE and Windows. However, you should consider
      keeping a copy in the folder for your own application, if you wish
      to modify the values in the constants (language appropriate text
      for speedtips and the "Today" button, images for buttons, fontSize ...).
      Descriptions of the constants are noted here and in the pKenCalendar
      header comments below.
      
      When you compile the kmDateWithCal.cc class, then the constants
      in the header are included and accessible.

   CHANGING ENTRYFIELD COLORS / SPEEDTIP / IMAGES
       These constants are defined in kmDateWithCal.h
       EFNormalColor -- assigned to the Entryfield's colorNormal property
          Default: "WindowText/Window"
       EFColorHighlight -- assigned to the Entryfield's colorHighlight
          property, the color when it has focus:
          Default: "WindowText/0x80ffff"
       CalButton1 -- the Calendar Button when the calendar is not
          displayed.
          Default: "RESOURCE PNG/calendar :resources:dFugue_24.dll"
       CalButton2 -- the Calendar Button when the calendar *is* displayed.
          Default: "RESOURCE PNG/calendarexport :resources:dFugue_24.dll"
       CalBtnSpeedTip1 -- the screenTip for when the calendar is NOT
          displayed
          Default:
       CalBtnSpeedTip2 -- the screenTip for when the calendar *is*
          displayed.
          Default: "Click to close the calendar"

   When the form is run and the pushbutton is clicked, the entryfield
   will be linked to the calendar, and updating the date in the calendar
   will automatically update the value property of the entryfield. The "cancel"
   button will set the value property back to what it was to start with
   (if it wasn't empty). If the field is empty (a new record for example),
   the calendar will assign the current date to the value. If the user
   wishes the field to be left empty they would need to empty the
   entryfield (delete what is there). One could, of course, add a "delete"
   button next to the calendar button to empty the value property if one
   wanted to. The code would be simply:
       this.parent.DateEF.value := {}
   to provide a blank date.
  
   ENTRYFIELD CONCERNS:
      This code is set to set focus to the entryfield when the pushbutton
      is clicked, either direction (it needs to be clicked two different
      times, once to open the calendar, once to close it). The reason for
      this is based on something Mervyn Bick pointed out in the newsgroups,
      if you want to fire code like an onLostFocus event handler for the
      entryfield, it won't fire unless the entryfield has focus in the
      first place. This ensures that it has focus first. This could
      also be used to effect field-level validation (perhaps a date range,
      etc.). See information about the autoTab property above.
  
   IMPORTANT DESIGN NOTE:
      You will need to experiment to be sure your form is tall/wide enough for
      the calendar to display, as it becomes part of the form while it is open.
      Once you get the control on the form, try running it, click the
      pushbutton, and check to see if the whole calendar displays or not.
      
      This means it will be cut off at the bottom (or right) of the form if
      you do not plan for it. It may be possible to add a new property for
      where to display the calendar (right/bottom as options for example),
      but for the moment, this is the issue. The larger the font,
      the bigger the calendar, the more space needed ...
  
   WHAT IS INCLUDED:
   The following is a short breakdown of what is here.
             --------------------------------------------------
   kmDateWithCalendar:
   This is a container with an entryfield designed to be dataLinked
   to a date field in a table, and a pushbutton that will open
   a calendar control under the container.
  
   kmDTWithCalendar:
   As above but for datetime (timestamp) fields, rather than
   pure date-only fields.
  
   DateEF:
   Contained inside kmDateWithCalendar, this is the entryfield object
   used to dataLink to the table, etc.
  
   CalendarButton:
   The pushbutton used to do the work. Clicking this will set the
   calendar's currentDate property to the value in the DateEF entryfield,
   set a reference that the calendar control understands to the entryfield,
   so that when clicking dates, the value changes ... the calendar
   will open on top of anything else on the form, and when closed (clicking
   the button again, using polymorphism to do this -- changing the appearance
   and the code just a bit) will close the calendar. All of the calendar
   code below has a HUGE amount of documentation.
             --------------------------------------------------
   Calendar Code:
   pKenCalendarWithDate
   The container for the calendar. There are a ton of buttons and some
   text objects, as well as the code to deal with things.
  
   See the documentation for this class for details on customization
   (including colors, fontSize, fontName, language, images and text for
   speedTips, and so on ...)
  
   CalPushbutton
   A base pushbutton class with some shared properties for all pushbuttons
   on the container.
  
   DayPushbutton
   The pushbutton class used to define the days.
  
   WeekDayText
   The text controls above the days (S for Sunday, M for Monday, etc.).
             --------------------------------------------------
   Code not associated with classes directly:
   Points2Pixels() -- a function that does a basic calculation to convert
   fontSize (points) to pixels -- helps determine the size of the buttons
   and other controls as well as the calendar itself.
                --------------------------------------------------
   DEPENDENCIES:
   If you choose to use this set of code with your own application,
   there are a lot of dependences you need to be aware of.
  
   For the images:
   Note that the default images are using the .DLLs provided by dBASE in the
   :resources: source code alias. To find the exact path to these, check
   the Properties dialog in the IDE, find the "Source Aliases" tab, and
   the "resources" source alias. Click it, and the path will appear
   in the dialog. Example, for dBASE Plus 11, on my Windows 10 computer:
      C:\Users\Public\Documents\dBASE\Plus11\media\Resources
   This is important if you wish to deploy this application and wish to use
   the images provided. You would need to deploy:
       dFugue_16_1.dll
       dFugue_24.dll
   See below as well for other files needed.
      
   DEPENDENCIES (Important for deploying an application that uses this
   control):
    
       :dUFLP:DATEEX.CC
       :dUFLP:HOLIDAY.CC
       :dUFLP:TIME.CC
       :dUFLP:HEBREW.CC
       DUFLP.H   *shouldn't need to be deployed, as it would be compiled
                  into the file needing it (DateEx.cc, etc.)*
       :dUFLP:kmDateWithCal.h -- same as dUFLP.H ... shouldn't need
                  to be deployed
      
       If using the default images, if you change the images
       (which is an option) you would need to deploy those images
       in whatever fashion is appropriate:
       :resources:dFugue_24.dll
       :resources:dFugue_16_1.dll
*/

// Don't remove this -- it's vital:
#INCLUDE kmDateWithCal.h

class kmDateWithCalendar( oParent ) of container( oParent ) custom
   // NOTE: constants (for images and speedTips) defined in kmDateWithCal.h
   with (this)
      metric       = 6 // Pixels
      borderStyle  = 3 // None
      transparent  = true
      width        = 110.0
      height       = 30.0
      onDesignOpen = class::onDesignOpen
      onOpen       = class::Container_onOpen
   endwith
   // Language -- for use with the API calls in DateEx.cc, so we can
   // get the correct info for the month and day of the week --
   // see documentation in :dUFLP:DateEx.cc for details:
   this.language   = "English (United States)"
   this.autoTab    = false  // can be modified in code, used to
                            // tab off the entryfield when
                            // calendar closes
   this.type       = "Date" // don't change this
  
  
   this.DateEF = new ENTRYFIELD( this )
   with ( this.DATEEF )
      height         = 22.0
      left           = 2.0
      top            = 3.0
      width          = 79.0
      value          = {  /  /    }
      pageno         = 0
      colorNormal    = EFNormalColor
      colorHighlight = EFColorHighlight
   endwith

   this.CalendarButton = new PUSHBUTTON( this )
   with ( this.CALENDARBUTTON )
      onClick      = class::CALENDARBUTTON_ONCLICK
      height       = 26.0
      left         = 83.0
      top          = 1.0
      width        = 26.0
      text         = ""
      speedBar     = true
      upBitmap     = CalButton1
      scaleBitmaps = true
      pageno       = 0
      speedtip     = CalBtnSpeedTip1
   endwith
      
   function onDesignOpen
      // called from container's onDesignOpen:
      if form.metric # 6
         msgbox( "Form's metric property is not '6 - Pixels', "+;
                 "this will not display properly.", ;
                 "Bad Form Metric!", 16 )
         return
      endif
   return
  
   function Container_onOpen
      // force this so any display issues
      // are minimized:
      form.doubleBuffered := true
   return

   function CALENDARBUTTON_onClick()
      // a polymorphing button: meaning that it basically has
      // two states -- if the calendar is not displayed,
      // the button will display it when clicked, if the button
      // is displayed, the button will close it when clicked
      local oParent, oEF
      if type( "this.CalendarOn" ) == "U"
         this.CalendarOn = false
      endif
      // if it's not 'on', then display it ... ('this' is the pushbutton)
      if not this.CalendarOn
         this.CalendarOn := true // set it to true now
         // modify display:
         this.speedtip := CalBtnSpeedTip2
         this.upBitmap := CalButton2
         oParent = this.parent // container ...
         oEF = oParent.DateEF  // entryfield with date
         // instantiate the calendar:
         this.oCalendar = new pKenCalendar( form ) // setting parent to the form
         // Pass the entryfield object to a custom
         // property of the calendar:
         this.oCalendar.EF = oEF
         // set reference to this button for subform:
         this.oCalendar.Btn = this
        
         // set language property of the subform:
         this.oCalendar.language := this.parent.language
        
         // if the date entryfield value is empty, set
         // it to the current date:
         if empty( oEF.value )
            if oParent.type == "Date"
               oEF.value := date()
            else
               oEF.value := datetime()
            endif
         endif
         // set the calendar's currentDate property to the
         // value of the entryfield:
         this.oCalendar.currentDate = oEF.value
         // determine whether date or datetime
         this.oCalendar.type = oParent.type
         oEF.setFocus() // this would fire any onLostFocus or
                        // similar events
         // set the position
         this.oCalendar.top := oParent.height+oParent.top
         this.oCalendar.left := oParent.left
         // open the subform which fires off the code for
         // the subform's onOpen event handler:
         this.oCalendar.open()
      else
        // reset flag:
         this.CalendarOn := false
         // reset display:
         this.speedtip := CalBtnSpeedTip1
         this.upBitmap := CalButton1
         // set focus back to the entryfield:
         this.parent.DateEF.setFocus()
         // autotab (put focus on next control of form)?
         if this.parent.autoTab
            keyboard( "{Tab}" )
         endif
         // release calendar and cleanup:
         this.oCalendar.close()
         release object this.oCalendar
         this.oCalendar = null
      endif // not this.CalendarOn
   return // from CALENDARBUTTON_onClick
endclass

/*
   kmDTWithCalendar -- a copy of the above but designed for
   DateTime (or Timestamp) fields, rather than just date.
   This is a subclass of the kmDateWithCalendar class above.
*/
class kmDTWithCalendar( oParent ) of kmDateWithCalendar( oParent ) custom
   // NOTE: constants (for images and speedTips) defined in kmDateWithCal.h
  
   // the Container:
   with (this)
      width        = 160.0
   endwith
   this.type       = "DateTime" // don't change this

   // modify the value and width only of the entryfield:
   with ( this.DATEEF )
      width          = 130.0
      value          = {00/00/0000 00:00:00.00}
   endwith

   // the calendar button, modify the position
   with ( this.CALENDARBUTTON )
      left         = 134.0
   endwith
  
endclass

/*
   pKenCalendar -- calendar class used by kmDateWithCalendar
   entryfield/button combination, based on pKenCal3.cc in the
   dUFLP and massively modified ...
  
   Author  : Ken Mayer
  
            January, 2017 in an attempt to make a more flexible
            calendar by allowing the developer using it to determine
            font, fontSize, and so on I ended up creating a whole new
            "thing". While very similar to some other calendars,
            this one is meant to be more flexible, with an updated
            appearance.
            
            I have given this one the ability to define (see below)
            text for language specific items in the code more easily
            (except for holidays -- that's trickier) ... See also
            comments for kmDateWithCalendar class above which provides
            more detail.

   Usage -- called from above, this is not designed as an independant control,
      although you could probably do something with it to make it useful
      for your own app without the kmDateWithCalendar class above.
      
   Modifying Constants and Properties:
  
   Open a local copy (one in the working folder for your development
   environment) of kmDateWithCal.h, and you can change the constants
   there. When you recompile kmDateWithCal.cc, the changes will take
   effect. The following are the various constants defined that affect
   the calendar itself. The ones that affect the Entryfield and
   Pushbutton parts of the control are explained in the header for
   that control above.
  
   CALENDAR TITLE TEXT:
      CalendarTitleText
         As this is a subform, the you can change the text
         in the title of the form.
         Default: "Calendar"
        
   COLOR CONSTANTS:
      The following custom color constants can be used
      to change the appearance of the calendar.
      You can change them in the file "kmDateWithCal.h". Below is
      a description of what they are used for.

      NormalColor
          This can be used to set the color of the non-selected
          days. Default: black/white
      SelectedColor
          This is used to set the selected day (current
          date) to a specific color so that it stands out.
          Default: white/blue
      SundayColor
          As above, this is used to display the first column
          in a specific color.
          NOTE: In this version, holidays that
          are defined in the "LoadHolidays" method of the
          container will appear in the "SundayColor"
          unless they are also the "selected" day ...
          Default: maroon/white
      HolidayColor
          As above, used specifically for Holidays, will
          override a sundaycolor setting ...
          Default: green/white
      MouseOverColor
          When the mouse is over a day, the color of the button
          changes to this color.
          Default: red/white
          
      Note: The colors used here are basic named colors, but you could
      use hexidecimal colors, such as: "0XA00000", but you would need to
      spend some time figuring out which values to use. For more details
      on colors, see the Appendices of The dBASE Book, by Ken Mayer.
          
   MONTH/YEAR INCREMENT/DECREMENT BUTTONS:
      These two values (also defined the same way as above, as constants)
      can be used to change the defaults for the buttons for adding
      or subtracting 'n' number of months/years -- the speedtip is
      updated as well as the actual calculation:
      
      MonthIncrement -- add/subtract 'n' months
         Default: 3
      YearIncrement -- add/subtract 'n' years
         Default: 10
        
   LANGUAGE Properties:
      The kmDateWithCalendar container has a "language" property that defaults to
         "English (United States)",
      used to format dates and deal with the months/day headings ...
      It can be changed either in the code here, or in a running
      form with:
          fMyForm.kmDateWithCalendar1.language := "German (Standard)"
      Details on these can be found in the code at the beginning
      of :dUFLP:DateEx.cc, in the definition code for the
      associative array: asLang -- this is a long list, but you have to have
      the correct language definition as there needs to be an exact match
      on the text. Example: there are quite a few variations of "Arabic"
      in the list, you couldn't just use "Arabic", you would need to use
      the specific version: "Arabic (Saudi Arabia)" or "Arabic (Qatar)".
      
      If you are using the subform on its own, then you would need to reference
      the subform to set the language appropriately:
         form.pKenCalendar1.language := ...

   LANGUAGE CONSTANTS:
      TodayText -- text of "Today" button
         Default: "Today"
      TodaySpeedTip -- text of speedtip for Today Button
         Default: "Go to Today's Date"
      CancelSpeedTip -- text of speedTip for the Cancel
         button in the lower right corner of the calendar.
         Default: "Cancel Changes"
      // these are all used in the speedtips for the
      // next/prev 'n' months, etc. buttons:
      MonthText -- singular (Next Month, Previous Month)
         Default: "Month"
      MonthsText -- multiple (n Months Ahead ...)
         Default: "Months"
      YearText -- singular (Next Year)
         Default: "Year"
      YearsText -- multiple (n Years Ahead ...)
         Default: "Years"
      BackText -- text used for "n Months Back"
         Default: "Back"
      PreviousText -- text used for "Previous Month"
         Default: "Previous"
      AheadText -- "n Months Ahead"
         Default: "Ahead"
      NextText -- "Next Month"    
         Default: "Next"
        
   BUTTON IMAGES:
      NextButtonImg -- next month/year:
         Default: "RESOURCE PNG/control :resources:dFugue_16_1.dll"
      Next10BtnImg -- next 'n' months/years:
         Default: "RESOURCE PNG/controldouble :resources:dFugue_16_1.dll"
      PrevButtonImg -- previous month/year:
         Default: "RESOURCE PNG/control180 :resources:dFugue_16_1.dll"
      Prev10BtnImg -- back n months/years:
         Default: "RESOURCE PNG/controldouble180 :resources:dFugue_16_1.dll"
      TodayBtnImg -- Today Button:
         Default: "RESOURCE PNG/calendarselect :resources:dFugue_16_1.dll"
      UndoButtonImg -- Cancel/Undo Changes Button
         Default: "RESOURCE PNG/arrowcircle225left :resources:dFugue_16_1.dll"
      TimeButtonImg -- Change Time Button:
         Default: "RESOURCE PNG/alarmclockblue :resources:dFugue_24.dll"
      TimeBackImg -- time button back to calendar:
         Default: "RESOURCE PNG/calendarimport :resources:dFugue_16_1.dll"

   Note that these images are using the .DLLs provided by dBASE in the
   :resources: source code alias. To find the exact path to these, check
   the Properties dialog in the IDE, find the "Source Aliases" tab, and
   the "resources" source alias. Click it, and the path will appear
   in the dialog. Example, for dBASE Plus 11, on my Windows 10 computer:
      C:\Users\Public\Documents\dBASE\Plus11\media\Resources
   This is important if you wish to deploy this application and wish to use
   the images provided. You would need to deploy:
       dFugue_16_1.dll
       dFugue_24.dll
   See below as well for other files needed.
      
   HOLIDAYS: see code in method LoadHolidays -- you can change the
      holidays used, the ones that are automatically loaded are
      standard United States Holidays. You may want to add
      your own, see the code examples. You may not want all
      the U.S. holidays if you aren't in the US. In a case like
      that, comment out the ones you don't want on the calendar,
      and again add your own. You may want to change the text
      for the buttons. Note that at least currently the
      software only handles one holiday per date ... not sure
      how standard speedTips would handle a line break to deal
      with multiple lines of text. :)      


   ** Note that this cc file uses Source Aliasing, specifically the
   ** dUFLP source Alias. If you do not know how to set up
   ** a Source Alias, see the instructions in WHATS.NEW at
   ** the top of the file, or in README.TXT.
   ** Any files referenced by :dUFLP:filename  must be
   ** included in an executable if you are building
   ** one ... make sure that your project includes these
   ** files.
   **
   ** This particular program uses:
   **           dateex.cc
   **           holiday.cc
   **           time.cc
   **           hebrew.cc
   **           duflp.h <== not referred to by source alias, used
   **             in DateEx.cc, etc.
   **           kmDateWithCal.h
   ** Images are from:
   **           :resources:dFugue_24.dll
   **           :resources:dFugue_16_1.dll
   ** You would either need to change the images, or
   ** deploy these two .dll files

    DEPENDENCIES (Important for deploying an application
                  that uses this control):
       DATEEX.CC
       HOLIDAY.CC
       TIME.CC
       HEBREW.CC
       dFugue_24.dll
       dFugue_16_1.dll
*/


/*
   -------------------------------------------------------
   The subform class here is what does all the work ...
   There are some custom button/text control definitions
   after the subform definition.
   -------------------------------------------------------
*/
class pKenCalendar(parentObj) of subform(parentObj)
   set procedure to :dUFLP:dateex.cc additive
   set procedure to :dUFLP:holiday.cc additive

   // Note that size and position are determined based
   // on calculations ...
   with (this)
      metric            := 6        // Pixels
      onOpen            := class::CONTAINEROPEN
      onClose           := class::CONTAINERCLOSE
      systemTheme       := false
      doubleBufferred   := true
      colorNormal       := "white"
      text              := CalendarTitleText
      smallTitle        := true
      showTaskBarButton := false
      mdi               := false
      topMost           := true
      escExit           := false
      sizeable          := false
      maximize          := false
      minimize          := false
      escExit           := false
      sysMenu           := false
   endwith
   // default, but the calendarButton in kmDateWithCalendar will set this
   // if it is changed in the form's onOpen event handler:
   this.language         = "English (United States)"

   // NOTE: other constants (not below) are defined in kmDateWithCal.h  
  
   // From here down, don't mess with these ...
   #define ButtonHeight   Points2Pixels( ButtonFontSize ) + (PaddingSize * 2) // pixels
   #define ButtonWidth    Points2Pixels( ButtonFontSize ) + (PaddingSize * 2) // pixels

   // need to define these here, but then need the column
   // positions below ...
   #define YearRow         4 // pixels from top of container
   // YMBtnHeight is the height of the Year and Month buttons
   // at the top of the calendar:
   #define YMBtnHeight    ButtonHeight + PaddingSize  // additional room for descenders
   #define MonthRow       YearRow+YMBtnHeight // from top
  
   // Define rows based on button heights:
   #define TITLEROW  MonthRow+YMBtnHeight+2
   #define ROW1      (TitleRow-PaddingSize)+YMBtnHeight
   #define ROW2      ROW1+ButtonHeight
   #define ROW3      ROW2+ButtonHeight
   #define ROW4      ROW3+ButtonHeight
   #define ROW5      ROW4+ButtonHeight
   #define ROW6      Row5+ButtonHeight
   #define TodayButtonTop Row6+ButtonHeight

   // define columns based on button widths:
   #define COL1      7 // pixels from left of container
   #define COL2      COL1+ButtonWidth
   #define COL3      COL2+ButtonWidth
   #define COL4      Col3+ButtonWidth
   #define COL5      Col4+ButtonWidth
   #define COL6      Col5+ButtonWidth
   #define COL7      Col6+ButtonWidth
  
   // Year and Month rows, we need to define
   // where everything is, the calcs will be a bit more
   // complex than some of the above.
   #define PrevBtnLeft   COL1+23
   // go to the right side of the buttons at COL7,
   // subtract width of Next10 button, and width of
   // Next button:
   #define NextBtnLeft   (COL7+ButtonWidth) - (23+18)
   // same as above but without the 'next' button
   #define Next10BtnLeft (COL7+ButtonWidth) - 23
  
   // then we deal with the left and widths of the Month and Year
   // text controls:
   #define YMTextleft  23+18+8
   #define YMTextWidth (COL7+ButtonWidth) - (2*(23+18)) - 8

   // width and height of the subform will
   // vary based on width/height of buttons:
   #if __version__ < 11
      #define ContainerWidth COL7+ButtonWidth+15
   #else
      #define ContainerWidth COL7+ButtonWidth+5
   #endif
   // once we add more buttons at the bottom, this will
   // need to be modified:
   #if __version__ < 11
      #define ContainerHeight TodayButtonTop+ButtonHeight+PaddingSize+10
   #else
      #define ContainerHeight TodayButtonTop+ButtonHeight+PaddingSize
   #endif
   this.width  := ContainerWidth
   this.height := ContainerHeight
  
   // set left of TodayButton based on width of container
   // and width of TodayButton ...
   //     left = (ContainerWidth - TodayButtonWidth) / 2
   // width: image width + text: "Today"
   #define TodayButtonWidth ( 23 + ( Points2Pixels( ButtonFontSize ) * 4 ) )
   #define TodayButtonLeft  (ContainerWidth - TodayButtonWidth) / 2

   // instance of dateex class and holiday class:
   this.DateEx        = new DateEx()
   this.Holiday       = new Holiday()
   // used to set speedtips ...
   this.cSpeedTip     = ""
   // currentDate and beginDate:
   this.currentDate   = {}
   this.beginDate     = {}

   // constructor for calendar begins here ... don't mess with this!
   this.YEARMINUS10 = new CalPushbutton(this)
   with (this.YEARMINUS10)
      onClick     := class::YEARMINUS10_ONCLICK
      height      := YMBtnHeight
      left        := COL1
      top         := YearRow
      width       := 23
      text        := ""
      upBitmap    := Prev10BtnImg
      speedBar    := true
      speedTip    := YearIncrement+" " + YearsText + " " + BackText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.PREVYEARPUSHBUTTON = new CalPushbutton(this)
   with (this.PREVYEARPUSHBUTTON)
      onClick  := CLASS::PREVYEARPUSHBUTTON_OnClick
      upBitmap := PrevButtonImg
      text     := ""
      height   := YMBtnHeight
      width    := 18
      left     := PrevBtnLeft
      top      := YearRow
      speedTip := PreviousText + " " + YearText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.TEXTYEAR = new TEXT(this)
   with (this.TEXTYEAR)
      fontSize        := ButtonFontSize
      text            := "9999"
      alignHorizontal := 1 // center
      alignVertical   := 1 // middle
      height          := YMBtnHeight-1 // odd discrepency, possibly border?
      left            := YMTextleft
      top             := YearRow+1 // compensate for -1 in height above
      width           := YMTextWidth
      border          := true
      #if __version__ < 11
         borderStyle := 1 // raised
      #else
         borderStyle     := 9 // etched in
      #endif
      colorNormal     := NormalColor
      pageNo      := 1
   endwith

   this.NEXTYEARPUSHBUTTON = new CalPushbutton(this)
   with (this.NEXTYEARPUSHBUTTON)
      onClick  := CLASS::NEXTYEARPUSHBUTTON_OnClick
      upBitmap := NextButtonImg
      text     := ""
      height   := YMBtnHeight
      width    := 18
      left     := NextBtnLeft
      top      := YearRow
      speedTip := NextText +" " +YearText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.YEARPLUS10 = new CalPushbutton(this)
   with (this.YEARPLUS10)
      onClick     := class::YEARPLUS10_ONCLICK
      upBitmap    := Next10BtnImg
      height      := YMBtnHeight
      left        := Next10BtnLeft
      top         := YearRow
      width       := 23
      text        := ""
      speedTip    := YearIncrement + " " + YearsText + " " + AheadText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.MONTHMINUS3 = new CalPushbutton(this)
   with (this.MONTHMINUS3)
      onClick     := class::MONTHMINUS3_ONCLICK
      height      := YMBtnHeight
      left        := COL1
      top         := MonthRow
      width       := 23
      text        := ""
      speedTip    := MonthIncrement + " " + MonthsText + " " + BackText
      colorNormal := NormalColor
      upBitmap    := Prev10BtnImg
      pageNo      := 1
   endwith

   this.PREVMONTHPUSHBUTTON = new CalPushbutton(this)
   with (this.PREVMONTHPUSHBUTTON)
      onClick  := CLASS::PREVMONTHPUSHBUTTON_OnClick
      upBitmap := PrevButtonImg
      text     := ""
      height   := YMBtnHeight
      width    := 18
      left     := PrevBtnLeft
      top      := MonthRow
      speedTip := PreviousText + " " + MonthText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.TEXTMONTH = new TEXT(this)
   with (this.TEXTMONTH)
      fontSize        := ButtonFontSize
      text            := "Month"
      alignHorizontal := 1 // center
      alignVertical   := 1 // middle
      height          := YMBtnHeight-1
      left            := YMTextleft
      width           := YMTextWidth
      top             := MonthRow+1
      border          := true
      #if __version__ < 11
         borderStyle := 1 // raised
      #else
         borderStyle     := 9 // etched in
      #endif
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.NEXTMONTHPUSHBUTTON = new CalPushbutton(this)
   with (this.NEXTMONTHPUSHBUTTON)
      onClick     := CLASS::NEXTMONTHPUSHBUTTON_OnClick
      height      := YMBtnHeight
      width       := 18
      left        := NextBtnLeft
      top         := MonthRow
      upBitmap    := NextButtonImg
      text        := ""
      speedTip    := NextText + " " + MonthText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.MONTHPLUS3 = new CalPushbutton(this)
   with (this.MONTHPLUS3)
      onClick     := class::MONTHPLUS3_ONCLICK
      height      := YMBtnHeight
      left        := Next10BtnLeft
      top         := MonthRow
      width       := 23
      text        := ""
      upBitmap    := Next10BtnImg
      speedTip    := MonthIncrement + " " + MonthsText + " " + AheadText
      colorNormal := NormalColor
      pageNo      := 1
   endwith

   this.TITLESUNDAY = new WeekDayText(this)
   with (this.TITLESUNDAY)
      left := COL1
      top  := TITLEROW
   endwith

   this.TITLEMONDAY = new WeekDayText(this)
   with (this.TITLEMONDAY)
      left := COL2
      top  := TITLEROW
      text := "M"
   endwith

   this.TITLETUESDAY = new WeekDayText(this)
   with (this.TITLETUESDAY)
      left := COL3
      top  := TITLEROW
      text := "T"
   endwith

   this.TITLEWEDNESDAY = new WeekDayText(this)
   with (this.TITLEWEDNESDAY)
      left := COL4
      top  := TITLEROW
      text := "W"
   endwith

   this.TITLETHURSDAY = new WeekDayText(this)
   with (this.TITLETHURSDAY)
      left := COL5
      top  := TITLEROW
      text := "T"
   endwith

   this.TITLEFRIDAY = new WeekDayText(this)
   with (this.TITLEFRIDAY)
      left := COL6
      top  := TITLEROW
      text := "F"
   endwith

   this.TITLESATURDAY = new WeekDayText(this)
   with (this.TITLESATURDAY)
      left := COL7
      top  := TITLEROW
   endwith

   this.ROW1COL1 = new DayPushButton(this)
   with (this.ROW1COL1)
      left = COL1
      top = ROW1
   endwith

   this.ROW1COL2 = new DayPushButton(this)
   with (this.ROW1COL2)
      left = COL2
      top = ROW1
   endwith

   this.ROW1COL3 = new DayPushButton(this)
   with (this.ROW1COL3)
      left = COL3
      top = ROW1
   endwith

   this.ROW1COL4 = new DayPushButton(this)
   with (this.ROW1COL4)
      left = COL4
      top = ROW1
   endwith

   this.ROW1COL5 = new DayPushButton(this)
   with (this.ROW1COL5)
      left = COL5
      top = ROW1
   endwith

   this.ROW1COL6 = new DayPushButton(this)
   with (this.ROW1COL6)
      left = COL6
      top = ROW1
   endwith

   this.ROW1COL7 = new DayPushButton(this)
   with (this.ROW1COL7)
      left = COL7
      top = ROW1
   endwith

   this.ROW2COL1 = new DayPushButton(this)
   with (this.ROW2COL1)
      left = COL1
      top = ROW2
   endwith

   this.ROW2COL2 = new DayPushButton(this)
   with (this.ROW2COL2)
      left = COL2
      top = ROW2
   endwith

   this.ROW2COL3 = new DayPushButton(this)
   with (this.ROW2COL3)
      left = COL3
      top = ROW2
   endwith

   this.ROW2COL4 = new DayPushButton(this)
   with (this.ROW2COL4)
      left = COL4
      top = ROW2
   endwith

   this.ROW2COL5 = new DayPushButton(this)
   with (this.ROW2COL5)
      left = COL5
      top = ROW2
   endwith

   this.ROW2COL6 = new DayPushButton(this)
   with (this.ROW2COL6)
      left = COL6
      top = ROW2
   endwith

   this.ROW2COL7 = new DayPushButton(this)
   with (this.ROW2COL7)
      left = COL7
      top = ROW2
   endwith

   this.ROW3COL1 = new DayPushButton(this)
   with (this.ROW3COL1)
      left = COL1
      top = ROW3
   endwith

   this.ROW3COL2 = new DayPushButton(this)
   with (this.ROW3COL2)
      left = COL2
      top = ROW3
   endwith

   this.ROW3COL3 = new DayPushButton(this)
   with (this.ROW3COL3)
      left = COL3
      top = ROW3
   endwith

   this.ROW3COL4 = new DayPushButton(this)
   with (this.ROW3COL4)
      left = COL4
      top = ROW3
   endwith

   this.ROW3COL5 = new DayPushButton(this)
   with (this.ROW3COL5)
      left = COL5
      top = ROW3
   endwith

   this.ROW3COL6 = new DayPushButton(this)
   with (this.ROW3COL6)
      left = COL6
      top = ROW3
   endwith

   this.ROW3COL7 = new DayPushButton(this)
   with (this.ROW3COL7)
      left = COL7
      top = ROW3
   endwith

   this.ROW4COL1 = new DayPushButton(this)
   with (this.ROW4COL1)
      left = COL1
      top = ROW4
   endwith

   this.ROW4COL2 = new DayPushButton(this)
   with (this.ROW4COL2)
      left = COL2
      top = ROW4
   endwith

   this.ROW4COL3 = new DayPushButton(this)
   with (this.ROW4COL3)
      left = COL3
      top = ROW4
   endwith

   this.ROW4COL4 = new DayPushButton(this)
   with (this.ROW4COL4)
      left = COL4
      top = ROW4
   endwith

   this.ROW4COL5 = new DayPushButton(this)
   with (this.ROW4COL5)
      left = COL5
      top = ROW4
   endwith

   this.ROW4COL6 = new DayPushButton(this)
   with (this.ROW4COL6)
      left = COL6
      top = ROW4
   endwith

   this.ROW4COL7 = new DayPushButton(this)
   with (this.ROW4COL7)
      left = COL7
      top = ROW4
   endwith

   this.ROW5COL1 = new DayPushButton(this)
   with (this.ROW5COL1)
      left = COL1
      top = ROW5
   endwith

   this.ROW5COL2 = new DayPushButton(this)
   with (this.ROW5COL2)
      left = COL2
      top = ROW5
   endwith

   this.ROW5COL3 = new DayPushButton(this)
   with (this.ROW5COL3)
      left = COL3
      top = ROW5
   endwith

   this.ROW5COL4 = new DayPushButton(this)
   with (this.ROW5COL4)
      left = COL4
      top = ROW5
   endwith

   this.ROW5COL5 = new DayPushButton(this)
   with (this.ROW5COL5)
      left = COL5
      top = ROW5
   endwith

   this.ROW5COL6 = new DayPushButton(this)
   with (this.ROW5COL6)
      left = COL6
      top = ROW5
   endwith

   this.ROW5COL7 = new DayPushButton(this)
   with (this.ROW5COL7)
      left = COL7
      top = ROW5
   endwith

   this.ROW6COL1 = new DayPushButton(this)
   with (this.ROW6COL1)
      left = COL1
      top = ROW6
   endwith

   this.ROW6COL2 = new DayPushButton(this)
   with (this.ROW6COL2)
      left = COl2
      top = ROW6
   endwith

   this.ROW6COL3 = new DayPushButton(this)
   with (this.ROW6COL3)
      left = COL3
      top = ROW6
   endwith

   this.ROW6COL4 = new DayPushButton(this)
   with (this.ROW6COL4)
      left = COL4
      top = ROW6
   endwith

   this.ROW6COL5 = new DayPushButton(this)
   with (this.ROW6COL5)
      left = COL5
      top = ROW6
   endwith

   this.ROW6COL6 = new DayPushButton(this)
   with (this.ROW6COL6)
      left = COL6
      top = ROW6
   endwith

   this.ROW6COL7 = new DayPushButton(this)
   with (this.ROW6COL7)
      left = COL7
      top = ROW6
   endwith

   this.TimeButton = new CalPushbutton(this)
   with (this.TimeButton)
      onClick     = class::TimeButton_OnClick
      height      = ButtonHeight
      width       = ButtonWidth
      text        = ""
      left        = COL1
      top         = TodayButtonTop
      speedTip    = TimeSpeedTip1
      colorNormal = NormalColor
      upBitmap    = TimeButtonImg
      visible     = false
      pageNo      = 0
   endwith

   this.TodayPushButton = new CalPushbutton(this)
   with (this.TodayPushButton)
      onClick     = CLASS::TodayPushButton_OnClick
      height      = ButtonHeight
      left        = TodayButtonLeft
      top         = TodayButtonTop
      width       = TodayButtonWidth
      text        = TodayText
      fontSize    = ButtonFontSize
      speedTip    = TodaySpeedTip
      colorNormal = NormalColor
      upBitmap    = TodayBtnImg
      pageNo      = 1
   endwith
  
   this.CancelButton = new CalPushbutton(this)
   with (this.CancelButton)
      onClick     = CLASS::CancelButton_OnClick
      height      = ButtonHeight
      width       = ButtonWidth
      text        = ""
      left        = COL7
      top         = TodayButtonTop
      speedTip    = CancelSpeedTip
      colorNormal = NormalColor
      upBitmap    = UndoButtonImg
      pageNo      = 1
   endwith
    
   /*
      Define controls for the time part of the calendar ...
      Look at controls in the dUFLP for handling time values
  
   */
  
   this.TimeTitle = new text( this )
   with( this.TimeTitle )
   fontSize           := ButtonFontSize
      text            := TimeTitleText
      alignHorizontal := 1 // center
      alignVertical   := 1 // middle
      height          := YMBtnHeight-1 // odd discrepency, possibly border?
      left            := YMTextleft-10
      top             := YearRow+1 // compensate for -1 in height above
      width           := YMTextWidth+20
      border          := true
      #if __version__ < 11
         borderStyle := 1 // raised
      #else
         borderStyle     := 9 // etched in
      #endif
      colorNormal     := NormalColor
      pageNo          := 2
   endwith
  
   this.HOURLabel = new TEXT(this)
   with (this.HOURLabel)
      height = 16.0
      left = COL2
      top = ROW1
      width = 18.0
      fontBold = true
      text = HoursText
      pageNo = 2
   endwith
  
   this.HOURSB = new SPINBOX(this)
   with (this.HOURSB)
      height = 22.0
      left = COL2
      top = ROW2
      width = 47.0
      speedTip = HoursSpeedTip
      picture = "99"
      function = "@L"
      rangeMax = 24
      rangeMin = 1
      value = 1
      rangeRequired = true
      colorNormal = EFNormalColor
      colorHighlight = EFColorHighlight
      pageNo = 2
      onChange = class::HoursSB_OnChange
   endwith
  
   this.MINUTESLabel = new TEXT(this)
   with (this.MINUTESLabel)
      height = 22.0
      left = COL4
      top = ROW1
      width = 18.0
      fontBold = true
      text = MinutesText
      pageNo = 2
   endwith
  
   this.MINUTESSB = new SPINBOX(this)
   with (this.MINUTESSB)
      height = 22.0
      left = COL4
      top = ROW2
      width = 47.0
      speedTip = MinutesSpeedTip
      picture = "99"
      function = "@L"
      rangeMax = 59
      rangeMin = 0
      value = 1
      rangeRequired = true
      colorNormal = EFNormalColor
      colorHighlight = EFColorHighlight
      pageNo = 2
      onChange = class::MinutesSB_OnChange
   endwith
  
   this.SecondsLabel = new TEXT(this)
   with (this.SecondsLabel)
      height = 22.0
      left = COL6
      top = ROW1
      width = 20.0
      fontBold = true
      text = SecondsText
      pageNo = 2
   endwith
  
   this.SECONDSSB = new SPINBOX(this)
   with (this.SECONDSSB)
      height = 22.0
      left = COL6
      top = ROW2
      width = 47.0
      speedTip = "Seconds"
      picture = "99"
      function = "@L"
      rangeMax = 59
      rangeMin = 0
      value = 1
      rangeRequired = true
      colorNormal = EFNormalColor
      colorHighlight = EFColorHighlight
      pageNo = 2
      onChange = class::SecondsSB_OnChange
   endwith


   function CheckMetric
      // called from container's onDesignOpen:
      if form.metric # 6
         msgbox( "Form's metric property is not '6 - Pixels', "+;
                 "this will not display properly.", ;
                 "Bad Form Metric!", 16 )
      endif
   return

   function containerOpen
      // if we have a custom property of "EF":
      if type( "this.EF" ) == "O" // object
         this.currentDate = this.EF.value
      endif
      
      // default date if needed:
      if type( 'this.currentDate' ) # "D" or empty( this.currentDate )
         if this.type == "Date"
            this.currentDate = date()
         else // datetime
            this.currentDate = datetime()
         endif
      endif

      // Set color of "sunday" title button
      this.titleSunday.colorNormal := SundayColor

      // store starting date value, in
      // case there's a cancel option,
      // the user can return to the 'beginDate':
      this.beginDate = this.currentDate

      // update day-of-week headings
      class::DayHeadings()
      
      // if we are working with a datetime field:
      if this.type == "DateTime"
         this.TimeButton.visible := true
      endif

      // newMonth routine -- ensures all the
      // buttons are the 'correct' colors, and
      // speedTips added for holidays, etc.
      class::NewMonth()
   return
  
   function ContainerClose
      // the Calendar button is a toggle, so we need to
      // reset it when the subform closes. We added a
      // reference (this.Btn) in the button's onClick
      // event handler for when we first click the button,
      // now we're just calling the code that causes
      // the polymorphism to occur and change the image
      // and code that fires for the button (allowing
      // the calendar to open properly again if necessary,
      // without multiple mouse clicks).
      this.Btn.onclick()
   return

   function DayHeadings
      // deal with language stuff for the
      // day of the week:
      local cDay, dTemp

      // Set the language for the DateEx object:
      this.dateEx.Language := this.Language

      // we need a day known to be a Sunday:
      dTemp = new date( 2004, 1, 1 ) // February 1, 2004
                                     // remember date object
                                     // is zero-based, hence
                                     // the second month of
                                     // the year is 1
      // Get Sunday
      cDay = this.dateEx.intlcdow( dTemp )
      // Assign first letter ...:
      this.TitleSunday.text := left( cDay, 1 )
      // Get Monday
      cDay = this.dateEx.intlcdow( dTemp+1 )
      // Assign first letter ...:
      this.TitleMonday.text := left( cDay, 1 )
      // Get Tuesday
      cDay = this.dateEx.intlcdow( dTemp+2 )
      // Assign first letter ...:
      this.TitleTuesday.text := left( cDay, 1 )
      // Get Wednesday
      cDay = this.dateEx.intlcdow( dTemp+3 )
      // Assign first letter ...:
      this.TitleWednesday.text := left( cDay, 1 )
      // Get Thursday
      cDay = this.dateEx.intlcdow( dTemp+4 )
      // Assign first letter ...:
      this.TitleThursday.text := left( cDay, 1 )
      // Get Friday
      cDay = this.dateEx.intlcdow( dTemp+5 )
      // Assign first letter ...:
      this.TitleFriday.text := left( cDay, 1 )
      // Get Saturday
      cDay = this.dateEx.intlcdow( dTemp+6 )
      // Assign first letter ...:
      this.TitleSaturday.text := left( cDay, 1 )
   return

   function newMonth
      // this function deals with setting values based
      // on changes to month/year -- determine where
      // first day is, last day is, everything in
      // between: set button texts, colors ...

      // First: need to determine what level we're at --
      // are we working from subform, or control
      // on subform (cRef needs to point to the subform):
      if "SUBFORM" $ upper( this.className ) or;
         "SUBFORM" $ upper( this.baseClassName )
         // we're on the subform
         oRef = this  
      else
         // we're on a pushbutton _on_ the subform
         oRef = this.parent
      endif

      // Make sure holiday list is current ...
      class::LoadHolidays()

      // now to get first day of month and last day of
      // month from 'currentDate'
      dDate  = oRef.currentDate
      dFirst = oRef.dateEx.fdom( dDate )
      dLast  = oRef.dateEx.ldom( dDate )
      nDay   = day( dDate ) // current day of month
      
      bDateTime = ( oRef.type == "DateTime" )
      if bDateTime
         // we need to deal with the time portion
         // of the value ...
         cTime = oRef.currentDate.hour+":"+;
                 oRef.currentDate.minute+":"+;
                 oRef.currentDate.second
      endif        

      // character values for month and year:
      oRef.textMonth.text := oRef.dateEx.intlCMon( dDate )
      oRef.textYear.text  := ltrim( str( year( dDate ) ) )

      // now the fun part ... assigning values, based
      // on where we start:
      nStart = dow( oRef.currentDate )

      // Clear out any outstanding speedTips
      for nRows = 1 to 6
          for nColumns = 1 to 7
              cObject = "oRef.Row1Col"+nColumns
              cSpeedTip = cObject+".speedTip"
              &cSpeedTip. := ""
          next
      next
      
      // We need to loop through everything, and set
      // visible properties as well as text if it's going
      // to display:
      nCurrent = 0
      for nRows = 1 to 6
          for nColumns = 1 to 7
              nCurrent++
              // start at day 1, but ...
              // for first row, loop through until we find
              // the first one (and make everything before
              // the first day of month invisible):
              if nCurrent == 1
                 do while nCurrent <= nColumns
                    if dow( dFirst ) == nColumns
                       // set the text:
                       cObject = "oRef.Row1Col"+nColumns
                       cText   = cObject+".text"
                       &cText. := "1"
                       // Set colors:
                       cColor = cObject+".colorNormal"

                       // if the day we're setting is the
                       // selected/current date:
                       dTestDate = new date(year(dDate), ;
                                   month(dDate)-1, nCurrent)
                       // Make it a real date
                       dTestDate = ctod( left( dTestDate.toLocaleString(), ;
                                   iif( set("CENTURY") == "ON", 10, 8 ) ) )
                       if nDay == nCurrent
                          &cColor. := SelectedColor //oRef.SELECTEDCOLOR
                          oRef.currentButton = &cObject.
                          cSpeedTip = cObject+".speedTip"
                          if class::isHoliday( dtestDate )
                             &cSpeedTip. = oRef.cSpeedTip
                          endif                      
                       else
                          // is it a sunday or a holiday?
                          cSpeedTip = cObject+".speedTip"
                          if nColumns == 1
                             &cColor. := SundayColor //oRef.SUNDAYCOLOR
                             if class::IsHoliday( dTestDate )
                                &cColor.    := HolidayColor //oRef.HOLIDAYCOLOR
                                &cSpeedTip. := oRef.cSpeedTip
                             endif
                          elseif class::IsHoliday( dTestDate )
                             &cColor. := HolidayColor //oRef.HOLIDAYCOLOR
                             &cSpeedTip. := oRef.cSpeedTip
                          else
                             // it's any other day of week ...
                             &cColor. := NormalColor //oRef.NORMALCOLOR
                          endif
                       endif // nDay == nCurrent

                       // set visible property
                       cVisible = cObject+".visible"
                       &cVisible. := true
                       // finish the row
                       for i = nColumns to 7
                           cObject = "oRef.Row1Col"+i
                           cText   = cObject+".text"
                           &cText. := "1"
                           // set visible property
                           cVisible = cObject+".visible"
                           &cVisible. := true
                       next
                       exit // out of this loop, we're done
                    else
                       if nColumns > 7
                          nColumns = 7
                          exit
                       endif
                       cObject = "oRef.Row1Col"+nColumns
                       cVisible = cObject+".visible"
                       &cVisible. := false
                    endif // dow( dFirst ) = nColumns
                    nColumns++ // increment column counter
                    loop       // top of _this_ loop
                 enddo // while nCurrent <= nColumns
                 loop // back to columns for/next loop
              endif // nCurrent = 1

              // now to attempt to handle setting
              // text and colors ...
              cObject = "oRef.Row"+nRows+"Col"+nColumns
              cSpeedTip = cObject+".speedTip"
              &cSpeedTip := "" // clear out whatever's there
              // if we're inside the month's dates:
              if nCurrent > 1 and nCurrent <= day( dLast )
                 // set the text property:
                 cText = cObject+".text"
                 &cText. := ""+nCurrent
                 // set the button to visible:
                 cVisible = cObject+".visible"
                 &cVisible. := true
                 // deal with colors:
                 cColor = cObject+".colorNormal"
                 // if the day we're setting is the
                 // selected/current date:
                 dTestDate = new date(year(dDate), ;
                             month(dDate)-1, nCurrent)
                 // Make it a real date
                 dTestDate = ctod( left( dTestDate.toLocaleString(), ;
                             iif( set("CENTURY") == "ON", 10, 8 ) ) )
                 if nDay == nCurrent
                    &cColor. := SelectedColor
                    oRef.currentButton = &cObject.
                    cSpeedTip = cObject+".speedTip"
                    if class::isHoliday( dtestDate )
                       &cSpeedTip. = oRef.cSpeedTip
                    endif                      
                 else
                    // is it a sunday or a holiday?
                    cSpeedTip = cObject+".speedTip"
                    if nColumns == 1
                       &cColor. := SundayColor
                       if class::IsHoliday( dTestDate )
                          &cColor.    := HolidayColor
                          &cSpeedTip. := oRef.cSpeedTip
                       endif
                    elseif class::IsHoliday( dTestDate )
                       &cColor. := HolidayColor
                       &cSpeedTip. := oRef.cSpeedTip
                    else
                       // it's any other day of week ...
                       &cColor. := NormalColor
                    endif
                 endif // nDay == nCurrent
              else
                 // we want to make it invisible
                 cVisible = cObject+".visible"
                 &cVisible. := false
              endif // nCurrent > 1 and nCurrent <= day( dLast )
          next // nColumns
      next // nRows

      // deal with DateTime:
      if oRef.type == "DateTime"
         cDate = dtoc( oRef.currentDate )
         cDate += " " + cTime
         oRef.currentDate = ctodt( cDate )
      endif
      
      // if it exists, refresh the entryfield:
      if type( "oRef.EF" ) == "O" // object
         oRef.EF.value = oRef.currentDate
      endif

   return
  
   function TodayPushButton_onClick
      // set today's date
      this.parent.currentDate = date()
      // refresh display
      class::NewMonth()
      // close the subform:
      this.parent.close()
   return
  
   function CancelButton_OnClick
      // reset date to the starting date:
      this.parent.currentDate = this.parent.beginDate
      // refresh display
      class::NewMonth()
   return

   function TimeButton_OnClick
      // need to change display of the subform to handle
      // time and morph the button back to point back to
      // the main calendar
      if this.parent.PageNo == 1
         this.parent.PageNo := 2 // change pages
         // morph the button
         this.speedTip := TimeSpeedTip2
         this.upBitMap := TimeBackImg
         // break up values for H/M/S and place in
         // controls. Need to get value from
         // this.parent.currentDate:
         this.parent.HourSB.value := this.parent.currentDate.hour
         this.parent.MinutesSB.value := this.parent.currentDate.minute
         this.parent.SecondsSB.value := this.parent.currentDate.second
         // set focus to Hours spinbox:
         this.parent.HourSB.setFocus()
      else
         this.parent.PageNo := 1
         // morph the button:
         this.speedTip := TimeSpeedTip1
         this.upBitMap := TimeButtonImg
      endif
   return


   function NEXTYEARPUSHBUTTON_onClick
      // code to add year to date,
      // and call newMonth routine

      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif

      // increment year:
      this.parent.currentDate = ;
           this.parent.dateEx.addYears( this.parent.currentDate, 1 )
          
      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif

      // update the whole thing
      class::NewMonth()      
   return

   function YEARPLUS10_onClick
      // code to add 10 years to date,
      // and call newMonth routine
      
      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif

      // increment year 'n' years:
      this.parent.currentDate = ;
           this.parent.dateEx.addYears( this.parent.currentDate, YearIncrement )

      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif
      
      // update the calendar
      class::NewMonth()
   return

   function PREVYEARPUSHBUTTON_onClick
      // code to subtract year from date,
      // and call newMonth routine

      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif

      // decrement year
      this.parent.currentDate = ;
           this.parent.dateEx.addYears( this.parent.currentDate, -1 )

      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif

      // update the calendar
      class::NewMonth()
   return

   function YEARMINUS10_onClick
      // code to subtract 10 years from date,
      // and call newMonth routine
      
      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif

      // decrement 'n' years
      this.parent.currentDate = ;
           this.parent.dateEx.addYears( this.parent.currentDate, -YearIncrement )
          
      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif

      // update the calendar
      class::NewMonth()      
   return
  
   function NEXTMONTHPUSHBUTTON_onClick
      // code to add month to date,
      // and call newMonth routine
      
      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif
      
      // increment month
      this.parent.currentDate = ;
           this.parent.dateEx.addMonths( this.parent.currentDate, 1 )
          
      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif
      
      // update the calendar
      class::NewMonth()
   return

   function MONTHPLUS3_onClick
      // code to add 3 months to date,
      // and call newMonth routine
      
      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif
      
      // increment 'n' months
      this.parent.currentDate = ;
           this.parent.dateEx.addMonths( this.parent.currentDate, MonthIncrement )
          
      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif
      
      // update the calendar
      class::NewMonth()
   return

   function PREVMONTHPUSHBUTTON_onClick
      // code to subtract month from date,
      // and call newMonth routine

      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif

      // decrement month
      this.parent.currentDate = ;
           this.parent.dateEx.addMonths( this.parent.currentDate, -1 )
          
      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif
      
      // update the calendar
      class::NewMonth()    
   return

   function MONTHMINUS3_onClick
      // code to subtract 3 months from date,
      // and call newMonth routine

      // if dateTime we need to catch the time and add it back in
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif
      
      // decrement 'n' months
      this.parent.currentDate = ;
           this.parent.dateEx.addMonths( this.parent.currentDate, -MonthIncrement )
      
      // if needed put the time back in
      if this.parent.type == "DateTime"
         this.parent.currentDate := ;
            ctodt( dtoc( this.parent.currentDate ) + " " + cTime )
      endif
      
      // update the calendar
      class::NewMonth()    
   return

   function HoursSB_OnChange
      // from the HoursSB (Spinbox), change the hours for the current date:
      oRef = this.parent
      
      // build datetime string:
      cDTString = oRef.currentDate.month+;
                  "/"+;
                  oRef.currentDate.date+;
                  "/"+;
                  oRef.currentDate.year+;
                  " "+;
                  this.value+;
                  ":"+;
                  oRef.currentDate.minute+;
                  ":"+;
                  oRef.currentDate.second
                  
       // call method to update:
       class::UpdateTime( cDTString )
   return
  
   function MinutesSB_OnChange
      // from the MinutesSB (Spinbox), change the minutes for the current date:
      oRef = this.parent
      
      // build datetime string:
      cDTString = oRef.currentDate.month+;
                  "/"+;
                  oRef.currentDate.date+;
                  "/"+;
                  oRef.currentDate.year+;
                  " "+;
                  oRef.currentDate.hour+;
                  ":"+;
                  this.value+;
                  ":"+;
                  oRef.currentDate.second
                  
       // call method to update:
       class::UpdateTime( cDTString )
   return

   function SecondsSB_OnChange
      // from the SecondsSB (Spinbox), change the seconds for the current date:
      oRef = this.parent
      
      // build datetime string:
      cDTString = oRef.currentDate.month+;
                  "/"+;
                  oRef.currentDate.date+;
                  "/"+;
                  oRef.currentDate.year+;
                  " "+;
                  oRef.currentDate.hour+;
                  ":"+;
                  oRef.currentDate.minute+;
                  ":"+;
                  this.value
                  
       // call method to update:
       class::UpdateTime( cDTString )
   return

   procedure UpdateTime( cDTString )
      // called from HoursSP, MinutesSB or SecondsSB
      oRef = this.parent
      
      // save old date setting in case not MDY:
      cOldDate = set( "date" )
      // set to MDY format:
      set date MDY

      // assign and convert string to currentDate property:
      oRef.currentDate = ctodt( cDTString )

      // reset date format
      set date &cOldDate.
      
      // update the entryfield:
      oRef.EF.value := oRef.currentDate
   return
  
   procedure LoadHolidays
      // Creates/re-creates array used to determine
      // a holiday ... NOTE: It adds an array
      // to the form ...
      local nYear, oRef, nHoliday, d
      local cMarkSet
      private cCmd, cDateSet


      // Have to determine if being called from container
      // or from a button call ...
      if "CALENDAR" $ this.className
         nYear = year( this.currentDate )
         oRef = this
      else
         nYear = year( this.parent.currentDate )
         oRef = this.parent
      endif

      // Create array
      oRef.Holidays = new Array(1,2) // 1 row, 2 columns
      
      // Load holidays using holidaydate method below:
      // floating holidays (most of these are US Holidays --
      // *********************************************
      // you may wish to modify if not in the US ...):
      // *********************************************
      // President's Day
      i = 0
      i++
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "P" )
      oRef.Holidays[i,2] = "President's Day"
      // Daylight Savings time -- always a Sunday
      // Memorial Day
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "M" )
      oRef.Holidays[i,2] = "Memorial Day"
      // Labor Day
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "L" )
      oRef.Holidays[i,2] = "Labor Day"
      // Columbus Day
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "C" )
      oRef.Holidays[i,2] = "Columbus Day"
      // Standard Time -- always a Sunday
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "S" )
      oRef.Holidays[i,2] = "Standard Time"
      // Daylight Savings Time
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "D" )
      oRef.Holidays[i,2] = "Daylight Savings Time"
      // Election Day
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "E" )
      oRef.Holidays[i,2] = "Election Day"
      // Thanksgiving
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "T" )
      oRef.Holidays[i,2] = "Thanksgiving"
      // Advent -- always a Sunday
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.HolidayDate( nYear, "A" )
      oRef.Holidays[i,2] = "Advent"

      // Easter requires special code ...:
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = oRef.Holiday.EasterDay( nYear )
      oRef.Holidays[i,2] = "Easter"

      // fixed dates:
      // deal with date format, so we don't
      // mess up international users ...
      cDateSet = set("DATE")
      cMarkSet = set("MARK")
      set date MDY

      // New Year's Day
      d = ctod( "01/01/"+nYear )
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "New Year's Day"
      // Lincoln's Birthday
      d = ctod( "02/12/"+nYear)
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "Lincoln's Birthday"
      // Valentine's Day
      d = ctod( "02/14/"+nYear )
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "Valentine's Day"
      // Washington's Birthday
      d = ctod( "02/22/"+nYear)
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "Washington's Birthday"
      // St. Patrick's Day
      d = ctod( "03/17/"+nYear)
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "St. Patrick's Day"
      // April Fool's Day
      d = ctod( "04/01/"+nYear)
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "April Fool's Day"
      // Fourth of July
      d = ctod( "07/04/"+nYear )
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "Independance Day"
      // Halloween (All Hallows Eve)
      d = ctod( "10/31/"+nYear )
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "Halloween"
      // Christmas
      d = ctod( "12/25/"+nYear )
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "Christmas"
      // New Year's Eve
      d = ctod( "12/31/"+nYear )
      i++
      oRef.Holidays.grow(1)
      oRef.Holidays[i,1] = d
      oRef.Holidays[i,2] = "New Year's Eve"

      // You can add more here if you wish ...
      // make sure you add a row to the array,
      // and add the name of the holiday or memorable
      // date ... Basically, copy the code as shown
      // above, and make appropriate changes

      // reset date format to whatever it was
      // before we changed to American
      set date &cDateSet.
      cCmd = "set mark to '"+cMarkSet+"'"
      &cCmd.

      // one last thing:
      oRef.Holidays.sort(1) // sort on first column
   return
  
   Function IsHoliday
      parameter dCheckIt
      // this routine reads the array "this.Holidays"
      // and checks the date to see if the date in
      // dCheck parameter is in the list, and returns
      // a logical value ...
      if "CALENDAR" $ upper( this.className )
         oRef = this
      else
         oRef = this.parent
      endif
      lHoliday = false
      oRef.cSpeedTip = ""
      for i = 1 to oRef.Holidays.size/2
          if oRef.Holidays[ i, 1 ] == dCheckIt
             lHoliday := true
             oRef.cSpeedTip = oRef.Holidays[ i, 2 ]
          endif
      next
   return ( lHoliday )

endclass
// end of class pKenCalendarContainer

/*
   ----------------------------------------------------------
   Pushbutton class definitions
   CalPushButton -- default button definition used for all
   buttons on form
  
   DayPushButton -- used to display the days on the calendar
   ----------------------------------------------------------
*/
class CalPushbutton( oParent ) of Pushbutton( oParent )
   this.fontName        := ButtonFontName
   this.speedBar        := true // so they don't keep focus
   #if __version__ < 11
      this.systemTheme := false
   #else
      // dBASE Plus 11 new property,
      // allows us to keep general pushbutton
      // appearance of theme, but change
      // the color of the button:
      this.themeBackground := false
   #endif
   this.visible         := true // unless turned off
   this.metric          := 6 // Pixels
endclass

class DayPushButton( oParent ) of CalPushbutton( oParent )
   with (this)
      fontSize := ButtonFontSize
      height   := ButtonHeight
      width    := ButtonWidth
      text     := "30" // set to this for layout purposes
      visible  := false
      pageNo   := 1
   endwith

   function onClick
      // deal with whether or not this is date or dateTime
      if this.parent.type == "DateTime"
         cTime = this.parent.currentDate.hour+":"+;
                 this.parent.currentDate.minute+":"+;
                 this.parent.currentDate.second
      endif
      
      /*
         The tricky part of this little routine is
         resetting colors -- in order to do that,
         we need to store a reference to the 'current'
         button, so we can reset that, before we change
         the now current button's color ...
      */
      dCurrentDate = new date(year(this.parent.currentDate), ;
                     month(this.parent.currentDate)-1, ;
                     VAL(this.parent.currentButton.text))
      dCurrentDate = ctod( left( dCurrentDate.toLocaleString(), ;
                     iif( set("CENTURY") == "ON", 10, 8 ) ) )
      if type( "this.parent.currentbutton" ) # "U"
         // if it's in Column 1, it's a "sunday" ...
         if "COL1" $ this.parent.currentButton.Name
            this.parent.currentButton.colorNormal := ;
                                  SundayColor // this.parent.SUNDAYCOLOR
         // set holiday color if needed:
         elseif this.parent.isHoliday( dCurrentDate )
               this.parent.currentButton.colorNormal := ;
                                  HolidayColor // this.parent.HOLIDAYCOLOR
         // otherwise, we have a "normal" day ...
         else
            this.parent.currentButton.colorNormal := ;
                                    NormalColor // this.parent.NORMALCOLOR
         endif
      endif

      // Assign currentButton property of container
      this.parent.currentButton = this
      // Assign color ...
      this.colorNormal := SelectedColor // this.parent.SELECTEDCOLOR

      // set current date to this one:
      this.parent.currentDate := ;
           new date( year(this.parent.currentDate), ;
                     month(this.parent.currentDate)-1, ;
                     VAL(this.text) )
      this.parent.currentDate := ;
                     ctod( left( this.parent.currentDate.toLocaleString(), ;
                     iif( set("CENTURY") == "ON", 10, 8 ) ) )
                    
      // and we need the darn time ...
      if this.parent.type == "DateTime"
         cDate = this.parent.currentDate + " " + cTime
         this.parent.currentDate = ctoDT( cDate )
      endif
      
      // because of adding the onMouseOver event, we
      // are having an issue here ... sequence
      // of event processing is throwing things
      // off (which makes sense, moving the mouse over
      // the control would happen before the onClick
      // event):
      this.oldColorNormal := this.colorNormal
      
      // deal with entryfield update:
      if type( "this.parent.EF" ) == "O" // object
         this.parent.EF.value := this.parent.currentDate
      endif
      
      // close the subform:
      this.parent.close()
   return
  
   function onMouseOver
      // save current color setting
      this.oldColorNormal = this.colorNormal
      // make it readable ...:
      this.colorNormal := MouseOverColor //this.parent.MouseOverColor
   return
  
   function onMouseOut
      this.colorNormal := this.oldColorNormal // revert to previous setting
   return

endclass

// custom class the "title" text so we have something nearly
// identical to the pushbuttons used for the days for the titles
class WeekDayText( oParent ) of Text( oParent )
   with (this)
      fontName        := ButtonFontName
      fontSize        := ButtonFontSize
      height          := ButtonHeight
      width           := ButtonWidth
      metric          := 6  // Pixels
      text            := "S"
      border          := true
      #if __version__ < 11
         borderStyle := 1 // raised
      #else
         borderStyle     := 9 // etched in
      #endif
      alignHorizontal := 1 // center
      alignVertical   := 1 // middle
      colorNormal     := normalColor
      pageNo          := 1
   endwith

endclass

// for conversion from fontSize (points) to Pixels (form metric):
function Points2Pixels( nPoints )
return round( nPoints * 1.3333333333333333, 0 )

/* END OF FILE -- kmDateWithCal.cc */