/*
   ------------------------------------------------------
   Filename....:  fontpb.cc
   ClassName...:  fontpb
   Purpose.....:  GUI object for calling dBL getFont().
                  Pre-load the dialog before displaying.
                  Extract and store a dialog selection.
   Programmer..:  Rick Miller
   Date........:  December 22, 2003
   Notes.......:  the getFont() dialog will NOT be pre-loaded
                  when this object is used on an SDI form.
   Written for.:  PLUS 2.01 and newer
   Rev. History:  December 29, 2003 -  added constants.
   Dependencies:  None
   Calls.......:  None
   Called by...:  Any
   Usage.......:  set procedure to :dUFLP:fontpb.cc additive
   Example.....:  see Example below
   SampleFile..:  :dUFLP:fontpb.wfm
   HelpFile....:  None
   ------------------------------------------------------
   Example:
      drop object on form.
      override the onClick event to a method
      similar to below in the form.
   function fontpb1_onClick
      if fontpb::onClick()
         // a font was selected.
         // assign font properties to a form object.
         this.assignFont(this.form.childobject)
      endif
   return
   ------------------------------------------------------
   Properties:    datatype:
      debug       bool 
      font        assocarray
         elements:      datatype:   value:
            bold           bool        fontBold
            italic         bool        fontItalic
            name           char        fontName
            size           int         fontSize
            strikeout      bool        fontStrikeout
            text           char        getFont() string
            underline      bool        fontUnderline
      runtime     bool
   ------------------------------------------------------
   Methods:
      see notes placed in each function.
   ------------------------------------------------------
   */
