compile
[kdegraphics.git] / kolourpaint / mainWindow / kpMainWindow_View_Thumbnail.cpp
blobc69a76d9c67aaf54a7746d8af72705d68b0716ec
2 /*
3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
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.
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.
29 #include <kpMainWindow.h>
30 #include <kpMainWindowPrivate.h>
32 #include <qdatetime.h>
33 #include <qpainter.h>
34 #include <qtimer.h>
36 #include <kapplication.h>
37 #include <kconfig.h>
38 #include <kconfiggroup.h>
39 #include <kdebug.h>
40 #include <kglobal.h>
41 #include <klocale.h>
42 #include <kselectaction.h>
43 #include <kstandardaction.h>
44 #include <ktoggleaction.h>
45 #include <kactioncollection.h>
47 #include <kpDefs.h>
48 #include <kpDocument.h>
49 #include <kpThumbnail.h>
50 #include <kpTool.h>
51 #include <kpToolToolBar.h>
52 #include <kpUnzoomedThumbnailView.h>
53 #include <kpViewManager.h>
54 #include <kpViewScrollableContainer.h>
55 #include <kpWidgetMapper.h>
56 #include <kpZoomedView.h>
57 #include <kpZoomedThumbnailView.h>
60 // private
61 void kpMainWindow::setupViewMenuThumbnailActions ()
63 d->thumbnailSaveConfigTimer = 0;
65 KActionCollection *ac = actionCollection ();
68 d->actionShowThumbnail = ac->add <KToggleAction> ("view_show_thumbnail");
69 d->actionShowThumbnail->setText (i18n ("Show T&humbnail"));
70 // TODO: This doesn't work when the thumbnail has focus.
71 // Testcase: Press CTRL+H twice on a fresh KolourPaint.
72 // The second CTRL+H doesn't close the thumbnail.
73 d->actionShowThumbnail->setShortcut (Qt::CTRL + Qt::Key_H);
74 //d->actionShowThumbnail->setCheckedState (KGuiItem(i18n ("Hide T&humbnail")));
75 connect (d->actionShowThumbnail, SIGNAL (triggered (bool)),
76 SLOT (slotShowThumbnailToggled ()));
78 // Please do not use setCheckedState() here - it wouldn't make sense
79 d->actionZoomedThumbnail = ac->add <KToggleAction> ("view_zoomed_thumbnail");
80 d->actionZoomedThumbnail->setText (i18n ("Zoo&med Thumbnail Mode"));
81 connect (d->actionZoomedThumbnail, SIGNAL (triggered (bool)),
82 SLOT (slotZoomedThumbnailToggled ()));
84 // For consistency with the above action, don't use setCheckedState()
86 // Also, don't use "Show Thumbnail Rectangle" because if entire doc
87 // can be seen in scrollView, checking option won't "Show" anything
88 // since rect _surrounds_ entire doc (hence, won't be rendered).
89 d->actionShowThumbnailRectangle = ac->add <KToggleAction> ("view_show_thumbnail_rectangle");
90 d->actionShowThumbnailRectangle->setText (i18n ("Enable Thumbnail &Rectangle"));
91 connect (d->actionShowThumbnailRectangle, SIGNAL (triggered (bool)),
92 SLOT (slotThumbnailShowRectangleToggled ()));
95 // private
96 void kpMainWindow::enableViewMenuThumbnailDocumentActions (bool enable)
98 d->actionShowThumbnail->setEnabled (enable);
99 enableThumbnailOptionActions (enable);
102 // private slot
103 void kpMainWindow::slotDestroyThumbnail ()
105 #if DEBUG_KP_MAIN_WINDOW
106 kDebug () << "kpMainWindow::slotDestroyThumbnail()";
107 #endif
109 d->actionShowThumbnail->setChecked (false);
110 enableThumbnailOptionActions (false);
111 updateThumbnail ();
114 // private slot
115 void kpMainWindow::slotDestroyThumbnailInitatedByUser ()
117 #if DEBUG_KP_MAIN_WINDOW
118 kDebug () << "kpMainWindow::slotDestroyThumbnailInitiatedByUser()";
119 #endif
121 d->actionShowThumbnail->setChecked (false);
122 slotShowThumbnailToggled ();
125 // private slot
126 void kpMainWindow::slotCreateThumbnail ()
128 #if DEBUG_KP_MAIN_WINDOW
129 kDebug () << "kpMainWindow::slotCreateThumbnail()";
130 #endif
132 d->actionShowThumbnail->setChecked (true);
133 enableThumbnailOptionActions (true);
134 updateThumbnail ();
137 // public
138 void kpMainWindow::notifyThumbnailGeometryChanged ()
140 #if DEBUG_KP_MAIN_WINDOW
141 kDebug () << "kpMainWindow::notifyThumbnailGeometryChanged()";
142 #endif
144 if (!d->thumbnailSaveConfigTimer)
146 d->thumbnailSaveConfigTimer = new QTimer (this);
147 d->thumbnailSaveConfigTimer->setSingleShot (true);
148 connect (d->thumbnailSaveConfigTimer, SIGNAL (timeout ()),
149 this, SLOT (slotSaveThumbnailGeometry ()));
152 // (single shot)
153 d->thumbnailSaveConfigTimer->start (500/*msec*/);
156 // private slot
157 void kpMainWindow::slotSaveThumbnailGeometry ()
159 #if DEBUG_KP_MAIN_WINDOW
160 kDebug () << "kpMainWindow::saveThumbnailGeometry()";
161 #endif
163 if (!d->thumbnail)
164 return;
166 QRect rect (d->thumbnail->x (), d->thumbnail->y (),
167 d->thumbnail->width (), d->thumbnail->height ());
168 #if DEBUG_KP_MAIN_WINDOW
169 kDebug () << "\tthumbnail relative geometry=" << rect;
170 #endif
172 d->configThumbnailGeometry = mapFromGlobal (rect);
174 #if DEBUG_KP_MAIN_WINDOW
175 kDebug () << "\tCONFIG: saving thumbnail geometry "
176 << d->configThumbnailGeometry
177 << endl;
178 #endif
180 KConfigGroup cfg (KGlobal::config (), kpSettingsGroupThumbnail);
182 cfg.writeEntry (kpSettingThumbnailGeometry, d->configThumbnailGeometry);
183 cfg.sync ();
186 // private slot
187 void kpMainWindow::slotShowThumbnailToggled ()
189 #if DEBUG_KP_MAIN_WINDOW
190 kDebug () << "kpMainWindow::slotShowThumbnailToggled()";
191 #endif
193 d->configThumbnailShown = d->actionShowThumbnail->isChecked ();
195 KConfigGroup cfg (KGlobal::config (), kpSettingsGroupThumbnail);
197 cfg.writeEntry (kpSettingThumbnailShown, d->configThumbnailShown);
198 cfg.sync ();
201 enableThumbnailOptionActions (d->actionShowThumbnail->isChecked ());
202 updateThumbnail ();
205 // private slot
206 void kpMainWindow::updateThumbnailZoomed ()
208 #if DEBUG_KP_MAIN_WINDOW
209 kDebug () << "kpMainWindow::updateThumbnailZoomed() zoomed="
210 << d->actionZoomedThumbnail->isChecked () << endl;
211 #endif
213 if (!d->thumbnailView)
214 return;
216 destroyThumbnailView ();
217 createThumbnailView ();
220 // private slot
221 void kpMainWindow::slotZoomedThumbnailToggled ()
223 #if DEBUG_KP_MAIN_WINDOW
224 kDebug () << "kpMainWindow::slotZoomedThumbnailToggled()";
225 #endif
227 d->configZoomedThumbnail = d->actionZoomedThumbnail->isChecked ();
229 KConfigGroup cfg (KGlobal::config (), kpSettingsGroupThumbnail);
231 cfg.writeEntry (kpSettingThumbnailZoomed, d->configZoomedThumbnail);
232 cfg.sync ();
235 updateThumbnailZoomed ();
238 // private slot
239 void kpMainWindow::slotThumbnailShowRectangleToggled ()
241 #if DEBUG_KP_MAIN_WINDOW
242 kDebug () << "kpMainWindow::slotThumbnailShowRectangleToggled()";
243 #endif
245 d->configThumbnailShowRectangle = d->actionShowThumbnailRectangle->isChecked ();
247 KConfigGroup cfg (KGlobal::config (), kpSettingsGroupThumbnail);
249 cfg.writeEntry (kpSettingThumbnailShowRectangle, d->configThumbnailShowRectangle);
250 cfg.sync ();
253 if (d->thumbnailView)
255 d->thumbnailView->showBuddyViewScrollableContainerRectangle (
256 d->actionShowThumbnailRectangle->isChecked ());
260 // private
261 void kpMainWindow::enableViewZoomedThumbnail (bool enable)
263 #if DEBUG_KP_MAIN_WINDOW
264 kDebug () << "kpMainWindow::enableSettingsViewZoomedThumbnail()";
265 #endif
267 d->actionZoomedThumbnail->setEnabled (enable &&
268 d->actionShowThumbnail->isChecked ());
270 // Note: Don't uncheck if disabled - being able to see the zoomed state
271 // before turning on the thumbnail can be useful.
272 d->actionZoomedThumbnail->setChecked (d->configZoomedThumbnail);
275 // private
276 void kpMainWindow::enableViewShowThumbnailRectangle (bool enable)
278 #if DEBUG_KP_MAIN_WINDOW
279 kDebug () << "kpMainWindow::enableViewShowThumbnailRectangle()";
280 #endif
282 d->actionShowThumbnailRectangle->setEnabled (enable &&
283 d->actionShowThumbnail->isChecked ());
285 // Note: Don't uncheck if disabled for consistency with
286 // enableViewZoomedThumbnail()
287 d->actionShowThumbnailRectangle->setChecked (
288 d->configThumbnailShowRectangle);
291 // private
292 void kpMainWindow::enableThumbnailOptionActions (bool enable)
294 enableViewZoomedThumbnail (enable);
295 enableViewShowThumbnailRectangle (enable);
299 // private
300 void kpMainWindow::createThumbnailView ()
302 #if DEBUG_KP_MAIN_WINDOW
303 kDebug () << "\t\tcreating new kpView:";
304 #endif
306 if (d->thumbnailView)
308 kDebug () << "kpMainWindow::createThumbnailView() had to destroy view";
309 destroyThumbnailView ();
312 if (d->actionZoomedThumbnail->isChecked ())
314 d->thumbnailView = new kpZoomedThumbnailView (
315 d->document, d->toolToolBar, d->viewManager,
316 d->mainView,
317 0/*scrollableContainer*/,
318 d->thumbnail);
319 d->thumbnailView->setObjectName ("thumbnailView");
321 else
323 d->thumbnailView = new kpUnzoomedThumbnailView (
324 d->document, d->toolToolBar, d->viewManager,
325 d->mainView,
326 0/*scrollableContainer*/,
327 d->thumbnail);
328 d->thumbnailView->setObjectName ("thumbnailView");
331 d->thumbnailView->showBuddyViewScrollableContainerRectangle (
332 d->actionShowThumbnailRectangle->isChecked ());
335 #if DEBUG_KP_MAIN_WINDOW
336 kDebug () << "\t\tgive kpThumbnail the kpView:";
337 #endif
338 if (d->thumbnail)
339 d->thumbnail->setView (d->thumbnailView);
340 else
341 kError () << "kpMainWindow::createThumbnailView() no thumbnail" << endl;
343 #if DEBUG_KP_MAIN_WINDOW
344 kDebug () << "\t\tregistering the kpView:";
345 #endif
346 if (d->viewManager)
347 d->viewManager->registerView (d->thumbnailView);
350 // private
351 void kpMainWindow::destroyThumbnailView ()
353 if (!d->thumbnailView)
354 return;
356 if (d->viewManager)
357 d->viewManager->unregisterView (d->thumbnailView);
359 if (d->thumbnail)
360 d->thumbnail->setView (0);
362 d->thumbnailView->deleteLater (); d->thumbnailView = 0;
366 // private
367 void kpMainWindow::updateThumbnail ()
369 #if DEBUG_KP_MAIN_WINDOW
370 kDebug () << "kpMainWindow::updateThumbnail()";
371 #endif
372 bool enable = d->actionShowThumbnail->isChecked ();
374 #if DEBUG_KP_MAIN_WINDOW
375 kDebug () << "\tthumbnail="
376 << bool (d->thumbnail)
377 << " action_isChecked="
378 << enable
379 << endl;
380 #endif
382 if (bool (d->thumbnail) == enable)
383 return;
385 if (!d->thumbnail)
387 #if DEBUG_KP_MAIN_WINDOW
388 kDebug () << "\tcreating thumbnail";
389 #endif
391 // Read last saved geometry before creating thumbnail & friends
392 // in case they call notifyThumbnailGeometryChanged()
393 QRect thumbnailGeometry = d->configThumbnailGeometry;
394 #if DEBUG_KP_MAIN_WINDOW
395 kDebug () << "\t\tlast used geometry=" << thumbnailGeometry;
396 #endif
398 d->thumbnail = new kpThumbnail (this);
400 createThumbnailView ();
402 #if DEBUG_KP_MAIN_WINDOW
403 kDebug () << "\t\tmoving thumbnail to right place";
404 #endif
405 if (!thumbnailGeometry.isEmpty () &&
406 QRect (0, 0, width (), height ()).intersects (thumbnailGeometry))
408 const QRect geometry = mapToGlobal (thumbnailGeometry);
409 d->thumbnail->resize (geometry.size ());
410 d->thumbnail->move (geometry.topLeft ());
412 else
414 if (d->scrollView)
416 const int margin = 20;
417 const int initialWidth = 160, initialHeight = 120;
419 QRect geometryRect (width () - initialWidth - margin * 2,
420 d->scrollView->y () + margin,
421 initialWidth,
422 initialHeight);
424 #if DEBUG_KP_MAIN_WINDOW
425 kDebug () << "\t\tcreating geometry=" << geometryRect;
426 #endif
428 geometryRect = mapToGlobal (geometryRect);
429 #if DEBUG_KP_MAIN_WINDOW
430 kDebug () << "\t\tmap to global=" << geometryRect;
431 #endif
432 d->thumbnail->resize (geometryRect.size ());
433 d->thumbnail->move (geometryRect.topLeft ());
437 #if DEBUG_KP_MAIN_WINDOW
438 kDebug () << "\t\tshowing thumbnail";
439 #endif
440 d->thumbnail->show ();
442 #if DEBUG_KP_MAIN_WINDOW
443 kDebug () << "\t\tconnecting signal thumbnail::windowClosed to destroy slot";
444 #endif
445 connect (d->thumbnail, SIGNAL (windowClosed ()),
446 this, SLOT (slotDestroyThumbnailInitatedByUser ()));
447 #if DEBUG_KP_MAIN_WINDOW
448 kDebug () << "\t\tDONE";
449 #endif
451 else
453 #if DEBUG_KP_MAIN_WINDOW
454 kDebug () << "\tdestroying thumbnail d->thumbnail="
455 << d->thumbnail << endl;
456 #endif
458 if (d->thumbnailSaveConfigTimer && d->thumbnailSaveConfigTimer->isActive ())
460 d->thumbnailSaveConfigTimer->stop ();
461 slotSaveThumbnailGeometry ();
464 // Must be done before hiding the thumbnail to avoid triggering
465 // this signal - re-entering this code.
466 disconnect (d->thumbnail, SIGNAL (windowClosed ()),
467 this, SLOT (slotDestroyThumbnailInitatedByUser ()));
469 // Avoid change/flicker of caption due to view delete
470 // (destroyThumbnailView())
471 d->thumbnail->hide ();
473 destroyThumbnailView ();
475 d->thumbnail->deleteLater (); d->thumbnail = 0;