File indexing completed on 2025-03-09 03:58:46

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2004-11-22
0007  * Description : digiKam light table - Configure
0008  *
0009  * SPDX-FileCopyrightText: 2007-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "lighttablewindow_p.h"
0016 
0017 namespace Digikam
0018 {
0019 
0020 void LightTableWindow::setupActions()
0021 {
0022     // -- Standard 'File' menu actions ---------------------------------------------
0023 
0024     KActionCollection* const ac =   actionCollection();
0025 
0026     d->backwardAction = buildStdAction(StdBackAction, this, SLOT(slotBackward()), this);
0027     ac->addAction(QLatin1String("lighttable_backward"), d->backwardAction);
0028     ac->setDefaultShortcuts(d->backwardAction, QList<QKeySequence>() << Qt::Key_PageUp << Qt::Key_Backspace);
0029 
0030     d->forwardAction = buildStdAction(StdForwardAction, this, SLOT(slotForward()), this);
0031     ac->addAction(QLatin1String("lighttable_forward"), d->forwardAction);
0032     ac->setDefaultShortcuts(d->forwardAction, QList<QKeySequence>() << Qt::Key_PageDown << Qt::Key_Space);
0033     d->forwardAction->setEnabled(false);
0034 
0035     d->firstAction = new QAction(QIcon::fromTheme(QLatin1String("go-first")), i18nc("@action: go to first item on list", "&First"), this);
0036     d->firstAction->setEnabled(false);
0037     connect(d->firstAction, SIGNAL(triggered()), this, SLOT(slotFirst()));
0038     ac->addAction(QLatin1String("lighttable_first"), d->firstAction);
0039     ac->setDefaultShortcuts(d->firstAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_Home));
0040 
0041     d->lastAction = new QAction(QIcon::fromTheme(QLatin1String("go-last")), i18nc("@action: go to last item on list", "&Last"), this);
0042     d->lastAction->setEnabled(false);
0043     connect(d->lastAction, SIGNAL(triggered()), this, SLOT(slotLast()));
0044     ac->addAction(QLatin1String("lighttable_last"), d->lastAction);
0045     ac->setDefaultShortcuts(d->lastAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_End));
0046 
0047     d->setItemLeftAction = new QAction(QIcon::fromTheme(QLatin1String("arrow-left")), i18n("On left"), this);
0048     d->setItemLeftAction->setEnabled(false);
0049     d->setItemLeftAction->setWhatsThis(i18n("Show item on left panel"));
0050     connect(d->setItemLeftAction, SIGNAL(triggered()), this, SLOT(slotSetItemLeft()));
0051     ac->addAction(QLatin1String("lighttable_setitemleft"), d->setItemLeftAction);
0052     ac->setDefaultShortcut(d->setItemLeftAction, Qt::CTRL | Qt::Key_L);
0053 
0054     d->setItemRightAction = new QAction(QIcon::fromTheme(QLatin1String("arrow-right")), i18n("On right"), this);
0055     d->setItemRightAction->setEnabled(false);
0056     d->setItemRightAction->setWhatsThis(i18n("Show item on right panel"));
0057     connect(d->setItemRightAction, SIGNAL(triggered()), this, SLOT(slotSetItemRight()));
0058     ac->addAction(QLatin1String("lighttable_setitemright"), d->setItemRightAction);
0059     ac->setDefaultShortcut(d->setItemRightAction, Qt::CTRL | Qt::Key_R);
0060 
0061     d->editItemAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Edit"), this);
0062     d->editItemAction->setEnabled(false);
0063     connect(d->editItemAction, SIGNAL(triggered()), this, SLOT(slotEditItem()));
0064     ac->addAction(QLatin1String("lighttable_edititem"), d->editItemAction);
0065     ac->setDefaultShortcut(d->editItemAction, Qt::Key_F4);
0066 
0067     QAction* const openWithAction = new QAction(QIcon::fromTheme(QLatin1String("preferences-desktop-filetype-association")), i18n("Open With Default Application"), this);
0068     openWithAction->setWhatsThis(i18n("Open the item with default assigned application."));
0069     connect(openWithAction, SIGNAL(triggered()), this, SLOT(slotFileWithDefaultApplication()));
0070     ac->addAction(QLatin1String("open_with_default_application"), openWithAction);
0071     ac->setDefaultShortcut(openWithAction, Qt::CTRL | Qt::Key_F4);
0072 
0073     d->removeItemAction = new QAction(QIcon::fromTheme(QLatin1String("list-remove")), i18n("Remove item from Light Table"), this);
0074     d->removeItemAction->setEnabled(false);
0075     connect(d->removeItemAction, SIGNAL(triggered()), this, SLOT(slotRemoveItem()));
0076     ac->addAction(QLatin1String("lighttable_removeitem"), d->removeItemAction);
0077     ac->setDefaultShortcut(d->removeItemAction, Qt::CTRL | Qt::Key_K);
0078 
0079     d->clearListAction = new QAction(QIcon::fromTheme(QLatin1String("edit-clear")), i18n("Remove all items from Light Table"), this);
0080     d->clearListAction->setEnabled(false);
0081     connect(d->clearListAction, SIGNAL(triggered()), this, SLOT(slotClearItemsList()));
0082     ac->addAction(QLatin1String("lighttable_clearlist"), d->clearListAction);
0083     ac->setDefaultShortcut(d->clearListAction, Qt::CTRL | Qt::SHIFT | Qt::Key_K);
0084 
0085     d->fileDeleteAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), i18nc("Non-pluralized", "Move to Trash"), this);
0086     d->fileDeleteAction->setEnabled(false);
0087     connect(d->fileDeleteAction, SIGNAL(triggered()), this, SLOT(slotDeleteItem()));
0088     ac->addAction(QLatin1String("lighttable_filedelete"), d->fileDeleteAction);
0089     ac->setDefaultShortcut(d->fileDeleteAction, Qt::Key_Delete);
0090 
0091     d->fileDeleteFinalAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Delete immediately"), this);
0092     d->fileDeleteFinalAction->setEnabled(false);
0093     connect(d->fileDeleteFinalAction, SIGNAL(triggered()), this, SLOT(slotDeleteFinalItem()));
0094     ac->addAction(QLatin1String("lighttable_filefinaldelete"), d->fileDeleteFinalAction);
0095     ac->setDefaultShortcut(d->fileDeleteFinalAction, Qt::SHIFT | Qt::Key_Delete);
0096 
0097     QAction* const closeAction = buildStdAction(StdCloseAction, this, SLOT(slotClose()), this);
0098     ac->addAction(QLatin1String("lighttable_close"), closeAction);
0099 
0100     // -- Standard 'View' menu actions ---------------------------------------------
0101 
0102     d->syncPreviewAction = new QAction(QIcon::fromTheme(QLatin1String("view-split-left-right")), i18n("Synchronize"), this);
0103     d->syncPreviewAction->setEnabled(false);
0104     d->syncPreviewAction->setCheckable(true);
0105     d->syncPreviewAction->setWhatsThis(i18n("Synchronize preview from left and right panels"));
0106     connect(d->syncPreviewAction, SIGNAL(triggered()), this, SLOT(slotToggleSyncPreview()));
0107     ac->addAction(QLatin1String("lighttable_syncpreview"), d->syncPreviewAction);
0108     ac->setDefaultShortcut(d->syncPreviewAction, Qt::CTRL | Qt::SHIFT | Qt::Key_Y);
0109 
0110     d->navigateByPairAction = new QAction(QIcon::fromTheme(QLatin1String("system-run")), i18n("By Pair"), this);
0111     d->navigateByPairAction->setEnabled(false);
0112     d->navigateByPairAction->setCheckable(true);
0113     d->navigateByPairAction->setWhatsThis(i18n("Navigate by pairs with all items"));
0114     connect(d->navigateByPairAction, SIGNAL(triggered()), this, SLOT(slotToggleNavigateByPair()));
0115     ac->addAction(QLatin1String("lighttable_navigatebypair"), d->navigateByPairAction);
0116     ac->setDefaultShortcut(d->navigateByPairAction, Qt::CTRL | Qt::SHIFT | Qt::Key_P);
0117 
0118     d->clearOnCloseAction = new QAction(QIcon::fromTheme(QLatin1String("edit-clear")), i18n("Clear On Close"), this);
0119     d->clearOnCloseAction->setEnabled(true);
0120     d->clearOnCloseAction->setCheckable(true);
0121     d->clearOnCloseAction->setToolTip(i18n("Clear light table when it is closed"));
0122     d->clearOnCloseAction->setWhatsThis(i18n("Remove all images from the light table when it is closed"));
0123     ac->addAction(QLatin1String("lighttable_clearonclose"), d->clearOnCloseAction);
0124     ac->setDefaultShortcut(d->clearOnCloseAction, Qt::CTRL | Qt::SHIFT | Qt::Key_C);
0125 
0126     d->showBarAction = d->barViewDock->getToggleAction(this);
0127     ac->addAction(QLatin1String("lighttable_showthumbbar"), d->showBarAction);
0128     ac->setDefaultShortcut(d->showBarAction, Qt::CTRL | Qt::Key_T);
0129 
0130     createFullScreenAction(QLatin1String("lighttable_fullscreen"));
0131     createSidebarActions();
0132 
0133     // Left Panel Zoom Actions
0134 
0135     d->leftZoomPlusAction  = buildStdAction(StdZoomInAction, d->previewView, SLOT(slotIncreaseLeftZoom()), this);
0136     d->leftZoomPlusAction->setEnabled(false);
0137     ac->addAction(QLatin1String("lighttable_zoomplus_left"), d->leftZoomPlusAction);
0138 
0139     d->leftZoomMinusAction  = buildStdAction(StdZoomOutAction, d->previewView, SLOT(slotDecreaseLeftZoom()), this);
0140     d->leftZoomMinusAction->setEnabled(false);
0141     ac->addAction(QLatin1String("lighttable_zoomminus_left"), d->leftZoomMinusAction);
0142 
0143     d->leftZoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), i18n("Zoom to 100%"), this);
0144     connect(d->leftZoomTo100percents, SIGNAL(triggered()), d->previewView, SLOT(slotLeftZoomTo100()));
0145     ac->addAction(QLatin1String("lighttable_zoomto100percents_left"), d->leftZoomTo100percents);
0146     ac->setDefaultShortcut(d->leftZoomTo100percents, Qt::CTRL | Qt::Key_Period);
0147 
0148     d->leftZoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), i18n("Fit to &Window"), this);
0149     connect(d->leftZoomFitToWindowAction, SIGNAL(triggered()), d->previewView, SLOT(slotLeftFitToWindow()));
0150     ac->addAction(QLatin1String("lighttable_zoomfit2window_left"), d->leftZoomFitToWindowAction);
0151     ac->setDefaultShortcut(d->leftZoomFitToWindowAction, Qt::CTRL | Qt::ALT | Qt::Key_E);
0152 
0153     // Right Panel Zoom Actions
0154 
0155     d->rightZoomPlusAction  = buildStdAction(StdZoomInAction, d->previewView, SLOT(slotIncreaseRightZoom()), this);
0156     d->rightZoomPlusAction->setEnabled(false);
0157     ac->addAction(QLatin1String("lighttable_zoomplus_right"), d->rightZoomPlusAction);
0158 
0159 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0160 
0161     ac->setDefaultShortcut(d->rightZoomPlusAction, QKeySequence(QKeyCombination(Qt::ShiftModifier, d->rightZoomPlusAction->shortcut()[0].key())));
0162 
0163 #else
0164 
0165     ac->setDefaultShortcut(d->rightZoomPlusAction, Qt::Key(d->rightZoomPlusAction->shortcut()[0] ^ Qt::SHIFT) & d->rightZoomPlusAction->shortcut()[0]);
0166 
0167 #endif
0168 
0169     d->rightZoomMinusAction  = buildStdAction(StdZoomOutAction, d->previewView, SLOT(slotDecreaseRightZoom()), this);
0170     d->rightZoomMinusAction->setEnabled(false);
0171     ac->addAction(QLatin1String("lighttable_zoomminus_right"), d->rightZoomMinusAction);
0172 
0173 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0174 
0175     ac->setDefaultShortcut(d->rightZoomMinusAction, QKeySequence(QKeyCombination(Qt::ShiftModifier, d->rightZoomMinusAction->shortcut()[0].key())));
0176 
0177 #else
0178 
0179     ac->setDefaultShortcut(d->rightZoomMinusAction, Qt::Key(d->rightZoomMinusAction->shortcut()[0] ^ Qt::SHIFT) &  d->rightZoomMinusAction->shortcut()[0]);
0180 
0181 #endif
0182 
0183     d->rightZoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), i18n("Zoom to 100%"), this);
0184     connect(d->rightZoomTo100percents, SIGNAL(triggered()), d->previewView, SLOT(slotRightZoomTo100()));
0185     ac->addAction(QLatin1String("lighttable_zoomto100percents_right"), d->rightZoomTo100percents);
0186     ac->setDefaultShortcut(d->rightZoomTo100percents, Qt::CTRL | Qt::SHIFT | Qt::Key_Period);
0187 
0188     d->rightZoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), i18n("Fit to &Window"), this);
0189     connect(d->rightZoomFitToWindowAction, SIGNAL(triggered()), d->previewView, SLOT(slotRightFitToWindow()));
0190     ac->addAction(QLatin1String("lighttable_zoomfit2window_right"), d->rightZoomFitToWindowAction);
0191     ac->setDefaultShortcut(d->rightZoomFitToWindowAction, Qt::CTRL | Qt::SHIFT | Qt::Key_E);
0192 
0193     // -----------------------------------------------------------
0194 
0195     d->viewCMViewAction = new QAction(QIcon::fromTheme(QLatin1String("video-display")), i18n("Color-Managed View"), this);
0196     d->viewCMViewAction->setCheckable(true);
0197     connect(d->viewCMViewAction, SIGNAL(triggered()), this, SLOT(slotToggleColorManagedView()));
0198     ac->addAction(QLatin1String("color_managed_view"), d->viewCMViewAction);
0199     ac->setDefaultShortcut(d->viewCMViewAction, Qt::Key_F12);
0200 
0201     // -----------------------------------------------------------------------------
0202 
0203     ThemeManager::instance()->registerThemeActions(this);
0204 
0205     // Standard 'Help' menu actions
0206 
0207     createHelpActions(QLatin1String("light_table"));
0208 
0209     // Provides a menu entry that allows showing/hiding the toolbar(s)
0210 
0211     setStandardToolBarMenuEnabled(true);
0212 
0213     // Provides a menu entry that allows showing/hiding the statusbar
0214 
0215     createStandardStatusBarAction();
0216 
0217     // Standard 'Configure' menu actions
0218 
0219     createSettingsActions();
0220 
0221     // -- Keyboard-only actions ----------------------------------------------------
0222 
0223     d->addPageUpDownActions(this, this);
0224 
0225     QAction* const altBackwardAction = new QAction(i18n("Previous Image"), this);
0226     ac->addAction(QLatin1String("lighttable_backward_shift_space"), altBackwardAction);
0227     ac->setDefaultShortcut(altBackwardAction, Qt::SHIFT | Qt::Key_Space);
0228     connect(altBackwardAction, SIGNAL(triggered()), this, SLOT(slotBackward()));
0229 
0230     // Labels shortcuts must be registered here to be saved in XML GUI files if user customize it.
0231 
0232     TagsActionMngr::defaultManager()->registerLabelsActions(ac);
0233 
0234     QAction* const editTitlesRight = new QAction(i18n("Edit Titles on the Right"), this);
0235     ac->addAction(QLatin1String("edit_titles_right"), editTitlesRight);
0236     ac->setDefaultShortcut(editTitlesRight, Qt::ALT | Qt::SHIFT | Qt::Key_T);
0237     connect(editTitlesRight, SIGNAL(triggered()), this, SLOT(slotRightSideBarActivateTitles()));
0238 
0239     QAction* const editCommentsRight = new QAction(i18n("Edit Comments on the Right"), this);
0240     ac->addAction(QLatin1String("edit_comments_right"), editCommentsRight);
0241     ac->setDefaultShortcut(editCommentsRight, Qt::ALT | Qt::SHIFT | Qt::Key_C);
0242     connect(editCommentsRight, SIGNAL(triggered()), this, SLOT(slotRightSideBarActivateComments()));
0243 
0244     QAction* const assignedTagsRight = new QAction(i18n("Show Assigned Tags on the Right"), this);
0245     ac->addAction(QLatin1String("assigned_tags_right"), assignedTagsRight);
0246     ac->setDefaultShortcut(assignedTagsRight, Qt::ALT | Qt::SHIFT | Qt::Key_A);
0247     connect(assignedTagsRight, SIGNAL(triggered()), this, SLOT(slotRightSideBarActivateAssignedTags()));
0248 
0249     QAction* const editTitlesLeft = new QAction(i18n("Edit Titles on the Left"), this);
0250     ac->addAction(QLatin1String("edit_titles_left"), editTitlesLeft);
0251     ac->setDefaultShortcut(editTitlesLeft, Qt::CTRL | Qt::ALT | Qt::SHIFT | Qt::Key_T);
0252     connect(editTitlesLeft, SIGNAL(triggered()), this, SLOT(slotLeftSideBarActivateTitles()));
0253 
0254     QAction* const editCommentsLeft = new QAction(i18n("Edit Comments on the Left"), this);
0255     ac->addAction(QLatin1String("edit_comments_left"), editCommentsLeft);
0256     ac->setDefaultShortcut(editCommentsLeft, Qt::CTRL | Qt::ALT | Qt::SHIFT | Qt::Key_C);
0257     connect(editCommentsLeft, SIGNAL(triggered()), this, SLOT(slotLeftSideBarActivateComments()));
0258 
0259     QAction* const assignedTagsLeft = new QAction(i18n("Show Assigned Tags on the Left"), this);
0260     ac->addAction(QLatin1String("assigned_tags_left"), assignedTagsLeft);
0261     ac->setDefaultShortcut(assignedTagsLeft, Qt::CTRL | Qt::ALT | Qt::SHIFT | Qt::Key_A);
0262     connect(assignedTagsLeft, SIGNAL(triggered()), this, SLOT(slotLeftSideBarActivateAssignedTags()));
0263 
0264     // ---------------------------------------------------------------------------------
0265 
0266     createGUI(xmlFile());
0267     registerPluginsActions();
0268 
0269     cleanupActions();
0270 
0271     showMenuBarAction()->setChecked(!menuBar()->isHidden());  // NOTE: workaround for bug #171080
0272 }
0273 
0274 void LightTableWindow::setupStatusBar()
0275 {
0276     d->leftZoomBar = new DZoomBar(statusBar());
0277     d->leftZoomBar->setZoomToFitAction(d->leftZoomFitToWindowAction);
0278     d->leftZoomBar->setZoomTo100Action(d->leftZoomTo100percents);
0279     d->leftZoomBar->setZoomPlusAction(d->leftZoomPlusAction);
0280     d->leftZoomBar->setZoomMinusAction(d->leftZoomMinusAction);
0281     d->leftZoomBar->setBarMode(DZoomBar::PreviewZoomCtrl);
0282     d->leftZoomBar->setEnabled(false);
0283     statusBar()->addWidget(d->leftZoomBar, 1);
0284 
0285     d->leftFileName = new DAdjustableLabel(statusBar());
0286     d->leftFileName->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
0287     statusBar()->addWidget(d->leftFileName, 10);
0288 
0289     d->statusProgressBar = new StatusProgressBar(statusBar());
0290     d->statusProgressBar->setAlignment(Qt::AlignCenter);
0291     statusBar()->addWidget(d->statusProgressBar, 10);
0292 
0293     d->rightFileName = new DAdjustableLabel(statusBar());
0294     d->rightFileName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
0295     statusBar()->addWidget(d->rightFileName, 10);
0296 
0297     d->rightZoomBar = new DZoomBar(statusBar());
0298     d->rightZoomBar->setZoomToFitAction(d->rightZoomFitToWindowAction);
0299     d->rightZoomBar->setZoomTo100Action(d->rightZoomTo100percents);
0300     d->rightZoomBar->setZoomPlusAction(d->rightZoomPlusAction);
0301     d->rightZoomBar->setZoomMinusAction(d->rightZoomMinusAction);
0302     d->rightZoomBar->setBarMode(DZoomBar::PreviewZoomCtrl);
0303     d->rightZoomBar->setEnabled(false);
0304     statusBar()->addWidget(d->rightZoomBar, 1);
0305 }
0306 
0307 void LightTableWindow::setupConnections()
0308 {
0309     connect(ApplicationSettings::instance(), SIGNAL(setupChanged()),
0310             this, SLOT(slotApplicationSettingsChanged()));
0311 
0312     connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()),
0313             this, SLOT(slotThemeChanged()));
0314 
0315     connect(IccSettings::instance(), SIGNAL(signalSettingsChanged()),
0316             this, SLOT(slotColorManagementOptionsChanged()));
0317 
0318     // Thumbs bar connections ---------------------------------------
0319 
0320     connect(d->thumbView, SIGNAL(signalSetItemOnLeftPanel(ItemInfo)),
0321             this, SLOT(slotSetItemOnLeftPanel(ItemInfo)));
0322 
0323     connect(d->thumbView, SIGNAL(signalSetItemOnRightPanel(ItemInfo)),
0324             this, SLOT(slotSetItemOnRightPanel(ItemInfo)));
0325 
0326     connect(d->thumbView, SIGNAL(signalRemoveItem(ItemInfo)),
0327             this, SLOT(slotRemoveItem(ItemInfo)));
0328 
0329     connect(d->thumbView, SIGNAL(signalEditItem(ItemInfo)),
0330             this, SLOT(slotEditItem(ItemInfo)));
0331 
0332     connect(d->thumbView, SIGNAL(signalClearAll()),
0333             this, SLOT(slotClearItemsList()));
0334 
0335     connect(d->thumbView, SIGNAL(signalDroppedItems(QList<ItemInfo>)),
0336             this, SLOT(slotThumbbarDroppedItems(QList<ItemInfo>)));
0337 
0338     connect(d->thumbView, SIGNAL(currentChanged(ItemInfo)),
0339             this, SLOT(slotItemSelected(ItemInfo)));
0340 
0341     connect(d->thumbView, SIGNAL(signalContentChanged()),
0342             this, SLOT(slotRefreshStatusBar()));
0343 
0344     // Zoom bars connections -----------------------------------------
0345 
0346     connect(d->leftZoomBar, SIGNAL(signalZoomSliderChanged(int)),
0347             d->previewView, SLOT(slotLeftZoomSliderChanged(int)));
0348 
0349     connect(d->leftZoomBar, SIGNAL(signalZoomValueEdited(double)),
0350             d->previewView, SLOT(setLeftZoomFactor(double)));
0351 
0352     connect(d->rightZoomBar, SIGNAL(signalZoomSliderChanged(int)),
0353             d->previewView, SLOT(slotRightZoomSliderChanged(int)));
0354 
0355     connect(d->rightZoomBar, SIGNAL(signalZoomValueEdited(double)),
0356             d->previewView, SLOT(setRightZoomFactor(double)));
0357 
0358     // View connections ---------------------------------------------
0359 
0360     connect(d->previewView, SIGNAL(signalLeftPreviewSelected(bool)),
0361             this, SLOT(slotLeftPreviewSelected(bool)));
0362 
0363     connect(d->previewView, SIGNAL(signalRightPreviewSelected(bool)),
0364             this, SLOT(slotRightPreviewSelected(bool)));
0365 
0366     connect(d->previewView, SIGNAL(signalLeftPopupTagsView()),
0367             d->leftSideBar, SLOT(slotPopupTagsView()));
0368 
0369     connect(d->previewView, SIGNAL(signalRightPopupTagsView()),
0370             d->rightSideBar, SLOT(slotPopupTagsView()));
0371 
0372     connect(d->previewView, SIGNAL(signalLeftZoomFactorChanged(double)),
0373             this, SLOT(slotLeftZoomFactorChanged(double)));
0374 
0375     connect(d->previewView, SIGNAL(signalRightZoomFactorChanged(double)),
0376             this, SLOT(slotRightZoomFactorChanged(double)));
0377 
0378     connect(d->previewView, SIGNAL(signalEditItem(ItemInfo)),
0379             this, SLOT(slotEditItem(ItemInfo)));
0380 
0381     connect(d->previewView, SIGNAL(signalDeleteItem(ItemInfo)),
0382             this, SLOT(slotDeleteItem(ItemInfo)));
0383 
0384     connect(d->previewView, SIGNAL(signalLeftSlideShowCurrent()),
0385             this, SLOT(slotLeftSlideShowManualFromCurrent()));
0386 
0387     connect(d->previewView, SIGNAL(signalRightSlideShowCurrent()),
0388             this, SLOT(slotRightSlideShowManualFromCurrent()));
0389 
0390     connect(d->previewView, SIGNAL(signalLeftDroppedItems(ItemInfoList)),
0391             this, SLOT(slotLeftDroppedItems(ItemInfoList)));
0392 
0393     connect(d->previewView, SIGNAL(signalRightDroppedItems(ItemInfoList)),
0394             this, SLOT(slotRightDroppedItems(ItemInfoList)));
0395 
0396     connect(d->previewView, SIGNAL(signalToggleOnSyncPreview(bool)),
0397             this, SLOT(slotToggleOnSyncPreview(bool)));
0398 
0399     connect(d->previewView, SIGNAL(signalLeftPreviewLoaded(bool)),
0400             this, SLOT(slotLeftPreviewLoaded(bool)));
0401 
0402     connect(d->previewView, SIGNAL(signalRightPreviewLoaded(bool)),
0403             this, SLOT(slotRightPreviewLoaded(bool)));
0404 
0405     connect(d->previewView, SIGNAL(signalLeftPanelLeftButtonClicked()),
0406             this, SLOT(slotLeftPanelLeftButtonClicked()));
0407 
0408     connect(d->previewView, SIGNAL(signalRightPanelLeftButtonClicked()),
0409             this, SLOT(slotRightPanelLeftButtonClicked()));
0410 
0411     connect(this, SIGNAL(signalWindowHasMoved()),
0412             d->leftZoomBar, SLOT(slotUpdateTrackerPos()));
0413 
0414     connect(this, SIGNAL(signalWindowHasMoved()),
0415             d->rightZoomBar, SLOT(slotUpdateTrackerPos()));
0416 
0417     // TODO: connect signal last image from SLideShow plugin to slotSlideShowLastItemUrl
0418 
0419     // -- FileWatch connections ------------------------------
0420 
0421     LoadingCacheInterface::connectToSignalFileChanged(this, SLOT(slotFileChanged(QString)));
0422 }
0423 
0424 void LightTableWindow::setupUserArea()
0425 {
0426     QWidget* const mainW    = new QWidget(this);
0427     d->hSplitter            = new SidebarSplitter(Qt::Horizontal, mainW);
0428     QHBoxLayout* const hlay = new QHBoxLayout(mainW);
0429 
0430     // The left sidebar
0431 
0432     d->leftSideBar          = new ItemPropertiesSideBarDB(mainW, d->hSplitter, Qt::LeftEdge, true);
0433 
0434     // The central preview is wrapped in a KMainWindow so that the thumbnail
0435     // bar can float around it.
0436 
0437     KMainWindow* const viewContainer = new KMainWindow(mainW, Qt::Widget);
0438     d->hSplitter->addWidget(viewContainer);
0439     d->hSplitter->setStretchFactor(d->hSplitter->indexOf(viewContainer), 10);
0440     d->previewView                   = new LightTableView(viewContainer);
0441     viewContainer->setCentralWidget(d->previewView);
0442 
0443     // The right sidebar.
0444 
0445     d->rightSideBar = new ItemPropertiesSideBarDB(mainW, d->hSplitter, Qt::RightEdge, true);
0446 
0447     hlay->addWidget(d->leftSideBar);
0448     hlay->addWidget(d->hSplitter);
0449     hlay->addWidget(d->rightSideBar);
0450     hlay->setSpacing(0);
0451     hlay->setContentsMargins(QMargins());
0452     hlay->setStretchFactor(d->hSplitter, 10);
0453 
0454     d->hSplitter->setFrameStyle(QFrame::NoFrame);
0455     d->hSplitter->setFrameShadow(QFrame::Plain);
0456     d->hSplitter->setFrameShape(QFrame::NoFrame);
0457     d->hSplitter->setOpaqueResize(false);
0458     d->hSplitter->setStretchFactor(1, 10);      // set previewview+thumbbar container default size to max.
0459 
0460     // The thumb bar is placed in a detachable/dockable widget.
0461 
0462     d->barViewDock = new ThumbBarDock(viewContainer, Qt::Tool);
0463     d->barViewDock->setObjectName(QLatin1String("lighttable_thumbbar"));
0464 
0465     d->thumbView   = new LightTableThumbBar(d->barViewDock);
0466 
0467     d->barViewDock->setWidget(d->thumbView);
0468     viewContainer->addDockWidget(Qt::TopDockWidgetArea, d->barViewDock);
0469     d->barViewDock->setFloating(false);
0470 
0471     // Restore the previous state. This doesn't Q_EMIT the proper signals to the
0472     // dock widget, so it has to be manually reinitialized.
0473 
0474     viewContainer->setAutoSaveSettings(QLatin1String("LightTable Thumbbar"), true);
0475 
0476     connect(d->barViewDock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),
0477             d->thumbView, SLOT(slotDockLocationChanged(Qt::DockWidgetArea)));
0478 
0479     d->barViewDock->reInitialize();
0480 
0481     setCentralWidget(mainW);
0482 }
0483 
0484 } // namespace Digikam