File indexing completed on 2024-05-12 15:55:37

0001 /* SPDX-FileCopyrightText: 2012-2020 The KPhotoAlbum Development Team
0002 
0003    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #include "DuplicateMatch.h"
0007 
0008 #include "MergeToolTip.h"
0009 
0010 #include <DB/ImageDB.h>
0011 #include <DB/ImageInfo.h>
0012 #include <DB/ImageInfoPtr.h>
0013 #include <ImageManager/AsyncLoader.h>
0014 #include <Utilities/DeleteFiles.h>
0015 
0016 #include <KLocalizedString>
0017 #include <QCheckBox>
0018 #include <QEvent>
0019 #include <QImage>
0020 #include <QLabel>
0021 #include <QRadioButton>
0022 #include <QToolButton>
0023 #include <QVBoxLayout>
0024 #include <QVariant>
0025 
0026 namespace MainWindow
0027 {
0028 
0029 DuplicateMatch::DuplicateMatch(const DB::FileNameList &files)
0030 {
0031     QVBoxLayout *topLayout = new QVBoxLayout(this);
0032 
0033     QHBoxLayout *horizontalLayout = new QHBoxLayout;
0034     topLayout->addLayout(horizontalLayout);
0035     m_image = new QLabel;
0036     horizontalLayout->addWidget(m_image);
0037 
0038     QVBoxLayout *rightSideLayout = new QVBoxLayout;
0039     horizontalLayout->addSpacing(20);
0040     horizontalLayout->addLayout(rightSideLayout);
0041     horizontalLayout->addStretch(1);
0042     rightSideLayout->addStretch(1);
0043 
0044     m_merge = new QCheckBox(i18n("Merge these images"));
0045     rightSideLayout->addWidget(m_merge);
0046     m_merge->setChecked(false);
0047     connect(m_merge, &QCheckBox::toggled, this, &DuplicateMatch::selectionChanged);
0048 
0049     QWidget *options = new QWidget;
0050     options->setEnabled(false);
0051     rightSideLayout->addWidget(options);
0052     QVBoxLayout *optionsLayout = new QVBoxLayout(options);
0053     connect(m_merge, &QCheckBox::toggled, options, &QWidget::setEnabled);
0054 
0055     QLabel *label = new QLabel(i18n("Select target:"));
0056     optionsLayout->addWidget(label);
0057 
0058     bool first = true;
0059     for (const DB::FileName &fileName : files) {
0060         QHBoxLayout *lay = new QHBoxLayout;
0061         optionsLayout->addLayout(lay);
0062         QRadioButton *button = new QRadioButton(fileName.relative());
0063         button->setProperty("data", QVariant::fromValue(fileName));
0064         lay->addWidget(button);
0065         if (first) {
0066             button->setChecked(true);
0067             first = false;
0068         }
0069         QToolButton *details = new QToolButton;
0070         details->setText(i18nc("i for info", "i"));
0071         details->installEventFilter(this);
0072         details->setProperty("data", QVariant::fromValue(fileName));
0073         lay->addWidget(details);
0074         m_buttons.append(button);
0075     }
0076     rightSideLayout->addStretch(1);
0077 
0078     QFrame *line = new QFrame;
0079     line->setFrameStyle(QFrame::HLine);
0080     topLayout->addWidget(line);
0081 
0082     const DB::ImageInfoPtr info = DB::ImageDB::instance()->info(files.first());
0083     const int angle = info->angle();
0084     ImageManager::ImageRequest *request = new ImageManager::ImageRequest(files.first(), QSize(300, 300), angle, this);
0085     ImageManager::AsyncLoader::instance()->load(request);
0086 }
0087 
0088 void DuplicateMatch::pixmapLoaded(ImageManager::ImageRequest * /*request*/, const QImage &image)
0089 {
0090     m_image->setPixmap(QPixmap::fromImage(image));
0091 }
0092 
0093 void DuplicateMatch::setSelected(bool b)
0094 {
0095     m_merge->setChecked(b);
0096 }
0097 
0098 bool DuplicateMatch::selected() const
0099 {
0100     return m_merge->isChecked();
0101 }
0102 
0103 void DuplicateMatch::execute(Utilities::DeleteMethod method)
0104 {
0105     if (!m_merge->isChecked())
0106         return;
0107 
0108     DB::FileName destination;
0109     for (const QRadioButton *button : qAsConst(m_buttons)) {
0110         if (button->isChecked()) {
0111             destination = button->property("data").value<DB::FileName>();
0112             break;
0113         }
0114     }
0115 
0116     DB::FileNameList deleteList, dupList;
0117     for (const QRadioButton *button : qAsConst(m_buttons)) {
0118         if (button->isChecked())
0119             continue;
0120         DB::FileName fileName = button->property("data").value<DB::FileName>();
0121         DB::ImageDB::instance()->copyData(fileName, destination);
0122         // can we safely delete the file?
0123         if (fileName != destination)
0124             deleteList.append(fileName);
0125         else
0126             dupList.append(fileName);
0127     }
0128 
0129     Utilities::DeleteFiles::deleteFiles(deleteList, method);
0130     // remove duplicate DB-entries without removing or blocking the file:
0131     DB::ImageDB::instance()->deleteList(dupList);
0132 }
0133 
0134 bool DuplicateMatch::eventFilter(QObject *obj, QEvent *event)
0135 {
0136     if (event->type() != QEvent::Enter)
0137         return false;
0138 
0139     QToolButton *but;
0140     if (!(but = qobject_cast<QToolButton *>(obj)))
0141         return false;
0142 
0143     const DB::FileName fileName = but->property("data").value<DB::FileName>();
0144     MergeToolTip::instance()->requestToolTip(fileName);
0145     return false;
0146 }
0147 
0148 } // namespace MainWindow
0149 
0150 // vi:expandtab:tabstop=4 shiftwidth=4:
0151 
0152 #include "moc_DuplicateMatch.cpp"