File indexing completed on 2025-03-09 03:58:53
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-11-24 0007 * Description : Available batch tools list. 0008 * 0009 * SPDX-FileCopyrightText: 2008-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 "toolslistview.h" 0016 0017 // Qt includes 0018 0019 #include <QDrag> 0020 #include <QHeaderView> 0021 #include <QMimeData> 0022 #include <QPainter> 0023 #include <QAction> 0024 #include <QMenu> 0025 #include <QIcon> 0026 0027 // KDE includes 0028 0029 #include <klocalizedstring.h> 0030 0031 // Local includes 0032 0033 #include "dpluginbqm.h" 0034 0035 namespace Digikam 0036 { 0037 0038 ToolListViewGroup::ToolListViewGroup(QTreeWidget* const parent, BatchTool::BatchToolGroup group) 0039 : QTreeWidgetItem(parent) 0040 { 0041 setFlags(Qt::ItemIsEnabled); 0042 0043 setExpanded(true); 0044 setDisabled(false); 0045 0046 m_group = group; 0047 0048 switch (m_group) 0049 { 0050 case BatchTool::ColorTool: 0051 { 0052 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0053 setText(0, i18nc("@title: color tools category", "Color")); 0054 break; 0055 } 0056 0057 case BatchTool::EnhanceTool: 0058 { 0059 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0060 setText(0, i18nc("@title: enhance tools category", "Enhance")); 0061 break; 0062 } 0063 0064 case BatchTool::TransformTool: 0065 { 0066 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0067 setText(0, i18nc("@title: transform tools category", "Transform")); 0068 break; 0069 } 0070 0071 case BatchTool::DecorateTool: 0072 { 0073 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0074 setText(0, i18nc("@title: decorate tools category", "Decorate")); 0075 break; 0076 } 0077 0078 case BatchTool::FiltersTool: 0079 { 0080 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0081 setText(0, i18nc("@title: filters tools category", "Filters")); 0082 break; 0083 } 0084 0085 case BatchTool::ConvertTool: 0086 { 0087 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0088 setText(0, i18nc("@title: convert tools category", "Convert")); 0089 break; 0090 } 0091 0092 case BatchTool::MetadataTool: 0093 { 0094 setIcon(0, QIcon::fromTheme(QLatin1String("digikam"))); 0095 setText(0, i18nc("@title: metadata tools category", "Metadata")); 0096 break; 0097 } 0098 0099 default: // User customized tools. 0100 { 0101 setIcon(0, QIcon::fromTheme(QLatin1String("user-properties"))); 0102 setText(0, i18nc("@title: custom tools category", "Custom Tools")); 0103 break; 0104 } 0105 } 0106 } 0107 0108 ToolListViewGroup::~ToolListViewGroup() 0109 { 0110 } 0111 0112 BatchTool::BatchToolGroup ToolListViewGroup::toolGroup() const 0113 { 0114 return m_group; 0115 } 0116 0117 // --------------------------------------------------------------------------- 0118 0119 ToolListViewItem::ToolListViewItem(ToolListViewGroup* const parent, BatchTool* const tool) 0120 : QTreeWidgetItem(parent) 0121 { 0122 setDisabled(false); 0123 setSelected(false); 0124 0125 m_tool = tool; 0126 0127 if (m_tool) 0128 { 0129 setIcon(0, m_tool->toolIcon()); 0130 setText(0, m_tool->toolTitle()); 0131 setText(1, m_tool->toolDescription()); 0132 } 0133 } 0134 0135 ToolListViewItem::~ToolListViewItem() 0136 { 0137 } 0138 0139 BatchTool* ToolListViewItem::tool() const 0140 { 0141 return m_tool; 0142 } 0143 0144 // --------------------------------------------------------------------------- 0145 0146 ToolsListView::ToolsListView(QWidget* const parent) 0147 : QTreeWidget(parent) 0148 { 0149 setContextMenuPolicy(Qt::CustomContextMenu); 0150 setIconSize(QSize(22, 22)); 0151 setSelectionMode(QAbstractItemView::ExtendedSelection); 0152 setSortingEnabled(false); 0153 setUniformRowHeights(true); 0154 setAllColumnsShowFocus(true); 0155 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0156 setColumnCount(2); 0157 setHeaderHidden(true); 0158 setDragEnabled(true); 0159 header()->setSectionResizeMode(QHeaderView::Stretch); 0160 0161 connect(this, SIGNAL(customContextMenuRequested(QPoint)), 0162 this, SLOT(slotContextMenu())); 0163 } 0164 0165 ToolsListView::~ToolsListView() 0166 { 0167 } 0168 0169 BatchToolsList ToolsListView::toolsList() 0170 { 0171 BatchToolsList list; 0172 0173 QTreeWidgetItemIterator it(this); 0174 0175 while (*it) 0176 { 0177 ToolListViewItem* const item = dynamic_cast<ToolListViewItem*>(*it); 0178 0179 if (item) 0180 { 0181 list.append(item->tool()); 0182 } 0183 0184 ++it; 0185 } 0186 0187 return list; 0188 } 0189 0190 void ToolsListView::addTool(BatchTool* const tool) 0191 { 0192 if (!tool) 0193 { 0194 return; 0195 } 0196 0197 ToolListViewGroup* const parent = findToolGroup(tool->toolGroup()); 0198 0199 if (parent) 0200 { 0201 ToolListViewItem* const item = new ToolListViewItem(parent, tool); 0202 0203 connect(tool, SIGNAL(signalVisible(bool)), 0204 this, SLOT(slotToolVisible(bool))); 0205 0206 item->setHidden(!tool->plugin()->shouldLoaded()); 0207 } 0208 } 0209 0210 void ToolsListView::slotToolVisible(bool b) 0211 { 0212 BatchTool* const tool = dynamic_cast<BatchTool*>(sender()); 0213 0214 if (tool) 0215 { 0216 ToolListViewItem* const item = findTool(tool); 0217 0218 if (item) 0219 { 0220 item->setHidden(!b); 0221 } 0222 } 0223 } 0224 0225 bool ToolsListView::removeTool(BatchTool* const tool) 0226 { 0227 QTreeWidgetItemIterator it(this); 0228 0229 while (*it) 0230 { 0231 ToolListViewItem* const item = dynamic_cast<ToolListViewItem*>(*it); 0232 0233 if (item && (item->tool() == tool)) 0234 { 0235 delete item; 0236 0237 return true; 0238 } 0239 0240 ++it; 0241 } 0242 0243 return false; 0244 } 0245 0246 ToolListViewGroup* ToolsListView::findToolGroup(BatchTool::BatchToolGroup group) 0247 { 0248 QTreeWidgetItemIterator it(this); 0249 0250 while (*it) 0251 { 0252 ToolListViewGroup* const item = dynamic_cast<ToolListViewGroup*>(*it); 0253 0254 if (item && (item->toolGroup() == group)) 0255 { 0256 return item; 0257 } 0258 0259 ++it; 0260 } 0261 0262 return nullptr; 0263 } 0264 0265 bool ToolsListView::hasTool(BatchTool* const tool) 0266 { 0267 return (findTool(tool) ? true : false); 0268 } 0269 0270 ToolListViewItem* ToolsListView::findTool(BatchTool* const tool) 0271 { 0272 QTreeWidgetItemIterator it(this); 0273 0274 while (*it) 0275 { 0276 ToolListViewItem* const item = dynamic_cast<ToolListViewItem*>(*it); 0277 0278 if (item && (item->tool() == tool)) 0279 { 0280 return item; 0281 } 0282 0283 ++it; 0284 } 0285 0286 return nullptr; 0287 } 0288 0289 void ToolsListView::startDrag(Qt::DropActions /*supportedActions*/) 0290 { 0291 QList<QTreeWidgetItem*> items = selectedItems(); 0292 0293 if (items.isEmpty()) 0294 { 0295 return; 0296 } 0297 0298 QPixmap icon(QIcon::fromTheme(QLatin1String("system-run")).pixmap(48)); 0299 int w = icon.width(); 0300 int h = icon.height(); 0301 0302 QPixmap pix(w + 4, h + 4); 0303 QString text(QString::number(items.count())); 0304 0305 QPainter p(&pix); 0306 p.fillRect(0, 0, pix.width() - 1, pix.height() - 1, QColor(Qt::white)); 0307 p.setPen(QPen(Qt::black, 1)); 0308 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1); 0309 p.drawPixmap(2, 2, icon); 0310 QRect r = p.boundingRect(2, 2, w, h, Qt::AlignLeft | Qt::AlignTop, text); 0311 r.setWidth(qMax(r.width(), r.height())); 0312 r.setHeight(qMax(r.width(), r.height())); 0313 p.fillRect(r, QColor(0, 80, 0)); 0314 p.setPen(Qt::white); 0315 QFont f(font()); 0316 f.setBold(true); 0317 p.setFont(f); 0318 p.drawText(r, Qt::AlignCenter, text); 0319 p.end(); 0320 0321 QDrag* drag = new QDrag(this); 0322 drag->setMimeData(mimeData(items)); 0323 drag->setPixmap(pix); 0324 drag->exec(); 0325 } 0326 0327 QStringList ToolsListView::mimeTypes() const 0328 { 0329 QStringList types; 0330 types << QLatin1String("digikam/batchtoolslist"); 0331 0332 return types; 0333 } 0334 0335 void ToolsListView::mouseDoubleClickEvent(QMouseEvent*) 0336 { 0337 if (viewport()->isEnabled()) 0338 { 0339 slotAssignTools(); 0340 } 0341 } 0342 0343 void ToolsListView::slotAssignTools() 0344 { 0345 QList<QTreeWidgetItem*> items = selectedItems(); 0346 0347 if (items.isEmpty()) 0348 { 0349 return; 0350 } 0351 0352 QMultiMap<int, QString> map = itemsToMap(items); 0353 0354 Q_EMIT signalAssignTools(map); 0355 } 0356 0357 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0358 0359 QMimeData* ToolsListView::mimeData(const QList<QTreeWidgetItem*>& items) const 0360 0361 #else 0362 0363 // cppcheck-suppress passedByValue 0364 QMimeData* ToolsListView::mimeData(const QList<QTreeWidgetItem*> items) const // clazy:exclude=function-args-by-ref 0365 0366 #endif 0367 0368 { 0369 QMimeData* const mimeData = new QMimeData(); 0370 QByteArray encodedData; 0371 0372 QDataStream stream(&encodedData, QIODevice::WriteOnly); 0373 QMultiMap<int, QString> map = itemsToMap(items); 0374 stream << map; 0375 0376 mimeData->setData(QLatin1String("digikam/batchtoolslist"), encodedData); 0377 0378 return mimeData; 0379 } 0380 0381 QMultiMap<int, QString> ToolsListView::itemsToMap(const QList<QTreeWidgetItem*>& items) const 0382 { 0383 QMultiMap<int, QString> map; 0384 0385 Q_FOREACH (QTreeWidgetItem* const itm, items) 0386 { 0387 ToolListViewItem* const tlwi = dynamic_cast<ToolListViewItem*>(itm); 0388 0389 if (tlwi) 0390 { 0391 map.insert((int)(tlwi->tool()->toolGroup()), tlwi->tool()->objectName()); 0392 } 0393 } 0394 0395 return map; 0396 } 0397 0398 void ToolsListView::slotContextMenu() 0399 { 0400 QMenu popmenu(this); 0401 QAction* const action = new QAction(QIcon::fromTheme(QLatin1String("list-add")), i18nc("@action", "Assign tools"), this); 0402 0403 connect(action, SIGNAL(triggered(bool)), 0404 this, SLOT(slotAssignTools())); 0405 0406 popmenu.addAction(action); 0407 popmenu.exec(QCursor::pos()); 0408 } 0409 0410 } // namespace Digikam 0411 0412 #include "moc_toolslistview.cpp"