commit e001fbab55aceef62ad9ca2bb87a170dacfe3fdd
Author: Kevin Kofler <kevin.kofler@chello.at>
Date:   Mon Jun 6 00:40:22 2011 +0200

    Fix landscape documents getting printed in portrait format if "Landscape" is selected in the print dialog (the default).
    
    Partly based on a patch by Falk from KDE bug #181290.
    
    BUG: 181290
    REVIEW: 101513

diff --git a/core/document.cpp b/core/document.cpp
index 8af1840..16c8985 100644
--- a/core/document.cpp
+++ b/core/document.cpp
@@ -3459,6 +3459,28 @@ bool Document::saveDocumentArchive( const QString &fileName )
     return true;
 }
 
+QPrinter::Orientation Document::orientation() const
+{
+    double width, height;
+    int landscape, portrait;
+    const Okular::Page *currentPage;
+
+    // if some pages are landscape and others are not, the most common wins, as
+    // QPrinter does not accept a per-page setting
+    landscape = 0;
+    portrait = 0;
+    for (uint i = 0; i < pages(); i++)
+    {
+        currentPage = page(i);
+        width = currentPage->width();
+        height = currentPage->height();
+        if (currentPage->orientation() == Okular::Rotation90 || currentPage->orientation() == Okular::Rotation270) qSwap(width, height);
+        if (width > height) landscape++;
+        else portrait++;
+    }
+    return (landscape > portrait) ? QPrinter::Landscape : QPrinter::Portrait;
+}
+
 void DocumentPrivate::requestDone( PixmapRequest * req )
 {
     if ( !req )
diff --git a/core/document.h b/core/document.h
index 587c03c..27cb442 100644
--- a/core/document.h
+++ b/core/document.h
@@ -19,11 +19,11 @@
 #include <QtCore/QObject>
 #include <QtCore/QStringList>
 #include <QtCore/QVector>
+#include <QtGui/QPrinter>
 #include <QtXml/QDomDocument>
 
 #include <kmimetype.h>
 
-class QPrinter;
 class QPrintDialog;
 class KComponentData;
 class KBookmark;
@@ -604,6 +604,15 @@ class OKULAR_EXPORT Document : public QObject
         */
         const SourceReference * dynamicSourceReference( int pageNr, double absX, double absY );
 
+        /**
+         * Returns the orientation of the document (for printing purposes). This
+         * is used in the KPart to initialize the print dialog and in the
+         * generators to check whether the document needs to be rotated or not.
+         *
+         * @since 0.14 (KDE 4.8)
+        */
+        QPrinter::Orientation orientation() const;
+
 
     public Q_SLOTS:
         /**
diff --git a/core/fileprinter.cpp b/core/fileprinter.cpp
index f08b104..b70b664 100644
--- a/core/fileprinter.cpp
+++ b/core/fileprinter.cpp
@@ -33,22 +33,44 @@
 
 using namespace Okular;
 
+// Deprecated overload for binary compatibility
 int FilePrinter::printFile( QPrinter &printer, const QString file, FileDeletePolicy fileDeletePolicy,
                             PageSelectPolicy pageSelectPolicy, const QString &pageRange )
 {
+    return printFile( printer, file, QPrinter::Portrait, fileDeletePolicy, pageSelectPolicy, pageRange );
+}
+
+int FilePrinter::printFile( QPrinter &printer, const QString file,
+                            QPrinter::Orientation documentOrientation, FileDeletePolicy fileDeletePolicy,
+                            PageSelectPolicy pageSelectPolicy, const QString &pageRange )
+{
     FilePrinter fp;
-    return fp.doPrintFiles( printer, QStringList( file ), fileDeletePolicy, pageSelectPolicy, pageRange );
+    return fp.doPrintFiles( printer, QStringList( file ), fileDeletePolicy, pageSelectPolicy, pageRange, 
+                            documentOrientation );
 }
 
+// Deprecated function kept for binary compatibility
+// This is deprecated because it cannot support different original orientations
+// for each document in the list.
 int FilePrinter::printFiles( QPrinter &printer, const QStringList &fileList, FileDeletePolicy fileDeletePolicy )
 {
     FilePrinter fp;
-    return fp.doPrintFiles( printer, fileList, fileDeletePolicy, FilePrinter::ApplicationSelectsPages, QString() );
+    return fp.doPrintFiles( printer, fileList, fileDeletePolicy, FilePrinter::ApplicationSelectsPages, QString(),
+                            QPrinter::Portrait );
 }
 
+// Deprecated overload for binary compatibility
 int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
                                PageSelectPolicy pageSelectPolicy, const QString &pageRange )
 {
+    return doPrintFiles( printer, fileList, fileDeletePolicy, pageSelectPolicy, pageRange,
+                         QPrinter::Portrait );
+}
+
+int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
+                               PageSelectPolicy pageSelectPolicy, const QString &pageRange,
+                               QPrinter::Orientation documentOrientation )
+{
 
     if ( fileList.size() < 1 ) {
         return -8;
@@ -135,7 +157,7 @@ int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDele
 
         bool useCupsOptions = cupsAvailable();
         argList = printArguments( printer, fileDeletePolicy, pageSelectPolicy, 
-                                  useCupsOptions, pageRange, exe ) << fileList;
+                                  useCupsOptions, pageRange, exe, documentOrientation ) << fileList;
         kDebug(OkularDebug) << "Executing" << exe << "with arguments" << argList;
 
         ret = KProcess::execute( exe, argList );
@@ -358,10 +380,20 @@ Generator::PrintError FilePrinter::printError( int c )
 
 
 
+// Deprecated overload for binary compatibility
 QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
                                          PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
                                          const QString &pageRange, const QString &version )
 {
+    return printArguments( printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions,
+                           pageRange, version, QPrinter::Portrait );
+}
+
+QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
+                                         PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
+                                         const QString &pageRange, const QString &version, 
+                                         QPrinter::Orientation documentOrientation )
+{
     QStringList argList;
 
     if ( ! destination( printer, version ).isEmpty() ) {
@@ -380,8 +412,8 @@ QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fil
         argList << pages( printer, pageSelectPolicy, pageRange, useCupsOptions, version );
     }
 
-    if ( useCupsOptions && ! cupsOptions( printer ).isEmpty() ) {
-        argList << cupsOptions( printer );
+    if ( useCupsOptions && ! cupsOptions( printer, documentOrientation ).isEmpty() ) {
+        argList << cupsOptions( printer, documentOrientation);
     }
 
     if ( ! deleteFile( printer, fileDeletePolicy, version ).isEmpty() ) {
@@ -484,16 +516,22 @@ QStringList FilePrinter::pages( QPrinter &printer, PageSelectPolicy pageSelectPo
     return QStringList(); // AllPages
 }
 
+// Deprecated overload for binary compatibility
 QStringList FilePrinter::cupsOptions( QPrinter &printer )
 {
+    return cupsOptions( printer, QPrinter::Portrait );
+}
+
+QStringList FilePrinter::cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation )
+{
     QStringList optionList;
 
     if ( ! optionMedia( printer ).isEmpty() ) {
         optionList << optionMedia( printer );
     }
 
-    if ( ! optionOrientation( printer ).isEmpty() ) {
-        optionList << optionOrientation( printer );
+    if ( ! optionOrientation( printer, documentOrientation ).isEmpty() ) {
+        optionList << optionOrientation( printer, documentOrientation );
     }
 
     if ( ! optionDoubleSidedPrinting( printer ).isEmpty() ) {
@@ -597,12 +635,23 @@ QString FilePrinter::mediaPaperSource( QPrinter &printer )
     }
 }
 
+// Deprecated overload for binary compatibility
 QStringList FilePrinter::optionOrientation( QPrinter &printer )
 {
-    switch ( printer.orientation() ) {
-    case QPrinter::Portrait:   return QStringList("-o") << "portrait";
-    case QPrinter::Landscape:  return QStringList("-o") << "landscape";
-    default:                   return QStringList();
+    return optionOrientation( printer, QPrinter::Portrait );
+}
+
+QStringList FilePrinter::optionOrientation( QPrinter &printer, QPrinter::Orientation documentOrientation )
+{
+    // portrait and landscape options rotate the document according to the document orientation
+    // If we want to print a landscape document as one would expect it, we have to pass the
+    // portrait option so that the document is not rotated additionaly
+    if ( printer.orientation() == documentOrientation ) {
+        // the user wants the document printed as is
+        return QStringList("-o") << "portrait";
+    } else {
+        // the user expects the document being rotated by 90 degrees
+        return QStringList("-o") << "landscape";
     }
 }
 
diff --git a/core/fileprinter.h b/core/fileprinter.h
index f17e09d..5fbb492 100644
--- a/core/fileprinter.h
+++ b/core/fileprinter.h
@@ -16,11 +16,14 @@
 
 #include <QtCore/QList>
 #include <QtCore/QString>
+#include <QtGui/QPrinter>
+
+// For KDE_DEPRECATED
+#include <kdemacros.h>
 
 #include "okular_export.h"
 #include "generator.h"
 
-class QPrinter;
 class QSize;
 
 namespace Okular {
@@ -53,8 +56,11 @@ public:
      *  Only supports CUPS and LPR on *NIX.  Page Range only supported in CUPS.
      *  Most settings unsupported by LPR, some settings unsupported by CUPS.
      *
+     *  The documentOrientation parameter was added in version 0.14.
+     *
      * @param printer the print settings to use
      * @param file the file to print
+     * @param documentOrientation the orientation stored in the document itself
      * @param fileDeletePolicy if the application or system deletes the file
      * @param pageSelectPolicy if the application or system selects the pages to print
      * @param pageRange page range to print if SystemSlectsPages and user chooses Selection in Print Dialog
@@ -68,13 +74,45 @@ public:
      *          -2 if the KProcess could not be started
      *          -1 if the KProcess crashed
      *          otherwise the KProcess exit code
+     *
+     * @since 0.14 (KDE 4.8)
      */
 
     static int printFile( QPrinter &printer, const QString file,
+                          QPrinter::Orientation documentOrientation,
                           FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles,
                           PageSelectPolicy pageSelectPolicy = FilePrinter::ApplicationSelectsPages,
                           const QString &pageRange = QString() );
 
+    /** Print a file using the settings in QPrinter (compatibility overload)
+     *
+     *  Only supports CUPS and LPR on *NIX.  Page Range only supported in CUPS.
+     *  Most settings unsupported by LPR, some settings unsupported by CUPS.
+     *
+     * @param printer the print settings to use
+     * @param file the file to print
+     * @param fileDeletePolicy if the application or system deletes the file
+     * @param pageSelectPolicy if the application or system selects the pages to print
+     * @param pageRange page range to print if SystemSlectsPages and user chooses Selection in Print Dialog
+     *
+     * @returns Returns exit code:
+     *          -9 if lpr not found
+     *          -8 if empty file name
+     *          -7 if unable to find file
+     *          -6 if invalid printer state
+     *          -5 if print to file copy failed
+     *          -2 if the KProcess could not be started
+     *          -1 if the KProcess crashed
+     *          otherwise the KProcess exit code
+     *
+     * @deprecated Use the overload which takes the documentOrientation instead.
+     */
+
+    static KDE_DEPRECATED int printFile( QPrinter &printer, const QString file,
+                                         FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles,
+                                         PageSelectPolicy pageSelectPolicy = FilePrinter::ApplicationSelectsPages,
+                                         const QString &pageRange = QString() );
+
     /** Print a list of files using the settings in QPrinter
      *
      *  Only supports CUPS and LPR on *NIX.
@@ -93,10 +131,12 @@ public:
      *          -2 if the KProcess could not be started
      *          -1 if the KProcess crashed
      *          otherwise the KProcess exit code
+     *
+     * @deprecated Use printFile instead, passing the documentOrientation for each file.
      */
 
-    static int printFiles( QPrinter &printer, const QStringList &fileList,
-                           FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles );
+    static KDE_DEPRECATED int printFiles( QPrinter &printer, const QStringList &fileList,
+                                          FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles );
 
     /** Return the list of pages selected by the user in the Print Dialog
      *
@@ -169,13 +209,21 @@ protected:
     bool detectCupsService();
     bool detectCupsConfig();
 
+    KDE_DEPRECATED int doPrintFiles( QPrinter &printer, const QStringList fileList,
+                                     FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
+                                     const QString &pageRange );
     int doPrintFiles( QPrinter &printer, const QStringList fileList,
                              FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
-                             const QString &pageRange );
+                             const QString &pageRange,
+                             QPrinter::Orientation documentOrientation );
 
+    KDE_DEPRECATED QStringList printArguments( QPrinter &printer,
+                                               FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
+                                               bool useCupsOptions, const QString &pageRange, const QString &version );
     QStringList printArguments( QPrinter &printer,
                                        FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
-                                       bool useCupsOptions, const QString &pageRange, const QString &version );
+                                       bool useCupsOptions, const QString &pageRange, const QString &version,
+                                       QPrinter::Orientation documentOrientation );
 
     QStringList destination( QPrinter &printer, const QString &version );
     QStringList copies( QPrinter &printer, const QString &version );
@@ -185,11 +233,13 @@ protected:
     QStringList pages( QPrinter &printer, PageSelectPolicy pageSelectPolicy,
                               const QString &pageRange, bool useCupsOptions, const QString &version );
 
-    QStringList cupsOptions( QPrinter &printer );
+    KDE_DEPRECATED QStringList cupsOptions( QPrinter &printer );
+    QStringList cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation );
     QStringList optionMedia( QPrinter &printer );
     QString mediaPageSize( QPrinter &printer );
     QString mediaPaperSource( QPrinter &printer );
-    QStringList optionOrientation( QPrinter &printer );
+    KDE_DEPRECATED QStringList optionOrientation( QPrinter &printer );
+    QStringList optionOrientation( QPrinter &printer, QPrinter::Orientation documentOrientation );
     QStringList optionDoubleSidedPrinting( QPrinter &printer );
     QStringList optionPageOrder( QPrinter &printer );
     QStringList optionCollateCopies( QPrinter &printer );
diff --git a/generators/djvu/generator_djvu.cpp b/generators/djvu/generator_djvu.cpp
index f05c0eb..93271bf 100644
--- a/generators/djvu/generator_djvu.cpp
+++ b/generators/djvu/generator_djvu.cpp
@@ -217,7 +217,7 @@ bool DjVuGenerator::print( QPrinter& printer )
         tf.setAutoRemove( false );
         const QString fileName = tf.fileName();
         tf.close();
-        int ret = Okular::FilePrinter::printFile( printer, fileName,
+        int ret = Okular::FilePrinter::printFile( printer, fileName, document()->orientation(),
                                                   Okular::FilePrinter::SystemDeletesFiles,
                                                   Okular::FilePrinter::ApplicationSelectsPages,
                                                   document()->bookmarkedPageRange() );
diff --git a/generators/dvi/dviRenderer.cpp b/generators/dvi/dviRenderer.cpp
index b80350a..1057bfb 100644
--- a/generators/dvi/dviRenderer.cpp
+++ b/generators/dvi/dviRenderer.cpp
@@ -767,9 +767,9 @@ void dviRenderer::exportPDF()
 }
 
 
-void dviRenderer::exportPS(const QString& fname, const QStringList& options, QPrinter* printer)
+void dviRenderer::exportPS(const QString& fname, const QStringList& options, QPrinter* printer, QPrinter::Orientation orientation)
 {
-  KSharedPtr<DVIExport> exporter(new DVIExportToPS(*this, parentWidget, fname, options, printer, font_pool.getUseFontHints()));
+  KSharedPtr<DVIExport> exporter(new DVIExportToPS(*this, parentWidget, fname, options, printer, font_pool.getUseFontHints(), orientation));
   if (exporter->started())
     all_exports_[exporter.data()] = exporter;
 }
diff --git a/generators/dvi/dviRenderer.h b/generators/dvi/dviRenderer.h
index 8f5f95a..c3ce5eb 100644
--- a/generators/dvi/dviRenderer.h
+++ b/generators/dvi/dviRenderer.h
@@ -29,6 +29,7 @@
 #include <QVector>
 #include <QTimer>
 #include <QMutex>
+#include <QtGui/QPrinter>
 
 class Anchor;
 class DocumentWidget;
@@ -37,7 +38,6 @@ class dviRenderer;
 class ghostscript_interface;
 //class infoDialog;
 class QEventLoop;
-class QPrinter;
 class KProgressDialog;
 class PreBookmark;
 class TeXFontDefinition;
@@ -154,7 +154,7 @@ public:
 //void          editor_finished(const DVISourceEditor*);
 
 public slots:
-  void          exportPS(const QString& fname = QString(), const QStringList& options = QStringList(), QPrinter* printer = 0);
+  void          exportPS(const QString& fname = QString(), const QStringList& options = QStringList(), QPrinter* printer = 0, QPrinter::Orientation orientation = QPrinter::Portrait);
   void          exportPDF();
 
 //void          showInfo();
diff --git a/generators/dvi/dviexport.cpp b/generators/dvi/dviexport.cpp
index f866559..46a1985 100644
--- a/generators/dvi/dviexport.cpp
+++ b/generators/dvi/dviexport.cpp
@@ -288,9 +288,11 @@ DVIExportToPS::DVIExportToPS(dviRenderer& parent,
                              const QString& output_name,
                              const QStringList& options,
                              QPrinter* printer,
-                             bool useFontHinting)
+                             bool useFontHinting,
+                             QPrinter::Orientation orientation)
   : DVIExport(parent, parent_widget),
-    printer_(printer)
+    printer_(printer),
+    orientation_(orientation)
 {
   // None of these should happen. Paranoia checks.
   if (!parent.dviFile)
@@ -457,7 +459,7 @@ void DVIExportToPS::finished_impl(int exit_code)
     const QFileInfo output(output_name_);
     if (output.exists() && output.isReadable()) {
         // I'm not 100% sure on this, think we still need to select pages in export to ps above
-        Okular::FilePrinter::printFile( (*printer_), output_name_,
+        Okular::FilePrinter::printFile( (*printer_), output_name_, orientation_,
                                 Okular::FilePrinter::ApplicationDeletesFiles,
                                 Okular::FilePrinter::ApplicationSelectsPages,
                                 QString() );
diff --git a/generators/dvi/dviexport.h b/generators/dvi/dviexport.h
index 295dc6e..3265645 100644
--- a/generators/dvi/dviexport.h
+++ b/generators/dvi/dviexport.h
@@ -22,11 +22,11 @@
 #include <ksharedptr.h>
 
 #include <QObject>
+#include <QtGui/QPrinter>
 
 
 class dviRenderer;
 class fontProgressDialog;
-class QPrinter;
 class KProcess;
 class QStringList;
 
@@ -124,13 +124,15 @@ public:
    *  passed to the external process's argv command line.
    *  @param printer having generated the PostScript file, it is passed
    *  to @c printer (if not null).
+   *  @param orientation the original orientation of the document
    */
   DVIExportToPS(dviRenderer& parent,
                 QWidget* parent_widget,
                 const QString& output_name,
                 const QStringList& options,
                 QPrinter* printer,
-                bool useFontHinting);
+                bool useFontHinting,
+                QPrinter::Orientation orientation = QPrinter::Portrait);
 
 private:
   virtual void abort_process_impl();
