Subject: Printer properties are not saved and displayed correctly References: https://bugzilla.mozilla.org/show_bug.cgi?id=324072 https://bugzilla.novell.com/show_bug.cgi?id=174082 https://bugzilla.mozilla.org/show_bug.cgi?id=342950 https://bugzilla.novell.com/show_bug.cgi?id=187013 Index: idl/nsIPrintSettingsService.idl =================================================================== RCS file: /cvsroot/mozilla/gfx/idl/Attic/nsIPrintSettingsService.idl,v retrieving revision 1.2 diff -p -u -d -8 -r1.2 nsIPrintSettingsService.idl --- idl/nsIPrintSettingsService.idl 17 Apr 2004 21:52:27 -0000 1.2 +++ gfx/idl/nsIPrintSettingsService.idl 11 May 2006 21:51:04 -0000 @@ -67,17 +67,17 @@ interface nsIPrintSettingsService : nsIS * then it should use "globalPrintSettings" * * Initializes the newPrintSettings from the default printer * */ readonly attribute nsIPrintSettings newPrintSettings; /** - * The name of the default printer + * The name of the last printer used, or else the system default printer. */ readonly attribute wstring defaultPrinterName; /** * Initializes certain settings from the native printer into the PrintSettings * if aPrinterName is null then it uses the default printer name if it can * These settings include, but are not limited to: * Page Orientation @@ -85,28 +85,31 @@ interface nsIPrintSettingsService : nsIS * Number of Copies */ void initPrintSettingsFromPrinter(in wstring aPrinterName, in nsIPrintSettings aPrintSettings); /** * Reads PrintSettings values from Prefs, * the values to be read are indicated by the "flags" arg. * - * First it reads in the "generic" set of PrintSetings not associated with any printer - * then it uses the PrinterName in the PrinterSettings to read any settings that were saved + * aPrintSettings should be initialized with the name of a printer. First + * it reads in the PrintSettings from the last print job. Then it uses the + * PrinterName in the PrinterSettings to read any settings that were saved * just for that printer. * * aPS - PrintSettings to have its settings read * aUsePrinterNamePrefix - indicates whether to use the printer name as a prefix - * aFlags - indicates which prefs to read, see nsIPrintSettings.idl for the const values. + * aFlags - indicates which prefs to read, see nsIPrintSettings.idl for the + * const values. * * Items not read: * startPageRange, endPageRange, scaling, printRange, title * docURL, howToEnableFrameUI, isCancelled, printFrameTypeUsage - * printFrameType, printSilent, shrinkToFit, numCopies + * printFrameType, printSilent, shrinkToFit, numCopies, + * printerName * */ void initPrintSettingsFromPrefs(in nsIPrintSettings aPrintSettings, in boolean aUsePrinterNamePrefix, in unsigned long aFlags); /** * Writes PrintSettings values to Prefs, * the values to be written are indicated by the "flags" arg. * Index: gfx/src/nsPrintOptionsImpl.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/Attic/nsPrintOptionsImpl.cpp,v retrieving revision 1.76 diff -p -u -d -8 -r1.76 nsPrintOptionsImpl.cpp --- src/nsPrintOptionsImpl.cpp 9 Aug 2005 01:35:48 -0000 1.76 +++ gfx/src/nsPrintOptionsImpl.cpp 11 May 2006 21:51:05 -0000 @@ -597,23 +597,16 @@ nsPrintOptions::ReadPrefs(nsIPrintSettin if (aFlags & nsIPrintSettings::kInitSavePrintCommand) { if (GETSTRPREF(kPrintCommand, str)) { aPS->SetPrintCommand(str.get()); DUMP_STR(kReadStr, kPrintCommand, str.get()); } } - if (aFlags & nsIPrintSettings::kInitSavePrinterName) { - if (GETSTRPREF(kPrinterName, str)) { - aPS->SetPrinterName(str.get()); - DUMP_STR(kReadStr, kPrinterName, str.get()); - } - } - if (aFlags & nsIPrintSettings::kInitSavePrintToFile) { if (GETBOOLPREF(kPrintToFile, &b)) { aPS->SetPrintToFile(b); DUMP_BOOL(kReadStr, kPrintToFile, b); } } if (aFlags & nsIPrintSettings::kInitSaveToFileName) { @@ -865,20 +858,22 @@ nsPrintOptions::WritePrefs(nsIPrintSetti if (aFlags & nsIPrintSettings::kInitSavePrintCommand) { if (NS_SUCCEEDED(aPS->GetPrintCommand(&uStr))) { DUMP_STR(kWriteStr, kPrintCommand, uStr); WritePrefString(uStr, GetPrefName(kPrintCommand, aPrinterName)); } } - if (aFlags & nsIPrintSettings::kInitSavePrinterName) { + // Only the general version of this pref is saved + if ((aFlags & nsIPrintSettings::kInitSavePrinterName) + && aPrinterName.IsEmpty()) { if (NS_SUCCEEDED(aPS->GetPrinterName(&uStr))) { DUMP_STR(kWriteStr, kPrinterName, uStr); - WritePrefString(uStr, GetPrefName(kPrinterName, aPrinterName)); + WritePrefString(uStr, kPrinterName); } } if (aFlags & nsIPrintSettings::kInitSavePrintToFile) { if (NS_SUCCEEDED(aPS->GetPrintToFile(&b))) { DUMP_BOOL(kWriteStr, kPrintToFile, b); mPrefBranch->SetBoolPref(GetPrefName(kPrintToFile, aPrinterName), b); } @@ -965,16 +960,22 @@ NS_IMETHODIMP nsPrintOptions::GetNativeD nsresult nsPrintOptions::_CreatePrintSettings(nsIPrintSettings **_retval) { // does not initially ref count nsPrintSettings * printSettings = new nsPrintSettings(); NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY); NS_ADDREF(*_retval = printSettings); // ref count + + nsXPIDLString printerName; + nsresult rv = GetDefaultPrinterName(getter_Copies(printerName)); + NS_ENSURE_SUCCESS(rv, rv); + (*_retval)->SetPrinterName(printerName.get()); + (void)InitPrintSettingsFromPrefs(*_retval, PR_FALSE, nsIPrintSettings::kInitSaveAll); return NS_OK; } NS_IMETHODIMP nsPrintOptions::CreatePrintSettings(nsIPrintSettings **_retval) { @@ -1003,16 +1004,42 @@ nsPrintOptions::GetNewPrintSettings(nsIP NS_IMETHODIMP nsPrintOptions::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName) { nsresult rv; nsCOMPtr prtEnum = do_GetService(kPrinterEnumeratorCID, &rv); NS_ENSURE_SUCCESS(rv, rv); + // Look up the printer from the last print job + nsAutoString lastPrinterName; + ReadPrefString(kPrinterName, lastPrinterName); + if (!lastPrinterName.IsEmpty()) { + // Verify it's still a valid printer + PRUnichar **printers; + PRUint32 ctPrinters; + rv = prtEnum->EnumeratePrinters(&ctPrinters, &printers); + if (NS_SUCCEEDED(rv)) { + PRBool isValid = PR_FALSE; + for (PRInt32 ii = ctPrinters - 1; ii >= 0; --ii) { + if (lastPrinterName.Equals(printers[ii])) { + isValid = PR_TRUE; + break; + } + } + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(ctPrinters, printers); + if (isValid) { + *aDefaultPrinterName = ToNewUnicode(lastPrinterName); + return NS_OK; + } + } + } + + // There is no last printer preference, or it doesn't name a valid printer. + // Return the default from the printer enumeration. return prtEnum->GetDefaultPrinterName(aDefaultPrinterName); } NS_IMETHODIMP nsPrintOptions::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) { NS_ENSURE_ARG_POINTER(aPrintSettings); @@ -1124,49 +1151,50 @@ nsPrintOptions::InitPrintSettingsFromPre nsAutoString prtName; // read any non printer specific prefs // with empty printer name nsresult rv = ReadPrefs(aPS, prtName, aFlags); NS_ENSURE_SUCCESS(rv, rv); // Get the Printer Name from the PrintSettings // to use as a prefix for Pref Names - GetAdjustedPrinterName(aPS, aUsePNP, prtName); - NS_ENSURE_FALSE(prtName.IsEmpty(), NS_OK); + rv = GetAdjustedPrinterName(aPS, aUsePNP, prtName); + NS_ENSURE_SUCCESS(rv, rv); + + if (prtName.IsEmpty()) { + NS_WARNING("Caller should supply a printer name."); + return NS_OK; + } // Now read any printer specific prefs rv = ReadPrefs(aPS, prtName, aFlags); if (NS_SUCCEEDED(rv)) aPS->SetIsInitializedFromPrefs(PR_TRUE); return NS_OK; } -/** --------------------------------------------------- - * This will save into prefs most all the PrintSettings either generically (not - * specified printer) or to a specific printer. +/** + * Save all of the printer settings; if we can find a printer name, save + * printer-specific preferences. Otherwise, save generic ones. */ nsresult nsPrintOptions::SavePrintSettingsToPrefs(nsIPrintSettings *aPS, PRBool aUsePrinterNamePrefix, PRUint32 aFlags) { NS_ENSURE_ARG_POINTER(aPS); nsAutoString prtName; - // Get the Printer Name from the PrinterSettings - // to use as a prefix for Pref Names + // Get the printer name from the PrinterSettings for an optional prefix. nsresult rv = GetAdjustedPrinterName(aPS, aUsePrinterNamePrefix, prtName); NS_ENSURE_SUCCESS(rv, rv); - // Now write any printer specific prefs - // XXX but when |prtName| is empty, how can we write printer specific prefs? - rv = WritePrefs(aPS, prtName, aFlags); - - return rv; + // Write the prefs, with or without a printer name prefix. + return WritePrefs(aPS, prtName, aFlags); } //----------------------------------------------------- //-- Protected Methods -------------------------------- //----------------------------------------------------- nsresult nsPrintOptions::ReadPrefString(const char * aPrefId, nsAString& aString)