This patch may not apply cleanly (especially if it is applied in
conjunction with the suppression of annotations), but it is a very
useful feature to have.

It was coded and submitted by Dmitry E. Oboukhov.


Regards,

-- 
Rogério Brito : rbr...@{ime.usp.br,gmail.com} : GPG key 1024D/7C2CAEB8
http://rb.doesntexist.org : Packages for LaTeX : algorithms.berlios.de
DebianQA: http://qa.debian.org/developer.php?login=rbrito%40ime.usp.br
--- a/xpdf/XPDFViewer.cc
+++ b/xpdf/XPDFViewer.cc
@@ -3169,7 +3169,7 @@
 //------------------------------------------------------------------------
 
 void XPDFViewer::initPrintDialog() {
-  Widget sep1, sep2, row, label1, label2, okBtn, cancelBtn;
+  Widget sep1, sep2, sep3, sep4, row, label1, label2, okBtn, cancelBtn;
   Arg args[20];
   int n;
   XmString s;
@@ -3295,12 +3295,106 @@
   sep2 = XmCreateSeparator(printDialog, "sep2", args, n);
   XtManageChild(sep2);
 
-  //----- "print" and "cancel" buttons
+  //----- Print All Pages
   n = 0;
   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
   XtSetArg(args[n], XmNtopWidget, sep2); ++n;
   XtSetArg(args[n], XmNtopOffset, 8); ++n;
   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNleftOffset, 8); ++n;
+  XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
+  XtSetArg(args[n], XmNset, XmSET); ++n;
+  s = XmStringCreateLocalized("Print all pages");
+  XtSetArg(args[n], XmNlabelString, s); ++n;
+  printAllPages = XmCreateToggleButton(printDialog, "printAllPages", args, n);
+  XmStringFree(s);
+  XtManageChild(printAllPages);
+  XtAddCallback(printAllPages, XmNvalueChangedCallback,
+    &printAllPagesBtnCbk, (XtPointer)this);
+
+  //----- Print Odd Pages
+  n = 0;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNtopWidget, printAllPages); ++n;
+//   XtSetArg(args[n], XmNtopOffset, 4); ++n;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNleftOffset, 8); ++n;
+  XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
+  XtSetArg(args[n], XmNset, XmUNSET); ++n;
+  s = XmStringCreateLocalized("Print odd pages");
+  XtSetArg(args[n], XmNlabelString, s); ++n;
+  printOddPages = XmCreateToggleButton(printDialog, "printOddPages", args, n);
+  XmStringFree(s);
+  XtManageChild(printOddPages);
+  XtAddCallback(printOddPages, XmNvalueChangedCallback,
+    &printOddPagesBtnCbk, (XtPointer)this);
+
+  //----- Print Even Pages
+  n = 0;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNtopWidget, printOddPages); ++n;
+//   XtSetArg(args[n], XmNtopOffset, 4); ++n;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNleftOffset, 8); ++n;
+  XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
+  XtSetArg(args[n], XmNset, XmUNSET); ++n;
+  s = XmStringCreateLocalized("Print even pages");
+  XtSetArg(args[n], XmNlabelString, s); ++n;
+  printEvenPages = XmCreateToggleButton(printDialog, "printEvenPages", args, 
n);
+  XmStringFree(s);
+  XtManageChild(printEvenPages);
+  XtAddCallback(printEvenPages, XmNvalueChangedCallback,
+    &printEvenPagesBtnCbk, (XtPointer)this);
+
+  //----- separator
+  n = 0;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNtopWidget, printEvenPages); ++n;
+  XtSetArg(args[n], XmNtopOffset, 8); ++n;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNleftOffset, 8); ++n;
+  XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNrightOffset, 8); ++n;
+  XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
+  sep3 = XmCreateSeparator(printDialog, "sep3", args, n);
+  XtManageChild(sep3);
+
+  //----- Print Back Order
+  n = 0;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNtopWidget, sep3); ++n;
+  XtSetArg(args[n], XmNtopOffset, 8); ++n;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNleftOffset, 8); ++n;
+  XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
+  XtSetArg(args[n], XmNset, XmUNSET); ++n;
+  s = XmStringCreateLocalized("Print back order");
+  XtSetArg(args[n], XmNlabelString, s); ++n;
+  printBackOrder = XmCreateToggleButton(printDialog, "printBackOrder", args, 
n);
+  XmStringFree(s);
+  XtManageChild(printBackOrder);
+  XtAddCallback(printBackOrder, XmNvalueChangedCallback,
+    &printBackOrderBtnCbk, (XtPointer)this);
+
+  //----- separator
+  n = 0;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNtopWidget, printBackOrder); ++n;
+  XtSetArg(args[n], XmNtopOffset, 8); ++n;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNleftOffset, 8); ++n;
+  XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNrightOffset, 8); ++n;
+  XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
+  sep3 = XmCreateSeparator(printDialog, "sep3", args, n);
+  XtManageChild(sep3);
+
+  //----- "print" and "cancel" buttons
+  n = 0;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNtopWidget, sep3); ++n;
+  XtSetArg(args[n], XmNtopOffset, 8); ++n;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
   XtSetArg(args[n], XmNleftOffset, 4); ++n;
   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
