Bug 193001 - "Use gnome's native print dialog" [p=ventnor.bugzilla@yahoo.com.au (Michael Ventnor) r+sr+a1.9=roc]

This commit is contained in:
reed@reedloden.com 2008-01-20 19:47:25 -08:00
parent 0e9e236c9e
commit 23bbd145b3
26 changed files with 1833 additions and 970 deletions

View File

@ -250,6 +250,9 @@ gtk/gtkinvisible.h
gtk/gtkmain.h
gtk/gtkmessagedialog.h
gtk/gtkobject.h
gtk/gtkprinter.h
gtk/gtkprintjob.h
gtk/gtkprintunixdialog.h
gtk/gtkprivate.h
gtk/gtkselection.h
gtk/gtksignal.h

View File

@ -4599,7 +4599,7 @@ fi
if test "$COMPILE_ENVIRONMENT"; then
if test "$MOZ_ENABLE_GTK2"
then
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gdk-x11-2.0 glib-2.0 gobject-2.0)
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 gdk-x11-2.0 glib-2.0 gobject-2.0)
fi
fi # COMPILE_ENVIRONMENT

View File

@ -44,6 +44,7 @@
#include "nsISupportsUtils.h"
#include "nsISupportsArray.h"
#include "nsString.h"
#include "nsIPrintDialogService.h"
// Printing Progress Includes
#include "nsPrintProgress.h"
@ -109,6 +110,13 @@ nsPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrin
NS_ENSURE_ARG(webBrowserPrint);
NS_ENSURE_ARG(printSettings);
// Try to access a component dialog
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
NS_PRINTDIALOGSERVICE_CONTRACTID));
if (dlgPrint)
return dlgPrint->Show(printSettings);
// Show the built-in dialog instead
ParamBlock block;
nsresult rv = block.Init();
if (NS_FAILED(rv))
@ -177,6 +185,12 @@ nsPrintingPromptService::ShowPageSetup(nsIDOMWindow *parent, nsIPrintSettings *p
{
NS_ENSURE_ARG(printSettings);
// Try to access a component dialog
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
NS_PRINTDIALOGSERVICE_CONTRACTID));
if (dlgPrint)
return dlgPrint->ShowPageSetup(printSettings);
ParamBlock block;
nsresult rv = block.Init();
if (NS_FAILED(rv))

View File

@ -3431,6 +3431,11 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
}
#endif
if (!mContainer) {
PR_PL(("Container was destroyed yet we are still trying to use it!"));
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
NS_ASSERTION(docShell, "This has to be a docshell");
@ -3525,6 +3530,11 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings,
}
#endif
if (!mContainer) {
PR_PL(("Container was destroyed yet we are still trying to use it!"));
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
NS_ASSERTION(docShell, "This has to be a docshell");
nsCOMPtr<nsIPresShell> presShell;

View File

@ -597,9 +597,14 @@ nsPrintEngine::DoCommonPrint(PRBool aIsPrintPreview,
// are telling GFX we want to print silent
printSilently = PR_TRUE;
}
// The user might have changed shrink-to-fit in the print dialog, so update our copy of its state
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
} else {
rv = NS_ERROR_GFX_NO_PRINTROMPTSERVICE;
}
} else {
// Call any code that requires a run of the event loop.
rv = mPrt->mPrintSettings->SetupSilentPrinting();
}
// Check explicitly for abort because it's expected
if (rv == NS_ERROR_ABORT)

View File

@ -0,0 +1,28 @@
printTitle=Print
optionsTabLabel=Options
printFramesTitle=Print Frames
# TRANSLATOR NOTE: For radio button labels and check button labels, an underscore _
# before a character will turn that character into an accesskey.
# e.g. "_As laid out" will make A the accesskey.
asLaidOut=_As Laid Out on the Screen
selectedFrame=The _Selected Frame
separateFrames=Each Frame on Separate _Pages
shrinkToFit=Ignore Scaling and S_hrink To Fit Page Width
selectionOnly=Print Selection _Only
printBGOptions=Print Backgrounds
printBGColors=Print Background _Colors
printBGImages=Print Background I_mages
headerFooter=Header and Footer
left=Left
center=Center
right=Right
headerFooterBlank=--blank--
headerFooterTitle=Title
headerFooterURL=URL
headerFooterDate=Date/Time
headerFooterPage=Page #
headerFooterPageTotal=Page # of #
headerFooterCustom=Custom...
customHeaderFooterPrompt=Please enter your custom header/footer text

View File

@ -40,6 +40,7 @@
+ locale/@AB_CD@/global/printPageSetup.dtd (%chrome/global/printPageSetup.dtd)
+ locale/@AB_CD@/global/printPreview.dtd (%chrome/global/printPreview.dtd)
+ locale/@AB_CD@/global/printPreviewProgress.dtd (%chrome/global/printPreviewProgress.dtd)
locale/@AB_CD@/global/gnomeprintdialog.properties (%chrome/global/gnomeprintdialog.properties)
+ locale/@AB_CD@/global/printProgress.dtd (%chrome/global/printProgress.dtd)
+ locale/@AB_CD@/global/regionNames.properties (%chrome/global/regionNames.properties)
+ locale/@AB_CD@/global/dialog.properties (%chrome/global/dialog.properties)

View File

@ -79,7 +79,10 @@ EXPORTS += nsIDragSessionBeOS.h
endif
ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
EXPORTS += nsIDragSessionGTK.h
EXPORTS += \
nsIDragSessionGTK.h \
nsIPrintDialogService.h \
$(NULL)
endif
XPIDLSRCS = \

View File

@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Kenneth Herron <kherron@fmailbox.com>
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIPrintDialogService_h__
#define nsIPrintDialogService_h__
#include "nsISupports.h"
class nsIPrintSettings;
/*
* Interface to a print dialog accessed through the widget library.
*/
#define NS_IPRINTDIALOGSERVICE_IID \
{ 0x3715eb1a, 0xb314, 0x447c, \
{ 0x95, 0x33, 0xd0, 0x6a, 0x6d, 0xa6, 0xa6, 0xf0 } }
/**
*
*/
class nsIPrintDialogService : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRINTDIALOGSERVICE_IID)
/**
* Initialize the service.
* @return NS_OK or a suitable error.
*/
NS_IMETHOD Init() = 0;
/**
* Show the print dialog.
* @param aSettings On entry, this contains initial settings for the
* print dialog. On return, if the print operation should
* proceed then this contains settings for the print
* operation.
* @return NS_OK if the print operation should proceed
* @return NS_ERROR_ABORT if the user indicated not to proceed
* @return a suitable error for failures to show the print dialog.
*/
NS_IMETHOD Show(nsIPrintSettings *aSettings) = 0;
/**
* Show the page setup dialog. Note that there is no way to tell whether the user clicked OK or Cancel on the
* dialog.
* @param aSettings On entry, this contains initial settings for the
* page setup dialog. On return, this contains new default page setup options.
* @return NS_OK if everything is OK.
* @return a suitable error for failures to show the page setup dialog.
*/
NS_IMETHOD ShowPageSetup(nsIPrintSettings *aSettings) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrintDialogService, NS_IPRINTDIALOGSERVICE_IID)
#define NS_PRINTDIALOGSERVICE_CONTRACTID ("@mozilla.org/widget/printdialog-service;1")
#endif // nsIPrintDialogService_h__

View File

@ -58,7 +58,7 @@ interface nsIPrintSession;
*
* @status UNDER_REVIEW
*/
[scriptable, uuid(81b8dfee-25cc-479c-ad2c-a5e3875650cb)]
[scriptable, uuid(3e097aba-c1d6-425d-9c52-b371d5da964a)]
interface nsIPrintSettings : nsISupports
{
@ -301,4 +301,14 @@ interface nsIPrintSettings : nsISupports
/* Purposely made this an "in" arg */
[noscript] void GetMarginInTwips(in nsNativeMarginRef aMargin);
[noscript] void GetEdgeInTwips(in nsNativeMarginRef aEdge);
/**
* We call this function so that anything that requires a run of the event loop
* can do so safely. The print dialog runs the event loop but in silent printing
* that doesn't happen.
*
* Either this or ShowPrintDialog (but not both) MUST be called by the print engine
* before printing, otherwise printing can fail on some platforms.
*/
[noscript] void SetupSilentPrinting();
};

View File

@ -167,3 +167,6 @@
{ 0x2f977d53, 0x5485, 0x11d4, \
{ 0x87, 0xe2, 0x00, 0x10, 0xa4, 0xe7, 0x5e, 0xf2 } }
#define NS_PRINTDIALOGSERVICE_CID \
{ 0x06beec76, 0xa183, 0x4d9f, \
{ 0x85, 0xdd, 0x08, 0x5f, 0x26, 0xda, 0x56, 0x5a } }

View File

@ -108,9 +108,9 @@ CPPSRCS = \
nsPrintOptionsGTK.cpp \
nsImageToPixbuf.cpp \
nsAccessibilityHelper.cpp \
nsPrintJobFactoryGTK.cpp \
nsPrintJobGTK.cpp \
nsIdleServiceGTK.cpp \
nsPrintDialogGTK.cpp \
nsPrintSettingsGTK.cpp \
$(NULL)
# build our subdirs, too

View File

