File indexing completed on 2024-04-28 04:20:21

0001 /*
0002    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0003    Copyright (c) 2011 Martin Koller <kollix@aon.at>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 #define DEBUG_STATUS_BAR (DEBUG_KP_MAIN_WINDOW && 0)
0029 
0030 
0031 #include "mainWindow/kpMainWindow.h"
0032 #include "kpMainWindowPrivate.h"
0033 
0034 #include <QLabel>
0035 #include <QStatusBar>
0036 #include <QString>
0037 
0038 #include "kpLogCategories.h"
0039 #include "kpDefs.h"
0040 #include "document/kpDocument.h"
0041 #include "tools/kpTool.h"
0042 #include "views/manager/kpViewManager.h"
0043 #include "kpViewScrollableContainer.h"
0044 #include "views/kpZoomedView.h"
0045 
0046 #include <KSqueezedTextLabel>
0047 #include <KLocalizedString>
0048 
0049 //---------------------------------------------------------------------
0050 
0051 // private
0052 void kpMainWindow::addPermanentStatusBarItem (int id, int maxTextLen)
0053 {
0054     QStatusBar *sb = statusBar ();
0055 
0056     QLabel *label = new QLabel (sb);
0057     label->setAlignment (Qt::AlignCenter);
0058     label->setFixedHeight (label->fontMetrics ().height () + 2);
0059     int maxWidth = label->fontMetrics().horizontalAdvance(QLatin1Char ('8')) * maxTextLen;
0060     // add some margins
0061     maxWidth += label->fontMetrics ().height ();
0062     label->setFixedWidth (maxWidth);
0063 
0064     // Permanent --> place on the right
0065     sb->addPermanentWidget (label);
0066 
0067     d->statusBarLabels.append (label);
0068     Q_ASSERT (d->statusBarLabels.at(id) == label);
0069 }
0070 
0071 //---------------------------------------------------------------------
0072 
0073 // private
0074 void kpMainWindow::createStatusBar ()
0075 {
0076     QStatusBar *sb = statusBar();
0077 
0078     // 9999 pixels "ought to be enough for anybody"
0079     const int maxDimenLength = 4;
0080 
0081     d->statusBarMessageLabel = new KSqueezedTextLabel(sb);
0082     // this is done to have the same height as the other labels in status bar; done like in kstatusbar.cpp
0083     d->statusBarMessageLabel->setFixedHeight(d->statusBarMessageLabel->fontMetrics().height() + 2);
0084     d->statusBarMessageLabel->setTextElideMode(Qt::ElideRight);  // this is the reason why we explicitly set a widget
0085     sb->addWidget(d->statusBarMessageLabel, 1/*stretch*/);
0086 
0087     addPermanentStatusBarItem (StatusBarItemShapePoints,
0088                                (maxDimenLength + 1/*,*/ + maxDimenLength) * 2 + 3/* - */);
0089     addPermanentStatusBarItem (StatusBarItemShapeSize,
0090                                (1/*+/-*/ + maxDimenLength) * 2 + 1/*x*/);
0091 
0092     QString numSample = i18n("%1 x %2", 5000, 5000);  // localized string; can e.g. be "5 000"
0093     addPermanentStatusBarItem(StatusBarItemDocSize, numSample.length());
0094 
0095     addPermanentStatusBarItem(StatusBarItemDocDepth, 5/*XXbpp*/);
0096 
0097     addPermanentStatusBarItem (StatusBarItemZoom,
0098                                5/*1600%*/);
0099 
0100     d->statusBarShapeLastPointsInitialised = false;
0101     d->statusBarShapeLastSizeInitialised = false;
0102     d->statusBarCreated = true;
0103 }
0104 
0105 //---------------------------------------------------------------------
0106 
0107 // private slot
0108 void kpMainWindow::setStatusBarMessage (const QString &message)
0109 {
0110 #if DEBUG_STATUS_BAR && 1
0111     qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarMessage("
0112                << message
0113                << ") ok=" << d->statusBarCreated;
0114 #endif
0115 
0116     if (!d->statusBarCreated) {
0117         return;
0118     }
0119 
0120     d->statusBarMessageLabel->setText (message);
0121 }
0122 
0123 //---------------------------------------------------------------------
0124 
0125 // private slot
0126 void kpMainWindow::setStatusBarShapePoints (const QPoint &startPoint,
0127                                             const QPoint &endPoint)
0128 {
0129 #if DEBUG_STATUS_BAR && 0
0130     qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarShapePoints("
0131                << startPoint << "," << endPoint
0132                << ") ok=" << d->statusBarCreated;
0133 #endif
0134 
0135     if (!d->statusBarCreated) {
0136         return;
0137     }
0138 
0139     if (d->statusBarShapeLastPointsInitialised &&
0140         startPoint == d->statusBarShapeLastStartPoint &&
0141         endPoint == d->statusBarShapeLastEndPoint)
0142     {
0143     #if DEBUG_STATUS_BAR && 0
0144         qCDebug(kpLogMainWindow) << "\tNOP";
0145     #endif
0146         return;
0147     }
0148 
0149     QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemShapePoints);
0150     if (startPoint == KP_INVALID_POINT)
0151     {
0152         statusBarLabel->setText (QString());
0153     }
0154     else if (endPoint == KP_INVALID_POINT)
0155     {
0156         statusBarLabel->setText (i18n ("%1,%2",
0157                                       startPoint.x (),
0158                                       startPoint.y ()));
0159     }
0160     else
0161     {
0162         statusBarLabel->setText (i18n ("%1,%2 - %3,%4",
0163                                       startPoint.x (),
0164                                       startPoint.y (),
0165                                       endPoint.x (),
0166                                       endPoint.y ()));
0167     }
0168 
0169     d->statusBarShapeLastStartPoint = startPoint;
0170     d->statusBarShapeLastEndPoint = endPoint;
0171     d->statusBarShapeLastPointsInitialised = true;
0172 }
0173 
0174 //---------------------------------------------------------------------
0175 
0176 // private slot
0177 void kpMainWindow::setStatusBarShapeSize (const QSize &size)
0178 {
0179 #if DEBUG_STATUS_BAR && 0
0180     qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarShapeSize("
0181                << size
0182                << ") ok=" << d->statusBarCreated;
0183 #endif
0184 
0185     if (!d->statusBarCreated) {
0186         return;
0187     }
0188 
0189     if (d->statusBarShapeLastSizeInitialised &&
0190         size == d->statusBarShapeLastSize)
0191     {
0192     #if DEBUG_STATUS_BAR && 0
0193         qCDebug(kpLogMainWindow) << "\tNOP";
0194     #endif
0195         return;
0196     }
0197 
0198     QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemShapeSize);
0199     if (size == KP_INVALID_SIZE)
0200     {
0201         statusBarLabel->setText (QString());
0202     }
0203     else
0204     {
0205         statusBarLabel->setText (i18n ("%1x%2",
0206                                       size.width (),
0207                                       size.height ()));
0208     }
0209 
0210     d->statusBarShapeLastSize = size;
0211     d->statusBarShapeLastSizeInitialised = true;
0212 }
0213 
0214 //---------------------------------------------------------------------
0215 
0216 // private slot
0217 void kpMainWindow::setStatusBarDocSize (const QSize &size)
0218 {
0219 #if DEBUG_STATUS_BAR && 0
0220     qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarDocSize("
0221                << size
0222                << ") ok=" << d->statusBarCreated;
0223 #endif
0224 
0225     if (!d->statusBarCreated) {
0226         return;
0227     }
0228 
0229     QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemDocSize);
0230     if (size == KP_INVALID_SIZE)
0231     {
0232         statusBarLabel->setText (QString());
0233     }
0234     else
0235     {
0236         statusBarLabel->setText (i18n ("%1 x %2",
0237                                       size.width (),
0238                                       size.height ()));
0239     }
0240 }
0241 
0242 //---------------------------------------------------------------------
0243 
0244 // private slot
0245 void kpMainWindow::setStatusBarDocDepth (int depth)
0246 {
0247 #if DEBUG_STATUS_BAR && 0
0248     qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarDocDepth("
0249                << depth
0250                << ") ok=" << d->statusBarCreated;
0251 #endif
0252 
0253     if (!d->statusBarCreated) {
0254         return;
0255     }
0256 
0257     QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemDocDepth);
0258     if (depth <= 0)
0259     {
0260         statusBarLabel->setText (QString());
0261     }
0262     else
0263     {
0264         statusBarLabel->setText (i18n ("%1bpp", depth));
0265     }
0266 }
0267 
0268 //---------------------------------------------------------------------
0269 
0270 // private slot
0271 void kpMainWindow::setStatusBarZoom (int zoom)
0272 {
0273 #if DEBUG_STATUS_BAR && 0
0274     qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarZoom("
0275                << zoom
0276                << ") ok=" << d->statusBarCreated;
0277 #endif
0278 
0279     if (!d->statusBarCreated) {
0280         return;
0281     }
0282 
0283     QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemZoom);
0284     if (zoom <= 0)
0285     {
0286         statusBarLabel->setText (QString());
0287     }
0288     else
0289     {
0290         statusBarLabel->setText (i18n ("%1%", zoom));
0291     }
0292 }
0293 
0294 //---------------------------------------------------------------------
0295 
0296 void kpMainWindow::recalculateStatusBarMessage ()
0297 {
0298 #if DEBUG_STATUS_BAR && 1
0299     qCDebug(kpLogMainWindow) << "kpMainWindow::recalculateStatusBarMessage()";
0300 #endif
0301     QString scrollViewMessage = d->scrollView->statusMessage ();
0302 #if DEBUG_STATUS_BAR && 1
0303     qCDebug(kpLogMainWindow) << "\tscrollViewMessage=" << scrollViewMessage;
0304     qCDebug(kpLogMainWindow) << "\tresizing doc? " << !d->scrollView->newDocSize ().isEmpty ();
0305     qCDebug(kpLogMainWindow) << "\tviewUnderCursor? "
0306                << (d->viewManager && d->viewManager->viewUnderCursor ());
0307 #endif
0308 
0309     // HACK: To work around kpViewScrollableContainer's unreliable
0310     //       status messages (which in turn is due to Qt not updating
0311     //       QWidget::underMouse() on drags and we needing to hack around it)
0312     if (!scrollViewMessage.isEmpty () &&
0313         d->scrollView->newDocSize ().isEmpty () &&
0314         d->viewManager && d->viewManager->viewUnderCursor ())
0315     {
0316     #if DEBUG_STATUS_BAR && 1
0317         qCDebug(kpLogMainWindow) << "\t\tnot resizing & viewUnderCursor - message is wrong - clearing";
0318     #endif
0319         d->scrollView->blockSignals (true);
0320         d->scrollView->clearStatusMessage ();
0321         d->scrollView->blockSignals (false);
0322 
0323         scrollViewMessage.clear ();
0324     #if DEBUG_STATUS_BAR && 1
0325         qCDebug(kpLogMainWindow) << "\t\t\tdone";
0326     #endif
0327     }
0328 
0329     if (!scrollViewMessage.isEmpty ())
0330     {
0331         setStatusBarMessage (scrollViewMessage);
0332     }
0333     else
0334     {
0335         const kpTool *t = tool ();
0336         if (t)
0337         {
0338             setStatusBarMessage (t->userMessage ());
0339         }
0340         else
0341         {
0342             setStatusBarMessage ();
0343         }
0344     }
0345 }
0346 
0347 //---------------------------------------------------------------------
0348 
0349 // private slot
0350 void kpMainWindow::recalculateStatusBarShape ()
0351 {
0352 #if DEBUG_STATUS_BAR && 0
0353     qCDebug(kpLogMainWindow) << "kpMainWindow::recalculateStatusBarShape()";
0354 #endif
0355 
0356     QSize docResizeTo = d->scrollView->newDocSize ();
0357 #if DEBUG_STATUS_BAR && 0
0358     qCDebug(kpLogMainWindow) << "\tdocResizeTo=" << docResizeTo;
0359 #endif
0360     if (docResizeTo.isValid ())
0361     {
0362         const QPoint startPoint (d->document->width (), d->document->height ());
0363     #if DEBUG_STATUS_BAR && 0
0364         qCDebug(kpLogMainWindow) << "\thavedMovedFromOrgSize="
0365                    << d->scrollView->haveMovedFromOriginalDocSize ();
0366     #endif
0367         if (!d->scrollView->haveMovedFromOriginalDocSize ())
0368         {
0369             setStatusBarShapePoints (startPoint);
0370             setStatusBarShapeSize ();
0371         }
0372         else
0373         {
0374             const int newWidth = docResizeTo.width ();
0375             const int newHeight = docResizeTo.height ();
0376 
0377             setStatusBarShapePoints (startPoint, QPoint (newWidth, newHeight));
0378             const QPoint sizeAsPoint (QPoint (newWidth, newHeight) - startPoint);
0379             setStatusBarShapeSize (QSize (sizeAsPoint.x (), sizeAsPoint.y ()));
0380         }
0381     }
0382     else
0383     {
0384         const kpTool *t = tool ();
0385     #if DEBUG_STATUS_BAR && 0
0386         qCDebug(kpLogMainWindow) << "\ttool=" << t;
0387     #endif
0388         if (t)
0389         {
0390             setStatusBarShapePoints (t->userShapeStartPoint (),
0391                                      t->userShapeEndPoint ());
0392             setStatusBarShapeSize (t->userShapeSize ());
0393         }
0394         else
0395         {
0396             setStatusBarShapePoints ();
0397             setStatusBarShapeSize ();
0398         }
0399     }
0400 }
0401 
0402 //---------------------------------------------------------------------
0403 
0404 // private slot
0405 void kpMainWindow::recalculateStatusBar ()
0406 {
0407 #if DEBUG_STATUS_BAR && 1
0408     qCDebug(kpLogMainWindow) << "kpMainWindow::recalculateStatusBar() ok="
0409                << d->statusBarCreated;
0410 #endif
0411 
0412     if (!d->statusBarCreated) {
0413         return;
0414     }
0415 
0416     recalculateStatusBarMessage ();
0417     recalculateStatusBarShape ();
0418 
0419     if (d->document)
0420     {
0421         setStatusBarDocSize (QSize (d->document->width (), d->document->height ()));
0422         setStatusBarDocDepth (d->document->image ().depth ());
0423     }
0424     else
0425     {
0426         setStatusBarDocSize ();
0427         setStatusBarDocDepth ();
0428     }
0429 
0430     if (d->mainView)
0431     {
0432         setStatusBarZoom (d->mainView->zoomLevelX ());
0433     }
0434     else
0435     {
0436         setStatusBarZoom ();
0437     }
0438 }
0439 
0440 //---------------------------------------------------------------------