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 }