From 01bcd3003a0ec9dad78c3cf99e6d395a0292ddb2 Mon Sep 17 00:00:00 2001 From: "mkaply%us.ibm.com" Date: Fri, 21 Sep 2001 13:52:39 +0000 Subject: [PATCH] #97907 r=kaie, r=dcone, sr=jst Checkin for Roland.Mainz@informatik.med.uni-giessen.de - add error codes to printing git-svn-id: svn://10.0.0.236/trunk@103447 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsDocumentViewer.cpp | 172 +++++++++++++----- mozilla/gfx/public/nsIDeviceContext.h | 38 ++++ .../src/gtk/nsDeviceContextSpecFactoryG.cpp | 31 ++-- mozilla/gfx/src/ps/nsDeviceContextPS.cpp | 16 +- mozilla/gfx/src/ps/nsPostScriptObj.cpp | 10 +- .../src/xlib/nsDeviceContextSpecFactoryX.cpp | 30 +-- mozilla/gfx/src/xprint/nsXPrintContext.cpp | 19 +- mozilla/layout/base/nsDocumentViewer.cpp | 172 +++++++++++++----- .../layout/html/base/src/printing.properties | 26 ++- 9 files changed, 381 insertions(+), 133 deletions(-) diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index 4a711ea9f1e..ac19fcf334b 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -19,6 +19,7 @@ * * Contributor(s): * Dan Rosen + * Roland Mainz */ #include "nscore.h" @@ -118,6 +119,13 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #include "nsIDOMHTMLFrameSetElement.h" #include "nsIDOMHTMLIFrameElement.h" +// Print error dialog +#include "nsIPrompt.h" +#include "nsIWindowWatcher.h" +#include "nsIStringBundle.h" + +#define NS_ERROR_GFX_PRINTER_BUNDLE_URL "chrome://communicator/locale/printing.properties" + // FrameSet #include "nsINodeInfo.h" #include "nsIDocument.h" @@ -131,23 +139,19 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #include "nsIDOMFocusListener.h" #include "nsISelectionController.h" -#include "nsISound.h" - #include "nsITransformMediator.h" #ifdef IBMBIDI #include "nsIUBidiUtils.h" #endif -static NS_DEFINE_IID(kSoundCID,NS_SOUND_CID); - static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID); static NS_DEFINE_CID(kGalleyContextCID, NS_GALLEYCONTEXT_CID); static NS_DEFINE_CID(kPrintContextCID, NS_PRINTCONTEXT_CID); static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID); -PRBool gCurrentlyPrinting = PR_FALSE; +static PRBool gCurrentlyPrinting = PR_FALSE; #ifdef NS_DEBUG @@ -170,11 +174,10 @@ PRBool gCurrentlyPrinting = PR_FALSE; #endif #define PRT_YESNO(_p) ((_p)?"YES":"NO") -const char * gFrameTypesStr[] = {"eDoc", "eFrame", "eIFrame", "eFrameSet"}; -const char * gPrintFrameTypeStr[] = {"kNoFrames", "kFramesAsIs", "kSelectedFrame", "kEachFrameSep"}; -const char * gFrameHowToEnableStr[] = {"kFrameEnableNone", "kFrameEnableAll", "kFrameEnableAsIsAndEach"}; -const char * gPrintRangeStr[] = {"kRangeAllPages", "kRangeSpecifiedPageRange", "kRangeSelection", "kRangeFocusFrame"}; - +static const char * gFrameTypesStr[] = {"eDoc", "eFrame", "eIFrame", "eFrameSet"}; +static const char * gPrintFrameTypeStr[] = {"kNoFrames", "kFramesAsIs", "kSelectedFrame", "kEachFrameSep"}; +static const char * gFrameHowToEnableStr[] = {"kFrameEnableNone", "kFrameEnableAll", "kFrameEnableAsIsAndEach"}; +static const char * gPrintRangeStr[] = {"kRangeAllPages", "kRangeSpecifiedPageRange", "kRangeSelection", "kRangeFocusFrame"}; #define PRINT_DEBUG_MSG1(_msg1) fprintf(mPrt->mDebugFD, (_msg1)); @@ -494,6 +497,9 @@ private: PRUint32 aDelay); void PrepareToStartLoad(void); + + // Misc + void ShowPrintErrorDialog(nsresult printerror); protected: // IMPORTANT: The ownership implicit in the following member @@ -4252,7 +4258,7 @@ DocumentViewerImpl::IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin) } return PR_FALSE; } - + /** --------------------------------------------------- * See documentation above in the nsIContentViewerfile class definition * @update 01/24/00 dwc @@ -4266,17 +4272,15 @@ nsresult rv; // the reason we check here is because this method can be called while // another is still in here (the printing dialog is a good example). // the only time we can print more than one job at a time is the regression tests - if(gCurrentlyPrinting) { - // Beep at the user, let them know we are not ready to print. - nsCOMPtr soundInterface( do_CreateInstance(kSoundCID, &rv) ); - if (NS_SUCCEEDED(rv) && (soundInterface != nsnull)){ - soundInterface->Beep(); - } - return NS_ERROR_FAILURE; - } else { - gCurrentlyPrinting = PR_TRUE; + if (gCurrentlyPrinting) { + // Let the user know we are not ready to print. + rv = NS_ERROR_NOT_AVAILABLE; + ShowPrintErrorDialog(rv); + return rv; } - + + // Let's print ... + gCurrentlyPrinting = PR_TRUE; mPrt = new PrintData(); if (mPrt == nsnull) { @@ -4370,11 +4374,11 @@ nsresult rv; } #endif + /* create factory (incl. create print dialog) */ nsCOMPtr factory = - do_CreateInstance(kDeviceContextSpecFactoryCID); - - if (factory) { - + do_CreateInstance(kDeviceContextSpecFactoryCID, &rv); + + if (NS_SUCCEEDED(rv)) { #ifdef DEBUG_dcone printf("PRINT JOB STARTING\n"); #endif @@ -4384,24 +4388,27 @@ nsresult rv; mPrt->mPrintDC = nsnull; // XXX why? mPrt->mFilePointer = aFile; - factory->CreateDeviceContextSpec(mWindow, devspec, aSilent); - if (nsnull != devspec) { - mPresContext->GetDeviceContext(getter_AddRefs(dx)); - rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC)); + rv = factory->CreateDeviceContextSpec(mWindow, devspec, aSilent); + if (NS_SUCCEEDED(rv)) { + rv = mPresContext->GetDeviceContext(getter_AddRefs(dx)); + if (NS_SUCCEEDED(rv)) + rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC)); + if (NS_SUCCEEDED(rv)) { - NS_RELEASE(devspec); if(webContainer) { // load the document and do the initial reflow on the entire document - nsCOMPtr printcon(do_CreateInstance(kPrintContextCID,&rv)); + nsCOMPtr printcon(do_CreateInstance(kPrintContextCID, &rv)); if (NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } else { mPrt->mPrintPC = do_QueryInterface(printcon, &rv); if (NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } } @@ -4425,24 +4432,28 @@ nsresult rv; mPrt->mPrintPS = do_CreateInstance(kPresShellCID, &rv); if(NS_FAILED(rv)){ gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } mPrt->mPrintVM = do_CreateInstance(kViewManagerCID, &rv); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } rv = mPrt->mPrintVM->Init(mPrt->mPrintDC); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } rv = CallCreateInstance(kViewCID, &mPrt->mPrintView); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } @@ -4450,6 +4461,7 @@ nsresult rv; rv = mPrt->mPrintView->Init(mPrt->mPrintVM,tbounds,nsnull); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } @@ -4512,7 +4524,7 @@ nsresult rv; mPrt->mPrintDC->GetDeviceSurfaceDimensions(i1,i2); printf(" DeviceDimension w = %d h = %d\n",i1,i2); -#endif +#endif /* DEBUG_dcone */ // Print listener setup... if (mPrt != nsnull) { mPrt->OnStartPrinting(); @@ -4536,24 +4548,102 @@ nsresult rv; } } } - } else { - if (mPagePrintTimer) { - mPagePrintTimer->Stop(); - NS_RELEASE(mPagePrintTimer); - } - mPrt->OnEndPrinting(NS_ERROR_FAILURE); + } + } + + /* cleaup on failure + notify user */ + if (NS_FAILED(rv)) { + /* cleanup... */ + if (mPagePrintTimer) { + mPagePrintTimer->Stop(); + NS_RELEASE(mPagePrintTimer); + } + + if (mPrt) { + mPrt->OnEndPrinting(rv); delete mPrt; mPrt = nsnull; - gCurrentlyPrinting = PR_FALSE; - rv = NS_ERROR_FAILURE; } + gCurrentlyPrinting = PR_FALSE; + /* cleanup done, let's fire-up an error dialog to notify the user + * what went wrong... + */ + ShowPrintErrorDialog(rv); } - + return rv; } +void +DocumentViewerImpl::ShowPrintErrorDialog(nsresult printerror) +{ + nsresult rv; + + static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); + nsCOMPtr stringBundleService = do_GetService(kCStringBundleServiceCID); + + if (!stringBundleService) { + NS_WARNING("ERROR: Failed to get StringBundle Service instance.\n"); + return; + } + nsCOMPtr myStringBundle; + rv = stringBundleService->CreateBundle(NS_ERROR_GFX_PRINTER_BUNDLE_URL, getter_AddRefs(myStringBundle)); + if (NS_FAILED(rv)) + return; + + PRUnichar *msg = nsnull, + *title = nsnull; + nsAutoString stringName; + + switch(printerror) + { +#define NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(nserr) case nserr: stringName = NS_LITERAL_STRING(#nserr); break; + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_CMD_NOT_FOUND) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_CMD_FAILURE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAIULABLE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_ACCESS_DENIED) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTER_NOT_READY) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_OUT_OF_PAPER) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTER_IO_ERROR) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_FILE_IO_ERROR) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_UNEXPECTED) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_OUT_OF_MEMORY) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_NOT_IMPLEMENTED) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_NOT_AVAILABLE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_ABORT) + default: + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE) +#undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG + } + + myStringBundle->GetStringFromName(stringName.get(), &msg); + myStringBundle->GetStringFromName(NS_LITERAL_STRING("print_error_dialog_title").get(), &title); + if (!msg) + return; + + nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + if (wwatch) { + nsCOMPtr active; + wwatch->GetActiveWindow(getter_AddRefs(active)); + + nsCOMPtr parent(do_QueryInterface(active)); + + if (parent) { + nsCOMPtr dialog; + parent->GetPrompter(getter_AddRefs(dialog)); + if (dialog) { + dialog->Alert(title, msg); + } + } + } +} + + NS_IMETHODIMP DocumentViewerImpl::GetPrintable(PRBool *aPrintable) { diff --git a/mozilla/gfx/public/nsIDeviceContext.h b/mozilla/gfx/public/nsIDeviceContext.h index 541c977128f..0852e00c6d0 100644 --- a/mozilla/gfx/public/nsIDeviceContext.h +++ b/mozilla/gfx/public/nsIDeviceContext.h @@ -18,6 +18,7 @@ * Rights Reserved. * * Contributor(s): + * Roland Mainz */ #ifndef nsIDeviceContext_h___ @@ -41,6 +42,43 @@ struct nsColor; //a cross platform way of specifying a native device context typedef void * nsNativeDeviceContext; +/* error codes for printer device contexts */ +#define NS_ERROR_GFX_PRINTER_BASE (1) /* adjustable :-) */ +/* Unix: print command (lp/lpr) not found */ +#define NS_ERROR_GFX_PRINTER_CMD_NOT_FOUND \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+1) +/* Unix: print command returned an error */ +#define NS_ERROR_GFX_PRINTER_CMD_FAILURE \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+2) +/* no printer available (e.g. cannot find _any_ printer) */ +#define NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAIULABLE \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+3) +/* _specified_ (by name) printer not found */ +#define NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+4) +/* access to printer denied */ +#define NS_ERROR_GFX_PRINTER_ACCESS_DENIED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+5) +/* invalid printer attribute (for example: unsupported paper size etc.) */ +#define NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+6) +/* printer not "ready" (offline ?) */ +#define NS_ERROR_GFX_PRINTER_PRINTER_NOT_READY \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+8) +/* printer out of paper */ +#define NS_ERROR_GFX_PRINTER_OUT_OF_PAPER \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+9) +/* generic printer I/O error */ +#define NS_ERROR_GFX_PRINTER_PRINTER_IO_ERROR \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+10) +/* print-to-file: could not open output file */ +#define NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+11) +/* print-to-file: I/O error while printing to file */ +#define NS_ERROR_GFX_PRINTER_FILE_IO_ERROR \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+12) + + #define NS_IDEVICE_CONTEXT_IID \ { 0x5931c580, 0xb917, 0x11d1, \ { 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } } diff --git a/mozilla/gfx/src/gtk/nsDeviceContextSpecFactoryG.cpp b/mozilla/gfx/src/gtk/nsDeviceContextSpecFactoryG.cpp index 9202d85acbf..535d2029501 100644 --- a/mozilla/gfx/src/gtk/nsDeviceContextSpecFactoryG.cpp +++ b/mozilla/gfx/src/gtk/nsDeviceContextSpecFactoryG.cpp @@ -17,7 +17,8 @@ * Copyright (C) 1999 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Roland Mainz */ #include "nsDeviceContextSpecFactoryG.h" @@ -42,9 +43,6 @@ nsDeviceContextSpecFactoryGTK :: ~nsDeviceContextSpecFactoryGTK() { } -static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); -static NS_DEFINE_CID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); - NS_IMPL_ISUPPORTS1(nsDeviceContextSpecFactoryGTK, nsIDeviceContextSpecFactory) /** ------------------------------------------------------- @@ -64,16 +62,19 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryGTK :: CreateDeviceContextSpec(nsIWidget nsIDeviceContextSpec *&aNewSpec, PRBool aQuiet) { -nsresult rv = NS_ERROR_FAILURE; -nsIDeviceContextSpec *devSpec = nsnull; + nsresult rv; + static NS_DEFINE_CID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); + nsCOMPtr devSpec = do_CreateInstance(kDeviceContextSpecCID, &rv); + if (NS_SUCCEEDED(rv)) + { + rv = ((nsDeviceContextSpecGTK *)devSpec.get())->Init(aQuiet); + if (NS_SUCCEEDED(rv)) + { + aNewSpec = devSpec; + NS_ADDREF(aNewSpec); + } + } - nsComponentManager::CreateInstance(kDeviceContextSpecCID, nsnull, kIDeviceContextSpecIID, (void **)&devSpec); - - if (nsnull != devSpec){ - if (NS_OK == ((nsDeviceContextSpecGTK *)devSpec)->Init(aQuiet)){ - aNewSpec = devSpec; - rv = NS_OK; - } - } - return rv; + return rv; } + diff --git a/mozilla/gfx/src/ps/nsDeviceContextPS.cpp b/mozilla/gfx/src/ps/nsDeviceContextPS.cpp index f7719b17a96..83e0887d0de 100644 --- a/mozilla/gfx/src/ps/nsDeviceContextPS.cpp +++ b/mozilla/gfx/src/ps/nsDeviceContextPS.cpp @@ -113,7 +113,7 @@ nsresult rv = NS_ERROR_OUT_OF_MEMORY; rv = NS_ERROR_OUT_OF_MEMORY; } - if (NS_OK != rv){ + if (NS_FAILED(rv)) { NS_IF_RELEASE(aContext); } @@ -187,20 +187,19 @@ NS_IMETHODIMP nsDeviceContextPS :: GetSystemAttribute(nsSystemAttrID anID, Syste NS_IMETHODIMP nsDeviceContextPS::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight) { nsIDeviceContextSpecPS *psSpec; - nsresult res; + nsresult rv = NS_ERROR_FAILURE; float width, height; float top,left,right,bottom; if ( nsnull != mSpec ) { - res = mSpec->QueryInterface(kIDeviceContextSpecPSIID, (void **) &psSpec); - if ( res == NS_OK ) { + rv = mSpec->QueryInterface(kIDeviceContextSpecPSIID, (void **) &psSpec); + if (NS_SUCCEEDED(rv)) { psSpec->GetPageDimensions( width, height ); aWidth = NSToIntRound((72.0f*width) * mDevUnitsToAppUnits); aHeight = NSToIntRound((72.0f*height) * mDevUnitsToAppUnits); - return NS_OK; } } - return NS_ERROR_FAILURE; + return rv; } /** --------------------------------------------------- @@ -247,7 +246,7 @@ NS_IMETHODIMP nsDeviceContextPS::BeginDocument(PRUnichar * aTitle) if ( nsnull != mSpec ) { mPSObj = new nsPostScriptObj(); res = mSpec->QueryInterface(kIDeviceContextSpecPSIID, (void **) &psSpec); - if ( res == NS_OK ) { + if (NS_SUCCEEDED(res)) { res = mPSObj->Init(psSpec,aTitle); } } @@ -260,8 +259,8 @@ NS_IMETHODIMP nsDeviceContextPS::BeginDocument(PRUnichar * aTitle) */ NS_IMETHODIMP nsDeviceContextPS::EndDocument(void) { - delete mPSObj; + mPSObj = nsnull; return NS_OK; } @@ -282,7 +281,6 @@ NS_IMETHODIMP nsDeviceContextPS::BeginPage(void) */ NS_IMETHODIMP nsDeviceContextPS::EndPage(void) { - // end the page mPSObj->end_page(); return NS_OK; diff --git a/mozilla/gfx/src/ps/nsPostScriptObj.cpp b/mozilla/gfx/src/ps/nsPostScriptObj.cpp index 81ef689179e..94cc2ae3c2b 100644 --- a/mozilla/gfx/src/ps/nsPostScriptObj.cpp +++ b/mozilla/gfx/src/ps/nsPostScriptObj.cpp @@ -198,6 +198,7 @@ nsPostScriptObj::~nsPostScriptObj() char VMSPrintCommand[1024]; PR_snprintf(VMSPrintCommand, sizeof(VMSPrintCommand), "%s /delete %s.", mPrintSetup->print_cmd, mPrintSetup->filename); + // FixMe: Check for error and return one of NS_ERROR_GFX_PRINTER_* on demand system(VMSPrintCommand); free(mPrintSetup->filename); } @@ -290,15 +291,18 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) } else { aSpec->GetPath( &buf ); mPrintSetup->filename = buf; - mPrintSetup->out = fopen(mPrintSetup->filename, "w"); + mPrintSetup->out = fopen(mPrintSetup->filename, "w"); + if (!mPrintSetup->out) + return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; } } else return NS_ERROR_FAILURE; /* make sure the open worked */ - if ( mPrintSetup->out == NULL ) - return NS_ERROR_FAILURE; + if (!mPrintSetup->out) + return NS_ERROR_GFX_PRINTER_CMD_FAILURE; + mPrintContext = new PSContext(); memset(mPrintContext, 0, sizeof(struct PSContext_)); memset(pi, 0, sizeof(struct PrintInfo_)); diff --git a/mozilla/gfx/src/xlib/nsDeviceContextSpecFactoryX.cpp b/mozilla/gfx/src/xlib/nsDeviceContextSpecFactoryX.cpp index a14aabee207..db4aa1b4403 100644 --- a/mozilla/gfx/src/xlib/nsDeviceContextSpecFactoryX.cpp +++ b/mozilla/gfx/src/xlib/nsDeviceContextSpecFactoryX.cpp @@ -18,7 +18,8 @@ * Rights Reserved. * * Contributor(s): - * Vino Fernando Crescini + * Vino Fernando Crescini + * Roland Mainz */ #include "nsDeviceContextSpecFactoryX.h" @@ -26,9 +27,6 @@ #include "nsGfxCIID.h" #include "plstr.h" -static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); -static NS_DEFINE_IID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); - NS_IMPL_ISUPPORTS1(nsDeviceContextSpecFactoryXlib, nsIDeviceContextSpecFactory) nsDeviceContextSpecFactoryXlib::nsDeviceContextSpecFactoryXlib() @@ -49,17 +47,19 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryXlib::CreateDeviceContextSpec(nsIWidget nsIDeviceContextSpec *&aNewSpec, PRBool aQuiet) { - nsresult rv = NS_ERROR_FAILURE; - nsIDeviceContextSpec *devSpec = nsnull; + nsresult rv; + static NS_DEFINE_CID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); + nsCOMPtr devSpec = do_CreateInstance(kDeviceContextSpecCID, &rv); + if (NS_SUCCEEDED(rv)) + { + rv = ((nsDeviceContextSpecXlib *)devSpec.get())->Init(aQuiet); + if (NS_SUCCEEDED(rv)) + { + aNewSpec = devSpec; + NS_ADDREF(aNewSpec); + } + } - nsComponentManager::CreateInstance(kDeviceContextSpecCID, nsnull, kIDeviceContextSpecIID, (void **)&devSpec); - - if (nsnull != devSpec) { - if (NS_OK == ((nsDeviceContextSpecXlib *)devSpec)->Init(aQuiet)) { - aNewSpec = devSpec; - rv = NS_OK; - } - } - return rv; + return rv; } diff --git a/mozilla/gfx/src/xprint/nsXPrintContext.cpp b/mozilla/gfx/src/xprint/nsXPrintContext.cpp index 66b36dad62f..57aeec53407 100644 --- a/mozilla/gfx/src/xprint/nsXPrintContext.cpp +++ b/mozilla/gfx/src/xprint/nsXPrintContext.cpp @@ -124,6 +124,7 @@ NS_IMETHODIMP nsXPrintContext::Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::Init()\n")); + nsresult rv = NS_ERROR_FAILURE; int prefDepth = 8; /* 24 or 8 for PS DDX, 24, 8, 1 for PCL DDX... * I wish current Xprt would have a 1bit/8bit StaticGray @@ -142,18 +143,20 @@ nsXPrintContext::Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec) unsigned short width, height; XRectangle rect; - if( NS_FAILED( XPU_TRACE(SetupPrintContext(aSpec)) ) ) - return NS_ERROR_FAILURE; + if (NS_FAILED(XPU_TRACE(rv = SetupPrintContext(aSpec)))) + return rv; mScreen = XpGetScreenOfContext(mPDisplay, mPContext); mScreenNumber = XScreenNumberOfScreen(mScreen); mXlibRgbHandle = xxlib_rgb_create_handle_with_depth("xprint", mPDisplay, mScreen, prefDepth); if (!mXlibRgbHandle) - return NS_ERROR_FAILURE; + return NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE; xxlib_disallow_image_tiling(mXlibRgbHandle, TRUE); XpGetPageDimensions(mPDisplay, mPContext, &width, &height, &rect); - SetupWindow(rect.x, rect.y, rect.width, rect.height); + rv = SetupWindow(rect.x, rect.y, rect.width, rect.height); + if (NS_FAILED(rv)) + return rv; XMapWindow(mPDisplay, mDrawable); @@ -261,7 +264,7 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("print to file '%s'\n", XPU_NULLXSTR(mPrintFile))); if( (mPrintFile == nsnull) || (strlen(mPrintFile) == 0) ) - return NS_ERROR_FAILURE; + return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; } /* workaround for crash in XCloseDisplay() on Solaris 2.7 Xserver - when @@ -274,7 +277,7 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) * ToDo: report error to user (dialog) */ if( XpuGetPrinter(buf, &mPDisplay, &mPContext) != 1 ) - return NS_ERROR_FAILURE; + return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND; #ifdef XPRINT_DEBUG_SOMETIMES_USEFULL dumpXpAttributes(mPDisplay, mPContext); @@ -314,7 +317,7 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) * ToDo: Report error to user (dialog) */ if( XpuGetResolution(mPDisplay, mPContext, &mPrintResolution) == False ) - return NS_ERROR_FAILURE; + return NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE; PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("print resolution %ld\n", (long)mPrintResolution)); @@ -379,7 +382,7 @@ nsXPrintContext::BeginDocument( PRUnichar *aTitle ) ("nsXPrintContext::BeginDocument(): XpuPrintToFile failure %s/(%d)\n", strerror(errno), errno)); - return NS_ERROR_FAILURE; + return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; } XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartJobNotify)); diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 4a711ea9f1e..ac19fcf334b 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -19,6 +19,7 @@ * * Contributor(s): * Dan Rosen + * Roland Mainz */ #include "nscore.h" @@ -118,6 +119,13 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #include "nsIDOMHTMLFrameSetElement.h" #include "nsIDOMHTMLIFrameElement.h" +// Print error dialog +#include "nsIPrompt.h" +#include "nsIWindowWatcher.h" +#include "nsIStringBundle.h" + +#define NS_ERROR_GFX_PRINTER_BUNDLE_URL "chrome://communicator/locale/printing.properties" + // FrameSet #include "nsINodeInfo.h" #include "nsIDocument.h" @@ -131,23 +139,19 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #include "nsIDOMFocusListener.h" #include "nsISelectionController.h" -#include "nsISound.h" - #include "nsITransformMediator.h" #ifdef IBMBIDI #include "nsIUBidiUtils.h" #endif -static NS_DEFINE_IID(kSoundCID,NS_SOUND_CID); - static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID); static NS_DEFINE_CID(kGalleyContextCID, NS_GALLEYCONTEXT_CID); static NS_DEFINE_CID(kPrintContextCID, NS_PRINTCONTEXT_CID); static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID); -PRBool gCurrentlyPrinting = PR_FALSE; +static PRBool gCurrentlyPrinting = PR_FALSE; #ifdef NS_DEBUG @@ -170,11 +174,10 @@ PRBool gCurrentlyPrinting = PR_FALSE; #endif #define PRT_YESNO(_p) ((_p)?"YES":"NO") -const char * gFrameTypesStr[] = {"eDoc", "eFrame", "eIFrame", "eFrameSet"}; -const char * gPrintFrameTypeStr[] = {"kNoFrames", "kFramesAsIs", "kSelectedFrame", "kEachFrameSep"}; -const char * gFrameHowToEnableStr[] = {"kFrameEnableNone", "kFrameEnableAll", "kFrameEnableAsIsAndEach"}; -const char * gPrintRangeStr[] = {"kRangeAllPages", "kRangeSpecifiedPageRange", "kRangeSelection", "kRangeFocusFrame"}; - +static const char * gFrameTypesStr[] = {"eDoc", "eFrame", "eIFrame", "eFrameSet"}; +static const char * gPrintFrameTypeStr[] = {"kNoFrames", "kFramesAsIs", "kSelectedFrame", "kEachFrameSep"}; +static const char * gFrameHowToEnableStr[] = {"kFrameEnableNone", "kFrameEnableAll", "kFrameEnableAsIsAndEach"}; +static const char * gPrintRangeStr[] = {"kRangeAllPages", "kRangeSpecifiedPageRange", "kRangeSelection", "kRangeFocusFrame"}; #define PRINT_DEBUG_MSG1(_msg1) fprintf(mPrt->mDebugFD, (_msg1)); @@ -494,6 +497,9 @@ private: PRUint32 aDelay); void PrepareToStartLoad(void); + + // Misc + void ShowPrintErrorDialog(nsresult printerror); protected: // IMPORTANT: The ownership implicit in the following member @@ -4252,7 +4258,7 @@ DocumentViewerImpl::IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin) } return PR_FALSE; } - + /** --------------------------------------------------- * See documentation above in the nsIContentViewerfile class definition * @update 01/24/00 dwc @@ -4266,17 +4272,15 @@ nsresult rv; // the reason we check here is because this method can be called while // another is still in here (the printing dialog is a good example). // the only time we can print more than one job at a time is the regression tests - if(gCurrentlyPrinting) { - // Beep at the user, let them know we are not ready to print. - nsCOMPtr soundInterface( do_CreateInstance(kSoundCID, &rv) ); - if (NS_SUCCEEDED(rv) && (soundInterface != nsnull)){ - soundInterface->Beep(); - } - return NS_ERROR_FAILURE; - } else { - gCurrentlyPrinting = PR_TRUE; + if (gCurrentlyPrinting) { + // Let the user know we are not ready to print. + rv = NS_ERROR_NOT_AVAILABLE; + ShowPrintErrorDialog(rv); + return rv; } - + + // Let's print ... + gCurrentlyPrinting = PR_TRUE; mPrt = new PrintData(); if (mPrt == nsnull) { @@ -4370,11 +4374,11 @@ nsresult rv; } #endif + /* create factory (incl. create print dialog) */ nsCOMPtr factory = - do_CreateInstance(kDeviceContextSpecFactoryCID); - - if (factory) { - + do_CreateInstance(kDeviceContextSpecFactoryCID, &rv); + + if (NS_SUCCEEDED(rv)) { #ifdef DEBUG_dcone printf("PRINT JOB STARTING\n"); #endif @@ -4384,24 +4388,27 @@ nsresult rv; mPrt->mPrintDC = nsnull; // XXX why? mPrt->mFilePointer = aFile; - factory->CreateDeviceContextSpec(mWindow, devspec, aSilent); - if (nsnull != devspec) { - mPresContext->GetDeviceContext(getter_AddRefs(dx)); - rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC)); + rv = factory->CreateDeviceContextSpec(mWindow, devspec, aSilent); + if (NS_SUCCEEDED(rv)) { + rv = mPresContext->GetDeviceContext(getter_AddRefs(dx)); + if (NS_SUCCEEDED(rv)) + rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC)); + if (NS_SUCCEEDED(rv)) { - NS_RELEASE(devspec); if(webContainer) { // load the document and do the initial reflow on the entire document - nsCOMPtr printcon(do_CreateInstance(kPrintContextCID,&rv)); + nsCOMPtr printcon(do_CreateInstance(kPrintContextCID, &rv)); if (NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } else { mPrt->mPrintPC = do_QueryInterface(printcon, &rv); if (NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } } @@ -4425,24 +4432,28 @@ nsresult rv; mPrt->mPrintPS = do_CreateInstance(kPresShellCID, &rv); if(NS_FAILED(rv)){ gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } mPrt->mPrintVM = do_CreateInstance(kViewManagerCID, &rv); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } rv = mPrt->mPrintVM->Init(mPrt->mPrintDC); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } rv = CallCreateInstance(kViewCID, &mPrt->mPrintView); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } @@ -4450,6 +4461,7 @@ nsresult rv; rv = mPrt->mPrintView->Init(mPrt->mPrintVM,tbounds,nsnull); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; + ShowPrintErrorDialog(rv); return rv; } @@ -4512,7 +4524,7 @@ nsresult rv; mPrt->mPrintDC->GetDeviceSurfaceDimensions(i1,i2); printf(" DeviceDimension w = %d h = %d\n",i1,i2); -#endif +#endif /* DEBUG_dcone */ // Print listener setup... if (mPrt != nsnull) { mPrt->OnStartPrinting(); @@ -4536,24 +4548,102 @@ nsresult rv; } } } - } else { - if (mPagePrintTimer) { - mPagePrintTimer->Stop(); - NS_RELEASE(mPagePrintTimer); - } - mPrt->OnEndPrinting(NS_ERROR_FAILURE); + } + } + + /* cleaup on failure + notify user */ + if (NS_FAILED(rv)) { + /* cleanup... */ + if (mPagePrintTimer) { + mPagePrintTimer->Stop(); + NS_RELEASE(mPagePrintTimer); + } + + if (mPrt) { + mPrt->OnEndPrinting(rv); delete mPrt; mPrt = nsnull; - gCurrentlyPrinting = PR_FALSE; - rv = NS_ERROR_FAILURE; } + gCurrentlyPrinting = PR_FALSE; + /* cleanup done, let's fire-up an error dialog to notify the user + * what went wrong... + */ + ShowPrintErrorDialog(rv); } - + return rv; } +void +DocumentViewerImpl::ShowPrintErrorDialog(nsresult printerror) +{ + nsresult rv; + + static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); + nsCOMPtr stringBundleService = do_GetService(kCStringBundleServiceCID); + + if (!stringBundleService) { + NS_WARNING("ERROR: Failed to get StringBundle Service instance.\n"); + return; + } + nsCOMPtr myStringBundle; + rv = stringBundleService->CreateBundle(NS_ERROR_GFX_PRINTER_BUNDLE_URL, getter_AddRefs(myStringBundle)); + if (NS_FAILED(rv)) + return; + + PRUnichar *msg = nsnull, + *title = nsnull; + nsAutoString stringName; + + switch(printerror) + { +#define NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(nserr) case nserr: stringName = NS_LITERAL_STRING(#nserr); break; + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_CMD_NOT_FOUND) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_CMD_FAILURE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAIULABLE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_ACCESS_DENIED) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTER_NOT_READY) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_OUT_OF_PAPER) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTER_IO_ERROR) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_FILE_IO_ERROR) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_UNEXPECTED) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_OUT_OF_MEMORY) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_NOT_IMPLEMENTED) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_NOT_AVAILABLE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_ABORT) + default: + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE) +#undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG + } + + myStringBundle->GetStringFromName(stringName.get(), &msg); + myStringBundle->GetStringFromName(NS_LITERAL_STRING("print_error_dialog_title").get(), &title); + if (!msg) + return; + + nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + if (wwatch) { + nsCOMPtr active; + wwatch->GetActiveWindow(getter_AddRefs(active)); + + nsCOMPtr parent(do_QueryInterface(active)); + + if (parent) { + nsCOMPtr dialog; + parent->GetPrompter(getter_AddRefs(dialog)); + if (dialog) { + dialog->Alert(title, msg); + } + } + } +} + + NS_IMETHODIMP DocumentViewerImpl::GetPrintable(PRBool *aPrintable) { diff --git a/mozilla/layout/html/base/src/printing.properties b/mozilla/layout/html/base/src/printing.properties index f16f0e2715f..820efb32ecf 100644 --- a/mozilla/layout/html/base/src/printing.properties +++ b/mozilla/layout/html/base/src/printing.properties @@ -15,7 +15,9 @@ # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # -# Contributor(s): +# Contributor(s): +# Roland Mainz +# # Page number formating ## @page_number The current page number @@ -40,3 +42,25 @@ fontname=serif # Print font size # The size of the font to be used to print the headers and footers fontsize=10 + +# Print error codes +print_error_dialog_title=Printer error +NS_ERROR_GFX_PRINTER_CMD_NOT_FOUND=Printer command not found +NS_ERROR_GFX_PRINTER_CMD_FAILURE=Printer command failure +NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAIULABLE=No printer found +NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND=Printer not found +NS_ERROR_GFX_PRINTER_ACCESS_DENIED=Access to printer denied +NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE=Invalid printer attribute +NS_ERROR_GFX_PRINTER_PRINTER_NOT_READY=Printer not ready +NS_ERROR_GFX_PRINTER_OUT_OF_PAPER=Printer out pf paper +NS_ERROR_GFX_PRINTER_PRINTER_IO_ERROR=Printer I/O error +NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE=Could not open output file for printing +NS_ERROR_GFX_PRINTER_FILE_IO_ERROR=Print file I/O error +NS_ERROR_UNEXPECTED=Unexpected error +NS_ERROR_OUT_OF_MEMORY=Out of memory +NS_ERROR_NOT_IMPLEMENTED=Functionality not implemented (yet) +NS_ERROR_NOT_AVAILABLE=Not available +NS_ERROR_ABORT=Job aborted +NS_ERROR_FAILURE=Failure +# EOF. +