File indexing completed on 2025-03-09 03:57:15

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-12-01
0007  * Description : Base-class for backends for geolocation interface
0008  *
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2009-2011 by Michael G. Hansen <mike at mghansen dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "mapbackend.h"
0017 
0018 // Qt includes
0019 
0020 #include <QMessageBox>
0021 #include <QImageWriter>
0022 #include <QAction>
0023 #include <QMenu>
0024 #include <QApplication>
0025 
0026 // KDE includes
0027 
0028 #include <klocalizedstring.h>
0029 
0030 // Local includes
0031 
0032 #include "dfiledialog.h"
0033 #include "geolocationsettings.h"
0034 #include "digikam_debug.h"
0035 
0036 namespace Digikam
0037 {
0038 
0039 MapBackend::MapBackend(const QExplicitlySharedDataPointer<GeoIfaceSharedData>& sharedData,
0040                        QObject* const parent)
0041     : QObject(parent),
0042       s      (sharedData)
0043 {
0044 }
0045 
0046 MapBackend::~MapBackend()
0047 {
0048 }
0049 
0050 void MapBackend::slotThumbnailAvailableForIndex(const QVariant& index, const QPixmap& pixmap)
0051 {
0052     Q_UNUSED(index)
0053     Q_UNUSED(pixmap)
0054 }
0055 
0056 void MapBackend::slotTrackManagerChanged()
0057 {
0058 }
0059 
0060 void MapBackend::addCommonOptions(QMenu* const configurationMenu)
0061 {
0062     QAction* const settings = new QAction(i18n("Settings..."), configurationMenu);
0063     configurationMenu->addAction(settings);
0064 
0065     connect(settings, &QAction::triggered,
0066             this, []()
0067         {
0068             GeolocationSettings::instance()->openSetupGeolocation(SetupGeolocation::GoogleMaps);
0069         }
0070     );
0071 
0072     QAction* const exportAs = new QAction(i18n("Export as..."), configurationMenu);
0073     configurationMenu->addAction(exportAs);
0074 
0075     connect(exportAs, SIGNAL(triggered()),
0076             this, SLOT(slotExportScreenshot()));
0077 }
0078 
0079 void MapBackend::slotExportScreenshot()
0080 {
0081     QStringList writableMimetypes;
0082     QList<QByteArray> supported = QImageWriter::supportedMimeTypes();
0083 
0084     Q_FOREACH (const QByteArray& mimeType, supported)
0085     {
0086         writableMimetypes.append(QLatin1String(mimeType));
0087     }
0088 
0089     // Put first class citizens at first place
0090 
0091     writableMimetypes.removeAll(QLatin1String("image/jpeg"));
0092     writableMimetypes.removeAll(QLatin1String("image/tiff"));
0093     writableMimetypes.removeAll(QLatin1String("image/png"));
0094     writableMimetypes.insert(0, QLatin1String("image/png"));
0095     writableMimetypes.insert(1, QLatin1String("image/jpeg"));
0096     writableMimetypes.insert(2, QLatin1String("image/tiff"));
0097 
0098     qCDebug(DIGIKAM_GEOIFACE_LOG) << "slotSaveImage: Offered mimetypes: " << writableMimetypes;
0099 
0100     QLatin1String defaultMimeType("image/png");
0101     QLatin1String defaultFileName("image.png");
0102 
0103     QPointer<DFileDialog> imageFileSaveDialog = new DFileDialog(nullptr,
0104                                                                 i18nc("@title:window", "New Image File Name"));
0105     imageFileSaveDialog->setAcceptMode(QFileDialog::AcceptSave);
0106     imageFileSaveDialog->setMimeTypeFilters(writableMimetypes);
0107     imageFileSaveDialog->selectMimeTypeFilter(defaultMimeType);
0108     imageFileSaveDialog->selectFile(defaultFileName);
0109 
0110     // Start dialog and check if canceled.
0111 
0112     imageFileSaveDialog->exec();
0113 
0114     if (!imageFileSaveDialog->hasAcceptedUrls())
0115     {
0116         delete imageFileSaveDialog;
0117 
0118         return;
0119     }
0120 
0121     QUrl newURL                  = imageFileSaveDialog->selectedUrls().first();
0122     QFileInfo fi(newURL.toLocalFile());
0123 
0124     // Parse name filter and extract file extension
0125 
0126     QString selectedFilterString = imageFileSaveDialog->selectedNameFilter();
0127     QLatin1String triggerString("*.");
0128     int triggerPos               = selectedFilterString.lastIndexOf(triggerString);
0129     QString format;
0130 
0131     if (triggerPos != -1)
0132     {
0133         format = selectedFilterString.mid(triggerPos + triggerString.size());
0134         format = format.left(format.size() - 1);
0135         format = format.toUpper();
0136     }
0137 
0138     // If name filter was selected, we guess image type using file extension.
0139 
0140     if (format.isEmpty())
0141     {
0142         format = fi.suffix().toUpper();
0143 
0144         QList<QByteArray> imgExtList = QImageWriter::supportedImageFormats();
0145         imgExtList << "TIF";
0146         imgExtList << "TIFF";
0147         imgExtList << "JPG";
0148         imgExtList << "JPE";
0149 
0150         if (!imgExtList.contains(format.toLatin1()) && !imgExtList.contains(format.toLower().toLatin1()))
0151         {
0152             QMessageBox::critical(nullptr, i18nc("@title:window", "Unsupported Format"),
0153                                   i18n("The target image file format \"%1\" is unsupported.", format));
0154 
0155             qCWarning(DIGIKAM_GEOIFACE_LOG) << "target image file format " << format << " is unsupported!";
0156 
0157             delete imageFileSaveDialog;
0158 
0159             return;
0160         }
0161     }
0162 
0163     if (!newURL.isValid())
0164     {
0165         QMessageBox::critical(nullptr, i18nc("@title:window", "Cannot Save File"),
0166                               i18n("Failed to save file\n\"%1\" to\n\"%2\".",
0167                               newURL.fileName(),
0168                               QDir::toNativeSeparators(newURL.toLocalFile().section(QLatin1Char('/'), -2, -2))));
0169 
0170         qCWarning(DIGIKAM_GEOIFACE_LOG) << "target URL is not valid !";
0171 
0172         delete imageFileSaveDialog;
0173 
0174         return;
0175     }
0176 
0177     // Check for overwrite ----------------------------------------------------------
0178 
0179     if (fi.exists())
0180     {
0181         int result = QMessageBox::warning(nullptr, i18nc("@title:window", "Overwrite File?"),
0182                                           i18n("A file named \"%1\" already "
0183                                                "exists. Are you sure you want "
0184                                                "to overwrite it?",
0185                                                newURL.fileName()),
0186                                                QMessageBox::Yes | QMessageBox::No);
0187 
0188         if (result != QMessageBox::Yes)
0189         {
0190             delete imageFileSaveDialog;
0191 
0192             return;
0193         }
0194     }
0195 
0196     delete imageFileSaveDialog;
0197     QApplication::setOverrideCursor(Qt::WaitCursor);
0198 
0199     QPixmap pixmap = mapWidget()->grab();
0200     pixmap.save(newURL.toLocalFile(), format.toLatin1().constData());
0201 
0202     QApplication::restoreOverrideCursor();
0203 }
0204 
0205 } // namespace Digikam
0206 
0207 #include "moc_mapbackend.cpp"