diff options
| author | craig <craig@11d20701-8431-0410-a711-e3c959e3b870> | 2012-01-01 11:40:09 +0000 |
|---|---|---|
| committer | craig <craig@11d20701-8431-0410-a711-e3c959e3b870> | 2012-01-01 11:40:09 +0000 |
| commit | 7ed83b6c6666eb8b6b104c211ae7e52907350372 (patch) | |
| tree | 4430b556abac0ad660a0aacf1887d77f85d8be02 /scribus/util_printer.cpp | |
| download | scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.gz scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.xz scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.zip | |
Branch 1.3.5 tree to 1.4.x tree, goodbye 1.3.x
git-svn-id: svn://scribus.net/branches/Version14x/Scribus@17163 11d20701-8431-0410-a711-e3c959e3b870
Diffstat (limited to 'scribus/util_printer.cpp')
| -rw-r--r-- | scribus/util_printer.cpp | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/scribus/util_printer.cpp b/scribus/util_printer.cpp new file mode 100644 index 0000000..1b173cd --- /dev/null +++ b/scribus/util_printer.cpp @@ -0,0 +1,318 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ +#include "util_printer.h" +#include "scconfig.h" + +#if defined( HAVE_CUPS ) + #include <cups/cups.h> + #include <cups/ppd.h> +#elif defined(_WIN32) + #include <windows.h> + #include <winspool.h> +#endif + +#include <QStringList> +#include <QDataStream> +#include <QByteArray> +#include "util.h" +#include "commonstrings.h" +#include "scribus.h" +#include "scribuscore.h" + +QStringList PrinterUtil::getPrinterNames() +{ + QString printerName; + QStringList printerNames; +#if defined (HAVE_CUPS) + cups_dest_t *dests; + int num_dests = cupsGetDests(&dests); + for (int pr = 0; pr < num_dests; ++pr) + { + printerName = QString(dests[pr].name); + printerNames.append(printerName); + } + cupsFreeDests(num_dests, dests); +#elif defined(_WIN32) + DWORD size; + DWORD numPrinters; + PRINTER_INFO_2W* printerInfos = NULL; + EnumPrintersW ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &size, &numPrinters ); + printerInfos = (PRINTER_INFO_2W*) malloc(size); + if ( EnumPrintersW ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) printerInfos, size, &size, &numPrinters ) ) + { + for ( uint i = 0; i < numPrinters; i++) + { + printerName = QString::fromUtf16( (const ushort*) printerInfos[i].pPrinterName ); + printerNames.append(printerName); + } + printerNames.sort(); + } + if ( printerInfos) free(printerInfos); +#else + QString tmp; + QString Pcap; + QStringList wt; + if (loadText("/etc/printcap", &Pcap)) + { + QDataStream ts(&Pcap, QIODevice::ReadOnly); + while(!ts.atEnd()) + { + tmp = readLinefromDataStream(ts); + if (tmp.isEmpty()) + continue; + if ((tmp[0] != '#') && (tmp[0] != ' ') && (tmp[0] != '\n') && (tmp[0] != '\t')) + { + tmp = tmp.trimmed(); + tmp = tmp.left(tmp.length() - (tmp.right(2) == ":\\" ? 2 : 1)); + wt = tmp.split("|", QString::SkipEmptyParts); + printerName = wt[0]; + printerNames.append(printerName); + } + } + } +#endif + return printerNames; +} + +#if defined(_WIN32) +bool PrinterUtil::getDefaultSettings( QString printerName, QByteArray& devModeA ) +{ + bool done; + uint size; + LONG result = IDOK+1; + Qt::HANDLE handle = NULL; + // Get the printer handle + done = OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL ); + if(!done) + return false; + // Get size of DEVMODE structure (public + private data) + size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0); + // Allocate the memory needed by the DEVMODE structure + devModeA.resize( size ); + // Retrieve printer default settings + result = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), (DEVMODEW*) devModeA.data(), NULL, DM_OUT_BUFFER); + // Free the printer handle + ClosePrinter( handle ); + return ( result == IDOK ); +} +#endif + +#if defined(_WIN32) +bool PrinterUtil::initDeviceSettings( QString printerName, QByteArray& devModeA ) +{ + bool done; + uint size; + LONG result = IDOK+1; + Qt::HANDLE handle = NULL; + // Get the printer handle + done = OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL ); + if(!done) + return false; + // Get size of DEVMODE structure (public + private data) + size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0); + // Compare size with DevMode structure size + if( devModeA.size() == size ) + { + // Merge printer settings + result = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), (DEVMODEW*) devModeA.data(), (DEVMODEW*) devModeA.data(), DM_IN_BUFFER | DM_OUT_BUFFER); + } + else + { + // Retrieve default settings + devModeA.resize( size ); + result = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), (DEVMODEW*) devModeA.data(), NULL, DM_OUT_BUFFER); + } + done = ( result == IDOK); + // Free the printer handle + ClosePrinter( handle ); + return done; +} +#endif + +bool PrinterUtil::getPrinterMarginValues(const QString& printerName, const QString& pageSize, double& ptsTopMargin, double& ptsBottomMargin, double& ptsLeftMargin, double& ptsRightMargin) +{ + bool retVal=false; +#if defined(HAVE_CUPS) + const char *filename; // tmp PPD filename + filename=cupsGetPPD(printerName.toLocal8Bit().constData()); + if (filename!=NULL) + { + ppd_file_t *ppd; // PPD data + ppd = ppdOpenFile(filename); + if (ppd!=NULL) + { + ppd_size_t *size; // page size data, null if printer doesnt support selected size + size = ppdPageSize(ppd, pageSize.toLocal8Bit().constData()); + if (size!=NULL) + { + //Store in pts for returning via getNewPrinterMargins in pts + retVal=true; + ptsTopMargin=size->length-size->top; + ptsBottomMargin=size->bottom; + ptsLeftMargin=size->left; + ptsRightMargin=size->width-size->right; + } + ppdClose(ppd); + } + } +#elif defined(_WIN32) + DWORD nPaper; + DWORD nPaperNames; + typedef WCHAR wchar64[64]; + nPaper = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERS, NULL, NULL ); + nPaperNames = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERNAMES, NULL, NULL ); + if ( (nPaper > 0) && (nPaperNames > 0) && (nPaper == nPaperNames) ) + { + int paperIndex = -1; + DWORD *papers = new DWORD[nPaper]; + wchar64 *paperNames = new wchar64[nPaperNames]; + DWORD s1 = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERS, (LPWSTR) papers, NULL ); + DWORD s2 = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERNAMES, (LPWSTR) paperNames, NULL ); + for ( uint i = 0; i < nPaperNames; i++ ) + { + if ( pageSize == QString::fromUtf16((const ushort*) paperNames[i]) ) + { + paperIndex = i; + break; + } + } + if ( paperIndex >= 0 ) + { + Qt::HANDLE handle = NULL; + if( OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL ) ) + { + // Retrieve DEVMODE structure for selected device + uint size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0); + QByteArray devModeW(size, 0); + DEVMODEW* devMode = (DEVMODEW*) devModeW.data(); + DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), devMode, NULL, DM_OUT_BUFFER); + ClosePrinter( handle ); + // Set paper size + devMode->dmPaperSize = papers[paperIndex]; + // Create device context + HDC printerDC = CreateDCW( NULL, (LPWSTR) printerName.utf16(), NULL, devMode ); + if( printerDC ) + { + retVal = true; + int logPixelsX = GetDeviceCaps( printerDC, LOGPIXELSX ); + int logPixelsY = GetDeviceCaps( printerDC, LOGPIXELSY ); + int physicalOffsetX = GetDeviceCaps( printerDC, PHYSICALOFFSETX ); + int physicalOffsetY = GetDeviceCaps( printerDC, PHYSICALOFFSETY ); + ptsLeftMargin = ptsRightMargin = ( physicalOffsetX / (double) logPixelsX * 72 ); + ptsTopMargin = ptsBottomMargin = ( physicalOffsetY / (double) logPixelsY * 72 ); + DeleteDC(printerDC); + } + } + } + delete[] papers; + delete[] paperNames; + } +#endif + return retVal; +} + +PrintEngine PrinterUtil::getDefaultPrintEngine(const QString& printerName, bool toFile) +{ + if(!toFile) + { +#if defined(_WIN32) + return WindowsGDI; +#else + return PostScript3; +#endif + } + return PostScript3; +} + +PrintEngineMap PrinterUtil::getPrintEngineSupport(const QString& printerName, bool toFile) +{ + PrintEngineMap prnMap; + if (toFile || PrinterUtil::isPostscriptPrinter(printerName)) + { + if (ScCore->haveGS()) + { + prnMap.insert(CommonStrings::trPostScript1, PostScript1); + prnMap.insert(CommonStrings::trPostScript2, PostScript2); + } + prnMap.insert(CommonStrings::trPostScript3, PostScript3); + } +#if defined(_WIN32) + if (!toFile) + prnMap.insert(CommonStrings::trWindowsGDI, WindowsGDI); +#endif + return prnMap; +} + +bool PrinterUtil::checkPrintEngineSupport(const QString& printerName, PrintEngine engine, bool toFile) +{ + bool psSupported = toFile || PrinterUtil::isPostscriptPrinter(printerName); + if (psSupported && (engine >= PostScript1 && engine <= PostScript3)) + return true; + else if (!psSupported && (engine >= PostScript1 && engine <= PostScript3)) + return false; + else if (engine == WindowsGDI) + { +#if defined(_WIN32) + return true; //WindowsGDI +#else + return false; +#endif + } + return false; +} + +//Parameter needed on win32.. +bool PrinterUtil::isPostscriptPrinter( QString printerName) +{ +#ifdef _WIN32 + HDC dc; + int escapeCode; + char technology[MAX_PATH] = {0}; + + // Create the default device context + dc = CreateDCW( NULL, (LPCWSTR) printerName.utf16(), NULL, NULL ); + if ( !dc ) + { + qWarning("isPostscriptPrinter() failed to create device context for %s", printerName.toAscii().data()); + return false; + } + // test if printer support the POSTSCRIPT_PASSTHROUGH escape code + escapeCode = POSTSCRIPT_PASSTHROUGH; + if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 ) + { + DeleteDC( dc ); + return true; + } + // test if printer support the POSTSCRIPT_DATA escape code + escapeCode = POSTSCRIPT_DATA; + if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 ) + { + DeleteDC( dc ); + return true; + } + // try to get postscript support by testing the printer technology + escapeCode = GETTECHNOLOGY; + if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 ) + { + // if GETTECHNOLOGY is supported, then ... get technology + if ( ExtEscape( dc, GETTECHNOLOGY, 0, NULL, MAX_PATH, (LPSTR) technology ) > 0 ) + { + // check technology string for postscript word + strupr( technology ); + if ( strstr( technology, "POSTSCRIPT" ) ) + { + DeleteDC( dc ); + return true; + } + } + } + DeleteDC( dc ); + return false; +#else + return true; +#endif +} |
