diff --git a/app/Index.js b/app/Index.js index 7a91315..e17abf2 100644 --- a/app/Index.js +++ b/app/Index.js @@ -1,4 +1,32 @@ function bookmarkFolders(urls) { } + +function showPreviews() +{ + browser.previews = !browser.previews + Maui.FM.setDirConf(browser.currentPath+"/.directory", "MAUIFM", "ShowThumbnail", browser.previews) +} + +function showHiddenFiles() +{ + var state = Maui.FM.dirConf(browser.currentPath+"/.directory").hidden + Maui.FM.setDirConf(browser.currentPath+"/.directory", "Settings", "HiddenFilesShown", !state) + browser.refresh() +} + +function createFolder() +{ + newFolderDialog.open() +} + +function createFile() +{ + newFileDialog.open() +} + +function bookmarkFolder() +{ + browser.bookmarkFolder([browser.currentPath]) +} diff --git a/app/app.pro b/app/app.pro index 0426718..b261d16 100644 --- a/app/app.pro +++ b/app/app.pro @@ -1,62 +1,62 @@ QT += qml QT += quick QT += sql CONFIG += c++11 - TARGET = index +DESTDIR = $$OUT_PWD/../ linux:unix:!android { message(Building for Linux KDE) include($$PWD/../kde/kde.pri) } else:android { message(Building helpers for Android) include($$PWD/../android/android.pri) include($$PWD/../3rdparty/kirigami/kirigami.pri) include($$PWD/../mauikit/mauikit.pri) DEFINES += STATIC_KIRIGAMI } else { message("Unknown configuration") } # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += main.cpp \ index.cpp RESOURCES += qml.qrc \ assets.qrc \ # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Additional import path used to resolve QML modules just for Qt Quick Designer QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ index.h \ inx.h include($$PWD/../install.pri) DISTFILES += \ ../org.kde.index.desktop diff --git a/app/main.qml b/app/main.qml index 96c8f83..6fe599f 100644 --- a/app/main.qml +++ b/app/main.qml @@ -1,154 +1,168 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.0 as Kirigami import org.kde.mauikit 1.0 as Maui import QtQuick.Window 2.0 import QtQuick.Controls.Material 2.1 import "widgets" import "widgets/views" import "widgets/sidebar" import "widgets_templates" import "Index.js" as INX Maui.ApplicationWindow { id: root title: browser.currentPath property int sidebarWidth: placesSidebar.isCollapsed ? placesSidebar.iconSize * 2: Kirigami.Units.gridUnit * (isMobile ? 14 : 11) pageStack.defaultColumnWidth: sidebarWidth pageStack.initialPage: [placesSidebar, browser] pageStack.interactive: isMobile pageStack.separatorVisible: pageStack.wideMode accentColor: altColor highlightColor: "#8682dd" altColor: "#43455a" altToolBars: false altColorText: "#ffffff" + property color headBarColor: "#bdc8e5" +// headBarBG.color: headBarColor headBar.middleContent: Maui.PathBar { id: pathBar +// pathBarBG.color:Qt.lighter(headBarColor, 1.1) height: iconSizes.big width: headBar.middleLayout.width * 0.9 onPathChanged: browser.openFolder(path) onHomeClicked: { if(pageStack.currentIndex !== 0 && !pageStack.wideMode) pageStack.currentIndex = 0 browser.openFolder(inx.homePath()) } onPlaceClicked: browser.openFolder(path) } PlacesSidebar { id: placesSidebar onPlaceClicked: { if(item.type === "Tags") browser.populateTags(item.path) else browser.openFolder(item.path) } width: isCollapsed ? iconSize*2 : parent.width height: parent.height } Browser { id: browser anchors.fill: parent Component.onCompleted: { browser.openFolder(inx.homePath()) + } } ItemMenu { id: itemMenu onBookmarkClicked: browser.bookmarkFolder(paths) onCopyClicked: { if(paths.length > 0) browser.selectionBar.animate("#6fff80") browser.copy(paths) } onCutClicked: { if(paths.length > 0) browser.selectionBar.animate("#fff44f") browser.cut(paths) } // onSaveToClicked: // { // fmDialog.saveDialog = false // fmDialog.multipleSelection = true // fmDialog.onlyDirs= true // var myPath = path // var paths = browser.selectionBar.selectedPaths // fmDialog.show(function(paths) // { // inx.copy(myPath, paths) // }) // } onRemoveClicked: { if(paths.length > 0) { browser.selectionBar.clear() browser.selectionBar.animate("red") } browser.remove(paths) } onShareClicked: isAndroid ? Maui.Android.shareDialog(paths) : shareDialog.show(paths) } Maui.NewDialog { id: newFolderDialog title: "New folder..." onFinished: inx.createDir(browser.currentPath, text) } Maui.NewDialog { id: newFileDialog title: "New file..." onFinished: inx.createFile(browser.currentPath, text) } Maui.ShareDialog { id: shareDialog // parent: browser } onSearchButtonClicked: fmDialog.show() Maui.FileDialog { id:fmDialog } + + Component.onCompleted: + { +// if(!isAndroid) +// Maui.KDE.setColorScheme("index", headBarColor, textColor) + + // if(isAndroid) + // switchColorScheme(colorScheme.Dark) + } + } diff --git a/app/widgets/views/Browser.qml b/app/widgets/views/Browser.qml index 3623ec6..7287351 100644 --- a/app/widgets/views/Browser.qml +++ b/app/widgets/views/Browser.qml @@ -1,553 +1,589 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import "../../widgets_templates" import "../terminal" import org.kde.kirigami 2.0 as Kirigami import org.kde.mauikit 1.0 as Maui +import "../../Index.js" as INX Maui.Page { property string currentPath: inx.homePath() property var copyPaths : [] property var cutPaths : [] property bool isCopy : false property bool isCut : false property bool selectionMode : false property bool detailsView: false property bool previews: false property bool terminalVisible : false property bool pathExists : inx.fileExists(currentPath) property alias terminal : terminalLoader.item property alias selectionBar : selectionBar property alias grid : viewLoader.item property alias detailsDrawer: detailsDrawer property alias browserMenu: browserMenu property var previousPath: [] property var nextPath: [] property var pathType : ({ directory : 0, tags : 1, applications : 2, none: 3 }) property int currentPathType : views.none property int thumbnailsSize : iconSizes.large margins: 0 Connections { target: inx onPathModified: browser.refresh() onItemReady: browser.append(item) } BrowserMenu { id: browserMenu } DetailsDrawer { id: detailsDrawer } Component { id: listViewBrowser Maui.ListBrowser { showPreviewThumbnails: previews showEmblem: currentPathType !== pathType.applications rightEmblem: "document-share" leftEmblem: "emblem-added" } } Component { id: gridViewBrowser Maui.GridBrowser { itemSize : thumbnailsSize showEmblem: currentPathType !== pathType.applications showPreviewThumbnails: previews rightEmblem: "document-share" leftEmblem: "emblem-added" } } Connections { target: viewLoader.item onItemClicked: openItem(index) onItemDoubleClicked: { var item = viewLoader.item.model.get(index) if(inx.isDir(item.path)) browser.openFolder(item.path) else browser.openFile(item.path) } onItemRightClicked: itemMenu.show([viewLoader.item.model.get(index).path]) onLeftEmblemClicked: browser.addToSelection(item, true) onRightEmblemClicked: isAndroid ? Maui.Android.shareDialog([item.path]) : shareDialog.show([item.path]) onAreaClicked: { if(!isMobile && mouse.button === Qt.RightButton) browserMenu.show() else return } onAreaRightClicked: browserMenu.show() } focus: true - headBarVisible: false Maui.Holder { id: holder visible: false/*|| !inx.fileExists(currentPath)*/ z: -1 emoji: pathExists ? "qrc:/assets/MoonSki.png" : "qrc:/assets/ElectricPlug.png" isMask: false title : pathExists ? "Folder is empty!" : "Folder doesn't exists!" body: pathExists ? "You can add new files to it" : "Create Folder?" emojiSize: iconSizes.huge } Keys.onSpacePressed: detailsDrawer.show(viewLoader.item.model.get(viewLoader.item.currentIndex).path) floatingBar: true footBarOverlap: true + headBarExit: false + + headBar.rightContent: [ + + Maui.ToolButton + { + iconName: "visibility" + onClicked: INX.showHiddenFiles() + }, + + Maui.ToolButton + { + iconName: "view-preview" + onClicked: INX.showPreviews() + }, + + Maui.ToolButton + { + iconName: "bookmark-new" + onClicked: INX.bookmarkFolder() + } + ] + + headBar.leftContent: [ + Maui.ToolButton + { + iconName: "folder-add" + onClicked: INX.createFolder() + }, + + Maui.ToolButton + { + iconName: "sort-name" + } + ] footBar.leftContent: Maui.ToolButton { id: viewBtn iconColor: floatingBar ? altColorText : textColor iconName: browser.detailsView ? "view-list-icons" : "view-list-details" onClicked: browser.switchView() } footBar.middleContent: Row { spacing: space.medium Maui.ToolButton { iconName: "go-previous" iconColor: floatingBar ? altColorText : textColor onClicked: browser.goBack() } Maui.ToolButton { iconName: "go-up" iconColor: floatingBar ? altColorText : textColor onClicked: browser.goUp() } Maui.ToolButton { iconName: "go-next" iconColor: floatingBar ? altColorText : textColor onClicked: browser.goNext() } } footBar.rightContent: [ // Maui.ToolButton // { // iconName: "documentinfo" // iconColor: browser.detailsDrawer.visible ? highlightColor : textColor // onClicked: browser.detailsDrawer.visible ? browser.detailsDrawer.close() : // browser.detailsDrawer.show(browser.currentPath) // }, Maui.ToolButton { iconName: "overflow-menu" iconColor: floatingBar ? altColorText : textColor onClicked: browser.browserMenu.show() } ] ColumnLayout { spacing: 0 anchors.fill: parent visible: !holder.visible z: holder.z + 1 Item { id: browserContainer Layout.fillWidth: true Layout.fillHeight: true Layout.margins: detailsView ? unit : contentMargins * 2 z: holder.z + 1 ColumnLayout { anchors.fill: parent Loader { id: viewLoader z: holder.z + 1 sourceComponent: detailsView ? listViewBrowser : gridViewBrowser Layout.margins: detailsView ? unit : contentMargins * 2 Layout.fillWidth: true Layout.fillHeight: true } Maui.SelectionBar { id: selectionBar Layout.fillWidth: true Layout.leftMargin: contentMargins*2 Layout.rightMargin: contentMargins*2 Layout.bottomMargin: contentMargins*2 z: holder.z +1 onIconClicked: itemMenu.show(selectedPaths) onExitClicked: clearSelection() } } anchors.top: parent.top anchors.bottom: terminalVisible ? handle.top : parent.bottom } Rectangle { id: handle visible: terminalVisible Layout.fillWidth: true height: 5 color: "transparent" Kirigami.Separator { anchors { bottom: parent.bottom right: parent.right left: parent.left } } MouseArea { anchors.fill: parent drag.target: parent drag.axis: Drag.YAxis drag.smoothed: true cursorShape: Qt.SizeVerCursor } } Loader { id: terminalLoader visible: terminalVisible focus: true Layout.fillWidth: true + Layout.fillHeight: true Layout.alignment: Qt.AlignBottom Layout.minimumHeight: 100 Layout.maximumHeight: parent.height *0.5 anchors.bottom: parent.bottom anchors.top: handle.bottom source: !isMobile ? "../terminal/Terminal.qml" : "" } } function openItem(index) { var item = viewLoader.item.model.get(index) if(selectionMode && !inx.isDir(item.path)) addToSelection(item, true) else { var path = item.path if(inx.isDir(path)) browser.openFolder(path) else if(inx.isCustom(path)) browser.openFolder(path) else if(inx.isApp(path)) browser.launchApp(path) else { if (isMobile) detailsDrawer.show(path) else browser.openFile(path) } } } function clear() { viewLoader.item.model.clear() } function launchApp(path) { inx.runApplication(path, "") } function openFile(path) { inx.openFile(path) } function openFolder(path) { previousPath.push(currentPath) populate(path) if(!isMobile) terminal.session.sendText("cd " + currentPath + "\n") // if(selectedPaths.length > 0) // clearSelection() } function openAppsPath(path) { setPath(path, pathType.applications) var items = inx.getCustomPathContent(path) if(items.length > 0) for(var i in items) viewLoader.item.model.append(items[i]) for(i=0; i < placesSidebar.count; i++) if(currentPath === placesSidebar.model.get(i).path) placesSidebar.currentIndex = i } function populate(path) { clear() if(path.indexOf("#apps") === 0) { browser.openAppsPath(path) return; } setPath(path, pathType.directory) /* Get directory configs */ var iconsize = Maui.FM.dirConf(path+"/.directory")["iconsize"] || iconSizes.large thumbnailsSize = parseInt(iconsize) detailsView = Maui.FM.dirConf(path+"/.directory")["detailview"] === "true" ? true : false if(!isAndroid) terminalVisible = Maui.FM.dirConf(path+"/.directory")["showterminal"] === "true" ? true : false previews = Maui.FM.dirConf(path+"/.directory")["showthumbnail"] === "true" ? true : false if(!detailsView) grid.adaptGrid() /* should it really return the paths or just use the signal? */ var items = inx.getPathContent(path) for(var i=0; i < placesSidebar.count; i++) if(currentPath === placesSidebar.model.get(i).path) placesSidebar.currentIndex = i inx.watchPath(currentPath) } function append(item) { viewLoader.item.model.append(item) } function goBack() { nextPath.push(currentPath) populate(previousPath.pop()) } function goNext() { openFolder(nextPath.pop()) } function goUp() { openFolder(inx.parentDir(currentPath)) } function refresh() { var pos = browser.grid.contentY populate(currentPath) browser.grid.contentY = pos } function addToSelection(item, append) { selectionBar.append(item) } function clearSelection() { clean() browser.selectionMode = false } function clean() { copyPaths = [] cutPaths = [] browserMenu.pasteFiles = 0 selectionBar.clear() } function copy(paths) { copyPaths = paths isCut = false isCopy = true } function cut(paths) { cutPaths = paths isCut = true isCopy = false } function paste() { if(isCopy) inx.copy(copyPaths, currentPath) else if(isCut) if(inx.cut(cutPaths, currentPath)) clearSelection() } function remove(paths) { for(var i in paths) inx.remove(paths[i]) } function switchView() { detailsView = !detailsView Maui.FM.setDirConf(currentPath+"/.directory", "MAUIFM", "DetailView", detailsView) populate(currentPath) } function bookmarkFolder(paths) { if(paths.length > 0) { for(var i in paths) { if(inx.isDefaultPath(paths[i])) continue inx.bookmark(paths[i]) } placesSidebar.populate() } } function populateTags(myTag) { clear() inx.getTagContent(myTag) setPath(myTag, pathType.tags) } function setPath(path, type) { currentPathType = type currentPath = path pathBar.append(currentPath) } function zoomIn() { switch(thumbnailsSize) { case iconSizes.tiny: thumbnailsSize = iconSizes.small break case iconSizes.small: thumbnailsSize = iconSizes.medium break case iconSizes.medium: thumbnailsSize = iconSizes.big break case iconSizes.big: thumbnailsSize = iconSizes.large break case iconSizes.large: thumbnailsSize = iconSizes.huge break case iconSizes.huge: thumbnailsSize = iconSizes.enormous break case iconSizes.enormous: thumbnailsSize = iconSizes.enormous break default: thumbnailsSize = iconSizes.large } Maui.FM.setDirConf(currentPath+"/.directory", "MAUIFM", "IconSize", thumbnailsSize) grid.adaptGrid() } function zoomOut() { switch(thumbnailsSize) { case iconSizes.tiny: thumbnailsSize = iconSizes.tiny break case iconSizes.small: thumbnailsSize = iconSizes.tiny break case iconSizes.medium: thumbnailsSize = iconSizes.small break case iconSizes.big: thumbnailsSize = iconSizes.medium break case iconSizes.large: thumbnailsSize = iconSizes.big break case iconSizes.huge: thumbnailsSize = iconSizes.large break case iconSizes.enormous: thumbnailsSize = iconSizes.huge break default: thumbnailsSize = iconSizes.large } Maui.FM.setDirConf(currentPath+"/.directory", "MAUIFM", "IconSize", thumbnailsSize) grid.adaptGrid() } } diff --git a/app/widgets/views/BrowserMenu.qml b/app/widgets/views/BrowserMenu.qml index 64f5116..2238e78 100644 --- a/app/widgets/views/BrowserMenu.qml +++ b/app/widgets/views/BrowserMenu.qml @@ -1,136 +1,132 @@ import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 import org.kde.mauikit 1.0 as Maui import org.kde.kirigami 2.2 as Kirigami import "../../Index.js" as INX Menu { x: parent.width / 2 - width / 2 y: parent.height / 2 - height / 2 modal: true focus: true parent: ApplicationWindow.overlay margins: 1 padding: 2 property int pasteFiles : 0 MenuItem { text: qsTr(browser.selectionMode ? "Selection OFF" : "Selection ON") onTriggered: browser.selectionMode = !browser.selectionMode } MenuSeparator { } MenuItem { visible: !isMobile text: qsTr(terminalVisible ? "Hide terminal" : "Show terminal") onTriggered: { terminalVisible = !terminalVisible Maui.FM.setDirConf(browser.currentPath+"/.directory", "MAUIFM", "ShowTerminal", browser.terminalVisible) close() } } MenuItem { text: qsTr("Compact mode") onTriggered: placesSidebar.isCollapsed = !placesSidebar.isCollapsed } MenuItem { text: qsTr("Show previews") onTriggered: { - browser.previews = !browser.previews - Maui.FM.setDirConf(browser.currentPath+"/.directory", "MAUIFM", "ShowThumbnail", browser.previews) + INX.showPreviews() close() } } MenuItem { text: qsTr("Show hidden files") onTriggered: { - var state = Maui.FM.dirConf(browser.currentPath+"/.directory").hidden - console.log(state) - Maui.FM.setDirConf(browser.currentPath+"/.directory", "Settings", "HiddenFilesShown", !state) - browser.refresh() + INX.showHiddenFiles() close() } } MenuSeparator { } MenuItem { text: qsTr("New folder") - onTriggered: newFolderDialog.open() + onTriggered: INX.createFolder() } MenuItem { text: qsTr("New file") - onTriggered: newFileDialog.open() + onTriggered: INX.createFile() } MenuItem { text: qsTr("Bookmark") - onTriggered: browser.bookmarkFolder([browser.currentPath]) + onTriggered: INX.bookmarkFolder() } MenuSeparator { } MenuItem { text: qsTr("Paste ")+"["+pasteFiles+"]" enabled: pasteFiles > 0 onTriggered: browser.paste() } MenuSeparator { } MenuItem { width: parent.width RowLayout { anchors.fill: parent Maui.ToolButton { Layout.fillHeight: true Layout.fillWidth: true iconName: "list-add" onClicked: zoomIn() } Maui.ToolButton { Layout.fillHeight: true Layout.fillWidth: true iconName: "list-remove" onClicked: zoomOut() } } } function show() { if(browser.currentPathType === browser.pathType.directory || browser.currentPathType === browser.pathType.tags) { if(browser.isCopy) pasteFiles = copyPaths.length else if(browser.isCut) pasteFiles = cutPaths.length if(isMobile) open() else popup() } } } diff --git a/index.pro b/index.pro index 8c51214..4ec2a6a 100644 --- a/index.pro +++ b/index.pro @@ -1,11 +1,11 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS += app linux:unix:!android { message(Building Terminal for Linux KDE) - SUBDIRS += kde/qmltermwidget + SUBDIRS += $$PWD/kde/qmltermwidget }