@ -23,6 +23,7 @@
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Ken Herron <kherron+mozilla@fmailbox.com>
* Julien Lafon <julien.lafon@gmail.com>
* Michael Ventnor <m.ventnor@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -66,12 +67,15 @@
#include "nsPaperPS.h" /* Paper size list */
#endif /* USE_POSTSCRIPT */
#include "nsPrintJobFactoryGTK.h"
#include "nsIPrintJobGTK.h"
#include "nsPrintSettingsGTK.h"
#include "nsIFileStreams.h"
#include "nsILocalFile.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
/* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
#define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE))
@ -382,13 +386,11 @@ nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull;
nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
{
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
mPrintJob = nsnull;
}
nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()
{
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n"));
delete mPrintJob;
}
NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK,
@ -410,18 +412,30 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurfac
height /= 20;
DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", path, width, height));
nsresult rv;
nsresult rv = nsPrintJobFactoryGTK::CreatePrintJob(this, mPrintJob);
if (NS_FAILED(rv))
return rv;
// Spool file. Use Glib's temporary file function since we're
// already dependent on the gtk software stack.
gchar *buf;
gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nsnull);
if (-1 == fd)
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
close(fd);
nsCOMPtr<nsILocalFile> file;
rv = mPrintJob->GetSpoolFile(getter_AddRefs(file));
if (NS_FAILED(rv))
return rv;
rv = NS_NewNativeLocalFile(nsDependentCString(buf), PR_FALSE,
getter_AddRefs(mSpoolFile));
if (NS_FAILED(rv)) {
unlink(buf);
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
}
mSpoolName = buf;
g_free(buf);
mSpoolFile->SetPermissions(0600);
nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
rv = stream->Init(file, -1, -1, 0);
rv = stream->Init(mSpoolFile, -1, -1, 0);
if (NS_FAILED(rv))
return rv;
@ -429,10 +443,31 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurfac
mPrintSettings->GetOutputFormat(&format);
nsRefPtr<gfxASurface> surface;
if (nsIPrintSettings::kOutputFormatPDF == format) {
surface = new gfxPDFSurface(stream, gfxSize(width, height));
gfxSize surfaceSize(width, height);
// Determine the real format with some GTK magic
if (format == nsIPrintSettings::kOutputFormatNative) {
if (mIsPPreview) {
// There is nothing to detect on Print Preview, use PS.
format = nsIPrintSettings::kOutputFormatPS;
} else {
const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) {
// Likely not print-to-file, check printer's capabilities
format = (gtk_printer_accepts_pdf(mGtkPrinter)) ? nsIPrintSettings::kOutputFormatPDF
: nsIPrintSettings::kOutputFormatPS;
} else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
format = nsIPrintSettings::kOutputFormatPDF;
} else {
format = nsIPrintSettings::kOutputFormatPS;
}
}
}
if (format == nsIPrintSettings::kOutputFormatPDF) {
surface = new gfxPDFSurface(stream, surfaceSize);
} else {
surface = new gfxPSSurface(stream, gfxSize(width, height));
surface = new gfxPSSurface(stream, surfaceSize);
}
if (!surface)
@ -453,104 +488,29 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget *aWidget,
PRBool aIsPrintPreview)
{
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::Init(aPS=%p)\n", aPS));
nsresult rv = NS_ERROR_FAILURE;
if (gtk_major_version < 2 ||
(gtk_major_version == 2 && gtk_minor_version < 10))
return NS_ERROR_NOT_AVAILABLE; // I'm so sorry bz
mPrintSettings = aPS;
mIsPPreview = aIsPrintPreview;
// if there is a current selection then enable the "Selection" radio button
rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
if (NS_FAILED(rv)) {
return rv;
}
// This is only set by embedders
PRBool toFile;
aPS->GetPrintToFile(&toFile);
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
mToPrinter = !toFile && !aIsPrintPreview;
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 *plexname = nsnull;
PRUnichar *resolutionname = nsnull;
PRUnichar *colorspace = nsnull;
PRBool downloadfonts = PR_TRUE;
PRUnichar *printfile = nsnull;
double dleft = 0.5;
double dright = 0.5;
double dtop = 0.5;
double dbottom = 0.5;
nsCOMPtr<nsPrintSettingsGTK> printSettingsGTK(do_QueryInterface(aPS));
if (!printSettingsGTK)
return NS_ERROR_NO_INTERFACE;
aPS->GetPrinterName(&printer);
aPS->GetPrintReversed(&reversed);
aPS->GetPrintInColor(&color);
aPS->GetPaperName(&papername);
aPS->GetResolutionName(&resolutionname);
aPS->GetColorspace(&colorspace);
aPS->GetDownloadFonts(&downloadfonts);
aPS->GetPlexName(&plexname);
aPS->GetOrientation(&orientation);
aPS->GetPrintCommand(&command);
aPS->GetPrintRange(&printRange);
aPS->GetToFileName(&printfile);
aPS->GetPrintToFile(&tofile);
aPS->GetStartPageRange(&fromPage);
aPS->GetEndPageRange(&toPage);
aPS->GetNumCopies(&copies);
aPS->GetMarginTop(&dtop);
aPS->GetMarginLeft(&dleft);
aPS->GetMarginBottom(&dbottom);
aPS->GetMarginRight(&dright);
mGtkPrinter = printSettingsGTK->GetGtkPrinter();
mGtkPrintSettings = printSettingsGTK->GetGtkPrintSettings();
mGtkPageSetup = printSettingsGTK->GetGtkPageSetup();
if (printfile)
PL_strncpyz(mPath, NS_ConvertUTF16toUTF8(printfile).get(), sizeof(mPath));
if (command)
PL_strncpyz(mCommand, NS_ConvertUTF16toUTF8(command).get(), sizeof(mCommand));
if (printer)
PL_strncpyz(mPrinter, NS_ConvertUTF16toUTF8(printer).get(), sizeof(mPrinter));
if (papername)
PL_strncpyz(mPaperName, NS_ConvertUTF16toUTF8(papername).get(), sizeof(mPaperName));
if (plexname)
PL_strncpyz(mPlexName, NS_ConvertUTF16toUTF8(plexname).get(), sizeof(mPlexName));
if (resolutionname)
PL_strncpyz(mResolutionName, NS_ConvertUTF16toUTF8(resolutionname).get(), sizeof(mResolutionName));
if (colorspace)
PL_strncpyz(mColorspace, NS_ConvertUTF16toUTF8(colorspace).get(), sizeof(mColorspace));
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_ConvertUTF16toUTF8(printfile).get():"<NULL>"));
DO_PR_DEBUG_LOG(("command '%s'\n", command? NS_ConvertUTF16toUTF8(command).get():"<NULL>"));
DO_PR_DEBUG_LOG(("printer '%s'\n", printer? NS_ConvertUTF16toUTF8(printer).get():"<NULL>"));
DO_PR_DEBUG_LOG(("papername '%s'\n", papername? NS_ConvertUTF16toUTF8(papername).get():"<NULL>"));
DO_PR_DEBUG_LOG(("plexname '%s'\n", plexname? NS_ConvertUTF16toUTF8(plexname).get():"<NULL>"));
DO_PR_DEBUG_LOG(("resolution '%s'\n", resolutionname? NS_ConvertUTF16toUTF8(resolutionname).get():"<NULL>"));
DO_PR_DEBUG_LOG(("colorspace '%s'\n", colorspace? NS_ConvertUTF16toUTF8(colorspace).get():"<NULL>"));
mTop = dtop;
mBottom = dbottom;
mLeft = dleft;
mRight = dright;
mFpf = !reversed;
mDownloadFonts = downloadfonts;
mGrayscale = !color;
mOrientation = orientation;
mToPrinter = !tofile;
mCopies = copies;
mIsPPreview = aIsPrintPreview;
mCancel = PR_FALSE;
}
return rv;
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecGTK::GetToPrinter(PRBool &aToPrinter)
@ -688,14 +648,69 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::ClosePrintManager()
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(PRUnichar * aTitle, PRUnichar * aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage)
static void
print_callback(GtkPrintJob *aJob, gpointer aData, GError *aError) {
g_object_unref(aJob);
((nsILocalFile*) aData)->Remove(PR_FALSE);
}
static void
ns_release_macro(gpointer aData) {
nsILocalFile* spoolFile = (nsILocalFile*) aData;
NS_RELEASE(spoolFile);
}
NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(PRUnichar * aTitle, PRUnichar * aPrintToFileName,
PRInt32 aStartPage, PRInt32 aEndPage)
{
if (mToPrinter) {
if (!GTK_IS_PRINTER(mGtkPrinter))
return NS_ERROR_FAILURE;
mPrintJob = gtk_print_job_new(NS_ConvertUTF16toUTF8(aTitle).get(), mGtkPrinter,
mGtkPrintSettings, mGtkPageSetup);
}
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument()
{
return mPrintJob->Submit();
if (mToPrinter) {
if (!gtk_print_job_set_source_file(mPrintJob, mSpoolName.get(), NULL))
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
NS_ADDREF(mSpoolFile.get());
gtk_print_job_send(mPrintJob, print_callback, mSpoolFile, ns_release_macro);
} else {
// Handle print-to-file ourselves for the benefit of embedders
nsXPIDLString targetPath;
nsCOMPtr<nsILocalFile> destFile;
mPrintSettings->GetToFileName(getter_Copies(targetPath));
nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath),
PR_FALSE, getter_AddRefs(destFile));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString destLeafName;
rv = destFile->GetLeafName(destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> destDir;
rv = destFile->GetParent(getter_AddRefs(destDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = mSpoolFile->MoveTo(destDir, destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
// This is the standard way to get the UNIX umask. Ugh.
mode_t mask = umask(0);
umask(mask);
// If you're not familiar with umasks, they contain the bits of what NOT to set in the permissions
// (thats because files and directories have different numbers of bits for their permissions)
destFile->SetPermissions(0666 & ~(mask));
}
return NS_OK;
}
/* Get prefs for printer

View File

@ -43,10 +43,13 @@
#include "nsIPrintSettings.h"
#include "nsIPrintOptions.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsCRT.h" /* should be <limits.h>? */
class nsIPrintJobGTK;
#include <gtk/gtk.h>
#include <gtk/gtkprinter.h>
#include <gtk/gtkprintjob.h>
#define NS_PORTRAIT 0
#define NS_LANDSCAPE 1
@ -117,7 +120,15 @@ protected:
float mRight; /* right margin */
float mTop; /* top margin */
float mBottom; /* bottom margin */
nsIPrintJobGTK * mPrintJob;
GtkPrintJob* mPrintJob;
GtkPrinter* mGtkPrinter;
GtkPrintSettings* mGtkPrintSettings;
GtkPageSetup* mGtkPageSetup;
nsCString mSpoolName;
nsCOMPtr<nsILocalFile> mSpoolFile;
};
//-------------------------------------------------------------------------

View File

@ -1,142 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Ken Herron <kherron@fastmail.us>.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIPrintJobGTK_h__
#define nsIPrintJobGTK_h__
#include "nsCOMPtr.h"
class nsDeviceContextSpecGTK;
class nsILocalFile;
/*
* This is an interface for a class that accepts and submits print jobs.
*
* Instances should be obtained through nsPrintJobFactoryGTK::CreatePrintJob().
* After obtaining a print job object, the caller can retrieve the spool file
* object associated with the print job and write the print job to that.
* Once that is done, the caller may call Submit() to finalize and print
* the job, or Cancel() to abort the job.
*/
class nsIPrintJobGTK
{
public:
virtual ~nsIPrintJobGTK();
/* Allow the print job factory to create instances */
friend class nsPrintJobFactoryGTK;
/**
* Set the number of copies for this print job. Some printing systems
* allow setting this out of band, instead of embedding it into the
* postscript.
* @param aNumCopies Number of copies requested. Values <= 1 are
* interpreted as "do not specify a copy count to the
* printing system" when possible, or else as
* one copy.
* @return NS_ERROR_NOT_IMPLEMENTED if this print job class doesn't
* support the specific copy count requested.
* @return NS_OK The print job class will request the specified
* number of copies when printing the job.
*/
virtual nsresult SetNumCopies(int aNumCopies)
{ return NS_ERROR_NOT_IMPLEMENTED; }
/**
* Set the print job title. Some printing systems accept a job title
* which is displayed on a banner page, in a print queue listing, etc.
*
* This must be called after Init() and before StartSubmission().
* nsIPrintJobGTK provides a stub implementation because most classes
* do not make use of this information.
*
* @param aTitle The job title.
*/
virtual void SetJobTitle(const PRUnichar *aTitle) { }
/**
* Get the temporary file that the print job should be written to. The
* caller may open this file for writing and write the text of the print
* job to it.
*
* The spool file is owned by the print job object, and will be removed
* by the print job dtor. Each print job object has one spool file.
*
* @return NS_ERROR_NOT_INITIALIZED if the object hasn't been initialized.
* NS_OK otherwise.
*
* This is currently non-virtual for efficiency.
*/
nsresult GetSpoolFile(nsILocalFile **aFile);
/**
* Submit a finished print job. The caller may call this after
* calling GetSpoolFile(), writing the text of the print job to the
* spool file, and closing the spool file. The return value indicates
* the overall success or failure of the print operation.
*
* The caller must not try to access the spool file in any way after
* calling this function.
*
* @return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED if the print
* job object doesn't actually support printing (e.g.
* for print preview)
* NS_OK for success
* Other values indicate failure of the print operation.
*/
virtual nsresult Submit() = 0;
protected:
/**
* Initialize an object from a device context spec. This must be
* called before any of the public methods. Implementations must
* initialize mSpoolFile declared below.
*
* @param aContext The device context spec describing the
* desired print job.
* @return NS_OK or a suitable error value.
*/
virtual nsresult Init(nsDeviceContextSpecGTK *aContext) = 0;
/* The spool file */
nsCOMPtr<nsILocalFile> mSpoolFile;
};
#endif /* nsIPrintJobGTK_h__ */

View File