@@ -139,6 +141,7 @@ private:
   QPrinter* printer_;
   QString output_name_;
   QString tmpfile_name_;
+  QPrinter::Orientation orientation_;
 };
 
 #endif
diff --git a/generators/dvi/generator_dvi.cpp b/generators/dvi/generator_dvi.cpp
index 35a8976..2bc8641 100644
--- a/generators/dvi/generator_dvi.cpp
+++ b/generators/dvi/generator_dvi.cpp
@@ -567,7 +567,7 @@ bool DviGenerator::print( QPrinter& printer )
 
     QEventLoop el;
     m_dviRenderer->setEventLoop( &el );
-    m_dviRenderer->exportPS( tf.fileName(), printOptions, &printer );
+    m_dviRenderer->exportPS( tf.fileName(), printOptions, &printer, document()->orientation() );
 
     tf.close();
 
diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp
index 42bad00..7e7d01d 100644
--- a/generators/poppler/generator_pdf.cpp
+++ b/generators/poppler/generator_pdf.cpp
@@ -976,6 +976,7 @@ bool PDFGenerator::print( QPrinter& printer )
         delete psConverter;
         tf.close();
         int ret = Okular::FilePrinter::printFile( printer, tempfilename,
+                                                  document()->orientation(),
                                                   Okular::FilePrinter::SystemDeletesFiles,
                                                   Okular::FilePrinter::ApplicationSelectsPages,
                                                   document()->bookmarkedPageRange() );
