1 /*
2 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
3 Copyright (c) 2011 Martin Koller <kollix@aon.at>
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #define DEBUG_STATUS_BAR (DEBUG_KP_MAIN_WINDOW && 0)
29
30
31 #include "mainWindow/kpMainWindow.h"
32 #include "kpMainWindowPrivate.h"
33
34 #include <QLabel>
35 #include <QStatusBar>
36 #include <QString>
37
38 #include "kpLogCategories.h"
39 #include "kpDefs.h"
40 #include "document/kpDocument.h"
41 #include "tools/kpTool.h"
42 #include "views/manager/kpViewManager.h"
43 #include "kpViewScrollableContainer.h"
44 #include "views/kpZoomedView.h"
45
46 #include <KSqueezedTextLabel>
47 #include <KLocalizedString>
48
49 //---------------------------------------------------------------------
50
51 // private
addPermanentStatusBarItem(int id,int maxTextLen)52 void kpMainWindow::addPermanentStatusBarItem (int id, int maxTextLen)
53 {
54 QStatusBar *sb = statusBar ();
55
56 QLabel *label = new QLabel (sb);
57 label->setAlignment (Qt::AlignCenter);
58 label->setFixedHeight (label->fontMetrics ().height () + 2);
59 int maxWidth = label->fontMetrics().horizontalAdvance(QLatin1Char ('8')) * maxTextLen;
60 // add some margins
61 maxWidth += label->fontMetrics ().height ();
62 label->setFixedWidth (maxWidth);
63
64 // Permanent --> place on the right
65 sb->addPermanentWidget (label);
66
67 d->statusBarLabels.append (label);
68 Q_ASSERT (d->statusBarLabels.at(id) == label);
69 }
70
71 //---------------------------------------------------------------------
72
73 // private
createStatusBar()74 void kpMainWindow::createStatusBar ()
75 {
76 QStatusBar *sb = statusBar();
77
78 // 9999 pixels "ought to be enough for anybody"
79 const int maxDimenLength = 4;
80
81 d->statusBarMessageLabel = new KSqueezedTextLabel(sb);
82 // this is done to have the same height as the other labels in status bar; done like in kstatusbar.cpp
83 d->statusBarMessageLabel->setFixedHeight(d->statusBarMessageLabel->fontMetrics().height() + 2);
84 d->statusBarMessageLabel->setTextElideMode(Qt::ElideRight); // this is the reason why we explicitly set a widget
85 sb->addWidget(d->statusBarMessageLabel, 1/*stretch*/);
86
87 addPermanentStatusBarItem (StatusBarItemShapePoints,
88 (maxDimenLength + 1/*,*/ + maxDimenLength) * 2 + 3/* - */);
89 addPermanentStatusBarItem (StatusBarItemShapeSize,
90 (1/*+/-*/ + maxDimenLength) * 2 + 1/*x*/);
91
92 QString numSample = i18n("%1 x %2", 5000, 5000); // localized string; can e.g. be "5 000"
93 addPermanentStatusBarItem(StatusBarItemDocSize, numSample.length());
94
95 addPermanentStatusBarItem(StatusBarItemDocDepth, 5/*XXbpp*/);
96
97 addPermanentStatusBarItem (StatusBarItemZoom,
98 5/*1600%*/);
99
100 d->statusBarShapeLastPointsInitialised = false;
101 d->statusBarShapeLastSizeInitialised = false;
102 d->statusBarCreated = true;
103 }
104
105 //---------------------------------------------------------------------
106
107 // private slot
setStatusBarMessage(const QString & message)108 void kpMainWindow::setStatusBarMessage (const QString &message)
109 {
110 #if DEBUG_STATUS_BAR && 1
111 qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarMessage("
112 << message
113 << ") ok=" << d->statusBarCreated;
114 #endif
115
116 if (!d->statusBarCreated) {
117 return;
118 }
119
120 d->statusBarMessageLabel->setText (message);
121 }
122
123 //---------------------------------------------------------------------
124
125 // private slot
setStatusBarShapePoints(const QPoint & startPoint,const QPoint & endPoint)126 void kpMainWindow::setStatusBarShapePoints (const QPoint &startPoint,
127 const QPoint &endPoint)
128 {
129 #if DEBUG_STATUS_BAR && 0
130 qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarShapePoints("
131 << startPoint << "," << endPoint
132 << ") ok=" << d->statusBarCreated;
133 #endif
134
135 if (!d->statusBarCreated) {
136 return;
137 }
138
139 if (d->statusBarShapeLastPointsInitialised &&
140 startPoint == d->statusBarShapeLastStartPoint &&
141 endPoint == d->statusBarShapeLastEndPoint)
142 {
143 #if DEBUG_STATUS_BAR && 0
144 qCDebug(kpLogMainWindow) << "\tNOP";
145 #endif
146 return;
147 }
148
149 QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemShapePoints);
150 if (startPoint == KP_INVALID_POINT)
151 {
152 statusBarLabel->setText (QString());
153 }
154 else if (endPoint == KP_INVALID_POINT)
155 {
156 statusBarLabel->setText (i18n ("%1,%2",
157 startPoint.x (),
158 startPoint.y ()));
159 }
160 else
161 {
162 statusBarLabel->setText (i18n ("%1,%2 - %3,%4",
163 startPoint.x (),
164 startPoint.y (),
165 endPoint.x (),
166 endPoint.y ()));
167 }
168
169 d->statusBarShapeLastStartPoint = startPoint;
170 d->statusBarShapeLastEndPoint = endPoint;
171 d->statusBarShapeLastPointsInitialised = true;
172 }
173
174 //---------------------------------------------------------------------
175
176 // private slot
setStatusBarShapeSize(const QSize & size)177 void kpMainWindow::setStatusBarShapeSize (const QSize &size)
178 {
179 #if DEBUG_STATUS_BAR && 0
180 qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarShapeSize("
181 << size
182 << ") ok=" << d->statusBarCreated;
183 #endif
184
185 if (!d->statusBarCreated) {
186 return;
187 }
188
189 if (d->statusBarShapeLastSizeInitialised &&
190 size == d->statusBarShapeLastSize)
191 {
192 #if DEBUG_STATUS_BAR && 0
193 qCDebug(kpLogMainWindow) << "\tNOP";
194 #endif
195 return;
196 }
197
198 QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemShapeSize);
199 if (size == KP_INVALID_SIZE)
200 {
201 statusBarLabel->setText (QString());
202 }
203 else
204 {
205 statusBarLabel->setText (i18n ("%1x%2",
206 size.width (),
207 size.height ()));
208 }
209
210 d->statusBarShapeLastSize = size;
211 d->statusBarShapeLastSizeInitialised = true;
212 }
213
214 //---------------------------------------------------------------------
215
216 // private slot
setStatusBarDocSize(const QSize & size)217 void kpMainWindow::setStatusBarDocSize (const QSize &size)
218 {
219 #if DEBUG_STATUS_BAR && 0
220 qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarDocSize("
221 << size
222 << ") ok=" << d->statusBarCreated;
223 #endif
224
225 if (!d->statusBarCreated) {
226 return;
227 }
228
229 QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemDocSize);
230 if (size == KP_INVALID_SIZE)
231 {
232 statusBarLabel->setText (QString());
233 }
234 else
235 {
236 statusBarLabel->setText (i18n ("%1 x %2",
237 size.width (),
238 size.height ()));
239 }
240 }
241
242 //---------------------------------------------------------------------
243
244 // private slot
setStatusBarDocDepth(int depth)245 void kpMainWindow::setStatusBarDocDepth (int depth)
246 {
247 #if DEBUG_STATUS_BAR && 0
248 qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarDocDepth("
249 << depth
250 << ") ok=" << d->statusBarCreated;
251 #endif
252
253 if (!d->statusBarCreated) {
254 return;
255 }
256
257 QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemDocDepth);
258 if (depth <= 0)
259 {
260 statusBarLabel->setText (QString());
261 }
262 else
263 {
264 statusBarLabel->setText (i18n ("%1bpp", depth));
265 }
266 }
267
268 //---------------------------------------------------------------------
269
270 // private slot
setStatusBarZoom(int zoom)271 void kpMainWindow::setStatusBarZoom (int zoom)
272 {
273 #if DEBUG_STATUS_BAR && 0
274 qCDebug(kpLogMainWindow) << "kpMainWindow::setStatusBarZoom("
275 << zoom
276 << ") ok=" << d->statusBarCreated;
277 #endif
278
279 if (!d->statusBarCreated) {
280 return;
281 }
282
283 QLabel *statusBarLabel = d->statusBarLabels.at (StatusBarItemZoom);
284 if (zoom <= 0)
285 {
286 statusBarLabel->setText (QString());
287 }
288 else
289 {
290 statusBarLabel->setText (i18n ("%1%", zoom));
291 }
292 }
293
294 //---------------------------------------------------------------------
295
recalculateStatusBarMessage()296 void kpMainWindow::recalculateStatusBarMessage ()
297 {
298 #if DEBUG_STATUS_BAR && 1
299 qCDebug(kpLogMainWindow) << "kpMainWindow::recalculateStatusBarMessage()";
300 #endif
301 QString scrollViewMessage = d->scrollView->statusMessage ();
302 #if DEBUG_STATUS_BAR && 1
303 qCDebug(kpLogMainWindow) << "\tscrollViewMessage=" << scrollViewMessage;
304 qCDebug(kpLogMainWindow) << "\tresizing doc? " << !d->scrollView->newDocSize ().isEmpty ();
305 qCDebug(kpLogMainWindow) << "\tviewUnderCursor? "
306 << (d->viewManager && d->viewManager->viewUnderCursor ());
307 #endif
308
309 // HACK: To work around kpViewScrollableContainer's unreliable
310 // status messages (which in turn is due to Qt not updating
311 // QWidget::underMouse() on drags and we needing to hack around it)
312 if (!scrollViewMessage.isEmpty () &&
313 d->scrollView->newDocSize ().isEmpty () &&
314 d->viewManager && d->viewManager->viewUnderCursor ())
315 {
316 #if DEBUG_STATUS_BAR && 1
317 qCDebug(kpLogMainWindow) << "\t\tnot resizing & viewUnderCursor - message is wrong - clearing";
318 #endif
319 d->scrollView->blockSignals (true);
320 d->scrollView->clearStatusMessage ();
321 d->scrollView->blockSignals (false);
322
323 scrollViewMessage.clear ();
324 #if DEBUG_STATUS_BAR && 1
325 qCDebug(kpLogMainWindow) << "\t\t\tdone";
326 #endif
327 }
328
329 if (!scrollViewMessage.isEmpty ())
330 {
331 setStatusBarMessage (scrollViewMessage);
332 }
333 else
334 {
335 const kpTool *t = tool ();
336 if (t)
337 {
338 setStatusBarMessage (t->userMessage ());
339 }
340 else
341 {
342 setStatusBarMessage ();
343 }
344 }
345 }
346
347 //---------------------------------------------------------------------
348
349 // private slot
recalculateStatusBarShape()350 void kpMainWindow::recalculateStatusBarShape ()
351 {
352 #if DEBUG_STATUS_BAR && 0
353 qCDebug(kpLogMainWindow) << "kpMainWindow::recalculateStatusBarShape()";
354 #endif
355
356 QSize docResizeTo = d->scrollView->newDocSize ();
357 #if DEBUG_STATUS_BAR && 0
358 qCDebug(kpLogMainWindow) << "\tdocResizeTo=" << docResizeTo;
359 #endif
360 if (docResizeTo.isValid ())
361 {
362 const QPoint startPoint (d->document->width (), d->document->height ());
363 #if DEBUG_STATUS_BAR && 0
364 qCDebug(kpLogMainWindow) << "\thavedMovedFromOrgSize="
365 << d->scrollView->haveMovedFromOriginalDocSize ();
366 #endif
367 if (!d->scrollView->haveMovedFromOriginalDocSize ())
368 {
369 setStatusBarShapePoints (startPoint);
370 setStatusBarShapeSize ();
371 }
372 else
373 {
374 const int newWidth = docResizeTo.width ();
375 const int newHeight = docResizeTo.height ();
376
377 setStatusBarShapePoints (startPoint, QPoint (newWidth, newHeight));
378 const QPoint sizeAsPoint (QPoint (newWidth, newHeight) - startPoint);
379 setStatusBarShapeSize (QSize (sizeAsPoint.x (), sizeAsPoint.y ()));
380 }
381 }
382 else
383 {
384 const kpTool *t = tool ();
385 #if DEBUG_STATUS_BAR && 0
386 qCDebug(kpLogMainWindow) << "\ttool=" << t;
387 #endif
388 if (t)
389 {
390 setStatusBarShapePoints (t->userShapeStartPoint (),
391 t->userShapeEndPoint ());
392 setStatusBarShapeSize (t->userShapeSize ());
393 }
394 else
395 {
396 setStatusBarShapePoints ();
397 setStatusBarShapeSize ();
398 }
399 }
400 }
401
402 //---------------------------------------------------------------------
403
404 // private slot
recalculateStatusBar()405 void kpMainWindow::recalculateStatusBar ()
406 {
407 #if DEBUG_STATUS_BAR && 1
408 qCDebug(kpLogMainWindow) << "kpMainWindow::recalculateStatusBar() ok="
409 << d->statusBarCreated;
410 #endif
411
412 if (!d->statusBarCreated) {
413 return;
414 }
415
416 recalculateStatusBarMessage ();
417 recalculateStatusBarShape ();
418
419 if (d->document)
420 {
421 setStatusBarDocSize (QSize (d->document->width (), d->document->height ()));
422 setStatusBarDocDepth (d->document->image ().depth ());
423 }
424 else
425 {
426 setStatusBarDocSize ();
427 setStatusBarDocDepth ();
428 }
429
430 if (d->mainView)
431 {
432 setStatusBarZoom (d->mainView->zoomLevelX ());
433 }
434 else
435 {
436 setStatusBarZoom ();
437 }
438 }
439
440 //---------------------------------------------------------------------
441