@ -0,0 +1,561 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla GTK2 print dialog interface.
*
* The Initial Developer of the Original Code is
* Kenneth Herron <kherron@fmailbox.com>
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Ventnor <m.ventnor@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <gtk/gtk.h>
#include <gtk/gtkprintunixdialog.h>
#include <stdlib.h>
#include "mozcontainer.h"
#include "nsAccessibilityHelper.h"
#include "nsIPrintSettings.h"
#include "nsIWidget.h"
#include "nsPrintDialogGTK.h"
#include "nsPrintSettingsGTK.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsILocalFile.h"
#include "nsNetUtil.h"
#include "nsIStringBundle.h"
#include "nsIPrintSettingsService.h"
static const char header_footer_tags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
#define CUSTOM_VALUE_INDEX NS_ARRAY_LENGTH(header_footer_tags)
static void
ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data)
{
if (gtk_combo_box_get_active(changed_box) != CUSTOM_VALUE_INDEX)
return;
nsCOMPtr<nsIStringBundleService> bundleSvc =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
nsCOMPtr<nsIStringBundle> printBundle;
bundleSvc->CreateBundle("chrome://global/locale/gnomeprintdialog.properties", getter_AddRefs(printBundle));
nsXPIDLString intlString;
printBundle->GetStringFromName(NS_LITERAL_STRING("headerFooterCustom").get(), getter_Copies(intlString));
GtkWidget* prompt_dialog = gtk_dialog_new_with_buttons(NS_ConvertUTF16toUTF8(intlString).get(), NULL,
GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
printBundle->GetStringFromName(NS_LITERAL_STRING("customHeaderFooterPrompt").get(), getter_Copies(intlString));
GtkWidget* custom_label = gtk_label_new(NS_ConvertUTF16toUTF8(intlString).get());
GtkWidget* custom_entry = gtk_entry_new();
GtkWidget* question_icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
// To be convenient, prefill the textbox with the existing value, if any, and select it all so they can easily
// both edit it and type in a new one.
const char* current_text = (const char*) g_object_get_data(G_OBJECT(changed_box), "custom-text");
if (current_text) {
gtk_entry_set_text(GTK_ENTRY(custom_entry), current_text);
gtk_editable_select_region(GTK_EDITABLE(custom_entry), 0, -1);
}
GtkWidget* custom_vbox = gtk_vbox_new(TRUE, 2);
gtk_box_pack_start(GTK_BOX(custom_vbox), custom_label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(custom_vbox), custom_entry, FALSE, FALSE, 5); // Make entry 5px underneath label
GtkWidget* custom_hbox = gtk_hbox_new(FALSE, 2);
gtk_box_pack_start(GTK_BOX(custom_hbox), question_icon, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(custom_hbox), custom_vbox, FALSE, FALSE, 10); // Make question icon 10px away from content
gtk_container_set_border_width(GTK_CONTAINER(custom_hbox), 2);
gtk_widget_show_all(custom_hbox);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(prompt_dialog)->vbox), custom_hbox, FALSE, FALSE, 0);
gint diag_response = gtk_dialog_run(GTK_DIALOG(prompt_dialog));
if (diag_response == GTK_RESPONSE_ACCEPT) {
const gchar* response_text = gtk_entry_get_text(GTK_ENTRY(custom_entry));
g_object_set_data_full(G_OBJECT(changed_box), "custom-text", strdup(response_text), (GDestroyNotify) free);
} else {
// XXX I wish there was a way to be smarter than this... but at least we were smarter than before
// where the dropdown stayed on Custom... even after clicking Cancel.
gtk_combo_box_set_active(changed_box, 0);
}
gtk_widget_destroy(prompt_dialog);
}
class nsPrintDialogWidgetGTK {
public:
nsPrintDialogWidgetGTK(nsIPrintSettings *aPrintSettings);
~nsPrintDialogWidgetGTK() { gtk_widget_destroy(dialog); }
NS_ConvertUTF16toUTF8 GetUTF8FromBundle(const char* aKey);
const gint Run();
nsresult ImportSettings(nsIPrintSettings *aNSSettings);
nsresult ExportSettings(nsIPrintSettings *aNSSettings);
private:
GtkWidget* dialog;
GtkWidget* radio_as_laid_out;
GtkWidget* radio_selected_frame;
GtkWidget* radio_separate_frames;
GtkWidget* shrink_to_fit_toggle;
GtkWidget* print_bg_colors_toggle;
GtkWidget* print_bg_images_toggle;
GtkWidget* selection_only_toggle;
GtkWidget* header_dropdown[3]; // {left, center, right}
GtkWidget* footer_dropdown[3];
nsCOMPtr<nsIStringBundle> printBundle;
GtkWidget* ConstructHeaderFooterDropdown(const PRUnichar *currentString);
const char* OptionWidgetToString(GtkWidget *dropdown);
/* Code to copy between GTK and NS print settings structures.
* In the following,
* "Import" means to copy from NS to GTK
* "Export" means to copy from GTK to NS
*/
void ExportFramePrinting(nsIPrintSettings *aNS, GtkPrintSettings *aSettings);
void ExportHeaderFooter(nsIPrintSettings *aNS);
};
nsPrintDialogWidgetGTK::nsPrintDialogWidgetGTK(nsIPrintSettings *aSettings)
{
nsCOMPtr<nsIStringBundleService> bundleSvc = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
bundleSvc->CreateBundle("chrome://global/locale/gnomeprintdialog.properties", getter_AddRefs(printBundle));
dialog = gtk_print_unix_dialog_new(GetUTF8FromBundle("printTitle").get(), NULL);
gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog),
GtkPrintCapabilities(
GTK_PRINT_CAPABILITY_PAGE_SET
| GTK_PRINT_CAPABILITY_COPIES
| GTK_PRINT_CAPABILITY_COLLATE
| GTK_PRINT_CAPABILITY_REVERSE
| GTK_PRINT_CAPABILITY_SCALE
)
);
// The vast majority of magic numbers in this widget construction are padding. e.g. for
// the set_border_width below, 12px matches that of just about every other window.
GtkWidget* custom_options_tab = gtk_vbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(custom_options_tab), 12);
GtkWidget* tab_label = gtk_label_new(GetUTF8FromBundle("optionsTabLabel").get());
PRInt16 frameUIFlag;
aSettings->GetHowToEnableFrameUI(&frameUIFlag);
radio_as_laid_out = gtk_radio_button_new_with_mnemonic(NULL, GetUTF8FromBundle("asLaidOut").get());
if (frameUIFlag == nsIPrintSettings::kFrameEnableNone)
gtk_widget_set_sensitive(radio_as_laid_out, FALSE);
radio_selected_frame = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_as_laid_out),
GetUTF8FromBundle("selectedFrame").get());
if (frameUIFlag == nsIPrintSettings::kFrameEnableNone ||
frameUIFlag == nsIPrintSettings::kFrameEnableAsIsAndEach)
gtk_widget_set_sensitive(radio_selected_frame, FALSE);
radio_separate_frames = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_as_laid_out),
GetUTF8FromBundle("separateFrames").get());
if (frameUIFlag == nsIPrintSettings::kFrameEnableNone)
gtk_widget_set_sensitive(radio_separate_frames, FALSE);
// "Print Frames" options label, bold and center-aligned
GtkWidget* print_frames_label = gtk_label_new(NULL);
char* pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("printFramesTitle").get());
gtk_label_set_markup(GTK_LABEL(print_frames_label), pangoMarkup);
g_free(pangoMarkup);
gtk_misc_set_alignment(GTK_MISC(print_frames_label), 0, 0);
// Align the radio buttons slightly so they appear to fall under the aforementioned label as per the GNOME HIG
GtkWidget* frames_radio_container = gtk_alignment_new(0, 0, 0, 0);
gtk_alignment_set_padding(GTK_ALIGNMENT(frames_radio_container), 8, 0, 12, 0);
// Radio buttons for the print frames options
GtkWidget* frames_radio_list = gtk_vbox_new(TRUE, 2);
gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_as_laid_out, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_selected_frame, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_separate_frames, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(frames_radio_container), frames_radio_list);
// Check buttons for shrink-to-fit and print selection
GtkWidget* check_buttons_container = gtk_vbox_new(TRUE, 2);
shrink_to_fit_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("shrinkToFit").get());
selection_only_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("selectionOnly").get());
PRBool canSelectText;
aSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &canSelectText);
if (!canSelectText)
gtk_widget_set_sensitive(selection_only_toggle, FALSE);
gtk_box_pack_start(GTK_BOX(check_buttons_container), shrink_to_fit_toggle, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(check_buttons_container), selection_only_toggle, FALSE, FALSE, 0);
// Check buttons for printing background
GtkWidget* appearance_buttons_container = gtk_vbox_new(TRUE, 2);
print_bg_colors_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("printBGColors").get());
print_bg_images_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("printBGImages").get());
gtk_box_pack_start(GTK_BOX(appearance_buttons_container), print_bg_colors_toggle, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(appearance_buttons_container), print_bg_images_toggle, FALSE, FALSE, 0);
// "Appearance" options label, bold and center-aligned
GtkWidget* appearance_label = gtk_label_new(NULL);
pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("printBGOptions").get());
gtk_label_set_markup(GTK_LABEL(appearance_label), pangoMarkup);
g_free(pangoMarkup);
gtk_misc_set_alignment(GTK_MISC(appearance_label), 0, 0);
GtkWidget* appearance_container = gtk_alignment_new(0, 0, 0, 0);
gtk_alignment_set_padding(GTK_ALIGNMENT(appearance_container), 8, 0, 12, 0);
gtk_container_add(GTK_CONTAINER(appearance_container), appearance_buttons_container);
GtkWidget* appearance_vertical_squasher = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(appearance_vertical_squasher), appearance_label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(appearance_vertical_squasher), appearance_container, FALSE, FALSE, 0);
// "Header & Footer" options label, bold and center-aligned
GtkWidget* header_footer_label = gtk_label_new(NULL);
pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("headerFooter").get());
gtk_label_set_markup(GTK_LABEL(header_footer_label), pangoMarkup);
g_free(pangoMarkup);
gtk_misc_set_alignment(GTK_MISC(header_footer_label), 0, 0);
GtkWidget* header_footer_container = gtk_alignment_new(0, 0, 0, 0);
gtk_alignment_set_padding(GTK_ALIGNMENT(header_footer_container), 8, 0, 12, 0);
// --- Table for making the header and footer options ---
GtkWidget* header_footer_table = gtk_table_new(3, 3, FALSE); // 3x3 table
nsXPIDLString header_footer_str[3];
aSettings->GetHeaderStrLeft(getter_Copies(header_footer_str[0]));
aSettings->GetHeaderStrCenter(getter_Copies(header_footer_str[1]));
aSettings->GetHeaderStrRight(getter_Copies(header_footer_str[2]));
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(header_dropdown); i++) {
header_dropdown[i] = ConstructHeaderFooterDropdown(header_footer_str[i].get());
// Those 4 magic numbers in the middle provide the position in the table.
// The last two numbers mean 2 px padding on every side.
gtk_table_attach(GTK_TABLE(header_footer_table), header_dropdown[i], i, (i + 1),
0, 1, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
}
const char labelKeys[][7] = {"left", "center", "right"};
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(labelKeys); i++) {
gtk_table_attach(GTK_TABLE(header_footer_table),
gtk_label_new(GetUTF8FromBundle(labelKeys[i]).get()),
i, (i + 1), 1, 2, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
}
aSettings->GetFooterStrLeft(getter_Copies(header_footer_str[0]));
aSettings->GetFooterStrCenter(getter_Copies(header_footer_str[1]));
aSettings->GetFooterStrRight(getter_Copies(header_footer_str[2]));
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(footer_dropdown); i++) {
footer_dropdown[i] = ConstructHeaderFooterDropdown(header_footer_str[i].get());
gtk_table_attach(GTK_TABLE(header_footer_table), footer_dropdown[i], i, (i + 1),
2, 3, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
}
// ---
gtk_container_add(GTK_CONTAINER(header_footer_container), header_footer_table);
GtkWidget* header_footer_vertical_squasher = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(header_footer_vertical_squasher), header_footer_label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(header_footer_vertical_squasher), header_footer_container, FALSE, FALSE, 0);
// Construction of everything
gtk_box_pack_start(GTK_BOX(custom_options_tab), print_frames_label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(custom_options_tab), frames_radio_container, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(custom_options_tab), check_buttons_container, FALSE, FALSE, 10); // 10px padding
gtk_box_pack_start(GTK_BOX(custom_options_tab), appearance_vertical_squasher, FALSE, FALSE, 10);
gtk_box_pack_start(GTK_BOX(custom_options_tab), header_footer_vertical_squasher, FALSE, FALSE, 0);
gtk_print_unix_dialog_add_custom_tab(GTK_PRINT_UNIX_DIALOG(dialog), custom_options_tab, tab_label);
gtk_widget_show_all(custom_options_tab);
}
NS_ConvertUTF16toUTF8
nsPrintDialogWidgetGTK::GetUTF8FromBundle(const char *aKey)
{
nsXPIDLString intlString;
printBundle->GetStringFromName(NS_ConvertUTF8toUTF16(aKey).get(), getter_Copies(intlString));
return NS_ConvertUTF16toUTF8(intlString); // Return the actual object so we don't lose reference
}
const char*
nsPrintDialogWidgetGTK::OptionWidgetToString(GtkWidget *dropdown)
{
gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(dropdown));
NS_ASSERTION(index <= CUSTOM_VALUE_INDEX, "Index of dropdown is higher than expected!");
if (index == CUSTOM_VALUE_INDEX)
return (const char*) g_object_get_data(G_OBJECT(dropdown), "custom-text");
else
return header_footer_tags[index];
}
const gint
nsPrintDialogWidgetGTK::Run()
{
const gint response = RunDialog(GTK_DIALOG(dialog));
gtk_widget_hide(dialog);
return response;
}
void
nsPrintDialogWidgetGTK::ExportFramePrinting(nsIPrintSettings *aNS, GtkPrintSettings *aSettings)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_as_laid_out)))
aNS->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_selected_frame)))
aNS->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_separate_frames)))
aNS->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
else
aNS->SetPrintFrameType(nsIPrintSettings::kNoFrames);
}
void
nsPrintDialogWidgetGTK::ExportHeaderFooter(nsIPrintSettings *aNS)
{
const char* header_footer_str;
header_footer_str = OptionWidgetToString(header_dropdown[0]);
aNS->SetHeaderStrLeft(NS_ConvertUTF8toUTF16(header_footer_str).get());
header_footer_str = OptionWidgetToString(header_dropdown[1]);
aNS->SetHeaderStrCenter(NS_ConvertUTF8toUTF16(header_footer_str).get());
header_footer_str = OptionWidgetToString(header_dropdown[2]);
aNS->SetHeaderStrRight(NS_ConvertUTF8toUTF16(header_footer_str).get());
header_footer_str = OptionWidgetToString(footer_dropdown[0]);
aNS->SetFooterStrLeft(NS_ConvertUTF8toUTF16(header_footer_str).get());
header_footer_str = OptionWidgetToString(footer_dropdown[1]);
aNS->SetFooterStrCenter(NS_ConvertUTF8toUTF16(header_footer_str).get());
header_footer_str = OptionWidgetToString(footer_dropdown[2]);
aNS->SetFooterStrRight(NS_ConvertUTF8toUTF16(header_footer_str).get());
}
nsresult
nsPrintDialogWidgetGTK::ImportSettings(nsIPrintSettings *aNSSettings)
{
NS_PRECONDITION(aNSSettings, "aSettings must not be null");
NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
if (!aNSSettingsGTK)
return NS_ERROR_FAILURE;
GtkPrintSettings* settings = aNSSettingsGTK->GetGtkPrintSettings();
GtkPageSetup* setup = aNSSettingsGTK->GetGtkPageSetup();
PRBool geckoBool;
aNSSettings->GetShrinkToFit(&geckoBool);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle), geckoBool);
aNSSettings->GetPrintBGColors(&geckoBool);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_bg_colors_toggle), geckoBool);
aNSSettings->GetPrintBGImages(&geckoBool);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_bg_images_toggle), geckoBool);
gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(dialog), settings);
gtk_print_unix_dialog_set_page_setup(GTK_PRINT_UNIX_DIALOG(dialog), setup);
return NS_OK;
}
nsresult
nsPrintDialogWidgetGTK::ExportSettings(nsIPrintSettings *aNSSettings)
{
NS_PRECONDITION(aNSSettings, "aSettings must not be null");
NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
GtkPrintSettings* settings = gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog));
GtkPageSetup* setup = gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog));
GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dialog));
if (settings && setup && printer) {
ExportFramePrinting(aNSSettings, settings);
ExportHeaderFooter(aNSSettings);
aNSSettings->SetOutputFormat(nsIPrintSettings::kOutputFormatNative);
// Print-to-file is true by default. This must be turned off or else printing won't occur!
// (We manually copy the spool file when this flag is set, because we love our embedders)
// Even if it is print-to-file in GTK's case, GTK does The Right Thing when we send the job.
aNSSettings->SetPrintToFile(PR_FALSE);
aNSSettings->SetShrinkToFit(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle)));
aNSSettings->SetPrintBGColors(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(print_bg_colors_toggle)));
aNSSettings->SetPrintBGImages(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(print_bg_images_toggle)));
// Try to save native settings in the session object
nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
if (aNSSettingsGTK) {
aNSSettingsGTK->SetGtkPrintSettings(settings);
aNSSettingsGTK->SetGtkPageSetup(setup);
aNSSettingsGTK->SetGtkPrinter(printer);
aNSSettingsGTK->SetForcePrintSelectionOnly(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(selection_only_toggle)));
}
}
if (settings)
g_object_unref(settings);
return NS_OK;
}
GtkWidget*
nsPrintDialogWidgetGTK::ConstructHeaderFooterDropdown(const PRUnichar *currentString)
{
GtkWidget* dropdown = gtk_combo_box_new_text();
const char hf_options[][22] = {"headerFooterBlank", "headerFooterTitle",
"headerFooterURL", "headerFooterDate",
"headerFooterPage", "headerFooterPageTotal",
"headerFooterCustom"};
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(hf_options); i++) {
gtk_combo_box_append_text(GTK_COMBO_BOX(dropdown), GetUTF8FromBundle(hf_options[i]).get());
}
PRPackedBool shouldBeCustom = PR_TRUE;
NS_ConvertUTF16toUTF8 currentStringUTF8(currentString);
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(header_footer_tags); i++) {
if (!strcmp(currentStringUTF8.get(), header_footer_tags[i])) {
gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), i);
shouldBeCustom = PR_FALSE;
break;
}
}
if (shouldBeCustom) {
gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), CUSTOM_VALUE_INDEX);
char* custom_string = strdup(currentStringUTF8.get());
g_object_set_data_full(G_OBJECT(dropdown), "custom-text", custom_string, (GDestroyNotify) free);
}
g_signal_connect(dropdown, "changed", (GCallback) ShowCustomDialog, NULL);
return dropdown;
}
NS_IMPL_ISUPPORTS1(nsPrintDialogServiceGTK, nsIPrintDialogService)
nsPrintDialogServiceGTK::nsPrintDialogServiceGTK()
{
}
nsPrintDialogServiceGTK::~nsPrintDialogServiceGTK()
{
}
NS_IMETHODIMP
nsPrintDialogServiceGTK::Init()
{
return NS_OK;
}
NS_IMETHODIMP
nsPrintDialogServiceGTK::Show(nsIPrintSettings *aSettings)
{
NS_PRECONDITION(aSettings, "aSettings must not be null");
nsPrintDialogWidgetGTK printDialog(aSettings);
nsresult rv = printDialog.ImportSettings(aSettings);
NS_ENSURE_SUCCESS(rv, rv);
const gint response = printDialog.Run();
// Handle the result
switch (response) {
case GTK_RESPONSE_OK: // Proceed
rv = printDialog.ExportSettings(aSettings);
break;
case GTK_RESPONSE_CANCEL:
case GTK_RESPONSE_CLOSE:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_NONE:
rv = NS_ERROR_ABORT;
break;
case GTK_RESPONSE_APPLY: // Print preview
default:
NS_WARNING("Unexpected response");
rv = NS_ERROR_ABORT;
}
return rv;
}
NS_IMETHODIMP
nsPrintDialogServiceGTK::ShowPageSetup(nsIPrintSettings *aNSSettings)
{
NS_PRECONDITION(aNSSettings, "aSettings must not be null");
NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
if (!aNSSettingsGTK)
return NS_ERROR_FAILURE;
// We need to init the prefs here because aNSSettings in its current form is a dummy in both uses of the word
nsCOMPtr<nsIPrintSettingsService> psService = do_GetService("@mozilla.org/gfx/printsettings-service;1");
if (psService) {
nsXPIDLString printName;
aNSSettings->GetPrinterName(getter_Copies(printName));
if (!printName) {
psService->GetDefaultPrinterName(getter_Copies(printName));
aNSSettings->SetPrinterName(printName.get());
}
psService->InitPrintSettingsFromPrefs(aNSSettings, PR_TRUE, nsIPrintSettings::kInitSaveAll);
}
GtkPrintSettings* gtkSettings = aNSSettingsGTK->GetGtkPrintSettings();
GtkPageSetup* oldPageSetup = aNSSettingsGTK->GetGtkPageSetup();
GtkPageSetup* newPageSetup = gtk_print_run_page_setup_dialog(NULL, oldPageSetup, gtkSettings);
aNSSettingsGTK->SetGtkPageSetup(newPageSetup);
// Now newPageSetup has a refcount of 2 (SetGtkPageSetup will addref), put it to 1 so if
// this gets replaced we don't leak.
g_object_unref(newPageSetup);
if (psService)
psService->SavePrintSettingsToPrefs(aNSSettings, PR_TRUE, nsIPrintSettings::kInitSaveAll);
return NS_OK;
}