@@ -3310,7 +3404,7 @@
                &printPrintCbk, (XtPointer)this);
   n = 0;
   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
-  XtSetArg(args[n], XmNtopWidget, sep2); ++n;
+  XtSetArg(args[n], XmNtopWidget, sep3); ++n;
   XtSetArg(args[n], XmNtopOffset, 8); ++n;
   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
   XtSetArg(args[n], XmNrightOffset, 4); ++n;
@@ -3335,6 +3429,60 @@
   }
 }
 
+void XPDFViewer::printAllPagesBtnCbk(Widget widget,
+  XtPointer ptr, XtPointer callData)
+{
+  XPDFViewer *viewer = (XPDFViewer *)ptr;
+  XmToggleButtonCallbackStruct *data =
+      (XmToggleButtonCallbackStruct *)callData;
+
+  if (data->set != XmSET) {
+    XmToggleButtonSetState(viewer->printAllPages, True, False);
+  }
+  XmToggleButtonSetState(viewer->printEvenPages, False, False);
+  XmToggleButtonSetState(viewer->printOddPages, False, False);
+}
+
+void XPDFViewer::printEvenPagesBtnCbk(Widget widget,
+  XtPointer ptr, XtPointer callData)
+{
+  XPDFViewer *viewer = (XPDFViewer *)ptr;
+  XmToggleButtonCallbackStruct *data =
+      (XmToggleButtonCallbackStruct *)callData;
+
+  if (data->set != XmSET) {
+    XmToggleButtonSetState(viewer->printEvenPages, True, False);
+  }
+  XmToggleButtonSetState(viewer->printAllPages, False, False);
+  XmToggleButtonSetState(viewer->printOddPages, False, False);
+  XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
+  XmToggleButtonSetState(viewer->printToFileBtn, False, False);
+}
+
+void XPDFViewer::printOddPagesBtnCbk(Widget widget,
+  XtPointer ptr, XtPointer callData)
+{
+  XPDFViewer *viewer = (XPDFViewer *)ptr;
+  XmToggleButtonCallbackStruct *data =
+      (XmToggleButtonCallbackStruct *)callData;
+
+  if (data->set != XmSET) {
+    XmToggleButtonSetState(viewer->printOddPages, True, False);
+  }
+  XmToggleButtonSetState(viewer->printAllPages, False, False);
+  XmToggleButtonSetState(viewer->printEvenPages, False, False);
+  XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
+  XmToggleButtonSetState(viewer->printToFileBtn, False, False);
+}
+
+void XPDFViewer::printBackOrderBtnCbk(Widget widget, XtPointer ptr,
+  XtPointer callData)
+{
+  XPDFViewer *viewer = (XPDFViewer *)ptr;
+  XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
+  XmToggleButtonSetState(viewer->printToFileBtn, False, False);
+}
+
 void XPDFViewer::setupPrintDialog() {
   PDFDoc *doc;
   char buf[20];
@@ -3402,12 +3550,17 @@
   XmToggleButtonSetState(viewer->printWithCmdBtn, False, False);
   XtVaSetValues(viewer->printFileText, XmNsensitive, True, NULL);
   XtVaSetValues(viewer->printCmdText, XmNsensitive, False, NULL);
+
+  XmToggleButtonSetState(viewer->printAllPages, True, False);
+  XmToggleButtonSetState(viewer->printOddPages, False, False);
+  XmToggleButtonSetState(viewer->printEvenPages, False, False);
+  XmToggleButtonSetState(viewer->printBackOrder, False, False);
 }
 
 void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
                               XtPointer callData) {
   XPDFViewer *viewer = (XPDFViewer *)ptr;
-  unsigned char withCmd;
+  unsigned char withCmd, printAll, printOdd, printEven, printBack;
   GString *psFileName;
   int firstPage, lastPage;
   PDFDoc *doc;
@@ -3424,6 +3577,11 @@
   viewer->core->setBusyCursor(gTrue);
 
   XtVaGetValues(viewer->printWithCmdBtn, XmNset, &withCmd, NULL);
+  XtVaGetValues(viewer->printAllPages, XmNset, &printAll, NULL);
+  XtVaGetValues(viewer->printOddPages, XmNset, &printOdd, NULL);
+  XtVaGetValues(viewer->printEvenPages, XmNset, &printEven, NULL);
+  XtVaGetValues(viewer->printBackOrder, XmNset, &printBack, NULL);
+
   if (withCmd) {
     psFileName = new GString(XmTextFieldGetString(viewer->printCmdText));
     psFileName->insert(0, '|');
@@ -3444,14 +3602,71 @@
     lastPage = doc->getNumPages();
   }
 
-  psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
-                         doc->getCatalog(), firstPage, lastPage,
-                         psModePS);
-  if (psOut->isOk()) {
-    doc->displayPages(psOut, firstPage, lastPage, 72, 72,
-                     0, gTrue, globalParams->getPSCrop(), gTrue);
+  // Normal print mode
+  if (printAll && !printBack)
+  {
+    psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
+          doc->getCatalog(), firstPage, lastPage,
+          psModePS);
+    if (psOut->isOk()) {
+      doc->displayPages(psOut, firstPage, lastPage, 72, 72,
+            0, gTrue, globalParams->getPSCrop(), gFalse);
+    }
+    delete psOut;
+  }
+  // Additional prints mode's
+  else
+  {
+    int step=1, i;
+    int beginPage, endPage;
+
+    if (!printAll)
+    {
+      step=2;
+      if (printEven)
+      {
+        firstPage+=firstPage&0x01?1:0;
+        lastPage-=lastPage&0x01?1:0;
+      }
+      else
+      {
+        firstPage+=firstPage&0x01?0:1;
+        lastPage-=lastPage&0x01?0:1;
+      }
+    }
+
+    if (printBack)
+    {
+      step=-step;
+      beginPage=lastPage;
+      endPage=firstPage;
+    }
+    else
+    {
+      beginPage=firstPage;
+      endPage=lastPage;
+    }
+
+    if (firstPage<=lastPage)
+    {
+      for (i=beginPage;; i+=step)
+      {
+        psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
+              doc->getCatalog(), i, i, psModePS);
+        if (psOut->isOk()) {
+          doc->displayPages(psOut, i, i, 72, 72,
+                0, gTrue, globalParams->getPSCrop(), gFalse);
+        }
+        else
+        {
+          delete psOut;
+          break;
+        }
+        delete psOut;
+        if (i==endPage) break;
+      }
+    }
   }
-  delete psOut;
   delete psFileName;
 
   viewer->core->setBusyCursor(gFalse);
--- a/xpdf/XPDFViewer.h
+++ b/xpdf/XPDFViewer.h
@@ -279,6 +279,16 @@
                                 XtPointer callData);
   static void printToFileBtnCbk(Widget widget, XtPointer ptr,
                                XtPointer callData);
+
+  static void printAllPagesBtnCbk(Widget widget, XtPointer ptr,
+                                XtPointer callData);
+  static void printEvenPagesBtnCbk(Widget widget, XtPointer ptr,
+                                XtPointer callData);
+  static void printOddPagesBtnCbk(Widget widget, XtPointer ptr,
+                                XtPointer callData);
+  static void printBackOrderBtnCbk(Widget widget, XtPointer ptr,
+                                XtPointer callData);
+
   static void printPrintCbk(Widget widget, XtPointer ptr,
                            XtPointer callData);
 
@@ -347,6 +357,8 @@
   Widget printFileText;
   Widget printFirstPage;
   Widget printLastPage;
+
+  Widget printAllPages, printEvenPages, printOddPages, printBackOrder;
 };
 
 #endif

Reply via email to