summaryrefslogtreecommitdiffstats
path: root/src/utilities/lighttable/lighttableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utilities/lighttable/lighttableview.cpp')
-rw-r--r--src/utilities/lighttable/lighttableview.cpp446
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
+