GetPrinters() and GetDefaultPrinter()

Post Reply
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

GetPrinters() and GetDefaultPrinter()

Post by xProgrammer »

Hi all

Neither of these functions exist in the LInux version of xHarbour apparently. I have just written such functions. My Linux version of GetPrinters() supports the first parameter (lPortInfo) but not the second one (lLocalPrinters). I have used the lpstat command to retrieve the necessary information. The xHarbour code is as follows:

Code: Select all

FUNCTION GetPrinters( xPortInfo )

LOCAL sOSCommand
LOCAL sPrinterInfo
LOCAL iFileHandle
LOCAL iEndOffset
LOCAL sPrinterLine
LOCAL sPrinterName
LOCAL aPrinters
LOCAL aPrinter

IF PCOUNT() < 1
   lPortInfo := .F.
  ELSE
   lPortInfo := xPortInfo
ENDIF 
aPrinters := ARRAY( 0 )
sOSCommand := "lpstat -s > lpstat.txt"
RUN ( sOSCommand )
iFileHandle := FOpen( "lpstat.txt" )
DO WHILE HB_FReadLine( iFileHandle, @sPrinterLine, CHR(10) ) = 0
   sTest := SUBSTR( sPrinterLine, 1, 11 )
   IF sTest = "device for "
      sTest := SUBSTR( sPrinterLine, 12 )
      iEndOffset := AT( ": ", sTest )
      IF iEndOffset > 0
         sPrinterName := SUBSTR( sTest, 1, iEndOffset - 1 )
         IF lPortInfo
            sPrinterInfo := SUBSTR( sTest, iEndOffset + 2 )
            aPrinter := ARRAY( 2 )
            aPrinter[1] := sPrinterName
            aPrinter[2] := sPrinterInfo
            AAdd( aPrinters, aPrinter )
           ELSE
            AAdd( aPrinters, sPrinterName )
         ENDIF       
      ENDIF
   ENDIF
ENDDO
FClose( iFileHandle )
RETURN aPrinters


FUNCTION GetDefaultPrinter()

LOCAL sOSCommand
LOCAL sPrinterInfo
LOCAL iFileHandle
LOCAL sPrinterLine
LOCAL sPrinterName
 
aPrinters := ARRAY( 0 )
sOSCommand := "lpstat -s > lpstat.txt"
RUN ( sOSCommand )
iFileHandle := FOpen( "lpstat.txt" )
DO WHILE HB_FReadLine( iFileHandle, @sPrinterLine, CHR(10) ) = 0
   sTest := SUBSTR( sPrinterLine, 1, 27 )
   IF sTest = "system default destination:"
      FClose( iFileHandle )
      RETURN ALLTRIM( SUBSTR( sPrinterLine, 28 ) )
   ENDIF
ENDDO
FClose( iFileHandle )

RETURN ""
The above work fine on Ubuntu 8.04 (my system) but should work on most Linux systems I believe. Having written the above it would be easy to create IsPrinter(), PrinterExists() and PrinterPortToName() functions if anyone needs them.

Regards
xProgrammer
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Using a PRINTERS Class

Post by xProgrammer »

Hi all

The code in the above post gave a fairly high degree of compatability with the Windows version of xHarbour but was a bit inefficient. I reworked the logic into a PRINTERS class without trying to be call compatible with the Windows version. This class is quite functional as it stands but doesn't include any error handling code. It will probably later on get a printer selection dialog.

Code: Select all

#include "hbclass.ch"

CLASS PRINTERS

DATA aNames          /** array of printer names */
DATA aPorts          /** array of printer ports */
DATA iCount          /** number of printers installed */
DATA sDefault        /** name of default printer */
DATA iDefault        /** number of default printer - index into aNames and aPorts */
DATA lDefault        /** is there a default printer */
DATA lExists         /** is any printer defined */

METHOD New( plGetList ) CONSTRUCTOR
METHOD GetList()

ENDCLASS


METHOD New( plGetList ) CLASS PRINTERS

/** _syntax: PRINTERS():New( [<lGetList>] )
    _arguments: 
                  <lGetList> a logical value  
                      If .T. the operating system is queried and printer lists and defaults are set as part of the object's initialisation.  
                      Defaults to .T.
    _returns:     the created PRINTERS object
    _description: see METHOD GetList() for a description of how the operating system is queried  */

IF PCOUNT() < 1
   lGetList := .T.
  ELSE
   lGetList := plGetList
ENDIF

IF lGetList
   ::GetList()
ENDIF

RETURN self


METHOD GetList() CLASS PRINTERS

/** _syntax:      <PRINTERS_object>:GetList()
    _arguments:   none
    _returns:     nil
    _description: Obtains information on installed printers from the operating system by RUNning lpstat -s > lpstat.txt.
                  Opens the redirected output of the above command and parses that file building a list of printernames (in ::aNames)
                      and ports (in ::aPorts).
                  Retrieves the name of the default printer (in ::sDefault) and determines its position (in ::iDefault)
                  If there is no default printer ::lDefault is set to .F.
                  Determines if there are any printers installed (in ::lExists) and how many are installed (in ::iCount) */


LOCAL iFileHandle
LOCAL sPrinterLine
LOCAL sTest
LOCAL iEndOffset
LOCAL lDefaultFound
LOCAL ii

::aNames := ARRAY( 0 )
::aPorts := ARRAY( 0 )
::iCount := 0
::sDefault := ""
::iDefault := 0
::lDefault := .F.
::lExists := .F.

RUN lpstat -s > lpstat.txt
iFileHandle := FOpen( "lpstat.txt" )
DO WHILE HB_FReadLine( iFileHandle, @sPrinterLine, CHR(10) ) = 0
   sTest := SUBSTR( sPrinterLine, 1, 11 )
   IF sTest = "device for "
      sTest := SUBSTR( sPrinterLine, 12 )
      iEndOffset := AT( ": ", sTest )
      IF iEndOffset > 0
         AAdd( ::aNames, ALLTRIM( SUBSTR( sTest, 1, iEndOffset - 1 ) ) )
         AAdd( ::aPorts, SUBSTR( sTest, iEndOffset + 2 ) )
         ::iCount += 1
         ::lExists := .T.
      ENDIF
     ELSE
      sTest := SUBSTR( sPrinterLine, 1, 27 )
      IF sTest = "system default destination:"
         ::sDefault := ALLTRIM( SUBSTR( sPrinterLine, 28 ) )
         ::lDefault := .T.         
      ENDIF
   ENDIF
ENDDO
FClose( iFileHandle )
IF ::lDefault
   FOR ii = 1 TO ::iCount
      IF ::aNames[ii] = ::sDefault
         ::iDefault := ii
         EXIT
      ENDIF
   NEXT
ENDIF

RETURN nil
Post Reply