File indexing completed on 2025-01-19 03:58:03

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-11-21
0007  * Description : Central object for managing bookmarks
0008  *
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2009-2010 by Michael G. Hansen <mike at mghansen dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "gpsbookmarkmodelhelper.h"
0017 
0018 // Qt includes
0019 
0020 #include <QStandardItemModel>
0021 #include <QStandardPaths>
0022 
0023 // KDE includes
0024 
0025 #include <klocalizedstring.h>
0026 
0027 // Local includes
0028 
0029 #include "digikam_debug.h"
0030 #include "bookmarknode.h"
0031 #include "gpsbookmarkowner.h"
0032 #include "gpsundocommand.h"
0033 #include "gpsitemmodel.h"
0034 
0035 namespace Digikam
0036 {
0037 
0038 class Q_DECL_HIDDEN GPSBookmarkModelHelper::Private
0039 {
0040 public:
0041 
0042     explicit Private()
0043       : model          (nullptr),
0044         bookmarkManager(nullptr),
0045         imageModel     (nullptr),
0046         visible        (false)
0047     {
0048     }
0049 
0050     void addBookmarkGroupToModel(BookmarkNode* const);
0051 
0052 public:
0053 
0054     QStandardItemModel* model;
0055     BookmarksManager*   bookmarkManager;
0056     GPSItemModel*       imageModel;
0057     QPixmap             pixmap;
0058     QUrl                bookmarkIconUrl;
0059     bool                visible;
0060 };
0061 
0062 void GPSBookmarkModelHelper::Private::addBookmarkGroupToModel(BookmarkNode* const node)
0063 {
0064     if (node->type() != BookmarkNode::Folder)
0065     {
0066         return;
0067     }
0068 
0069     QList<BookmarkNode*> list = node->children();
0070 
0071     if (list.isEmpty())
0072     {
0073         return;
0074     }
0075 
0076     Q_FOREACH (BookmarkNode* const currentBookmark, list)
0077     {
0078         if (currentBookmark)
0079         {
0080             if (currentBookmark->type() == BookmarkNode::Folder)
0081             {
0082                 addBookmarkGroupToModel(currentBookmark);
0083             }
0084             else
0085             {
0086                 bool okay                        = false;
0087                 const GeoCoordinates coordinates = GeoCoordinates::fromGeoUrl(currentBookmark->url, &okay);
0088 
0089                 if (okay)
0090                 {
0091                     QStandardItem* const item    = new QStandardItem();
0092                     item->setData(currentBookmark->title, Qt::DisplayRole);
0093                     item->setData(QVariant::fromValue(coordinates), GPSBookmarkModelHelper::CoordinatesRole);
0094                     model->appendRow(item);
0095                 }
0096             }
0097         }
0098     }
0099 }
0100 
0101 GPSBookmarkModelHelper::GPSBookmarkModelHelper(BookmarksManager* const bookmarkManager,
0102                                                GPSItemModel* const imageModel,
0103                                                QObject* const parent)
0104     : GeoModelHelper(parent),
0105       d(new Private())
0106 {
0107     d->model           = new QStandardItemModel(this);
0108     d->bookmarkManager = bookmarkManager;
0109     d->imageModel      = imageModel;
0110     d->bookmarkIconUrl = QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation,
0111                                              QLatin1String("digikam/geolocationedit/bookmarks-marker.png")));
0112     d->pixmap          = QPixmap(d->bookmarkIconUrl.toLocalFile());
0113 
0114     connect(d->bookmarkManager, SIGNAL(entryChanged(BookmarkNode*)),
0115             this, SLOT(slotUpdateBookmarksModel()));
0116 
0117     connect(d->bookmarkManager, SIGNAL(entryAdded(BookmarkNode*)),
0118             this, SLOT(slotUpdateBookmarksModel()));
0119 
0120     connect(d->bookmarkManager, SIGNAL(entryRemoved(BookmarkNode*,int,BookmarkNode*)),
0121             this, SLOT(slotUpdateBookmarksModel()));
0122 
0123     slotUpdateBookmarksModel();
0124 }
0125 
0126 GPSBookmarkModelHelper::~GPSBookmarkModelHelper()
0127 {
0128     delete d;
0129 }
0130 
0131 QAbstractItemModel* GPSBookmarkModelHelper::model() const
0132 {
0133     return d->model;
0134 }
0135 
0136 QItemSelectionModel* GPSBookmarkModelHelper::selectionModel() const
0137 {
0138     return nullptr;
0139 }
0140 
0141 bool GPSBookmarkModelHelper::itemCoordinates(const QModelIndex& index,
0142                                              GeoCoordinates* const coordinates) const
0143 {
0144     const GeoCoordinates itemCoordinates = index.data(CoordinatesRole).value<GeoCoordinates>();
0145 
0146     if (coordinates)
0147     {
0148         *coordinates = itemCoordinates;
0149     }
0150 
0151     return itemCoordinates.hasCoordinates();
0152 }
0153 
0154 bool GPSBookmarkModelHelper::itemIcon(const QModelIndex& index,
0155                                       QPoint* const offset,
0156                                       QSize* const size,
0157                                       QPixmap* const pixmap,
0158                                       QUrl* const url) const
0159 {
0160     Q_UNUSED(index)
0161 
0162     if (offset)
0163     {
0164         *offset = QPoint(d->pixmap.width()/2, d->pixmap.height()-1);
0165     }
0166 
0167     if (url)
0168     {
0169         *url = d->bookmarkIconUrl;
0170 
0171         if (size)
0172         {
0173             *size = d->pixmap.size();
0174         }
0175     }
0176     else
0177     {
0178         *pixmap = d->pixmap;
0179     }
0180 
0181     return true;
0182 }
0183 
0184 void GPSBookmarkModelHelper::slotUpdateBookmarksModel()
0185 {
0186     d->model->clear();
0187 
0188     // iterate through all bookmarks
0189 
0190     d->addBookmarkGroupToModel(d->bookmarkManager->bookmarks());
0191 }
0192 
0193 void GPSBookmarkModelHelper::setVisible(const bool state)
0194 {
0195     d->visible = state;
0196 
0197     Q_EMIT signalVisibilityChanged();
0198 }
0199 
0200 GeoModelHelper::PropertyFlags GPSBookmarkModelHelper::modelFlags() const
0201 {
0202     return (FlagSnaps | (d->visible ? FlagVisible : FlagNull));
0203 }
0204 
0205 GeoModelHelper::PropertyFlags GPSBookmarkModelHelper::itemFlags(const QModelIndex&) const
0206 {
0207     return (FlagVisible | FlagSnaps);
0208 }
0209 
0210 void GPSBookmarkModelHelper::snapItemsTo(const QModelIndex& targetIndex,
0211                                          const QList<QModelIndex>& snappedIndices)
0212 {
0213     GeoCoordinates targetCoordinates;
0214 
0215     if (!itemCoordinates(targetIndex, &targetCoordinates))
0216     {
0217         return;
0218     }
0219 
0220     GPSUndoCommand* const undoCommand = new GPSUndoCommand();
0221 
0222     for (int i = 0 ; i < snappedIndices.count() ; ++i)
0223     {
0224         const QPersistentModelIndex itemIndex = snappedIndices.at(i);
0225         GPSItemContainer* const item          = d->imageModel->itemFromIndex(itemIndex);
0226 
0227         GPSDataContainer newData;
0228         newData.setCoordinates(targetCoordinates);
0229 
0230         GPSUndoCommand::UndoInfo undoInfo(itemIndex);
0231         undoInfo.readOldDataFromItem(item);
0232 
0233         item->setGPSData(newData);
0234         undoInfo.readNewDataFromItem(item);
0235 /*
0236         undoCommand->addUndoInfo(GPSUndoCommand::UndoInfo(itemIndex, oldData, newData, oldTagList, newTagList));
0237 */
0238         undoCommand->addUndoInfo(undoInfo);
0239     }
0240 
0241     qCDebug(DIGIKAM_GENERAL_LOG)<<targetIndex.data(Qt::DisplayRole).toString();
0242     undoCommand->setText(i18np("1 image snapped to '%2'",
0243                                "%1 images snapped to '%2'", snappedIndices.count(), targetIndex.data(Qt::DisplayRole).toString()));
0244 
0245     Q_EMIT signalUndoCommand(undoCommand);
0246 }
0247 
0248 } // namespace Digikam
0249 
0250 #include "moc_gpsbookmarkmodelhelper.cpp"