23import QtQuick.Controls
26import org.mauikit.controls as Maui
27import org.mauikit.filebrowsing as FB
29import "private" as Private
106 onGoBackTriggered: control.goBack()
107 onGoForwardTriggered: control.goForward()
113 flickable: control.currentView.flickable
115 floatingFooter:
false
128 property alias currentPath : _browser.path
129 onCurrentPathChanged : _searchField.clear()
144 readonly
property alias settings : _browser.settings
150 readonly
property alias view : _stackView.currentItem
157 readonly
property alias browser : _browser
166 readonly
property alias dropArea : _dropArea
171 property int currentIndex : -1
173 Binding on currentIndex
175 value: currentView.currentIndex
184 readonly
property QtObject currentView : _stackView.currentItem.browser
191 readonly
property FB.FMList currentFMList : view.currentFMList
197 readonly
property Maui.BaseModel currentFMModel : view.currentFMModel
202 readonly
property bool isSearchView : _stackView.currentItem.objectName ===
"searchView"
209 property alias selectionMode: _browser.selectionMode
217 property alias gridItemSize : _browser.gridItemSize
224 property alias listItemSize : _browser.listItemSize
277 property Maui.SelectionBar selectionBar : null
284 readonly
property alias dialog : dialogLoader.item
290 property alias readOnly : _browser.readOnly
297 signal itemClicked(
int index)
303 signal itemDoubleClicked(
int index)
309 signal itemRightClicked(
int index)
316 signal itemLeftEmblemClicked(
int index)
322 signal rightClicked()
328 signal areaClicked(var mouse)
335 signal keyPress(var event)
341 signal urlsDropped(var urls)
343 headBar.forceCenterMiddleContent: isWide
344 headBar.visible: control.settings.searchBarVisible
345 headBar.leftContent: Loader
348 active: control.isSearchView
350 sourceComponent: ToolButton
352 text:
i18nd(
"mauikitfilebrowsing",
"Back")
353 icon.name:
"go-previous"
354 onClicked: control.quitSearch()
358 headBar.middleContent:
Maui.SearchField
362 Layout.fillWidth:
true
363 Layout.maximumWidth: 500
364 Layout.alignment:
Qt.AlignCenter
365 placeholderText: _filterButton.checked ?
i18nd(
"mauikitfilebrowsing",
"Filter") : (
"Search")
366 inputMethodHints:
Qt.ImhNoAutoUppercase
370 if(_filterButton.checked)
372 if(text.includes(
","))
374 control.view.filters = text.split(
",")
377 control.view.filter = text
388 if(_filterButton.checked)
390 control.currentFMModel.clearFilters()
396 if(_filterButton.checked)
397 _searchField.accepted()
400 Keys.enabled: _filterButton.checked
406 control.currentView.forceActiveFocus()
413 icon.name:
"view-filter"
419 control.view.filter =
""
421 _searchField.forceActiveFocus()
426 footBar.
visible: control.currentPath.startsWith(
"trash:/")
428 footerPositioning: ListView.InlineFooter
430 footBar.rightContent:
Button
432 visible: control.currentPath.startsWith(
"trash:/")
433 icon.name:
"trash-empty"
434 text:
i18nd(
"mauikitfilebrowsing",
"Empty Trash")
435 onClicked: FB.
FM.emptyTrash()
445 id: _quitSearchDialogComponent
450 message: i18n("Are you sure you want to quit the current search in progress?")
454 _browser.forceActiveFocus()
463 id: removeDialogComponent
469 property double freedSpace : calculateFreedSpace(urls)
471 title:
i18nd(
"mauikitfilebrowsing",
"Removing %1 files", urls.length)
472 message: i18nd("mauikitfilebrowsing", "Delete %1 \nTotal freed space %2", (
Maui.
Handy.isLinux ? "or move to trash?" : "? This action can not be undone."),
Maui.
Handy.formatSize(freedSpace))
477 text:
i18nd(
"mauikitfilebrowsing",
"Cancel")
478 onTriggered: _removeDialog.close()
483 text:
i18nd(
"mauikitfilebrowsing",
"Delete")
487 control.currentFMList.removeFiles(urls)
493 text:
i18nd(
"mauikitfilebrowsing",
"Trash")
498 control.currentFMList.moveToTrash(urls)
504 function calculateFreedSpace(urls)
509 size += parseFloat(FB.FM.getFileInfo(url).size)
519 id: newDialogComponent
525 title: _newDirOp.checked ?
i18nd(
"mauikitfilebrowsing",
"New folder") :
i18nd(
"mauikitfilebrowsing",
"New file")
526 message:
i18nd(
"mauikitfilebrowsing",
"Create a new folder or a file with a custom name.")
528 template.iconSource: _newDirOp.checked ?
"folder" : FB.
FM.getIconName(textEntry.text)
529 template.iconVisible: true
531 onFinished: (text) =>
533 if(_newDirOp.checked)
535 control.currentFMList.createDir(text)
538 if(_newFileOp.checked)
540 control.currentFMList.createFile(text)
545 textEntry.placeholderText:
i18nd(
"mauikitfilebrowsing",
"Name")
552 display: ToolButton.TextBesideIcon
557 icon.name:
"folder-new"
558 text:
i18nd(
"mauikitfilebrowsing",
"Folder")
559 checked: String(_newDialog.textEntry.text).indexOf(".") < 0
565 icon.name:
"document-new"
566 text:
i18nd(
"mauikitfilebrowsing",
"File")
567 checked: String(_newDialog.textEntry.text).indexOf(".") >= 0
575 id: renameDialogComponent
581 property var item : ({})
583 title:
i18nd(
"mauikitfilebrowsing",
"Rename")
584 message:
i18nd(
"mauikitfilebrowsing",
"Change the name of a file or folder. Write a new name and click Rename to apply the change.")
588 template.iconSource: item.icon
589 template.imageSource: item.thumbnail
590 template.iconSizeHint:
Maui.
Style.iconSizes.huge
592 textEntry.text: item.
label
593 textEntry.placeholderText:
i18nd(
"mauikitfilebrowsing",
"New name")
595 onFinished: control.currentFMList.
renameFile(item.
path, textEntry.text)
603 item = control.currentFMModel.get(control.currentIndex)
605 if(_renameDialog.textEntry.text.lastIndexOf(
".") >= 0)
607 _renameDialog.textEntry.select(0, _renameDialog.textEntry.text.lastIndexOf(
"."))
610 _renameDialog.textEntry.selectAll()
618 id: _newTagDialogComponent
625 property string typingQuery
630 Maui.Theme.colorSet:
Maui.Theme.Complementary
631 visible: _typingTimer.running
632 label.text: typingQuery
634 anchors.top: parent.top
635 showCloseButton:
false
636 anchors.margins:
Maui.Style.space.medium
645 const index = control.currentFMList.indexOfName(typingQuery)
648 console.log(
"FOUDN TRYPIGN IDNEX", index)
649 control.currentIndex = control.currentFMModel.mappedFromSource(index)
658 target: control.currentView
659 ignoreUnknownSignals:
true
661 function onKeyPress(event)
663 const index = control.currentIndex
664 const item = control.currentFMModel.get(index)
666 var pat = /^([a-zA-Z0-9 _-]+)$/
670 typingQuery +=
event.text
671 _typingTimer.restart()
672 event.accepted =
true
678 control.currentFMList.refresh()
679 event.accepted =
true
685 dialogLoader.sourceComponent = renameDialogComponent
687 event.accepted =
true
691 if((
event.key ===
Qt.Key_A) && (
event.modifiers &
Qt.ControlModifier))
694 event.accepted =
true
699 if(control.selectionBar && control.selectionBar.contains(item.path))
701 control.selectionBar.removeAtUri(item.path)
704 control.addToSelection(item)
710 if(
event.key ===
Qt.Key_Return)
712 control.openItem(index)
713 event.accepted =
true
717 if((
event.key ==
Qt.Key_V) && (
event.modifiers &
Qt.ControlModifier))
720 event.accepted =
true
724 if((
event.key ==
Qt.Key_X) && (
event.modifiers &
Qt.ControlModifier))
726 const urls = filterSelection(control.currentPath, item.path)
728 event.accepted = true
732 if((event.key ==
Qt.Key_C) && (event.modifiers &
Qt.ControlModifier))
734 const urls = filterSelection(control.currentPath, item.path)
736 event.accepted = true
740 if(event.key ===
Qt.Key_Delete)
742 const urls = filterSelection(control.currentPath, item.path)
744 event.accepted = true
748 if(event.key ===
Qt.Key_Backspace || event.key ==
Qt.Key_Back)
750 if(control.selectionBar && control.selectionBar.count> 0)
752 control.selectionBar.clear()
758 event.accepted =
true
762 if(
event.key ===
Qt.Key_Escape)
764 if(control.selectionBar && control.selectionBar.count > 0)
766 control.selectionBar.clear()
769 control.view.filter =
""
770 event.accepted =
true
774 if((
event.key ===
Qt.Key_F) && (
event.modifiers &
Qt.ControlModifier))
776 control.toggleSearchBar()
777 event.accepted =
true
780 control.keyPress(event)
783 function onItemsSelected(indexes)
787 control.currentIndex = indexes[0]
788 control.selectIndexes(indexes)
792 function onItemClicked(index)
794 control.currentIndex = index
795 control.itemClicked(index)
796 control.currentView.forceActiveFocus()
799 function onItemDoubleClicked(index)
801 control.currentIndex = index
802 control.itemDoubleClicked(index)
803 control.currentView.forceActiveFocus()
806 function onItemRightClicked(index)
808 control.currentIndex = index
809 control.itemRightClicked(index)
810 control.currentView.forceActiveFocus()
813 function onItemToggled(index)
815 const item = control.currentFMModel.get(index)
817 if(control.selectionBar && control.selectionBar.contains(item.path))
819 control.selectionBar.removeAtUri(item.path)
822 control.addToSelection(item)
824 control.itemLeftEmblemClicked(index)
825 control.currentView.forceActiveFocus()
828 function onAreaClicked(mouse)
830 if(control.isSearchView)
833 if(!
Maui.Handy.isMobile && mouse.button ===
Qt.RightButton)
835 control.rightClicked()
838 control.areaClicked(mouse)
839 control.currentView.forceActiveFocus()
847 enabled: !control.isSearchView
851 enabled: !control.readOnly
852 text:
i18nd(
"mauikitfilebrowsing",
"Copy Here")
853 icon.name: "edit-copy"
856 const urls = _dropMenu.urls.
split(
",")
857 console.log(
"COPY THESE URLS,", urls, _dropMenu.urls)
858 control.currentFMList.copyInto(urls)
864 enabled: !control.readOnly
865 text:
i18nd(
"mauikitfilebrowsing",
"Move Here")
866 icon.name: "edit-move"
869 const urls = _dropMenu.urls.
split(
",")
870 control.currentFMList.cutInto(urls)
876 enabled: !control.readOnly
878 text:
i18nd(
"mauikitfilebrowsing",
"Link Here")
879 icon.name: "edit-link"
882 const urls = _dropMenu.urls.
split(
",")
884 control.currentFMList.createSymlink(urls[i])
890 enabled: FB.FM.isDir(_dropMenu.urls.split(
",")[0])
891 text:
i18nd(
"mauikitfilebrowsing",
"Open Here")
892 icon.name: "folder-open"
895 const urls = _dropMenu.urls.
split(
",")
896 control.browser.path = urls[0]
904 text:
i18nd(
"mauikitfilebrowsing",
"Cancel")
905 icon.name: "dialog-cancel"
906 onTriggered: _dropMenu.close()
915 initialItem: DropArea
919 readonly
property alias browser : _browser
920 readonly
property alias currentFMList : _browser.currentFMList
921 readonly
property alias currentFMModel: _browser.currentFMModel
922 property alias
filter: _browser.filter
923 property alias filters: _browser.filters
924 readonly
property alias title : _browser.title
930 _dropMenu.urls =
drop.urls.join(
",")
932 control.urlsDropped(
drop.urls)
936 opacity: _dropArea.containsDrag ? 0.5 : 1
943 Binding on currentIndex
945 value: control.currentIndex
946 restoreMode: Binding.RestoreBindingOrValue
951 active: (control.currentPath ===
"tags://" || control.currentPath ===
"tags:///") && !control.readOnly
956 anchors.bottom: parent.bottom
957 anchors.rightMargin:
Maui.
Style.toolBarHeight
958 anchors.bottomMargin:
Maui.
Style.toolBarHeight + control.flickable.bottomMargin
962 icon.name :
"list-add"
965 dialogLoader.sourceComponent = _newTagDialogComponent
975 id: _searchBrowserComponent
980 property alias browser : _searchBrowser
982 path: control.currentPath
983 Binding on currentIndex
985 value: control.currentIndex
986 restoreMode: Binding.RestoreBindingOrValue
989 objectName:
"searchView"
990 gridItemSize: control.gridItemSize
991 listItemSize: control.listItemSize
993 currentFMList.autoLoad:
false
994 settings.viewType: control.settings.viewType
995 settings.sortBy: control.settings.sortBy
996 settings.showHiddenFiles: control.settings.showHiddenFiles
997 settings.group: control.settings.group
998 settings.foldersFirst: control.settings.foldersFirst
1004 Component.onCompleted:
1006 control.currentView.forceActiveFocus()
1015 if(urls.length <= 0)
1020 Maui.Handy.copyToClipboard({
"urls": urls},
false)
1029 if(control.readOnly)
1032 if(urls.length <= 0)
1037 Maui.Handy.copyToClipboard({
"urls": urls},
true)
1045 control.currentFMList.paste()
1054 if(urls.length <= 0)
1059 dialogLoader.sourceComponent = removeDialogComponent
1068 function openItem(index)
1070 const item = control.currentFMModel.get(index)
1071 const path = item.path
1073 switch(control.currentFMList.pathType)
1075 case FB.FMList.CLOUD_PATH:
1076 if(item.isdir ===
"true")
1078 control.openFolder(path)
1082 FB.FM.openCloudItem(item)
1086 if(control.selectionMode && item.isdir ==
"false")
1088 if(control.selectionBar && control.selectionBar.contains(item.path))
1090 control.selectionBar.removeAtPath(item.path)
1093 control.addToSelection(item)
1098 if(item.isdir ==
"true")
1100 control.openFolder(path)
1104 control.openFile(path)
1114 function openFile(path)
1123 function openFolder(path)
1125 if(!String(path).length)
1130 if(control.isSearchView)
1132 control.quitSearch()
1135 control.currentPath =
path
1136 _browser.forceActiveFocus()
1144 openFolder(control.currentFMList.previousPath())
1150 function goForward()
1152 openFolder(control.currentFMList.posteriorPath())
1160 openFolder(control.currentFMList.parentPath)
1168 if(_browser.viewType ===
Maui.AltBrowser.ViewType.List)
1169 _browser.currentView.flickable.incrementCurrentIndex()
1171 _browser.currentView.flickable.moveCurrentIndexRight()
1178 function previousItem()
1180 if(_browser.viewType ===
Maui.AltBrowser.ViewType.List)
1181 _browser.currentView.flickable.decrementCurrentIndex()
1183 _browser.currentView.flickable.moveCurrentIndexLeft()
1192 function addToSelection(item)
1194 if(control.selectionBar == null || item.path.startsWith(
"tags://") || item.path.startsWith(
"applications://"))
1199 control.selectionBar.
append(item.path, item)
1206 function selectIndexes(indexes)
1208 if(control.selectionBar == null)
1213 for(var i in indexes)
1214 addToSelection(control.currentFMModel.get(indexes[i]))
1224 if(control.selectionBar == null)
1229 selectIndexes([...Array( control.currentFMList.count ).keys()])
1236 function bookmarkFolder(paths)
1240 FB.FM.bookmark(paths[i])
1247 function toggleSearchBar()
1249 if(control.settings.searchBarVisible)
1251 control.settings.searchBarVisible =
false
1253 _browser.forceActiveFocus()
1256 control.settings.searchBarVisible =
true
1257 _searchField.forceActiveFocus()
1264 function openSearch()
1266 if(!control.isSearchView)
1268 _stackView.push(_searchBrowserComponent)
1270 control.settings.searchBarVisible =
true
1271 _searchField.forceActiveFocus()
1277 function quitSearch()
1279 if(control.currentView.loading)
1281 dialogLoader.sourceComponent = _quitSearchDialogComponent
1282 control.dialog.open()
1287 _browser.forceActiveFocus()
1294 function search(query)
1297 _searchField.text = query
1299 _stackView.currentItem.title = i18nd("mauikitfilebrowsing", "Search: %1", query)
1300 _stackView.currentItem.currentFMList.search(query, true)
1302 _stackView.currentItem.forceActiveFocus()
1311 if(control.isSearchView)
1314 dialogLoader.sourceComponent = newDialogComponent
1316 dialog.forceActiveFocus()
1323 function renameItem()
1325 if(control.isSearchView)
1328 dialogLoader.sourceComponent= renameDialogComponent
1330 dialog.forceActiveFocus()
1337 function removeItem()
1339 if(control.isSearchView)
1342 dialogLoader.sourceComponent= renameDialogComponent
1344 dialog.forceActiveFocus()
1356 function filterSelection(currentPath, itemPath)
1360 if(selectionBar && selectionBar.count > 0 && selectionBar.contains(itemPath))
1362 const uris = selectionBar.uris
1363 for(var uri of uris)
1365 if(String(FB.FM.parentDir(uri)) === currentPath)
1382 function forceActiveFocus()
1384 control.currentView.forceActiveFocus()
The FM class stands for File Management, and exposes methods for file listing, browsing and handling,...
Q_SCRIPTABLE CaptureState status()
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
KIOWIDGETS_EXPORT DropJob * drop(const QDropEvent *dropEvent, const QUrl &destUrl, DropJobFlags dropjobFlags, JobFlags flags=DefaultFlags)
QString path(const QString &relativePath)
const QList< QKeySequence > & close()
const QList< QKeySequence > & cut()
const QList< QKeySequence > & paste()
QString label(StandardShortcut id)
const QList< QKeySequence > & copy()
const QList< QKeySequence > & renameFile()
const QList< QKeySequence > & selectAll()
QString & append(QChar ch)
QString & fill(QChar ch, qsizetype size)
QString left(qsizetype n) const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QTextStream & right(QTextStream &stream)
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)