File indexing completed on 2024-04-14 14:35:56

0001 /************************************************************************
0002  *                                  *
0003  *  This file is part of Kooka, a scanning/OCR application using    *
0004  *  Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>.  *
0005  *                                  *
0006  *  Copyright (C) 2003-2016 Klaas Freitag <freitag@suse.de>     *
0007  *                          Jonathan Marten <jjm@keelhaul.me.uk>    *
0008  *                                  *
0009  *  Kooka is free software; you can redistribute it and/or modify it    *
0010  *  under the terms of the GNU Library General Public License as    *
0011  *  published by the Free Software Foundation and appearing in the  *
0012  *  file COPYING included in the packaging of this file;  either    *
0013  *  version 2 of the License, or (at your option) any later version.    *
0014  *                                  *
0015  *  As a special exception, permission is given to link this program    *
0016  *  with any version of the KADMOS OCR/ICR engine (a product of     *
0017  *  reRecognition GmbH, Kreuzlingen), and distribute the resulting  *
0018  *  executable without including the source code for KADMOS in the  *
0019  *  source distribution.                        *
0020  *                                  *
0021  *  This program is distributed in the hope that it will be useful, *
0022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *
0023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *
0024  *  GNU General Public License for more details.            *
0025  *                                  *
0026  *  You should have received a copy of the GNU General Public       *
0027  *  License along with this program;  see the file COPYING.  If     *
0028  *  not, see <http://www.gnu.org/licenses/>.                *
0029  *                                  *
0030  ************************************************************************/
0031 
0032 #include "kookaprint.h"
0033 
0034 #include <math.h>
0035 
0036 #include <qpainter.h>
0037 #include <qfontmetrics.h>
0038 #include <qguiapplication.h>
0039 
0040 #include <klocalizedstring.h>
0041 
0042 #include "scanimage.h"
0043 
0044 #include "imgprintdialog.h"
0045 #include "kookasettings.h"
0046 #include "kscandevice.h"
0047 #include "kooka_logging.h"
0048 
0049 
0050 #define CUT_MARGIN      5           // margin in millimetres
0051 
0052 #define PRINT_ORDER_COLUMNS
0053 #define CUTMARKS_COLOURSEGS
0054 
0055 
0056 KookaPrint::KookaPrint()
0057     : QPrinter(QPrinter::HighResolution)
0058 {
0059     qCDebug(KOOKA_LOG);
0060     m_image = nullptr;
0061 
0062     // Initial default print parameters
0063     m_scaleOption = static_cast<KookaPrint::ScaleOption>(KookaSettings::printScaleOption());
0064     m_printSize = KookaSettings::printPrintSize();
0065     m_maintainAspect = KookaSettings::printMaintainAspect();
0066     m_lowResDraft = KookaSettings::printLowResDraft();
0067     m_cutsOption = static_cast<KookaPrint::CutMarksOption>(KookaSettings::printCutsOption());
0068 
0069     setOutputFileName(KookaSettings::printFileName());
0070 
0071     m_screenResolution = -1;                // set by caller
0072     m_scanResolution = -1;              // taken from image
0073     m_copyMode = false;                 // normal print mode
0074 }
0075 
0076 
0077 void KookaPrint::recalculatePrintParameters()
0078 {
0079     if (m_image==nullptr) return;               // no image to print
0080 
0081     qCDebug(KOOKA_LOG) << "image:";
0082     qCDebug(KOOKA_LOG) << "  size (pix) =" << m_image->size();
0083     qCDebug(KOOKA_LOG) << "  dpi X =" << DPM_TO_DPI(m_image->dotsPerMeterX());
0084     qCDebug(KOOKA_LOG) << "  dpi Y =" << DPM_TO_DPI(m_image->dotsPerMeterY());
0085     qCDebug(KOOKA_LOG) << "printer:";
0086     qCDebug(KOOKA_LOG) << "  name =" << printerName();
0087     qCDebug(KOOKA_LOG) << "  colour mode =" << colorMode();
0088     qCDebug(KOOKA_LOG) << "  full page?" << fullPage();
0089     qCDebug(KOOKA_LOG) << "  output format =" << outputFormat();
0090     qCDebug(KOOKA_LOG) << "  paper rect (mm) =" << paperRect(QPrinter::Millimeter);
0091     qCDebug(KOOKA_LOG) << "  page rect (mm) =" << pageRect(QPrinter::Millimeter);
0092     qCDebug(KOOKA_LOG) << "  resolution =" << resolution();
0093     qCDebug(KOOKA_LOG) << "options:";
0094     qCDebug(KOOKA_LOG) << "  scale mode =" << m_scaleOption;
0095     qCDebug(KOOKA_LOG) << "  print size (mm) =" << m_printSize;
0096     qCDebug(KOOKA_LOG) << "  scan resolution =" << m_scanResolution;
0097     qCDebug(KOOKA_LOG) << "  screen resolution =" << m_screenResolution;
0098     qCDebug(KOOKA_LOG) << "  cuts option =" << m_cutsOption;
0099     qCDebug(KOOKA_LOG) << "  maintain aspect?" << m_maintainAspect;
0100     qCDebug(KOOKA_LOG) << "  low res draft?" << m_lowResDraft;
0101 
0102     // Calculate the available page size, in real world units
0103     QRectF r = pageRect(QPrinter::Millimeter);
0104     mPageWidthMm = r.width();
0105     mPageHeightMm = r.height();
0106 
0107     // Calculate the size at which the image is to be printed,
0108     // depending on the scaling option.
0109 
0110     mImageWidthPix = m_image->width();          // image size in pixels
0111     mImageHeightPix = m_image->height();
0112 
0113     if (m_scaleOption==KookaPrint::ScaleScan)       // Original scan size
0114     {
0115         const int imageRes = m_scanResolution!=-1 ? DPI_TO_DPM(m_scanResolution) : m_image->dotsPerMeterX();
0116     Q_ASSERT(imageRes>0);               // dots per metre
0117         mPrintWidthMm = double(mImageWidthPix)/imageRes*1000;
0118         mPrintHeightMm = double(mImageHeightPix)/imageRes*1000;
0119     }
0120     else if (m_scaleOption==KookaPrint::ScaleScreen)    // Scale to screen resolution
0121     {
0122         int screenRes = DPI_TO_DPM(m_screenResolution);
0123         Q_ASSERT(screenRes>0);              // dots per metre
0124         mPrintWidthMm = double(mImageWidthPix)/screenRes*1000;
0125         mPrintHeightMm = double(mImageHeightPix)/screenRes*1000;
0126     }
0127     else if (m_scaleOption==KookaPrint::ScaleCustom)    // Custom size
0128     {
0129         // For this option, "Maintain aspect ratio" can be enabled in the GUI.
0130         // There is however no need to take account of it here, because the
0131         // values are already scaled/adjusted there.
0132 
0133         mPrintWidthMm = double(m_printSize.width());
0134         mPrintHeightMm = double(m_printSize.height());
0135         Q_ASSERT(mPrintWidthMm>0 && mPrintHeightMm>0);
0136     }
0137     else if (m_scaleOption==KookaPrint::ScaleFitPage)   // Fit to one page
0138     {
0139         mPrintWidthMm = mPageWidthMm;
0140         mPrintHeightMm = mPageHeightMm;
0141 
0142         // If cut marks are being "always" shown, then reduce the printed
0143         // image size here to account for them.  For the other cut marks
0144         // options, the image for this scale will by definition fit on one page
0145         // and so they will not be shown.
0146 
0147         if (m_cutsOption==KookaPrint::CutMarksAlways)
0148         {
0149             mPrintWidthMm -= 2*CUT_MARGIN;
0150             mPrintHeightMm -= 2*CUT_MARGIN;
0151         }
0152 
0153         if (m_maintainAspect)               // maintain the aspect ratio
0154         {
0155             QRectF r = pageRect(QPrinter::DevicePixel);
0156             double wAspect = r.width()/mImageWidthPix;  // scaling ratio image -> page
0157             double hAspect = r.height()/mImageHeightPix;
0158 
0159             if (wAspect>hAspect)
0160             {
0161                 // More scaling up is needed in the horizontal direction,
0162                 // so reduce that to maintain the aspect ratio
0163                 mPrintWidthMm *= hAspect/wAspect;
0164             }
0165             else if (hAspect>wAspect)
0166             {
0167                 // More scaling up is needed in the vertical direction,
0168                 // so reduce that to maintain the aspect ratio
0169                 mPrintHeightMm *= wAspect/hAspect;
0170             }
0171         }
0172     }
0173     else Q_ASSERT(false);
0174 
0175     qCDebug(KOOKA_LOG) << "scaled image size (mm) =" << QSizeF(mPrintWidthMm, mPrintHeightMm);
0176 
0177     mPrintResolution = DPI_TO_DPM(resolution())/1000;   // dots per millimetre
0178 
0179     // Now that we have the image size to be printed,
0180     // see if cut marks are required.
0181 
0182     mPageWidthAdjustedMm = mPageWidthMm;
0183     mPageHeightAdjustedMm = mPageHeightMm;
0184 
0185     bool withCutMarks;
0186     if (m_cutsOption==KookaPrint::CutMarksMultiple) withCutMarks = !(mPrintWidthMm<=mPageWidthMm && mPrintHeightMm<=mPageHeightMm);
0187     else if (m_cutsOption==KookaPrint::CutMarksAlways) withCutMarks = true;
0188     else if (m_cutsOption==KookaPrint::CutMarksNone) withCutMarks = false;
0189     else Q_ASSERT(false);
0190     qCDebug(KOOKA_LOG) << "for cuts" << m_cutsOption << "with marks?" << withCutMarks;
0191 
0192     // If cut marks are required, reduce the available page size
0193     // to allow for them.
0194 
0195     mPrintLeftPix = 0;                  // page origin of print
0196     mPrintTopPix = 0;
0197 
0198     if (withCutMarks)
0199     {
0200         mPageWidthAdjustedMm -= 2*CUT_MARGIN;
0201         mPageHeightAdjustedMm -= 2*CUT_MARGIN;
0202         qCDebug(KOOKA_LOG) << "adjusted page size (mm) =" << QSizeF(mPageWidthAdjustedMm, mPageHeightAdjustedMm);
0203 
0204         mPrintLeftPix = mPrintTopPix = CUT_MARGIN*mPrintResolution;
0205     }
0206 
0207     bool onOnePage = (mPrintWidthMm<=mPageWidthAdjustedMm && mPrintHeightMm<=mPageHeightAdjustedMm);
0208     qCDebug(KOOKA_LOG) << "on one page?" << onOnePage;  // see if fits on one page
0209                             // must be true for this
0210     if (m_scaleOption==KookaPrint::ScaleFitPage) Q_ASSERT(onOnePage);
0211 
0212     // If the image fits on one page, then adjust the print margins so
0213     // that it is centered.  I'm not sure whether this is the right thing
0214     // to do, but it is implied by tool tips set in ImgPrintDialog.
0215     // TODO: maybe make it an option
0216 
0217     if (onOnePage)
0218     {
0219         int widthSpareMm = mPageWidthAdjustedMm-mPrintWidthMm;
0220         mPrintLeftPix += (widthSpareMm/2)*mPrintResolution;
0221         int heightSpareMm = mPageHeightAdjustedMm-mPrintHeightMm;
0222         mPrintTopPix += (heightSpareMm/2)*mPrintResolution;
0223     }
0224 
0225     // Calculate how many parts (including partial parts)
0226     // the image needs to be sliced up into.
0227 
0228     double ipart;
0229     double fpart = modf(mPrintWidthMm/mPageWidthAdjustedMm, &ipart);
0230     //qCDebug(KOOKA_LOG) << "for cols ipart" << ipart << "fpart" << fpart;
0231     mPrintColumns = qRound(ipart)+(fpart>0 ? 1 : 0);
0232     fpart = modf(mPrintHeightMm/mPageHeightAdjustedMm, &ipart);
0233     //qCDebug(KOOKA_LOG) << "for rows ipart" << ipart << "fpart" << fpart;
0234     mPrintRows = qRound(ipart)+(fpart>0 ? 1 : 0);
0235 
0236     int totalPages = mPrintColumns*mPrintRows;
0237     qCDebug(KOOKA_LOG) << "print cols" << mPrintColumns << "rows" << mPrintRows << "pages" << totalPages;
0238     Q_ASSERT(totalPages>0);             // checks for sanity
0239     if (onOnePage) Q_ASSERT(totalPages==1);
0240 
0241     qCDebug(KOOKA_LOG) << "done";
0242 }
0243 
0244 
0245 void KookaPrint::printImage()
0246 {
0247     if (m_image==nullptr) return;           // no image to print
0248     qCDebug(KOOKA_LOG) << "starting";
0249     QGuiApplication::setOverrideCursor(Qt::WaitCursor); // this may take some time
0250 
0251     if (!m_copyMode)
0252     {
0253         // Save the print parameters used
0254         KookaSettings::setPrintScaleOption(m_scaleOption);
0255         KookaSettings::setPrintPrintSize(m_printSize);
0256         KookaSettings::setPrintMaintainAspect(m_maintainAspect);
0257         KookaSettings::setPrintLowResDraft(m_lowResDraft);
0258         KookaSettings::setPrintCutsOption(m_cutsOption);
0259         KookaSettings::setPrintFileName(outputFileName());
0260         KookaSettings::self()->save();
0261     }
0262     else qCDebug(KOOKA_LOG) << "copy mode, not saving print parameters";
0263 
0264 #if 1
0265     // TODO: does this work?
0266     if (m_lowResDraft) setResolution(75);
0267 #endif
0268 
0269     // Create the painter after all the print parameters have been set.
0270     QPainter painter(this);
0271     painter.setRenderHint(QPainter::SmoothPixmapTransform);
0272 
0273     // The image is to be printed as 'mPrintColumns' columns in 'mPrintRows'
0274     // rows. Each whole slice is 'sliceWidthPix' pixels wide and 'sliceHeightPix'
0275     // pixels high;  the last slice in each row and column may be smaller.
0276 
0277     int sliceWidthPix = qRound(mImageWidthPix*mPageWidthAdjustedMm/mPrintWidthMm);
0278     int sliceHeightPix = qRound(mImageHeightPix*mPageHeightAdjustedMm/mPrintHeightMm);
0279     qCDebug(KOOKA_LOG) << "slice size =" << QSize(sliceWidthPix, sliceHeightPix);
0280 
0281     // Print columns and rows in this order, so that in the usual printer
0282     // and alignment case the sheets line up corresponding with the columns.
0283 
0284     const int totalPages = mPrintColumns*mPrintRows;
0285     int page = 1;
0286 #ifdef PRINT_ORDER_COLUMNS
0287     for (int col = 0; col<mPrintColumns; ++col)
0288 #else
0289     for (int row = 0; row<mPrintRows; ++row)
0290 #endif
0291     {
0292 #ifdef PRINT_ORDER_COLUMNS
0293         for (int row = 0; row<mPrintRows; ++row)
0294 #else
0295         for (int col = 0; col<mPrintColumns; ++col)
0296 #endif
0297         {
0298             qCDebug(KOOKA_LOG) << "print page" << page << "col" << col << "row" << row;
0299 
0300             // The slice starts at 'sliceLeftPix' and 'sliceTopPix' in the image.
0301             int sliceLeftPix = col*sliceWidthPix;
0302             int sliceTopPix = row*sliceHeightPix;
0303 
0304             // Calculate the source rectangle within the image
0305             int thisWidthPix = qMin(sliceWidthPix, (mImageWidthPix-sliceLeftPix));
0306             int thisHeightPix = qMin(sliceHeightPix, (mImageHeightPix-sliceTopPix));
0307             const QRect sourceRect(sliceLeftPix, sliceTopPix, thisWidthPix, thisHeightPix);
0308 
0309             // Calculate the target rectangle on the painter
0310             int targetWidthPix = qRound((mPageWidthAdjustedMm*mPrintResolution)*(double(thisWidthPix)/sliceWidthPix));
0311             int targetHeightPix = qRound((mPageHeightAdjustedMm*mPrintResolution)*(double(thisHeightPix)/sliceHeightPix));
0312             const QRect targetRect(mPrintLeftPix, mPrintTopPix, targetWidthPix, targetHeightPix);
0313 
0314             qCDebug(KOOKA_LOG) << " " << sourceRect << "->" << targetRect;
0315             // The markers are drawn first so that the image will overwrite them.
0316             drawCornerMarkers(&painter, targetRect, row, col, mPrintRows, mPrintColumns);
0317             // Then the image rectangle.
0318             painter.drawImage(targetRect, *m_image, sourceRect);
0319 
0320             ++page;
0321             if (page<=totalPages) newPage();        // not for the last page
0322         }
0323     }
0324 
0325     QGuiApplication::restoreOverrideCursor();
0326     qCDebug(KOOKA_LOG) << "done";
0327 }
0328 
0329 
0330 // Draw a cross marker centered on that corner of the printed image.
0331 void KookaPrint::drawMarkerAroundPoint(QPainter *painter, const QPoint &p)
0332 {
0333     const int len = (CUT_MARGIN-1)*mPrintResolution;    // length in device pixels
0334 
0335     painter->save();
0336     painter->setPen(QPen(QBrush(Qt::black), 0));    // cosmetic pen width
0337     painter->drawLine(p-QPoint(len, 0), p+QPoint(len, 0));
0338     painter->drawLine(p-QPoint(0, len), p+QPoint(0, len));
0339     painter->restore();
0340 }
0341 
0342 
0343 void KookaPrint::drawCutSign(QPainter *painter, const QPoint &p, int num, Qt::Corner dir)
0344 {
0345     painter->save();
0346     int start = 0;
0347     const int radius = (CUT_MARGIN-2)*mPrintResolution; // offset in device pixels
0348 
0349     QColor brushColor(Qt::red);
0350     int toffX = 0;
0351     int toffY = 0;
0352     QString numStr = QString::number(num);
0353 
0354     QFontMetrics fm = painter->fontMetrics();
0355     int textWidth = fm.horizontalAdvance(numStr)/2;
0356     int textHeight = fm.height()/2;
0357     int textYOff = 0;
0358     int textXOff = 0;
0359     switch (dir) {
0360     case Qt::BottomLeftCorner:
0361         start = -90;
0362         brushColor = Qt::green;
0363         toffX = -1;
0364         toffY = 1;
0365         textXOff = -1 * textWidth;
0366         textYOff = textHeight;
0367         break;
0368     case Qt::TopLeftCorner:
0369         start = -180;
0370         brushColor = Qt::blue;
0371         toffX = -1;
0372         toffY = -1;
0373         textXOff = -1 * textWidth;
0374         textYOff = textHeight;
0375         break;
0376     case Qt::TopRightCorner:
0377         start = -270;
0378         brushColor = Qt::yellow;
0379         toffX = 1;
0380         toffY = -1;
0381         textXOff = -1 * textWidth;
0382         textYOff = textHeight;
0383         break;
0384     case Qt::BottomRightCorner:
0385         start = 0;
0386         brushColor = Qt::magenta;
0387         toffX = 1;
0388         toffY = 1;
0389         textXOff = -1 * textWidth;
0390         textYOff = textHeight;
0391         break;
0392     default:
0393         start = 0;
0394     }
0395 
0396     /* to draw around the point p, subtraction of the half radius is needed */
0397     int x = p.x() - radius / 2;
0398     int y = p.y() - radius / 2;
0399 
0400     // painter->drawRect( x, y, radius, radius );  /* debug !!! */
0401     const int tAway = radius * 3 / 4;
0402 
0403     int textX = p.x() + tAway * toffX + textXOff;
0404     int textY = p.y() + tAway * toffY + textYOff;
0405 
0406     //painter->drawRect( textX, textY, bRect.width(), bRect.height() );
0407     painter->drawText(textX, textY, numStr);
0408 
0409 #ifdef CUTMARKS_COLOURSEGS
0410     QBrush b(brushColor);               // draw a colour segment
0411     painter->setBrush(b);               // to show correct orientation
0412     painter->drawPie(x, y, radius, radius, start*16, -90*16);
0413 #endif
0414 
0415     painter->restore();
0416 }
0417 
0418 
0419 // Draw the circle and the numbers that indicate the adjacent pages
0420 void KookaPrint::drawCornerMarkers(QPainter *painter, const QRect &targetRect,
0421                                    int row, int col, int maxRows, int maxCols)
0422 {
0423     const bool multiPages = (maxRows>1 || maxCols>1);
0424 
0425     const bool firstColumn = (col==0);
0426     const bool lastColumn = (col==(maxCols-1));
0427     const bool firstRow = (row==0);
0428     const bool lastRow = (row==(maxRows-1));
0429 
0430 #ifdef PRINT_ORDER_COLUMNS
0431     const int indx = maxRows*col + row + 1;
0432 #else
0433     const int indx = maxCols*row + col + 1;
0434 #endif
0435     //qCDebug(KOOKA_LOG) << "for col" << col << "/" << maxCols << "row" << row << "/" << maxRows << "-> index" << indx;
0436 
0437     // All the measurements here are derived from 'targetRect',
0438     // which is in device pixels.
0439 
0440     // Page index, if required
0441     if (multiPages)
0442     {
0443         const QString numStr = QString("= %1 =").arg(indx);
0444         const QFontMetrics &fm = painter->fontMetrics();
0445         const int xoff = targetRect.left()+((targetRect.width()-fm.horizontalAdvance(numStr))/2);
0446 
0447         painter->setPen(Qt::black);
0448         painter->drawText(xoff, fm.height()-1, numStr);
0449     }
0450 
0451     // Top left
0452     QPoint p = targetRect.topLeft();
0453     drawMarkerAroundPoint(painter, p);
0454     if (multiPages)
0455     {
0456 #ifdef PRINT_ORDER_COLUMNS
0457         if (!firstColumn) drawCutSign(painter, p, indx - maxRows, Qt::BottomLeftCorner);
0458         if (!firstRow) drawCutSign(painter, p, indx - 1, Qt::TopRightCorner);
0459         if (!firstColumn && !firstRow) drawCutSign(painter, p, indx - maxRows - 1, Qt::TopLeftCorner);
0460 #else
0461         if (!firstColumn) drawCutSign(painter, p, indx - 1, Qt::BottomLeftCorner);
0462         if (!firstRow) drawCutSign(painter, p, indx - maxCols, Qt::TopRightCorner);
0463         if (!firstColumn && !firstRow) drawCutSign(painter, p, indx - maxCols - 1, Qt::TopLeftCorner);
0464 #endif
0465     }
0466 
0467     // Top right
0468     p = targetRect.topRight();
0469     drawMarkerAroundPoint(painter, p);
0470     if (multiPages)
0471     {
0472 #ifdef PRINT_ORDER_COLUMNS
0473         if (!lastColumn) drawCutSign(painter, p, indx + maxRows, Qt::BottomRightCorner);
0474         if (!firstRow) drawCutSign(painter, p, indx - 1, Qt::TopLeftCorner);
0475         if (!lastColumn && !firstRow) drawCutSign(painter, p, indx + maxRows - 1, Qt::TopRightCorner);
0476 #else
0477         if (!lastColumn) drawCutSign(painter, p, indx + 1, Qt::BottomRightCorner);
0478         if (!firstRow) drawCutSign(painter, p, indx - maxCols, Qt::TopLeftCorner);
0479         if (!lastColumn && !firstRow) drawCutSign(painter, p, indx - maxCols + 1, Qt::TopRightCorner);
0480 #endif
0481     }
0482 
0483     // Bottom right
0484     p = targetRect.bottomRight();
0485     drawMarkerAroundPoint(painter, p);
0486     if (multiPages)
0487     {
0488 #ifdef PRINT_ORDER_COLUMNS
0489         if (!lastColumn) drawCutSign(painter, p, indx + maxRows, Qt::TopRightCorner);
0490         if (!lastRow) drawCutSign(painter, p, indx + 1, Qt::BottomLeftCorner);
0491         if (!lastColumn && !lastRow) drawCutSign(painter, p, indx + maxRows + 1, Qt::BottomRightCorner);
0492 #else
0493         if (!lastColumn) drawCutSign(painter, p, indx + 1, Qt::TopRightCorner);
0494         if (!lastRow) drawCutSign(painter, p, indx + maxCols, Qt::BottomLeftCorner);
0495         if (!lastColumn && !lastRow) drawCutSign(painter, p, indx + maxCols + 1, Qt::BottomRightCorner);
0496 #endif
0497     }
0498 
0499     // Bottom left
0500     p = targetRect.bottomLeft();
0501     drawMarkerAroundPoint(painter, p);
0502     if (multiPages)
0503     {
0504 #ifdef PRINT_ORDER_COLUMNS
0505         if (!firstColumn) drawCutSign(painter, p, indx - maxRows, Qt::TopLeftCorner);
0506         if (!lastRow) drawCutSign(painter, p, indx + 1, Qt::BottomRightCorner);
0507         if (!firstColumn && !lastRow) drawCutSign(painter, p, indx - maxRows + 1, Qt::BottomLeftCorner);
0508 #else
0509         if (!firstColumn) drawCutSign(painter, p, indx - 1, Qt::TopLeftCorner);
0510         if (!lastRow) drawCutSign(painter, p, indx + maxCols, Qt::BottomRightCorner);
0511         if (!firstColumn && !lastRow) drawCutSign(painter, p, indx + maxCols - 1, Qt::BottomLeftCorner);
0512 #endif
0513     }
0514 }
0515 
0516 
0517 void KookaPrint::setCopyMode(bool on)
0518 {
0519     qCDebug(KOOKA_LOG) << on;
0520     m_copyMode = on;
0521 }