File indexing completed on 2025-01-05 03:57:57
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2021-09-27 0007 * Description : Showfoto stack view favorites list 0008 * 0009 * SPDX-FileCopyrightText: 2021-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "showfotostackviewfavoritelist.h" 0016 0017 // Qt includes 0018 0019 #include <QHeaderView> 0020 #include <QMimeData> 0021 #include <QFileInfo> 0022 #include <QDir> 0023 #include <QDrag> 0024 #include <QMenu> 0025 #include <QMimeType> 0026 #include <QMimeDatabase> 0027 0028 // KDE includes 0029 0030 #include <klocalizedstring.h> 0031 0032 // Local include 0033 0034 #include "digikam_debug.h" 0035 #include "digikam_globals.h" 0036 #include "showfotostackviewfavorites.h" 0037 #include "showfotostackviewfavoriteitem.h" 0038 #include "dfileoperations.h" 0039 #include "drawdecoder.h" 0040 0041 using namespace Digikam; 0042 0043 namespace ShowFoto 0044 { 0045 0046 class Q_DECL_HIDDEN ShowfotoStackViewFavoriteList::Private 0047 { 0048 public: 0049 0050 explicit Private() 0051 : parent (nullptr), 0052 draggedItem(nullptr) 0053 { 0054 } 0055 0056 public: 0057 0058 ShowfotoStackViewFavorites* parent; 0059 QTreeWidgetItem* draggedItem; 0060 QString filter; 0061 }; 0062 0063 ShowfotoStackViewFavoriteList::ShowfotoStackViewFavoriteList(ShowfotoStackViewFavorites* const parent) 0064 : QTreeWidget(parent), 0065 d (new Private) 0066 { 0067 d->parent = parent; 0068 0069 setWhatsThis(i18nc("@info", "You can add or remove favorite stacks here.")); 0070 setAlternatingRowColors(true); 0071 setColumnCount(1); 0072 setSortingEnabled(true); 0073 setUniformRowHeights(true); 0074 setAllColumnsShowFocus(true); 0075 sortByColumn(0, Qt::AscendingOrder); 0076 setSelectionMode(QAbstractItemView::SingleSelection); 0077 setHeaderHidden(true); 0078 header()->setSectionResizeMode(QHeaderView::Stretch); 0079 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0080 setContextMenuPolicy(Qt::CustomContextMenu); 0081 0082 setAcceptDrops(true); 0083 setDragEnabled(true); 0084 setDragDropMode(QAbstractItemView::InternalMove); 0085 setDropIndicatorShown(true); 0086 viewport()->setAcceptDrops(true); 0087 viewport()->setMouseTracking(true); 0088 0089 connect(this, SIGNAL(customContextMenuRequested(QPoint)), 0090 this, SLOT(slotContextMenu(QPoint))); 0091 } 0092 0093 ShowfotoStackViewFavoriteList::~ShowfotoStackViewFavoriteList() 0094 { 0095 delete d; 0096 } 0097 0098 void ShowfotoStackViewFavoriteList::slotOpenInFileManager() 0099 { 0100 ShowfotoStackViewFavoriteItem* const fvitem = dynamic_cast<ShowfotoStackViewFavoriteItem*>(currentItem()); 0101 0102 if (fvitem) 0103 { 0104 DFileOperations::openInFileManager(fvitem->urls()); 0105 } 0106 } 0107 0108 void ShowfotoStackViewFavoriteList::slotLoadContents() 0109 { 0110 ShowfotoStackViewFavoriteItem* const fvitem = dynamic_cast<ShowfotoStackViewFavoriteItem*>(currentItem()); 0111 0112 if (fvitem) 0113 { 0114 Q_EMIT signalLoadContentsFromFiles(fvitem->urlsToPaths(), fvitem->currentUrl().toLocalFile()); 0115 } 0116 } 0117 0118 void ShowfotoStackViewFavoriteList::slotContextMenu(const QPoint& pos) 0119 { 0120 QMenu* const ctxmenu = new QMenu(this); 0121 ctxmenu->setTitle(i18nc("@title", "Favorites")); 0122 ctxmenu->addAction(d->parent->toolBarAction(QLatin1String("AddFavorite"))); 0123 ctxmenu->addAction(d->parent->toolBarAction(QLatin1String("AddFolder"))); 0124 0125 ShowfotoStackViewFavoriteItem* const fvitem = dynamic_cast<ShowfotoStackViewFavoriteItem*>(itemAt(pos)); 0126 0127 if (fvitem) 0128 { 0129 if (fvitem->favoriteType() != ShowfotoStackViewFavoriteItem::FavoriteRoot) 0130 { 0131 ctxmenu->addAction(d->parent->toolBarAction(QLatin1String("DelItem"))); 0132 ctxmenu->addAction(d->parent->toolBarAction(QLatin1String("EditItem"))); 0133 } 0134 0135 ctxmenu->addSeparator(); 0136 0137 if (fvitem->favoriteType() == ShowfotoStackViewFavoriteItem::FavoriteItem) 0138 { 0139 ctxmenu->addActions(d->parent->pluginActions()); 0140 ctxmenu->addSeparator(); 0141 0142 QAction* const loadContents = new QAction(QIcon::fromTheme(QLatin1String("media-playlist-normal")), 0143 i18nc("@action: context menu", "Load Contents"), ctxmenu); 0144 ctxmenu->addAction(loadContents); 0145 0146 connect(loadContents, SIGNAL(triggered()), 0147 this, SLOT(slotLoadContents())); 0148 0149 QAction* const openFileMngr = new QAction(QIcon::fromTheme(QLatin1String("folder-open")), 0150 i18nc("@action: context menu", "Open in File Manager"), ctxmenu); 0151 ctxmenu->addAction(openFileMngr); 0152 0153 connect(openFileMngr, SIGNAL(triggered()), 0154 this, SLOT(slotOpenInFileManager())); 0155 } 0156 } 0157 0158 ctxmenu->exec(mapToGlobal(pos)); 0159 0160 delete ctxmenu; 0161 } 0162 0163 QStringList ShowfotoStackViewFavoriteList::mimeTypes() const 0164 { 0165 return QStringList(QLatin1String("text/uri-list")); 0166 } 0167 0168 Qt::DropActions ShowfotoStackViewFavoriteList::supportedDropActions() const 0169 { 0170 return (Qt::CopyAction | Qt::MoveAction); 0171 } 0172 0173 void ShowfotoStackViewFavoriteList::startDrag(Qt::DropActions /*supportedActions*/) 0174 { 0175 QList<QTreeWidgetItem*> items = selectedItems(); 0176 0177 if (items.isEmpty()) 0178 { 0179 return; 0180 } 0181 0182 d->draggedItem = items.first(); 0183 0184 QDrag* const drag = new QDrag(this); 0185 drag->setMimeData(mimeData(items)); 0186 drag->exec(); 0187 } 0188 0189 void ShowfotoStackViewFavoriteList::dragEnterEvent(QDragEnterEvent* e) 0190 { 0191 QTreeWidget::dragEnterEvent(e); 0192 e->accept(); 0193 } 0194 0195 void ShowfotoStackViewFavoriteList::dragMoveEvent(QDragMoveEvent* e) 0196 { 0197 if ((e->source() == this) && 0198 0199 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0200 0201 (dynamic_cast<ShowfotoStackViewFavoriteItem*>(itemAt(e->position().toPoint())) != d->parent->topFavoritesItem())) 0202 0203 #else 0204 0205 (dynamic_cast<ShowfotoStackViewFavoriteItem*>(itemAt(e->pos())) != d->parent->topFavoritesItem())) 0206 0207 #endif 0208 0209 { 0210 QTreeWidget::dragMoveEvent(e); 0211 e->accept(); 0212 0213 return; 0214 } 0215 0216 if (e->mimeData()->hasUrls()) 0217 { 0218 QList<QUrl> mimeurls = e->mimeData()->urls(); 0219 QList<QUrl> urls; 0220 0221 Q_FOREACH (const QUrl& url, mimeurls) 0222 { 0223 if (isReadableImageFile(url.toLocalFile())) 0224 { 0225 urls << url; 0226 } 0227 } 0228 0229 if (!urls.isEmpty()) 0230 { 0231 QTreeWidget::dragMoveEvent(e); 0232 e->accept(); 0233 return; 0234 } 0235 } 0236 0237 e->ignore(); 0238 } 0239 0240 void ShowfotoStackViewFavoriteList::dropEvent(QDropEvent* e) 0241 { 0242 if (e->source() == this) 0243 { 0244 ShowfotoStackViewFavoriteItem* const src = dynamic_cast<ShowfotoStackViewFavoriteItem*>(d->draggedItem); 0245 0246 if (!src) 0247 { 0248 return; 0249 } 0250 0251 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0252 0253 ShowfotoStackViewFavoriteItem* const tgt = dynamic_cast<ShowfotoStackViewFavoriteItem*>(itemAt(e->position().toPoint())); 0254 0255 #else 0256 0257 ShowfotoStackViewFavoriteItem* const tgt = dynamic_cast<ShowfotoStackViewFavoriteItem*>(itemAt(e->pos())); 0258 0259 #endif 0260 0261 if (!tgt) 0262 { 0263 return; 0264 } 0265 0266 for (int i = 0 ; i < tgt->childCount() ; ++i) 0267 { 0268 ShowfotoStackViewFavoriteItem* const chl = dynamic_cast<ShowfotoStackViewFavoriteItem*>(tgt->child(i)); 0269 0270 if (chl && (chl->name() == src->name())) 0271 { 0272 // Ignore event if a target child item with same name than source already exist. 0273 return; 0274 } 0275 } 0276 0277 QTreeWidget::dropEvent(e); 0278 e->acceptProposedAction(); 0279 0280 rebaseHierarchy(tgt); 0281 d->draggedItem = nullptr; 0282 0283 return; 0284 } 0285 0286 if (e->mimeData()->hasUrls()) 0287 { 0288 QList<QUrl> mimeurls = e->mimeData()->urls(); 0289 QList<QUrl> urls; 0290 0291 Q_FOREACH (const QUrl& url, mimeurls) 0292 { 0293 if (isReadableImageFile(url.toLocalFile())) 0294 { 0295 urls << url; 0296 } 0297 } 0298 0299 if (!urls.isEmpty()) 0300 { 0301 QTreeWidget::dropEvent(e); 0302 0303 Q_EMIT signalAddFavorite(urls, urls.first()); 0304 0305 e->acceptProposedAction(); 0306 return; 0307 } 0308 } 0309 0310 e->ignore(); 0311 } 0312 0313 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0314 0315 QMimeData* ShowfotoStackViewFavoriteList::mimeData(const QList<QTreeWidgetItem*>& items) const 0316 0317 #else 0318 // cppcheck-suppress passedByValue 0319 QMimeData* ShowfotoStackViewFavoriteList::mimeData(const QList<QTreeWidgetItem*> items) const // clazy:exclude=function-args-by-ref 0320 0321 #endif 0322 0323 { 0324 QList<QUrl> urls; 0325 0326 Q_FOREACH (QTreeWidgetItem* const itm, items) 0327 { 0328 ShowfotoStackViewFavoriteItem* const vitem = dynamic_cast<ShowfotoStackViewFavoriteItem*>(itm); 0329 0330 if (vitem) 0331 { 0332 urls.append(vitem->urls()); 0333 } 0334 } 0335 0336 QMimeData* const data = new QMimeData; 0337 data->setUrls(urls); 0338 0339 return data; 0340 } 0341 0342 0343 ShowfotoStackViewFavoriteItem* ShowfotoStackViewFavoriteList::findFavoriteByHierarchy(const QString& hierarchy) 0344 { 0345 ShowfotoStackViewFavoriteItem* item = nullptr; 0346 QTreeWidgetItemIterator it(this); 0347 0348 while (*it) 0349 { 0350 item = dynamic_cast<ShowfotoStackViewFavoriteItem*>(*it); 0351 0352 if (item && (hierarchy == item->hierarchy())) 0353 { 0354 return item; 0355 } 0356 0357 ++it; 0358 } 0359 0360 return nullptr; 0361 } 0362 0363 void ShowfotoStackViewFavoriteList::rebaseHierarchy(ShowfotoStackViewFavoriteItem* const parent) 0364 { 0365 if (parent) 0366 { 0367 QTreeWidgetItemIterator it(parent); 0368 0369 while (*it) 0370 { 0371 ShowfotoStackViewFavoriteItem* const item = dynamic_cast<ShowfotoStackViewFavoriteItem*>(*it); 0372 0373 if (item) 0374 { 0375 item->setName(item->name()); 0376 } 0377 0378 ++it; 0379 } 0380 } 0381 } 0382 0383 void ShowfotoStackViewFavoriteList::setFilter(const QString& filter, Qt::CaseSensitivity cs) 0384 { 0385 d->filter = filter; 0386 int query = 0; 0387 ShowfotoStackViewFavoriteItem* fitem = nullptr; 0388 QTreeWidgetItemIterator it(this); 0389 0390 while (*it) 0391 { 0392 fitem = dynamic_cast<ShowfotoStackViewFavoriteItem*>(*it); 0393 0394 if (fitem) 0395 { 0396 if (fitem->name().contains(filter, cs)) 0397 { 0398 query++; 0399 0400 QTreeWidgetItem* item = *it; 0401 0402 do 0403 { 0404 item->setHidden(false); 0405 item = item->parent(); 0406 } 0407 while (item); 0408 } 0409 else 0410 { 0411 fitem->setHidden(true); 0412 } 0413 } 0414 0415 ++it; 0416 } 0417 0418 Q_EMIT signalSearchResult(query); 0419 } 0420 0421 QString ShowfotoStackViewFavoriteList::filter() const 0422 { 0423 return d->filter; 0424 } 0425 0426 } // namespace ShowFoto 0427 0428 #include "moc_showfotostackviewfavoritelist.cpp"