diff options
Diffstat (limited to 'src/utilities/lighttable/lighttableview.cpp')
-rw-r--r-- | src/utilities/lighttable/lighttableview.cpp | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/src/utilities/lighttable/lighttableview.cpp b/src/utilities/lighttable/lighttableview.cpp new file mode 100644 index 00000000..51f45ab5 --- /dev/null +++ b/src/utilities/lighttable/lighttableview.cpp @@ -0,0 +1,446 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2007-03-05 + * Description : a widget to display 2 preview image on + * lightable to compare pictures. + * + * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// TQt includes. + +#include <tqlayout.h> + +// KDE includes. + +#include <kdialogbase.h> + +// Local includes. + +#include "ddebug.h" +#include "thumbnailsize.h" +#include "lighttablepreview.h" +#include "lighttableview.h" +#include "lighttableview.moc" + +namespace Digikam +{ + +class LightTableViewPriv +{ +public: + + LightTableViewPriv() + { + syncPreview = false; + leftLoading = false; + rightLoading = false; + leftPreview = 0; + rightPreview = 0; + grid = 0; + } + + bool syncPreview; + bool leftLoading; // To not sync right panel during left loading. + bool rightLoading; // To not sync left panel during right loading. + + TQGridLayout *grid; + + LightTablePreview *leftPreview; + LightTablePreview *rightPreview; +}; + +LightTableView::LightTableView(TQWidget *parent) + : TQFrame(parent, 0, TQt::WDestructiveClose) +{ + d = new LightTableViewPriv; + + setFrameStyle(TQFrame::NoFrame); + setMargin(0); + setLineWidth(0); + + d->grid = new TQGridLayout(this, 1, 1, 0, 1); + d->leftPreview = new LightTablePreview(this); + d->rightPreview = new LightTablePreview(this); + + d->grid->addMultiCellWidget(d->leftPreview, 0, 0, 0, 0); + d->grid->addMultiCellWidget(d->rightPreview, 0, 0, 1, 1); + + d->grid->setColStretch(0, 10), + d->grid->setColStretch(1, 10), + d->grid->setRowStretch(0, 10), + + // Left panel connections ------------------------------------------------ + + connect(d->leftPreview, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SIGNAL(signalLeftZoomFactorChanged(double))); + + connect(d->leftPreview, TQ_SIGNAL(contentsMoving(int, int)), + this, TQ_SLOT(slotLeftContentsMoved(int, int))); + + connect(d->leftPreview, TQ_SIGNAL(signalSlideShow()), + this, TQ_SIGNAL(signalSlideShow())); + + connect(d->leftPreview, TQ_SIGNAL(signalDeleteItem(ImageInfo*)), + this, TQ_SIGNAL(signalDeleteItem(ImageInfo*))); + + connect(d->leftPreview, TQ_SIGNAL(signalEditItem(ImageInfo*)), + this, TQ_SIGNAL(signalEditItem(ImageInfo*))); + + connect(d->leftPreview, TQ_SIGNAL(signalDroppedItems(const ImageInfoList&)), + this, TQ_SIGNAL(signalLeftDroppedItems(const ImageInfoList&))); + + connect(d->leftPreview, TQ_SIGNAL(signalPreviewLoaded(bool)), + this, TQ_SLOT(slotLeftPreviewLoaded(bool))); + + connect(d->leftPreview, TQ_SIGNAL(signalLeftButtonClicked()), + this, TQ_SIGNAL(signalLeftPanelLeftButtonClicked())); + + // Right panel connections ------------------------------------------------ + + connect(d->rightPreview, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SIGNAL(signalRightZoomFactorChanged(double))); + + connect(d->rightPreview, TQ_SIGNAL(contentsMoving(int, int)), + this, TQ_SLOT(slotRightContentsMoved(int, int))); + + connect(d->rightPreview, TQ_SIGNAL(signalDeleteItem(ImageInfo*)), + this, TQ_SIGNAL(signalDeleteItem(ImageInfo*))); + + connect(d->rightPreview, TQ_SIGNAL(signalEditItem(ImageInfo*)), + this, TQ_SIGNAL(signalEditItem(ImageInfo*))); + + connect(d->rightPreview, TQ_SIGNAL(signalDroppedItems(const ImageInfoList&)), + this, TQ_SIGNAL(signalRightDroppedItems(const ImageInfoList&))); + + connect(d->rightPreview, TQ_SIGNAL(signalSlideShow()), + this, TQ_SIGNAL(signalSlideShow())); + + connect(d->rightPreview, TQ_SIGNAL(signalPreviewLoaded(bool)), + this, TQ_SLOT(slotRightPreviewLoaded(bool))); + + connect(d->rightPreview, TQ_SIGNAL(signalLeftButtonClicked()), + this, TQ_SIGNAL(signalRightPanelLeftButtonClicked())); +} + +LightTableView::~LightTableView() +{ + delete d; +} + +void LightTableView::setLoadFullImageSize(bool b) +{ + d->leftPreview->setLoadFullImageSize(b); + d->rightPreview->setLoadFullImageSize(b); +} + +void LightTableView::setSyncPreview(bool sync) +{ + d->syncPreview = sync; + + // Left panel like a reference to resync preview. + if (d->syncPreview) + slotLeftContentsMoved(d->leftPreview->contentsX(), d->leftPreview->contentsY()); +} + +void LightTableView::setNavigateByPair(bool b) +{ + d->leftPreview->setDragAndDropEnabled(!b); + d->rightPreview->setDragAndDropEnabled(!b); +} + +void LightTableView::slotDecreaseZoom() +{ + if (d->syncPreview) + { + slotDecreaseLeftZoom(); + return; + } + + if (d->leftPreview->isSelected()) + slotDecreaseLeftZoom(); + else if (d->rightPreview->isSelected()) + slotDecreaseRightZoom(); +} + +void LightTableView::slotIncreaseZoom() +{ + if (d->syncPreview) + { + slotIncreaseLeftZoom(); + return; + } + + if (d->leftPreview->isSelected()) + slotIncreaseLeftZoom(); + else if (d->rightPreview->isSelected()) + slotIncreaseRightZoom(); +} + +void LightTableView::slotDecreaseLeftZoom() +{ + d->leftPreview->slotDecreaseZoom(); +} + +void LightTableView::slotIncreaseLeftZoom() +{ + d->leftPreview->slotIncreaseZoom(); +} + +void LightTableView::slotDecreaseRightZoom() +{ + d->rightPreview->slotDecreaseZoom(); +} + +void LightTableView::slotIncreaseRightZoom() +{ + d->rightPreview->slotIncreaseZoom(); +} + +void LightTableView::setLeftZoomFactor(double z) +{ + d->leftPreview->setZoomFactor(z); +} + +void LightTableView::setRightZoomFactor(double z) +{ + d->rightPreview->setZoomFactor(z); +} + +void LightTableView::fitToWindow() +{ + d->leftPreview->fitToWindow(); + d->rightPreview->fitToWindow(); +} + +void LightTableView::toggleFitToWindowOr100() +{ + // If we are currently precisely at 100%, then fit to window, + // otherwise zoom to a centered 100% view. + if ((d->leftPreview->zoomFactor()==1.0) && + (d->rightPreview->zoomFactor()==1.0)) + { + fitToWindow(); + } + else + { + d->leftPreview->setZoomFactor(1.0, true); + d->rightPreview->setZoomFactor(1.0, true); + } +} + +double LightTableView::leftZoomMax() +{ + return d->leftPreview->zoomMax(); +} + +double LightTableView::leftZoomMin() +{ + return d->leftPreview->zoomMin(); +} + +bool LightTableView::leftMaxZoom() +{ + return d->leftPreview->maxZoom(); +} + +bool LightTableView::leftMinZoom() +{ + return d->leftPreview->minZoom(); +} + +double LightTableView::rightZoomMax() +{ + return d->rightPreview->zoomMax(); +} + +double LightTableView::rightZoomMin() +{ + return d->rightPreview->zoomMin(); +} + +bool LightTableView::rightMaxZoom() +{ + return d->rightPreview->maxZoom(); +} + +bool LightTableView::rightMinZoom() +{ + return d->rightPreview->minZoom(); +} + +void LightTableView::slotLeftZoomSliderChanged(int size) +{ + double h = (double)ThumbnailSize::Huge; + double s = (double)ThumbnailSize::Small; + double zmin = d->leftPreview->zoomMin(); + double zmax = d->leftPreview->zoomMax(); + double b = (zmin-(zmax*s/h))/(1-s/h); + double a = (zmax-b)/h; + double z = a*size+b; + + d->leftPreview->setZoomFactorSnapped(z); +} + +void LightTableView::slotRightZoomSliderChanged(int size) +{ + double h = (double)ThumbnailSize::Huge; + double s = (double)ThumbnailSize::Small; + double zmin = d->rightPreview->zoomMin(); + double zmax = d->rightPreview->zoomMax(); + double b = (zmin-(zmax*s/h))/(1-s/h); + double a = (zmax-b)/h; + double z = a*size+b; + + d->rightPreview->setZoomFactorSnapped(z); +} + +void LightTableView::leftReload() +{ + d->leftPreview->reload(); +} + +void LightTableView::rightReload() +{ + d->rightPreview->reload(); +} + +void LightTableView::slotLeftContentsMoved(int x, int y) +{ + if (d->syncPreview && !d->leftLoading) + { + disconnect(d->rightPreview, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SIGNAL(signalRightZoomFactorChanged(double))); + + disconnect(d->rightPreview, TQ_SIGNAL(contentsMoving(int, int)), + this, TQ_SLOT(slotRightContentsMoved(int, int))); + + setRightZoomFactor(d->leftPreview->zoomFactor()); + emit signalRightZoomFactorChanged(d->leftPreview->zoomFactor()); + d->rightPreview->setContentsPos(x, y); + + connect(d->rightPreview, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SIGNAL(signalRightZoomFactorChanged(double))); + + connect(d->rightPreview, TQ_SIGNAL(contentsMoving(int, int)), + this, TQ_SLOT(slotRightContentsMoved(int, int))); + } +} + +void LightTableView::slotRightContentsMoved(int x, int y) +{ + if (d->syncPreview && !d->rightLoading) + { + disconnect(d->leftPreview, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SIGNAL(signalLeftZoomFactorChanged(double))); + + disconnect(d->leftPreview, TQ_SIGNAL(contentsMoving(int, int)), + this, TQ_SLOT(slotLeftContentsMoved(int, int))); + + + setLeftZoomFactor(d->rightPreview->zoomFactor()); + emit signalLeftZoomFactorChanged(d->rightPreview->zoomFactor()); + d->leftPreview->setContentsPos(x, y); + + connect(d->leftPreview, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SIGNAL(signalLeftZoomFactorChanged(double))); + + connect(d->leftPreview, TQ_SIGNAL(contentsMoving(int, int)), + this, TQ_SLOT(slotLeftContentsMoved(int, int))); + } +} + +ImageInfo* LightTableView::leftImageInfo() const +{ + return d->leftPreview->getImageInfo(); +} + +ImageInfo* LightTableView::rightImageInfo() const +{ + return d->rightPreview->getImageInfo(); +} + +void LightTableView::setLeftImageInfo(ImageInfo* info) +{ + d->leftLoading = true; + d->leftPreview->setImageInfo(info); +} + +void LightTableView::setRightImageInfo(ImageInfo* info) +{ + d->rightLoading = true; + d->rightPreview->setImageInfo(info); +} + +void LightTableView::slotLeftPreviewLoaded(bool success) +{ + checkForSyncPreview(); + d->leftLoading = false; + slotRightContentsMoved(d->rightPreview->contentsX(), + d->rightPreview->contentsY()); + + emit signalLeftPreviewLoaded(success); +} + +void LightTableView::slotRightPreviewLoaded(bool success) +{ + checkForSyncPreview(); + d->rightLoading = false; + slotLeftContentsMoved(d->leftPreview->contentsX(), + d->leftPreview->contentsY()); + + emit signalRightPreviewLoaded(success); +} + +void LightTableView::checkForSyncPreview() +{ + if (d->leftPreview->getImageInfo() && d->rightPreview->getImageInfo() && + d->leftPreview->getImageSize() == d->rightPreview->getImageSize()) + { + d->syncPreview = true; + } + else + { + d->syncPreview = false; + } + + emit signalToggleOnSyncPreview(d->syncPreview); +} + +void LightTableView::checkForSelection(ImageInfo* info) +{ + if (!info) + { + d->leftPreview->setSelected(false); + d->rightPreview->setSelected(false); + return; + } + + if (d->leftPreview->getImageInfo()) + { + d->leftPreview->setSelected(d->leftPreview->getImageInfo()->id() == info->id()); + } + + if (d->rightPreview->getImageInfo()) + { + d->rightPreview->setSelected(d->rightPreview->getImageInfo()->id() == info->id()); + } +} + +} // namespace Digikam + |