In case anyone else would find it useful, I've finally managed to tune up my handlers for LiveCode printing from a Mac laptop, designed to avoid any unnecessary printing dialogs. This is useful if you, like me, use a LiveCode app on your laptop in a number of different venues and need to print using the currently connected printer. I got annoyed that every time I switched venues I had to tell the system what printer to use (I do a lot of printing of patient notes, prescriptions, etc.). The system knows what's connected, right? So if I have one and only one printer connected why should it have to ask me to choose my printer?

The set of handlers below will detect the currently available printer, whether connected by USB or on a wireless network, and automatically send the print job to that printer (if I'm printing from a LiveCode script).

The way it works is this -- the IO registry is queried with a shell call and the result is parsed to identify USB-connected printers (not a foolproof algorithm, but seems to work so far). If the IOR listing is already associated with a printer name then that printer is used, all done. If no printer name has been associated with the IOR listing then the user is asked to identify the printer to be used and the IOR listing / printerName association is stored as a custom prop, so that thereafter it will be used automatically.

If there are no USB printers identified, a shell call fetches the MAC address of any wireless network you are connected to. If none, then the user gets "not connected to any printer," and printing is aborted. Otherwise, the user is asked once, as above, to identify the printer on that network, and the MAC address / printerName association is stored for future use.

To use, just call "checkPrinter" before any printing command in LiveCode, and everything else is taken care of. Should work on Mac laptops. Sorry, I don't have a Windows or Linux laptop to develop the corresponding routines on for the other OSes, but that should be do- able for anyone with the need.

Thanks to the dozen or more members of this list that have helped me with ideas, shell calls, etc. I absolutely could not have done it without you.

-- Peter

Peter M. Brigham
[email protected]
http://home.comcast.net/~pmbrig

-----------------

constant storageStack = "<yourStackNameHere>"
-- the short name of the stack that stores the customprops for the printer names

on checkPrinter printingWhat
   if the controlkey is down then
      -- bypass the routines entirely
      answer printer
      exit checkPrinter
   end if
-- get listing of connected printer in IO registry, and MAC address for wireless
   put getActivePrinter() into tLivePrinterInIOR
   put sr(tLivePrinterInIOR) into tLivePrinterInIOR
   put tLivePrinterInIOR into IORrawPrinterList
   put the printername into origPrinterName
   put getWirelessMACaddress() into MACaddr

   if tLivePrinterInIOR = empty then
      -- no USB printer detected
      if MACaddr = empty then
put "You are not connected to any active printer. Please check that" && \ "your printer is turned on and connected properly." into cmt
         answer cmt as sheet
         exit to top -- abort printing
      else -- connected to a network
put the MACaddrToPrinterName[MACaddr] of stack storageStack into tLivePrinterName
         if tLivePrinterName <> empty then
            set the printername to tPossiblePrinterName
         else
put "Please choose the wireless printer on this network" && \
                   "so it can be identified in the future." into cmt
            answer cmt as sheet
            set the systemprintselector to true
            answer printer
            -- sets the printername (used by Rev for printing)
            if the result = "cancel" then exit to top
            -- abort printing
            put the printername into tPrinterName
set the MACaddrToPrinterName[MACaddr] of stack storageStack to tPrinterName
            -- store printer name for this device
         end if
         exit checkPrinter -- proceed to printing
      end if
   end if

-- the following is when there is a possible USB printer and no wireless printer

   -- more than one device might be a printer
   -- but we might know this printer already
   repeat for each line p in tLivePrinterInIOR
put the IORtoPrinterName[p] of stack "PDdata" into tPossiblePrinterName
      if tPossiblePrinterName <> empty then
         -- found a known printer, set it, then done
         set the printername to tPossiblePrinterName
         exit checkPrinter -- proceed to printing
      end if
   end repeat
   -- no known printers found,
   -- ask user to sort it out
   -- have to construct answer dialog
   -- with buttons for each device
   if the number of lines of tLivePrinterInIOR > 1 then
      put q("cancel") into btnList
      repeat for each line p in tLivePrinterInIOR
         put q(truncate(p,18)) into btnName
         put q(truncate(p,35)) into promptLine
         put " and " & btnName after btnList
         put " & cr &" && promptLine after promptList
      end repeat
put "There are several USB devices currently connected. Please identify the" \ && "one that is the printer so it will be recognized in the future:" \
             & quote & promptList into theDo
      put "answer" && quote before theDo
      put " with" && btnList && "as sheet" after theDo
      do theDo
      put it into whichDevice
      if whichDevice = "cancel" then exit to top
if char -1 of whichDevice = "…" then delete char -1 of whichDevice
      put lineoffsets(whichDevice,tLivePrinterInIOR) into pOffset
      if the number of items of pOffset > 1 then
answer "Having difficulty identifying your printer. Please unplug" \ && "all USB devices except the active printer and try printing again." \
                as sheet
         exit to top
      else
         put line pOffset of tLivePrinterInIOR into tLivePrinterInIOR
      end if
   end if
   -- now tLivePrinterInIOR contains one line
put the IORtoPrinterName[tLivePrinterInIOR] of stack "PDdata" into tLivePrinterName
   -- system prefs name of currently live printer,
   -- stored when printer first encountered
if origPrinterName = tLivePrinterName and origPrinterName <> empty then
      -- currently connected to the chosen printer,
      -- proceed to printing
      exit checkPrinter
   end if
   -- else:
   if tLivePrinterName = empty then
      -- never seen this printer
      setupicons
      put "Please choose the current printer (" & tLivePrinterInIOR & \
             ") so it can be identified in the future." into cmt
      answer cmt as sheet
      set the systemprintselector to true
      answer printer
      -- sets the printername (used by Rev for printing)
      if the result = "cancel" then exit to top
      -- abort printing
      put the printername into tPrinterName
set the IORtoPrinterName[tLivePrinterInIOR] of stack storageStack to tPrinterName
      -- store printer name for this device
   else if tCurrentRevPrinterName <> tLivePrinterName then
-- a different known printer is currently live, just tell Rev to use it
     set the printername to tLivePrinterName
   end if
end checkPrinter

function getUSBdevices
   --  returns list of currently connected USB devices
   --  with tab-indented list of properties for each

   -- get USB device info from system profiler
   set the hideconsolewindows to true
put shell("system_profiler -detailLevel full SPUSBDataType") into tData

   -- convert data to one line per USB device
replace (colon & cr & cr) with numToChar(245) in tData -- device name
   replace (cr & cr) with numtoChar(250) in tData
   replace cr with tab in tData
   replace numtoChar(245) with (colon & tab) in tData
   replace numtoChar(250) with cr in tData
   replace tab with cr & tab in tData
   repeat until cr & space is not in tData
      replace cr & space with cr in tData
   end repeat
   repeat until tab & space is not in tData
      replace tab & space with tab in tData
   end repeat
   delete word 1 of tData
   return tData
end getUSBdevices

function getWirelessMACaddress
put shell("cd /usr/sbin;system_profiler SPNetworkDataType #####REVEXCLUDEDSTRING#####grep -i signature") into s
   set the itemdel to "="
   put line 1 of (item -1 of s) into tMAC
   return tMAC
end getWirelessMACaddress

function getActivePrinter
   set the hideconsolewindows to true
   put shell("ioreg") into tList
   filter tList with "*<class IOUSBDevice*"
   filter tList without "*UserClient*"
   filter tList without "*Keyboard*"
   filter tList without "* IR *"
   filter tList without "*Wireless*"
   filter tList without "*mouse*"
   filter tList without "*iSight*"
   filter tList without "*Store 'n' Go*"
   filter tList without "*iPhone*"

   -- more filtering needed for other devices?

   filter tList without empty
   repeat for each line d in tList
      -- could be more than one
      put offset("+-o",d)+4 into startChar
      put offset("@",d)-1 into endChar
      put (char startChar to endChar of d) & cr after printerList
   end repeat
   delete char -1 of printerList
   return printerList
end getActivePrinter

function sr str
   -- strips white space fore and aft
   return word 1 to -1 of str
end sr

function q str
   return quote & str & quote
end q

function truncate str, n
   -- returns a string of at most n chars
   if length(str) <= n then return str
   return char 1 to n-1 of str & "…" -- ellipsis
end truncate

function offsets str,ctr
   -- returns a comma-delimited list of all the offsets of str in ctr
   put "" into mosList
   put 0 into startPoint
   repeat
      put offset(str,ctr,startPoint) into os
      if os = 0 then exit repeat
      add os to startPoint
      put startPoint & "," after mosList
   end repeat
   if char -1 of mosList = "," then delete last char of mosList
   if mosList = "" then return "0"
   return mosList
end offsets

function lineOffsets str,ctr
-- returns a comma-delimited list of all the lineoffsets of str in ctr
   put offsets(str,ctr) into charList
   if charList = "0" then return "0"
   put the number of items of charList into nbr
   put "" into mlo
   repeat for each item n in charList
      put the number of lines of (char 1 to n of ctr) & "," after mlo
   end repeat
   if char -1 of mlo = "," then delete char -1 of mlo
   return mlo
end lineOffsets

_______________________________________________
use-revolution mailing list
[email protected]
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution

Reply via email to