File indexing completed on 2025-01-19 03:53:52
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-03-13 0007 * Description : Image files selection dialog - Improved Qt based file dialog. 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 "imagedialog_p.h" 0016 0017 namespace Digikam 0018 { 0019 0020 class Q_DECL_HIDDEN ImageDialog::Private 0021 { 0022 0023 public: 0024 0025 explicit Private() 0026 : dlg (nullptr), 0027 provider (nullptr), 0028 showToolTips(true), 0029 toolTipTimer(nullptr), 0030 toolTip (nullptr), 0031 toolTipView (nullptr) 0032 { 0033 } 0034 0035 QStringList fileFormats; 0036 QList<QUrl> urls; 0037 DFileDialog* dlg; 0038 ImageDialogIconProvider* provider; 0039 bool showToolTips; 0040 QTimer* toolTipTimer; 0041 ImageDialogToolTip* toolTip; 0042 QAbstractItemView* toolTipView; 0043 QModelIndex toolTipIndex; 0044 QUrl toolTipUrl; 0045 }; 0046 0047 ImageDialog::ImageDialog(QWidget* const parent, const QUrl& url, bool singleSelect, const QString& caption) 0048 : QObject(parent), 0049 d (new Private) 0050 { 0051 QString all; 0052 d->fileFormats = supportedImageMimeTypes(QIODevice::ReadOnly, all); 0053 qCDebug(DIGIKAM_GENERAL_LOG) << "file formats=" << d->fileFormats; 0054 0055 d->toolTip = new ImageDialogToolTip(); 0056 d->toolTipTimer = new QTimer(this); 0057 0058 connect(d->toolTipTimer, SIGNAL(timeout()), 0059 this, SLOT(slotToolTip())); 0060 0061 d->provider = new ImageDialogIconProvider(); 0062 d->dlg = new DFileDialog(parent); 0063 d->dlg->setWindowTitle(caption); 0064 d->dlg->setDirectoryUrl(url); 0065 d->dlg->setIconProvider(d->provider); 0066 d->dlg->setNameFilters(d->fileFormats); 0067 d->dlg->selectNameFilter(d->fileFormats.last()); 0068 d->dlg->setAcceptMode(QFileDialog::AcceptOpen); 0069 d->dlg->setFileMode(singleSelect ? QFileDialog::ExistingFile : QFileDialog::ExistingFiles); 0070 0071 for (auto* item : d->dlg->findChildren<QAbstractItemView*>()) 0072 { 0073 qCDebug(DIGIKAM_GENERAL_LOG) << item; 0074 item->installEventFilter(this); 0075 item->setMouseTracking(true); 0076 } 0077 0078 d->dlg->exec(); 0079 0080 if (d->dlg && d->dlg->hasAcceptedUrls()) 0081 { 0082 d->urls = d->dlg->selectedUrls(); 0083 } 0084 } 0085 0086 ImageDialog::~ImageDialog() 0087 { 0088 delete d->toolTip; 0089 delete d->dlg; 0090 delete d->provider; 0091 delete d; 0092 } 0093 0094 void ImageDialog::setEnableToolTips(bool val) 0095 { 0096 d->showToolTips = val; 0097 0098 if (!val) 0099 { 0100 hideToolTip(); 0101 } 0102 } 0103 0104 void ImageDialog::hideToolTip() 0105 { 0106 d->toolTipIndex = QModelIndex(); 0107 d->toolTipTimer->stop(); 0108 slotToolTip(); 0109 } 0110 0111 void ImageDialog::slotToolTip() 0112 { 0113 d->toolTip->setData(d->toolTipView, d->toolTipIndex, d->toolTipUrl); 0114 } 0115 0116 bool ImageDialog::acceptToolTip(const QUrl& url) const 0117 { 0118 if (url.isValid()) 0119 { 0120 QFileInfo info(url.toLocalFile()); 0121 0122 if (info.isFile() && !info.isSymLink() && !info.isDir() && !info.isRoot()) 0123 { 0124 return true; 0125 } 0126 } 0127 0128 return false; 0129 } 0130 0131 bool ImageDialog::eventFilter(QObject* obj, QEvent* ev) 0132 { 0133 if (d->dlg) 0134 { 0135 QAbstractItemView* const view = dynamic_cast<QAbstractItemView*>(obj); 0136 0137 if (view) 0138 { 0139 if ((ev->type() == QEvent::HoverMove) && (qApp->mouseButtons() == Qt::NoButton)) 0140 { 0141 QHoverEvent* const hev = dynamic_cast<QHoverEvent*>(ev); 0142 0143 if (hev) 0144 { 0145 QModelIndex index = view->indexAt(view->viewport()->mapFromGlobal(QCursor::pos())); 0146 0147 if (index.isValid()) 0148 { 0149 QString name = index.data(Qt::DisplayRole).toString(); 0150 0151 if (!name.isEmpty()) 0152 { 0153 QUrl url = QUrl::fromLocalFile(QDir::fromNativeSeparators(d->dlg->directoryUrl().toLocalFile() + 0154 QLatin1Char('/') + name)); 0155 0156 if (d->showToolTips) 0157 { 0158 if (!d->dlg->isActiveWindow()) 0159 { 0160 hideToolTip(); 0161 return false; 0162 } 0163 0164 if (index != d->toolTipIndex) 0165 { 0166 hideToolTip(); 0167 0168 if (acceptToolTip(url)) 0169 { 0170 d->toolTipView = view; 0171 d->toolTipIndex = index; 0172 d->toolTipUrl = url; 0173 d->toolTipTimer->setSingleShot(true); 0174 d->toolTipTimer->start(500); 0175 } 0176 } 0177 0178 if ((index == d->toolTipIndex) && !acceptToolTip(url)) 0179 { 0180 hideToolTip(); 0181 } 0182 } 0183 0184 return false; 0185 } 0186 } 0187 else 0188 { 0189 hideToolTip(); 0190 return false; 0191 } 0192 } 0193 } 0194 else if ((ev->type() == QEvent::HoverLeave) || 0195 (ev->type() == QEvent::FocusOut) || 0196 (ev->type() == QEvent::Wheel) || 0197 (ev->type() == QEvent::KeyPress) || 0198 (ev->type() == QEvent::Paint)) 0199 { 0200 hideToolTip(); 0201 return false; 0202 } 0203 } 0204 } 0205 0206 // pass the event on to the parent class 0207 0208 return QObject::eventFilter(obj, ev); 0209 } 0210 0211 QStringList ImageDialog::fileFormats() const 0212 { 0213 return d->fileFormats; 0214 } 0215 0216 QUrl ImageDialog::url() const 0217 { 0218 if (d->urls.isEmpty()) 0219 { 0220 return QUrl(); 0221 } 0222 0223 return d->urls.first(); 0224 } 0225 0226 QList<QUrl> ImageDialog::urls() const 0227 { 0228 return d->urls; 0229 } 0230 0231 QUrl ImageDialog::getImageURL(QWidget* const parent, const QUrl& url, const QString& caption) 0232 { 0233 ImageDialog dlg(parent, url, true, caption.isEmpty() ? i18n("Select an Item") : caption); 0234 0235 if (dlg.url() != QUrl()) 0236 { 0237 return dlg.url(); 0238 } 0239 else 0240 { 0241 return QUrl(); 0242 } 0243 } 0244 0245 QList<QUrl> ImageDialog::getImageURLs(QWidget* const parent, const QUrl& url, const QString& caption) 0246 { 0247 ImageDialog dlg(parent, url, false, caption.isEmpty() ? i18n("Select Items") : caption); 0248 0249 if (!dlg.urls().isEmpty()) 0250 { 0251 return dlg.urls(); 0252 } 0253 else 0254 { 0255 return QList<QUrl>(); 0256 } 0257 } 0258 0259 } // namespace Digikam 0260 0261 #include "moc_imagedialog.cpp"