MauiKit File Browsing

fmlist.cpp
1/*
2 * <one line to give the program's name and a brief idea of what it does.>
3 * Copyright (C) 2018 camilo higuita <milo.h@aol.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "fmlist.h"
20#include "fm.h"
21#include "tagging.h"
22
23#ifdef COMPONENT_SYNCING
24#include "syncing.h"
25#endif
26
27#include <QFuture>
28#include <QThread>
29#include <QtConcurrent/QtConcurrentRun>
30#include <QtConcurrent>
31
32#include <QClipboard>
33#include <QGuiApplication>
34
35#include <KLocalizedString>
36
39 , fm(new FM(this))
40{
41 qRegisterMetaType<FMList *>("const FMList*"); // this is needed for QML to know of FMList in the search method
43 if (this->path == res.path) {
44 this->assignList(res.content);
45 }
46 });
47
48 connect(this->fm, &FM::pathContentReady, [this](QUrl) {
49 Q_EMIT this->preListChanged();
50 this->sortList();
51 this->setStatus({PathStatus::STATUS_CODE::READY, this->list.isEmpty() ? i18n("Nothing here!") : QStringLiteral(""), this->list.isEmpty() ? i18n("This place seems to be empty") : QStringLiteral(""), this->list.isEmpty() ? QStringLiteral("folder-add") : QStringLiteral(""), this->list.isEmpty(), true});
52 Q_EMIT this->postListChanged();
53 Q_EMIT this->countChanged();
54 });
55
56 connect(this->fm, &FM::pathContentItemsChanged, [this](QVector<QPair<FMH::MODEL, FMH::MODEL>> res)
57 {
58 for (const auto &item : std::as_const(res))
59 {
60 const auto index = this->indexOf(FMH::MODEL_KEY::PATH, item.first[FMH::MODEL_KEY::PATH]);
61
62 if (index >= this->list.size() || index < 0)
63 return;
64
65 this->list[index] = item.second;
66 Q_EMIT this->updateModel(index, FMH::modelRoles(item.second));
67 }
68 });
69
71 if (res.path != this->path)
72 return;
73
74 this->appendToList(res.content);
75 });
76
78 if (res.path != this->path)
79 return;
80
81 if (!FMH::fileExists(res.path)) {
82 this->setStatus({PathStatus::STATUS_CODE::ERROR, i18n("Error"), i18n("This URL cannot be listed"), QStringLiteral("documentinfo"), true, false});
83 return;
84 }
85
86 for (const auto &item : std::as_const(res.content)) {
87 const auto index = this->indexOf(FMH::MODEL_KEY::PATH, item[FMH::MODEL_KEY::PATH]);
88 qDebug() << "SUPOSSED TO REMOVED THIS FORM THE LIST" << index << this->list.count() << item[FMH::MODEL_KEY::PATH];
89
90 this->remove(index);
91 }
92
93 this->setStatus({PathStatus::STATUS_CODE::READY, this->list.isEmpty() ? i18n("Nothing here!") : QStringLiteral(""), this->list.isEmpty() ? i18n("This place seems to be empty") : QStringLiteral(""), this->list.isEmpty() ? QStringLiteral("folder-add") : QStringLiteral(""), this->list.isEmpty(), true});
94 });
95
96 connect(this->fm, &FM::warningMessage, [this](const QString &message) {
97 Q_EMIT this->warning(message);
98 });
99
100 connect(this->fm, &FM::loadProgress, [this](const int &percent) {
101 Q_EMIT this->progress(percent);
102 });
103
104 connect(this->fm, &FM::pathContentChanged, [this](const QUrl &path) {
105 qDebug() << "FOLDER PATH CHANGED" << path;
106 if (path != this->path)
107 return;
108 this->sortList();
109 });
110
111 connect(this->fm, &FM::newItem, [this](const FMH::MODEL &item, const QUrl &url) {
112 if (this->path == url) {
113 Q_EMIT this->preItemAppended();
114 this->list << item;
115 Q_EMIT this->postItemAppended();
116 Q_EMIT this->countChanged();
117 }
118 });
119
121 {
122 if(this->getPathType() == FMList::PATHTYPE::TAGS_PATH)
123 {
124 const auto url = this->path.toString();
125 if(url.endsWith(tag))
126 {
127 this->refresh();
128 }
129 }
130 });
131
132 connect(Tagging::getInstance(), &Tagging::tagged, [this](QVariantMap)
133 {
134 if(this->pathType == PATHTYPE::TAGS_PATH)
135 {
136 this->refresh();
137 }
138 });
139
141 {
142 if(this->pathType == PATHTYPE::TAGS_PATH)
143 {
144 this->refresh();
145 }
146 });
147}
148
149void FMList::assignList(const FMH::MODEL_LIST &list)
150{
151 Q_EMIT this->preListChanged();
152 this->list = list;
153 this->sortList();
154 this->setStatus({PathStatus::STATUS_CODE::READY, this->list.isEmpty() ? i18n("Nothing here!") : QStringLiteral(""), this->list.isEmpty() ? i18n("This place seems to be empty") : QStringLiteral(""), this->list.isEmpty() ? QStringLiteral("folder-add") : QStringLiteral(""), this->list.isEmpty(), true});
155 Q_EMIT this->postListChanged();
156 Q_EMIT this->countChanged();
157}
158
159void FMList::appendToList(const FMH::MODEL_LIST &list)
160{
161 Q_EMIT this->preItemsAppended(list.size());
162 this->list << list;
163 Q_EMIT this->postItemAppended();
164 Q_EMIT this->countChanged();
165}
166
167void FMList::clear()
168{
169 Q_EMIT this->preListChanged();
170 this->list.clear();
171 Q_EMIT this->postListChanged();
172 Q_EMIT this->countChanged();
173}
174
175FMH::MODEL_LIST FMList::getTagContent(const QString &tag, const QStringList &filters)
176{
177 if (tag.isEmpty()) {
178 return Tagging::getInstance()->getTags();
179 } else {
180 FMH::MODEL_LIST content;
181 const auto urls = Tagging::getInstance()->getTagUrls(tag, filters, false);
182 for (const auto &url : urls) {
183 content << FMStatic::getFileInfoModel(url);
184 }
185
186 return content;
187 }
188}
189
190void FMList::setList()
191{
192 qDebug() << "PATHTYPE FOR URL" << pathType << this->path.toString() << this->filters << this;
193
194 if(this->path.isEmpty() || !m_autoLoad)
195 {
196 return;
197 }
198
199 this->clear();
200
201 switch (this->pathType)
202 {
203 case FMList::PATHTYPE::TAGS_PATH:
204 this->assignList(getTagContent(this->path.fileName(), QStringList() << this->filters << FMStatic::FILTER_LIST[static_cast<FMStatic::FILTER_TYPE>(this->filterType)]));
205 break; // SYNC
206
207 case FMList::PATHTYPE::CLOUD_PATH:
208 this->fm->getCloudServerContent(this->path, this->filters, this->cloudDepth);
209 break; // ASYNC
210
211 default: {
212 const bool exists = this->path.isLocalFile() ? FMH::fileExists(this->path) : true;
213 if (!exists)
214 this->setStatus({PathStatus::STATUS_CODE::ERROR, i18n("Error"), i18n("This URL cannot be listed"), QStringLiteral("documentinfo"), this->list.isEmpty(), exists});
215 else {
216 const auto _filters = m_mergeFilters ? QStringList() << this->filters << FMStatic::FILTER_LIST[static_cast<FMStatic::FILTER_TYPE>(this->filterType)] : this->filters.isEmpty() ? FMStatic::FILTER_LIST[static_cast<FMStatic::FILTER_TYPE>(this->filterType)] : this->filters;
217 this->fm->getPathContent(this->path, this->hidden, this->onlyDirs, _filters);
218 }
219 break; // ASYNC
220 }
221 }
222}
223
224void FMList::setMergeFilters(bool value)
225{
226 if(value == m_mergeFilters)
227 return;
228
229 m_mergeFilters = value;
230 Q_EMIT mergeFiltersChanged();
231}
232
233bool FMList::mergeFilters() const
234{
235 return m_mergeFilters;
236}
237
238void FMList::reset()
239{
240 this->setList();
241}
242
244{
245 return this->list;
246}
247
248FMList::SORTBY FMList::getSortBy() const
249{
250 return this->sort;
251}
252
253void FMList::setSortBy(const FMList::SORTBY &key)
254{
255 if (this->sort == key)
256 return;
257
258 this->sort = key;
259 Q_EMIT this->sortByChanged();
260}
261
262void FMList::sortList()
263{
264 const FMH::MODEL_KEY key = static_cast<FMH::MODEL_KEY>(this->sort);
265 auto it = this->list.begin();
266
267 const auto sortFunc = [key](const FMH::MODEL &e1, const FMH::MODEL &e2) -> bool
268 {
269 switch (key) {
270 case FMH::MODEL_KEY::SIZE: {
271 if (e1[key].toDouble() > e2[key].toDouble())
272 return true;
273 break;
274 }
275
276 case FMH::MODEL_KEY::ADDDATE:
277 case FMH::MODEL_KEY::MODIFIED:
278 case FMH::MODEL_KEY::DATE: {
279 auto currentTime = QDateTime::currentDateTime();
280
281 auto date1 = QDateTime::fromString(e1[key], Qt::TextDate);
282 auto date2 = QDateTime::fromString(e2[key], Qt::TextDate);
283
284 if (date1.secsTo(currentTime) < date2.secsTo(currentTime))
285 return true;
286
287 break;
288 }
289
290 case FMH::MODEL_KEY::MIME:
291 case FMH::MODEL_KEY::LABEL: {
292 const auto str1 = QString(e1[key]).toLower();
293 const auto str2 = QString(e2[key]).toLower();
294
295 if (str1 < str2)
296 return true;
297 break;
298 }
299
300 default:
301 if (e1[key] < e2[key])
302 return true;
303 }
304
305 return false;
306 };
307
308 if (this->foldersFirst) {
309
310 it = std::partition(this->list.begin(),
311 this->list.end(),
312 [](const FMH::MODEL &e1) -> bool {
313 return e1[FMH::MODEL_KEY::MIME] == QStringLiteral("inode/directory");
314 });
315
316 if(this->list.begin() != it)
317 {
318 std::sort(this->list.begin(), it, sortFunc);
319 }
320 }
321
322 if(it != this->list.end())
323 {
324 std::sort(it, this->list.end(), sortFunc);
325 }
326}
327
328QString FMList::getPathName() const
329{
330 return this->pathName;
331}
332
333QString FMList::getPath() const
334{
335 return this->path.toString();
336}
337
338void FMList::setPath(const QString &path)
339{
341
342 if (this->path == path_)
343 return;
344
345 this->path = path_;
346 m_navHistory.appendPath(this->path);
347
348 this->setStatus({PathStatus::STATUS_CODE::LOADING, i18n("Loading content"), i18n("Almost ready!"), QStringLiteral("view-refresh"), true, false});
349
350 const auto __scheme = this->path.scheme();
351 this->pathName = QDir(this->path.toLocalFile()).dirName();
352
354 this->pathType = FMList::PATHTYPE::CLOUD_PATH;
355
357 this->pathType = FMList::PATHTYPE::APPS_PATH;
358
360 this->pathType = FMList::PATHTYPE::TAGS_PATH;
361 this->pathName = this->path.path();
362
364 this->pathType = FMList::PATHTYPE::TRASH_PATH;
365 this->pathName = QStringLiteral("Trash");
366
368 this->pathType = FMList::PATHTYPE::PLACES_PATH;
369
371 this->pathType = FMList::PATHTYPE::MTP_PATH;
372
374 this->pathType = FMList::PATHTYPE::FISH_PATH;
375
377 this->pathType = FMList::PATHTYPE::REMOTE_PATH;
378
380 this->pathType = FMList::PATHTYPE::DRIVES_PATH;
381 } else {
382 this->pathType = FMList::PATHTYPE::OTHER_PATH;
383 }
384
385 Q_EMIT this->pathNameChanged();
386 Q_EMIT this->pathTypeChanged();
387 Q_EMIT this->pathChanged();
388}
389
390FMList::PATHTYPE FMList::getPathType() const
391{
392 return this->pathType;
393}
394
395QStringList FMList::getFilters() const
396{
397 return this->filters;
398}
399
400void FMList::setFilters(const QStringList &filters)
401{
402 if (this->filters == filters)
403 return;
404
405 this->filters = filters;
406
407 Q_EMIT this->filtersChanged();
408}
409
410void FMList::resetFilters()
411{
412 this->setFilters(QStringList());
413}
414
415FMList::FILTER FMList::getFilterType() const
416{
417 return this->filterType;
418}
419
420void FMList::setFilterType(const FMList::FILTER &type)
421{
422 if (this->filterType == type)
423 return;
424
425 this->filterType = type;
426
427 Q_EMIT this->filterTypeChanged();
428}
429
430void FMList::resetFilterType()
431{
432 this->setFilterType(FMList::FILTER::NONE);
433}
434
435bool FMList::getHidden() const
436{
437 return this->hidden;
438}
439
440void FMList::setHidden(const bool &state)
441{
442 if (this->hidden == state)
443 return;
444
445 this->hidden = state;
446 Q_EMIT this->hiddenChanged();
447}
448
449bool FMList::getOnlyDirs() const
450{
451 return this->onlyDirs;
452}
453
454void FMList::setOnlyDirs(const bool &state)
455{
456 if (this->onlyDirs == state)
457 return;
458
459 this->onlyDirs = state;
460
461 Q_EMIT this->onlyDirsChanged();
462}
463
465{
466 Q_EMIT this->pathChanged();
467}
468
469void FMList::createDir(const QString &name)
470{
471 if(m_readOnly)
472 return;
473
474 if (this->pathType == FMList::PATHTYPE::CLOUD_PATH) {
475#ifdef COMPONENT_SYNCING
476 this->fm->createCloudDir(QString(this->path.toString()).replace(FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::CLOUD_PATH] + "/" + this->fm->sync->getUser(), ""), name);
477#endif
478 } else {
479 FMStatic::createDir(this->path, name);
480 }
481}
482
484{
485 if(m_readOnly)
486 return;
487
488 FMStatic::createFile(this->path, name);
489}
490
491void FMList::renameFile(const QString& url, const QString& newName)
492{
493 if(m_readOnly)
494 return;
495
496 FMStatic::rename(QUrl(url), newName);
497}
498
500{
501 if(m_readOnly)
502 return;
503
505}
506
508{
509 if(m_readOnly)
510 return;
511
513}
514
516{
517 if(m_readOnly)
518 return;
519
520 FMStatic::createSymlink(QUrl(url), this->path);
521}
522
523bool FMList::saveImageFile(const QImage& image)
524{
525 QString fileName = QString(QStringLiteral("%1/pasted_image-0.%2")).arg(path.toLocalFile(), QStringLiteral("png"));
526
527 int idx = 1;
528 while ( QFile::exists( fileName ) )
529 {
530 fileName = QString(QStringLiteral("%1/pasted_image-%2.%3")).arg(path.toLocalFile(), QString::number(idx), QStringLiteral("png"));
531 idx++;
532 }
533
534 return image.save(fileName);
535}
536
537bool FMList::saveTextFile(const QString& data, const QString &format)
538{
539 QString fileName = QString(QStringLiteral("%1/pasted_text-0.%2")).arg(path.toLocalFile(), format);
540
541 int idx = 1;
542 while ( QFile::exists( fileName ) )
543 {
544 fileName = QString(QStringLiteral("%1/pasted_text-%2.%3")).arg(path.toLocalFile(), QString::number(idx), format);
545 idx++;
546 }
547
548 QFile file(fileName);
549
550 if (file.open(QIODevice::ReadWrite))
551 {
552 QTextStream out(&file);
553 out << data;
554 file.close();
555 return true;
556 }
557
558 return false;
559}
560
562{
563 if(m_readOnly)
564 return;
565
566 const QClipboard *clipboard = QGuiApplication::clipboard();
567 const QMimeData *mimeData = clipboard->mimeData();
568
569 if(!mimeData)
570 {
571 qWarning() << "Could not get mime data from the clipboard";
572 return;
573 }
574
575 if (mimeData->hasImage())
576 {
577 saveImageFile(qvariant_cast<QImage>(mimeData->imageData()));
578 } else if (mimeData->hasUrls())
579 {
580 const QByteArray a = mimeData->data(QStringLiteral("application/x-kde-cutselection"));
581 const bool cut = (!a.isEmpty() && a.at(0) == '1');
582
583 if(cut)
584 {
585 cutInto(QUrl::toStringList(mimeData->urls()));
586 // mimeData->clear();
587 }else
588 {
589 copyInto(QUrl::toStringList(mimeData->urls()));
590 }
591
592 } else if (mimeData->hasText())
593 {
594 saveTextFile(mimeData->text(), QStringLiteral("txt"));
595 } else
596 {
597 qWarning() << "Unexpected mime type from clipboard content for performing a paste";
598 }
599}
600
601int FMList::clipboardFilesCount()
602{
604 {
605 const QClipboard *clipboard = QGuiApplication::clipboard();
606 const QMimeData *mimeData = clipboard->mimeData();
607
608
609 if( mimeData->hasUrls())
610 {
611 return mimeData->urls().size();
612
613 }
614
615 if(mimeData->hasImage() || mimeData->hasText())
616 {
617 return 1;
618 }
619 }
620
621 return 0;
622}
623
625{
626 const QClipboard *clipboard = QGuiApplication::clipboard();
627 const QMimeData *mimeData = clipboard->mimeData();
628
629 if(!mimeData)
630 {
631 qWarning() << "Could not get mime data from the clipboard";
632 return false;
633 }
634
635 return mimeData->hasUrls() || mimeData->hasImage() || mimeData->hasText();
636}
637
638
640{
641 if(m_readOnly)
642 return;
643
644 this->fm->copy(QUrl::fromStringList(urls), this->path);
645}
646
648{
649 if(m_readOnly)
650 return;
651
652 this->fm->cut(QUrl::fromStringList(urls), this->path);
653}
654
655void FMList::setDirIcon(const int &index, const QString &iconName)
656{
657 if (index >= this->list.size() || index < 0)
658 return;
659
660 const auto path = QUrl(this->list.at(index)[FMH::MODEL_KEY::PATH]);
661
662 if (!FMStatic::isDir(path))
663 return;
664
665 FMStatic::setDirConf(QUrl(path.toString() + QStringLiteral("/.directory")), QStringLiteral("Desktop Entry"), QStringLiteral("Icon"), iconName);
666
667 this->list[index][FMH::MODEL_KEY::ICON] = iconName;
668 Q_EMIT this->updateModel(index, QVector<int> {FMH::MODEL_KEY::ICON});
669}
670
671const QUrl FMList::getParentPath()
672{
673 switch (this->pathType)
674 {
675 case FMList::PATHTYPE::PLACES_PATH:
676 return FMStatic::parentDir(this->path);
677 default:
678 return this->previousPath();
679 }
680}
681
683{
684 const auto url = m_navHistory.getPosteriorPath();
685
686 if (url.isEmpty())
687 return this->path;
688
689 return url;
690}
691
693{
694 const auto url = m_navHistory.getPreviousPath();
695
696 if (url.isEmpty())
697 return this->path;
698
699 return url;
700}
701
702bool FMList::getFoldersFirst() const
703{
704 return this->foldersFirst;
705}
706
707void FMList::setFoldersFirst(const bool &value)
708{
709 if (this->foldersFirst == value)
710 return;
711
712 Q_EMIT this->preListChanged();
713
714 this->foldersFirst = value;
715
716 Q_EMIT this->foldersFirstChanged();
717
718 this->sortList();
719
720 Q_EMIT this->postListChanged();
721 Q_EMIT this->countChanged();
722}
723
724void FMList::componentComplete()
725{
726 connect(this, &FMList::pathChanged, this, &FMList::setList);
727 connect(this, &FMList::filtersChanged, this, &FMList::setList);
728 connect(this, &FMList::filterTypeChanged, this, &FMList::setList);
729 connect(this, &FMList::hiddenChanged, this, &FMList::setList);
730 connect(this, &FMList::onlyDirsChanged, this, &FMList::setList);
731
732 connect(this, &FMList::sortByChanged, [this]()
733 {
734 if(this->list.size() > 0)
735 {
736 Q_EMIT this->preListChanged();
737 this->sortList();
738 Q_EMIT this->postListChanged();
739 Q_EMIT this->countChanged();
740 }
741 });
742
743 if(!this->path.isEmpty() && this->path.isValid())
744 {
745 this->setList();
746 }
747}
748
749void FMList::search(const QString &query, bool recursive)
750{
751 if(this->path.isEmpty())
752 {
753 this->setStatus({PathStatus::ERROR, i18n("Error"), i18n("No path to perform the search"), QStringLiteral("document-info"), true, false});
754 }
755
756 qDebug() << "SEARCHING FOR" << query << this->path;
757
758 if (!this->path.isLocalFile() || !recursive)
759 { //if the path is not local then search will not be performed and instead will be filtered
760 qWarning() << "URL recived is not a local file. So search will only filter the content" << this->path;
761 this->filterContent(query, this->path);
762 return;
763 }
764
767 const auto res = watcher->future().result();
768
769 this->assignList(res.content);
770 watcher->deleteLater();
771 });
772
775 res.path = path;
776 res.content = FMStatic::search(query, this->path, this->hidden, this->onlyDirs, this->filters);
777 return res;
778 });
779 watcher->setFuture(t1);
780}
781
782void FMList::filterContent(const QString &query, const QUrl &path)
783{
784 if (this->list.isEmpty()) {
785 qDebug() << "Can not filter content. List is empty";
786 return;
787 }
788
789 QFutureWatcher<FMStatic::PATH_CONTENT> *watcher = new QFutureWatcher<FMStatic::PATH_CONTENT>;
791 const auto res = watcher->future().result();
792
793 this->assignList(res.content);
794 watcher->deleteLater();
795 });
796
797 QFuture<FMStatic::PATH_CONTENT> t1 = QtConcurrent::run([=]() -> FMStatic::PATH_CONTENT {
798 FMH::MODEL_LIST m_content;
799 FMStatic::PATH_CONTENT res;
800
801 for (const auto &item : std::as_const(this->list))
802 {
803 if (item[FMH::MODEL_KEY::LABEL].contains(query, Qt::CaseInsensitive) || item[FMH::MODEL_KEY::SUFFIX].contains(query, Qt::CaseInsensitive) || item[FMH::MODEL_KEY::MIME].contains(query, Qt::CaseInsensitive)) {
804 m_content << item;
805 }
806 }
807
808 res.path = path;
809 res.content = m_content;
810 return res;
811 });
812 watcher->setFuture(t1);
813}
814
815int FMList::getCloudDepth() const
816{
817 return this->cloudDepth;
818}
819
820void FMList::setCloudDepth(const int &value)
821{
822 if (this->cloudDepth == value)
823 return;
824
825 this->cloudDepth = value;
826
827 Q_EMIT this->cloudDepthChanged();
828}
829
830PathStatus FMList::getStatus() const
831{
832 return this->m_status;
833}
834
835void FMList::setStatus(const PathStatus &status)
836{
837 this->m_status = status;
838 Q_EMIT this->statusChanged();
839}
840
841void FMList::remove(const int &index)
842{
843 if (index >= this->list.size() || index < 0)
844 return;
845
846 Q_EMIT this->preItemRemoved(index);
847 this->list.remove(index);
848 Q_EMIT this->postItemRemoved();
849 Q_EMIT this->countChanged();
850}
851
853{
854 const auto it = std::find_if(this->items().constBegin(), this->items().constEnd(), [query](const FMH::MODEL &item) -> bool {
855 return item[FMH::MODEL_KEY::LABEL].startsWith(query, Qt::CaseInsensitive);
856 });
857
858 if (it != this->items().constEnd())
859 return (std::distance(this->items().constBegin(), it));
860 else
861 return -1;
862}
863
864bool FMList::getAutoLoad() const
865{
866 return m_autoLoad;
867}
868
869void FMList::setAutoLoad(bool value)
870{
871 if(value == m_autoLoad)
872 {
873 return;
874 }
875
876 m_autoLoad = value;
877 Q_EMIT autoLoadChanged();
878}
879
880bool FMList::readOnly() const
881{
882 return m_readOnly;
883}
884
885void FMList::setReadOnly(bool value)
886{
887 if(m_readOnly == value)
888 return;
889
890 m_readOnly = value;
891 Q_EMIT readOnlyChanged();
892}
893
894int FMList::indexOfFile(const QString& url)
895{
896 const auto it = std::find_if(this->items().constBegin(), this->items().constEnd(), [url](const FMH::MODEL &item) -> bool {
897 return item[FMH::MODEL_KEY::URL] == url;
898 });
899
900 if (it != this->items().constEnd())
901 return (std::distance(this->items().constBegin(), it));
902 else
903 return -1;
904}
905
906
907
int indexOfName(const QString &query)
Given a file-name-query, check if it exists in the current location.
Definition fmlist.cpp:852
const FMH::MODEL_LIST & items() const final override
items
Definition fmlist.cpp:243
void moveToTrash(const QStringList &urls)
Remove and move to the trash the provided set of file URLs.
Definition fmlist.cpp:499
QString path
The URL to location path to proceed listing all of its file entries.
Definition fmlist.h:161
FMList(QObject *parent=nullptr)
FMList.
Definition fmlist.cpp:37
void createFile(const QString &name)
Create a new file.
Definition fmlist.cpp:483
void removeFiles(const QStringList &urls)
Completely remove the set of file URLs provided.
Definition fmlist.cpp:507
void renameFile(const QString &url, const QString &newName)
Rename a file with from a given URL to the a new name provided.
Definition fmlist.cpp:491
FILTER
The possible values to filter the a location content by a mime-type.
Definition fmlist.h:279
@ NONE
Any file type.
Definition fmlist.h:318
PATHTYPE
The different location or places types.
Definition fmlist.h:325
bool readOnly
Whether destructive actions or modifications can be done to the current location contents,...
Definition fmlist.h:210
bool onlyDirs
Whether only directories should be listed.
Definition fmlist.h:173
void search(const QString &query, bool recursive=true)
Start a search - starting from the current location - for a given name query.
Definition fmlist.cpp:749
QStringList filters
The list of string values to filter the listing.
Definition fmlist.h:192
bool foldersFirst
Whether the folders should be sorted first and then the files.
Definition fmlist.h:179
const QUrl previousPath()
The immediate previous path location that was navigated.
Definition fmlist.cpp:692
const QUrl posteriorPath()
The immediate posterior path location that was navigated.
Definition fmlist.cpp:682
SORTBY
The possible values to sort the location contents.
Definition fmlist.h:243
FMList::FILTER filterType
A convenient way to filter the location contents by a file type (mimetype).
Definition fmlist.h:198
void createSymlink(const QString &url)
Create a symbolic link to the given URL in the current location.
Definition fmlist.cpp:515
PathStatus status
The current status of the location contents listing.
Definition fmlist.h:226
void paste()
Handle the paste action.
Definition fmlist.cpp:561
void refresh()
Refresh the model for new changes.
Definition fmlist.cpp:464
bool mergeFilters
Merge the name filters and mimetype filters together for filtering the requested location contentent'...
Definition fmlist.h:237
int cloudDepth
When the location if a remote cloud directory, this allows to define the depth of the levels for list...
Definition fmlist.h:186
QString pathName
The title name of the current location.
Definition fmlist.h:216
FMList::PATHTYPE pathType
The known type of the current location.
Definition fmlist.h:221
void progress(int percent)
Emitted while the file listing is still in progress.
void setDirIcon(const int &index, const QString &iconName)
Changes the icon of a directory by making use of the directory config file.
Definition fmlist.cpp:655
void createDir(const QString &name)
Create a new directory within the current directory.
Definition fmlist.cpp:469
void warning(QString message)
Emitted when the listing process has any error message that needs to be notified.
void cutInto(const QStringList &urls)
Cut/move a list of file URLs to the current directory.
Definition fmlist.cpp:647
void remove(const int &index)
Remove an item from the model, this does not remove the file from the file system.
Definition fmlist.cpp:841
bool hidden
Whether to list the hidden entries.
Definition fmlist.h:167
void copyInto(const QStringList &urls)
Copy a list of file URLs into the current directory.
Definition fmlist.cpp:639
static bool clipboardHasContent()
Whether the clipboard has a supported type of content.
Definition fmlist.cpp:624
static FMH::MODEL_LIST search(const QString &query, const QUrl &path, const bool &hidden=false, const bool &onlyDirs=false, const QStringList &filters=QStringList())
Search for files in a path using name filters.
Definition fmstatic.cpp:79
static const QHash< PATHTYPE_KEY, QString > PATHTYPE_SCHEME
The map of the PATH_TYPE to its associated protocol scheme.
Definition fmstatic.h:339
static QHash< FILTER_TYPE, QStringList > FILTER_LIST
Convenient map set of file type extensions.
Definition fmstatic.h:220
static bool createSymlink(const QUrl &path, const QUrl &where)
Creates a symbolic link to a given file URL.
Definition fmstatic.cpp:394
static QUrl parentDir(const QUrl &path)
Given a file URL return its parent directory.
Definition fmstatic.cpp:127
static bool removeFiles(const QList< QUrl > &urls)
List of files to be removed completely.
Definition fmstatic.cpp:296
static const FMH::MODEL getFileInfoModel(const QUrl &path)
getFileInfoModel
Definition fmstatic.cpp:560
static bool isDir(const QUrl &path)
Whether a local file URL is a directory.
Definition fmstatic.cpp:139
static bool createDir(const QUrl &path, const QString &name)
Creates a new directory given a base path and a name.
Definition fmstatic.cpp:371
static bool rename(const QUrl &url, const QString &name)
Rename a file.
Definition fmstatic.cpp:366
static void setDirConf(const QUrl &path, const QString &group, const QString &key, const QVariant &value)
Write a configuration key-value entry to the directory conf file.
Definition fmstatic.cpp:464
static void moveToTrash(const QList< QUrl > &urls)
Moves to the trashcan the provided file URLs.
Definition fmstatic.cpp:323
FILTER_TYPE
The common file types for filtering.
Definition fmstatic.h:46
static bool createFile(const QUrl &path, const QString &name)
Creates a file given the base directory path and a file name.
Definition fmstatic.cpp:382
@ REMOTE_PATH
Remote locations, such as servers accessed via SSH or FTP.
Definition fmstatic.h:267
@ FISH_PATH
A remote SHH or FTP.
Definition fmstatic.h:312
@ APPS_PATH
The applications location.
Definition fmstatic.h:292
@ TAGS_PATH
A tag location.
Definition fmstatic.h:282
@ DRIVES_PATH
Hard drives locations.
Definition fmstatic.h:272
@ MTP_PATH
MTP path.
Definition fmstatic.h:317
@ CLOUD_PATH
A remote cloud server path.
Definition fmstatic.h:307
@ TRASH_PATH
The trash location.
Definition fmstatic.h:297
@ PLACES_PATH
Local paths, such as the Downloads, Pictures, etc.
Definition fmstatic.h:262
The FM class stands for File Management, and exposes methods for file listing, browsing and handling,...
Definition fm.h:104
void warningMessage(QString message)
Emitted when there is an error.
void cloudServerContentReady(FMStatic::PATH_CONTENT list)
Emitted once the requested contents of the server are ready.
void newItem(FMH::MODEL item, QUrl path)
Emitted when a new item is available in the remote server in the current location.
void pathContentItemsRemoved(FMStatic::PATH_CONTENT list)
Emitted when a set of entries in the current location have been removed.
void loadProgress(int percent)
Emitted with the progress of the listing.
void pathContentReady(QUrl path)
Emitted once the contents of the current location are ready and the listing has finished.
void pathContentItemsChanged(QVector< QPair< FMH::MODEL, FMH::MODEL > > items)
Emitted when the current location entries have changed.
void pathContentItemsReady(FMStatic::PATH_CONTENT list)
Emitted when a set of entries for the current location are ready.
void pathContentChanged(QUrl path)
Emitted when the contents of the current location has changed, either by some new entries being added...
void preItemAppended()
void countChanged()
void updateModel(int index, QVector< int > roles)
void postItemAppended()
void preItemRemoved(int index)
void preItemsAppended(uint count)
MauiList(QObject *parent=nullptr)
void preListChanged()
void postListChanged()
void postItemRemoved()
int indexOf(const FMH::MODEL_KEY &key, const QString &value) const
bool exists(const FMH::MODEL_KEY &key, const QString &value) const
void urlTagged(QString url, QString tag)
Emitted when a tag has been assigened to a file URL.
QList< QUrl > getTagUrls(const QString &tag, const QStringList &filters, const bool &strict=false, const int &limit=9999, const QString &mime=QStringLiteral(""))
Shortcut for getting a list of file URLs associated to a tag, the resulting list of URLs can be filte...
Definition tagging.cpp:348
void tagRemoved(QString tag)
Emitted when a tag has been removed.
void tagged(QVariantMap tag)
Emitted when a new tag has been created.
FMH::MODEL_LIST getTags(const int &limit=5)
Get all the tags available with detailed information packaged as a FMH::MODEL_LIST.
Definition tagging.cpp:374
static Tagging * getInstance()
Returns an instance to the tagging object.
Definition tagging.cpp:70
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
const QVector< int > modelRoles(const MODEL &model)
QVector< MODEL > MODEL_LIST
bool fileExists(const QUrl &path)
QHash< MODEL_KEY, QString > MODEL
char at(qsizetype i) const const
bool isEmpty() const const
const QMimeData * mimeData(Mode mode) const const
QDateTime currentDateTime()
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
bool exists(const QString &fileName)
bool exists() const const
QFuture< T > future() const const
void setFuture(const QFuture< T > &future)
QClipboard * clipboard()
bool save(QIODevice *device, const char *format, int quality) const const
QByteArray data(const QString &mimeType) const const
bool hasImage() const const
bool hasText() const const
bool hasUrls() const const
QVariant imageData() const const
QString text() const const
QList< QUrl > urls() const const
QObject(QObject *parent)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
QObject * parent() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
CaseInsensitive
TextDate
QFuture< T > run(Function function,...)
PreferLocalFile
AssumeLocalFile
QUrl adjusted(FormattingOptions options) const const
QList< QUrl > fromStringList(const QStringList &urls, ParsingMode mode)
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
QString path(ComponentFormattingOptions options) const const
QString toString(FormattingOptions options) const const
QStringList toStringList(const QList< QUrl > &urls, FormattingOptions options)
A location contents structured for convenience.
Definition fmstatic.h:244
FMH::MODEL_LIST content
The contents of the location.
Definition fmstatic.h:254
QUrl path
The location URL holding all of the contents.
Definition fmstatic.h:249
@ LOADING
The content is still loading its contents.
Definition fmlist.h:81
@ READY
The listing has finished successfully.
Definition fmlist.h:91
@ ERROR
The listing of the contents has failed.
Definition fmlist.h:86
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 11:51:37 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.