diff --git a/gfx/src/qt/nsDeviceContextQT.cpp b/gfx/src/qt/nsDeviceContextQT.cpp index ae787fe730c7..d5ca9402cf55 100644 --- a/gfx/src/qt/nsDeviceContextQT.cpp +++ b/gfx/src/qt/nsDeviceContextQT.cpp @@ -22,6 +22,7 @@ * Contributor(s): * John C. Griggs * Esben Mose Hansen + * Roland Mainz * * * Alternatively, the contents of this file may be used under the terms of @@ -51,11 +52,16 @@ #include "nsFont.h" #include "nsGfxCIID.h" #include "nsRenderingContextQT.h" +#include "nsDeviceContextSpecQT.h" #ifdef USE_POSTSCRIPT #include "nsGfxPSCID.h" #include "nsIDeviceContextPS.h" -#endif +#endif /* USE_POSTSCRIPT */ +#ifdef USE_XPRINT +#include "nsGfxXPrintCID.h" +#include "nsIDeviceContextXPrint.h" +#endif /* USE_XPRINT */ #include #include @@ -384,36 +390,68 @@ NS_IMETHODIMP nsDeviceContextQT::GetClientRect(nsRect &aRect) return GetRect(aRect); } -NS_IMETHODIMP -nsDeviceContextQT::GetDeviceContextFor(nsIDeviceContextSpec *aDevice, - nsIDeviceContext *&aContext) +NS_IMETHODIMP nsDeviceContextQT::GetDeviceContextFor(nsIDeviceContextSpec *aDevice, + nsIDeviceContext *&aContext) { - dmsg(ENTER, "GetDeviceContextFor"); - nsresult rv; -#ifdef USE_POSTSCRIPT - static NS_DEFINE_CID(kCDeviceContextPS,NS_DEVICECONTEXTPS_CID); + nsresult rv; + PrintMethod method; + nsDeviceContextSpecQT *spec = NS_STATIC_CAST(nsDeviceContextSpecQT *, aDevice); - // Create a Postscript device context - nsIDeviceContextPS *dcps; - - rv = nsComponentManager::CreateInstance(kCDeviceContextPS,nsnull, - NS_GET_IID(nsIDeviceContextPS), - (void**)&dcps); - NS_ASSERTION(NS_SUCCEEDED(rv),"Couldn't create PS Device context"); - - dcps->SetSpec(aDevice); - dcps->InitDeviceContextPS((nsIDeviceContext*)aContext, - (nsIDeviceContext*)this); + rv = spec->GetPrintMethod(method); + if (NS_FAILED(rv)) + return rv; - rv = dcps->QueryInterface(NS_GET_IID(nsIDeviceContext), - (void**)&aContext); - NS_RELEASE(dcps); -#else - //XXX add xprint support - rv = NS_ERROR_NOT_IMPLEMENTED; -#endif - dmsg(EXIT, "GetDeviceContextFor"); - return rv; +#ifdef USE_XPRINT + if (method == pmXprint) { // XPRINT + static NS_DEFINE_CID(kCDeviceContextXp, NS_DEVICECONTEXTXP_CID); + nsCOMPtr dcxp(do_CreateInstance(kCDeviceContextXp, &rv)); + NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create Xp Device context."); + if (NS_FAILED(rv)) + return rv; + + rv = dcxp->SetSpec(aDevice); + if (NS_FAILED(rv)) + return rv; + + rv = dcxp->InitDeviceContextXP((nsIDeviceContext*)aContext, + (nsIDeviceContext*)this); + if (NS_FAILED(rv)) + return rv; + + rv = dcxp->QueryInterface(NS_GET_IID(nsIDeviceContext), + (void **)&aContext); + return rv; + } + else +#endif /* USE_XPRINT */ +#ifdef USE_POSTSCRIPT + if (method == pmPostScript) { // PostScript + // default/PS + static NS_DEFINE_CID(kCDeviceContextPS, NS_DEVICECONTEXTPS_CID); + + // Create a Postscript device context + nsCOMPtr dcps(do_CreateInstance(kCDeviceContextPS, &rv)); + NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create PS Device context."); + if (NS_FAILED(rv)) + return rv; + + rv = dcps->SetSpec(aDevice); + if (NS_FAILED(rv)) + return rv; + + rv = dcps->InitDeviceContextPS((nsIDeviceContext*)aContext, + (nsIDeviceContext*)this); + if (NS_FAILED(rv)) + return rv; + + rv = dcps->QueryInterface(NS_GET_IID(nsIDeviceContext), + (void **)&aContext); + return rv; + } +#endif /* USE_POSTSCRIPT */ + + NS_WARNING("no print module created."); + return NS_ERROR_UNEXPECTED; } NS_IMETHODIMP nsDeviceContextQT::BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage) diff --git a/gfx/src/qt/nsDeviceContextSpecFactoryQT.cpp b/gfx/src/qt/nsDeviceContextSpecFactoryQT.cpp index 6b803cf84b8d..0c1a3897d4be 100644 --- a/gfx/src/qt/nsDeviceContextSpecFactoryQT.cpp +++ b/gfx/src/qt/nsDeviceContextSpecFactoryQT.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -16,11 +16,11 @@ * * The Initial Developer of the Original Code is * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 + * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * John C. Griggs + * Roland Mainz * * * Alternatively, the contents of this file may be used under the terms of @@ -39,84 +39,43 @@ #include "nsDeviceContextSpecFactoryQT.h" #include "nsDeviceContextSpecQT.h" -#include "nsRenderingContextQT.h" #include "nsGfxCIID.h" #include "plstr.h" -#include - -#include "qtlog.h" - -#ifdef DEBUG -PRUint32 gDCSpecFactoryCount = 0; -PRUint32 gDCSpecFactoryID = 0; -#endif - -/** ------------------------------------------------------- - * Constructor - * @update dc 2/16/98 - */ -nsDeviceContextSpecFactoryQT::nsDeviceContextSpecFactoryQT() -{ -#ifdef DEBUG - gDCSpecFactoryCount++; - mID = gDCSpecFactoryID++; - PR_LOG(gQTLogModule, QT_BASIC, - ("nsDeviceContextSpecFactoryQT CTOR (%p) ID: %d, Count: %d\n", - this, mID, gDCSpecFactoryCount)); -#endif - NS_INIT_ISUPPORTS(); -} - -/** ------------------------------------------------------- - * Destructor - * @update dc 2/16/98 - */ -nsDeviceContextSpecFactoryQT::~nsDeviceContextSpecFactoryQT() -{ -#ifdef DEBUG - gDCSpecFactoryCount--; - PR_LOG(gQTLogModule, QT_BASIC, - ("nsDeviceContextSpecFactoryQT DTOR (%p) ID: %d, Count: %d\n", - this, mID, gDCSpecFactoryCount)); -#endif -} - -static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); -static NS_DEFINE_IID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); NS_IMPL_ISUPPORTS1(nsDeviceContextSpecFactoryQT, nsIDeviceContextSpecFactory) -/** ------------------------------------------------------- - * Initialize the device context spec factory - * @update dc 2/16/98 - */ +nsDeviceContextSpecFactoryQT::nsDeviceContextSpecFactoryQT() +{ + NS_INIT_ISUPPORTS(); +} + +nsDeviceContextSpecFactoryQT::~nsDeviceContextSpecFactoryQT() +{ +} + NS_IMETHODIMP nsDeviceContextSpecFactoryQT::Init(void) { - return NS_OK; + return NS_OK; } -/** ------------------------------------------------------- - * Get a device context specification - * @update dc 2/16/98 - */ -NS_IMETHODIMP -nsDeviceContextSpecFactoryQT::CreateDeviceContextSpec(nsIWidget *aWidget, - nsIPrintSettings* aPrintSettings, - nsIDeviceContextSpec *&aNewSpec, - PRBool aIsPrintPreview) +NS_IMETHODIMP nsDeviceContextSpecFactoryQT::CreateDeviceContextSpec(nsIWidget *aWidget, + nsIPrintSettings* aPrintSettings, + nsIDeviceContextSpec *&aNewSpec, + PRBool aIsPrintPreview) { - nsresult rv = NS_ERROR_FAILURE; - nsIDeviceContextSpec *devSpec = nsnull; - - nsComponentManager::CreateInstance(kDeviceContextSpecCID,nsnull, - kIDeviceContextSpecIID, - (void **)&devSpec); - - if (nsnull != devSpec) { - if (NS_OK == ((nsDeviceContextSpecQT*)devSpec)->Init(aPrintSettings)) { - aNewSpec = devSpec; - rv = NS_OK; - } + nsresult rv; + static NS_DEFINE_CID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); + nsCOMPtr devSpec = do_CreateInstance(kDeviceContextSpecCID, &rv); + if (NS_SUCCEEDED(rv)) + { + rv = ((nsDeviceContextSpecQT *)devSpec.get())->Init(aPrintSettings); + if (NS_SUCCEEDED(rv)) + { + aNewSpec = devSpec; + NS_ADDREF(aNewSpec); } - return rv; + } + + return rv; } + diff --git a/gfx/src/qt/nsDeviceContextSpecFactoryQT.h b/gfx/src/qt/nsDeviceContextSpecFactoryQT.h index 43e4bb8ce0cb..d487eeee8d7f 100644 --- a/gfx/src/qt/nsDeviceContextSpecFactoryQT.h +++ b/gfx/src/qt/nsDeviceContextSpecFactoryQT.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -16,11 +16,11 @@ * * The Initial Developer of the Original Code is * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 + * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * John C. Griggs + * Roland Mainz * * * Alternatively, the contents of this file may be used under the terms of @@ -45,23 +45,20 @@ class nsDeviceContextSpecFactoryQT : public nsIDeviceContextSpecFactory { + public: - nsDeviceContextSpecFactoryQT(); + nsDeviceContextSpecFactoryQT(); - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS - NS_IMETHOD Init(void); - NS_IMETHOD CreateDeviceContextSpec(nsIWidget *aWidget, - nsIPrintSettings* aPrintSettings, - nsIDeviceContextSpec *&aNewSpec, - PRBool aIsPrintPreview); + NS_IMETHOD Init(void); + NS_IMETHOD CreateDeviceContextSpec(nsIWidget *aWidget, + nsIPrintSettings* aPrintSettings, + nsIDeviceContextSpec *&aNewSpec, + PRBool aIsPrintPreview); protected: - virtual ~nsDeviceContextSpecFactoryQT(); -#ifdef DEBUG -private: - PRUint32 mID; -#endif + virtual ~nsDeviceContextSpecFactoryQT(); }; -#endif +#endif /* !nsDeviceContextSpecFactoryQT_h___ */ diff --git a/gfx/src/qt/nsDeviceContextSpecQT.cpp b/gfx/src/qt/nsDeviceContextSpecQT.cpp index a03b68f334b9..c99918dfb261 100644 --- a/gfx/src/qt/nsDeviceContextSpecQT.cpp +++ b/gfx/src/qt/nsDeviceContextSpecQT.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -20,7 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * John C. Griggs + * Roland Mainz * * * Alternatively, the contents of this file may be used under the terms of @@ -36,136 +36,283 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +/* Store per-printer features in temp. prefs vars that the + * print dialog can pick them up... */ +#define SET_PRINTER_FEATURES_VIA_PREFS 1 +#define PRINTERFEATURES_PREF "print.tmp.printerfeatures" + +#define FORCE_PR_LOG /* Allow logging in the release build */ +#define PR_LOGGING 1 +#include "prlog.h" #include "nsDeviceContextSpecQT.h" -#include "nsRenderingContextQT.h" -#include "nsIPrefBranch.h" -#include "nsIPrefService.h" +#include "nsIPref.h" #include "prenv.h" /* for PR_GetEnv */ -#include "nsIServiceManagerUtils.h" + +#include "nsPrintfCString.h" #include "nsReadableUtils.h" +#include "nsIServiceManager.h" +#include "nsCRT.h" -#include +#ifdef USE_XPRINT +#include "xprintutil.h" +#endif /* USE_XPRINT */ -#include "qtlog.h" +#ifdef USE_POSTSCRIPT +/* Fetch |postscript_module_paper_sizes| */ +#include "nsPostScriptObj.h" +#endif /* USE_POSTSCRIPT */ -#ifdef DEBUG -PRUint32 gDCSpecCount = 0; -PRUint32 gDCSpecID = 0; -#endif +/* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */ +#define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE)) + +#ifdef PR_LOGGING +static PRLogModuleInfo *DeviceContextSpecQTLM = PR_NewLogModule("DeviceContextSpecQT"); +#endif /* PR_LOGGING */ +/* Macro to make lines shorter */ +#define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecQTLM, PR_LOG_DEBUG, x) + +//---------------------------------------------------------------------------------- +// The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecQT +// The PrinterEnumerator creates the printer info +// but the nsDeviceContextSpecQT cleans it up +// If it gets created (via the Page Setup Dialog) but the user never prints anything +// then it will never be delete, so this class takes care of that. +class GlobalPrinters { +public: + static GlobalPrinters* GetInstance() { return &mGlobalPrinters; } + ~GlobalPrinters() { FreeGlobalPrinters(); } + + void FreeGlobalPrinters(); + nsresult InitializeGlobalPrinters(); + + PRBool PrintersAreAllocated() { return mGlobalPrinterList != nsnull; } + PRInt32 GetNumPrinters() { return mGlobalNumPrinters; } + nsString* GetStringAt(PRInt32 aInx) { return mGlobalPrinterList->StringAt(aInx); } + void GetDefaultPrinterName(PRUnichar **aDefaultPrinterName); + +protected: + GlobalPrinters() {} + + static GlobalPrinters mGlobalPrinters; + static nsStringArray* mGlobalPrinterList; + static int mGlobalNumPrinters; +}; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS +/* "Prototype" for the new nsPrinterFeatures service */ +class nsPrinterFeatures { +public: + nsPrinterFeatures( const char *printername ); + ~nsPrinterFeatures() {}; + + /* Does this device allow to set/change the paper size ? */ + void SetCanChangePaperSize( PRBool aCanSetPaperSize ); + /* Set number of paper size records and the records itself */ + void SetNumPaperSizeRecords( PRInt32 aCount ); + void SetPaperRecord( PRInt32 aIndex, const char *aName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch ); + + /* Does this device allow to set/change the content orientation ? */ + void SetCanChangeOrientation( PRBool aCanSetOrientation ); + /* Set number of orientation records and the records itself */ + void SetNumOrientationRecords( PRInt32 aCount ); + void SetOrientationRecord( PRInt32 aIndex, const char *aName ); + + /* Does this device allow to set/change the spooler command ? */ + void SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ); + + /* Does this device allow to set/change number of copies for an document ? */ + void SetCanChangeNumCopies( PRBool aCanSetNumCopies ); + +private: + /* private helper methods */ + void SetBoolValue( const char *tagname, PRBool value ); + void SetIntValue( const char *tagname, PRInt32 value ); + void SetCharValue( const char *tagname, const char *value ); + + nsXPIDLCString mPrinterName; + nsCOMPtr mPrefs; +}; + +void nsPrinterFeatures::SetBoolValue( const char *tagname, PRBool value ) +{ + mPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); +} + +void nsPrinterFeatures::SetIntValue( const char *tagname, PRInt32 value ) +{ + mPrefs->SetIntPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); +} + +void nsPrinterFeatures::SetCharValue( const char *tagname, const char *value ) +{ + mPrefs->SetCharPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); +} + +nsPrinterFeatures::nsPrinterFeatures( const char *printername ) +{ + DO_PR_DEBUG_LOG(("nsPrinterFeatures::nsPrinterFeatures('%s')\n", printername)); + mPrinterName.Assign(printername); + mPrefs = do_GetService(NS_PREF_CONTRACTID); + + SetBoolValue("has_special_printerfeatures", PR_TRUE); +} + +void nsPrinterFeatures::SetCanChangePaperSize( PRBool aCanSetPaperSize ) +{ + SetBoolValue("can_change_paper_size", aCanSetPaperSize); +} + +/* Set number of paper size records and the records itself */ +void nsPrinterFeatures::SetNumPaperSizeRecords( PRInt32 aCount ) +{ + SetIntValue("paper.count", aCount); +} + +void nsPrinterFeatures::SetPaperRecord(PRInt32 aIndex, const char *aPaperName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch) +{ + SetCharValue(nsPrintfCString(256, "paper.%d.name", aIndex).get(), aPaperName); + SetIntValue( nsPrintfCString(256, "paper.%d.width_mm", aIndex).get(), aWidthMM); + SetIntValue( nsPrintfCString(256, "paper.%d.height_mm", aIndex).get(), aHeightMM); + SetBoolValue(nsPrintfCString(256, "paper.%d.is_inch", aIndex).get(), aIsInch); +} + +void nsPrinterFeatures::SetCanChangeOrientation( PRBool aCanSetOrientation ) +{ + SetBoolValue("can_change_orientation", aCanSetOrientation); +} + +void nsPrinterFeatures::SetNumOrientationRecords( PRInt32 aCount ) +{ + SetIntValue("orientation.count", aCount); +} + +void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName ) +{ + SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName); +} + +void nsPrinterFeatures::SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ) +{ + SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand); +} + +void nsPrinterFeatures::SetCanChangeNumCopies( PRBool aCanSetNumCopies ) +{ + SetBoolValue("can_change_num_copies", aCanSetNumCopies); +} + +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + +//--------------- +// static members +GlobalPrinters GlobalPrinters::mGlobalPrinters; +nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull; +int GlobalPrinters::mGlobalNumPrinters = 0; +//--------------- -/** ------------------------------------------------------- - * Construct the nsDeviceContextSpecQT - * @update dc 12/02/98 - */ nsDeviceContextSpecQT::nsDeviceContextSpecQT() { -#ifdef DEBUG - gDCSpecCount++; - mID = gDCSpecID++; - PR_LOG(gQTLogModule, QT_BASIC, - ("nsDeviceContextSpecQT CTOR (%p) ID: %d, Count: %d\n", - this, mID, gDCSpecCount)); -#endif + DO_PR_DEBUG_LOG(("nsDeviceContextSpecQT::nsDeviceContextSpecQT()\n")); NS_INIT_ISUPPORTS(); } -/** ------------------------------------------------------- - * Destroy the nsDeviceContextSpecQT - * @update dc 2/15/98 - */ nsDeviceContextSpecQT::~nsDeviceContextSpecQT() { -#ifdef DEBUG - gDCSpecCount--; - PR_LOG(gQTLogModule, QT_BASIC, - ("nsDeviceContextSpecQT DTOR (%p) ID: %d, Count: %d\n", - this, mID, gDCSpecCount)); -#endif + DO_PR_DEBUG_LOG(("nsDeviceContextSpecQT::~nsDeviceContextSpecQT()\n")); } -static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); -#ifdef USE_POSTSCRIPT -static NS_DEFINE_IID(kIDeviceContextSpecPSIID, NS_IDEVICE_CONTEXT_SPEC_PS_IID); +/* Use both PostScript and Xprint module */ +#if defined(USE_XPRINT) && defined(USE_POSTSCRIPT) +NS_IMPL_ISUPPORTS3(nsDeviceContextSpecQT, + nsIDeviceContextSpec, + nsIDeviceContextSpecPS, + nsIDeviceContextSpecXp) +/* Use only PostScript module */ +#elif !defined(USE_XPRINT) && defined(USE_POSTSCRIPT) +NS_IMPL_ISUPPORTS2(nsDeviceContextSpecQT, + nsIDeviceContextSpec, + nsIDeviceContextSpecPS) +/* Use only Xprint module module */ +#elif defined(USE_XPRINT) && !defined(USE_POSTSCRIPT) +NS_IMPL_ISUPPORTS2(nsDeviceContextSpecQT, + nsIDeviceContextSpec, + nsIDeviceContextSpecXp) +/* Both Xprint and PostScript module are missing */ +#elif !defined(USE_XPRINT) && !defined(USE_POSTSCRIPT) +NS_IMPL_ISUPPORTS1(nsDeviceContextSpecQT, + nsIDeviceContextSpec) +#else +#error "This should not happen" #endif -NS_IMPL_ADDREF(nsDeviceContextSpecQT) -NS_IMPL_RELEASE(nsDeviceContextSpecQT) - -NS_IMETHODIMP nsDeviceContextSpecQT::QueryInterface(REFNSIID aIID, - void** aInstancePtr) -{ - if (nsnull == aInstancePtr) - return NS_ERROR_NULL_POINTER; - - if (aIID.Equals(kIDeviceContextSpecIID)) { - nsIDeviceContextSpec* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } -#ifdef USE_POSTSCRIPT - if (aIID.Equals(kIDeviceContextSpecPSIID)) { - nsIDeviceContextSpecPS* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } -#endif - static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - - if (aIID.Equals(kISupportsIID)) { - nsIDeviceContextSpec* tmp = this; - nsISupports* tmp2 = tmp; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - /** ------------------------------------------------------- * Initialize the nsDeviceContextSpecQT * @update dc 2/15/98 * @update syd 3/2/99 + * + * gisburn: Please note that this function exists as 1:1 copy in other + * toolkits including: + * - GTK+-toolkit: + * file: mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp + * function: NS_IMETHODIMP nsDeviceContextSpecGTK::Init() + * - Xlib-toolkit: + * file: mozilla/gfx/src/xlib/nsDeviceContextSpecQT.cpp + * function: NS_IMETHODIMP nsDeviceContextSpecQT::Init() + * - Qt-toolkit: + * file: mozilla/gfx/src/qt/nsDeviceContextSpecQT.cpp + * function: NS_IMETHODIMP nsDeviceContextSpecQT::Init() + * + * ** Please update the other toolkits when changing this function. */ -NS_IMETHODIMP nsDeviceContextSpecQT::Init(nsIPrintSettings* aPS) +NS_IMETHODIMP nsDeviceContextSpecQT::Init(nsIPrintSettings *aPS) { - nsresult rv = NS_ERROR_FAILURE; - NS_ASSERTION(aPS, "Must have a PrintSettings!"); + DO_PR_DEBUG_LOG(("nsDeviceContextSpecQT::Init(aPS=%p\n", aPS)); + nsresult rv = NS_ERROR_FAILURE; + + mPrintSettings = aPS; // if there is a current selection then enable the "Selection" radio button - if (aPS) { - mPrintSettings = aPS; + if (mPrintSettings) { PRBool isOn; - aPS->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, - &isOn); - nsCOMPtr prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv) && prefBranch) { - prefBranch->SetBoolPref("print.selection_radio_enabled", isOn); + mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); + nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + (void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn); } } - char *path; - PRBool reversed = PR_FALSE; - PRBool color = PR_FALSE; - PRBool tofile = PR_FALSE; - PRInt16 printRange = nsIPrintSettings::kRangeAllPages; - PRInt32 paper_size = NS_LETTER_SIZE; - PRInt32 orientation = NS_PORTRAIT; - PRInt32 fromPage = 1; - PRInt32 toPage = 1; - PRUnichar *command = nsnull; - PRUnichar *printfile = nsnull; - double dleft = 0.5; - double dright = 0.5; - double dtop = 0.5; - double dbottom = 0.5; + + rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); + if (NS_FAILED(rv)) { + return rv; + } + + GlobalPrinters::GetInstance()->FreeGlobalPrinters(); if (aPS) { + PRBool reversed = PR_FALSE; + PRBool color = PR_FALSE; + PRBool tofile = PR_FALSE; + PRInt16 printRange = nsIPrintSettings::kRangeAllPages; + PRInt32 orientation = NS_PORTRAIT; + PRInt32 fromPage = 1; + PRInt32 toPage = 1; + PRUnichar *command = nsnull; + PRInt32 copies = 1; + PRUnichar *printer = nsnull; + PRUnichar *papername = nsnull; + PRUnichar *printfile = nsnull; + double dleft = 0.5; + double dright = 0.5; + double dtop = 0.5; + double dbottom = 0.5; + + aPS->GetPrinterName(&printer); aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); - aPS->GetPaperSize(&paper_size); + aPS->GetPaperName(&papername); aPS->GetOrientation(&orientation); aPS->GetPrintCommand(&command); aPS->GetPrintRange(&printRange); @@ -173,205 +320,722 @@ NS_IMETHODIMP nsDeviceContextSpecQT::Init(nsIPrintSettings* aPS) aPS->GetPrintToFile(&tofile); aPS->GetStartPageRange(&fromPage); aPS->GetEndPageRange(&toPage); + aPS->GetNumCopies(&copies); aPS->GetMarginTop(&dtop); aPS->GetMarginLeft(&dleft); aPS->GetMarginBottom(&dbottom); aPS->GetMarginRight(&dright); - if (command != nsnull && printfile != nsnull) { - // convert Unicode strings to cstrings - nsAutoString cmdStr; - nsAutoString printFileStr; + if (printfile) + strcpy(mPath, NS_ConvertUCS2toUTF8(printfile).get()); + if (command) + strcpy(mCommand, NS_ConvertUCS2toUTF8(command).get()); + if (printer) + strcpy(mPrinter, NS_ConvertUCS2toUTF8(printer).get()); + if (papername) + strcpy(mPaperName, NS_ConvertUCS2toUTF8(papername).get()); - cmdStr = command; - printFileStr = printfile; - char *pCmdStr = ToNewCString(cmdStr); - char *pPrintFileStr = ToNewCString(printFileStr); - sprintf(mPrData.command,pCmdStr); - sprintf(mPrData.path,pPrintFileStr); - nsMemory::Free(pCmdStr); - nsMemory::Free(pPrintFileStr); - } - } else { -#ifndef VMS - const char* kCommandStr = "lpr"; -#else - // Note to whoever puts the "lpr" into the prefs file. Please contact me - // as I need to make the default be "print" instead of "lpr" for OpenVMS. - const char* kCommandStr = "print"; -#endif - sprintf( mPrData.command, kCommandStr ); - } - mPrData.top = dtop; - mPrData.bottom = dbottom; - mPrData.left = dleft; - mPrData.right = dright; - mPrData.fpf = !reversed; - mPrData.grayscale = !color; - mPrData.size = paper_size; - mPrData.orientation = orientation; - mPrData.toPrinter = !tofile; + DO_PR_DEBUG_LOG(("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright)); + DO_PR_DEBUG_LOG(("printRange %d\n", printRange)); + DO_PR_DEBUG_LOG(("fromPage %d\n", fromPage)); + DO_PR_DEBUG_LOG(("toPage %d\n", toPage)); + DO_PR_DEBUG_LOG(("tofile %d\n", tofile)); + DO_PR_DEBUG_LOG(("printfile '%s'\n", printfile? NS_ConvertUCS2toUTF8(printfile).get():"")); + DO_PR_DEBUG_LOG(("command '%s'\n", command? NS_ConvertUCS2toUTF8(command).get():"")); + DO_PR_DEBUG_LOG(("printer '%s'\n", printer? NS_ConvertUCS2toUTF8(printer).get():"")); + DO_PR_DEBUG_LOG(("papername '%s'\n", papername? NS_ConvertUCS2toUTF8(papername).get():"")); - // PWD, HOME, or fail - if (!printfile) { - if ((path = PR_GetEnv("PWD")) == (char*)NULL) - if ((path = PR_GetEnv("HOME")) == (char*)NULL) - strcpy(mPrData.path,"mozilla.ps"); - if (path != (char*)NULL) - sprintf(mPrData.path,"%s/mozilla.ps",path); - else - return NS_ERROR_FAILURE; + mTop = dtop; + mBottom = dbottom; + mLeft = dleft; + mRight = dright; + mFpf = !reversed; + mGrayscale = !color; + mOrientation = orientation; + mToPrinter = !tofile; + mCopies = copies; } - if (command != nsnull) { - nsMemory::Free(command); - } - if (printfile != nsnull) { - nsMemory::Free(printfile); - } - return NS_OK; + + return rv; } NS_IMETHODIMP nsDeviceContextSpecQT::GetToPrinter(PRBool &aToPrinter) { - aToPrinter = mPrData.toPrinter; + aToPrinter = mToPrinter; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecQT::GetPrinterName (const char **aPrinter) +NS_IMETHODIMP nsDeviceContextSpecQT::GetPrinterName ( const char **aPrinter ) { - *aPrinter = &mPrData.printer[0]; + *aPrinter = mPrinter; return NS_OK; } - -NS_IMETHODIMP nsDeviceContextSpecQT::GetFirstPageFirst(PRBool &aFpf) -{ - aFpf = mPrData.fpf; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetGrayscale(PRBool &aGrayscale) -{ - aGrayscale = mPrData.grayscale; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) -{ - return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetSize(int &aSize) -{ - aSize = mPrData.size; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetPageDimensions(float &aWidth, - float &aHeight) -{ - if (mPrData.size == NS_LETTER_SIZE) { - aWidth = 8.5; - aHeight = 11.0; - } - else if (mPrData.size == NS_LEGAL_SIZE) { - aWidth = 8.5; - aHeight = 14.0; - } - else if (mPrData.size == NS_EXECUTIVE_SIZE) { - aWidth = 7.5; - aHeight = 10.0; - } - else if (mPrData.size == NS_A4_SIZE) { - // 210mm X 297mm == 8.27in X 11.69in - aWidth = 8.27; - aHeight = 11.69; - } - else if (mPrData.size == NS_A3_SIZE) { - // 297mm X 420mm == 11.69in X 16.53in - aWidth = 11.69; - aHeight = 16.53; - } - - if (mPrData.orientation == NS_LANDSCAPE) { - float temp; - temp = aWidth; - aWidth = aHeight; - aHeight = temp; - } - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetLandscape(PRBool &landscape) -{ - landscape = (mPrData.orientation == NS_LANDSCAPE); - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetTopMargin(float &value) -{ - value = mPrData.top; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetBottomMargin(float &value) -{ - value = mPrData.bottom; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetRightMargin(float &value) -{ - value = mPrData.right; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetLeftMargin(float &value) -{ - value = mPrData.left; - return NS_OK; -} NS_IMETHODIMP nsDeviceContextSpecQT::GetCopies ( int &aCopies ) { - NS_NOTREACHED("nsDeviceContextSpecQT::GetCopies not yet implemented"); - aCopies = 1; + aCopies = mCopies; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetFirstPageFirst(PRBool &aFpf) +{ + aFpf = mFpf; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecQT::GetCommand(const char **aCommand) +NS_IMETHODIMP nsDeviceContextSpecQT::GetGrayscale(PRBool &aGrayscale) { - *aCommand = &mPrData.command[0]; + aGrayscale = mGrayscale; return NS_OK; } - -NS_IMETHODIMP nsDeviceContextSpecQT::GetPath(const char **aPath) + +NS_IMETHODIMP nsDeviceContextSpecQT::GetLandscape(PRBool &aLandscape) { - *aPath = &mPrData.path[0]; + aLandscape = (mOrientation == NS_LANDSCAPE); + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetTopMargin(float &aValue) +{ + aValue = mTop; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetBottomMargin(float &aValue) +{ + aValue = mBottom; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetRightMargin(float &aValue) +{ + aValue = mRight; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetLeftMargin(float &aValue) +{ + aValue = mLeft; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetCommand(const char **aCommand) +{ + *aCommand = mCommand; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetPath(const char **aPath) +{ + *aPath = mPath; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetUserCancelled(PRBool &aCancel) +{ + aCancel = mCancel; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecQT::GetPaperName( const char **aPaperName ) { - /* - * Apparantly, this gives undefined behaviour in the GTK toolkit. I find this a little better. - */ - static const char* const paperName = "Not Implemented."; - *aPaperName = paperName; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecQT::GetUserCancelled(PRBool &aCancel) -{ - aCancel = mPrData.cancel; + *aPaperName = mPaperName; return NS_OK; } -/** ------------------------------------------------------- - * Closes the printmanager if it is open. - * @update dc 2/15/98 - */ +NS_IMETHODIMP nsDeviceContextSpecQT::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) +{ + return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); +} + +NS_IMETHODIMP nsDeviceContextSpecQT::GetPrintMethod(PrintMethod &aMethod) +{ + return GetPrintMethod(mPrinter, aMethod); +} + +/* static !! */ +nsresult nsDeviceContextSpecQT::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod) +{ +#if defined(USE_POSTSCRIPT) && defined(USE_XPRINT) + /* printer names for the PostScript module alwas start with + * the NS_POSTSCRIPT_DRIVER_NAME string */ + if (strncmp(aPrinter, NS_POSTSCRIPT_DRIVER_NAME, + NS_POSTSCRIPT_DRIVER_NAME_LEN) != 0) + aMethod = pmXprint; + else + aMethod = pmPostScript; + return NS_OK; +#elif defined(USE_XPRINT) + aMethod = pmXprint; + return NS_OK; +#elif defined(USE_POSTSCRIPT) + aMethod = pmPostScript; + return NS_OK; +#else + return NS_ERROR_UNEXPECTED; +#endif +} + NS_IMETHODIMP nsDeviceContextSpecQT::ClosePrintManager() { - return NS_OK; + return NS_OK; } + +/* Get prefs for printer + * Search order: + * - Get prefs per printer name and module name + * - Get prefs per printer name + * - Get prefs per module name + * - Get prefs + */ +static +nsresult CopyPrinterCharPref(nsIPref *pref, const char *modulename, const char *printername, const char *prefname, char **return_buf) +{ + DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname)); + + NS_ENSURE_ARG_POINTER(return_buf); + + nsXPIDLCString name; + nsresult rv = NS_ERROR_FAILURE; + + if (printername && modulename) { + /* Get prefs per printer name and module name */ + name = nsPrintfCString(512, "print.%s.printer_%s.%s", modulename, printername, prefname); + DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); + rv = pref->CopyCharPref(name, return_buf); + } + + if (NS_FAILED(rv)) { + if (printername) { + /* Get prefs per printer name */ + name = nsPrintfCString(512, "print.printer_%s.%s", printername, prefname); + DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); + rv = pref->CopyCharPref(name, return_buf); + } + + if (NS_FAILED(rv)) { + if (modulename) { + /* Get prefs per module name */ + name = nsPrintfCString(512, "print.%s.%s", modulename, prefname); + DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); + rv = pref->CopyCharPref(name, return_buf); + } + + if (NS_FAILED(rv)) { + /* Get prefs */ + name = nsPrintfCString(512, "print.%s", prefname); + DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); + rv = pref->CopyCharPref(name, return_buf); + } + } + } + +#ifdef PR_LOG + if (NS_SUCCEEDED(rv)) { + DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", *return_buf)); + } + else + { + DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n")); + } +#endif /* PR_LOG */ + + return rv; +} + +// Printer Enumerator +nsPrinterEnumeratorQT::nsPrinterEnumeratorQT() +{ + NS_INIT_ISUPPORTS(); +} + +NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorQT, nsIPrinterEnumerator) + +NS_IMETHODIMP nsPrinterEnumeratorQT::EnumeratePrinters(PRUint32* aCount, PRUnichar*** aResult) +{ + NS_ENSURE_ARG(aCount); + NS_ENSURE_ARG_POINTER(aResult); + + if (aCount) + *aCount = 0; + else + return NS_ERROR_NULL_POINTER; + + if (aResult) + *aResult = nsnull; + else + return NS_ERROR_NULL_POINTER; + + nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); + if (NS_FAILED(rv)) { + return rv; + } + + PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters(); + + PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numPrinters * sizeof(PRUnichar*)); + if (!array && numPrinters > 0) { + GlobalPrinters::GetInstance()->FreeGlobalPrinters(); + return NS_ERROR_OUT_OF_MEMORY; + } + + int count = 0; + while( count < numPrinters ) + { + PRUnichar *str = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(count)); + + if (!str) { + for (int i = count - 1; i >= 0; i--) + nsMemory::Free(array[i]); + + nsMemory::Free(array); + + GlobalPrinters::GetInstance()->FreeGlobalPrinters(); + return NS_ERROR_OUT_OF_MEMORY; + } + array[count++] = str; + + } + *aCount = count; + *aResult = array; + GlobalPrinters::GetInstance()->FreeGlobalPrinters(); + + return NS_OK; +} + +/* readonly attribute wstring defaultPrinterName; */ +NS_IMETHODIMP nsPrinterEnumeratorQT::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName) +{ + DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQT::GetDefaultPrinterName()\n")); + NS_ENSURE_ARG_POINTER(aDefaultPrinterName); + + GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName); + + DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUCS2toUTF8(*aDefaultPrinterName).get())); + return NS_OK; +} + +/* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ +NS_IMETHODIMP nsPrinterEnumeratorQT::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) +{ + DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQT::InitPrintSettingsFromPrinter()")); + nsresult rv; + + NS_ENSURE_ARG_POINTER(aPrinterName); + NS_ENSURE_ARG_POINTER(aPrintSettings); + + NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE); + + nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + + nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ + printerName; /* "Stripped" name of printer */ + fullPrinterName.Assign(NS_ConvertUCS2toUTF8(aPrinterName)); + printerName.Assign(NS_ConvertUCS2toUTF8(aPrinterName)); + DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get())); + + PrintMethod type = pmInvalid; + rv = nsDeviceContextSpecQT::GetPrintMethod(printerName, type); + if (NS_FAILED(rv)) + return rv; + +#ifdef USE_POSTSCRIPT + /* "Demangle" postscript printer name */ + if (type == pmPostScript) { + /* Strip the leading NS_POSTSCRIPT_DRIVER_NAME from |printerName|, + * e.g. turn "PostScript/foobar" to "foobar" */ + printerName.Cut(0, NS_POSTSCRIPT_DRIVER_NAME_LEN); + } +#endif /* USE_POSTSCRIPT */ + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + /* Defaults to FALSE */ + pPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.has_special_printerfeatures", fullPrinterName.get()).get(), PR_FALSE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + + /* Set filename */ + nsXPIDLCString filename; + if (NS_FAILED(CopyPrinterCharPref(pPrefs, nsnull, printerName, "filename", getter_Copies(filename)))) { + const char *path; + + if (!(path = PR_GetEnv("PWD"))) + path = PR_GetEnv("HOME"); + + if (path) + filename = nsPrintfCString(PATH_MAX, "%s/mozilla.ps", path); + else + filename.Assign("mozilla.ps"); + } + DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get())); + aPrintSettings->SetToFileName(NS_ConvertUTF8toUCS2(filename).get()); + + aPrintSettings->SetIsInitializedFromPrinter(PR_TRUE); +#ifdef USE_XPRINT + if (type == pmXprint) { + DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for Xprint printer\n")); + + Display *pdpy; + XPContext pcontext; + if (XpuGetPrinter(printerName, &pdpy, &pcontext) != 1) + return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND; + + XpuSupportedFlags supported_doc_attrs = XpuGetSupportedDocAttributes(pdpy, pcontext); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + nsPrinterFeatures printerFeatures(fullPrinterName); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + /* Setup orientation stuff */ + XpuOrientationList olist; + int ocount; + XpuOrientationRec *default_orientation; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + PRBool canSetOrientation = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_CONTENT_ORIENTATION); + printerFeatures.SetCanChangeOrientation(canSetOrientation); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + /* Get list of supported orientations */ + olist = XpuGetOrientationList(pdpy, pcontext, &ocount); + if (olist) { + default_orientation = &olist[0]; /* First entry is the default one */ + + if (!PL_strcasecmp(default_orientation->orientation, "portrait")) { + DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n")); + aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation); + } + else if (!PL_strcasecmp(default_orientation->orientation, "landscape")) { + DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n")); + aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); + } + else { + DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", default_orientation->orientation)); + } + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; i < ocount ; i++ ) + { + XpuOrientationRec *curr = &olist[i]; + printerFeatures.SetOrientationRecord(i, curr->orientation); + } + printerFeatures.SetNumOrientationRecords(ocount); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuFreeOrientationList(olist); + } + + /* Setup Number of Copies */ +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + PRBool canSetNumCopies = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_COPY_COUNT); + printerFeatures.SetCanChangeNumCopies(canSetNumCopies); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + long numCopies; + if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "copy-count", &numCopies) != 1 ) + { + /* Fallback on failure */ + numCopies = 1; + } + aPrintSettings->SetNumCopies(numCopies); + + /* Setup paper size stuff */ + XpuMediumSourceSizeList mlist; + int mcount; + XpuMediumSourceSizeRec *default_medium; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + PRBool canSetPaperSize = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM); + printerFeatures.SetCanChangePaperSize(canSetPaperSize); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + mlist = XpuGetMediumSourceSizeList(pdpy, pcontext, &mcount); + if (mlist) { + nsXPIDLCString papername; + + default_medium = &mlist[0]; /* First entry is the default one */ + double total_width = default_medium->ma1 + default_medium->ma2, + total_height = default_medium->ma3 + default_medium->ma4; + + /* Either "paper" or "tray/paper" */ + if (default_medium->tray_name) { + papername = nsPrintfCString(256, "%s/%s", default_medium->tray_name, default_medium->medium_name); + } + else { + papername.Assign(default_medium->medium_name); + } + + DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g/%g mm)\n", papername.get(), total_width, total_height)); + aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined); + aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters); + aPrintSettings->SetPaperWidth(total_width); + aPrintSettings->SetPaperHeight(total_height); + aPrintSettings->SetPaperName(NS_ConvertUTF8toUCS2(papername).get()); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; i < mcount ; i++ ) + { + XpuMediumSourceSizeRec *curr = &mlist[i]; + double total_width = curr->ma1 + curr->ma2, + total_height = curr->ma3 + curr->ma4; + if (curr->tray_name) { + papername = nsPrintfCString(256, "%s/%s", curr->tray_name, curr->medium_name); + } + else { + papername.Assign(curr->medium_name); + } + + printerFeatures.SetPaperRecord(i, papername, PRInt32(total_width), PRInt32(total_height), PR_FALSE); + } + printerFeatures.SetNumPaperSizeRecords(mcount); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuFreeMediumSourceSizeList(mlist); + } + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + /* Xprint does not allow the client to set a spooler command. + * Job spooling is the job of the server side (=Xprt) */ + printerFeatures.SetCanChangeSpoolerCommand(PR_FALSE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuClosePrinterDisplay(pdpy, pcontext); + + return NS_OK; + } + else +#endif /* USE_XPRINT */ + +#ifdef USE_POSTSCRIPT + if (type == pmPostScript) { + DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n")); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + nsPrinterFeatures printerFeatures(fullPrinterName); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeOrientation(PR_TRUE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + nsXPIDLCString orientation; + if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "orientation", getter_Copies(orientation)))) { + if (!PL_strcasecmp(orientation, "portrait")) { + DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n")); + aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation); + } + else if (!PL_strcasecmp(orientation, "landscape")) { + DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n")); + aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); + } + else { + DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get())); + } + } + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; postscript_module_orientations[i].orientation != nsnull ; i++ ) + { + const PSOrientationRec *curr = &postscript_module_orientations[i]; + printerFeatures.SetOrientationRecord(i, curr->orientation); + } + printerFeatures.SetNumOrientationRecords(i); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangePaperSize(PR_TRUE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + nsXPIDLCString papername; + if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) { + int i; + const PSPaperSizeRec *default_paper = nsnull; + + for( i = 0 ; postscript_module_paper_sizes[i].name != nsnull ; i++ ) + { + const PSPaperSizeRec *curr = &postscript_module_paper_sizes[i]; + + if (!PL_strcasecmp(papername, curr->name)) { + default_paper = curr; + break; + } + } + + if (default_paper) { + DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g inch/%g inch)\n", + default_paper->name, + PSPaperSizeRec_FullPaperWidth(default_paper), + PSPaperSizeRec_FullPaperHeight(default_paper))); + aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined); + aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeInches); + aPrintSettings->SetPaperWidth(PSPaperSizeRec_FullPaperWidth(default_paper)); + aPrintSettings->SetPaperHeight(PSPaperSizeRec_FullPaperHeight(default_paper)); + aPrintSettings->SetPaperName(NS_ConvertUTF8toUCS2(default_paper->name).get()); + } + else { + DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get())); + } +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + for( i = 0 ; postscript_module_paper_sizes[i].name != nsnull ; i++ ) + { + const PSPaperSizeRec *curr = &postscript_module_paper_sizes[i]; +#define CONVERT_INCH_TO_MILLIMETERS(inch) ((inch) * 25.4) + double total_width = CONVERT_INCH_TO_MILLIMETERS(PSPaperSizeRec_FullPaperWidth(curr)), + total_height = CONVERT_INCH_TO_MILLIMETERS(PSPaperSizeRec_FullPaperHeight(curr)); + + printerFeatures.SetPaperRecord(i, curr->name, PRInt32(total_width), PRInt32(total_height), PR_TRUE); + } + printerFeatures.SetNumPaperSizeRecords(i); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + } + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeSpoolerCommand(PR_TRUE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + nsXPIDLCString command; + if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "print_command", getter_Copies(command)))) { + DO_PR_DEBUG_LOG(("setting default print command to '%s'\n", command.get())); + aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUCS2(command).get()); + } + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeNumCopies(PR_TRUE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + return NS_OK; + } +#endif /* USE_POSTSCRIPT */ + + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP nsPrinterEnumeratorQT::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings) +{ + return NS_OK; +} + +//---------------------------------------------------------------------- +nsresult GlobalPrinters::InitializeGlobalPrinters () +{ + if (PrintersAreAllocated()) { + return NS_OK; + } + + mGlobalNumPrinters = 0; + mGlobalPrinterList = new nsStringArray(); + if (!mGlobalPrinterList) + return NS_ERROR_OUT_OF_MEMORY; + +#ifdef USE_XPRINT + XPPrinterList plist = XpuGetPrinterList(nsnull, &mGlobalNumPrinters); + + if (plist && (mGlobalNumPrinters > 0)) + { + int i; + for( i = 0 ; i < mGlobalNumPrinters ; i++ ) + { + mGlobalPrinterList->AppendString(nsString(NS_ConvertASCIItoUCS2(plist[i].name))); + } + + XpuFreePrinterList(plist); + } +#endif /* USE_XPRINT */ + +#ifdef USE_POSTSCRIPT + /* Get the list of PostScript-module printers */ + char *printerList = nsnull; + PRBool added_default_printer = PR_FALSE; /* Did we already add the default printer ? */ + + /* The env var MOZILLA_POSTSCRIPT_PRINTER_LIST can "override" the prefs */ + printerList = PR_GetEnv("MOZILLA_POSTSCRIPT_PRINTER_LIST"); + + if (!printerList) { + nsresult rv; + nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + (void) pPrefs->CopyCharPref("print.printer_list", &printerList); + } + } + + if (printerList) { + char *tok_lasts; + const char *name; + + /* PL_strtok_r() will modify the string - copy it! */ + printerList = strdup(printerList); + if (!printerList) + return NS_ERROR_OUT_OF_MEMORY; + + for( name = PL_strtok_r(printerList, " ", &tok_lasts) ; + name != nsnull ; + name = PL_strtok_r(nsnull, " ", &tok_lasts) ) + { + /* Is this the "default" printer ? */ + if (!strcmp(name, "default")) + added_default_printer = PR_TRUE; + + mGlobalPrinterList->AppendString( + nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME)) + + nsString(NS_ConvertASCIItoUCS2(name))); + mGlobalNumPrinters++; + } + + free(printerList); + } + + /* Add an entry for the default printer (see nsPostScriptObj.cpp) if we + * did not add it already... */ + if (!added_default_printer) + { + mGlobalPrinterList->AppendString( + nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME "default"))); + mGlobalNumPrinters++; + } +#endif /* USE_POSTSCRIPT */ + + if (mGlobalNumPrinters == 0) + return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE; + + return NS_OK; +} + +//---------------------------------------------------------------------- +void GlobalPrinters::FreeGlobalPrinters() +{ + if (mGlobalPrinterList) { + delete mGlobalPrinterList; + mGlobalPrinterList = nsnull; + mGlobalNumPrinters = 0; + } +} + +void +GlobalPrinters::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName) +{ + *aDefaultPrinterName = nsnull; + + PRBool allocate = (GlobalPrinters::GetInstance()->PrintersAreAllocated() == PR_FALSE); + + if (allocate) { + nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); + if (NS_FAILED(rv)) { + return; + } + } + NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters"); + + if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0) + return; + + *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0)); + + if (allocate) { + GlobalPrinters::GetInstance()->FreeGlobalPrinters(); + } +} + diff --git a/gfx/src/qt/nsDeviceContextSpecQT.h b/gfx/src/qt/nsDeviceContextSpecQT.h index 08f3cc85426a..c219a9e90bc6 100644 --- a/gfx/src/qt/nsDeviceContextSpecQT.h +++ b/gfx/src/qt/nsDeviceContextSpecQT.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -20,7 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * John C. Griggs + * Roland Mainz * * * Alternatively, the contents of this file may be used under the terms of @@ -40,95 +40,91 @@ #ifndef nsDeviceContextSpecQT_h___ #define nsDeviceContextSpecQT_h___ +#include "nsCOMPtr.h" #include "nsIDeviceContextSpec.h" -#include "nsDeviceContextSpecQT.h" +#include "nsIPrintSettings.h" +#include "nsIPrintOptions.h" +#include "nsVoidArray.h" +#include #ifdef USE_POSTSCRIPT #include "nsIDeviceContextSpecPS.h" -#endif -#include "nsIPrintSettings.h" -#include "nsCOMPtr.h" -//XXX WHAT IN THE WORLD VV ?? -#include "../gtk/nsPrintdGTK.h" +#endif /* USE_POSTSCRIPT */ +#ifdef USE_XPRINT +#include "nsIDeviceContextSpecXPrint.h" +#endif /* USE_XPRINT */ -class nsDeviceContextSpecQT -: public nsIDeviceContextSpec +#define NS_PORTRAIT 0 +#define NS_LANDSCAPE 1 + +typedef enum +{ + pmInvalid = 0, + pmXprint, + pmPostScript +} PrintMethod; + +class nsDeviceContextSpecQT : public nsIDeviceContextSpec #ifdef USE_POSTSCRIPT -, public nsIDeviceContextSpecPS -#endif + , public nsIDeviceContextSpecPS +#endif /* USE_POSTSCRIPT */ +#ifdef USE_XPRINT + , public nsIDeviceContextSpecXp +#endif /* USE_XPRINT */ { public: -/** - * Construct a nsDeviceContextSpecQT, which is an object which contains and manages a printrecord - * @update dc 12/02/98 - */ - nsDeviceContextSpecQT(); + nsDeviceContextSpecQT(); - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS -/** - * Initialize the nsDeviceContextSpecQT for use. This will allocate a printrecord for use - * @update dc 2/16/98 - * @return error status - */ - NS_IMETHOD Init(nsIPrintSettings* aPS); + NS_IMETHOD Init(nsIPrintSettings* aPS); + NS_IMETHOD ClosePrintManager(); + + NS_IMETHOD GetToPrinter(PRBool &aToPrinter); + NS_IMETHOD GetPrinterName ( const char **aPrinter ); + NS_IMETHOD GetCopies ( int &aCopies ); + NS_IMETHOD GetFirstPageFirst(PRBool &aFpf); + NS_IMETHOD GetGrayscale(PRBool &aGrayscale); + NS_IMETHOD GetTopMargin(float &value); + NS_IMETHOD GetBottomMargin(float &value); + NS_IMETHOD GetLeftMargin(float &value); + NS_IMETHOD GetRightMargin(float &value); + NS_IMETHOD GetCommand(const char **aCommand); + NS_IMETHOD GetPath (const char **aPath); + NS_IMETHOD GetLandscape (PRBool &aLandscape); + NS_IMETHOD GetUserCancelled(PRBool &aCancel); + NS_IMETHOD GetPrintMethod(PrintMethod &aMethod); + static nsresult GetPrintMethod(const char *aPrinter, PrintMethod &aMethod); + NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight); + NS_IMETHOD GetPaperName(const char **aPaperName); + virtual ~nsDeviceContextSpecQT(); - -/** - * Closes the printmanager if it is open. - * @update dc 2/13/98 - * @return error status - */ - NS_IMETHOD ClosePrintManager(); - - NS_IMETHOD GetToPrinter(PRBool &aToPrinter); - - NS_IMETHOD GetPrinterName ( const char **aPrinter ); - - NS_IMETHOD GetFirstPageFirst(PRBool &aFpf); - - NS_IMETHOD GetGrayscale(PRBool &aGrayscale); - - NS_IMETHOD GetSize(int &aSize); - - NS_IMETHOD GetTopMargin(float &value); - - NS_IMETHOD GetBottomMargin(float &value); - - NS_IMETHOD GetLeftMargin(float &value); - - NS_IMETHOD GetCopies ( int &aCopies ); - - NS_IMETHOD GetRightMargin(float &value); - - NS_IMETHOD GetCommand(const char **aCommand); - - NS_IMETHOD GetPath(const char **aPath); - - NS_IMETHOD GetPageDimensions(float &aWidth, float &aHeight); - - NS_IMETHOD GetLandscape(PRBool &aLandscape); - - NS_IMETHOD GetUserCancelled(PRBool &aCancel); - - NS_IMETHOD GetPaperName( const char **aPaperName ); - - NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight); - - protected: -/** - * Destuct a nsDeviceContextSpecQT, this will release the printrecord - * @update dc 2/16/98 - */ - virtual ~nsDeviceContextSpecQT(); - -protected: - UnixPrData mPrData; - nsCOMPtr mPrintSettings; -#ifdef DEBUG -private: - PRUint32 mID; -#endif + nsCOMPtr mPrintSettings; + PRBool mToPrinter; /* If PR_TRUE, print to printer */ + PRBool mFpf; /* If PR_TRUE, first page first */ + PRBool mGrayscale; /* If PR_TRUE, print grayscale */ + int mOrientation; /* Orientation e.g. Portrait */ + char mCommand[PATH_MAX]; /* Print command e.g., lpr */ + char mPath[PATH_MAX]; /* If toPrinter = PR_FALSE, dest file */ + char mPrinter[256]; /* Printer name */ + char mPaperName[256]; /* Printer name */ + int mCopies; /* number of copies */ + PRBool mCancel; /* If PR_TRUE, user cancelled */ + float mLeft; /* left margin */ + float mRight; /* right margin */ + float mTop; /* top margin */ + float mBottom; /* bottom margin */ }; -#endif +//------------------------------------------------------------------------- +// Printer Enumerator +//------------------------------------------------------------------------- +class nsPrinterEnumeratorQT : public nsIPrinterEnumerator +{ +public: + nsPrinterEnumeratorQT(); + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTERENUMERATOR +}; + +#endif /* !nsDeviceContextSpecQT_h___ */