View File

@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -13,11 +12,11 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
* The Original Code is the Mozilla GTK2 print dialog interface.
*
* The Initial Developer of the Original Code is
* Kenneth Herron <kherron@fastmail.us>.
* Portions created by the Initial Developer are Copyright (C) 2004
* Kenneth Herron <kherron@fmailbox.com>
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
@ -36,35 +35,24 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPrintJobFactoryGTK_h__
#define nsPrintJobFactoryGTK_h__
#ifndef nsPrintDialog_h__
#define nsPrintDialog_h__
class nsIPrintJobGTK;
class nsDeviceContextSpecGTK;
#include "nsIPrintDialogService.h"
/* Factory class for the print job subsystem. This class determines
* which print job class should handle a print job, and constructs
* an object of the appropriate class.
*/
class nsIPrintSettings;
class nsPrintJobFactoryGTK
class nsPrintDialogServiceGTK : public nsIPrintDialogService
{
public:
/**
* Construct a print job object for the given device context spec.
* On success, the print job object is owned by the caller and should
* be destroyed when no longer needed.
*
* @param aSpec An nsIDeviceContextSpecGTK object for the print
* job in question.
* @param aPrintJob If NS_OK is returned, this will be filled in with
* a pointer to a print job object.
* @return NS_OK or a suitable error value.
*/
static nsresult CreatePrintJob(nsDeviceContextSpecGTK *aSpec,
nsIPrintJobGTK* &aPrintJob);
nsPrintDialogServiceGTK();
virtual ~nsPrintDialogServiceGTK();
NS_DECL_ISUPPORTS
NS_IMETHODIMP Init();
NS_IMETHODIMP Show(nsIPrintSettings *aSettings);
NS_IMETHODIMP ShowPageSetup(nsIPrintSettings *aSettings);
};
#endif /* nsPrintJobFactoryGTK_h__ */
#endif

