Warning, /maui/index-fm/src/main.qml is written in an unsupported language. File is not indexed.
0001 // Copyright 2018-2020 Camilo Higuita <milo.h@aol.com> 0002 // Copyright 2018-2020 Nitrux Latinoamericana S.C. 0003 // 0004 // SPDX-License-Identifier: GPL-3.0-or-later 0005 0006 import QtQuick 2.15 0007 import QtQuick.Controls 2.15 0008 import QtQuick.Layouts 1.3 0009 0010 import Qt.labs.settings 1.0 0011 0012 import org.mauikit.controls 1.3 as Maui 0013 0014 import org.mauikit.filebrowsing 1.3 as FB 0015 import org.maui.index 1.0 as Index 0016 0017 import "widgets" 0018 import "widgets/views" 0019 import "widgets/previewer" 0020 0021 Maui.ApplicationWindow 0022 { 0023 id: root 0024 title: currentTab ? currentTab.title : "" 0025 0026 Maui.Style.accentColor : Maui.Handy.isAndroid ? "#6765C2": undefined 0027 0028 readonly property alias dialog : dialogLoader.item 0029 readonly property alias selectionBar : _browserView.selectionBar 0030 readonly property alias pathBar: _pathBarLoader.item 0031 0032 readonly property alias currentTab : _browserView.currentTab 0033 readonly property alias currentSplit : _browserView.currentSplit 0034 readonly property FB.FileBrowser currentBrowser : currentSplit.browser 0035 0036 readonly property alias appSettings : settings 0037 0038 property alias currentTabIndex : _browserView.currentTabIndex 0039 property bool selectionMode: false 0040 0041 Maui.Notify 0042 { 0043 id: _notifyOperation 0044 componentName: "org.kde.index" 0045 eventId: "fileOperation" 0046 } 0047 0048 Settings 0049 { 0050 id: settings 0051 category: "Browser" 0052 0053 property bool showHiddenFiles: false 0054 property bool showThumbnails: true 0055 property bool previewFiles : Maui.Handy.isMobile 0056 property bool restoreSession: false 0057 property bool overviewStart : false 0058 0059 property int viewType : FB.FMList.LIST_VIEW 0060 property int listSize : 0 // s-m-l-x-xl 0061 property int gridSize : 3 // s-m-l-x-xl 0062 0063 property var lastSession : [[({'path': FB.FM.homePath()})]] 0064 property int lastTabIndex : 0 0065 0066 property bool quickSidebarSection : true 0067 property var sidebarSections : [ 0068 FB.FMList.BOOKMARKS_PATH, 0069 FB.FMList.REMOTE_PATH, 0070 FB.FMList.REMOVABLE_PATH, 0071 FB.FMList.DRIVES_PATH] 0072 0073 0074 property alias sideBarWidth : _sideBarView.sideBar.preferredWidth 0075 0076 property bool dirConf : true 0077 property bool syncTerminal: true 0078 property bool previewerWindow: Maui.Handy.isLinux && !Maui.Handy.isMobile 0079 property bool autoPlayPreviews: true 0080 property bool terminalFollowsColorScheme: true 0081 property string terminalColorScheme: "Maui-Dark" 0082 } 0083 0084 Settings 0085 { 0086 id: sortSettings 0087 category: "Sorting" 0088 property bool foldersFirst: true 0089 property int sortBy: FB.FMList.MODIFIED 0090 property int sortOrder: Qt.AscendingOrder 0091 property bool group: false 0092 } 0093 0094 onClosing: (close) => 0095 { 0096 close.accepted = !settings.restoreSession 0097 var tabs = [] 0098 0099 for(var i = 0; i < _browserView.browserList.count; i ++) 0100 { 0101 const tab = _browserView.browserList.contentModel.get(i) 0102 var tabPaths = [] 0103 0104 for(var j = 0; j < tab.model.count; j++) 0105 { 0106 const browser = tab.model.get(j) 0107 const tabMap = {'path': browser.currentPath} 0108 tabPaths.push(tabMap) 0109 0110 console.log("saving tabs", browser.currentPath) 0111 0112 } 0113 0114 tabs.push(tabPaths) 0115 } 0116 0117 console.log("saving tabs", tabs.length) 0118 0119 settings.lastSession = tabs 0120 settings.lastTabIndex = currentTabIndex 0121 0122 close.accepted = true 0123 } 0124 0125 Component 0126 { 0127 id: _tagsDialogComponent 0128 0129 FB.TagsDialog 0130 { 0131 taglist.strict: false 0132 composerList.strict: false 0133 0134 onTagsReady: 0135 { 0136 composerList.updateToUrls(tags) 0137 } 0138 } 0139 } 0140 0141 Component 0142 { 0143 id: _openWithDialogComponent 0144 FB.OpenWithDialog {} 0145 } 0146 0147 Component 0148 { 0149 id: _configDialogComponent 0150 SettingsDialog {} 0151 } 0152 0153 Component 0154 { 0155 id: _shortcutsDialogComponent 0156 ShortcutsDialog {} 0157 } 0158 0159 Component 0160 { 0161 id: _extractDialogComponent 0162 0163 Maui.InputDialog 0164 { 0165 id: _extractDialog 0166 0167 title: i18n("Extract") 0168 message: i18n("Extract the content of the compressed file into a new or existing subdirectory or inside the current directory.") 0169 0170 onFinished: 0171 { 0172 _compressedFile.extract(currentBrowser.currentPath, text) 0173 } 0174 } 0175 } 0176 0177 Component 0178 { 0179 id: _compressDialogComponent 0180 0181 Maui.FileListingDialog 0182 { 0183 id: _compressDialog 0184 0185 title: i18np("Compress %1 file", "Compress %1 files", urls.length) 0186 message: i18n("Compress selected files into a new file.") 0187 0188 TextField 0189 { 0190 id: _textEntry 0191 Layout.fillWidth: true 0192 placeholderText: i18n("Archive name...") 0193 } 0194 0195 function clear() 0196 { 0197 _textEntry.clear() 0198 compressType.type = "zip" 0199 urls = [] 0200 _showCompressedFiles.checked = false 0201 } 0202 0203 Maui.ToolActions 0204 { 0205 id: compressType 0206 autoExclusive: true 0207 expanded: true 0208 property string type: "zip" 0209 0210 Action 0211 { 0212 text: ".ZIP" 0213 checked: compressType.type === "zip" 0214 } 0215 0216 Action 0217 { 0218 text: ".TAR" 0219 checked: compressType.type === "tar" 0220 } 0221 0222 Action 0223 { 0224 text: ".7ZIP" 0225 checked: compressType.type === "7zip" 0226 } 0227 } 0228 0229 actions: 0230 [ 0231 Action 0232 { 0233 text: i18n("Close") 0234 onTriggered: _compressDialog.close() 0235 }, 0236 0237 Action 0238 { 0239 text: i18n("Compress") 0240 onTriggered: 0241 { 0242 var error = _compressedFile.compress(urls, currentBrowser.currentPath, _textEntry.text, compressType.currentIndex) 0243 0244 if(error) 0245 { 0246 root.notify("","Compress Error", "Some error occurs. Maybe current user does not have permission for writing in this directory.") 0247 } 0248 else 0249 { 0250 _compressDialog.close() 0251 } 0252 } 0253 } 0254 ] 0255 } 0256 } 0257 0258 Component 0259 { 0260 id: _previewerComponent 0261 0262 PreviewerDialog 0263 { 0264 onClosed: 0265 { 0266 dialogLoader.sourceComponent = null 0267 } 0268 } 0269 } 0270 0271 Component 0272 { 0273 id: _previewerWindowComponent 0274 PreviewerWindow 0275 { 0276 onClosing: destroy() 0277 } 0278 } 0279 0280 Component 0281 { 0282 id: _browserComponent 0283 BrowserLayout {} 0284 } 0285 0286 Maui.NotifyAction 0287 { 0288 id: _extractionFinishedAction 0289 text: i18n("Open folder") 0290 } 0291 0292 Index.CompressedFile 0293 { 0294 id: _compressedFile 0295 0296 onExtractionFinished: 0297 { 0298 _notifyOperation.title = i18n("Extracted") 0299 _notifyOperation.message = i18n("File was extracted") 0300 _notifyOperation.defaultAction = _extractionFinishedAction 0301 _notifyOperation.iconName = "application-x-archive" 0302 _notifyOperation.send() 0303 } 0304 } 0305 0306 Loader 0307 { 0308 id: dialogLoader 0309 } 0310 0311 Maui.SideBarView 0312 { 0313 id: _sideBarView 0314 anchors.fill: parent 0315 sideBar.preferredWidth: 200 0316 0317 sideBar.minimumWidth: 200 0318 sideBar.autoShow: true 0319 sideBar.autoHide: true 0320 sideBarContent: PlacesSideBar 0321 { 0322 id: placesSidebar 0323 anchors.fill: parent 0324 } 0325 0326 Maui.Page 0327 { 0328 anchors.fill: parent 0329 headBar.visible: false 0330 footer: Loader 0331 { 0332 id: _actionBarLoader 0333 width: parent.width 0334 asynchronous: true 0335 visible: active && !_homeViewComponent.visible 0336 sourceComponent: ActionBar {} 0337 } 0338 0339 StackView 0340 { 0341 id: _stackView 0342 anchors.fill: parent 0343 clip: false 0344 0345 initialItem: BrowserView 0346 { 0347 id: _browserView 0348 0349 flickable: currentBrowser.flickable 0350 0351 headBar.forceCenterMiddleContent: width > 1000 0352 altHeader: Maui.Handy.isMobile 0353 showCSDControls: true 0354 0355 headBar.farLeftContent: Loader 0356 { 0357 asynchronous: true 0358 active: _sideBarView.sideBar.collapsed 0359 visible: active 0360 0361 sourceComponent: ToolButton 0362 { 0363 icon.name: _sideBarView.sideBar.visible ? "sidebar-collapse" : "sidebar-expand" 0364 onClicked: _sideBarView.sideBar.toggle() 0365 checked: _sideBarView.sideBar.visible 0366 ToolTip.delay: 1000 0367 ToolTip.timeout: 5000 0368 ToolTip.visible: hovered 0369 ToolTip.text: i18n("Toggle sidebar") 0370 } 0371 } 0372 0373 headBar.middleContent: Loader 0374 { 0375 id: _pathBarLoader 0376 0377 asynchronous: true 0378 0379 Layout.fillWidth: true 0380 Layout.minimumWidth: 100 0381 0382 sourceComponent: Item 0383 { 0384 implicitHeight: _pathBar.implicitHeight 0385 readonly property alias pathBar: _pathBar 0386 0387 PathBar 0388 { 0389 id: _pathBar 0390 anchors.centerIn: parent 0391 width: Math.min(parent.width, implicitWidth) 0392 0393 url: currentBrowser.currentPath 0394 onPathChanged: (path) => currentBrowser.openFolder(path) 0395 0396 onHomeClicked: currentBrowser.openFolder(FB.FM.homePath()) 0397 onPlaceClicked: (path) => 0398 { 0399 if(path === currentBrowser.currentPath) 0400 { 0401 openMenu() 0402 } 0403 else 0404 { 0405 currentBrowser.openFolder(path) 0406 } 0407 } 0408 0409 onPlaceRightClicked: (path) => 0410 { 0411 _pathBarmenu.path = path 0412 _pathBarmenu.show() 0413 } 0414 0415 function openMenu() 0416 { 0417 _actionBarLoader.item.openMainMenu() 0418 } 0419 0420 Maui.ContextualMenu 0421 { 0422 id: _pathBarmenu 0423 property url path 0424 0425 MenuItem 0426 { 0427 text: i18n("Bookmark") 0428 icon.name: "bookmark-new" 0429 onTriggered: currentBrowser.bookmarkFolder([_pathBarmenu.path]) 0430 } 0431 0432 MenuItem 0433 { 0434 text: i18n("Open in New Tab") 0435 icon.name: "tab-new" 0436 onTriggered: openTab(_pathBarmenu.path) 0437 } 0438 0439 MenuItem 0440 { 0441 visible: root.currentTab.count === 1 0442 text: i18n("Open in Split View") 0443 icon.name: "view-split-left-right" 0444 onTriggered: currentTab.split(_pathBarmenu.path, Qt.Horizontal) 0445 } 0446 0447 } 0448 } 0449 } 0450 } 0451 } 0452 0453 Loader 0454 { 0455 id: _homeViewComponent 0456 asynchronous: true 0457 visible: StackView.status === StackView.Active 0458 active: StackView.status === StackView.Active || item 0459 0460 sourceComponent: HomeView {} 0461 0462 BusyIndicator 0463 { 0464 running: parent.status === Loader.Loading 0465 anchors.centerIn: parent 0466 } 0467 } 0468 } 0469 } 0470 } 0471 0472 Component.onCompleted: 0473 { 0474 setAndroidStatusBarColor() 0475 0476 if(settings.overviewStart) 0477 { 0478 root.openTab(FB.FM.homePath()) 0479 0480 _stackView.push(_homeViewComponent) 0481 return 0482 } 0483 0484 if(initPaths.length) 0485 { 0486 for(var path of initPaths) 0487 root.openTab(path) 0488 return; 0489 } 0490 0491 const tabs = settings.lastSession 0492 if(settings.restoreSession && tabs.length) 0493 { 0494 console.log("restore", tabs.length) 0495 restoreSession(tabs) 0496 return 0497 } 0498 0499 root.openTab(FB.FM.homePath()) 0500 } 0501 0502 function setAndroidStatusBarColor() 0503 { 0504 if(Maui.Handy.isAndroid) 0505 { 0506 const dark = Maui.Style.styleType === Maui.Style.Dark 0507 Maui.Android.statusbarColor( Maui.Theme.backgroundColor, !dark) 0508 Maui.Android.navBarColor( Maui.Theme.backgroundColor, !dark) 0509 } 0510 } 0511 0512 function toogleSplitView() 0513 { 0514 if(currentTab.count === 2) 0515 currentTab.pop() 0516 else 0517 currentTab.split(currentBrowser.currentPath, Qt.Horizontal) 0518 } 0519 0520 function openConfigDialog() 0521 { 0522 dialogLoader.sourceComponent = _configDialogComponent 0523 dialog.open() 0524 } 0525 0526 function closeTab(index) 0527 { 0528 _browserView.browserList.closeTab(index) 0529 } 0530 0531 function openDirs(paths) 0532 { 0533 for(var path of paths) 0534 root.openTab(path) 0535 } 0536 0537 function openTab(path, path2 = "") 0538 { 0539 if(path) 0540 { 0541 if(_stackView.depth === 2) 0542 _stackView.pop() 0543 0544 0545 _browserView.browserList.addTab(_browserComponent, {'path': path, 'path2': path2}, false) 0546 } 0547 } 0548 0549 function tagFiles(urls) 0550 { 0551 if(urls.length <= 0) 0552 { 0553 return 0554 } 0555 0556 dialogLoader.sourceComponent = _tagsDialogComponent 0557 dialog.composerList.urls =urls 0558 dialog.open() 0559 } 0560 0561 /** 0562 * For this to work the implementation needs to have passed a selectionBar 0563 **/ 0564 function openWith(urls) 0565 { 0566 if(urls.length <= 0) 0567 { 0568 return 0569 } 0570 0571 if(Maui.Handy.isAndroid) 0572 { 0573 FB.FM.openUrl(urls[0]) 0574 return 0575 } 0576 0577 dialogLoader.sourceComponent = _openWithDialogComponent 0578 dialog.urls = urls 0579 dialog.open() 0580 } 0581 0582 /** 0583 * 0584 **/ 0585 function shareFiles(urls) 0586 { 0587 if(urls.length <= 0) 0588 { 0589 return 0590 } 0591 0592 Maui.Platform.shareFiles(urls) 0593 } 0594 0595 function openPreview(model, index) 0596 { 0597 if(appSettings.previewerWindow) 0598 { 0599 var previewer = _previewerWindowComponent.createObject(root) 0600 previewer.previewer.setData(model, index) 0601 }else 0602 { 0603 dialogLoader.sourceComponent = _previewerComponent 0604 dialog.previewer.setData(model, index) 0605 dialog.open() 0606 } 0607 } 0608 0609 function restoreSession(tabs) 0610 { 0611 for(var i = 0; i < tabs.length; i++ ) 0612 { 0613 const tab = tabs[i] 0614 0615 if(tab.length === 2) 0616 { 0617 root.openTab(tab[0].path, tab[1].path) 0618 }else 0619 { 0620 root.openTab(tab[0].path) 0621 } 0622 } 0623 0624 currentTabIndex = settings.lastTabIndex 0625 } 0626 0627 function toggleSection(section) 0628 { 0629 placesSidebar.list.toggleSection(section) 0630 appSettings.sidebarSections = placesSidebar.list.groups 0631 } 0632 0633 function isUrlOpen(url : string) : bool 0634 { 0635 return _browserView.isUrlOpen(url); 0636 } 0637 }