File indexing completed on 2024-04-28 17:06:21
0001 /* 0002 SPDX-FileCopyrightText: 2009 Jan Lepper <krusader@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2009-2022 Krusader Krew <https://krusader.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "krpreviewjob.h" 0009 0010 #include "../FileSystem/fileitem.h" 0011 #include "../defaults.h" 0012 #include "PanelView/krview.h" 0013 #include "PanelView/krviewitem.h" 0014 #include "krpreviews.h" 0015 0016 #include <stdio.h> 0017 0018 // QtWidgets 0019 #include <QWidget> 0020 0021 #define ASSERT(what) \ 0022 if (!(what)) \ 0023 abort(); 0024 0025 // how much items to process by a single job 0026 // view becomes unresponsive during load if set too high 0027 #define MAX_CHUNK_SIZE 50 0028 0029 KrPreviewJob::KrPreviewJob(KrPreviews *parent) 0030 : _job(nullptr) 0031 , _parent(parent) 0032 { 0033 _timer.setSingleShot(true); 0034 _timer.setInterval(0); 0035 connect(&_timer, &QTimer::timeout, this, &KrPreviewJob::slotStartJob); 0036 } 0037 0038 KrPreviewJob::~KrPreviewJob() 0039 { 0040 doKill(); 0041 } 0042 0043 void KrPreviewJob::scheduleItem(KrViewItem *item) 0044 { 0045 if (!_scheduled.contains(item)) { 0046 _scheduled.append(item); 0047 setTotalAmount(KJob::Files, totalAmount(KJob::Files) + 1); 0048 } 0049 if (!_job) 0050 _timer.start(); 0051 } 0052 0053 void KrPreviewJob::removeItem(KrViewItem *item) 0054 { 0055 setTotalAmount(KJob::Files, totalAmount(KJob::Files) - _scheduled.removeAll(item)); 0056 if (_job) { 0057 doKill(); 0058 if (!_scheduled.isEmpty()) 0059 _timer.start(); 0060 } 0061 if (_scheduled.isEmpty()) 0062 emitResult(); 0063 } 0064 0065 void KrPreviewJob::slotFailed(const KFileItem &item) 0066 { 0067 slotGotPreview(item, QPixmap()); 0068 } 0069 0070 void KrPreviewJob::slotGotPreview(const KFileItem &item, const QPixmap &preview) 0071 { 0072 KrViewItem *vi = _hash[item]; 0073 ASSERT(vi); 0074 0075 _scheduled.removeOne(vi); 0076 0077 const FileItem *file = vi->getFileItem(); 0078 _parent->addPreview(file, preview); 0079 vi->redraw(); 0080 0081 setProcessedAmount(KJob::Files, processedAmount(KJob::Files) + 1); 0082 emitPercent(processedAmount(KJob::Files), totalAmount(KJob::Files)); 0083 } 0084 0085 void KrPreviewJob::slotStartJob() 0086 { 0087 ASSERT(_job == nullptr); 0088 ASSERT(!_scheduled.isEmpty()); 0089 0090 _hash.clear(); 0091 sort(); 0092 0093 int size = _parent->_view->fileIconSize(); 0094 0095 KFileItemList list; 0096 for (int i = 0; i < _scheduled.count() && i < MAX_CHUNK_SIZE; i++) { 0097 KFileItem fi(_scheduled[i]->getFileItem()->getUrl(), nullptr, 0); 0098 list.append(fi); 0099 _hash.insert(fi, _scheduled[i]); 0100 } 0101 QStringList allPlugins = KIO::PreviewJob::availablePlugins(); 0102 _job = new KIO::PreviewJob(list, QSize(size, size), &allPlugins); 0103 _job->setOverlayIconAlpha(0); 0104 _job->setOverlayIconSize(0); 0105 _job->setScaleType(KIO::PreviewJob::ScaledAndCached); 0106 connect(_job, &KIO::PreviewJob::gotPreview, this, &KrPreviewJob::slotGotPreview); 0107 connect(_job, &KIO::PreviewJob::failed, this, &KrPreviewJob::slotFailed); 0108 connect(_job, &KIO::PreviewJob::result, this, &KrPreviewJob::slotJobResult); 0109 } 0110 0111 void KrPreviewJob::slotJobResult(KJob *job) 0112 { 0113 (void)job; 0114 0115 if (!disconnect(_job, nullptr, this, nullptr)) 0116 abort(); 0117 0118 _job = nullptr; 0119 _hash.clear(); 0120 0121 if (_scheduled.isEmpty()) 0122 emitResult(); 0123 else 0124 _timer.start(); 0125 } 0126 0127 // move currently visible items to beginning of the list 0128 void KrPreviewJob::sort() 0129 { 0130 for (int i = 0, visible_end = 0; i < _scheduled.count(); i++) { 0131 KrViewItem *item = _scheduled[i]; 0132 if (_parent->_view->widget()->rect().intersects(item->itemRect())) { 0133 if (i != visible_end) 0134 _scheduled.move(i, visible_end); 0135 visible_end++; 0136 } 0137 } 0138 } 0139 0140 bool KrPreviewJob::doKill() 0141 { 0142 _timer.stop(); 0143 if (_job) { 0144 if (!disconnect(_job, nullptr, this, nullptr)) 0145 abort(); 0146 if (!_job->kill()) 0147 abort(); 0148 _job = nullptr; 0149 } 0150 _hash.clear(); 0151 return true; 0152 }