diff --git a/generators/spectre/generator_ghostview.cpp b/generators/spectre/generator_ghostview.cpp
index 7150df8..4d0a4f6 100644
--- a/generators/spectre/generator_ghostview.cpp
+++ b/generators/spectre/generator_ghostview.cpp
@@ -145,7 +145,7 @@ bool GSGenerator::print( QPrinter& printer )
     if ( exportStatus == SPECTRE_STATUS_SUCCESS && endStatus == SPECTRE_STATUS_SUCCESS )
     {
         tf.setAutoRemove( false );
-        int ret = Okular::FilePrinter::printFile( printer, fileName,
+        int ret = Okular::FilePrinter::printFile( printer, fileName, document()->orientation(),
                                                   Okular::FilePrinter::SystemDeletesFiles,
                                                   Okular::FilePrinter::ApplicationSelectsPages,
                                                   document()->bookmarkedPageRange() );
diff --git a/part.cpp b/part.cpp
index 5b0346d..c71384f 100644
--- a/part.cpp
+++ b/part.cpp
@@ -2073,24 +2073,7 @@ void Part::slotPrint()
 
 void Part::setupPrint( QPrinter &printer )
 {
-    double width, height;
-    int landscape, portrait;
-    const Okular::Page *page;
-
-    // if some pages are landscape and others are not the most common win as QPrinter does
-    // not accept a per page setting
-    landscape = 0;
-    portrait = 0;
-    for (uint i = 0; i < m_document->pages(); i++)
-    {
-        page = m_document->page(i);
-        width = page->width();
-        height = page->height();
-        if (page->orientation() == Okular::Rotation90 || page->orientation() == Okular::Rotation270) qSwap(width, height);
-        if (width > height) landscape++;
-        else portrait++;
-    }
-    if (landscape > portrait) printer.setOrientation(QPrinter::Landscape);
+    printer.setOrientation(m_document->orientation());
 
     // title
     QString title = m_document->metaData( "DocumentTitle" ).toString();