// defines for english version of dBL getFont().
// these may need changing when used with other languages.
#define  FONTPBDEBUG    "fontpb deBug Information"
#define  PBBOLD         "B"            // string to query.
#define  PBDEFAULTTEXT  "Choose Font"  // default text.
#define  PBFONTBOLD     "Bold"         // string to query.
#define  PBFONTITALIC   "Italic"       // string to query.
#define  PBFONTREGULAR  "Regular"      // string to query.
#define  PBITALIC       "I"            // string to query.
#define  PBREMOVETEXT1  ",Decorative"  // string to query.
#define  PBREMOVETEXT2  ",Modern"      // string to query.
#define  PBREMOVETEXT3  ",Roman"       // string to query.
#define  PBREMOVETEXT4  ",Script"      // string to query.
#define  PBREMOVETEXT5  ",Swiss"       // string to query.
#define  PBSTRIKEOUT    "S"            // string to query.
#define  PBUNDERLINE    "U"            // string to query.
#define  FONTPB_PUBLISHERINFO "Rick Miller"
#define  FONTPB_VERSIONINFO   "5.0210"
//---------------------------------------------------------------//
//          fontpb constructor
//---------------------------------------------------------------//
class fontpb(parentObj) of pushbutton(parentObj) custom

   // methods and properties have been left exposed.

   with (this)
      onClick           =  class::onClick
      onRightDblClick   =  class::onRightDblClick
      onOpen            =  class::onOpen
      text              =  PBDEFAULTTEXT
   endwith

   this.debug  =  false
   this.runtime   =  iif("run" $ lower(version(0)), true, false)
   this.versioninfo  =  FONTPB_VERSIONINFO
   this.publishinfo  =  FONTPB_PUBLISHERINFO

   //------------------------------------------------------------//
   //       end of constructor   -  methods below
   //------------------------------------------------------------//
   // assign the passed oRef properties with this.font[] values.
   // Note: with/endwith is not used for added
   //       compatibility when assigning properties
   //       to a non GUI object.
   function assignFont(oRef)
      oRef.fontname  =  this.font["name"]
      oRef.fontsize  =  this.font["size"]
      oRef.fontbold  =  this.font["bold"]
      oRef.fontitalic   =  this.font["italic"]
      oRef.fontstrikeout   =  this.font["strikeout"]
      oRef.fontunderline   =  this.font["underline"]
   return

   //------------------------------------------------------------//
   // stuff keystrokes into the keyboard buffer
   // for the getFont dialog to use.
   function loadGetFont
      Local cStyl
      cStyl =  PBFONTREGULAR

      // the dialog opens on the font name combobox.
      // use current font["name"] information.
      keyboard(this.font["name"])

      // move to the next control in dialog.
      // this will be the font style combobox.
      keyboard("{Tab}")
      // use the current font style information.
      if this.font["bold"]
         // re-assign cStyl.
         cStyl := PBFONTBOLD
      endif
      if this.font["italic"]
         if cStyl == PBFONTBOLD
            // already has Bold in it.
            // append onto it.
            cStyl += " " + PBFONTITALIC
         else
            // re-assign cStyl.
            cStyl := PBFONTITALIC
         endif
      endif
      keyboard(cStyl)

      // move to next control in dialog.
      // this will be the font size combobox.
      keyboard("{Tab}")
      // key the current font["size"] information.
      keyboard("" + int(this.font["size"]))

      // move to the next control in dialog.
      // this will be the font strikeout checkbox.
      keyboard("{Tab}")
      if this.font["strikeout"]
         // mark the checkbox.
         keyboard("{Space}")
      endif

      // move to the next control in dialog.
      // this will be the font underline checkbox.
      keyboard("{Tab}")
      if this.font["underline"]
         // mark the checkbox.
         keyboard("{Space}")
      endif

      // move to font name in the dialog.
      keyboard("{Tab}")
      keyboard("{Tab}")
      keyboard("{Tab}")
      keyboard("{Tab}")

   return

   //------------------------------------------------------------//
   // normal use would override and callback.
   // see Example in header.
   function onClick
      Local bSbar, cFont, oActive
      bSbar =  iif(this.speedbar, true, false)
      // get a reference to the activecontrol.
      oActive  =  this.form.activecontrol
      if bSbar
         // re-assign speedbar property,
         // cuz this is going to receive focus.
         this.speedbar  := false
      endif
      if not oActive == this
         // make this the activecontrol,
         // so keyboard() does not interfere with
         // any other control on the form.
         this.setfocus()
      endif
      if not type("this.font") == "O"
         // just in case the onOpen was overridden
         // and no callback was done at that time.
         // call the onOpen in this file.
         class::onOpen()
      endif
      if this.form.mdi
         // pre-load the getFont() dialog.
         this.loadGetFont()
      endif

      //---------------------------------------//
      // call the dBL getFont dialog.
      cFont =  getFont()
      //---------------------------------------//

      if not empty(cFont)
         // a font selection was made.
         // assign the selection to this.font[].
         this.setFont(cFont)
         this.setFontText(cFont)
      endif
      // insure focus moves back to the form.
      oActive.setfocus()
      if bSbar
         // re-assign the speedbar property
         // to it's original value.
         this.speedbar  := true
      endif
   return not empty(cFont)

   //------------------------------------------------------------//
   // create and assign this.font[] assocarray.
   function onOpen
      this.font   =  new assocarray()
      this.font["name"] =  (this.fontname)
      this.font["size"] =  int(this.fontsize)
      this.font["bold"] =  (this.fontbold)
      this.font["italic"]  =  (this.fontitalic)
      this.font["strikeout"]  =  (this.fontstrikeout)
      this.font["underline"]  =  (this.fontunderline)
      this.setFontText(false)
   return

   //------------------------------------------------------------//
   // display control version when in the IDE.
   // turn debug of control on/off ?
   function onRightDblClick(flags, col, row)
      if not this.runtime
         if msgbox( ;
            this.classname + ": Version " + FONTPB_VERSIONINFO,;
            "Set fontpb debug " + iif(this.debug, "OFF", "ON") +;
            " ?", 36 + 256) == 6
            this.debug  := not this.debug
         endif
      endif
   return

   //------------------------------------------------------------//
   // assign this.font[] assocarray values.
   function setFont(cFont)
      Local nAt1, nAt2, nAt3, nLen, cStyl, cText
      // strip off trailing ",Roman" ",Swiss" and others.
      do case
         case cFont.indexof(PBREMOVETEXT1) > 0
            cText =  cFont.left(cFont.indexof(PBREMOVETEXT1))
         case cFont.indexof(PBREMOVETEXT2) > 0
            cText =  cFont.left(cFont.indexof(PBREMOVETEXT2))
         case cFont.indexof(PBREMOVETEXT3) > 0
            cText =  cFont.left(cFont.indexof(PBREMOVETEXT3))
         case cFont.indexof(PBREMOVETEXT4) > 0
            cText =  cFont.left(cFont.indexof(PBREMOVETEXT4))
         case cFont.indexof(PBREMOVETEXT5) > 0
            cText =  cFont.left(cFont.indexof(PBREMOVETEXT5))
         otherwise
            cText =  (cFont)
      endcase

      nLen  =  cText.length
      // Note: getFont() may return:
      //       1, 2, or 3 commas.
      //       suffix of Roman, Swiss, others or no suffix.
      // assign nAt? variables
      // relative to any remaining "," (commas)
      // for parsing during evaluation.
      nAt1  =  cText.indexof(",")
      nAt2  =  cText.indexof(",", nAt1 + 1)
      if nAt2 > 0
         // there is a 2nd "," (comma).
         nAt3  =  cText.indexof(",", nAt2 + 1)
         if nAt3 < 0
            // there is NOT a 3rd "," (comma).
            nAt3  := nLen
         endif
      else
         // there is NOT a 2nd "," (comma).
         nAt2  := nLen
         nAt3  =  nLen
      endif

      // extract the font name.
      this.font["name"] =  cText.left(nAt1)

      // extract the font size.
      this.font["size"] =  ;
         int(val(cText.substring(nAt1 + 1, nAt2)))

      // extract the font style.
      cStyl =  cText.substring(nAt2, nAt3)
      this.font["bold"]    =  ;
         iif(cStyl.indexof(PBBOLD) > -1, true, false)
      this.font["italic"]  =  ;
         iif(cStyl.indexof(PBITALIC) > -1, true, false)
      this.font["strikeout"]  =  ;
         iif(cStyl.indexof(PBSTRIKEOUT) > -1, true, false)
      this.font["underline"]  =  ;
         iif(cStyl.indexof(PBUNDERLINE) > -1, true, false)
      if this.debug and not this.runtime
         Local cSp
         cSp   =  space(3) + "<"
         ?
         ? " " + FONTPBDEBUG
         ? cSp + cFont + ">"
         ? cSp + cText + ">"
         ? cSp + nAt1 + ">" +;
            cSp + nAt2 + ">" +;
            cSp + nAt3 + ">"
         ? cSp + cText.left(nAt1) +;
            "><" + cText.substring(nAt1 + 1, nAt2) +;
            "><" + cStyl + ">"
      endif
   return

   //------------------------------------------------------------//
   // assign this.font["text"] assocarray value.
   function setFontText(cFont)
      if type("argvector(1)") == "C"
         // a string was passed, so use it.
         this.font["text"] =  (cFont)
      else
         // a string was not passed.
         // create the string from this.font[] assocarray.
         Local cStyl
         cStyl =  iif(this.font["bold"], PBBOLD, "")
         cStyl += iif(this.font["italic"], PBITALIC, "")
         cStyl += iif(this.font["underline"], PBUNDERLINE, "")
         cStyl += iif(this.font["strikeout"], PBSTRIKEOUT, "")
         this.font["text"] =  ;
            this.font["name"] + "," +;
            int(this.font["size"]) +;
            iif(empty(cStyl), "", "," + cStyl)
      endif
   return

endclass
//---------------------------------------------------------------//
//          end of fontpb
//---------------------------------------------------------------//