Warning, /maui/mauikit-filebrowsing/src/controls.6/FileDialog.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * Copyright 2018 Camilo Higuita <milo.h@aol.com> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU Library General Public License as 0006 * published by the Free Software Foundation; either version 2, or 0007 * (at your option) any later version. 0008 * 0009 * This program is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 * GNU General Public License for more details 0013 * 0014 * You should have received a copy of the GNU Library General Public 0015 * License along with this program; if not, write to the 0016 * Free Software Foundation, Inc., 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0018 */ 0019 0020 import QtQuick 0021 import QtQml 0022 0023 import QtQuick.Controls 0024 import QtQuick.Layouts 0025 0026 import org.mauikit.controls 1.3 as Maui 0027 import org.mauikit.filebrowsing 1.3 as FB 0028 0029 /** 0030 * @inherit org::mauikit::controls::PopupPage 0031 * 0032 * @brief A dialog to quickly select files for opening or saving. 0033 * 0034 * This controls inherits from MauiKit PopupPage, to checkout its inherited properties refer to the docs. 0035 * @see MauiKit::PopupPage 0036 * 0037 * @note This component makes use of the FileBrowser. 0038 * 0039 * The FileDialog can be in two modes, one for Opening and other for Saving files. 0040 * 0041 * The file dialog allows to have multiple or single selection, 0042 * and filtering content specific to a file type or arbitrary name filters. 0043 * 0044 * @image html filedialog.png 0045 * 0046 * @code 0047 * Maui.Page 0048 * { 0049 * Maui.Controls.showCSD: true 0050 * anchors.fill: parent 0051 * 0052 * Column 0053 * { 0054 * width: 100 0055 * anchors.centerIn: parent 0056 * 0057 * Button 0058 * { 0059 * text: "Open" 0060 * onClicked: 0061 * { 0062 * _dialog.mode = FB.FileDialog.Modes.Open 0063 * _dialog.callback = (paths) => 0064 * { 0065 * console.log("Selected Paths", paths) 0066 * _text.text = paths.join("\n") 0067 * } 0068 * _dialog.open() 0069 * } 0070 * } 0071 * 0072 * Button 0073 * { 0074 * text: "Save" 0075 * onClicked: 0076 * { 0077 * _dialog.mode = FB.FileDialog.Modes.Save 0078 * _dialog.callback = (paths) => 0079 * { 0080 * console.log("Save to", paths) 0081 * _text.text = paths.join("\n") 0082 * } 0083 * _dialog.open() 0084 * } 0085 * } 0086 * 0087 * Text 0088 * { 0089 * id: _text 0090 * } 0091 * } 0092 * } 0093 * 0094 * FB.FileDialog 0095 * { 0096 * id: _dialog 0097 * } 0098 * @endcode 0099 * 0100 * <a href="https://invent.kde.org/maui/mauikit-filebrowser/examples/FileDialog.qml">You can find a more complete example at this link.</a> 0101 */ 0102 Maui.PopupPage 0103 { 0104 id: control 0105 0106 maxHeight: Maui.Handy.isMobile ? parent.height * 0.95 : 500 0107 maxWidth: 700 0108 0109 hint: 1 0110 0111 page.padding: 0 0112 closeButtonVisible: false 0113 headBar.visible: false 0114 0115 /** 0116 * @brief The current path of the directory URL. 0117 * @see FileBrowser::currentPath 0118 */ 0119 property alias currentPath : _browser.currentPath 0120 0121 /** 0122 * @brief The FileBrowser used for listing. 0123 * For more details on how it works check its documentation. 0124 * @property FileBrowser FileDialog::browser 0125 */ 0126 readonly property alias browser : _browser 0127 0128 /** 0129 * @see FileBrowser::selectionBar 0130 * This control already has a predefined SelectionBar, and can be accessed via this alias. 0131 * @property MauiKit::SelectionBar FileDialog::selectionBar 0132 */ 0133 readonly property alias selectionBar: _selectionBar 0134 0135 /** 0136 * @brief If true then only one item can be selected, either for saving or for opening. 0137 * @property bool FileDialog::singleSelection 0138 */ 0139 property alias singleSelection : _selectionBar.singleSelection 0140 0141 /** 0142 * @brief On save mode a text field is visible and this property is used to assign its default text value. 0143 * By default this is set to empty string 0144 */ 0145 property string suggestedFileName : "" 0146 0147 /** 0148 * @brief Show the search bar to enter a search query. 0149 */ 0150 property bool searchBar : false 0151 onSearchBarChanged: if(!searchBar) _browser.quitSearch() 0152 0153 /** 0154 * @brief The two different modes to use with this dialog. 0155 */ 0156 enum Modes 0157 { 0158 /** 0159 * To use this dialog for selecting one or multiple entries for opening. 0160 */ 0161 Open, 0162 0163 /** 0164 * To use this dialog to select a single directory where to save a file entry with a given name. 0165 */ 0166 Save 0167 } 0168 0169 /** 0170 * @brief The current mode in use. 0171 * By default this is set to `FileDialog.Modes.Open` 0172 * @see Modes 0173 */ 0174 property int mode : FileDialog.Modes.Open 0175 0176 /** 0177 * @brief A callback function that will be invoked once the user is done selecting the files. 0178 * This is useful when the file dialog is going to be used for multiple purposes. 0179 * Otherwise you might want to use the `urlsSelected` signal. 0180 * @see urlsSelected 0181 */ 0182 property var callback 0183 0184 /** 0185 * @brief On Save mode a text field is visible, this property gives access to it. 0186 */ 0187 readonly property alias textField: _textField 0188 0189 /** 0190 * @brief Emitted once the URLs have been selected. 0191 * @param urls the selected list of URLs 0192 */ 0193 signal urlsSelected(var urls) 0194 0195 /** 0196 * @brief Emitted once the selection has been done. 0197 * @param urls the selected list of URLs 0198 */ 0199 signal finished(var urls) 0200 0201 actions: 0202 [ 0203 Action 0204 { 0205 text: i18nd("mauikitfilebrowsing", "Cancel") 0206 onTriggered: control.close() 0207 }, 0208 0209 Action 0210 { 0211 text: control.mode === FileDialog.Modes.Save ? i18nd("mauikitfilebrowsing", "Save") : i18nd("mauikitfilebrowsing", "Open") 0212 onTriggered: 0213 { 0214 console.log("CURRENT PATHb", _browser.currentPath+"/"+textField.text) 0215 if(control.mode === modes.SAVE && textField.text.length === 0) 0216 return 0217 0218 if(control.mode === FileDialog.Modes.Save && FB.FM.fileExists(_browser.currentPath+"/"+textField.text)) 0219 { 0220 _confirmationDialog.open() 0221 }else 0222 { 0223 done() 0224 } 0225 } 0226 } 0227 ] 0228 0229 page.footerColumn: [ 0230 0231 Maui.ToolBar 0232 { 0233 visible: control.mode === FileDialog.Modes.Save 0234 width: parent.width 0235 position: ToolBar.Footer 0236 0237 middleContent: TextField 0238 { 0239 id: _textField 0240 Layout.fillWidth: true 0241 placeholderText: i18nd("mauikitfilebrowsing", "File name...") 0242 text: suggestedFileName 0243 } 0244 } 0245 ] 0246 0247 Maui.InfoDialog 0248 { 0249 id: _confirmationDialog 0250 0251 title: i18nd("mauikitfilebrowsing", "Error") 0252 message: i18nd("mauikitfilebrowsing", "A file named '%1' already exists!\n This action will overwrite '%1'. Are you sure you want to do this?", control.textField.text) 0253 template.iconSource: "dialog-warning" 0254 0255 standardButtons: Dialog.Ok | Dialog.Cancel 0256 0257 onAccepted: control.done() 0258 onRejected: close() 0259 } 0260 0261 stack: Maui.SideBarView 0262 { 0263 id: pageRow 0264 0265 Layout.fillHeight: true 0266 Layout.fillWidth: true 0267 0268 sideBar.preferredWidth: 200 0269 sideBar.minimumWidth: 200 0270 sideBarContent: Loader 0271 { 0272 id: sidebarLoader 0273 asynchronous: true 0274 anchors.fill: parent 0275 sourceComponent: FB.PlacesListBrowser 0276 { 0277 onPlaceClicked: 0278 { 0279 //pageRow.currentIndex = 1 0280 _browser.openFolder(path) 0281 } 0282 0283 currentPath: _browser.currentPath 0284 0285 list.groups: [ 0286 FB.FMList.BOOKMARKS_PATH, 0287 FB.FMList.REMOTE_PATH, 0288 FB.FMList.CLOUD_PATH, 0289 FB.FMList.DRIVES_PATH] 0290 } 0291 } 0292 0293 Maui.Page 0294 { 0295 id: _browserLayout 0296 anchors.fill: parent 0297 0298 floatingFooter: true 0299 flickable: _browser.flickable 0300 headBar.visible: true 0301 headerColorSet: Maui.Theme.Header 0302 headBar.farLeftContent: ToolButton 0303 { 0304 icon.name: pageRow.sideBar.visible ? "sidebar-collapse" : "sidebar-expand" 0305 onClicked: pageRow.sideBar.toggle() 0306 checked: pageRow.sideBar.visible 0307 ToolTip.delay: 1000 0308 ToolTip.timeout: 5000 0309 ToolTip.visible: hovered 0310 ToolTip.text: i18nd("mauikitfilebrowsing", "Toogle SideBar") 0311 } 0312 0313 headBar.rightContent:[ 0314 0315 ToolButton 0316 { 0317 id: searchButton 0318 icon.name: "edit-find" 0319 onClicked: browser.toggleSearchBar() 0320 checked: browser.headBar.visible 0321 }, 0322 0323 Loader 0324 { 0325 asynchronous: true 0326 sourceComponent: Maui.ToolButtonMenu 0327 { 0328 icon.name: browser.settings.viewType === FB.FMList.LIST_VIEW ? "view-list-details" : "view-list-icons" 0329 0330 Maui.MenuItemActionRow 0331 { 0332 Action 0333 { 0334 icon.name: "view-hidden" 0335 // text: i18nd("mauikitfilebrowsing", "Hidden Files") 0336 checkable: true 0337 checked: settings.showHiddenFiles 0338 onTriggered: settings.showHiddenFiles = !settings.showHiddenFiles 0339 } 0340 0341 Action 0342 { 0343 icon.name: "folder-new" 0344 onTriggered: browser.newItem() 0345 } 0346 } 0347 0348 Maui.LabelDelegate 0349 { 0350 width: parent.width 0351 isSection: true 0352 label: i18nd("mauikitfilebrowsing", "View type") 0353 } 0354 0355 Action 0356 { 0357 text: i18nd("mauikitfilebrowsing", "List") 0358 icon.name: "view-list-details" 0359 checked: browser.settings.viewType === FB.FMList.LIST_VIEW 0360 checkable: true 0361 onTriggered: 0362 { 0363 if(browser) 0364 { 0365 browser.settings.viewType = FB.FMList.LIST_VIEW 0366 } 0367 } 0368 } 0369 0370 Action 0371 { 0372 text: i18nd("mauikitfilebrowsing", "Grid") 0373 icon.name: "view-list-icons" 0374 checked: browser.settings.viewType === FB.FMList.ICON_VIEW 0375 checkable: true 0376 0377 onTriggered: 0378 { 0379 if(browser) 0380 { 0381 browser.settings.viewType = FB.FMList.ICON_VIEW 0382 } 0383 } 0384 } 0385 0386 MenuSeparator {} 0387 0388 Maui.LabelDelegate 0389 { 0390 width: parent.width 0391 isSection: true 0392 label: i18nd("mauikitfilebrowsing", "Sort by") 0393 } 0394 0395 Action 0396 { 0397 text: i18nd("mauikitfilebrowsing", "Type") 0398 checked: browser.settings.sortBy === FB.FMList.MIME 0399 checkable: true 0400 0401 onTriggered: 0402 { 0403 browser.settings.sortBy = FB.FMList.MIME 0404 } 0405 } 0406 0407 Action 0408 { 0409 text: i18nd("mauikitfilebrowsing", "Date") 0410 checked: browser.settings.sortBy === FB.FMList.DATE 0411 checkable: true 0412 0413 onTriggered: 0414 { 0415 browser.settings.sortBy = FB.FMList.DATE 0416 } 0417 } 0418 0419 Action 0420 { 0421 text: i18nd("mauikitfilebrowsing", "Modified") 0422 checked: browser.settings.sortBy === FB.FMList.MODIFIED 0423 checkable: true 0424 0425 onTriggered: 0426 { 0427 browser.settings.sortBy = FB.FMList.MODIFIED 0428 } 0429 } 0430 0431 Action 0432 { 0433 text: i18nd("mauikitfilebrowsing", "Size") 0434 checked: browser.settings.sortBy === FB.FMList.SIZE 0435 checkable: true 0436 0437 onTriggered: 0438 { 0439 browser.settings.sortBy = FB.FMList.SIZE 0440 } 0441 } 0442 0443 Action 0444 { 0445 text: i18nd("mauikitfilebrowsing", "Name") 0446 checked: browser.settings.sortBy === FB.FMList.LABEL 0447 checkable: true 0448 0449 onTriggered: 0450 { 0451 browser.settings.sortBy = FB.FMList.LABEL 0452 } 0453 } 0454 0455 MenuSeparator{} 0456 0457 MenuItem 0458 { 0459 text: i18nd("mauikitfilebrowsing", "Show Folders First") 0460 checked: browser.settings.foldersFirst 0461 checkable: true 0462 0463 onTriggered: 0464 { 0465 browser.settings.foldersFirst = !browser.settings.foldersFirst 0466 } 0467 } 0468 0469 MenuItem 0470 { 0471 id: groupAction 0472 text: i18nd("mauikitfilebrowsing", "Group") 0473 checkable: true 0474 checked: browser.settings.group 0475 onTriggered: 0476 { 0477 browser.settings.group = !browser.settings.group 0478 } 0479 } 0480 } 0481 } 0482 ] 0483 0484 headBar.leftContent: Loader 0485 { 0486 asynchronous: true 0487 sourceComponent: Maui.ToolActions 0488 { 0489 expanded: true 0490 autoExclusive: false 0491 checkable: false 0492 0493 Action 0494 { 0495 icon.name: "go-previous" 0496 onTriggered : browser.goBack() 0497 } 0498 0499 Action 0500 { 0501 icon.name: "go-up" 0502 onTriggered : browser.goUp() 0503 } 0504 0505 Action 0506 { 0507 icon.name: "go-next" 0508 onTriggered: browser.goNext() 0509 } 0510 } 0511 } 0512 0513 footer: Maui.SelectionBar 0514 { 0515 id: _selectionBar 0516 0517 anchors.horizontalCenter: parent.horizontalCenter 0518 width: Math.min(parent.width-(Maui.Style.space.medium*2), implicitWidth) 0519 maxListHeight: control.height - (Maui.Style.contentMargins*2) 0520 0521 listDelegate: Maui.ListBrowserDelegate 0522 { 0523 width: ListView.view.width 0524 iconSource: model.icon 0525 imageSource: model.thumbnail 0526 label1.text: model.label 0527 label2.text: model.url 0528 } 0529 0530 onExitClicked: 0531 { 0532 _selectionBar.clear() 0533 } 0534 } 0535 0536 FB.FileBrowser 0537 { 0538 id: _browser 0539 anchors.fill: parent 0540 0541 selectionBar: _selectionBar 0542 settings.viewType: FB.FMList.LIST_VIEW 0543 currentPath: FB.FM.homePath() 0544 selectionMode: control.mode === FileDialog.Modes.Open 0545 onItemClicked: (index) => 0546 { 0547 if(Maui.Handy.singleClick) 0548 { 0549 performAction(index) 0550 } 0551 } 0552 0553 onItemDoubleClicked: (index) => 0554 { 0555 if(!Maui.Handy.singleClick) 0556 { 0557 performAction(index) 0558 } 0559 } 0560 0561 function performAction(index) 0562 { 0563 if(currentFMModel.get(index).isdir == "true") 0564 { 0565 openItem(index) 0566 } 0567 0568 switch(control.mode) 0569 { 0570 case FileDialog.Modes.Open : 0571 addToSelection(currentFMModel.get(index)) 0572 break; 0573 0574 case FileDialog.Modes.Save: 0575 textField.text = currentFMModel.get(index).label 0576 break; 0577 } 0578 } 0579 } 0580 } 0581 } 0582 0583 onClosed: 0584 { 0585 _selectionBar.clear() 0586 } 0587 0588 /** 0589 * @private 0590 */ 0591 function done() 0592 { 0593 var paths = _browser.selectionBar && _browser.selectionBar.visible ? _browser.selectionBar.uris : [_browser.currentPath] 0594 0595 if(control.mode === FileDialog.Modes.Save) 0596 { 0597 for(var i in paths) 0598 { 0599 paths[i] = paths[i] + "/" + textField.text 0600 } 0601 0602 // _tagsBar.list.urls = paths 0603 // _tagsBar.list.updateToUrls(_tagsBar.getTags()) 0604 } 0605 0606 control.finished(paths) 0607 0608 // if(control.mode === modes.SAVE) //do it after finished in cas ethe files need to be saved aka exists, before tryign to insert tags 0609 // { 0610 // _tagsBar.list.urls = paths 0611 // _tagsBar.list.updateToUrls(_tagsBar.getTags()) 0612 // } 0613 0614 if(control.callback) 0615 { 0616 control.callback(paths) 0617 } 0618 0619 control.urlsSelected(paths) 0620 control.close() 0621 } 0622 }