View File

@ -1,93 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Kenneth Herron <kherron@fastmail.us>.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDebug.h"
#include "nsPrintJobFactoryGTK.h"
#include "nsIDeviceContextSpec.h"
#include "nsDeviceContextSpecG.h"
#include "nsPrintJobGTK.h"
#include "nsPSPrinters.h"
/**
* Construct a print job object for the given device context spec.
*
* @param aSpec An nsDeviceContextSpecGTK object for the print
* job in question.
* @param aPrintJob A pointer to a print job object which will
* handle the print job.
* @return NS_OK if all is well, or a suitable error value.
*/
nsresult
nsPrintJobFactoryGTK::CreatePrintJob(nsDeviceContextSpecGTK *aSpec,
nsIPrintJobGTK* &aPrintJob)
{
NS_PRECONDITION(nsnull != aSpec, "aSpec is NULL");
nsIPrintJobGTK *newPJ;
PRBool setting;
aSpec->GetIsPrintPreview(setting);
if (setting)
newPJ = new nsPrintJobPreviewGTK();
else {
aSpec->GetToPrinter(setting);
if (!setting)
newPJ = new nsPrintJobFileGTK();
else
{
const char *printerName;
aSpec->GetPrinterName(&printerName);
if (nsPSPrinterList::kTypeCUPS == nsPSPrinterList::GetPrinterType(
nsDependentCString(printerName)))
newPJ = new nsPrintJobCUPS();
else
newPJ = new nsPrintJobPipeGTK();
}
}
if (!newPJ)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = newPJ->Init(aSpec);
if (NS_FAILED(rv))
delete newPJ;
else
aPrintJob = newPJ;
return rv;
}

View File

@ -1,481 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Ken Herron <kherron@fastmail.us>.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
#include "nsIDeviceContext.h" // NS_ERROR_GFX_*
#include "nsIDeviceContextSpec.h"
#include "nsDeviceContextSpecG.h"
#include "nsPrintJobGTK.h"
#include "nsPSPrinters.h"
#include "nsReadableUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFileStreams.h"
#include "prenv.h"
#include "prinit.h"
#include "prlock.h"
#include "prprf.h"
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
/* Routines to set environment variables. These are defined toward
* the end of this file.
*/
static PRStatus EnvLock();
static PRStatus EnvSetPrinter(nsCString&);
static void EnvClear();
/* Interface class. It implements a spoolfile getter and destructor
* so that none of the subclasses have to.
*/
nsIPrintJobGTK::~nsIPrintJobGTK()
{
if (mSpoolFile)
mSpoolFile->Remove(PR_FALSE);
}
nsresult
nsIPrintJobGTK::GetSpoolFile(nsILocalFile **aFile)
{
if (!mSpoolFile)
return NS_ERROR_NOT_INITIALIZED;
*aFile = mSpoolFile;
NS_ADDREF(*aFile);
return NS_OK;
}
/**** nsPrintJobPreviewGTK - Stub class for print preview ****/
/* nsDeviceContextSpecGTK needs a spool file even for print preview, so this
* class includes code to create one. Some of the other print job classes
* inherit from this one to reuse the spoolfile initializer.
*/
nsresult
nsPrintJobPreviewGTK::InitSpoolFile(PRUint32 aPermissions)
{
nsCOMPtr<nsIFile> spoolFile;
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
getter_AddRefs(spoolFile));
NS_ENSURE_SUCCESS(rv, NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE);
spoolFile->AppendNative(NS_LITERAL_CSTRING("tmp.prn"));
rv = spoolFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, aPermissions);
if (NS_FAILED(rv))
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
mSpoolFile = do_QueryInterface(spoolFile, &rv);
if (NS_FAILED(rv))
spoolFile->Remove(PR_FALSE);
return rv;
}
nsresult
nsPrintJobPreviewGTK::Init(nsDeviceContextSpecGTK *aSpec)
{
#ifdef DEBUG
PRBool isPreview;
aSpec->GetIsPrintPreview(isPreview);
NS_PRECONDITION(isPreview, "This print job is to a printer");
#endif
return InitSpoolFile(0600);
}
/**** nsPrintJobFileGTK - Print-to-file support ****/
/**
* Initialize the print-to-file object from the printing spec.
* See nsPrintJobGTK.h for details.
*/
nsresult
nsPrintJobFileGTK::Init(nsDeviceContextSpecGTK *aSpec)
{
NS_PRECONDITION(aSpec, "aSpec must not be NULL");
#ifdef DEBUG
PRBool toPrinter;
aSpec->GetToPrinter(toPrinter);
NS_PRECONDITION(!toPrinter, "This print job is to a printer");
#endif
// The final output file will inherit the permissions of the temporary.
nsresult rv = InitSpoolFile(0666);
if (NS_SUCCEEDED(rv)) {
const char *path;
aSpec->GetPath(&path);
rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_FALSE,
getter_AddRefs(mDestFile));
}
return rv;
}
nsresult
nsPrintJobFileGTK::Submit()
{
// Move the spool file to the destination
nsAutoString destLeafName;
nsresult rv = mDestFile->GetLeafName(destLeafName);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIFile> mDestDir;
rv = mDestFile->GetParent(getter_AddRefs(mDestDir));
if (NS_SUCCEEDED(rv)) {
rv = mSpoolFile->MoveTo(mDestDir, destLeafName);
}
}
return rv;
}
/**** Print-to-Pipe for unix and unix-like systems ****/
/* This launches a command using popen(); the print job is then written
* to the pipe.
*/
/**
* Initialize a print-to-pipe object.
* See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
*/
nsresult
nsPrintJobPipeGTK::Init(nsDeviceContextSpecGTK *aSpec)
{
NS_PRECONDITION(aSpec, "argument must not be NULL");
#ifdef DEBUG
PRBool toPrinter;
aSpec->GetToPrinter(toPrinter);
NS_PRECONDITION(toPrinter, "Wrong class for this print job");
#endif
/* Spool file */
nsresult rv = InitSpoolFile(0600);
if (NS_FAILED(rv))
return rv;
/* Print command */
const char *command;
aSpec->GetCommand(&command);
mCommand = command;
/* Printer name */
const char *printerName;
aSpec->GetPrinterName(&printerName);
if (printerName) {
const char *slash = strchr(printerName, '/');
if (slash)
printerName = slash + 1;
if (0 != strcmp(printerName, "default"))
mPrinterName = printerName;
}
return NS_OK;
}
/* Helper for nsPrintJobPipeGTK::Submit(). Start the print command. */
static nsresult
popenPrintCommand(FILE **aPipe, nsCString &aPrinter, nsCString &aCommand)
{
// Set up the environment for the print command
if (PR_SUCCESS != EnvLock())
return NS_ERROR_OUT_OF_MEMORY; // Couldn't allocate the object?
if (!aPrinter.IsEmpty())
EnvSetPrinter(aPrinter);
// Start the print command
*aPipe = popen(aCommand.get(), "w");
EnvClear();
return (*aPipe) ? NS_OK : NS_ERROR_GFX_PRINTER_CMD_FAILURE;
}
/* Helper for nsPrintJobPipeGTK::Submit(). Copy data from a temporary file
* to the command pipe.
*/
static nsresult
CopySpoolToCommand(nsIFileInputStream *aSource, FILE *aDest)
{
nsresult rv;
PRUint32 count;
do {
char buf[256];
count = 0;
rv = aSource->Read(buf, sizeof buf, &count);
fwrite(buf, 1, count, aDest);
} while (NS_SUCCEEDED(rv) && count);
return rv;
}
/**
* Launch the print command using popen(), then copy the print job data
* to the pipe. See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
*/
nsresult
nsPrintJobPipeGTK::Submit()
{
NS_PRECONDITION(mSpoolFile, "No spool file");
// Open the spool file
nsCOMPtr<nsIFileInputStream> spoolStream =
do_CreateInstance("@mozilla.org/network/file-input-stream;1");
if (!spoolStream)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = spoolStream->Init(mSpoolFile, -1, -1,
nsIFileInputStream::DELETE_ON_CLOSE|nsIFileInputStream::CLOSE_ON_EOF);
NS_ENSURE_SUCCESS(rv, rv);
// Start the print command
FILE *destPipe = NULL;
rv = popenPrintCommand(&destPipe, mPrinterName, mCommand);
if (NS_SUCCEEDED(rv)) {
rv = CopySpoolToCommand(spoolStream, destPipe);
int presult = pclose(destPipe);
if (NS_SUCCEEDED(rv)) {
if (!WIFEXITED(presult) || (EXIT_SUCCESS != WEXITSTATUS(presult)))
rv = NS_ERROR_GFX_PRINTER_CMD_FAILURE;
}
}
spoolStream->Close();
return rv;
}
/**** Print via CUPS ****/
/* nsPrintJobCUPS doesn't inherit its spoolfile code from the preview
* class. CupsPrintFile() needs the filename as an 8-bit string, but an
* nsILocalFile doesn't portably expose the filename in this format.
* So it's necessary to construct the spoolfile name outside of the
* nsILocalFile object, and retain it as a string for use when calling
* CupsPrintFile().
*/
/**
* Initialize a print-to-CUPS object.
* See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
*/
nsresult
nsPrintJobCUPS::Init(nsDeviceContextSpecGTK *aSpec)
{
NS_PRECONDITION(aSpec, "argument must not be NULL");
#ifdef DEBUG
PRBool toPrinter;
aSpec->GetToPrinter(toPrinter);
NS_PRECONDITION(toPrinter, "Wrong class for this print job");
#endif
NS_ENSURE_TRUE(mCups.Init(), NS_ERROR_NOT_INITIALIZED);
/* Printer name */
const char *printerName = nsnull;
aSpec->GetPrinterName(&printerName);
NS_ENSURE_TRUE(printerName, NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND);
const char *slash = strchr(printerName, '/');
mPrinterName = slash ? slash + 1 : printerName;
mJobTitle.SetIsVoid(PR_TRUE);
/* Spool file */
int fd;
char buf[FILENAME_MAX];
fd = (mCups.mCupsTempFd)(buf, sizeof buf);
// The CUPS manual doesn't describe what cupsTempFd() returns to
// indicate failure. -1 is a likely value.
NS_ENSURE_TRUE(fd > 0, NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE);
close(fd);
nsresult rv = NS_NewNativeLocalFile(nsDependentCString(buf), PR_FALSE,
getter_AddRefs(mSpoolFile));
if (NS_FAILED(rv)) {
unlink(buf);
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
}
mSpoolName = buf;
return NS_OK;
}
nsresult
nsPrintJobCUPS::SetNumCopies(int aNumCopies)
{
mNumCopies.Truncate();
if (aNumCopies > 1)
mNumCopies.AppendInt(aNumCopies);
return NS_OK;
}
/* According to the cups.development forum, only plain ASCII may be
* reliably used for CUPS print job titles. See
* <http://www.cups.org/newsgroups.php?s523+gcups.development+v530+T0>.
*/
void
nsPrintJobCUPS::SetJobTitle(const PRUnichar *aTitle)
{
if (aTitle) {
LossyCopyUTF16toASCII(aTitle, mJobTitle);
}
}
nsresult
nsPrintJobCUPS::Submit()
{
NS_ENSURE_TRUE(mCups.IsInitialized(), NS_ERROR_NOT_INITIALIZED);
NS_PRECONDITION(!mSpoolName.IsEmpty(), "No spool file");
nsCStringArray printer(3);
printer.ParseString(mPrinterName.get(),"/");
cups_dest_t *dests, *dest;
int num_dests = (mCups.mCupsGetDests)(&dests);
if (printer.Count() == 1) {
dest = (mCups.mCupsGetDest)(printer.CStringAt(0)->get(), NULL, num_dests, dests);
} else {
dest = (mCups.mCupsGetDest)(printer.CStringAt(0)->get(),
printer.CStringAt(1)->get(), num_dests, dests);
}
// Setting result just to get rid of compilation warning
int result=0;
if (dest != NULL) {
if (!mNumCopies.IsEmpty())
dest->num_options = (mCups.mCupsAddOption)("copies",
mNumCopies.get(),
dest->num_options,
&dest->options);
const char *title = mJobTitle.IsVoid() ?
"Untitled Document" : mJobTitle.get();
result = (mCups.mCupsPrintFile)(printer.CStringAt(0)->get(),
mSpoolName.get(), title,
dest->num_options, dest->options);
}
(mCups.mCupsFreeDests)(num_dests, dests);
// cupsPrintFile() result codes below 0x0300 indicate success.
// Individual success codes are defined in the cups headers, but
// we're not including those.
if (dest == NULL)
return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND;
else
return (result < 0x0300) ? NS_OK : NS_ERROR_GFX_PRINTER_CMD_FAILURE;
}
/* Routines to set the MOZ_PRINTER_NAME environment variable and to
* single-thread print jobs while the variable is set.
*/
static PRLock *EnvLockObj;
static PRCallOnceType EnvLockOnce;
/* EnvLock callback function */
static PRStatus
EnvLockInit()
{
EnvLockObj = PR_NewLock();
return EnvLockObj ? PR_SUCCESS : PR_FAILURE;
}
/**
* Get the lock for setting printing-related environment variables and
* running print commands.
* @return PR_SUCCESS on success
* PR_FAILURE if the lock object could not be initialized.
*
*/
static PRStatus
EnvLock()
{
if (PR_FAILURE == PR_CallOnce(&EnvLockOnce, EnvLockInit))
return PR_FAILURE;
PR_Lock(EnvLockObj);
return PR_SUCCESS;
}
static char *EnvPrinterString;
static const char EnvPrinterName[] = { "MOZ_PRINTER_NAME" };
/**
* Set MOZ_PRINTER_NAME to the specified string.
* @param aPrinter The value for MOZ_PRINTER_NAME. May be an empty string.
* @return PR_SUCCESS on success.
* PR_FAILURE if memory could not be allocated.
*/
static PRStatus
EnvSetPrinter(nsCString& aPrinter)
{
/* Construct the new environment string */
char *newVar = PR_smprintf("%s=%s", EnvPrinterName, aPrinter.get());
if (!newVar)
return PR_FAILURE;
/* Add it to the environment and dispose of any old string */
PR_SetEnv(newVar);
if (EnvPrinterString)
PR_smprintf_free(EnvPrinterString);
EnvPrinterString = newVar;
return PR_SUCCESS;
}
/**
* Clear the printer environment variable and release the environment lock.
*/
static void
EnvClear()
{
if (EnvPrinterString) {
/* On some systems, setenv("FOO") will remove FOO
* from the environment.
*/
PR_SetEnv(EnvPrinterName);
if (!PR_GetEnv(EnvPrinterName)) {
/* It must have worked */
PR_smprintf_free(EnvPrinterString);
EnvPrinterString = nsnull;
}
}
PR_Unlock(EnvLockObj);
}

