3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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>
36 #include <kapplication.h>
38 #include <kconfiggroup.h>
42 #include <kselectaction.h>
43 #include <kstandardaction.h>
44 #include <ktoggleaction.h>
45 #include <kactioncollection.h>
48 #include <kpDocument.h>
49 #include <kpThumbnail.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>
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 ()));
96 void kpMainWindow::enableViewMenuThumbnailDocumentActions (bool enable
)
98 d
->actionShowThumbnail
->setEnabled (enable
);
99 enableThumbnailOptionActions (enable
);
103 void kpMainWindow::slotDestroyThumbnail ()
105 #if DEBUG_KP_MAIN_WINDOW
106 kDebug () << "kpMainWindow::slotDestroyThumbnail()";
109 d
->actionShowThumbnail
->setChecked (false);
110 enableThumbnailOptionActions (false);
115 void kpMainWindow::slotDestroyThumbnailInitatedByUser ()
117 #if DEBUG_KP_MAIN_WINDOW
118 kDebug () << "kpMainWindow::slotDestroyThumbnailInitiatedByUser()";
121 d
->actionShowThumbnail
->setChecked (false);
122 slotShowThumbnailToggled ();
126 void kpMainWindow::slotCreateThumbnail ()
128 #if DEBUG_KP_MAIN_WINDOW
129 kDebug () << "kpMainWindow::slotCreateThumbnail()";
132 d
->actionShowThumbnail
->setChecked (true);
133 enableThumbnailOptionActions (true);
138 void kpMainWindow::notifyThumbnailGeometryChanged ()
140 #if DEBUG_KP_MAIN_WINDOW
141 kDebug () << "kpMainWindow::notifyThumbnailGeometryChanged()";
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 ()));
153 d
->thumbnailSaveConfigTimer
->start (500/*msec*/);
157 void kpMainWindow::slotSaveThumbnailGeometry ()
159 #if DEBUG_KP_MAIN_WINDOW
160 kDebug () << "kpMainWindow::saveThumbnailGeometry()";
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
;
172 d
->configThumbnailGeometry
= mapFromGlobal (rect
);
174 #if DEBUG_KP_MAIN_WINDOW
175 kDebug () << "\tCONFIG: saving thumbnail geometry "
176 << d
->configThumbnailGeometry
180 KConfigGroup
cfg (KGlobal::config (), kpSettingsGroupThumbnail
);
182 cfg
.writeEntry (kpSettingThumbnailGeometry
, d
->configThumbnailGeometry
);
187 void kpMainWindow::slotShowThumbnailToggled ()
189 #if DEBUG_KP_MAIN_WINDOW
190 kDebug () << "kpMainWindow::slotShowThumbnailToggled()";
193 d
->configThumbnailShown
= d
->actionShowThumbnail
->isChecked ();
195 KConfigGroup
cfg (KGlobal::config (), kpSettingsGroupThumbnail
);
197 cfg
.writeEntry (kpSettingThumbnailShown
, d
->configThumbnailShown
);
201 enableThumbnailOptionActions (d
->actionShowThumbnail
->isChecked ());
206 void kpMainWindow::updateThumbnailZoomed ()
208 #if DEBUG_KP_MAIN_WINDOW
209 kDebug () << "kpMainWindow::updateThumbnailZoomed() zoomed="
210 << d
->actionZoomedThumbnail
->isChecked () << endl
;
213 if (!d
->thumbnailView
)
216 destroyThumbnailView ();
217 createThumbnailView ();
221 void kpMainWindow::slotZoomedThumbnailToggled ()
223 #if DEBUG_KP_MAIN_WINDOW
224 kDebug () << "kpMainWindow::slotZoomedThumbnailToggled()";
227 d
->configZoomedThumbnail
= d
->actionZoomedThumbnail
->isChecked ();
229 KConfigGroup
cfg (KGlobal::config (), kpSettingsGroupThumbnail
);
231 cfg
.writeEntry (kpSettingThumbnailZoomed
, d
->configZoomedThumbnail
);
235 updateThumbnailZoomed ();
239 void kpMainWindow::slotThumbnailShowRectangleToggled ()
241 #if DEBUG_KP_MAIN_WINDOW
242 kDebug () << "kpMainWindow::slotThumbnailShowRectangleToggled()";
245 d
->configThumbnailShowRectangle
= d
->actionShowThumbnailRectangle
->isChecked ();
247 KConfigGroup
cfg (KGlobal::config (), kpSettingsGroupThumbnail
);
249 cfg
.writeEntry (kpSettingThumbnailShowRectangle
, d
->configThumbnailShowRectangle
);
253 if (d
->thumbnailView
)
255 d
->thumbnailView
->showBuddyViewScrollableContainerRectangle (
256 d
->actionShowThumbnailRectangle
->isChecked ());
261 void kpMainWindow::enableViewZoomedThumbnail (bool enable
)
263 #if DEBUG_KP_MAIN_WINDOW
264 kDebug () << "kpMainWindow::enableSettingsViewZoomedThumbnail()";
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
);
276 void kpMainWindow::enableViewShowThumbnailRectangle (bool enable
)
278 #if DEBUG_KP_MAIN_WINDOW
279 kDebug () << "kpMainWindow::enableViewShowThumbnailRectangle()";
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
);
292 void kpMainWindow::enableThumbnailOptionActions (bool enable
)
294 enableViewZoomedThumbnail (enable
);
295 enableViewShowThumbnailRectangle (enable
);
300 void kpMainWindow::createThumbnailView ()
302 #if DEBUG_KP_MAIN_WINDOW
303 kDebug () << "\t\tcreating new kpView:";
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
,
317 0/*scrollableContainer*/,
319 d
->thumbnailView
->setObjectName ("thumbnailView");
323 d
->thumbnailView
= new kpUnzoomedThumbnailView (
324 d
->document
, d
->toolToolBar
, d
->viewManager
,
326 0/*scrollableContainer*/,
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:";
339 d
->thumbnail
->setView (d
->thumbnailView
);
341 kError () << "kpMainWindow::createThumbnailView() no thumbnail" << endl
;
343 #if DEBUG_KP_MAIN_WINDOW
344 kDebug () << "\t\tregistering the kpView:";
347 d
->viewManager
->registerView (d
->thumbnailView
);
351 void kpMainWindow::destroyThumbnailView ()
353 if (!d
->thumbnailView
)
357 d
->viewManager
->unregisterView (d
->thumbnailView
);
360 d
->thumbnail
->setView (0);
362 d
->thumbnailView
->deleteLater (); d
->thumbnailView
= 0;
367 void kpMainWindow::updateThumbnail ()
369 #if DEBUG_KP_MAIN_WINDOW
370 kDebug () << "kpMainWindow::updateThumbnail()";
372 bool enable
= d
->actionShowThumbnail
->isChecked ();
374 #if DEBUG_KP_MAIN_WINDOW
375 kDebug () << "\tthumbnail="
376 << bool (d
->thumbnail
)
377 << " action_isChecked="
382 if (bool (d
->thumbnail
) == enable
)
387 #if DEBUG_KP_MAIN_WINDOW
388 kDebug () << "\tcreating thumbnail";
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
;
398 d
->thumbnail
= new kpThumbnail (this);
400 createThumbnailView ();
402 #if DEBUG_KP_MAIN_WINDOW
403 kDebug () << "\t\tmoving thumbnail to right place";
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 ());
416 const int margin
= 20;
417 const int initialWidth
= 160, initialHeight
= 120;
419 QRect
geometryRect (width () - initialWidth
- margin
* 2,
420 d
->scrollView
->y () + margin
,
424 #if DEBUG_KP_MAIN_WINDOW
425 kDebug () << "\t\tcreating geometry=" << geometryRect
;
428 geometryRect
= mapToGlobal (geometryRect
);
429 #if DEBUG_KP_MAIN_WINDOW
430 kDebug () << "\t\tmap to global=" << geometryRect
;
432 d
->thumbnail
->resize (geometryRect
.size ());
433 d
->thumbnail
->move (geometryRect
.topLeft ());
437 #if DEBUG_KP_MAIN_WINDOW
438 kDebug () << "\t\tshowing thumbnail";
440 d
->thumbnail
->show ();
442 #if DEBUG_KP_MAIN_WINDOW
443 kDebug () << "\t\tconnecting signal thumbnail::windowClosed to destroy slot";
445 connect (d
->thumbnail
, SIGNAL (windowClosed ()),
446 this, SLOT (slotDestroyThumbnailInitatedByUser ()));
447 #if DEBUG_KP_MAIN_WINDOW
448 kDebug () << "\t\tDONE";
453 #if DEBUG_KP_MAIN_WINDOW
454 kDebug () << "\tdestroying thumbnail d->thumbnail="
455 << d
->thumbnail
<< endl
;
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;