View File

@ -1,108 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Ken Herron <kherron@fastmail.us>.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPrintJobGTK_h__
#define nsPrintJobGTK_h__
#include "nsCUPSShim.h"
#include "nsDebug.h"
#include "nsIDeviceContext.h" // for NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED
#include "nsILocalFile.h"
#include "nsIPrintJobGTK.h"
#include "nsString.h"
#include "nsDeviceContextSpecG.h"
/* Print job class for print preview operations. */
class nsPrintJobPreviewGTK : public nsIPrintJobGTK {
public:
/* see nsIPrintJobGTK.h. Print preview doesn't actually
* implement printing.
*/
virtual nsresult Submit()
{ return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED; }
protected:
virtual nsresult Init(nsDeviceContextSpecGTK *);
nsresult InitSpoolFile(PRUint32 aPermissions);
};
/* Print job class for print-to-file. */
class nsPrintJobFileGTK : public nsPrintJobPreviewGTK {
public:
virtual nsresult Submit();
protected:
virtual nsresult Init(nsDeviceContextSpecGTK *);
nsCOMPtr<nsILocalFile> mDestFile;
};
/* This is the class for printing to a pipe. */
class nsPrintJobPipeGTK : public nsPrintJobPreviewGTK {
public:
virtual nsresult Submit();
protected:
virtual nsresult Init(nsDeviceContextSpecGTK *);
private:
nsCString mCommand;
nsCString mPrinterName;
};
/* This class submits print jobs through CUPS. */
class nsPrintJobCUPS : public nsIPrintJobGTK {
public:
virtual nsresult Submit();
virtual nsresult SetNumCopies(int aNumCopies);
virtual void SetJobTitle(const PRUnichar *aTitle);
protected:
virtual nsresult Init(nsDeviceContextSpecGTK *);
private:
nsCUPSShim mCups;
nsCString mPrinterName;
nsCString mNumCopies;
nsCString mJobTitle; // IsVoid() if no title
nsCString mSpoolName;
};
#endif /* nsPrintJobPS_h__ */

View File

@ -35,7 +35,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsPrintOptionsGTK.h"
#include "nsPrintSettingsGTK.h"
/** ---------------------------------------------------
@ -55,3 +55,16 @@ nsPrintOptionsGTK::~nsPrintOptionsGTK()
{
}
/* nsIPrintSettings CreatePrintSettings (); */
nsresult nsPrintOptionsGTK::_CreatePrintSettings(nsIPrintSettings **_retval)
{
*_retval = nsnull;
nsPrintSettingsGTK* printSettings = new nsPrintSettingsGTK(); // does not initially ref count
NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*_retval = printSettings); // ref count
return NS_OK;
}

View File

@ -52,6 +52,7 @@ public:
nsPrintOptionsGTK();
virtual ~nsPrintOptionsGTK();
virtual nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
};

View File

@ -0,0 +1,732 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Ventnor <m.ventnor@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsPrintSettingsGTK.h"
#include "nsILocalFile.h"
#include "nsNetUtil.h"
#include <stdlib.h>
static
gboolean ref_printer(GtkPrinter *aPrinter, gpointer aData)
{
((nsPrintSettingsGTK*) aData)->SetGtkPrinter(aPrinter);
return TRUE;
}
static
gboolean printer_enumerator(GtkPrinter *aPrinter, gpointer aData)
{
if (gtk_printer_is_default(aPrinter))
return ref_printer(aPrinter, aData);
return FALSE; // Keep 'em coming...
}
static
GtkPaperSize* moz_gtk_paper_size_copy_to_new_custom(GtkPaperSize* oldPaperSize)
{
// We make a "custom-ified" copy of the paper size so it can be changed later.
return gtk_paper_size_new_custom(gtk_paper_size_get_name(oldPaperSize),
gtk_paper_size_get_display_name(oldPaperSize),
gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH),
gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH),
GTK_UNIT_INCH);
}
NS_IMPL_ISUPPORTS_INHERITED1(nsPrintSettingsGTK,
nsPrintSettings,
nsPrintSettingsGTK)
/** ---------------------------------------------------
*/
nsPrintSettingsGTK::nsPrintSettingsGTK() :
mPageSetup(NULL),
mPrintSettings(NULL),
mGTKPrinter(NULL)
{
// The aim here is to set up the objects enough that silent printing works well.
// These will be replaced anyway if the print dialog is used.
mPrintSettings = gtk_print_settings_new();
mPageSetup = gtk_page_setup_new();
SetOutputFormat(nsIPrintSettings::kOutputFormatNative);
GtkPaperSize* defaultPaperSize = gtk_paper_size_new(NULL);
mPaperSize = moz_gtk_paper_size_copy_to_new_custom(defaultPaperSize);
gtk_paper_size_free(defaultPaperSize);
SaveNewPageSize();
}
/** ---------------------------------------------------
*/
nsPrintSettingsGTK::~nsPrintSettingsGTK()
{
if (mPageSetup) {
g_object_unref(mPageSetup);
mPageSetup = NULL;
}
if (mPrintSettings) {
g_object_unref(mPrintSettings);
mPrintSettings = NULL;
}
if (mGTKPrinter) {
g_object_unref(mGTKPrinter);
mGTKPrinter = NULL;
}
gtk_paper_size_free(mPaperSize);
}
/** ---------------------------------------------------
*/
nsPrintSettingsGTK::nsPrintSettingsGTK(const nsPrintSettingsGTK& aPS) :
mPageSetup(NULL),
mPrintSettings(NULL),
mGTKPrinter(NULL),
mPrintSelectionOnly(PR_FALSE)
{
*this = aPS;
}
/** ---------------------------------------------------
*/
nsPrintSettingsGTK& nsPrintSettingsGTK::operator=(const nsPrintSettingsGTK& rhs)
{
if (this == &rhs) {
return *this;
}
nsPrintSettings::operator=(rhs);
if (mPageSetup)
g_object_unref(mPageSetup);
mPageSetup = gtk_page_setup_copy(rhs.mPageSetup);
if (mPrintSettings)
g_object_unref(mPrintSettings);
mPrintSettings = gtk_print_settings_copy(rhs.mPrintSettings);
if (mGTKPrinter)
g_object_unref(mGTKPrinter);
mGTKPrinter = (GtkPrinter*) g_object_ref(rhs.mGTKPrinter);
mPrintSelectionOnly = rhs.mPrintSelectionOnly;
return *this;
}
/** -------------------------------------------
*/
nsresult nsPrintSettingsGTK::_Clone(nsIPrintSettings **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
nsPrintSettingsGTK *newSettings = new nsPrintSettingsGTK(*this);
if (!newSettings)
return NS_ERROR_FAILURE;
*_retval = newSettings;
NS_ADDREF(*_retval);
return NS_OK;
}
/** -------------------------------------------
*/
NS_IMETHODIMP
nsPrintSettingsGTK::_Assign(nsIPrintSettings *aPS)
{
nsPrintSettingsGTK *printSettingsGTK = static_cast<nsPrintSettingsGTK*>(aPS);
if (!printSettingsGTK)
return NS_ERROR_UNEXPECTED;
*this = *printSettingsGTK;
return NS_OK;
}
/** ---------------------------------------------------
*/
void
nsPrintSettingsGTK::SetGtkPageSetup(GtkPageSetup *aPageSetup)
{
if (mPageSetup)
g_object_unref(mPageSetup);
mPageSetup = (GtkPageSetup*) g_object_ref(aPageSetup);
// We make a custom copy of the GtkPaperSize so it can be mutable. If a
// GtkPaperSize wasn't made as custom, its properties are immutable.
GtkPaperSize* newPaperSize = gtk_page_setup_get_paper_size(aPageSetup);
if (newPaperSize) { // Yes, this can be null
gtk_paper_size_free(mPaperSize);
mPaperSize = moz_gtk_paper_size_copy_to_new_custom(newPaperSize);
}
// If newPaperSize was not null, we must update our twin too (GtkPrintSettings).
// If newPaperSize was null, we must set this object to use mPaperSize.
SaveNewPageSize();
}
/** ---------------------------------------------------
*/
void
nsPrintSettingsGTK::SetGtkPrintSettings(GtkPrintSettings *aPrintSettings)
{
if (mPrintSettings)
g_object_unref(mPrintSettings);
mPrintSettings = (GtkPrintSettings*) g_object_ref(aPrintSettings);
GtkPaperSize* newPaperSize = gtk_print_settings_get_paper_size(aPrintSettings);
if (newPaperSize) {
gtk_paper_size_free(mPaperSize);
mPaperSize = moz_gtk_paper_size_copy_to_new_custom(newPaperSize);
}
SaveNewPageSize();
}
/** ---------------------------------------------------
*/
void
nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter *aPrinter)
{
if (mGTKPrinter)
g_object_unref(mGTKPrinter);
mGTKPrinter = (GtkPrinter*) g_object_ref(aPrinter);
}
/**
* Reimplementation of nsPrintSettings functions so that we get the values
* from the GTK objects rather than our own variables.
*/
/* attribute long printRange; */
NS_IMETHODIMP nsPrintSettingsGTK::GetPrintRange(PRInt16 *aPrintRange)
{
NS_ENSURE_ARG_POINTER(aPrintRange);
if (mPrintSelectionOnly) {
*aPrintRange = kRangeSelection;
return NS_OK;
}
GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
if (gtkRange == GTK_PRINT_PAGES_RANGES)
*aPrintRange = kRangeSpecifiedPageRange;
else
*aPrintRange = kRangeAllPages;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettingsGTK::SetPrintRange(PRInt16 aPrintRange)
{
if (aPrintRange == kRangeSelection) {
mPrintSelectionOnly = PR_TRUE;
return NS_OK;
}
mPrintSelectionOnly = PR_FALSE;
if (aPrintRange == kRangeSpecifiedPageRange)
gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_RANGES);
else
gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_ALL);
return NS_OK;
}
/* attribute long startPageRange; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetStartPageRange(PRInt32 *aStartPageRange)
{
gint ctRanges;
GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
// Make sure we got a range.
if (ctRanges < 1) {
*aStartPageRange = 1;
} else {
// GTK supports multiple page ranges; gecko only supports 1. So find
// the lowest start page.
PRInt32 start(lstRanges[0].start);
for (gint ii = 1; ii < ctRanges; ii++) {
start = PR_MIN(lstRanges[ii].start, start);
}
*aStartPageRange = start + 1;
}
g_free(lstRanges);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetStartPageRange(PRInt32 aStartPageRange)
{
PRInt32 endRange;
GetEndPageRange(&endRange);
GtkPageRange gtkRange;
gtkRange.start = aStartPageRange - 1;
gtkRange.end = endRange - 1;
gtk_print_settings_set_page_ranges(mPrintSettings, &gtkRange, 1);
return NS_OK;
}
/* attribute long endPageRange; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetEndPageRange(PRInt32 *aEndPageRange)
{
gint ctRanges;
GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
if (ctRanges < 1) {
*aEndPageRange = 1;
} else {
PRInt32 end(lstRanges[0].end);
for (gint ii = 1; ii < ctRanges; ii++) {
end = PR_MAX(lstRanges[ii].end, end);
}
*aEndPageRange = end + 1;
}
g_free(lstRanges);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetEndPageRange(PRInt32 aEndPageRange)
{
PRInt32 startRange;
GetStartPageRange(&startRange);
GtkPageRange gtkRange;
gtkRange.start = startRange - 1;
gtkRange.end = aEndPageRange - 1;
gtk_print_settings_set_page_ranges(mPrintSettings, &gtkRange, 1);
return NS_OK;
}
/* attribute boolean printReversed; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetPrintReversed(PRBool *aPrintReversed)
{
*aPrintReversed = gtk_print_settings_get_reverse(mPrintSettings);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPrintReversed(PRBool aPrintReversed)
{
gtk_print_settings_set_reverse(mPrintSettings, aPrintReversed);
return NS_OK;
}
/* attribute boolean printInColor; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetPrintInColor(PRBool *aPrintInColor)
{
*aPrintInColor = gtk_print_settings_get_use_color(mPrintSettings);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPrintInColor(PRBool aPrintInColor)
{
gtk_print_settings_set_use_color(mPrintSettings, aPrintInColor);
return NS_OK;
}
/* attribute short orientation; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetOrientation(PRInt32 *aOrientation)
{
NS_ENSURE_ARG_POINTER(aOrientation);
GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
switch (gtkOrient) {
case GTK_PAGE_ORIENTATION_LANDSCAPE:
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
*aOrientation = kLandscapeOrientation;
break;
case GTK_PAGE_ORIENTATION_PORTRAIT:
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
default:
*aOrientation = kPortraitOrientation;
}
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetOrientation(PRInt32 aOrientation)
{
GtkPageOrientation gtkOrient;
if (aOrientation == kLandscapeOrientation)
gtkOrient = GTK_PAGE_ORIENTATION_LANDSCAPE;
else
gtkOrient = GTK_PAGE_ORIENTATION_PORTRAIT;
gtk_print_settings_set_orientation(mPrintSettings, gtkOrient);
gtk_page_setup_set_orientation(mPageSetup, gtkOrient);
return NS_OK;
}
/* attribute wstring toFileName; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetToFileName(PRUnichar * *aToFileName)
{
// Get the gtk output filename
const char* gtk_output_uri = gtk_print_settings_get(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI);
if (!gtk_output_uri) {
*aToFileName = ToNewUnicode(mToFileName);
return NS_OK;
}
// Convert to an nsIFile
nsCOMPtr<nsIFile> file;
NS_GetFileFromURLSpec(nsDependentCString(gtk_output_uri), getter_AddRefs(file));
// Extract the path
nsAutoString path;
file->GetPath(path);
*aToFileName = ToNewUnicode(path);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetToFileName(const PRUnichar * aToFileName)
{
if (aToFileName[0] == 0) {
mToFileName.SetLength(0);
gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, NULL);
return NS_OK;
}
nsCOMPtr<nsILocalFile> file;
NS_NewLocalFile(nsDependentString(aToFileName), PR_TRUE, getter_AddRefs(file));
// Convert the nsIFile to a URL
nsCAutoString url;
NS_GetURLSpecFromFile(file, url);
gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, url.get());
mToFileName = aToFileName;
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::GetPrinterName(PRUnichar * *aPrinter)
{
const char* gtkPrintName = gtk_print_settings_get_printer(mPrintSettings);
if (!gtkPrintName) {
if (GTK_IS_PRINTER(mGTKPrinter)) {
gtkPrintName = gtk_printer_get_name(mGTKPrinter);
} else {
*aPrinter = nsnull;
return NS_OK;
}
}
*aPrinter = ToNewUnicode(nsDependentCString(gtkPrintName));
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPrinterName(const PRUnichar * aPrinter)
{
NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter);
if (StringBeginsWith(gtkPrinter, NS_LITERAL_CSTRING("PostScript/"))) {
// Don't bother importing this name
gtkPrinter.AssignLiteral("");
}
if (StringBeginsWith(gtkPrinter, NS_LITERAL_CSTRING("CUPS/"))) {
// Strip off "CUPS/"; GTK might recognize the rest
gtkPrinter.Cut(0, strlen("CUPS/"));
}
if (!gtkPrinter.Equals(gtk_print_settings_get_printer(mPrintSettings))) {
mIsInitedFromPrinter = PR_FALSE;
mIsInitedFromPrefs = PR_FALSE;
gtk_print_settings_set_printer(mPrintSettings, gtkPrinter.get());
}
return NS_OK;
}
/* attribute long numCopies; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetNumCopies(PRInt32 *aNumCopies)
{
NS_ENSURE_ARG_POINTER(aNumCopies);
*aNumCopies = gtk_print_settings_get_n_copies(mPrintSettings);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetNumCopies(PRInt32 aNumCopies)
{
gtk_print_settings_set_n_copies(mPrintSettings, aNumCopies);
return NS_OK;
}
/* attribute double edgeTop; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetEdgeTop(double *aEdgeTop)
{
NS_ENSURE_ARG_POINTER(aEdgeTop);
*aEdgeTop = gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetEdgeTop(double aEdgeTop)
{
gtk_page_setup_set_top_margin(mPageSetup, aEdgeTop, GTK_UNIT_INCH);
return NS_OK;
}
/* attribute double edgeLeft; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetEdgeLeft(double *aEdgeLeft)
{
NS_ENSURE_ARG_POINTER(aEdgeLeft);
*aEdgeLeft = gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetEdgeLeft(double aEdgeLeft)
{
gtk_page_setup_set_left_margin(mPageSetup, aEdgeLeft, GTK_UNIT_INCH);
return NS_OK;
}
/* attribute double edgeBottom; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetEdgeBottom(double *aEdgeBottom)
{
NS_ENSURE_ARG_POINTER(aEdgeBottom);
*aEdgeBottom = gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetEdgeBottom(double aEdgeBottom)
{
gtk_page_setup_set_bottom_margin(mPageSetup, aEdgeBottom, GTK_UNIT_INCH);
return NS_OK;
}
/* attribute double edgeRight; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetEdgeRight(double *aEdgeRight)
{
NS_ENSURE_ARG_POINTER(aEdgeRight);
*aEdgeRight = gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetEdgeRight(double aEdgeRight)
{
gtk_page_setup_set_right_margin(mPageSetup, aEdgeRight, GTK_UNIT_INCH);
return NS_OK;
}
/* attribute double scaling; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetScaling(double *aScaling)
{
*aScaling = gtk_print_settings_get_scale(mPrintSettings) / 100.0;
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetScaling(double aScaling)
{
gtk_print_settings_set_scale(mPrintSettings, aScaling * 100.0);
return NS_OK;
}
/* attribute wstring paperName; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetPaperName(PRUnichar * *aPaperName)
{
NS_ENSURE_ARG_POINTER(aPaperName);
*aPaperName = ToNewUnicode(NS_ConvertUTF8toUTF16(gtk_paper_size_get_name(mPaperSize)));
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPaperName(const PRUnichar * aPaperName)
{
NS_ConvertUTF16toUTF8 gtkPaperName(aPaperName);
// Convert these Gecko names to GTK names
if (gtkPaperName.EqualsIgnoreCase("letter"))
gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LETTER);
else if (gtkPaperName.EqualsIgnoreCase("legal"))
gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LEGAL);
// Try to get the display name from the name so our paper size fits in the Page Setup dialog.
GtkPaperSize* paperSize = gtk_paper_size_new(gtkPaperName.get());
char* displayName = strdup(gtk_paper_size_get_display_name(paperSize));
gtk_paper_size_free(paperSize);
paperSize = gtk_paper_size_new_custom(gtkPaperName.get(), displayName,
gtk_paper_size_get_width(mPaperSize, GTK_UNIT_INCH),
gtk_paper_size_get_height(mPaperSize, GTK_UNIT_INCH),
GTK_UNIT_INCH);
free(displayName);
gtk_paper_size_free(mPaperSize);
mPaperSize = paperSize;
SaveNewPageSize();
return NS_OK;
}
GtkUnit
nsPrintSettingsGTK::GetGTKUnit(PRInt16 aGeckoUnit)
{
if (aGeckoUnit == kPaperSizeMillimeters)
return GTK_UNIT_MM;
else
return GTK_UNIT_INCH;
}
void
nsPrintSettingsGTK::SaveNewPageSize()
{
gtk_print_settings_set_paper_size(mPrintSettings, mPaperSize);
gtk_page_setup_set_paper_size(mPageSetup, mPaperSize);
}
/* attribute double paperWidth; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetPaperWidth(double *aPaperWidth)
{
NS_ENSURE_ARG_POINTER(aPaperWidth);
*aPaperWidth = gtk_paper_size_get_width(mPaperSize, GetGTKUnit(mPaperSizeUnit));
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPaperWidth(double aPaperWidth)
{
gtk_paper_size_set_size(mPaperSize,
aPaperWidth,
gtk_paper_size_get_height(mPaperSize, GetGTKUnit(mPaperSizeUnit)),
GetGTKUnit(mPaperSizeUnit));
SaveNewPageSize();
return NS_OK;
}
/* attribute double paperHeight; */
NS_IMETHODIMP
nsPrintSettingsGTK::GetPaperHeight(double *aPaperHeight)
{
NS_ENSURE_ARG_POINTER(aPaperHeight);
*aPaperHeight = gtk_paper_size_get_height(mPaperSize, GetGTKUnit(mPaperSizeUnit));
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPaperHeight(double aPaperHeight)
{
gtk_paper_size_set_size(mPaperSize,
gtk_paper_size_get_width(mPaperSize, GetGTKUnit(mPaperSizeUnit)),
aPaperHeight,
GetGTKUnit(mPaperSizeUnit));
SaveNewPageSize();
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetPaperSizeUnit(PRInt16 aPaperSizeUnit)
{
// Convert units internally. e.g. they might have set the values while we're still in mm but
// they change to inch just afterwards, expecting that their sizes are in inches.
gtk_paper_size_set_size(mPaperSize,
gtk_paper_size_get_width(mPaperSize, GetGTKUnit(mPaperSizeUnit)),
gtk_paper_size_get_height(mPaperSize, GetGTKUnit(mPaperSizeUnit)),
GetGTKUnit(aPaperSizeUnit));
SaveNewPageSize();
mPaperSizeUnit = aPaperSizeUnit;
return NS_OK;
}
// Get/Set our margins as an nsMargin
NS_IMETHODIMP
nsPrintSettingsGTK::SetEdgeInTwips(nsMargin& aEdge)
{
gtk_page_setup_set_top_margin(mPageSetup, NS_TWIPS_TO_INCHES(aEdge.top), GTK_UNIT_INCH);
gtk_page_setup_set_left_margin(mPageSetup, NS_TWIPS_TO_INCHES(aEdge.left), GTK_UNIT_INCH);
gtk_page_setup_set_bottom_margin(mPageSetup, NS_TWIPS_TO_INCHES(aEdge.bottom), GTK_UNIT_INCH);
gtk_page_setup_set_right_margin(mPageSetup, NS_TWIPS_TO_INCHES(aEdge.right), GTK_UNIT_INCH);
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::GetEdgeInTwips(nsMargin& aEdge)
{
aEdge.SizeTo(NS_INCHES_TO_TWIPS(gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH)),
NS_INCHES_TO_TWIPS(gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH)),
NS_INCHES_TO_TWIPS(gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH)),
NS_INCHES_TO_TWIPS(gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH)));
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::GetEffectivePageSize(double *aWidth, double *aHeight)
{
*aWidth = NS_INCHES_TO_TWIPS(gtk_paper_size_get_width(mPaperSize, GTK_UNIT_INCH));
*aHeight = NS_INCHES_TO_TWIPS(gtk_paper_size_get_height(mPaperSize, GTK_UNIT_INCH));
GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
if (gtkOrient == GTK_PAGE_ORIENTATION_LANDSCAPE ||
gtkOrient == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) {
double temp = *aWidth;
*aWidth = *aHeight;
*aHeight = temp;
}
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsGTK::SetupSilentPrinting()
{
// We have to get a printer here, rather than when the print settings are constructed.
// This is because when we request sync, GTK makes us wait in the *event loop* while waiting
// for the enumeration to finish. We must do this when event loop runs are expected.
gtk_enumerate_printers(printer_enumerator, this, NULL, TRUE);
// XXX If no default printer set, get the first one.
if (!GTK_IS_PRINTER(mGTKPrinter))
gtk_enumerate_printers(ref_printer, this, NULL, TRUE);
return NS_OK;
}

View File

@ -0,0 +1,177 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Ventnor <m.ventnor@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPrintSettingsGTK_h_
#define nsPrintSettingsGTK_h_
#include "nsPrintSettingsImpl.h"
extern "C" {
#include <gtk/gtk.h>
#include <gtk/gtkprinter.h>
#include <gtk/gtkprintjob.h>
}
#define NS_PRINTSETTINGSGTK_IID \
{ 0x758df520, 0xc7c3, 0x11dc, { 0x95, 0xff, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
//*****************************************************************************
//*** nsPrintSettingsGTK
//*****************************************************************************
class nsPrintSettingsGTK : public nsPrintSettings
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PRINTSETTINGSGTK_IID)
nsPrintSettingsGTK();
virtual ~nsPrintSettingsGTK();
// We're overriding these methods because we want to read/write with GTK objects,
// not local variables. This allows a simpler settings implementation between
// Gecko and GTK.
GtkPageSetup* GetGtkPageSetup() { return mPageSetup; };
void SetGtkPageSetup(GtkPageSetup *aPageSetup);
GtkPrintSettings* GetGtkPrintSettings() { return mPrintSettings; };
void SetGtkPrintSettings(GtkPrintSettings *aPrintSettings);
GtkPrinter* GetGtkPrinter() { return mGTKPrinter; };
void SetGtkPrinter(GtkPrinter *aPrinter);
PRBool GetForcePrintSelectionOnly() { return mPrintSelectionOnly; };
void SetForcePrintSelectionOnly(PRBool aPrintSelectionOnly) { mPrintSelectionOnly = aPrintSelectionOnly; };
// If not printing the selection, this is stored in the GtkPrintSettings. Printing the
// selection is stored as a protected boolean (mPrintSelectionOnly).
NS_IMETHOD GetPrintRange(PRInt16 *aPrintRange);
NS_IMETHOD SetPrintRange(PRInt16 aPrintRange);
// The page range is stored as as single range in the GtkPrintSettings object.
NS_IMETHOD GetStartPageRange(PRInt32 *aStartPageRange);
NS_IMETHOD SetStartPageRange(PRInt32 aStartPageRange);
NS_IMETHOD GetEndPageRange(PRInt32 *aEndPageRange);
NS_IMETHOD SetEndPageRange(PRInt32 aEndPageRange);
// Reversed, color, orientation and file name are all stored in the GtkPrintSettings.
// Orientation is also stored in the GtkPageSetup and its setting takes priority when getting the orientation.
NS_IMETHOD GetPrintReversed(PRBool *aPrintReversed);
NS_IMETHOD SetPrintReversed(PRBool aPrintReversed);
NS_IMETHOD GetPrintInColor(PRBool *aPrintInColor);
NS_IMETHOD SetPrintInColor(PRBool aPrintInColor);
NS_IMETHOD GetOrientation(PRInt32 *aOrientation);
NS_IMETHOD SetOrientation(PRInt32 aOrientation);
NS_IMETHOD GetToFileName(PRUnichar * *aToFileName);
NS_IMETHOD SetToFileName(const PRUnichar * aToFileName);
// Gets/Sets the printer name in the GtkPrintSettings. If no printer name is specified there,
// you will get back the name of the current internal GtkPrinter.
NS_IMETHOD GetPrinterName(PRUnichar * *aPrinter);
NS_IMETHOD SetPrinterName(const PRUnichar * aPrinter);
// Number of copies is stored/gotten from the GtkPrintSettings.
NS_IMETHOD GetNumCopies(PRInt32 *aNumCopies);
NS_IMETHOD SetNumCopies(PRInt32 aNumCopies);
NS_IMETHOD GetEdgeTop(double *aEdgeTop);
NS_IMETHOD SetEdgeTop(double aEdgeTop);
NS_IMETHOD GetEdgeLeft(double *aEdgeLeft);
NS_IMETHOD SetEdgeLeft(double aEdgeLeft);
NS_IMETHOD GetEdgeBottom(double *aEdgeBottom);
NS_IMETHOD SetEdgeBottom(double aEdgeBottom);
NS_IMETHOD GetEdgeRight(double *aEdgeRight);
NS_IMETHOD SetEdgeRight(double aEdgeRight);
NS_IMETHOD GetScaling(double *aScaling);
NS_IMETHOD SetScaling(double aScaling);
// A name recognised by GTK is strongly advised here, as this is used to create a GtkPaperSize.
NS_IMETHOD GetPaperName(PRUnichar * *aPaperName);
NS_IMETHOD SetPaperName(const PRUnichar * aPaperName);
NS_IMETHOD GetPaperWidth(double *aPaperWidth);
NS_IMETHOD SetPaperWidth(double aPaperWidth);
NS_IMETHOD GetPaperHeight(double *aPaperHeight);
NS_IMETHOD SetPaperHeight(double aPaperHeight);
NS_IMETHOD SetPaperSizeUnit(PRInt16 aPaperSizeUnit);
NS_IMETHOD SetEdgeInTwips(nsMargin& aEdge);
NS_IMETHOD GetEdgeInTwips(nsMargin& aEdge);
NS_IMETHOD GetEffectivePageSize(double *aWidth, double *aHeight);
NS_IMETHOD SetupSilentPrinting();
protected:
nsPrintSettingsGTK(const nsPrintSettingsGTK& src);
nsPrintSettingsGTK& operator=(const nsPrintSettingsGTK& rhs);
virtual nsresult _Clone(nsIPrintSettings **_retval);
virtual nsresult _Assign(nsIPrintSettings *aPS);
GtkUnit GetGTKUnit(PRInt16 aGeckoUnit);
void SaveNewPageSize();
/**
* On construction:
* - mPrintSettings, mPageSetup and mPaperSize are just new objects with defaults determined by GTK.
* - mGTKPrinter is NULL!!! Remember to be careful when accessing this property.
*/
GtkPageSetup* mPageSetup;
GtkPrintSettings* mPrintSettings;
GtkPrinter* mGTKPrinter;
GtkPaperSize* mPaperSize;
PRBool mPrintSelectionOnly;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPrintSettingsGTK, NS_PRINTSETTINGSGTK_IID)
#endif // nsPrintSettingsGTK_h_

View File

@ -60,6 +60,7 @@
#include "nsIPrefBranch.h"
#include "nsImageToPixbuf.h"
#include "nsIdleServiceGTK.h"
#include "nsPrintDialogGTK.h"
#ifdef NATIVE_THEME_SUPPORT
#include "nsNativeThemeGTK.h"
@ -97,6 +98,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorGTK)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageToPixbuf)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceGTK)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceGTK, Init)
static NS_IMETHODIMP
nsFilePickerConstructor(nsISupports *aOuter, REFNSIID aIID,
@ -274,6 +276,10 @@ static const nsModuleComponentInfo components[] =
NS_IDLE_SERVICE_CID,
"@mozilla.org/widget/idleservice;1",
nsIdleServiceGTKConstructor },
{ "Native Print Dialog",
NS_PRINTDIALOGSERVICE_CID,
NS_PRINTDIALOGSERVICE_CONTRACTID,
nsPrintDialogServiceGTKConstructor },
};
PR_STATIC_CALLBACK(void)

View File

@ -971,6 +971,15 @@ nsPrintSettings::GetEdgeInTwips(nsMargin& aEdge)
return NS_OK;
}
/** ---------------------------------------------------
* Stub - platform-specific implementations can use this function.
*/
NS_IMETHODIMP
nsPrintSettings::SetupSilentPrinting()
{
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
*/