diff --git a/maui-style/Button.qml b/maui-style/Button.qml index 8554814..d28b39f 100755 --- a/maui-style/Button.qml +++ b/maui-style/Button.qml @@ -1,51 +1,50 @@ /* * Copyright 2017 Marco Martin * Copyright 2017 The Qt Company Ltd. * * GNU Lesser General Public License Usage * Alternatively, this file may be used under the terms of the GNU Lesser * General Public License version 3 as published by the Free Software * Foundation and appearing in the file LICENSE.LGPLv3 included in the * packaging of this file. Please review the following information to * ensure the GNU Lesser General Public License version 3 requirements * will be met: https://www.gnu.org/licenses/lgpl.html. * * GNU General Public License Usage * Alternatively, this file may be used under the terms of the GNU * General Public License version 2.0 or later as published by the Free * Software Foundation and appearing in the file LICENSE.GPL included in * the packaging of this file. Please review the following information to * ensure the GNU General Public License version 2.0 requirements will be * met: http://www.gnu.org/licenses/gpl-2.0.html. */ import QtQuick 2.6 import QtQuick.Templates 2.3 as T import org.kde.kirigami 2.3 as Kirigami T.Button { id: controlRoot - implicitWidth: background.implicitWidth + implicitWidth: Math.max(background.implicitWidth, contentItem.implicitWidth + Kirigami.Units.smallSpacing ) implicitHeight: background.implicitHeight hoverEnabled: true - contentItem: Text { + contentItem: Label { text: controlRoot.text font: controlRoot.font color: !controlRoot.enabled ? Kirigami.Theme.disabledTextColor : - controlRoot.highlighted || controlRoot.down ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.buttonTextColor + controlRoot.highlighted || controlRoot.down ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { - implicitWidth: (Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.smallMedium : Kirigami.Units.iconSizes.medium) * 2 + Kirigami.Units.smallSpacing - implicitHeight: Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.smallMedium : Kirigami.Units.iconSizes.medium + implicitWidth: (Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.medium) * 2 + Kirigami.Units.smallSpacing + implicitHeight: Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.medium - color: !controlRoot.enabled ? Kirigami.Theme.backgroundColor : - controlRoot.highlighted || controlRoot.down ? Kirigami.Theme.buttonFocusColor : Kirigami.Theme.buttonBackgroundColor + color: Kirigami.Theme.backgroundColor border.color: controlRoot.hovered ? Kirigami.Theme.buttonHoverColor : Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) border.width: Kirigami.Units.devicePixelRatio - radius: height * 0.05 + radius: height * 0.07 } } diff --git a/maui-style/ComboBox.qml b/maui-style/ComboBox.qml index cfe7f50..0bbae20 100755 --- a/maui-style/ComboBox.qml +++ b/maui-style/ComboBox.qml @@ -1,149 +1,155 @@ -/* - * Copyright 2017 Marco Martin - * Copyright 2017 The Qt Company Ltd. - * - * GNU Lesser General Public License Usage - * Alternatively, this file may be used under the terms of the GNU Lesser - * General Public License version 3 as published by the Free Software - * Foundation and appearing in the file LICENSE.LGPLv3 included in the - * packaging of this file. Please review the following information to - * ensure the GNU Lesser General Public License version 3 requirements - * will be met: https://www.gnu.org/licenses/lgpl.html. - * - * GNU General Public License Usage - * Alternatively, this file may be used under the terms of the GNU - * General Public License version 2.0 or later as published by the Free - * Software Foundation and appearing in the file LICENSE.GPL included in - * the packaging of this file. Please review the following information to - * ensure the GNU General Public License version 2.0 requirements will be - * met: http://www.gnu.org/licenses/gpl-2.0.html. - */ - - -import QtQuick 2.6 -import QtQuick.Window 2.2 -import QtQuick.Templates 2.3 as T -import QtQuick.Controls 2.3 as Controls -import QtGraphicalEffects 1.0 -import org.kde.kirigami 2.2 as Kirigami +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Window 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Controls.impl 2.12 +import QtQuick.Templates 2.12 as T +import org.kde.kirigami 2.7 as Kirigami T.ComboBox { - id: controlRoot - //NOTE: typeof necessary to not have warnings on Qt 5.7 - Kirigami.Theme.colorSet: typeof(editable) != "undefined" && editable ? Kirigami.Theme.View : Kirigami.Theme.Button - Kirigami.Theme.inherit: false - - implicitWidth: background.implicitWidth + leftPadding + rightPadding - implicitHeight: background.implicitHeight - baselineOffset: contentItem.y + contentItem.baselineOffset - - hoverEnabled: true - padding: 5 - leftPadding: padding + 5 - rightPadding: padding + 5 - - delegate: ItemDelegate { - width: controlRoot.popup.width - text: controlRoot.textRole ? (Array.isArray(controlRoot.model) ? modelData[controlRoot.textRole] : model[controlRoot.textRole]) : modelData - highlighted: controlRoot.highlightedIndex == index - property bool separatorVisible: false - Kirigami.Theme.colorSet: controlRoot.Kirigami.Theme.inherit ? controlRoot.Kirigami.Theme.colorSet : Kirigami.Theme.View - Kirigami.Theme.inherit: controlRoot.Kirigami.Theme.inherit + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + topInset: 6 + bottomInset: 6 + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + + delegate: MenuItem { + width: parent.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData +// Material.foreground: control.currentIndex === index ? parent.Material.accent : parent.Material.foreground + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled } - indicator: Item {} + indicator: Kirigami.Icon { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: control.enabled ? control.Kirigami.Theme.textColor : control.Kirigami.Theme.highlightColor + source: "arrow-down" + height: iconSizes.small + width: height + } - contentItem: MouseArea { - onPressed: mouse.accepted = false; - onWheel: { - if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) { - controlRoot.currentIndex = (controlRoot.currentIndex + 1) % delegateModel.count - } else { - controlRoot.currentIndex = (controlRoot.currentIndex - 1 + delegateModel.count) % delegateModel.count - } - } - T.TextField { - anchors { - fill: parent - leftMargin: controlRoot.mirrored ? 12 : 1 - rightMargin: !controlRoot.mirrored ? 12 : 1 - } - - text: controlRoot.editText - - visible: typeof(controlRoot.editable) != "undefined" && controlRoot.editable - readOnly: controlRoot.popup.visible - inputMethodHints: controlRoot.inputMethodHints - validator: controlRoot.validator - renderType: Window.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering - color: controlRoot.enabled ? Kirigami.Theme.textColor : Kirigami.Theme.disabledTextColor - selectionColor: Kirigami.Theme.highlightColor - selectedTextColor: Kirigami.Theme.highlightedTextColor - selectByMouse: true - - font: controlRoot.font - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - opacity: controlRoot.enabled ? 1 : 0.3 - } + contentItem: T.TextField { + padding: 6 + leftPadding: control.editable ? 2 : control.mirrored ? 0 : 12 + rightPadding: control.editable ? 2 : control.mirrored ? 12 : 0 + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + + font: control.font + color: control.enabled ? control.Kirigami.Theme.textColor : control.Kirigami.Theme.highlightColor + selectionColor: control.Kirigami.Theme.highlightColor + selectedTextColor: control.Kirigami.Theme.highlightedTextColor + verticalAlignment: Text.AlignVCenter + +// cursorDelegate: CursorDelegate { } } -// background: StylePrivate.StyleItem { -// id: styleitem -// control: controlRoot -// elementType: "combobox" -// anchors.fill: parent -// hover: controlRoot.hovered -// sunken: controlRoot.pressed -// raised: !sunken -// hasFocus: controlRoot.activeFocus -// enabled: controlRoot.enabled -// // contentHeight as in QComboBox magic numbers taken from QQC1 style -// contentHeight: Math.max(Math.ceil(textHeight("")), 14) + 2 -// text: controlRoot.displayText -// properties: { -// "editable" : control.editable -// } -// } + background: Rectangle { + implicitWidth: (Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.medium) * 2 + Kirigami.Units.smallSpacing + implicitHeight: Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.medium + + radius: height * 0.07 + + color: !control.editable ? control.Kirigami.Theme.backgroundColor : "transparent" + + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) + + + Rectangle { + visible: control.editable + y: parent.y + control.baselineOffset + width: parent.width + height: control.activeFocus ? 2 : 1 + color: control.editable && control.activeFocus ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.highlightedTextColor + } + } popup: T.Popup { - y: controlRoot.height - width: Math.max(controlRoot.width, 150) - implicitHeight: contentItem.implicitHeight - topMargin: 6 - bottomMargin: 6 - Kirigami.Theme.colorSet: Kirigami.Theme.View - Kirigami.Theme.inherit: controlRoot.Kirigami.Theme.inherit +// y: control.editable ? control.height - 5 : 0 + width: control.width + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + transformOrigin: Item.Top + topMargin: 12 + bottomMargin: 12 + enter: Transition { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition { + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } contentItem: ListView { - id: listview clip: true implicitHeight: contentHeight - model: controlRoot.popup.visible ? controlRoot.delegateModel : null - currentIndex: controlRoot.highlightedIndex - highlightRangeMode: ListView.ApplyRange + model: control.delegateModel + currentIndex: control.highlightedIndex highlightMoveDuration: 0 - T.ScrollBar.vertical: Controls.ScrollBar { } + + T.ScrollIndicator.vertical: ScrollIndicator { } } + background: Rectangle { - anchors { - fill: parent - margins: -1 - } - radius: 2 - color: Kirigami.Theme.backgroundColor - property color borderColor: Kirigami.Theme.textColor - border.color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3) - layer.enabled: true - - layer.effect: DropShadow { - transparentBorder: true - radius: 4 - samples: 8 - horizontalOffset: 2 - verticalOffset: 2 - color: Qt.rgba(0, 0, 0, 0.3) - } + radius: height * 0.07 + color: parent.Kirigami.Theme.backgroundColor + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) + } } } diff --git a/maui-style/Menu.qml b/maui-style/Menu.qml index 876909c..1c95588 100755 --- a/maui-style/Menu.qml +++ b/maui-style/Menu.qml @@ -1,80 +1,111 @@ -/* - * Copyright 2017 Marco Martin - * Copyright 2017 The Qt Company Ltd. - * - * GNU Lesser General Public License Usage - * Alternatively, this file may be used under the terms of the GNU Lesser - * General Public License version 3 as published by the Free Software - * Foundation and appearing in the file LICENSE.LGPLv3 included in the - * packaging of this file. Please review the following information to - * ensure the GNU Lesser General Public License version 3 requirements - * will be met: https://www.gnu.org/licenses/lgpl.html. - * - * GNU General Public License Usage - * Alternatively, this file may be used under the terms of the GNU - * General Public License version 2.0 or later as published by the Free - * Software Foundation and appearing in the file LICENSE.GPL included in - * the packaging of this file. Please review the following information to - * ensure the GNU General Public License version 2.0 requirements will be - * met: http://www.gnu.org/licenses/gpl-2.0.html. - */ - - -import QtQuick 2.6 -import QtQuick.Layouts 1.2 +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Templates 2.12 as T +import QtQuick.Window 2.12 +import org.kde.kirigami 2.7 as Kirigami +import org.kde.mauikit 1.0 as Maui import QtGraphicalEffects 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Templates 2.3 as T -import org.kde.kirigami 2.2 as Kirigami T.Menu { id: control - implicitWidth: Math.max(background ? background.implicitWidth : 0, - contentItem ? contentItem.implicitWidth + leftPadding + rightPadding : 0) - implicitHeight: Math.max(background ? background.implicitHeight : 0, - contentItem ? contentItem.implicitHeight : 0) + topPadding + bottomPadding + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) margins: 0 + verticalPadding: 8 + + transformOrigin: !cascade ? Item.Top : (mirrored ? Item.TopRight : Item.TopLeft) - contentItem: ColumnLayout {} + delegate: MenuItem { } enter: Transition { - NumberAnimation { - property: "opacity" - from: 0 - to: 1 - easing.type: Easing.InOutQuad - duration: 150 - } + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } } exit: Transition { - NumberAnimation { - property: "opacity" - from: 1 - to: 0 - easing.type: Easing.InOutQuad - duration: 150 - } + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + contentItem: ListView { + implicitHeight: contentHeight + + model: control.contentModel + interactive: Window.window ? contentHeight > Window.window.height : false + clip: true + currentIndex: control.currentIndex + + ScrollIndicator.vertical: ScrollIndicator {} } background: Rectangle { - radius: height * 0.005 - implicitWidth: Kirigami.Units.gridUnit * 8 - implicitHeight: 40 - color: Kirigami.Theme.backgroundColor - property color borderColor: Kirigami.Theme.textColor - border.color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3) + implicitWidth: 200 + implicitHeight: Maui.Style.rowHeight + + radius: radiusV + color: control.Kirigami.Theme.backgroundColor + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) layer.enabled: true - + layer.effect: DropShadow { transparentBorder: true - radius: 4 - samples: 8 - horizontalOffset: 2 - verticalOffset: 2 + radius: 8 + samples: 16 + horizontalOffset: 0 + verticalOffset: 4 color: Qt.rgba(0, 0, 0, 0.3) } } + + T.Overlay.modal: Rectangle { + color: "#333" + Behavior on opacity { NumberAnimation { duration: 150 } } + } + + T.Overlay.modeless: Rectangle { + color: "#333" + Behavior on opacity { NumberAnimation { duration: 150 } } + } } diff --git a/maui-style/MenuItem.qml b/maui-style/MenuItem.qml index 8334a8f..6b65a76 100755 --- a/maui-style/MenuItem.qml +++ b/maui-style/MenuItem.qml @@ -1,66 +1,106 @@ -/* - * Copyright 2017 Marco Martin - * Copyright 2017 The Qt Company Ltd. - * - * GNU Lesser General Public License Usage - * Alternatively, this file may be used under the terms of the GNU Lesser - * General Public License version 3 as published by the Free Software - * Foundation and appearing in the file LICENSE.LGPLv3 included in the - * packaging of this file. Please review the following information to - * ensure the GNU Lesser General Public License version 3 requirements - * will be met: https://www.gnu.org/licenses/lgpl.html. - * - * GNU General Public License Usage - * Alternatively, this file may be used under the terms of the GNU - * General Public License version 2.0 or later as published by the Free - * Software Foundation and appearing in the file LICENSE.GPL included in - * the packaging of this file. Please review the following information to - * ensure the GNU General Public License version 2.0 requirements will be - * met: http://www.gnu.org/licenses/gpl-2.0.html. - */ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ - -import QtQuick 2.6 -import QtQuick.Layouts 1.2 -import QtQuick.Templates 2.3 as T -import org.kde.kirigami 2.2 as Kirigami +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import QtQuick.Controls 2.12 +import QtQuick.Controls.impl 2.12 +import QtQuick.Controls.Material 2.12 +import QtQuick.Controls.Material.impl 2.12 +import org.kde.kirigami 2.7 as Kirigami +import org.kde.mauikit 1.0 as Maui T.MenuItem { - id: controlRoot + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: visible ? Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) : 0 + + padding: 16 + // verticalPadding: Material.menuItemVerticalPadding + spacing: 16 - implicitWidth: Math.max(background ? background.implicitWidth : 0, - contentItem.implicitWidth + leftPadding + rightPadding) - implicitHeight: Math.max(background ? background.implicitHeight : 0, - Math.max(contentItem.implicitHeight, - indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) - baselineOffset: contentItem.y + contentItem.baselineOffset + icon.width: Kirigami.Units.iconSizes.smallMedium + icon.height: 24 + icon.color: control.enabled ? (control.highlighted ? control.Kirigami.Theme.highlightedTextColor : control.Kirigami.Theme.textColor) : + control.Kirigami.Theme.disabledTextColor +// indicator: CheckIndicator { +// x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 +// y: control.topPadding + (control.availableHeight - height) / 2 +// visible: control.checkable +// control: control +// checked: control.checked ? Qt.Checked : Qt.Unchecked +// } + + arrow: Kirigami.Icon { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.subMenu +// mirror: control.mirrored + color: control.enabled ? (control.highlighted ? control.Kirigami.Theme.highlightedTextColor : control.Kirigami.Theme.textColor) : + control.Kirigami.Theme.disabledTextColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Material/images/arrow-indicator.png" + } - Layout.fillWidth: true - padding: Kirigami.Settings.isMobile ? Kirigami.Units.largeSpacing : Kirigami.Units.smallSpacing - hoverEnabled: true + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding - contentItem: Label { - leftPadding: !controlRoot.mirrored ? (controlRoot.indicator ? controlRoot.indicator.width : 0) + controlRoot.spacing : 0 - rightPadding: controlRoot.mirrored ? (controlRoot.indicator ? controlRoot.indicator.width : 0) + controlRoot.spacing : 0 + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft - text: controlRoot.text - font: controlRoot.font - color: controlRoot.hovered && !controlRoot.pressed ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor - elide: Text.ElideRight - visible: controlRoot.text - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? (control.highlighted ? control.Kirigami.Theme.highlightedTextColor : control.Kirigami.Theme.textColor) : + control.Kirigami.Theme.disabledTextColor } - background: Item { - anchors.fill: parent - implicitWidth: Kirigami.Units.gridUnit * 8 + background: Rectangle { + implicitWidth: 200 + implicitHeight: Maui.Style.rowHeight + color: control.highlighted ? control.Kirigami.Theme.highlightColor : "transparent" - Rectangle { - anchors.fill: parent - color: Kirigami.Theme.highlightColor - opacity: controlRoot.hovered && !controlRoot.pressed ? 1 : 0 - Behavior on opacity { NumberAnimation { duration: 150 } } - } } } diff --git a/maui-style/Popup.qml b/maui-style/Popup.qml index 56c7106..2981b1a 100755 --- a/maui-style/Popup.qml +++ b/maui-style/Popup.qml @@ -1,82 +1,81 @@ /* * Copyright 2017 Marco Martin * Copyright 2017 The Qt Company Ltd. * * GNU Lesser General Public License Usage * Alternatively, this file may be used under the terms of the GNU Lesser * General Public License version 3 as published by the Free Software * Foundation and appearing in the file LICENSE.LGPLv3 included in the * packaging of this file. Please review the following information to * ensure the GNU Lesser General Public License version 3 requirements * will be met: https://www.gnu.org/licenses/lgpl.html. * * GNU General Public License Usage * Alternatively, this file may be used under the terms of the GNU * General Public License version 2.0 or later as published by the Free * Software Foundation and appearing in the file LICENSE.GPL included in * the packaging of this file. Please review the following information to * ensure the GNU General Public License version 2.0 requirements will be * met: http://www.gnu.org/licenses/gpl-2.0.html. */ import QtQuick 2.6 import QtGraphicalEffects 1.0 import QtQuick.Templates 2.3 as T import org.kde.kirigami 2.2 as Kirigami T.Popup { id: control implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0) implicitHeight: Math.max(background ? background.implicitHeight : 0, contentWidth > 0 ? contentHeight + topPadding + bottomPadding : 0) contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) topPadding: Kirigami.Units.devicePixelRatio * 4 bottomPadding: Kirigami.Units.devicePixelRatio * 4 rightPadding: Kirigami.Units.devicePixelRatio * 2 leftPadding: Kirigami.Units.devicePixelRatio * 2 enter: Transition { NumberAnimation { property: "opacity" from: 0 to: 1 easing.type: Easing.InOutQuad duration: 250 } } exit: Transition { NumberAnimation { property: "opacity" from: 1 to: 0 easing.type: Easing.InOutQuad duration: 250 } } contentItem: Item { } background: Rectangle { - radius: Kirigami.Units.devicePixelRatio * 4 - color: Kirigami.Theme.viewBackgroundColor - property color borderColor: Kirigami.Theme.textColor - border.color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3) + radius: radiusV + color: Kirigami.Theme.backgroundColor + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) layer.enabled: true layer.effect: DropShadow { transparentBorder: true radius: 8 samples: 16 horizontalOffset: 0 verticalOffset: 4 color: Qt.rgba(0, 0, 0, 0.3) } } } diff --git a/maui-style/TextField.qml b/maui-style/TextField.qml index 487932a..bc3b3db 100755 --- a/maui-style/TextField.qml +++ b/maui-style/TextField.qml @@ -1,87 +1,88 @@ /* * Copyright 2017 Marco Martin * Copyright 2017 The Qt Company Ltd. * * GNU Lesser General Public License Usage * Alternatively, this file may be used under the terms of the GNU Lesser * General Public License version 3 as published by the Free Software * Foundation and appearing in the file LICENSE.LGPLv3 included in the * packaging of this file. Please review the following information to * ensure the GNU Lesser General Public License version 3 requirements * will be met: https://www.gnu.org/licenses/lgpl.html. * * GNU General Public License Usage * Alternatively, this file may be used under the terms of the GNU * General Public License version 2.0 or later as published by the Free * Software Foundation and appearing in the file LICENSE.GPL included in * the packaging of this file. Please review the following information to * ensure the GNU General Public License version 2.0 requirements will be * met: http://www.gnu.org/licenses/gpl-2.0.html. */ import QtQuick 2.6 import QtQuick.Window 2.1 import QtQuick.Controls 2.3 as Controls import QtQuick.Templates 2.3 as T import org.kde.kirigami 2.2 as Kirigami T.TextField { id: controlRoot Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.inherit: false implicitWidth: Math.max(200, placeholderText ? placeholder.implicitWidth + leftPadding + rightPadding : 0) || contentWidth + leftPadding + rightPadding implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, background ? Kirigami.Units.iconSizes.smallMedium : 0, placeholder.implicitHeight + topPadding + bottomPadding) padding: 6 /* color: controlRoot.enabled ? Kirigami.Theme.textColor : Kirigami.Theme.disabledTextColor selectionColor: Kirigami.Theme.highlightColor selectedTextColor: Kirigami.Theme.highlightedTextColor verticalAlignment: TextInput.AlignVCenter*/ //Text.NativeRendering is broken on non integer pixel ratios renderType: Window.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering - color: enabled ? colorScheme.textColor : Qt.lighter(colorScheme.textColor, 1.4) - selectionColor: highlightColor - selectedTextColor: highlightedTextColor + color: enabled ? Kirigami.Theme.textColor : Kirigami.Theme.disabledtextColor + selectionColor: Kirigami.Theme.highlightColor + selectedTextColor: Kirigami.Theme.highlightedTextColor verticalAlignment: TextInput.AlignVCenter horizontalAlignment: Text.AlignHCenter // cursorDelegate: CursorDelegate { } Controls.Label { id: placeholder x: control.leftPadding y: control.topPadding width: control.width - (control.leftPadding + control.rightPadding) height: control.height - (control.topPadding + control.bottomPadding) text: control.placeholderText font: control.font - color: Qt.lighter(colorScheme.textColor, 1.4) + color: Qt.lighter(Kirigami.Theme.textColor, 1.4) opacity: 0.4 horizontalAlignment: control.horizontalAlignment verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight } background: Rectangle { implicitWidth: unit * 120 - implicitHeight: iconSizes.big - color: control.activeFocus ? Qt.lighter(colorScheme.backgroundColor, 1.4) - : (control.hovered ? Qt.lighter(colorScheme.backgroundColor, 1.3) : colorScheme.backgroundColor) - border.color: colorScheme.borderColor - radius: radiusV + implicitHeight: Kirigami.Settings.isMobile ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.medium + color: control.activeFocus ? Qt.lighter(Kirigami.Theme.backgroundColor, 1.4) + : (control.hovered ? Qt.lighter(Kirigami.Theme.backgroundColor, 1.3) : Kirigami.Theme.backgroundColor) + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) + + radius: radiusV border.width: unit } } diff --git a/maui-style/ToolBar.qml b/maui-style/ToolBar.qml index 0c68cd1..942aa80 100755 --- a/maui-style/ToolBar.qml +++ b/maui-style/ToolBar.qml @@ -1,79 +1,53 @@ /* * Copyright 2017 Marco Martin * Copyright 2017 The Qt Company Ltd. * * GNU Lesser General Public License Usage * Alternatively, this file may be used under the terms of the GNU Lesser * General Public License version 3 as published by the Free Software * Foundation and appearing in the file LICENSE.LGPLv3 included in the * packaging of this file. Please review the following information to * ensure the GNU Lesser General Public License version 3 requirements * will be met: https://www.gnu.org/licenses/lgpl.html. * * GNU General Public License Usage * Alternatively, this file may be used under the terms of the GNU * General Public License version 2.0 or later as published by the Free * Software Foundation and appearing in the file LICENSE.GPL included in * the packaging of this file. Please review the following information to * ensure the GNU General Public License version 2.0 requirements will be * met: http://www.gnu.org/licenses/gpl-2.0.html. */ import QtQuick 2.6 -import QtQuick.Controls 2.2 -import QtQuick.Templates 2.3 as T -import org.kde.kirigami 2.2 as Kirigami +import QtQuick.Templates 2.5 as T +import org.kde.kirigami 2.4 as Kirigami +import org.kde.mauikit 1.0 as Maui T.ToolBar { id: controlRoot + palette: Kirigami.Theme.palette implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) -// leftPadding: Kirigami.Units.smallSpacing*2 -// rightPadding: Kirigami.Units.smallSpacing*2 - contentWidth: contentChildren[0].implicitWidth contentHeight: contentChildren[0].implicitHeight + padding: Kirigami.Units.smallSpacing contentItem: Item {} - - readonly property bool mainHeader : controlRoot == T.ApplicationWindow.header - readonly property bool mainFooter : controlRoot == T.ApplicationWindow.footer - readonly property bool isFooter : controlRoot.position == T.ToolBar.Footer - readonly property bool isHeader : controlRoot.position == T.ToolBar.Header - - background: Rectangle - { - implicitHeight: Kirigami.Units.iconSizes.medium + (Kirigami.Settings.isMobile ? Kirigami.Units.smallSpacing : Kirigami.Units.largeSpacing) - -// color: mainHeader || mainFooter ? Kirigami.Theme.buttonBackgroundColor : Kirigami.Theme.viewBackgroundColor - color: Kirigami.Theme.viewBackgroundColor - - Kirigami.Separator - { - visible: mainHeader - color: Qt.darker(Kirigami.Theme.backgroundColor, 1.2) - anchors - { - left: parent.left - right: parent.right - top: mainHeader && !Kirigami.Settings.isMobile ? parent.top : undefined - } - } - - Kirigami.Separator - { - color: Qt.darker(Kirigami.Theme.backgroundColor, 1.2) - - anchors - { + position: controlRoot.parent.footer == controlRoot ? ToolBar.Footer : ToolBar.Header + background: Rectangle { + implicitHeight: Maui.Style.toolBarHeight + color: Kirigami.Theme.backgroundColor + Kirigami.Separator { + anchors { left: parent.left right: parent.right - bottom: !isFooter ? parent.bottom : undefined + top: controlRoot.position == T.ToolBar.Footer || (controlRoot.parent.footer && controlRoot.parent.footer == controlRoot) ? parent.top : undefined + bottom: controlRoot.position == T.ToolBar.Footer || (controlRoot.parent.footer && controlRoot.parent.footer == controlRoot) ? undefined : parent.bottom } } - } } diff --git a/maui-style/ToolButton.qml b/maui-style/ToolButton.qml index 98491a9..8129103 100755 --- a/maui-style/ToolButton.qml +++ b/maui-style/ToolButton.qml @@ -1,81 +1,81 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPLv3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or later as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information to ** ensure the GNU General Public License version 2.0 requirements will be ** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Controls.impl 2.3 import QtQuick.Templates 2.3 as T -import org.kde.kirigami 2.2 as Kirigami +import org.kde.kirigami 2.7 as Kirigami T.ToolButton { id: control implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset padding: Kirigami.Units.smallSpacing spacing: Kirigami.Units.smallSpacing icon.width: Kirigami.Units.iconSizes.smallMedium icon.height: Kirigami.Units.iconSizes.smallMedium - icon.color: visualFocus ? control.palette.highlight : control.palette.buttonText + icon.color: visualFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor flat: control.parent === T.ToolBar contentItem: IconLabel { spacing: control.spacing mirrored: control.mirrored display: control.display icon: control.icon text: control.text font: control.font - color: control.visualFocus ? control.palette.highlight : control.palette.buttonText + color: control.visualFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor } background: Rectangle { implicitWidth: Kirigami.Units.iconSizes.medium implicitHeight: Kirigami.Units.iconSizes.medium - radius: height * 0.05 + radius: height * 0.07 - opacity: control.down ? 1.0 : 0.5 + opacity: control.down ? 1.0 : 0.4 color: (control.down || control.checked || control.highlighted ? Kirigami.Theme.buttonHoverColor : "transparent") } } diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 1a20c81..a7b48de 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,143 +1,143 @@ + android:name="com.example.android.tools.NotificationClient" - - + diff --git a/src/android/icons.qrc b/src/android/icons.qrc index 8b53f24..08d9b6a 100644 --- a/src/android/icons.qrc +++ b/src/android/icons.qrc @@ -1,491 +1,496 @@ icons/luv-icon-theme/Luv/index.theme icons/luv-icon-theme/Luv/LICENSE icons/luv-icon-theme/Luv/places/16/folder-documents.svg icons/luv-icon-theme/Luv/places/16/folder-download.svg icons/luv-icon-theme/Luv/places/16/folder-images.svg icons/luv-icon-theme/Luv/places/16/folder-music.svg icons/luv-icon-theme/Luv/places/16/folder-network.svg icons/luv-icon-theme/Luv/places/16/folder-pictures.svg icons/luv-icon-theme/Luv/places/16/folder-publicshare.svg icons/luv-icon-theme/Luv/places/16/folder-red.svg icons/luv-icon-theme/Luv/places/16/folder-sound.svg icons/luv-icon-theme/Luv/places/16/folder-text.svg icons/luv-icon-theme/Luv/places/16/folder-videos.svg icons/luv-icon-theme/Luv/places/16/folder.svg icons/luv-icon-theme/Luv/places/16/network-workgroup.svg icons/luv-icon-theme/Luv/places/16/user-desktop.svg icons/luv-icon-theme/Luv/places/16/user-home.svg icons/luv-icon-theme/Luv/places/16/user-trash-full.svg icons/luv-icon-theme/Luv/places/16/user-trash.svg icons/luv-icon-theme/Luv/actions/22/album.svg icons/luv-icon-theme/Luv/actions/22/amarok_artist.svg icons/luv-icon-theme/Luv/actions/22/amarok_clock.svg icons/luv-icon-theme/Luv/actions/22/amarok_lyrics.svg icons/luv-icon-theme/Luv/actions/22/amarok_playlist_refresh.svg icons/luv-icon-theme/Luv/actions/22/application-menu.svg icons/luv-icon-theme/Luv/actions/22/archive-extract.svg icons/luv-icon-theme/Luv/actions/22/archive-insert.svg icons/luv-icon-theme/Luv/actions/22/archive-remove.svg icons/luv-icon-theme/Luv/actions/22/artist.svg icons/luv-icon-theme/Luv/actions/22/bookmark-new.svg icons/luv-icon-theme/Luv/actions/22/configure.svg icons/luv-icon-theme/Luv/actions/22/dialog-close.svg icons/luv-icon-theme/Luv/actions/22/document-close.svg icons/luv-icon-theme/Luv/actions/22/document-download.svg icons/luv-icon-theme/Luv/actions/22/document-edit.svg icons/luv-icon-theme/Luv/actions/22/document-export.svg icons/luv-icon-theme/Luv/actions/22/document-import.svg icons/luv-icon-theme/Luv/actions/22/document-launch.svg icons/luv-icon-theme/Luv/actions/22/document-new.svg icons/luv-icon-theme/Luv/actions/22/document-open.svg icons/luv-icon-theme/Luv/actions/22/document-preview-archive.svg icons/luv-icon-theme/Luv/actions/22/document-save-as.svg icons/luv-icon-theme/Luv/actions/22/document-save.svg icons/luv-icon-theme/Luv/actions/22/document-share.svg icons/luv-icon-theme/Luv/actions/22/documentinfo.svg icons/luv-icon-theme/Luv/actions/22/draw-text.svg icons/luv-icon-theme/Luv/actions/22/edit-clear.svg icons/luv-icon-theme/Luv/actions/22/edit-find.svg icons/luv-icon-theme/Luv/actions/22/edit-pin.svg icons/luv-icon-theme/Luv/actions/22/edit-redo.svg icons/luv-icon-theme/Luv/actions/22/edit-select.svg icons/luv-icon-theme/Luv/actions/22/edit-undo.svg icons/luv-icon-theme/Luv/actions/22/entry-delete.svg icons/luv-icon-theme/Luv/actions/22/filename-filetype-amarok.svg icons/luv-icon-theme/Luv/actions/22/filename-space-amarok.svg icons/luv-icon-theme/Luv/actions/22/folder-add.svg icons/luv-icon-theme/Luv/actions/22/format-text-bold.svg icons/luv-icon-theme/Luv/actions/22/format-text-italic.svg icons/luv-icon-theme/Luv/actions/22/format-text-underline.svg icons/luv-icon-theme/Luv/actions/22/format-text-uppercase.svg icons/luv-icon-theme/Luv/actions/22/games-config-options.svg icons/luv-icon-theme/Luv/actions/22/go-down.svg icons/luv-icon-theme/Luv/actions/22/go-first.svg icons/luv-icon-theme/Luv/actions/22/go-home.svg icons/luv-icon-theme/Luv/actions/22/go-last.svg icons/luv-icon-theme/Luv/actions/22/go-next.svg icons/luv-icon-theme/Luv/actions/22/go-previous.svg icons/luv-icon-theme/Luv/actions/22/go-up.svg icons/luv-icon-theme/Luv/actions/22/headphones.svg icons/luv-icon-theme/Luv/actions/22/help-contents.svg icons/luv-icon-theme/Luv/actions/22/help-contextual.svg icons/luv-icon-theme/Luv/actions/22/hint.svg icons/luv-icon-theme/Luv/actions/22/image-folder-view.svg icons/luv-icon-theme/Luv/actions/22/image-frames.svg icons/luv-icon-theme/Luv/actions/22/image-multiple.svg icons/luv-icon-theme/Luv/actions/22/image.svg icons/luv-icon-theme/Luv/actions/22/internet-amarok.svg icons/luv-icon-theme/Luv/actions/22/internet-services.svg icons/luv-icon-theme/Luv/actions/22/list-add.svg icons/luv-icon-theme/Luv/actions/22/list-remove.svg icons/luv-icon-theme/Luv/actions/22/love.svg icons/luv-icon-theme/Luv/actions/22/media-album-track.svg icons/luv-icon-theme/Luv/actions/22/media-eject.svg icons/luv-icon-theme/Luv/actions/22/media-playback-pause.svg icons/luv-icon-theme/Luv/actions/22/media-playback-start.svg icons/luv-icon-theme/Luv/actions/22/media-playlist-append.svg icons/luv-icon-theme/Luv/actions/22/media-playlist-normal.svg icons/luv-icon-theme/Luv/actions/22/media-playlist-play.svg icons/luv-icon-theme/Luv/actions/22/media-playlist-repeat.svg icons/luv-icon-theme/Luv/actions/22/media-playlist-shuffle.svg icons/luv-icon-theme/Luv/actions/22/media-skip-backward.svg icons/luv-icon-theme/Luv/actions/22/media-skip-forward.svg icons/luv-icon-theme/Luv/actions/22/musicnote.svg icons/luv-icon-theme/Luv/actions/22/nx-configure.svg icons/luv-icon-theme/Luv/actions/22/nx-home.svg icons/luv-icon-theme/Luv/actions/22/object-rotate-left.svg icons/luv-icon-theme/Luv/actions/22/object-rotate-right.svg icons/luv-icon-theme/Luv/actions/22/overflow-menu.svg icons/luv-icon-theme/Luv/actions/22/process-stop.svg icons/luv-icon-theme/Luv/actions/22/tag.svg icons/luv-icon-theme/Luv/actions/22/view-books.svg icons/luv-icon-theme/Luv/actions/22/view-fullscreen.svg icons/luv-icon-theme/Luv/actions/22/view-left-close.svg icons/luv-icon-theme/Luv/actions/22/view-links.svg icons/luv-icon-theme/Luv/actions/22/view-list-details.svg icons/luv-icon-theme/Luv/actions/22/view-list-icons.svg icons/luv-icon-theme/Luv/actions/22/view-list-tree.svg icons/luv-icon-theme/Luv/actions/22/view-media-album.svg icons/luv-icon-theme/Luv/actions/22/view-media-artist.svg icons/luv-icon-theme/Luv/actions/22/view-media-chart.svg icons/luv-icon-theme/Luv/actions/22/view-media-config.svg icons/luv-icon-theme/Luv/actions/22/view-media-favorite.svg icons/luv-icon-theme/Luv/actions/22/view-media-genre.svg icons/luv-icon-theme/Luv/actions/22/view-media-playcount.svg icons/luv-icon-theme/Luv/actions/22/view-media-playlist.svg icons/luv-icon-theme/Luv/actions/22/view-media-recent.svg icons/luv-icon-theme/Luv/actions/22/view-media-similarartists.svg icons/luv-icon-theme/Luv/actions/22/view-media-track.svg icons/luv-icon-theme/Luv/actions/22/view-notes.svg icons/luv-icon-theme/Luv/actions/22/view-preview.svg icons/luv-icon-theme/Luv/actions/22/view-refresh.svg icons/luv-icon-theme/Luv/actions/22/view-restore.svg icons/luv-icon-theme/Luv/actions/22/view-right-close.svg icons/luv-icon-theme/Luv/actions/22/view-right-new.svg icons/luv-icon-theme/Luv/actions/22/view-sort.svg icons/luv-icon-theme/Luv/actions/22/visibility.svg icons/luv-icon-theme/Luv/actions/22/window-close.svg icons/luv-icon-theme/Luv/actions/16/amarok_playlist_refresh.svg icons/luv-icon-theme/Luv/actions/16/application-exit.svg icons/luv-icon-theme/Luv/actions/16/bookmark-new.svg icons/luv-icon-theme/Luv/actions/16/configure.svg icons/luv-icon-theme/Luv/actions/16/dialog-ok-apply.svg icons/luv-icon-theme/Luv/actions/16/dialog-ok.svg icons/luv-icon-theme/Luv/actions/16/document-import.svg icons/luv-icon-theme/Luv/actions/16/document-new.svg icons/luv-icon-theme/Luv/actions/16/document-open.svg icons/luv-icon-theme/Luv/actions/16/document-revert.svg icons/luv-icon-theme/Luv/actions/16/document-save-as.svg icons/luv-icon-theme/Luv/actions/16/document-save.svg icons/luv-icon-theme/Luv/actions/16/document-share.svg icons/luv-icon-theme/Luv/actions/16/edit-copy.svg icons/luv-icon-theme/Luv/actions/16/edit-cut.svg icons/luv-icon-theme/Luv/actions/16/edit-delete.svg icons/luv-icon-theme/Luv/actions/16/edit-find.svg icons/luv-icon-theme/Luv/actions/16/edit-paste.svg icons/luv-icon-theme/Luv/actions/16/edit-redo.svg icons/luv-icon-theme/Luv/actions/16/edit-undo.svg icons/luv-icon-theme/Luv/actions/16/filename-bpm-amarok.svg icons/luv-icon-theme/Luv/actions/16/filename-title-amarok.svg icons/luv-icon-theme/Luv/actions/16/get-hot-new-stuff.svg icons/luv-icon-theme/Luv/actions/16/go-jump-today.svg icons/luv-icon-theme/Luv/actions/16/help-contents.svg icons/luv-icon-theme/Luv/actions/16/list-add.svg icons/luv-icon-theme/Luv/actions/16/list-remove.svg icons/luv-icon-theme/Luv/actions/16/media-eject.svg icons/luv-icon-theme/Luv/actions/16/system-run.svg icons/luv-icon-theme/Luv/actions/16/tab-new.svg icons/luv-icon-theme/Luv/actions/16/view-calendar-day.svg icons/luv-icon-theme/Luv/actions/16/view-calendar-month.svg icons/luv-icon-theme/Luv/actions/16/view-calendar.svg icons/luv-icon-theme/Luv/actions/16/view-filter.svg icons/luv-icon-theme/Luv/actions/16/view-left-close.svg icons/luv-icon-theme/Luv/actions/16/view-list-details.svg icons/luv-icon-theme/Luv/actions/16/view-list-icons.svg icons/luv-icon-theme/Luv/actions/16/view-list-tree.svg icons/luv-icon-theme/Luv/actions/16/view-preview.svg icons/luv-icon-theme/Luv/actions/16/view-refresh.svg icons/luv-icon-theme/Luv/actions/16/view-right-close.svg icons/luv-icon-theme/Luv/actions/16/view-right-new.svg icons/luv-icon-theme/Luv/actions/16/window-new.svg icons/luv-icon-theme/Luv/actions/32/application-exit.svg icons/luv-icon-theme/Luv/actions/32/chronometer.svg icons/luv-icon-theme/Luv/actions/32/configure-shortcuts.svg icons/luv-icon-theme/Luv/actions/32/document-open-recent.svg icons/luv-icon-theme/Luv/actions/32/edit-select.svg icons/luv-icon-theme/Luv/actions/32/flag.svg icons/luv-icon-theme/Luv/actions/32/go-home.svg icons/luv-icon-theme/Luv/actions/32/object-group.svg icons/luv-icon-theme/Luv/actions/32/system-run.svg icons/luv-icon-theme/Luv/actions/32/tools-check-spelling.svg icons/luv-icon-theme/Luv/actions/32/view-choose.svg icons/luv-icon-theme/Luv/actions/32/view-filter.svg icons/luv-icon-theme/Luv/actions/32/view-list-tree.svg icons/luv-icon-theme/Luv/actions/32/view-preview.svg icons/luv-icon-theme/Luv/actions/32/window-duplicate.svg icons/luv-icon-theme/Luv/actions/48/configure.svg icons/luv-icon-theme/Luv/actions/48/system-run.svg icons/luv-icon-theme/Luv/categories/32/applications-development.svg icons/luv-icon-theme/Luv/categories/32/applications-games.svg icons/luv-icon-theme/Luv/categories/32/applications-graphics.svg icons/luv-icon-theme/Luv/categories/32/applications-internet.svg icons/luv-icon-theme/Luv/categories/32/applications-multimedia.svg icons/luv-icon-theme/Luv/categories/32/applications-office.svg icons/luv-icon-theme/Luv/categories/32/applications-other.svg icons/luv-icon-theme/Luv/categories/32/applications-system.svg icons/luv-icon-theme/Luv/categories/32/applications-utilities.svg icons/luv-icon-theme/Luv/categories/16/applications-graphics.svg icons/luv-icon-theme/Luv/devices/16/battery.svg icons/luv-icon-theme/Luv/devices/16/camera-web.svg icons/luv-icon-theme/Luv/devices/16/computer.svg icons/luv-icon-theme/Luv/devices/16/cpu.svg icons/luv-icon-theme/Luv/devices/16/drive-harddisk.svg icons/luv-icon-theme/Luv/devices/16/drive-removable-media-usb-pendrive.svg icons/luv-icon-theme/Luv/devices/16/drive-removable-media-usb.svg icons/luv-icon-theme/Luv/devices/16/drive-removable-media.svg icons/luv-icon-theme/Luv/devices/16/media-optical.svg icons/luv-icon-theme/Luv/devices/16/multimedia-player.svg icons/luv-icon-theme/Luv/devices/16/network-card.svg icons/luv-icon-theme/Luv/devices/16/phone.svg icons/luv-icon-theme/Luv/devices/16/smartphone.svg icons/luv-icon-theme/Luv/devices/16/video-display.svg icons/luv-icon-theme/Luv/devices/32/camera-photo.svg icons/luv-icon-theme/Luv/devices/32/drive-harddisk.svg icons/luv-icon-theme/Luv/devices/32/drive-removable-media-usb-pendrive.svg icons/luv-icon-theme/Luv/devices/32/drive-removable-media-usb.svg icons/luv-icon-theme/Luv/devices/32/drive-removable-media.svg icons/luv-icon-theme/Luv/devices/32/input-keyboard.svg icons/luv-icon-theme/Luv/devices/32/input-touchpad.svg icons/luv-icon-theme/Luv/devices/32/printer.svg icons/luv-icon-theme/Luv/devices/64/drive-harddisk.svg icons/luv-icon-theme/Luv/devices/64/smartphone.svg icons/luv-icon-theme/Luv/emblems/8/emblem-mounted.svg icons/luv-icon-theme/Luv/emblems/8/emblem-symbolic-link.svg icons/luv-icon-theme/Luv/emblems/8/emblem-unmounted.svg icons/luv-icon-theme/Luv/emblems/16/emblem-added.svg icons/luv-icon-theme/Luv/emblems/16/emblem-mounted.svg icons/luv-icon-theme/Luv/emblems/16/emblem-remove.svg icons/luv-icon-theme/Luv/emblems/16/emblem-symbolic-link.svg icons/luv-icon-theme/Luv/emblems/16/emblem-unmounted.svg icons/luv-icon-theme/Luv/emblems/22/emblem-default.svg icons/luv-icon-theme/Luv/emblems/22/emblem-encrypted-locked.svg icons/luv-icon-theme/Luv/emblems/22/emblem-encrypted-unlocked.svg icons/luv-icon-theme/Luv/emblems/22/emblem-error.svg icons/luv-icon-theme/Luv/emblems/22/emblem-important.svg icons/luv-icon-theme/Luv/emblems/22/emblem-info.svg icons/luv-icon-theme/Luv/emblems/22/emblem-locked.svg icons/luv-icon-theme/Luv/emblems/22/emblem-mounted.svg icons/luv-icon-theme/Luv/emblems/22/emblem-nowrite.svg icons/luv-icon-theme/Luv/emblems/22/emblem-readonly.svg icons/luv-icon-theme/Luv/emblems/22/emblem-select-add.svg icons/luv-icon-theme/Luv/emblems/22/emblem-select-remove.svg icons/luv-icon-theme/Luv/emblems/22/emblem-symbolic-link.svg icons/luv-icon-theme/Luv/emblems/22/emblem-unlocked.svg icons/luv-icon-theme/Luv/emblems/22/emblem-unmounted.svg icons/luv-icon-theme/Luv/emblems/32/emblem-symbolic-link.svg icons/luv-icon-theme/Luv/emotes/32/face-smile.svg icons/luv-icon-theme/Luv/mimetypes/16/application-x-cd-image.svg icons/luv-icon-theme/Luv/mimetypes/16/application-x-iso.svg icons/luv-icon-theme/Luv/mimetypes/16/inode-directory.svg icons/luv-icon-theme/Luv/mimetypes/32/application-epub+zip.svg icons/luv-icon-theme/Luv/mimetypes/32/application-javascript.svg icons/luv-icon-theme/Luv/mimetypes/32/application-pdf.svg icons/luv-icon-theme/Luv/mimetypes/32/application-pkcs8+pem.svg icons/luv-icon-theme/Luv/mimetypes/32/application-pkcs10.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.android.package-archive.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.ms-excel.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.ms-powerpoint.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.ms-word.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.openxmlformats-officedocument.presentationml.presentation.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.openxmlformats-officedocument.spreadsheetml.sheet.svg icons/luv-icon-theme/Luv/mimetypes/32/application-vnd.openxmlformats-officedocument.wordprocessingml.document.svg icons/luv-icon-theme/Luv/mimetypes/32/application-wps-office.doc.svg icons/luv-icon-theme/Luv/mimetypes/32/application-wps-office.ppt.svg icons/luv-icon-theme/Luv/mimetypes/32/application-wps-office.xlsx.svg icons/luv-icon-theme/Luv/mimetypes/32/application-x-7z-compressed.svg icons/luv-icon-theme/Luv/mimetypes/32/application-x-bittorrent.svg icons/luv-icon-theme/Luv/mimetypes/32/application-x-cd-image.svg icons/luv-icon-theme/Luv/mimetypes/32/application-x-executable.svg icons/luv-icon-theme/Luv/mimetypes/32/application-x-font-ttf.svg icons/luv-icon-theme/Luv/mimetypes/32/application-x-iso.svg icons/luv-icon-theme/Luv/mimetypes/32/audio-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/32/image-svg+xml.svg icons/luv-icon-theme/Luv/mimetypes/32/image-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/32/inode-directory.svg icons/luv-icon-theme/Luv/mimetypes/32/text-plain.svg icons/luv-icon-theme/Luv/mimetypes/32/text-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/32/video-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/48/application-vnd.ms-excel.svg icons/luv-icon-theme/Luv/mimetypes/48/application-vnd.ms-powerpoint.svg icons/luv-icon-theme/Luv/mimetypes/48/application-vnd.ms-word.svg icons/luv-icon-theme/Luv/mimetypes/48/application-vnd.openxmlformats-officedocument.presentationml.presentation.svg icons/luv-icon-theme/Luv/mimetypes/48/application-vnd.openxmlformats-officedocument.spreadsheetml.sheet.svg icons/luv-icon-theme/Luv/mimetypes/48/application-vnd.openxmlformats-officedocument.wordprocessingml.document.svg icons/luv-icon-theme/Luv/mimetypes/48/application-x-cd-image.svg icons/luv-icon-theme/Luv/mimetypes/48/application-x-iso.svg icons/luv-icon-theme/Luv/mimetypes/48/inode-directory.svg icons/luv-icon-theme/Luv/mimetypes/48/text-plain.svg icons/luv-icon-theme/Luv/mimetypes/48/text-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/64/application-epub+zip.svg icons/luv-icon-theme/Luv/mimetypes/64/application-javascript.svg icons/luv-icon-theme/Luv/mimetypes/64/application-octet-stream.svg icons/luv-icon-theme/Luv/mimetypes/64/application-pdf.svg icons/luv-icon-theme/Luv/mimetypes/64/application-pkcs8+pem.svg icons/luv-icon-theme/Luv/mimetypes/64/application-pkcs10.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.android.package-archive.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.ms-excel.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.ms-powerpoint.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.ms-word.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.openxmlformats-officedocument.presentationml.presentation.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.openxmlformats-officedocument.spreadsheetml.sheet.svg icons/luv-icon-theme/Luv/mimetypes/64/application-vnd.openxmlformats-officedocument.wordprocessingml.document.svg icons/luv-icon-theme/Luv/mimetypes/64/application-wps-office.doc.svg icons/luv-icon-theme/Luv/mimetypes/64/application-wps-office.ppt.svg icons/luv-icon-theme/Luv/mimetypes/64/application-wps-office.xlsx.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-7z-compressed.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-bzip-compressed-tar.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-cd-image.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-compressed-tar.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-cue.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-executable.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-font-otf.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-font-ttf.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-iso.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-java-archive.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-lha.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-pem-key.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-raw-disk-image.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-ruby.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-sharedlib.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-shellscript.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-tar.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-theme.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-trash.svg icons/luv-icon-theme/Luv/mimetypes/64/application-x-zerosize.svg icons/luv-icon-theme/Luv/mimetypes/64/application-zip.svg icons/luv-icon-theme/Luv/mimetypes/64/audio-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/64/font-ttf.svg icons/luv-icon-theme/Luv/mimetypes/64/fonts-package.svg icons/luv-icon-theme/Luv/mimetypes/64/image-bmp.svg icons/luv-icon-theme/Luv/mimetypes/64/image-jpeg.svg icons/luv-icon-theme/Luv/mimetypes/64/image-png.svg icons/luv-icon-theme/Luv/mimetypes/64/image-svg+xml-compressed.svg icons/luv-icon-theme/Luv/mimetypes/64/image-svg+xml.svg icons/luv-icon-theme/Luv/mimetypes/64/image-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/64/inode-blockdevice.svg icons/luv-icon-theme/Luv/mimetypes/64/inode-chardevice.svg icons/luv-icon-theme/Luv/mimetypes/64/inode-directory.svg icons/luv-icon-theme/Luv/mimetypes/64/package-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/64/text-css.svg icons/luv-icon-theme/Luv/mimetypes/64/text-html.svg icons/luv-icon-theme/Luv/mimetypes/64/text-markdown.svg icons/luv-icon-theme/Luv/mimetypes/64/text-plain.svg icons/luv-icon-theme/Luv/mimetypes/64/text-x-cmake.svg icons/luv-icon-theme/Luv/mimetypes/64/text-x-credits.svg icons/luv-icon-theme/Luv/mimetypes/64/text-x-generic.svg icons/luv-icon-theme/Luv/mimetypes/64/video-mp4.svg icons/luv-icon-theme/Luv/mimetypes/64/video-x-matroska.svg icons/luv-icon-theme/Luv/mimetypes/64/video-x-msvideo.svg icons/luv-icon-theme/Luv/places/32/bookmarks.svg icons/luv-icon-theme/Luv/places/32/folder-documents.svg icons/luv-icon-theme/Luv/places/32/folder-download.svg icons/luv-icon-theme/Luv/places/32/folder-dropbox.svg icons/luv-icon-theme/Luv/places/32/folder-github.svg icons/luv-icon-theme/Luv/places/32/folder-google-drive.svg icons/luv-icon-theme/Luv/places/32/folder-launchpad.svg icons/luv-icon-theme/Luv/places/32/folder-mega.svg icons/luv-icon-theme/Luv/places/32/folder-music.svg icons/luv-icon-theme/Luv/places/32/folder-network.svg icons/luv-icon-theme/Luv/places/32/folder-pictures.svg icons/luv-icon-theme/Luv/places/32/folder-publicshare.svg icons/luv-icon-theme/Luv/places/32/folder-red.svg icons/luv-icon-theme/Luv/places/32/folder-templates.svg icons/luv-icon-theme/Luv/places/32/folder-videos.svg icons/luv-icon-theme/Luv/places/32/folder.svg icons/luv-icon-theme/Luv/places/32/network-workgroup.svg icons/luv-icon-theme/Luv/places/32/user-desktop.svg icons/luv-icon-theme/Luv/places/32/user-home.svg icons/luv-icon-theme/Luv/places/32/user-trash-full.svg icons/luv-icon-theme/Luv/places/32/user-trash.svg icons/luv-icon-theme/Luv/places/48/folder-documents.svg icons/luv-icon-theme/Luv/places/48/folder-download.svg icons/luv-icon-theme/Luv/places/48/folder-dropbox.svg icons/luv-icon-theme/Luv/places/48/folder-github.svg icons/luv-icon-theme/Luv/places/48/folder-google-drive.svg icons/luv-icon-theme/Luv/places/48/folder-launchpad.svg icons/luv-icon-theme/Luv/places/48/folder-mega.svg icons/luv-icon-theme/Luv/places/48/folder-music.svg icons/luv-icon-theme/Luv/places/48/folder-network.svg icons/luv-icon-theme/Luv/places/48/folder-pictures.svg icons/luv-icon-theme/Luv/places/48/folder-publicshare.svg icons/luv-icon-theme/Luv/places/48/folder-red.svg icons/luv-icon-theme/Luv/places/48/folder-templates.svg icons/luv-icon-theme/Luv/places/48/folder-videos.svg icons/luv-icon-theme/Luv/places/48/folder.svg icons/luv-icon-theme/Luv/places/48/network-workgroup.svg icons/luv-icon-theme/Luv/places/48/user-desktop.svg icons/luv-icon-theme/Luv/places/48/user-home.svg icons/luv-icon-theme/Luv/places/48/user-trash-full.svg icons/luv-icon-theme/Luv/places/48/user-trash.svg icons/luv-icon-theme/Luv/places/64/folder-documents.svg icons/luv-icon-theme/Luv/places/64/folder-download.svg icons/luv-icon-theme/Luv/places/64/folder-dropbox.svg icons/luv-icon-theme/Luv/places/64/folder-github.svg icons/luv-icon-theme/Luv/places/64/folder-google-drive.svg icons/luv-icon-theme/Luv/places/64/folder-launchpad.svg icons/luv-icon-theme/Luv/places/64/folder-mega.svg icons/luv-icon-theme/Luv/places/64/folder-music.svg icons/luv-icon-theme/Luv/places/64/folder-network.svg icons/luv-icon-theme/Luv/places/64/folder-pictures.svg icons/luv-icon-theme/Luv/places/64/folder-publicshare.svg icons/luv-icon-theme/Luv/places/64/folder-red.svg icons/luv-icon-theme/Luv/places/64/folder-templates.svg icons/luv-icon-theme/Luv/places/64/folder-videos.svg icons/luv-icon-theme/Luv/places/64/folder.svg icons/luv-icon-theme/Luv/places/64/network-workgroup.svg icons/luv-icon-theme/Luv/places/64/user-desktop.svg icons/luv-icon-theme/Luv/places/64/user-home.svg icons/luv-icon-theme/Luv/places/64/user-trash-full.svg icons/luv-icon-theme/Luv/places/64/user-trash.svg icons/luv-icon-theme/Luv/status/22/dialog-information.svg icons/luv-icon-theme/Luv/status/22/update-high.svg icons/luv-icon-theme/Luv/status/22/update-low.svg icons/luv-icon-theme/Luv/status/22/update-medium.svg icons/luv-icon-theme/Luv/status/22/update-none.svg icons/luv-icon-theme/Luv/status/32/security-high.svg icons/luv-icon-theme/Luv/status/32/update-none.svg icons/luv-icon-theme/Luv/status/32/user-online.svg icons/luv-icon-theme/Luv/status/32/weather-clear-night.svg icons/luv-icon-theme/Luv/status/32/weather-clear.svg icons/luv-icon-theme/Luv/status/32/weather-clouds-nights.svg icons/luv-icon-theme/Luv/status/32/weather-clouds.svg icons/luv-icon-theme/Luv/status/32/weather-few-clouds-night.svg icons/luv-icon-theme/Luv/status/32/weather-few-clouds.svg icons/luv-icon-theme/Luv/status/32/weather-freezing-rain.svg icons/luv-icon-theme/Luv/status/32/weather-hail.svg icons/luv-icon-theme/Luv/status/32/weather-many-clouds.svg icons/luv-icon-theme/Luv/status/32/weather-overcast.svg icons/luv-icon-theme/Luv/status/32/weather-showers-day.svg icons/luv-icon-theme/Luv/status/32/weather-showers-night.svg icons/luv-icon-theme/Luv/status/32/weather-showers-scattered-day.svg icons/luv-icon-theme/Luv/status/32/weather-showers-scattered-night.svg icons/luv-icon-theme/Luv/status/32/weather-showers-scattered.svg icons/luv-icon-theme/Luv/status/32/weather-showers.svg icons/luv-icon-theme/Luv/status/32/weather-snow-rain.svg icons/luv-icon-theme/Luv/status/32/weather-snow-scattered-day.svg icons/luv-icon-theme/Luv/status/32/weather-snow-scattered-night.svg icons/luv-icon-theme/Luv/status/32/weather-snow-scattered.svg icons/luv-icon-theme/Luv/status/32/weather-snow.svg icons/luv-icon-theme/Luv/status/32/weather-storm-night.svg icons/luv-icon-theme/Luv/status/32/weather-storm.svg icons/luv-icon-theme/Luv/status/48/dialog-information.svg icons/luv-icon-theme/Luv/status/64/dialog-information.svg icons/luv-icon-theme/Luv/status/128/dialog-information.svg icons/luv-icon-theme/Luv/status/128/user-identity.svg icons/luv-icon-theme/Luv/apps/22/nx-software-center.svg icons/luv-icon-theme/Luv/actions/22/checkbox.svg icons/luv-icon-theme/Luv/actions/22/configure-toolbars.svg icons/luv-icon-theme/Luv/actions/22/draw-star.svg icons/luv-icon-theme/Luv/actions/22/edit-link.svg icons/luv-icon-theme/Luv/actions/22/go-bottom.svg icons/luv-icon-theme/Luv/actions/22/go-jump.svg icons/luv-icon-theme/Luv/actions/22/go-top.svg icons/luv-icon-theme/Luv/actions/22/handle-sort.svg icons/luv-icon-theme/Luv/actions/22/image-preview.svg icons/luv-icon-theme/Luv/actions/22/item-select.svg icons/luv-icon-theme/Luv/actions/22/list-add-user.svg icons/luv-icon-theme/Luv/actions/22/ok-apply.svg icons/luv-icon-theme/Luv/actions/22/settings-configure.svg icons/luv-icon-theme/Luv/actions/22/view-calendar.svg icons/luv-icon-theme/Luv/actions/22/view-media-video.svg icons/luv-icon-theme/Luv/actions/22/zoom-fit-height.svg icons/luv-icon-theme/Luv/actions/22/zoom-fit-width.svg icons/luv-icon-theme/Luv/actions/22/zoom-in.svg icons/luv-icon-theme/Luv/actions/22/zoom-original.svg icons/luv-icon-theme/Luv/actions/22/zoom-out.svg icons/luv-icon-theme/Luv/actions/22/zoom.svg icons/luv-icon-theme/Luv/actions/22/sms.svg icons/luv-icon-theme/Luv/actions/22/email.svg icons/luv-icon-theme/Luv/actions/22/edit-add-effect.svg icons/luv-icon-theme/Luv/actions/22/dialer-call-start.svg icons/luv-icon-theme/Luv/actions/22/dialer-call-pause.svg icons/luv-icon-theme/Luv/actions/22/dialer-call-end.svg icons/luv-icon-theme/Luv/actions/22/view-pim-notes.svg icons/luv-icon-theme/Luv/actions/22/view-pim-news.svg icons/luv-icon-theme/Luv/actions/22/view-pim-journal.svg icons/luv-icon-theme/Luv/actions/22/view-pim-contacts.svg icons/luv-icon-theme/Luv/actions/22/view-contacts.svg icons/luv-icon-theme/Luv/actions/22/send-sms.svg icons/luv-icon-theme/Luv/actions/22/send-email.svg icons/luv-icon-theme/Luv/actions/22/pin.svg icons/luv-icon-theme/Luv/actions/22/media-speaker.svg icons/luv-icon-theme/Luv/actions/22/media-silence.svg icons/luv-icon-theme/Luv/actions/22/media-bluetooth.svg icons/luv-icon-theme/Luv/actions/22/folder-new.svg + icons/luv-icon-theme/Luv/actions/22/email.svg + icons/luv-icon-theme/Luv/actions/22/edit-add-effect.svg icons/luv-icon-theme/Luv/actions/22/dialer-pad.svg icons/luv-icon-theme/Luv/actions/22/dialer-call.svg + icons/luv-icon-theme/Luv/actions/22/dialer-call-start.svg + icons/luv-icon-theme/Luv/actions/22/dialer-call-pause.svg + icons/luv-icon-theme/Luv/actions/22/dialer-call-end.svg icons/luv-icon-theme/Luv/actions/22/add-image.svg diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml index 56ed852..80f4949 100644 --- a/src/controls/ApplicationWindow.qml +++ b/src/controls/ApplicationWindow.qml @@ -1,521 +1,458 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import QtQuick.Window 2.3 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui import QtQuick.Controls.Material 2.1 import "private" Kirigami.AbstractApplicationWindow { id: root visible: true width: Screen.width * (isMobile ? 1 : 0.4) height: Screen.height * (isMobile ? 1 : 0.4) property bool showAccounts : true /***************************************************/ /******************** ALIASES *********************/ /*************************************************/ property alias headBar : _headBar property alias footBar: _footBar property alias dialog: dialogLoader.item property alias leftIcon : menuBtn property alias rightIcon : searchBtn property alias mainMenu : mainMenu.contentData property alias about : aboutDialog property alias accounts: _accountsDialogLoader.item property var currentAccount: Maui.App.accounts.currentAccount property alias notifyDialog: _notify //redefines here as here we can know a pointer to PageRow wideScreen: isWide /***************************************************/ /*********************** UI ***********************/ /*************************************************/ property bool isWide : root.width >= Kirigami.Units.gridUnit * 30 property int radiusV : unit * 4 property int iconSize : iconSizes.medium * (isMobile ? 0.95 : 1) readonly property int unit : Maui.Style.unit readonly property int rowHeight: Maui.Style.rowHeight readonly property int rowHeightAlt: Maui.Style.rowHeightAlt readonly property int toolBarHeight: Maui.Style.toolBarHeight readonly property int toolBarHeightAlt: Maui.Style.toolBarHeightAlt readonly property int contentMargins: space.medium readonly property var fontSizes: Maui.Style.fontSizes readonly property var space : Maui.Style.space readonly property var iconSizes : Maui.Style.iconSizes property string colorSchemeName : Qt.application.name /***************************************************/ /********************* COLORS *********************/ /*************************************************/ - - readonly property var colorScheme: ({ - Default : 1, - Light : 2, - Dark: 3, - Custom: 4 - }) - property color headBarBGColor: Kirigami.Theme.backgroundColor property color headBarFGColor: Kirigami.Theme.textColor property color warningColor : Maui.Style.warningColor property color dangerColor : Maui.Style.dangerColor property color infoColor : Maui.Style.infoColor property color suggestedColor : Maui.Style.suggestedColor - - /* ANDROID THEMING*/ - -// Material.theme: Material.Dark -// Material.accent: "yellow" -// Material.background: headBarBGColor -// Material.primary: headBarBGColor -// Material.foreground: Kirigami.Theme.textColor + /***************************************************/ /**************** READONLY PROPS ******************/ /*************************************************/ readonly property bool isMobile : Kirigami.Settings.isMobile readonly property bool isAndroid: Qt.platform.os == "android" readonly property real screenWidth : Screen.width readonly property real screenHeight : Screen.height /***************************************************/ /********************* PROPS **********************/ /*************************************************/ property alias searchButton : searchBtn property alias menuButton : menuBtn /***************************************************/ /******************** SIGNALS *********************/ /*************************************************/ signal menuButtonClicked(); signal searchButtonClicked(); - signal goBackTriggered(); - signal goFowardTriggered(); - - // overlay.modal: Rectangle - // { - // color: Color.transparent(altColor, 0.5) - // } - - - // overlay.modeless: Rectangle { - // color: "transparent" - // } - - + onClosing: { if(!isMobile) { var height = root.height var width = root.width var x = root.x var y = root.y Maui.FM.saveSettings("GEOMETRY", Qt.rect(x, y, width, height), "WINDOW") } } property bool isPortrait: Screen.primaryOrientation === Qt.PortraitOrientation || Screen.primaryOrientation === Qt.InvertedPortraitOrientation onIsPortraitChanged: { if(isPortrait) { console.log("PORTARIT MODE CHANGED") width: Screen.width height: Screen.height } } // onHeadBarBGColorChanged: // { // if(!isMobile && colorSchemeName.length > 0) // Maui.KDE.setColorScheme(colorSchemeName, headBarBGColor, headBarFGColor) // else if(isAndroid && headBar.position === ToolBar.Header) // Maui.Android.statusbarColor(headBarBGColor, false) // else if(isAndroid && headBar.position === ToolBar.Footer) // Maui.Android.statusbarColor(Kirigami.Theme.viewBackgroundColor, true) // // } // // onHeadBarFGColorChanged: // { // if(!isAndroid && !isMobile && colorSchemeName.length > 0 && headBar.position === ToolBar.Header) // Maui.KDE.setColorScheme(colorSchemeName, headBarBGColor, headBarFGColor) // else if(isAndroid && headBar.position === ToolBar.Header) // Maui.Android.statusbarColor(headBarBGColor, false) // else if(isAndroid && headBar.position === ToolBar.Footer) // Maui.Android.statusbarColor(Kirigami.Theme.viewBackgroundColor, true) // } /* * background: Rectangle * { * color: bgColor } */ property QtObject mheadBar : Maui.ToolBar { id: _headBar visible: count > 1 position: ToolBar.Header width: root.width // Kirigami.Theme.backgroundColor: headBarBGColor // Kirigami.Theme.textColor: headBarFGColor // Kirigami.Theme.inherit: true leftContent: [ ToolButton { id: menuBtn icon.name: "application-menu" icon.color: headBarFGColor icon.width: iconSizes.medium icon.height: iconSizes.medium checked: mainMenu.visible onClicked: { menuButtonClicked() mainMenu.visible ? mainMenu.close() : mainMenu.popup(parent, parent.x , parent.height+ space.medium) } Menu { id: mainMenu modal: true z: 999 width: unit * 200 Item { height: _accountCombobox.visible ? _accountCombobox.implicitHeight + space.big: 0 anchors { left: parent.left right: parent.right top: parent.top margins: space.medium } ComboBox { id: _accountCombobox anchors.centerIn: parent // parent: mainMenu popup.z: 999 width: parent.width // visible: (count > 1) && showAccounts textRole: "user" flat: true model: Maui.BaseModel { list: Maui.App.accounts } onActivated: Maui.App.accounts.currentAccountIndex = index; Component.onCompleted: { if(_accountCombobox.count > 0) { _accountCombobox.currentIndex = 0 Maui.App.accounts.currentAccountIndex = _accountCombobox.currentIndex } } } } MenuItem { text: qsTr("Accounts") visible: root.showAccounts icon.name: "list-add-user" onTriggered: { if(root.accounts) accounts.open() } } MenuSeparator { visible: _accountCombobox.visible } MenuItem { text: qsTr("About") icon.name: "documentinfo" onTriggered: aboutDialog.open() } } }, Kirigami.Separator { visible: menuBtn.visible Layout.preferredHeight: 16 opacity: 0.5 width: visible ? 2 : 0 } ] rightContent: ToolButton { id: searchBtn icon.name: "edit-find" icon.color: headBarFGColor onClicked: searchButtonClicked() } } property QtObject mfootBar : Maui.ToolBar { id: _footBar visible: count position: ToolBar.Footer width: root.width - // Kirigami.Theme.backgroundColor: Kirigami.Theme.backgroundColor } header: headBar.count && headBar.position === ToolBar.Header ? headBar : undefined footer: Column { id: _footer visible : children > 0 children: { if(headBar.position === ToolBar.Footer && headBar.count && footBar.count) return [footBar , headBar] else if(headBar.position === ToolBar.Footer && headBar.count) return [headBar] else if(footBar.count) return [footBar] else return [] } } Maui.AboutDialog { id: aboutDialog } Loader { id: _accountsDialogLoader sourceComponent: root.showAccounts ? _accountsDialogComponent : undefined } Component { id: _accountsDialogComponent AccountsHelper {} } Maui.Dialog { id: _notify property var cb : ({}) verticalAlignment: Qt.AlignTop defaultButtons: false maxHeight: Math.max(unit * 120, (_notifyLayout.implicitHeight)) maxWidth: isMobile ? parent.width * 0.9 : unit * 500 Timer { id: _notifyTimer onTriggered: _notify.close() } onClosed: _notifyTimer.stop() MouseArea { anchors.fill: parent onClicked: { if(_notify.cb) _notify.cb() _notify.close() } } GridLayout { anchors.fill: parent columns: 2 rows: 1 Item { Layout.fillHeight: true Layout.preferredWidth: iconSizes.huge + space.big Layout.row: 1 Layout.column: 1 ToolButton { id: _notifyIcon icon.width: iconSizes.large anchors.centerIn: parent } } Item { Layout.fillHeight: true Layout.fillWidth: true Layout.row: 1 Layout.column: 2 ColumnLayout { anchors.fill: parent id: _notifyLayout Label { id: _notifyTitle Layout.fillHeight: true Layout.fillWidth: true font.weight: Font.Bold font.bold: true font.pointSize: fontSizes.big // color: _notify.colorScheme.textColor elide: Qt.ElideRight wrapMode: Text.Wrap } Label { id: _notifyBody Layout.fillHeight: true Layout.fillWidth: true font.pointSize: fontSizes.default // color: _notify.colorScheme.textColor elide: Qt.ElideRight wrapMode: Text.Wrap } } } } function show(callback) { _notify.cb = callback _notifyTimer.start() _notify.open() } } Loader { id: dialogLoader } Component.onCompleted: { if(isAndroid && headBar.position === ToolBar.Footer) Maui.Android.statusbarColor(Kirigami.Theme.backgroundColor, true) if(!isMobile) { var rect = Maui.FM.loadSettings("GEOMETRY", "WINDOW", Qt.rect(root.x, root.y, root.width, root.height)) root.x = rect.x root.y = rect.y root.width = rect.width root.height = rect.height } } - function switchColorScheme(variant) - { - // switch(variant) - // { - // case colorScheme.Default: - // - // backgroundColor = Maui.Style.backgroundColor - // textColor = Maui.Style.textColor - // highlightColor = Maui.Style.highlightColor - // highlightedTextColor = Maui.Style.highlightedTextColor - // buttonBackgroundColor = Maui.Style.buttonBackgroundColor - // viewBackgroundColor = Maui.Style.viewBackgroundColor - // altColor = Maui.Style.altColor - // borderColor = Maui.Style.borderColor - // if(isAndroid) Maui.Android.statusbarColor(backgroundColor, true) - // break - // - // case colorScheme.Dark: - // borderColor = darkBorderColor - // backgroundColor = darkBackgroundColor - // textColor = darkTextColor - // highlightColor = darkHighlightColor - // highlightedTextColor = darkHighlightedTextColor - // buttonBackgroundColor = darkButtonBackgroundColor - // viewBackgroundColor = darkViewBackgroundColor - // altColor = darkDarkColor - // altColorText = darkAltColorText - // bgColor =darkBgColor - // - // if(isAndroid) Maui.Android.statusbarColor(backgroundColor, false) - // break - // } - } - function notify(icon, title, body, callback, timeout) { _notifyIcon.icon.name = icon _notifyTitle.text = title _notifyBody.text = body _notifyTimer.interval = timeout ? timeout : 2500 _notify.show(callback) } } diff --git a/src/controls/FileBrowser.qml b/src/controls/FileBrowser.qml index 5ca5e66..ae03057 100644 --- a/src/controls/FileBrowser.qml +++ b/src/controls/FileBrowser.qml @@ -1,1158 +1,1103 @@ import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui import "private" Maui.Page { - id: control - - property alias trackChanges: modelList.trackChanges - property alias saveDirProps: modelList.saveDirProps - - property string currentPath: Maui.FM.homePath() - - property var copyItems : [] - property var cutItems : [] - - property var indexHistory : [] - - property bool isCopy : false - property bool isCut : false - - property bool selectionMode : false - property bool group : false - property bool showEmblems: true - property bool singleSelection: false - - property alias selectionBar : selectionBarLoader.item - - property alias model : folderModel - property alias list : modelList - property alias browser : viewLoader.item - property var currentFMList : modelList - - property alias previewer : previewer - property alias menu : browserMenu.contentData - property alias itemMenu: itemMenu - property alias holder: holder - property alias dialog : dialogLoader.item - property alias goUpButton : goUpButton - - property int currentPathType : currentFMList.pathType - property int thumbnailsSize : iconSizes.large - - signal itemClicked(int index) - signal itemDoubleClicked(int index) - signal itemRightClicked(int index) - signal itemLeftEmblemClicked(int index) - signal itemRightEmblemClicked(int index) - signal rightClicked() - signal newBookmark(var paths) - - focus: true - Kirigami.Theme.colorSet: Kirigami.Theme.View - Kirigami.Theme.inherit: false -// Kirigami.Theme.backgroundColor: Kirigami.Theme.viewBackgroundColor - - Loader - { - id: dialogLoader - } - - Component - { - id: removeDialogComponent - - Maui.Dialog - { - property var items: [] - - title: qsTr("Remove files?") - message: qsTr("You can move the file to the Trash or Delete it completely from your system. Which one you preffer?") - rejectButton.text: qsTr("Delete") - acceptButton.text: qsTr("Trash") -// acceptButton.Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.neutralTextColor.r, Kirigami.Theme.neutralTextColor.g, Kirigami.Theme.neutralTextColor.b, 0.2) -// acceptButton.Kirigami.Theme.textColor: Kirigami.Theme.neutralTextColor - onRejected: - { - if(control.selectionBar && control.selectionBar.visible) - { - control.selectionBar.clear() - control.selectionBar.animate(Maui.Style.dangerColor) - } - - control.remove(items) - close() - } - - onAccepted: - { - if(control.selectionBar && control.selectionBar.visible) - { - control.selectionBar.clear() - control.selectionBar.animate(Maui.Style.dangerColor) - } - - control.trash(items) - close() - } - } - } - - Component - { - id: newFolderDialogComponent - - Maui.NewDialog - { - title: qsTr("New folder") - message: qsTr("Create a new folder with a custom name") - acceptButton.text: qsTr("Create") - onFinished: list.createDir(text) - rejectButton.visible: false - textEntry.placeholderText: qsTr("Folder name...") - } - } - - Component - { - id: newFileDialogComponent - - Maui.NewDialog - { - title: qsTr("New file") - message: qsTr("Create a new file with a custom name and extension") - acceptButton.text: qsTr("Create") - onFinished: Maui.FM.createFile(control.currentPath, text) - rejectButton.visible: false - textEntry.placeholderText: qsTr("File name...") - } - } - - Component - { - id: renameDialogComponent - Maui.NewDialog - { - title: qsTr("Rename file") - message: qsTr("Rename a file or folder to a new custom name") - textEntry.text: itemMenu.item.label - textEntry.placeholderText: qsTr("New name...") - onFinished: Maui.FM.rename(itemMenu.item.path, textEntry.text) - onRejected: close() - acceptText: qsTr("Rename") - rejectText: qsTr("Cancel") - } - } - - Component - { - id: shareDialogComponent - Maui.ShareDialog {} - } - - Component - { - id: tagsDialogComponent - Maui.TagsDialog - { - onTagsReady: composerList.updateToUrls(tags) - } - } - - BrowserMenu - { - id: browserMenu - // width: unit *200 - z : control.z +1 - } - - Maui.FilePreviewer - { - id: previewer - parent: parent - onShareButtonClicked: control.shareFiles([url]) - } - - Maui.BaseModel - { - id: folderModel - list: modelList - } - - Maui.FMList - { - id: modelList - preview: true - path: currentPath - foldersFirst: true - onSortByChanged: if(group) groupBy() - onContentReadyChanged: console.log("CONTENT READY?", contentReady) - onWarning: - { - notify("dialog-information", "An error happened", message) - } - - onProgress: - { - if(percent === 100) - _progressBar.value = 0 - else - _progressBar.value = percent/100 - } - } - - FileMenu - { - id: itemMenu - width: unit *200 - onBookmarkClicked: control.newBookmark([item.path]) - onCopyClicked: - { - if(item) - control.copy([item]) - } - - onCutClicked: - { - if(item) - control.cut([item]) - } - - onTagsClicked: - { - if(item) - { - dialogLoader.sourceComponent = tagsDialogComponent - dialog.composerList.urls = item.path - dialog.open() - } - } - - onRenameClicked: - { - dialogLoader.sourceComponent = renameDialogComponent - dialog.open() - - } - - // 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: - { - dialogLoader.sourceComponent= removeDialogComponent - dialog.items = [item] - dialog.open() - } - - onShareClicked: control.shareFiles([item.path]) - - } - - Component - { - id: listViewBrowser - - Maui.ListBrowser - { - showPreviewThumbnails: modelList.preview - keepEmblemOverlay: selectionMode - rightEmblem: isMobile ? "document-share" : "" - leftEmblem: "list-add" - showDetailsInfo: true - // itemSize: thumbnailsSize - model: folderModel - section.delegate: Maui.LabelDelegate - { - id: delegate - label: section - labelTxt.font.pointSize: fontSizes.big - - isSection: true - boldLabel: true - height: toolBarHeightAlt - } - } - } - - Component - { - id: gridViewBrowser - - Maui.GridBrowser - { - itemSize : thumbnailsSize + fontSizes.default - keepEmblemOverlay: selectionMode - showPreviewThumbnails: modelList.preview - rightEmblem: isMobile ? "document-share" : "" - leftEmblem: "list-add" - model: folderModel - } - } - - Component - { - id: millerViewBrowser - - Kirigami.ColumnView - { - id: _millerColumns - columnWidth: Math.min(Kirigami.Units.gridUnit * 22, control.width) -// fillWidth: true - columnResizeMode: Kirigami.ColumnView.DynamicColumns - - signal itemClicked(int index) - signal itemDoubleClicked(int index) - signal itemRightClicked(int index) - - signal rightEmblemClicked(int index) - signal leftEmblemClicked(int index) - - signal areaClicked(var mouse) - signal areaRightClicked() - - Maui.PathList - { - id: _millerList - path: control.currentPath - onPathChanged: _millerColumns.currentIndex = _repeater.count - 1 - } - - Maui.BaseModel - { - id: _millerModel - list: _millerList - } - - Repeater - { - id: _repeater - model: _millerModel - - onItemAdded: - { -// if(viewLoader.sourceComponent === millerViewBrowser) -// _millerColumns.currentIndex = _millerColumns.count-1 - -// _millerColumns.contentX= _millerColumns.columnWidth * _millerColumns.count + id: control + + property alias trackChanges: modelList.trackChanges + property alias saveDirProps: modelList.saveDirProps + + property string currentPath: Maui.FM.homePath() + + property var copyItems : [] + property var cutItems : [] + + property var indexHistory : [] + + property bool isCopy : false + property bool isCut : false + + property bool selectionMode : false + property bool group : false + property bool showEmblems: true + property bool singleSelection: false + + property alias selectionBar : selectionBarLoader.item + + property alias model : folderModel + property alias list : modelList + property alias browser : viewLoader.item + property var currentFMList : modelList + + property alias previewer : previewer + property alias menu : browserMenu.contentData + property alias itemMenu: itemMenu + property alias holder: holder + property alias dialog : dialogLoader.item + property alias goUpButton : goUpButton + + property int currentPathType : currentFMList.pathType + property int thumbnailsSize : iconSizes.large + + signal itemClicked(int index) + signal itemDoubleClicked(int index) + signal itemRightClicked(int index) + signal itemLeftEmblemClicked(int index) + signal itemRightEmblemClicked(int index) + signal rightClicked() + signal newBookmark(var paths) + + focus: true + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + + onGoBackTriggered: control.goBack() + onGoForwardTriggered: control.goNext() + + Keys.onSpacePressed: previewer.show(control.currentFMList.get(browser.currentIndex).path) + headBar.visible: currentPathType !== Maui.FMList.APPS_PATH + headBar.position: isMobile ? ToolBar.Footer : ToolBar.Header + property list t_actions: + [ + Action + { + id: _previewAction + icon.name: "image-preview" + text: qsTr("Previews") + checkable: true + checked: list.preview + onTriggered: list.preview = !list.preview + }, + + Action + { + id: _hiddenAction + icon.name: "visibility" + text: qsTr("Hidden files") + checkable: true + checked: list.hidden + onTriggered: list.hidden = !list.hidden + }, + + Action + { + id: _bookmarkAction + icon.name: "bookmark-new" + text: qsTr("Bookmark") + onTriggered: newBookmark([currentPath]) + }, + + Action + { + id: _newFolderAction + icon.name: "folder-add" + text: qsTr("New folder") + onTriggered: + { + dialogLoader.sourceComponent= newFolderDialogComponent + dialog.open() + } + }, + + Action + { + id: _newDocumentAction + icon.name: "document-new" + text: qsTr("New file") + onTriggered: + { + dialogLoader.sourceComponent= newFileDialogComponent + dialog.open() + } + }, + + Action + { + id: _pasteAction + text: qsTr("Paste ")+"["+browserMenu.pasteFiles+"]" + icon.name: "edit-paste" + enabled: browserMenu.pasteFiles > 0 + onTriggered: paste() + }] + + Loader + { + id: dialogLoader + } + + Component + { + id: removeDialogComponent + + Maui.Dialog + { + property var items: [] + + title: qsTr("Remove files?") + message: qsTr("You can move the file to the Trash or Delete it completely from your system. Which one you preffer?") + rejectButton.text: qsTr("Delete") + acceptButton.text: qsTr("Trash") + acceptButton.visible: !isMobile + + onRejected: + { + if(control.selectionBar && control.selectionBar.visible) + { + control.selectionBar.clear() + control.selectionBar.animate(Maui.Style.dangerColor) + } + + control.remove(items) + close() + } + + onAccepted: + { + if(control.selectionBar && control.selectionBar.visible) + { + control.selectionBar.clear() + control.selectionBar.animate(Maui.Style.dangerColor) } - - Item - { - Maui.FMList - { - id: _millersFMList - preview: modelList.preview - path: model.path - foldersFirst: modelList.foldersFirst - onWarning: - { - notify("dialog-information", "An error happened", message) - } - - onProgress: - { - if(percent === 100) - _progressBar.value = 0 - else - _progressBar.value = percent/100 - } - } - - Maui.ListBrowser - { - id: _millerListView - anchors.fill: parent - - showPreviewThumbnails: modelList.preview - keepEmblemOverlay: selectionMode - rightEmblem: isMobile ? "document-share" : "" - leftEmblem: "list-add" - showDetailsInfo: true - // itemSize: thumbnailsSize - onItemClicked: - { - control.currentFMList = _millersFMList - _millerColumns.itemClicked(index) - } - // onItemDoubleClicked: - // { - // modelList.path = _millersFMList.path - // _millerColumns.onItemDoubleClicked(index) - // } - - onItemRightClicked: - { + + control.trash(items) + close() + } + } + } + + Component + { + id: newFolderDialogComponent + + Maui.NewDialog + { + title: qsTr("New folder") + message: qsTr("Create a new folder with a custom name") + acceptButton.text: qsTr("Create") + onFinished: list.createDir(text) + rejectButton.visible: false + textEntry.placeholderText: qsTr("Folder name...") + } + } + + Component + { + id: newFileDialogComponent + + Maui.NewDialog + { + title: qsTr("New file") + message: qsTr("Create a new file with a custom name and extension") + acceptButton.text: qsTr("Create") + onFinished: Maui.FM.createFile(control.currentPath, text) + rejectButton.visible: false + textEntry.placeholderText: qsTr("File name...") + } + } + + Component + { + id: renameDialogComponent + Maui.NewDialog + { + title: qsTr("Rename file") + message: qsTr("Rename a file or folder to a new custom name") + textEntry.text: itemMenu.item.label + textEntry.placeholderText: qsTr("New name...") + onFinished: Maui.FM.rename(itemMenu.item.path, textEntry.text) + onRejected: close() + acceptText: qsTr("Rename") + rejectText: qsTr("Cancel") + } + } + + Component + { + id: shareDialogComponent + Maui.ShareDialog {} + } + + Component + { + id: tagsDialogComponent + Maui.TagsDialog + { + onTagsReady: composerList.updateToUrls(tags) + } + } + + BrowserMenu + { + id: browserMenu + z : control.z +1 + } + + Maui.FilePreviewer + { + id: previewer + parent: parent + onShareButtonClicked: control.shareFiles([url]) + } + + Maui.BaseModel + { + id: folderModel + list: modelList + } + + Maui.FMList + { + id: modelList + preview: true + path: currentPath + foldersFirst: true + onSortByChanged: if(group) groupBy() + onContentReadyChanged: console.log("CONTENT READY?", contentReady) + onWarning: + { + notify("dialog-information", "An error happened", message) + } + + onProgress: + { + if(percent === 100) + _progressBar.value = 0 + else + _progressBar.value = percent/100 + } + } + + FileMenu + { + id: itemMenu + width: unit *200 + onBookmarkClicked: control.newBookmark([item.path]) + onCopyClicked: + { + if(item) + control.copy([item]) + } + + onCutClicked: + { + if(item) + control.cut([item]) + } + + onTagsClicked: + { + if(item) + { + dialogLoader.sourceComponent = tagsDialogComponent + dialog.composerList.urls = item.path + dialog.open() + } + } + + onRenameClicked: + { + dialogLoader.sourceComponent = renameDialogComponent + dialog.open() + } + + onRemoveClicked: + { + dialogLoader.sourceComponent= removeDialogComponent + dialog.items = [item] + dialog.open() + } + + onShareClicked: control.shareFiles([item.path]) + } + + Component + { + id: listViewBrowser + + Maui.ListBrowser + { + showPreviewThumbnails: modelList.preview + keepEmblemOverlay: selectionMode + rightEmblem: isMobile ? "document-share" : "" + leftEmblem: "list-add" + showDetailsInfo: true + model: folderModel + section.delegate: Maui.LabelDelegate + { + id: delegate + label: section + labelTxt.font.pointSize: fontSizes.big + + isSection: true + boldLabel: true + height: toolBarHeightAlt + } + } + } + + Component + { + id: gridViewBrowser + + Maui.GridBrowser + { + itemSize : thumbnailsSize + fontSizes.default + keepEmblemOverlay: selectionMode + showPreviewThumbnails: modelList.preview + rightEmblem: isMobile ? "document-share" : "" + leftEmblem: "list-add" + model: folderModel + } + } + + Component + { + id: millerViewBrowser + + Kirigami.ColumnView + { + id: _millerColumns + columnWidth: Math.min(Kirigami.Units.gridUnit * 22, control.width) + columnResizeMode: Kirigami.ColumnView.DynamicColumns + + signal itemClicked(int index) + signal itemDoubleClicked(int index) + signal itemRightClicked(int index) + + signal rightEmblemClicked(int index) + signal leftEmblemClicked(int index) + + signal areaClicked(var mouse) + signal areaRightClicked() + + Maui.PathList + { + id: _millerList + path: control.currentPath + onPathChanged: _millerColumns.currentIndex = _repeater.count - 1 + } + + Maui.BaseModel + { + id: _millerModel + list: _millerList + } + + Repeater + { + id: _repeater + model: _millerModel + + + Item + { + Maui.FMList + { + id: _millersFMList + preview: modelList.preview + path: model.path + foldersFirst: modelList.foldersFirst + onWarning: + { + notify("dialog-information", "An error happened", message) + } + + onProgress: + { + if(percent === 100) + _progressBar.value = 0 + else + _progressBar.value = percent/100 + } + } + + Maui.ListBrowser + { + id: _millerListView + anchors.fill: parent + + showPreviewThumbnails: modelList.preview + keepEmblemOverlay: selectionMode + rightEmblem: isMobile ? "document-share" : "" + leftEmblem: "list-add" + showDetailsInfo: true + onItemClicked: + { + control.currentFMList = _millersFMList + _millerColumns.itemClicked(index) + } + + onItemDoubleClicked: + { + control.currentFMList = _millersFMList + _millerColumns.itemDoubleClicked(index) + } + + onItemRightClicked: + { control.currentFMList = _millersFMList _millerColumns.itemRightClicked(index) } - onRightEmblemClicked: - { + onRightEmblemClicked: + { control.currentFMList = _millersFMList - _millerColumns.rightEmblemClicked(index) + _millerColumns.rightEmblemClicked(index) } - onLeftEmblemClicked: - { + onLeftEmblemClicked: + { control.currentFMList = _millersFMList _millerColumns.leftEmblemClicked(index) } onAreaClicked: { - control.currentFMList = _millersFMList - _millerColumns.areaClicked(mouse) - } - - onAreaRightClicked: - { - control.currentFMList = _millersFMList - _millerColumns.areaRightClicked() - } - - model: Maui.BaseModel - { - list: _millersFMList - } - - section.delegate: Maui.LabelDelegate - { - id: delegate - label: section - labelTxt.font.pointSize: fontSizes.big - - isSection: true - boldLabel: true - height: toolBarHeightAlt - } - } - } - } - } - } - - Connections - { - target: browser - - onItemClicked: - { - browser.currentIndex = index - indexHistory.push(index) - control.itemClicked(index) - } - - onItemDoubleClicked: - { - browser.currentIndex = index - indexHistory.push(index) - control.itemDoubleClicked(index) - } - - onItemRightClicked: - { - if(currentFMList.pathType !== Maui.FMList.TRASH_PATH && - currentFMList.pathType !== Maui.FMList.REMOTE_PATH - ) - itemMenu.show(index) - control.itemRightClicked(index) - } - - onLeftEmblemClicked: - { - control.addToSelection(control.currentFMList.get(index), true) - control.itemLeftEmblemClicked(index) - } - - onRightEmblemClicked: - { - isAndroid ? Maui.Android.shareDialog([control.currentFMList.get(index).path]) : shareDialog.show([control.currentFMList.get(index).path]) - control.itemRightEmblemClicked(index) - } - - onAreaClicked: - { - if(!isMobile && mouse.button === Qt.RightButton) - browserMenu.show() - else return - - control.rightClicked() - } - - onAreaRightClicked: browserMenu.show() - } - - Maui.Holder - { - id: holder - anchors.fill : parent - z: -1 - visible: !control.currentFMList.pathExists || control.currentFMList.pathEmpty || !control.currentFMList.contentReady - emoji: if(control.currentFMList.pathExists && control.currentFMList.pathEmpty) - "qrc:/assets/MoonSki.png" - else if(!control.currentFMList.pathExists) - "qrc:/assets/ElectricPlug.png" - else if(!control.currentFMList.contentReady && currentPathType === Maui.FMList.SEARCH_PATH) - "qrc:/assets/animat-search-color.gif" - else if(!control.currentFMList.contentReady) - "qrc:/assets/animat-rocket-color.gif" - - isGif: !control.currentFMList.contentReady - isMask: false - title : if(control.currentFMList.pathExists && control.currentFMList.pathEmpty) - qsTr("Folder is empty!") - else if(!control.currentFMList.pathExists) - qsTr("Folder doesn't exists!") - else if(!control.currentFMList.contentReady && currentPathType === Maui.FMList.SEARCH_PATH) - qsTr("Searching for content!") - else if(!control.currentFMList.contentReady) - qsTr("Loading content!") - - - body: if(control.currentFMList.pathExists && control.currentFMList.pathEmpty) - qsTr("You can add new files to it") - else if(!control.currentFMList.pathExists) - qsTr("Create Folder?") - else if(!control.currentFMList.contentReady && currentPathType === Maui.FMList.SEARCH_PATH) - qsTr("This might take a while!") - else if(!control.currentFMList.contentReady) - qsTr("Almost ready!") - - - - emojiSize: iconSizes.huge - - onActionTriggered: - { - if(!control.currentFMList.pathExists) - { - Maui.FM.createDir(control.currentPath.slice(0, control.currentPath.lastIndexOf("/")), control.currentPath.split("/").pop()) - control.openFolder(control.currentFMList.parentPath) - } - } - } - - Keys.onSpacePressed: previewer.show(control.currentFMList.get(browser.currentIndex).path) - headBar.visible: currentPathType !== Maui.FMList.APPS_PATH - headBar.position: isMobile ? ToolBar.Footer : ToolBar.Header - property list t_actions: - [ - Action - { - id: _previewAction - icon.name: "image-preview" - text: qsTr("Previews") - checkable: true - checked: list.preview - onTriggered: list.preview = !list.preview - }, - - Action - { - id: _hiddenAction - icon.name: "visibility" - text: qsTr("Hidden files") - checkable: true - checked: list.hidden - onTriggered: list.hidden = !list.hidden - }, - - Action - { - id: _bookmarkAction - icon.name: "bookmark-new" - text: qsTr("Bookmark") - onTriggered: newBookmark([currentPath]) - }, - - Action - { - id: _newFolderAction - icon.name: "folder-add" - text: qsTr("New folder") - onTriggered: - { - dialogLoader.sourceComponent= newFolderDialogComponent - dialog.open() - } - }, - - Action - { - id: _newDocumentAction - icon.name: "document-new" - text: qsTr("New file") - onTriggered: - { - dialogLoader.sourceComponent= newFileDialogComponent - dialog.open() - } - }, - - Action - { - id: _pasteAction - text: qsTr("Paste ")+"["+browserMenu.pasteFiles+"]" - icon.name: "edit-paste" - enabled: browserMenu.pasteFiles > 0 - onTriggered: paste() - }] - - -// headBar.stickyRightContent: true - headBar.rightContent:[ - Kirigami.ActionToolBar - { + control.currentFMList = _millersFMList + _millerColumns.areaClicked(mouse) + } + + onAreaRightClicked: + { + control.currentFMList = _millersFMList + _millerColumns.areaRightClicked() + } + + model: Maui.BaseModel + { + list: _millersFMList + } + + section.delegate: Maui.LabelDelegate + { + id: delegate + label: section + labelTxt.font.pointSize: fontSizes.big + + isSection: true + boldLabel: true + height: toolBarHeightAlt + } + } + } + } + } + } + + Connections + { + target: browser + + onItemClicked: + { + browser.currentIndex = index + indexHistory.push(index) + control.itemClicked(index) + } + + onItemDoubleClicked: + { + browser.currentIndex = index + indexHistory.push(index) + control.itemDoubleClicked(index) + } + + onItemRightClicked: + { + if(currentFMList.pathType !== Maui.FMList.TRASH_PATH && + currentFMList.pathType !== Maui.FMList.REMOTE_PATH + ) + itemMenu.show(index) + control.itemRightClicked(index) + } + + onLeftEmblemClicked: + { + control.addToSelection(control.currentFMList.get(index), true) + control.itemLeftEmblemClicked(index) + } + + onRightEmblemClicked: + { + isAndroid ? Maui.Android.shareDialog([control.currentFMList.get(index).path]) : shareDialog.show([control.currentFMList.get(index).path]) + control.itemRightEmblemClicked(index) + } + + onAreaClicked: + { + if(!isMobile && mouse.button === Qt.RightButton) + browserMenu.show() + else return + + control.rightClicked() + } + + onAreaRightClicked: browserMenu.show() + } + + Maui.Holder + { + id: holder + anchors.fill : parent + z: -1 + visible: !control.currentFMList.pathExists || control.currentFMList.pathEmpty || !control.currentFMList.contentReady + emoji: if(control.currentFMList.pathExists && control.currentFMList.pathEmpty) + "qrc:/assets/MoonSki.png" + else if(!control.currentFMList.pathExists) + "qrc:/assets/ElectricPlug.png" + else if(!control.currentFMList.contentReady && currentPathType === Maui.FMList.SEARCH_PATH) + "qrc:/assets/animat-search-color.gif" + else if(!control.currentFMList.contentReady) + "qrc:/assets/animat-rocket-color.gif" + + isGif: !control.currentFMList.contentReady + isMask: false + title : if(control.currentFMList.pathExists && control.currentFMList.pathEmpty) + qsTr("Folder is empty!") + else if(!control.currentFMList.pathExists) + qsTr("Folder doesn't exists!") + else if(!control.currentFMList.contentReady && currentPathType === Maui.FMList.SEARCH_PATH) + qsTr("Searching for content!") + else if(!control.currentFMList.contentReady) + qsTr("Loading content!") + + + body: if(control.currentFMList.pathExists && control.currentFMList.pathEmpty) + qsTr("You can add new files to it") + else if(!control.currentFMList.pathExists) + qsTr("Create Folder?") + else if(!control.currentFMList.contentReady && currentPathType === Maui.FMList.SEARCH_PATH) + qsTr("This might take a while!") + else if(!control.currentFMList.contentReady) + qsTr("Almost ready!") + + + + emojiSize: iconSizes.huge + + onActionTriggered: + { + if(!control.currentFMList.pathExists) + { + Maui.FM.createDir(control.currentPath.slice(0, control.currentPath.lastIndexOf("/")), control.currentPath.split("/").pop()) + control.openFolder(control.currentFMList.parentPath) + } + } + } + + + + + // headBar.stickyRightContent: true + headBar.rightContent:[ + Kirigami.ActionToolBar + { position: ToolBar.Header Layout.fillWidth: true hiddenActions: t_actions - + display: isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly - - actions: [ - Action - { - icon.name: "view-list-icons" - onTriggered: list.viewType = Maui.FMList.ICON_VIEW - checkable: false - checked: list.viewType === Maui.FMList.ICON_VIEW - icon.width: iconSizes.medium - text: qsTr("Grid view") -// autoExclusive: true - }, - - Action - { - icon.name: "view-list-details" - onTriggered: list.viewType = Maui.FMList.LIST_VIEW - icon.width: iconSizes.medium - checked: list.viewType === Maui.FMList.LIST_VIEW - text: qsTr("List view") -// autoExclusive: true - }, - - Action - { - icon.name: "view-file-columns" - onTriggered: list.viewType = Maui.FMList.MILLERS_VIEW - icon.width: iconSizes.medium - checked: list.viewType === Maui.FMList.MILLERS_VIEW - text: qsTr("Column view") -// autoExclusive: true - }, - - Kirigami.Action - { - icon.name: "view-sort" - text: qsTr("Sort") - - Kirigami.Action - { - text: qsTr("Folders first") - checked: list.foldersFirst - onTriggered: list.foldersFirst = !list.foldersFirst - } - - Kirigami.Action - { - text: qsTr("Type") - checked: list.sortBy === Maui.FMList.MIME - onTriggered: list.sortBy = Maui.FMList.MIME - } - - Kirigami.Action - { - text: qsTr("Date") - checked: list.sortBy === Maui.FMList.DATE - onTriggered: list.sortBy = Maui.FMList.DATE - } - - Kirigami.Action - { - text: qsTr("Modified") - checked: list.sortBy === Maui.FMList.MODIFIED - onTriggered: list.sortBy = Maui.FMList.MODIFIED - } - - Kirigami.Action - { - text: qsTr("Size") - checked: list.sortBy === Maui.FMList.SIZE - onTriggered: list.sortBy = Maui.FMList.SIZE - } - - Kirigami.Action - { - text: qsTr("Name") - checked: list.sortBy === Maui.FMList.LABEL - onTriggered: list.sortBy = Maui.FMList.LABEL - } - - Kirigami.Action - { - id: groupAction - text: qsTr("Group") - checked: group - onTriggered: - { - group = !group - if(group) - groupBy() - else - browser.section.property = "" - } - } - }, - - Kirigami.Action - { - text: qsTr("Select") - icon.name: "item-select" - checkable: false - checked: selectionMode - onTriggered: selectionMode = !selectionMode - - } - ] - } - ] - - headBar.leftContent: [ - ToolButton - { - icon.name: "go-previous" - onClicked: control.goBack() - }, - - ToolButton - { - id: goUpButton - visible: true - icon.name: "go-up" - onClicked: control.goUp() - }, - - ToolButton - { - icon.name: "go-next" - onClicked: control.goNext() - } - ] - - footBar.visible: false - - - Component - { - id: selectionBarComponent - - Maui.SelectionBar - { - anchors.fill: parent - onIconClicked: _selectionBarmenu.popup() - onExitClicked: clearSelection() - - Menu - { - id: _selectionBarmenu - MenuItem - { - text: qsTr("Copy...") - onTriggered: - { - if(control.selectionBar) - control.selectionBar.animate("#6fff80") - control.copy(selectedItems) - console.log(selectedItems) - _selectionBarmenu.close() - } - } - - MenuItem - { - text: qsTr("Cut...") - onTriggered: - { - if(control.selectionBar) - control.selectionBar.animate("#fff44f") - control.cut(selectedItems) - - _selectionBarmenu.close() - } - } - - MenuItem - { - text: qsTr("Share") - onTriggered: - { - control.shareFiles(selectedPaths) - _selectionBarmenu.close() - } - } - - MenuSeparator{} - - MenuItem - { - text: qsTr("Remove...") - Kirigami.Theme.textColor: dangerColor - - onTriggered: - { - dialogLoader.sourceComponent= removeDialogComponent - dialog.items = selectedItems - dialog.open() - _selectionBarmenu.close() - } - } - } - } - } - - ColumnLayout - { - anchors.fill: parent - visible: !holder.visible - z: holder.z + 1 - spacing: 0 - - Loader - { - id: viewLoader - z: holder.z + 1 - sourceComponent: switch(list.viewType) - { - case Maui.FMList.ICON_VIEW: return gridViewBrowser - case Maui.FMList.LIST_VIEW: return listViewBrowser - case Maui.FMList.MILLERS_VIEW: return millerViewBrowser - } - - onLoaded: - { - if(sourceComponent !== millerViewBrowser) - control.currentFMList = modelList - - } - - Layout.topMargin: list.viewType == Maui.FMList.ICON_VIEW ? contentMargins * 2 : unit - Layout.margins: 0 - - Layout.fillWidth: true - Layout.fillHeight: true - } - - Loader - { - id: selectionBarLoader - Layout.fillWidth: true - Layout.preferredHeight: control.selectionBar && control.selectionBar.visible ? control.selectionBar.barHeight: 0 - Layout.leftMargin: contentMargins * (isMobile ? 3 : 2) - Layout.rightMargin: contentMargins * (isMobile ? 3 : 2) - Layout.bottomMargin: control.selectionBar && control.selectionBar.visible ? contentMargins*2 : 0 - z: holder.z +1 - } - - ProgressBar - { - id: _progressBar - Layout.fillWidth: true - Layout.alignment: Qt.AlignBottom - Layout.preferredHeight: visible ? iconSizes.medium : 0 - visible: value > 0 - } - } - -// PinchArea -// { -// anchors.fill: parent -// -// property real initialWidth -// property real initialHeight -// -// onPinchStarted: -// { -// console.log("pinch started") -// } -// -// onPinchUpdated: -// { -// console.log(pinch.scale) -// } -// -// onPinchFinished: -// { -// console.log("pinch finished") -// } -// } - - onThumbnailsSizeChanged: - { - if(trackChanges && saveDirProps) - Maui.FM.setDirConf(currentPath+"/.directory", "MAUIFM", "IconSize", thumbnailsSize) - else - Maui.FM.saveSettings("IconSize", thumbnailsSize, "SETTINGS") - - if(list.viewType == Maui.FMList.ICON_VIEW) - browser.adaptGrid() - } - - - function shareFiles(urls) - { - if(urls.length <= 0) - return; - - if(isAndroid) - Maui.Android.shareDialog(urls[0]) - else - { - dialogLoader.sourceComponent= shareDialogComponent - dialog.show(urls) - } - } - - function openItem(index) - { - var item = control.currentFMList.get(index) - var path = item.path - - switch(currentPathType) - { - case Maui.FMList.APPS_PATH: - if(item.path.endsWith("/")) - populate(path) - else - Maui.FM.runApplication(path) - break - case Maui.FMList.CLOUD_PATH: - if(item.mime === "inode/directory") - control.openFolder(path) - else - Maui.FM.openCloudItem(item) - break; - default: - if(selectionMode && !Maui.FM.isDir(item.path)) - addToSelection(item, true) - else - { - if(item.mime === "inode/directory") - control.openFolder(path) - else if(Maui.FM.isApp(path)) - control.launchApp(path) - else - { - if (isMobile) - previewer.show(path) - else - control.openFile(path) - } - } - } - } - - - function launchApp(path) - { - Maui.FM.runApplication(path, "") - } - - function openFile(path) - { - Maui.FM.openUrl(path) - } - - function openFolder(path) - { - populate(Maui.FM.fileDir(path))// make sure the path is a dir - } - - function setPath(path) - { - currentPath = path - } - - function populate(path) - { - if(!path.length) - return; - - browser.currentIndex = 0 - setPath(path) - - if(currentPathType === Maui.FMList.PLACES_PATH) - { - if(trackChanges && saveDirProps) - { - var conf = Maui.FM.dirConf(path+"/.directory") - var iconsize = conf["iconsize"] || iconSizes.large - thumbnailsSize = parseInt(iconsize) - }else - { - thumbnailsSize = parseInt(Maui.FM.loadSettings("IconSize", "SETTINGS", thumbnailsSize)) - } - } - - if(list.viewType == Maui.FMList.ICON_VIEW) - browser.adaptGrid() - } - - function goBack() - { - populate(modelList.previousPath) - browser.currentIndex = indexHistory.pop() - // browser.positionViewAtIndex(browser.currentIndex, ListView.Center) - } - - function goNext() - { - openFolder(modelList.posteriorPath) - } - - function goUp() - { - openFolder(modelList.parentPath) - } - - function refresh() - { - var pos = browser.contentY -// control.currentFMList.refresh() - - browser.contentY = pos - } - - function addToSelection(item, append) - { - selectionBarLoader.sourceComponent= selectionBarComponent - selectionBar.singleSelection = control.singleSelection - selectionBar.append(item) - } - - function clearSelection() - { - clean() - // selectionMode = false - } - - function clean() - { - copyItems = [] - cutItems = [] - browserMenu.pasteFiles = 0 - - if(control.selectionBar && control.selectionBar.visible) - selectionBar.clear() - } - - function copy(items) - { - copyItems = items - isCut = false - isCopy = true - } - - function cut(items) - { - cutItems = items - isCut = true - isCopy = false - } - - function paste() - { - if(isCopy) - currentFMList.copyInto(copyItems) - else if(isCut) - { - currentFMList.cutInto(cutItems) - clearSelection() - } - } - - function remove(items) - { - for(var i in items) - Maui.FM.removeFile(items[i].path) - } - - function trash(items) - { - for(var i in items) - Maui.FM.moveToTrash(items[i].path) - } - - function bookmarkFolder(paths) - { - newBookmark(paths) - } - - function zoomIn() - { - control.thumbnailsSize = control.thumbnailsSize + 8 - } - - function zoomOut() - { - var newSize = control.thumbnailsSize - 8 - - if(newSize >= iconSizes.small) - control.thumbnailsSize = newSize - } - - function groupBy() - { - var prop = "" - var criteria = ViewSection.FullString - - switch(modelList.sortBy) - { - case Maui.FMList.LABEL: - prop = "label" - criteria = ViewSection.FirstCharacter - break; - case Maui.FMList.MIME: - prop = "mime" - break; - case Maui.FMList.SIZE: - prop = "size" - break; - case Maui.FMList.DATE: - prop = "date" - break; - case Maui.FMList.MODIFIED: - prop = "modified" - break; - } - - list.viewType = Maui.FMList.LIST_VIEW - - if(!prop) - { - browser.section.property = "" - return - } - - browser.section.property = prop - browser.section.criteria = criteria - } + + actions: [ + Action + { + icon.name: "view-list-icons" + onTriggered: list.viewType = Maui.FMList.ICON_VIEW + checkable: false + checked: list.viewType === Maui.FMList.ICON_VIEW + icon.width: iconSizes.medium + text: qsTr("Grid view") + // autoExclusive: true + }, + + Action + { + icon.name: "view-list-details" + onTriggered: list.viewType = Maui.FMList.LIST_VIEW + icon.width: iconSizes.medium + checked: list.viewType === Maui.FMList.LIST_VIEW + text: qsTr("List view") + // autoExclusive: true + }, + + Action + { + icon.name: "view-file-columns" + onTriggered: list.viewType = Maui.FMList.MILLERS_VIEW + icon.width: iconSizes.medium + checked: list.viewType === Maui.FMList.MILLERS_VIEW + text: qsTr("Column view") + // autoExclusive: true + }, + + Kirigami.Action + { + icon.name: "view-sort" + text: qsTr("Sort") + + Kirigami.Action + { + text: qsTr("Folders first") + checked: list.foldersFirst + onTriggered: list.foldersFirst = !list.foldersFirst + } + + Kirigami.Action + { + text: qsTr("Type") + checked: list.sortBy === Maui.FMList.MIME + onTriggered: list.sortBy = Maui.FMList.MIME + } + + Kirigami.Action + { + text: qsTr("Date") + checked: list.sortBy === Maui.FMList.DATE + onTriggered: list.sortBy = Maui.FMList.DATE + } + + Kirigami.Action + { + text: qsTr("Modified") + checked: list.sortBy === Maui.FMList.MODIFIED + onTriggered: list.sortBy = Maui.FMList.MODIFIED + } + + Kirigami.Action + { + text: qsTr("Size") + checked: list.sortBy === Maui.FMList.SIZE + onTriggered: list.sortBy = Maui.FMList.SIZE + } + + Kirigami.Action + { + text: qsTr("Name") + checked: list.sortBy === Maui.FMList.LABEL + onTriggered: list.sortBy = Maui.FMList.LABEL + } + + Kirigami.Action + { + id: groupAction + text: qsTr("Group") + checked: group + onTriggered: + { + group = !group + if(group) + groupBy() + else + browser.section.property = "" + } + } + }, + + Kirigami.Action + { + text: qsTr("Select") + icon.name: "item-select" + checkable: false + checked: selectionMode + onTriggered: selectionMode = !selectionMode + + } + ] + } + ] + + headBar.leftContent: [ + ToolButton + { + icon.name: "go-previous" + onClicked: control.goBack() + }, + + ToolButton + { + id: goUpButton + visible: true + icon.name: "go-up" + onClicked: control.goUp() + }, + + ToolButton + { + icon.name: "go-next" + onClicked: control.goNext() + } + ] + + footBar.visible: false + + + Component + { + id: selectionBarComponent + + Maui.SelectionBar + { + anchors.fill: parent + onIconClicked: _selectionBarmenu.popup() + onExitClicked: clean() + + Menu + { + id: _selectionBarmenu + MenuItem + { + text: qsTr("Copy...") + onTriggered: + { + if(control.selectionBar) + control.selectionBar.animate("#6fff80") + control.copy(selectedItems) + console.log(selectedItems) + _selectionBarmenu.close() + } + } + + MenuItem + { + text: qsTr("Cut...") + onTriggered: + { + if(control.selectionBar) + control.selectionBar.animate("#fff44f") + control.cut(selectedItems) + + _selectionBarmenu.close() + } + } + + MenuItem + { + text: qsTr("Share") + onTriggered: + { + control.shareFiles(selectedPaths) + _selectionBarmenu.close() + } + } + + MenuSeparator{} + + MenuItem + { + text: qsTr("Remove...") + Kirigami.Theme.textColor: dangerColor + + onTriggered: + { + dialogLoader.sourceComponent= removeDialogComponent + dialog.items = selectedItems + dialog.open() + _selectionBarmenu.close() + } + } + } + } + } + + ColumnLayout + { + anchors.fill: parent + visible: !holder.visible + z: holder.z + 1 + spacing: 0 + + Loader + { + id: viewLoader + z: holder.z + 1 + sourceComponent: switch(list.viewType) + { + case Maui.FMList.ICON_VIEW: return gridViewBrowser + case Maui.FMList.LIST_VIEW: return listViewBrowser + case Maui.FMList.MILLERS_VIEW: return millerViewBrowser + } + + onLoaded: + { + if(sourceComponent !== millerViewBrowser) + control.currentFMList = modelList + + } + + Layout.topMargin: list.viewType == Maui.FMList.ICON_VIEW ? contentMargins * 2 : unit + Layout.margins: 0 + + Layout.fillWidth: true + Layout.fillHeight: true + } + + Loader + { + id: selectionBarLoader + Layout.fillWidth: true + Layout.preferredHeight: control.selectionBar && control.selectionBar.visible ? control.selectionBar.barHeight: 0 + Layout.leftMargin: contentMargins * (isMobile ? 3 : 2) + Layout.rightMargin: contentMargins * (isMobile ? 3 : 2) + Layout.bottomMargin: control.selectionBar && control.selectionBar.visible ? contentMargins*2 : 0 + z: holder.z +1 + } + + ProgressBar + { + id: _progressBar + Layout.fillWidth: true + Layout.alignment: Qt.AlignBottom + Layout.preferredHeight: visible ? iconSizes.medium : 0 + visible: value > 0 + } + } + + onThumbnailsSizeChanged: + { + if(trackChanges && saveDirProps) + Maui.FM.setDirConf(currentPath+"/.directory", "MAUIFM", "IconSize", thumbnailsSize) + else + Maui.FM.saveSettings("IconSize", thumbnailsSize, "SETTINGS") + + if(list.viewType == Maui.FMList.ICON_VIEW) + browser.adaptGrid() + } + + + function shareFiles(urls) + { + if(urls.length <= 0) + return; + + if(isAndroid) + Maui.Android.shareDialog(urls[0]) + else + { + dialogLoader.sourceComponent= shareDialogComponent + dialog.show(urls) + } + } + + function openItem(index) + { + var item = control.currentFMList.get(index) + var path = item.path + + switch(currentPathType) + { + case Maui.FMList.APPS_PATH: + if(item.path.endsWith("/")) + populate(path) + else + Maui.FM.runApplication(path) + break + case Maui.FMList.CLOUD_PATH: + if(item.mime === "inode/directory") + control.openFolder(path) + else + Maui.FM.openCloudItem(item) + break; + default: + if(selectionMode && !Maui.FM.isDir(item.path)) + addToSelection(item, true) + else + { + if(item.mime === "inode/directory") + control.openFolder(path) + else if(Maui.FM.isApp(path)) + control.launchApp(path) + else + { + if (isMobile) + previewer.show(path) + else + control.openFile(path) + } + } + } + } + + + function launchApp(path) + { + Maui.FM.runApplication(path, "") + } + + function openFile(path) + { + Maui.FM.openUrl(path) + } + + function openFolder(path) + { + populate(Maui.FM.fileDir(path))// make sure the path is a dir + } + + function setPath(path) + { + currentPath = path + } + + function populate(path) + { + if(!path.length) + return; + + browser.currentIndex = 0 + setPath(path) + + if(currentPathType === Maui.FMList.PLACES_PATH) + { + if(trackChanges && saveDirProps) + { + var conf = Maui.FM.dirConf(path+"/.directory") + var iconsize = conf["iconsize"] || iconSizes.large + thumbnailsSize = parseInt(iconsize) + }else + { + thumbnailsSize = parseInt(Maui.FM.loadSettings("IconSize", "SETTINGS", thumbnailsSize)) + } + } + + if(list.viewType == Maui.FMList.ICON_VIEW) + browser.adaptGrid() + } + + function goBack() + { + populate(modelList.previousPath) + browser.currentIndex = indexHistory.pop() + } + + function goNext() + { + openFolder(modelList.posteriorPath) + } + + function goUp() + { + openFolder(modelList.parentPath) + } + + function refresh() + { + var pos = browser.contentY + browser.contentY = pos + } + + function addToSelection(item, append) + { + selectionBarLoader.sourceComponent= selectionBarComponent + selectionBar.singleSelection = control.singleSelection + selectionBar.append(item) + } + + function clean() + { + copyItems = [] + cutItems = [] + browserMenu.pasteFiles = 0 + + if(control.selectionBar && control.selectionBar.visible) + selectionBar.clear() + } + + function copy(items) + { + copyItems = items + isCut = false + isCopy = true + } + + function cut(items) + { + cutItems = items + isCut = true + isCopy = false + } + + function paste() + { + if(isCopy) + currentFMList.copyInto(copyItems) + else if(isCut) + { + currentFMList.cutInto(cutItems) + clean() + } + } + + function remove(items) + { + for(var i in items) + Maui.FM.removeFile(items[i].path) + } + + function trash(items) + { + for(var i in items) + Maui.FM.moveToTrash(items[i].path) + } + + function bookmarkFolder(paths) + { + newBookmark(paths) + } + + function zoomIn() + { + control.thumbnailsSize = control.thumbnailsSize + 8 + } + + function zoomOut() + { + var newSize = control.thumbnailsSize - 8 + + if(newSize >= iconSizes.small) + control.thumbnailsSize = newSize + } + + function groupBy() + { + var prop = "" + var criteria = ViewSection.FullString + + switch(modelList.sortBy) + { + case Maui.FMList.LABEL: + prop = "label" + criteria = ViewSection.FirstCharacter + break; + case Maui.FMList.MIME: + prop = "mime" + break; + case Maui.FMList.SIZE: + prop = "size" + break; + case Maui.FMList.DATE: + prop = "date" + break; + case Maui.FMList.MODIFIED: + prop = "modified" + break; + } + + list.viewType = Maui.FMList.LIST_VIEW + + if(!prop) + { + browser.section.property = "" + return + } + + browser.section.property = prop + browser.section.criteria = criteria + } } diff --git a/src/controls/Page.qml b/src/controls/Page.qml index 80c9731..0d04ee6 100644 --- a/src/controls/Page.qml +++ b/src/controls/Page.qml @@ -1,112 +1,105 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import org.kde.mauikit 1.0 as Maui import org.kde.kirigami 2.7 as Kirigami import QtQuick.Layouts 1.3 import QtQuick.Window 2.3 Page { - id: control - -// property int margins: 0 -// contentItem.anchors.margins: margins -// contentItem.anchors.left: contentItem.parent.left -// contentItem.anchors.top: contentItem.parent.top -// contentItem.anchors.bottom: contentItem.parent.bottom -// contentItem.anchors.right: contentItem.parent.right - -leftPadding: control.padding -rightPadding: control.padding -topPadding: control.padding -bottomPadding: control.padding - - property alias headBar : _headBar - property alias footBar: _footBar - property QtObject mheadBar : Maui.ToolBar - { - id: _headBar - visible: count > 1 - width: control.width - position: ToolBar.Header -// Kirigami.Theme.backgroundColor: control.Kirigami.Theme.backgroundColor - - Component - { - id: _titleComponent - Label - { - text: control.title - elide : Text.ElideRight - font.bold : false - font.weight: Font.Bold - color : Kirigami.Theme.textColor - font.pointSize: fontSizes.big - horizontalAlignment : Text.AlignHCenter - verticalAlignment : Text.AlignVCenter - - } - } - - middleContent: Loader - { + id: control + + leftPadding: control.padding + rightPadding: control.padding + topPadding: control.padding + bottomPadding: control.padding + + signal goBackTriggered(); + signal goForwardTriggered(); + + property alias headBar : _headBar + property alias footBar: _footBar + property QtObject mheadBar : Maui.ToolBar + { + id: _headBar + visible: count > 1 + width: control.width + position: ToolBar.Header + + Component + { + id: _titleComponent + Label + { + text: control.title + elide : Text.ElideRight + font.bold : false + font.weight: Font.Bold + color : Kirigami.Theme.textColor + font.pointSize: fontSizes.big + horizontalAlignment : Text.AlignHCenter + verticalAlignment : Text.AlignVCenter + + } + } + + middleContent: Loader + { Layout.fillWidth: sourceComponent === _titleComponent Layout.fillHeight: sourceComponent === _titleComponent - sourceComponent: control.title ? _titleComponent : undefined - } - } - - property QtObject mfootBar : Maui.ToolBar - { - id: _footBar - visible: count - position: ToolBar.Footer - width: control.width -// Kirigami.Theme.backgroundColor: control.Kirigami.Theme.backgroundColor - } - - header: headBar.count && headBar.position === ToolBar.Header ? headBar : undefined - - footer: Column - { - id: _footer - children: - { - if(headBar.position === ToolBar.Footer && footBar.count) - return [footBar , headBar] - else if(headBar.position === ToolBar.Footer) - return [headBar] - else if(footBar.count) - return [footBar] - else - return [] - } - } - - - Keys.onBackPressed: - { - goBackTriggered(); - console.log("GO BACK CLICKED") - event.accepted = true - } - - Shortcut - { - sequence: "Forward" - onActivated: goFowardTriggered(); - } - - Shortcut - { - sequence: StandardKey.Forward - onActivated: goFowardTriggered(); - } - - Shortcut - { - sequence: StandardKey.Back - onActivated: goBackTriggered(); - } + sourceComponent: control.title ? _titleComponent : undefined + } + } + + property QtObject mfootBar : Maui.ToolBar + { + id: _footBar + visible: count + position: ToolBar.Footer + width: control.width + } + + header: headBar.count && headBar.position === ToolBar.Header ? headBar : undefined + + footer: Column + { + id: _footer + children: + { + if(headBar.position === ToolBar.Footer && footBar.count) + return [footBar , headBar] + else if(headBar.position === ToolBar.Footer) + return [headBar] + else if(footBar.count) + return [footBar] + else + return [] + } + } + + + Keys.onBackPressed: + { + control.goBackTriggered(); + event.accepted = true + } + + Shortcut + { + sequence: "Forward" + onActivated: control.goForwardTriggered(); + } + + Shortcut + { + sequence: StandardKey.Forward + onActivated: control.goForwardTriggered(); + } + + Shortcut + { + sequence: StandardKey.Back + onActivated: control.goBackTriggered(); + } } diff --git a/src/controls/Popup.qml b/src/controls/Popup.qml index cb54724..7d4c087 100644 --- a/src/controls/Popup.qml +++ b/src/controls/Popup.qml @@ -1,106 +1,97 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.9 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.2 import QtQuick.Controls.Material 2.1 import org.kde.kirigami 2.7 as Kirigami import QtGraphicalEffects 1.0 import "private" Popup { id: control -// property alias backgroudItem: popupBackground.data + // property alias backgroudItem: popupBackground.data property int maxWidth : parent.width property int maxHeight : parent.height property double hint : 0.9 property double heightHint : hint property double widthHint : hint - + property int verticalAlignment : Qt.AlignVCenter parent: ApplicationWindow.overlay - - width: Math.max(Math.min(parent.width * widthHint, maxWidth), Math.min(maxWidth, parent.width * widthHint)) - height: Math.max(Math.min(parent.height * heightHint, maxHeight), Math.min(maxHeight, parent.height * heightHint)) - - - x: parent.width / 2 - width / 2 - y: if(verticalAlignment === Qt.AlignVCenter) - parent.height / 2 - height / 2 - else if(verticalAlignment === Qt.AlignTop) - (height + space.huge) - else if(verticalAlignment === Qt.AlignBottom) - (parent.height) - (height + space.huge) -else - parent.height / 2 - height / 2 - - -// z: parent.z+1 - - modal: control.width !== control.parent.width && control.height !== control.parent.height - focus: true - clip: true - margins: unit - padding: unit + width: Math.max(Math.min(parent.width * widthHint, maxWidth), Math.min(maxWidth, parent.width * widthHint)) + height: Math.max(Math.min(parent.height * heightHint, maxHeight), Math.min(maxHeight, parent.height * heightHint)) -// topPadding: popupBackground.radius -// bottomPadding: popupBackground.radius -topPadding: control.padding -bottomPadding: control.padding - leftPadding: control.padding - rightPadding: control.padding - rightMargin: control.margins - leftMargin: control.margins - topMargin: control.margins - bottomMargin: control.margins - -// background: Rectangle -// { -// id: popupBackground -// radius: control.width === control.parent.width && control.height === control.parent.height ? 0 : radiusV -// color: Kirigami.Theme.backgroundColor -// border.color: control.width === control.parent.width && control.height === control.parent.height ? "transparent" : Kirigami.Theme.borderColor -// -// } - - enter: Transition - { - // grow_fade_in - NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } - NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } - } - - exit: Transition - { - // shrink_fade_out - NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } - NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } - } - - Material.accent: Kirigami.Theme.highlightColor - Material.background: Kirigami.Theme.backgroundColor - Material.primary: Kirigami.Theme.backgroundColor - Material.foreground: Kirigami.Theme.textColor + x: parent.width / 2 - width / 2 + y: if(verticalAlignment === Qt.AlignVCenter) + parent.height / 2 - height / 2 + else if(verticalAlignment === Qt.AlignTop) + (height + space.huge) + else if(verticalAlignment === Qt.AlignBottom) + (parent.height) - (height + space.huge) + else + parent.height / 2 - height / 2 + + + // z: parent.z+1 + + modal: control.width !== control.parent.width && control.height !== control.parent.height + focus: true + clip: true + + margins: unit + padding: unit + + // topPadding: popupBackground.radius + // bottomPadding: popupBackground.radius + topPadding: control.padding + bottomPadding: control.padding + leftPadding: control.padding + rightPadding: control.padding + + rightMargin: control.margins + leftMargin: control.margins + topMargin: control.margins + bottomMargin: control.margins + + enter: Transition + { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition + { + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + +// Material.accent: Kirigami.Theme.highlightColor +// Material.background: Kirigami.Theme.backgroundColor +// Material.primary: Kirigami.Theme.backgroundColor +// Material.foreground: Kirigami.Theme.textColor } diff --git a/src/controls/SelectionBar.qml b/src/controls/SelectionBar.qml index d37be63..9f2a00a 100644 --- a/src/controls/SelectionBar.qml +++ b/src/controls/SelectionBar.qml @@ -1,372 +1,377 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui import "private" Item { id: control Kirigami.Theme.inherit: false Kirigami.Theme.colorSet: Kirigami.Theme.Complementary property var selectedPaths: [] property var selectedItems: [] property alias selectionList : selectionList property alias anim : anim property alias model : selectionList.model property alias count : selectionList.count property int barHeight : itemHeight + space.large property color animColor : "black" property int itemHeight: iconSizes.big + space.big property int itemWidth: iconSizes.big + (isMobile? space.big : space.large) + space.big property int position: Qt.Horizontal property string iconName : "overflow-menu" property bool iconVisible: true /** * if singleSelection is set to true then only a single item is selected * at time, and replaced with a newe item appended **/ property bool singleSelection: false signal iconClicked() signal modelCleared() signal exitClicked() height: if(position === Qt.Horizontal) barHeight else if(position === Qt.Vertical) parent.height else undefined width: if(position === Qt.Horizontal) parent.width else if(position === Qt.Vertical) barHeight else undefined visible: selectionList.count > 0 Drag.keys: control.selectedPaths Drag.active: _mouseArea.drag.active Drag.dragType: Drag.Automatic Drag.supportedActions: Qt.CopyAction MouseArea { id: _mouseArea anchors.fill: parent drag.target: parent onPressed: selectionList.grabToImage(function(result) { console.log("PRESSED SELECTIONBOX", control.selectedPaths.join(",")) parent.Drag.imageSource = result.url }) } Rectangle { id: bg anchors.fill: parent // Kirigami.Theme.colorSet: Kirigami.Theme.Complementary color: Kirigami.Theme.backgroundColor radius: radiusV opacity: 1 border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) - SequentialAnimation - { - id: anim - PropertyAnimation - { - target: bg - property: "color" - easing.type: Easing.InOutQuad - from: animColor - to: Qt.lighter(Kirigami.Theme.backgroundColor, 1.2) - duration: 500 - } - } + } + GridLayout { anchors.fill: parent rows: if(position === Qt.Horizontal) 1 else if(position === Qt.Vertical) 4 else undefined columns: if(position === Qt.Horizontal) 4 else if(position === Qt.Vertical) 1 else undefined + Maui.Badge { anchors.verticalCenter: parent.top anchors.horizontalCenter: parent.left Layout.column: if(position === Qt.Horizontal) 1 else if(position === Qt.Vertical) 1 else undefined Layout.row: if(position === Qt.Horizontal) 1 else if(position === Qt.Vertical) 1 else undefined iconName: "window-close" Kirigami.Theme.backgroundColor: dangerColor Kirigami.Theme.textColor: Kirigami.Theme.highlightedTextColor onClicked: { selectionList.model.clear() exitClicked() } } Item { Layout.fillHeight: true Layout.fillWidth: true Layout.column: if(position === Qt.Horizontal) 2 else if(position === Qt.Vertical) 1 else undefined Layout.row: if(position === Qt.Horizontal) 1 else if(position === Qt.Vertical) 2 else undefined Layout.alignment: if(position === Qt.Horizontal) Qt.AlignVCenter else if(position === Qt.Vertical) Qt.AlignHCenter else undefined ListView { id: selectionList anchors.fill: parent + SequentialAnimation + { + id: anim + PropertyAnimation + { + target: selectionList + property: "y" + easing.type: Easing.InOutQuad + from: (-200) + to: 0 + duration: 100 + } + } + boundsBehavior: !isMobile? Flickable.StopAtBounds : Flickable.OvershootBounds orientation: if(position === Qt.Horizontal) ListView.Horizontal else if(position === Qt.Vertical) ListView.Vertical else undefined clip: true spacing: space.small focus: true interactive: true model: ListModel{} delegate: Maui.IconDelegate { id: delegate anchors.verticalCenter: position === Qt.Horizontal ? parent.verticalCenter : undefined anchors.horizontalCenter: position === Qt.Vertical ? parent.horizontalCenter : undefined height: itemHeight width: itemWidth folderSize: iconSizes.big showLabel: true emblemAdded: true keepEmblemOverlay: true + showEmblem: true showSelectionBackground: false labelColor: Kirigami.Theme.textColor showTooltip: true showThumbnails: true emblemSize: iconSizes.small leftEmblem: "list-remove" Kirigami.Theme.highlightColor: Kirigami.Theme.highlightColor Kirigami.Theme.backgroundColor: Kirigami.Theme.complementaryBackgroundColor Kirigami.Theme.textColor: Kirigami.Theme.textColor Connections { target: delegate onLeftEmblemClicked: removeSelection(index) } } } } Item { Layout.alignment: if(position === Qt.Horizontal) Qt.AlignRight || Qt.AlignVCenter else if(position === Qt.Vertical) Qt.AlignCenter else undefined Layout.fillWidth: position === Qt.Vertical Layout.fillHeight: position === Qt.Horizontal Layout.maximumWidth: iconSizes.medium Layout.column: if(position === Qt.Horizontal) 3 else if(position === Qt.Vertical) 1 else undefined Layout.row: if(position === Qt.Horizontal) 1 else if(position === Qt.Vertical) 3 else undefined Layout.margins: space.big ToolButton { visible: iconVisible anchors.centerIn: parent icon.name: control.iconName icon.color: control.Kirigami.Theme.textColor onClicked: iconClicked() } } Maui.Badge { Kirigami.Theme.backgroundColor: Kirigami.Theme.highlightColor text: selectionList.count anchors.verticalCenter: parent.top anchors.horizontalCenter: parent.right Layout.column: if(position === Qt.Horizontal) 4 else if(position === Qt.Vertical) 1 else undefined Layout.row: if(position === Qt.Horizontal) 1 else if(position === Qt.Vertical) 4 else undefined onClicked: { clear() modelCleared() } } } onVisibleChanged: { if(position === Qt.Vertical) return if(typeof(riseContent) === "undefined") return if(control.visible) riseContent() else dropContent() } function clear() { selectedPaths = [] selectedItems = [] selectionList.model.clear() } function removeSelection(index) { var path = selectionList.model.get(index).path if(selectedPaths.indexOf(path) > -1) { selectedPaths.splice(index, 1) selectedItems.splice(index, 1) selectionList.model.remove(index) } } function append(item) { if(selectedPaths.indexOf(item.path) < 0) { if(control.singleSelection) clear() selectedItems.push(item) selectedPaths.push(item.path) // for(var i = 0; i < selectionList.count ; i++ ) // if(selectionList.model.get(i).path === item.path) // { // selectionList.model.remove(i) // return // } selectionList.model.append(item) selectionList.positionViewAtEnd() } } function animate(color) { animColor = color anim.running = true } function getSelectedPathsString() { var paths = ""+selectedPaths.join(",") return paths } } diff --git a/src/controls/TextField.qml b/src/controls/TextField.qml index 404ab1b..e366c58 100644 --- a/src/controls/TextField.qml +++ b/src/controls/TextField.qml @@ -1,150 +1,150 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.9 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.2 import QtQuick.Controls.Material 2.1 import org.kde.kirigami 2.2 as Kirigami import QtQuick.Controls.impl 2.3 import QtQuick.Controls.Material.impl 2.3 import org.kde.mauikit 1.0 as Maui import "private" TextField { id: control property alias menu : entryMenu signal cleared() signal goBackTriggered(); signal goFowardTriggered(); // height: implicitHeight // width: implicitWidth z: 1 // topPadding: space.tiny bottomPadding: space.tiny rightPadding: clearButton.width + space.small selectByMouse: !isMobile persistentSelection: true focus: true wrapMode: TextInput.WordWrap - onPressAndHold: entryMenu.popup() + onPressAndHold: !isMobile ? entryMenu.popup() : undefined onPressed: { if(!isMobile && event.button === Qt.RightButton) entryMenu.popup() } Keys.onBackPressed: { goBackTriggered(); event.accepted = true } Shortcut { sequence: "Forward" onActivated: goFowardTriggered(); } Shortcut { sequence: StandardKey.Forward onActivated: goFowardTriggered(); } Shortcut { sequence: StandardKey.Back onActivated: goBackTriggered(); } ToolButton { id: clearButton visible: control.text.length anchors.top: control.top anchors.right: control.right anchors.rightMargin: space.small anchors.verticalCenter: parent.verticalCenter icon.name: "edit-clear" icon.color: control.color onClicked: { control.clear() cleared() } } Menu { id: entryMenu z: control.z +1 MenuItem { text: qsTr("Copy") onTriggered: control.copy() enabled: control.selectedText.length } MenuItem { text: qsTr("Cut") onTriggered: control.cut() enabled: control.selectedText.length } MenuItem { text: qsTr("Paste") onTriggered: { var text = control.paste() control.insert(control.cursorPosition, text) } } MenuItem { text: qsTr("Select all") onTriggered: control.selectAll() enabled: control.text.length } MenuItem { text: qsTr("Undo") onTriggered: control.undo() enabled: control.canUndo } MenuItem { text: qsTr("Redo") onTriggered: control.redo() enabled: control.canRedo } } } diff --git a/src/controls/ToolBar.qml b/src/controls/ToolBar.qml index 8495c81..09f08a7 100644 --- a/src/controls/ToolBar.qml +++ b/src/controls/ToolBar.qml @@ -1,267 +1,267 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.6 import QtQuick.Controls 2.2 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import "private" ToolBar { id: control // implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) - implicitHeight: visible ? (floating ? toolBarHeightAlt : toolBarHeight) : 0 + implicitHeight: visible ? toolBarHeight : 0 // width: parent.width height: implicitHeight property alias stickyRightContent : rightRowContent.sticky property alias stickyLeftContent : leftRowContent.sticky property alias stickyMiddleContent : middleRowContent.sticky property alias leftContent : leftRowContent.data property alias middleContent : middleRowContent.data property alias rightContent : rightRowContent.data property alias middleLayout : middleRowContent property alias leftLayout : leftRowContent property alias rightLayout : rightRowContent property alias layout : layout property int margins: space.medium spacing: space.medium property int count : leftContent.length + middleContent.length + rightContent.length property bool dropShadow: false property bool drawBorder: false property bool floating: false property bool plegable: false //deprecrated property bool folded : false //deprecrated property bool flickable: true property bool strech : true property bool leftSretch: strech property bool rightSretch: strech property bool middleStrech: strech padding: 0 // leftPadding: Kirigami.Units.smallSpacing*2 // rightPadding: Kirigami.Units.smallSpacing*2 signal unfolded() // onPlegableChanged: folded = plegable // onVisibleChanged: // { // if(control.visible) // control.height= implicitHeight // else // control.height= 0 // // } // background: Rectangle // { // id: headBarBG // color: colorScheme.backgroundColor // implicitHeight: toolBarHeightAlt // radius: floating ? radiusV : 0 // border.color: floating ? colorScheme.borderColor : "transparent" // // SequentialAnimation on radius // { // ColorAnimation { to: colorScheme.backgroundColor ; duration: 1000 } // } // // Kirigami.Separator // { // visible: drawBorder // color: colorScheme.borderColor // height: unit // anchors // { // left: parent.left // right: parent.right // bottom: control.position == ToolBar.Footer ? undefined : parent.bottom // top: control.position == ToolBar.Footer ? parent.top : undefined // } // } // // layer.enabled: dropShadow // layer.effect: DropShadow // { // anchors.fill: headBarBG // horizontalOffset: 0 // verticalOffset: unit * (altToolBars ? -1 : 1) // radius: 8 // samples: 25 // color: Qt.darker(colorScheme.backgroundColor, 1.4) // source: headBarBG // } // } MouseArea { id: _rightFlickRec width: iconSizes.medium height: parent.height visible: /*!mainFlickable.atXEnd && */!mainFlickable.fits && control.flickable hoverEnabled: true anchors { top: parent.top bottom: parent.bottom right: parent.right } z: 999 Kirigami.Icon { anchors.centerIn: parent source: "arrow-right-double" width: iconSizes.small height: iconSizes.small color: _rightFlickRec.hovered ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor } enabled: !mainFlickable.atXEnd opacity: enabled ? 1 : 0.4 onClicked: { mainFlickable.flick(100, 0) if(!mainFlickable.atXEnd) mainFlickable.contentX += control.height if(mainFlickable.atXEnd) mainFlickable.returnToBounds() } } MouseArea { id: _leftFlickRec width: iconSizes.medium height: parent.height visible: /*!mainFlickable.atXBeginning &&*/ !mainFlickable.fits && control.flickable hoverEnabled: true anchors { top: parent.top bottom: parent.bottom left: parent.left } z: 999 Kirigami.Icon { anchors.centerIn: parent source: "arrow-left-double" width: iconSizes.small height: iconSizes.small color: _leftFlickRec.hovered ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor } enabled: !mainFlickable.atXBeginning opacity: enabled ? 1 : 0.4 onClicked: { if(!mainFlickable.atXBeginning) mainFlickable.contentX -= control.height if(mainFlickable.atXBeginning) mainFlickable.returnToBounds() } } Flickable { id: mainFlickable property bool fits : contentWidth < control.width onFitsChanged: returnToBounds() anchors.fill: parent anchors.leftMargin: !fits && _leftFlickRec.visible && control.flickable ? _leftFlickRec.width : margins anchors.rightMargin: !fits && _rightFlickRec.visible && control.flickable ? _rightFlickRec.width : margins flickableDirection: Flickable.HorizontalFlick interactive: !fits && Kirigami.Settings.isMobile contentWidth: ((control.margins) + space.medium) + (control.stickyLeftContent ? leftRowContent.implicitWidth : leftRowContent.width) + (control.stickyMiddleContent ? middleRowContent.implicitWidth : middleRowContent.width) + (control.stickyRightContent ? rightRowContent.implicitWidth : rightRowContent.width) boundsBehavior: isMobile ? Flickable.DragOverBounds : Flickable.StopAtBounds clip: true RowLayout { id: layout width: control.width - control.margins - space.medium height: control.height RowLayout { id: leftRowContent // visible: control.leftSretch && implicitWidth property bool sticky : false Layout.leftMargin: rightRowContent.implicitWidth && implicitWidth === 0 && middleRowContent.implicitWidth && control.leftSretch ? rightRowContent.implicitWidth : undefined Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft spacing: leftContent.length > 0 ? control.spacing : 0 Layout.minimumWidth: !sticky ? undefined : implicitWidth Layout.fillWidth: control.leftSretch && implicitWidth Layout.fillHeight: true } RowLayout { id: middleRowContent property bool sticky : false // visible: control.middleStrech && implicitWidth Layout.alignment: Qt.AlignCenter spacing: middleContent.length === 1 ? 0 : control.spacing Layout.minimumWidth: !sticky ? undefined : implicitWidth // Layout.maximumWidth: control.width - leftRowContent.implicitWidth - rightRowContent.implicitWidth Layout.fillWidth: control.middleStrech Layout.fillHeight: true } RowLayout { id: rightRowContent // visible: control.rightSretch && implicitWidth property bool sticky : false Layout.rightMargin: leftRowContent.implicitWidth && implicitWidth === 0 && middleRowContent.implicitWidth && control.rightSretch ? leftRowContent.implicitWidth : undefined Layout.alignment: Qt.AlignVCenter | Qt.AlignRight spacing: rightContent.length > 0 ? control.spacing : 0 Layout.minimumWidth: !sticky ? undefined : implicitWidth // Layout.maximumWidth: !sticky ? rightRowContent.width : implicitWidth Layout.fillWidth: control.rightSretch && implicitWidth Layout.fillHeight: true } } // ScrollBar.horizontal: ScrollBar { visible: false} } } diff --git a/src/controls/private/BrowserMenu.qml b/src/controls/private/BrowserMenu.qml index c467a67..4e61959 100644 --- a/src/controls/private/BrowserMenu.qml +++ b/src/controls/private/BrowserMenu.qml @@ -1,68 +1,68 @@ - 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.6 as Kirigami +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.6 as Kirigami + +Menu +{ + property int pasteFiles : 0 - Menu - { - property int pasteFiles : 0 - - // popup.z : 999 - - /* Maui.MenuItem - * { - * che - * ckable: true - * checked: saveDirProps - * text: qsTr("Per dir props") - * onTriggered: saveDirProps = !saveDirProps - }*/ -// property list actions: t_actions - - MenuItem - { - action: _previewAction - } - - MenuItem - { - action: _hiddenAction - } - - MenuItem - { - action: _bookmarkAction - } - - MenuItem - { - action: _newFolderAction - } - - MenuItem - { - action: _newDocumentAction - } - - - MenuItem - { - action: _pasteAction - } - - - function show() + // popup.z : 999 + + /* Maui.MenuItem + * { + * che + * ckable: true + * checked: saveDirProps + * text: qsTr("Per dir props") + * onTriggered: saveDirProps = !saveDirProps +}*/ + // property list actions: t_actions + + MenuItem + { + action: _previewAction + } + + MenuItem + { + action: _hiddenAction + } + + MenuItem + { + action: _bookmarkAction + } + + MenuItem + { + action: _newFolderAction + } + + MenuItem + { + action: _newDocumentAction + } + + + MenuItem + { + action: _pasteAction + } + + + function show() + { + if(currentPathType === Maui.FMList.PLACES_PATH || currentPathType === Maui.FMList.TAGS_PATH || currentPathType === Maui.FMList.CLOUD_PATH) { - if(currentPathType === Maui.FMList.PLACES_PATH || currentPathType === Maui.FMList.TAGS_PATH || currentPathType === Maui.FMList.CLOUD_PATH) - { - if(isCopy) - pasteFiles = copyItems.length - else if(isCut) - pasteFiles = cutItems.length - - popup() - } + if(isCopy) + pasteFiles = copyItems.length + else if(isCut) + pasteFiles = cutItems.length + + popup() } } - +} + diff --git a/src/controls/private/FileMenu.qml b/src/controls/private/FileMenu.qml index 56fd331..753f773 100644 --- a/src/controls/private/FileMenu.qml +++ b/src/controls/private/FileMenu.qml @@ -1,151 +1,151 @@ 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 Menu { id: control implicitWidth: colorBar.implicitWidth + space.big - property var item : {} + property var item : ({}) property int index : -1 property bool isDir : false signal bookmarkClicked(var item) signal removeClicked(var item) signal shareClicked(var item) signal copyClicked(var item) signal cutClicked(var item) signal renameClicked(var item) signal tagsClicked(var item) MenuItem { text: qsTr("Select") onTriggered: { addToSelection(currentFMList.get(index)) } } MenuSeparator{} MenuItem { text: qsTr("Copy...") onTriggered: { copyClicked(control.item) close() } } MenuItem { text: qsTr("Cut...") onTriggered: { cutClicked(control.item) close() } } MenuItem { text: qsTr("Rename...") onTriggered: { renameClicked(control.item) close() } } MenuSeparator{} MenuItem { text: qsTr("Bookmark") enabled: isDir onTriggered: { bookmarkClicked(control.item) close() } } MenuItem { text: qsTr("Tags...") onTriggered: { tagsClicked(control.item) close() } } MenuItem { text: qsTr("Share...") onTriggered: { shareClicked(control.item) close() } } MenuItem { text: qsTr("Preview...") onTriggered: { previewer.show(control.item.path) close() } } MenuSeparator{} MenuItem { text: qsTr("Remove...") Kirigami.Theme.textColor: dangerColor onTriggered: { removeClicked(control.item) close() } } MenuSeparator{ visible: colorBar.visible } MenuItem { width: parent.width height: visible ? iconSize + space.big : 0 visible: isDir Maui.ColorsBar { id: colorBar visible: parent.visible anchors.centerIn: parent size: iconSize onColorPicked: currentFMList.setDirIcon(index, color) } } function show(index) { control.item = currentFMList.get(index) if(item) { control.index = index isDir = Maui.FM.isDir(item.path) popup() } } } diff --git a/src/fm/fmh.h b/src/fm/fmh.h index 604ce21..7b6ad6d 100644 --- a/src/fm/fmh.h +++ b/src/fm/fmh.h @@ -1,1005 +1,1005 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FMH_H #define FMH_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(Q_OS_ANDROID) #include "mauiandroid.h" #elif defined(Q_OS_LINUX) #include #include #include #include #endif namespace FMH { inline bool isAndroid() { #if defined(Q_OS_ANDROID) return true; #elif defined(Q_OS_LINUX) return false; #elif defined(Q_OS_WIN32) return false; #elif defined(Q_OS_WIN64) return false; #elif defined(Q_OS_MACOS) return false; #elif defined(Q_OS_IOS) return false; #elif defined(Q_OS_HAIKU) return false; #endif } enum FILTER_TYPE : int { AUDIO, VIDEO, TEXT, IMAGE, DOCUMENT, NONE }; static const QHash FILTER_LIST = { {FILTER_TYPE::AUDIO, QStringList {"*.mp3", "*.mp4", "*.wav", "*.ogg", "*.flac"}}, {FILTER_TYPE::VIDEO, QStringList {"*.mp4", "*.mkv", "*.mov", "*.avi", "*.flv"}}, - {FILTER_TYPE::TEXT, QStringList {"*.txt", "*.cpp", "*.js", "*.doc", "*.h", "*.json", "*.html", "*.rtf"}}, + {FILTER_TYPE::TEXT, QStringList {"*.txt", "*.cpp", "*.js", "*.doc", "*.h", "*.json", "*.html", "*.rtf", "*.qml", "*.py", "*.go"}}, {FILTER_TYPE::DOCUMENT, QStringList {"*.pdf", "*.txt", "*.cbz", "*.cbr", "*.epub", "*.cbt", "*.cba", "*.cb7"}}, {FILTER_TYPE::IMAGE, QStringList {"*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.bmp"}}, {FILTER_TYPE::NONE, QStringList()} }; enum MODEL_KEY : int { ICON, LABEL, PATH, URL, TYPE, GROUP, OWNER, SUFFIX, NAME, DATE, SIZE, MODIFIED, MIME, TAG, PERMISSIONS, THUMBNAIL, THUMBNAIL_1, THUMBNAIL_2, THUMBNAIL_3, HIDDEN, ICONSIZE, DETAILVIEW, SHOWTHUMBNAIL, SHOWTERMINAL, COUNT, SORTBY, USER, PASSWORD, SERVER, FOLDERSFIRST, VIEWTYPE, ADDDATE, FAV, FAVORITE, COLOR, RATE, FORMAT, PLACE, LOCATION, ALBUM, ARTIST, TRACK, DURATION, ARTWORK, PLAYLIST, LYRICS, WIKI, MOOD, SOURCETYPE, GENRE, NOTE, COMMENT, CONTEXT, SOURCE, TITLE, ID, RELEASEDATE, LICENSE, DESCRIPTION, BOOKMARK, ACCOUNT, ACCOUNTTYPE, VERSION, DOMAIN, CATEGORY, CONTENT, PIN, IMG, PREVIEW, LINK, STAMP, BOOK, /** ccdav keys **/ N, PHOTO, GENDER, ADR, ADR_2, ADR_3, EMAIL, EMAIL_2, EMAIL_3, LANG, NICKNAME, ORG, PROFILE, TZ, TEL, TEL_2, TEL_3, IM, /** other keys **/ CITY, STATE, COUNTRY }; static const QHash MODEL_NAME = { {MODEL_KEY::ICON, "icon"}, {MODEL_KEY::LABEL, "label"}, {MODEL_KEY::PATH, "path"}, {MODEL_KEY::URL, "url"}, {MODEL_KEY::TYPE, "type"}, {MODEL_KEY::GROUP, "group"}, {MODEL_KEY::OWNER, "owner"}, {MODEL_KEY::SUFFIX, "suffix"}, {MODEL_KEY::NAME, "name"}, {MODEL_KEY::DATE, "date"}, {MODEL_KEY::MODIFIED, "modified"}, {MODEL_KEY::MIME, "mime"}, {MODEL_KEY::SIZE, "size"}, {MODEL_KEY::TAG, "tag"}, {MODEL_KEY::PERMISSIONS, "permissions"}, {MODEL_KEY::THUMBNAIL, "thumbnail"}, {MODEL_KEY::THUMBNAIL_1, "thumbnail_1"}, {MODEL_KEY::THUMBNAIL_2, "thumbnail_2"}, {MODEL_KEY::THUMBNAIL_3, "thumbnail_3"}, {MODEL_KEY::ICONSIZE, "iconsize"}, {MODEL_KEY::HIDDEN, "hidden"}, {MODEL_KEY::DETAILVIEW, "detailview"}, {MODEL_KEY::SHOWTERMINAL, "showterminal"}, {MODEL_KEY::SHOWTHUMBNAIL, "showthumbnail"}, {MODEL_KEY::COUNT, "count"}, {MODEL_KEY::SORTBY, "sortby"}, {MODEL_KEY::USER, "user"}, {MODEL_KEY::PASSWORD, "password"}, {MODEL_KEY::SERVER, "server"}, {MODEL_KEY::FOLDERSFIRST, "foldersfirst"}, {MODEL_KEY::VIEWTYPE, "viewtype"}, {MODEL_KEY::ADDDATE, "adddate"}, {MODEL_KEY::FAV, "fav"}, {MODEL_KEY::FAVORITE, "favorite"}, {MODEL_KEY::COLOR, "color"}, {MODEL_KEY::RATE, "rate"}, {MODEL_KEY::FORMAT, "format"}, {MODEL_KEY::PLACE, "place"}, {MODEL_KEY::LOCATION, "location"}, {MODEL_KEY::ALBUM, "album"}, {MODEL_KEY::DURATION, "duration"}, {MODEL_KEY::RELEASEDATE, "releasedate"}, {MODEL_KEY::ARTIST, "artist"}, {MODEL_KEY::LYRICS, "lyrics"}, {MODEL_KEY::TRACK, "track"}, {MODEL_KEY::GENRE, "genre"}, {MODEL_KEY::WIKI, "wiki"}, {MODEL_KEY::CONTEXT, "context"}, {MODEL_KEY::SOURCETYPE, "sourcetype"}, {MODEL_KEY::ARTWORK, "artwork"}, {MODEL_KEY::NOTE, "note"}, {MODEL_KEY::MOOD, "mood"}, {MODEL_KEY::COMMENT, "comment"}, {MODEL_KEY::PLAYLIST, "playlist"}, {MODEL_KEY::SOURCE, "source"}, {MODEL_KEY::TITLE, "title"}, {MODEL_KEY::ID, "id"}, {MODEL_KEY::LICENSE, "license"}, {MODEL_KEY::DESCRIPTION, "description"}, {MODEL_KEY::BOOKMARK, "bookmark"}, {MODEL_KEY::ACCOUNT, "account"}, {MODEL_KEY::ACCOUNTTYPE, "accounttype"}, {MODEL_KEY::VERSION, "version"}, {MODEL_KEY::DOMAIN, "domain"}, {MODEL_KEY::CATEGORY, "category"}, {MODEL_KEY::CONTENT, "content"}, {MODEL_KEY::PIN, "pin"}, {MODEL_KEY::IMG, "img"}, {MODEL_KEY::PREVIEW, "preview"}, {MODEL_KEY::LINK, "link"}, {MODEL_KEY::STAMP, "stamp"}, {MODEL_KEY::BOOK, "book"}, /** ccdav keys **/ {MODEL_KEY::N, "n"}, {MODEL_KEY::IM, "im"}, {MODEL_KEY::PHOTO, "photo"}, {MODEL_KEY::GENDER, "gender"}, {MODEL_KEY::ADR, "adr"}, {MODEL_KEY::ADR_2, "adr2"}, {MODEL_KEY::ADR_3, "adr3"}, {MODEL_KEY::EMAIL, "email"}, {MODEL_KEY::EMAIL_2, "email2"}, {MODEL_KEY::EMAIL_3, "email3"}, {MODEL_KEY::LANG, "lang"}, {MODEL_KEY::NICKNAME, "nickname"}, {MODEL_KEY::ORG, "org"}, {MODEL_KEY::PROFILE, "profile"}, {MODEL_KEY::TZ, "tz"}, {MODEL_KEY::TEL, "tel"}, {MODEL_KEY::TEL_2, "tel2"}, {MODEL_KEY::TEL_3, "tel3"}, {MODEL_KEY::CITY, "city"}, {MODEL_KEY::STATE, "state"}, {MODEL_KEY::COUNTRY, "country"} }; static const QHash MODEL_NAME_KEY = { {MODEL_NAME[MODEL_KEY::ICON], MODEL_KEY::ICON}, {MODEL_NAME[MODEL_KEY::LABEL], MODEL_KEY::LABEL}, {MODEL_NAME[MODEL_KEY::PATH], MODEL_KEY::PATH}, {MODEL_NAME[MODEL_KEY::URL], MODEL_KEY::URL}, {MODEL_NAME[MODEL_KEY::TYPE], MODEL_KEY::TYPE}, {MODEL_NAME[MODEL_KEY::GROUP], MODEL_KEY::GROUP}, {MODEL_NAME[MODEL_KEY::OWNER], MODEL_KEY::OWNER}, {MODEL_NAME[MODEL_KEY::SUFFIX], MODEL_KEY::SUFFIX}, {MODEL_NAME[MODEL_KEY::NAME], MODEL_KEY::NAME}, {MODEL_NAME[MODEL_KEY::DATE], MODEL_KEY::DATE}, {MODEL_NAME[MODEL_KEY::MODIFIED], MODEL_KEY::MODIFIED}, {MODEL_NAME[MODEL_KEY::MIME], MODEL_KEY::MIME}, {MODEL_NAME[MODEL_KEY::SIZE], MODEL_KEY::SIZE,}, {MODEL_NAME[MODEL_KEY::TAG], MODEL_KEY::TAG}, {MODEL_NAME[MODEL_KEY::PERMISSIONS], MODEL_KEY::PERMISSIONS}, {MODEL_NAME[MODEL_KEY::THUMBNAIL], MODEL_KEY::THUMBNAIL}, {MODEL_NAME[MODEL_KEY::THUMBNAIL_1], MODEL_KEY::THUMBNAIL_1}, {MODEL_NAME[MODEL_KEY::THUMBNAIL_2], MODEL_KEY::THUMBNAIL_2}, {MODEL_NAME[MODEL_KEY::THUMBNAIL_3], MODEL_KEY::THUMBNAIL_3}, {MODEL_NAME[MODEL_KEY::ICONSIZE], MODEL_KEY::ICONSIZE}, {MODEL_NAME[MODEL_KEY::HIDDEN], MODEL_KEY::HIDDEN}, {MODEL_NAME[MODEL_KEY::DETAILVIEW], MODEL_KEY::DETAILVIEW}, {MODEL_NAME[MODEL_KEY::SHOWTERMINAL], MODEL_KEY::SHOWTERMINAL}, {MODEL_NAME[MODEL_KEY::SHOWTHUMBNAIL], MODEL_KEY::SHOWTHUMBNAIL}, {MODEL_NAME[MODEL_KEY::COUNT], MODEL_KEY::COUNT}, {MODEL_NAME[MODEL_KEY::SORTBY], MODEL_KEY::SORTBY}, {MODEL_NAME[MODEL_KEY::USER], MODEL_KEY::USER}, {MODEL_NAME[MODEL_KEY::PASSWORD], MODEL_KEY::PASSWORD}, {MODEL_NAME[MODEL_KEY::SERVER], MODEL_KEY::SERVER}, {MODEL_NAME[MODEL_KEY::VIEWTYPE], MODEL_KEY::VIEWTYPE}, {MODEL_NAME[MODEL_KEY::ADDDATE], MODEL_KEY::ADDDATE}, {MODEL_NAME[MODEL_KEY::FAV], MODEL_KEY::FAV}, {MODEL_NAME[MODEL_KEY::FAVORITE], MODEL_KEY::FAVORITE}, {MODEL_NAME[MODEL_KEY::COLOR], MODEL_KEY::COLOR}, {MODEL_NAME[MODEL_KEY::RATE], MODEL_KEY::RATE}, {MODEL_NAME[MODEL_KEY::FORMAT], MODEL_KEY::FORMAT}, {MODEL_NAME[MODEL_KEY::PLACE], MODEL_KEY::PLACE}, {MODEL_NAME[MODEL_KEY::LOCATION], MODEL_KEY::LOCATION}, {MODEL_NAME[MODEL_KEY::ALBUM], MODEL_KEY::ALBUM}, {MODEL_NAME[MODEL_KEY::ARTIST], MODEL_KEY::ARTIST}, {MODEL_NAME[MODEL_KEY::DURATION], MODEL_KEY::DURATION}, {MODEL_NAME[MODEL_KEY::TRACK], MODEL_KEY::TRACK}, {MODEL_NAME[MODEL_KEY::GENRE], MODEL_KEY::GENRE}, {MODEL_NAME[MODEL_KEY::LYRICS], MODEL_KEY::LYRICS}, {MODEL_NAME[MODEL_KEY::RELEASEDATE], MODEL_KEY::RELEASEDATE}, {MODEL_NAME[MODEL_KEY::FORMAT], MODEL_KEY::FORMAT}, {MODEL_NAME[MODEL_KEY::WIKI], MODEL_KEY::WIKI}, {MODEL_NAME[MODEL_KEY::SOURCETYPE], MODEL_KEY::SOURCETYPE}, {MODEL_NAME[MODEL_KEY::ARTWORK], MODEL_KEY::ARTWORK}, {MODEL_NAME[MODEL_KEY::NOTE], MODEL_KEY::NOTE}, {MODEL_NAME[MODEL_KEY::MOOD], MODEL_KEY::MOOD}, {MODEL_NAME[MODEL_KEY::COMMENT], MODEL_KEY::COMMENT}, {MODEL_NAME[MODEL_KEY::CONTEXT], MODEL_KEY::CONTEXT}, {MODEL_NAME[MODEL_KEY::SOURCE], MODEL_KEY::SOURCE}, {MODEL_NAME[MODEL_KEY::TITLE], MODEL_KEY::TITLE}, {MODEL_NAME[MODEL_KEY::ID], MODEL_KEY::ID}, {MODEL_NAME[MODEL_KEY::LICENSE], MODEL_KEY::LICENSE}, {MODEL_NAME[MODEL_KEY::DESCRIPTION], MODEL_KEY::DESCRIPTION}, {MODEL_NAME[MODEL_KEY::BOOKMARK], MODEL_KEY::BOOKMARK}, {MODEL_NAME[MODEL_KEY::ACCOUNT], MODEL_KEY::ACCOUNT}, {MODEL_NAME[MODEL_KEY::ACCOUNTTYPE], MODEL_KEY::ACCOUNTTYPE}, {MODEL_NAME[MODEL_KEY::VERSION], MODEL_KEY::VERSION}, {MODEL_NAME[MODEL_KEY::DOMAIN], MODEL_KEY::DOMAIN}, {MODEL_NAME[MODEL_KEY::CATEGORY], MODEL_KEY::CATEGORY}, {MODEL_NAME[MODEL_KEY::CONTENT], MODEL_KEY::CONTENT}, {MODEL_NAME[MODEL_KEY::PIN], MODEL_KEY::PIN}, {MODEL_NAME[MODEL_KEY::IMG], MODEL_KEY::IMG}, {MODEL_NAME[MODEL_KEY::PREVIEW], MODEL_KEY::PREVIEW}, {MODEL_NAME[MODEL_KEY::LINK], MODEL_KEY::LINK}, {MODEL_NAME[MODEL_KEY::STAMP], MODEL_KEY::STAMP}, {MODEL_NAME[MODEL_KEY::BOOK], MODEL_KEY::BOOK}, /** ccdav keys **/ {MODEL_NAME[MODEL_KEY::N], MODEL_KEY::N}, {MODEL_NAME[MODEL_KEY::IM], MODEL_KEY::IM}, {MODEL_NAME[MODEL_KEY::PHOTO], MODEL_KEY::PHOTO}, {MODEL_NAME[MODEL_KEY::GENDER], MODEL_KEY::GENDER}, {MODEL_NAME[MODEL_KEY::ADR], MODEL_KEY::ADR}, {MODEL_NAME[MODEL_KEY::ADR_2], MODEL_KEY::ADR_2}, {MODEL_NAME[MODEL_KEY::ADR_3], MODEL_KEY::ADR_3}, {MODEL_NAME[MODEL_KEY::EMAIL], MODEL_KEY::EMAIL}, {MODEL_NAME[MODEL_KEY::EMAIL_2], MODEL_KEY::EMAIL_2}, {MODEL_NAME[MODEL_KEY::EMAIL_3], MODEL_KEY::EMAIL_3}, {MODEL_NAME[MODEL_KEY::LANG], MODEL_KEY::LANG}, {MODEL_NAME[MODEL_KEY::NICKNAME], MODEL_KEY::NICKNAME}, {MODEL_NAME[MODEL_KEY::ORG], MODEL_KEY::ORG}, {MODEL_NAME[MODEL_KEY::PROFILE], MODEL_KEY::PROFILE}, {MODEL_NAME[MODEL_KEY::TZ], MODEL_KEY::TZ}, {MODEL_NAME[MODEL_KEY::TEL], MODEL_KEY::TEL}, {MODEL_NAME[MODEL_KEY::TEL_2], MODEL_KEY::TEL_2}, {MODEL_NAME[MODEL_KEY::TEL_3], MODEL_KEY::TEL_3}, {MODEL_NAME[MODEL_KEY::CITY], MODEL_KEY::CITY}, {MODEL_NAME[MODEL_KEY::STATE], MODEL_KEY::STATE}, {MODEL_NAME[MODEL_KEY::COUNTRY], MODEL_KEY::COUNTRY} }; typedef QHash MODEL; typedef QVector MODEL_LIST; static const inline QVariantMap toMap(const FMH::MODEL& model) { QVariantMap map; for(const auto &key : model.keys()) map.insert(FMH::MODEL_NAME[key], model[key]); return map; } static const inline FMH::MODEL toModel(const QVariantMap& map) { FMH::MODEL model; for(const auto &key : map.keys()) model.insert(FMH::MODEL_NAME_KEY[key], map[key].toString()); return model; } static const inline FMH::MODEL filterModel(const FMH::MODEL &model, const QVector &keys) { FMH::MODEL res; for(const auto &key : keys) if(model.contains(key)) res[key] = model[key]; return res; } struct PATH_CONTENT { QString path; FMH::MODEL_LIST content; }; #ifdef Q_OS_ANDROID enum PATHTYPE_KEY : int { PLACES_PATH, REMOTE_PATH, DRIVES_PATH, REMOVABLE_PATH, TAGS_PATH, UNKNOWN_TYPE, APPS_PATH, TRASH_PATH, SEARCH_PATH, CLOUD_PATH, FISH_PATH, MTP_PATH }; #else enum PATHTYPE_KEY : int { PLACES_PATH = KFilePlacesModel::GroupType::PlacesType, REMOTE_PATH = KFilePlacesModel::GroupType::RemoteType, DRIVES_PATH = KFilePlacesModel::GroupType::DevicesType, REMOVABLE_PATH = KFilePlacesModel::GroupType::RemovableDevicesType, TAGS_PATH = KFilePlacesModel::GroupType::TagsType, UNKNOWN_TYPE = KFilePlacesModel::GroupType::UnknownType, APPS_PATH = 9, TRASH_PATH = 10, SEARCH_PATH = 11, CLOUD_PATH = 12, FISH_PATH = 13, MTP_PATH = 14, }; #endif static const QHash PATHTYPE_SCHEME = { {PATHTYPE_KEY::PLACES_PATH, "file"}, {PATHTYPE_KEY::DRIVES_PATH, "drives"}, {PATHTYPE_KEY::APPS_PATH, "apps"}, {PATHTYPE_KEY::REMOTE_PATH, "remote"}, {PATHTYPE_KEY::REMOVABLE_PATH, "removable"}, {PATHTYPE_KEY::UNKNOWN_TYPE, "Unkown"}, {PATHTYPE_KEY::TRASH_PATH, "trash"}, {PATHTYPE_KEY::TAGS_PATH, "tags"}, {PATHTYPE_KEY::SEARCH_PATH, "search"}, {PATHTYPE_KEY::CLOUD_PATH, "cloud"}, {PATHTYPE_KEY::FISH_PATH, "fish"}, {PATHTYPE_KEY::MTP_PATH, "mtp"} }; static const QHash PATHTYPE_URI = { {PATHTYPE_KEY::PLACES_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::PLACES_PATH] + "://"}, {PATHTYPE_KEY::DRIVES_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::DRIVES_PATH] + "://"}, {PATHTYPE_KEY::APPS_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::APPS_PATH] + "://"}, {PATHTYPE_KEY::REMOTE_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::REMOTE_PATH] + "://"}, {PATHTYPE_KEY::REMOVABLE_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::REMOVABLE_PATH] + "://"}, {PATHTYPE_KEY::UNKNOWN_TYPE, PATHTYPE_SCHEME[PATHTYPE_KEY::UNKNOWN_TYPE] + "://"}, {PATHTYPE_KEY::TRASH_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::TRASH_PATH] + "://"}, {PATHTYPE_KEY::TAGS_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::TAGS_PATH] + "://"}, {PATHTYPE_KEY::SEARCH_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::SEARCH_PATH] + "://"}, {PATHTYPE_KEY::CLOUD_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::CLOUD_PATH] + "://"}, {PATHTYPE_KEY::FISH_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::FISH_PATH] + "://"}, {PATHTYPE_KEY::MTP_PATH, PATHTYPE_SCHEME[PATHTYPE_KEY::MTP_PATH] + "://"} }; static const QHash PATHTYPE_LABEL = { {PATHTYPE_KEY::PLACES_PATH, ("Places")}, {PATHTYPE_KEY::DRIVES_PATH, ("Drives")}, {PATHTYPE_KEY::APPS_PATH, ("Apps")}, {PATHTYPE_KEY::REMOTE_PATH, ("Remote")}, {PATHTYPE_KEY::REMOVABLE_PATH, ("Removable")}, {PATHTYPE_KEY::UNKNOWN_TYPE, ("Unknown")}, {PATHTYPE_KEY::TRASH_PATH, ("Trash")}, {PATHTYPE_KEY::TAGS_PATH, ("Tags")}, {PATHTYPE_KEY::SEARCH_PATH, ("Search")}, {PATHTYPE_KEY::CLOUD_PATH, ("Cloud")}, {PATHTYPE_KEY::FISH_PATH, ("Remote")}, {PATHTYPE_KEY::MTP_PATH, ("Drives")} }; const QString DataPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); const QString CloudCachePath = FMH::DataPath+"/Cloud/"; #if defined(Q_OS_ANDROID) const QString PicturesPath = QUrl::fromLocalFile(PATHS::PicturesPath).toString(); const QString DownloadsPath = QUrl::fromLocalFile(PATHS::DownloadsPath).toString(); const QString DocumentsPath = QUrl::fromLocalFile(PATHS::DocumentsPath).toString(); const QString HomePath = QUrl::fromLocalFile(PATHS::HomePath).toString(); const QString MusicPath = QUrl::fromLocalFile(PATHS::MusicPath).toString(); const QString VideosPath = QUrl::fromLocalFile(PATHS::VideosPath).toString(); const QStringList defaultPaths = { FMH::HomePath, FMH::DocumentsPath, FMH::PicturesPath, FMH::MusicPath, FMH::VideosPath, FMH::DownloadsPath }; const QMap folderIcon { {PicturesPath, "folder-pictures"}, {DownloadsPath, "folder-download"}, {DocumentsPath, "folder-documents"}, {HomePath, "user-home"}, {MusicPath, "folder-music"}, {VideosPath, "folder-videos"}, }; #else const QString PicturesPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)).toString(); const QString DownloadsPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)).toString(); const QString DocumentsPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString(); const QString HomePath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).toString(); const QString MusicPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::MusicLocation)).toString(); const QString VideosPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)).toString(); const QString DesktopPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).toString(); const QString AppsPath = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)).toString(); const QString RootPath = "file:///"; const QStringList defaultPaths = { FMH::HomePath, FMH::DesktopPath, FMH::DocumentsPath, FMH::PicturesPath, FMH::MusicPath, FMH::VideosPath, FMH::DownloadsPath, FMH::RootPath }; const QMap folderIcon { {PicturesPath, "folder-pictures"}, {DownloadsPath, "folder-download"}, {DocumentsPath, "folder-documents"}, {HomePath, "user-home"}, {MusicPath, "folder-music"}, {VideosPath, "folder-videos"}, {DesktopPath, "user-desktop"}, {AppsPath, "system-run"}, {RootPath, "folder-root"} }; #endif /** * Checks if a local file exists. * The URL must represent a local file path, by using the scheme file:// **/ inline bool fileExists(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return false; } return QFileInfo::exists(path.toLocalFile()); } /** * Return the configuration of a single directory represented * by a QVariantMap. * The passed path must be a local file URL. **/ inline QVariantMap dirConf(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return QVariantMap(); } if(!FMH::fileExists(path)) return QVariantMap(); QString icon, iconsize, hidden, detailview, showthumbnail, showterminal; uint count = 0, sortby = FMH::MODEL_KEY::MODIFIED, viewType = 0; bool foldersFirst = false; #ifdef Q_OS_ANDROID QSettings file(path.toLocalFile(), QSettings::Format::NativeFormat); file.beginGroup(QString("Desktop Entry")); icon = file.value("Icon").toString(); file.endGroup(); file.beginGroup(QString("Settings")); hidden = file.value("HiddenFilesShown").toString(); file.endGroup(); file.beginGroup(QString("MAUIFM")); iconsize = file.value("IconSize").toString(); detailview = file.value("DetailView").toString(); showthumbnail = file.value("ShowThumbnail").toString(); showterminal = file.value("ShowTerminal").toString(); count = file.value("Count").toInt(); sortby = file.value("SortBy").toInt(); foldersFirst = file.value("FoldersFirst").toBool(); viewType = file.value("ViewType").toInt(); file.endGroup(); #else KConfig file(path.toLocalFile()); icon = file.entryMap(QString("Desktop Entry"))["Icon"]; hidden = file.entryMap(QString("Settings"))["HiddenFilesShown"]; iconsize = file.entryMap(QString("MAUIFM"))["IconSize"]; detailview = file.entryMap(QString("MAUIFM"))["DetailView"]; showthumbnail = file.entryMap(QString("MAUIFM"))["ShowThumbnail"]; showterminal = file.entryMap(QString("MAUIFM"))["ShowTerminal"]; count = file.entryMap(QString("MAUIFM"))["Count"].toInt(); sortby = file.entryMap(QString("MAUIFM"))["SortBy"].toInt(); foldersFirst = file.entryMap(QString("MAUIFM"))["FoldersFirst"] == "true" ? true : false; viewType = file.entryMap(QString("MAUIFM"))["ViewType"].toInt(); #endif return QVariantMap({ {FMH::MODEL_NAME[FMH::MODEL_KEY::ICON], icon.isEmpty() ? "folder" : icon}, {FMH::MODEL_NAME[FMH::MODEL_KEY::ICONSIZE], iconsize}, {FMH::MODEL_NAME[FMH::MODEL_KEY::COUNT], count}, {FMH::MODEL_NAME[FMH::MODEL_KEY::SHOWTERMINAL], showterminal.isEmpty() ? "false" : showterminal}, {FMH::MODEL_NAME[FMH::MODEL_KEY::SHOWTHUMBNAIL], showthumbnail.isEmpty() ? "false" : showthumbnail}, {FMH::MODEL_NAME[FMH::MODEL_KEY::DETAILVIEW], detailview.isEmpty() ? "false" : detailview}, {FMH::MODEL_NAME[FMH::MODEL_KEY::HIDDEN], hidden.isEmpty() ? false : (hidden == "true" ? true : false)}, {FMH::MODEL_NAME[FMH::MODEL_KEY::SORTBY], sortby}, {FMH::MODEL_NAME[FMH::MODEL_KEY::FOLDERSFIRST], foldersFirst}, {FMH::MODEL_NAME[FMH::MODEL_KEY::VIEWTYPE], viewType} }); } inline void setDirConf(const QUrl &path, const QString &group, const QString &key, const QVariant &value) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return; } #ifdef Q_OS_ANDROID QSettings file(path.toLocalFile(), QSettings::Format::IniFormat); file.beginGroup(group); file.setValue(key, value); file.endGroup(); file.sync(); #else KConfig file(path.toLocalFile(), KConfig::SimpleConfig); auto kgroup = file.group(group); kgroup.writeEntry(key, value); // file.reparseConfiguration(); file.sync(); #endif } /** * Returns the icon name for certain file. * The file path must be represented as a local file URL. * It also looks into the directory config file to get custom set icons **/ inline QString getIconName(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file. FMH::getIconName" << path; } if(path.isLocalFile() && QFileInfo(path.toLocalFile()).isDir()) { if(folderIcon.contains(path.toString())) return folderIcon[path.toString()]; else { auto icon = FMH::dirConf(QString(path.toString()+"/%1").arg(".directory"))[FMH::MODEL_NAME[FMH::MODEL_KEY::ICON]].toString(); return icon.isEmpty() ? "folder" : icon; } }else { #if defined(Q_OS_ANDROID) QMimeDatabase mime; auto type = mime.mimeTypeForFile(path.toString()); return type.iconName(); #else KFileItem mime(path); return mime.iconName(); #endif } } inline QString getMime(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return QString(); } const QMimeDatabase mimedb; return mimedb.mimeTypeForFile(path.toLocalFile()).name(); } enum class TABLE : uint { BOOKMARKS, CLOUDS }; static const QMap TABLEMAP = { {TABLE::BOOKMARKS, "bookmarks"}, {TABLE::CLOUDS, "clouds"} }; typedef QMap DB; const QString FMPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/maui/fm/"; const QString DBName = "fm.db"; inline FMH::MODEL getDirInfoModel(const QUrl &path, const QString &type = QString()) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return FMH::MODEL(); } const QDir dir (path.toLocalFile()); if(!dir.exists()) return FMH::MODEL(); return FMH::MODEL { {FMH::MODEL_KEY::ICON, FMH::getIconName(path)}, {FMH::MODEL_KEY::LABEL, dir.dirName()}, {FMH::MODEL_KEY::PATH, path.toString()}, {FMH::MODEL_KEY::TYPE, type} }; } inline QVariantMap getDirInfo(const QUrl &path, const QString &type = QString()) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return QVariantMap(); } const QFileInfo file(path.toLocalFile()); if(!file.exists()) return QVariantMap(); const auto data = FMH::getDirInfoModel(path); QVariantMap res; for(const auto &key : data.keys()) res.insert(FMH::MODEL_NAME[key], data[key]); return res; } inline FMH::MODEL getFileInfoModel(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return FMH::MODEL(); } const QFileInfo file(path.toLocalFile()); if(!file.exists()) return FMH::MODEL(); qDebug()<< "trying to get path info model. exists"; const auto mime = FMH::getMime(path); return FMH::MODEL { {FMH::MODEL_KEY::GROUP, file.group()}, {FMH::MODEL_KEY::OWNER, file.owner()}, {FMH::MODEL_KEY::SUFFIX, file.completeSuffix()}, {FMH::MODEL_KEY::LABEL, /*file.isDir() ? file.baseName() :*/ path == FMH::HomePath ? QStringLiteral("Home") : file.fileName()}, {FMH::MODEL_KEY::NAME, file.fileName()}, {FMH::MODEL_KEY::DATE, file.birthTime().toString(Qt::TextDate)}, {FMH::MODEL_KEY::MODIFIED, file.lastModified().toString(Qt::TextDate)}, {FMH::MODEL_KEY::MIME, mime }, {FMH::MODEL_KEY::ICON, FMH::getIconName(path)}, {FMH::MODEL_KEY::SIZE, QString::number(file.size()) /*locale.formattedDataSize(file.size())*/}, {FMH::MODEL_KEY::PATH, path.toString()}, {FMH::MODEL_KEY::THUMBNAIL, path.toString()}, {FMH::MODEL_KEY::COUNT, file.isDir() ? QString::number(QDir(path.toLocalFile()).count() - 2) : "0"} }; } inline QVariantMap getFileInfo(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file" << path; return QVariantMap(); } const QFileInfo file(path.toLocalFile()); if(!file.exists()) return QVariantMap(); const auto data = FMH::getFileInfoModel(path); qDebug()<< "getting item info model" << data; QVariantMap res; for(const auto &key : data.keys()) res.insert(FMH::MODEL_NAME[key], data[key]); return res; } #ifndef STATIC_MAUIKIT #include "mauikit_export.h" #endif #ifdef STATIC_MAUIKIT class Downloader : public QObject #else class MAUIKIT_EXPORT Downloader : public QObject #endif { Q_OBJECT public: explicit Downloader(QObject *parent = 0) : QObject(parent), manager(new QNetworkAccessManager) {} virtual ~Downloader() { qDebug()<< "DELETEING DOWNLOADER"; this->manager->deleteLater(); // this->reply->deleteLater(); } void setFile(const QString &fileURL, const QString &fileName = QString()) { QString filePath = fileURL; if(fileName.isEmpty() || fileURL.isEmpty()) return; QNetworkRequest request; request.setUrl(QUrl(fileURL)); reply = manager->get(request); file = new QFile; file->setFileName(fileName); file->open(QIODevice::WriteOnly); connect(reply, SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(onDownloadProgress(qint64,qint64))); connect(manager, SIGNAL(finished(QNetworkReply*)),this,SLOT(onFinished(QNetworkReply*))); connect(reply, SIGNAL(readyRead()),this,SLOT(onReadyRead())); connect(reply, SIGNAL(finished()),this,SLOT(onReplyFinished())); } void getArray(const QString &fileURL, const QMap &headers = {}) { qDebug() << fileURL << headers; if(fileURL.isEmpty()) return; QNetworkRequest request; request.setUrl(QUrl(fileURL)); if(!headers.isEmpty()) { for(auto key: headers.keys()) request.setRawHeader(key.toLocal8Bit(), headers[key].toLocal8Bit()); } reply = manager->get(request); connect(reply, &QNetworkReply::readyRead, [this]() { switch(reply->error()) { case QNetworkReply::NoError: { this->array = reply->readAll(); break; } default: { qDebug() << reply->errorString(); emit this->warning(reply->errorString()); }; } }); connect(reply, &QNetworkReply::finished, [=]() { qDebug() << "Array reply is now finished"; emit this->dataReady(this->array); emit this->done(); }); } private: QNetworkAccessManager *manager; QNetworkReply *reply; QFile *file; QByteArray array; signals: void progress(int percent); void downloadReady(); void fileSaved(QString path); void warning(QString warning); void dataReady(QByteArray array); void done(); private slots: void onDownloadProgress(qint64 bytesRead, qint64 bytesTotal) { emit this->progress((bytesRead * bytesTotal) / 100); } void onFinished(QNetworkReply* reply) { switch(reply->error()) { case QNetworkReply::NoError: { qDebug("file is downloaded successfully."); emit this->downloadReady(); break; } default: { emit this->warning(reply->errorString()); }; } if(file->isOpen()) { file->close(); emit this->fileSaved(file->fileName()); file->deleteLater(); } } void onReadyRead() { file->write(reply->readAll()); // emit this->fileSaved(file->fileName()); } void onReplyFinished() { if(file->isOpen()) { file->close(); // emit this->fileSaved(file->fileName()); file->deleteLater(); } emit done(); } }; } #endif // FMH_H diff --git a/src/fm/fmlist.cpp b/src/fm/fmlist.cpp index 48f1305..9a9301b 100644 --- a/src/fm/fmlist.cpp +++ b/src/fm/fmlist.cpp @@ -1,883 +1,900 @@ /* * - * Copyright (C) 2018 camilo + * Copyright (C) 2018 camilo higuita * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "fmlist.h" #include "fm.h" #include "utils.h" #include #include #include #include #include #include #include FMList::FMList(QObject *parent) : MauiList(parent), fm(new FM(this)), watcher(new QFileSystemWatcher(this)) { connect(this->fm, &FM::cloudServerContentReady, [&](const FMH::MODEL_LIST &list, const QString &url) { if(this->path == url) { this->pre(); this->list = list; this->pathEmpty = this->list.isEmpty(); emit this->pathEmptyChanged(); this->pos(); this->setContentReady(true); } }); connect(this->fm, &FM::trashContentReady, [&](const FMH::MODEL_LIST &list) { if(this->path == "trash://") { this->pre(); this->list = list; this->pathEmpty = this->list.isEmpty(); emit this->pathEmptyChanged(); this->pos(); this->setContentReady(true); } }); connect(this->fm, &FM::pathContentReady, [&](const FMH::PATH_CONTENT &res) { qDebug()<< "PATHCN ONTEN READY" << res.path << this->path << res.content; // if(this->pathType != FMList::PATHTYPE::PLACES_PATH) // return; if(res.path != this->path) return; emit this->preListChanged(); this->list = res.content; this->pathEmpty = this->list.isEmpty() /*&& FM::fileExists(this->path)*/; emit this->pathEmptyChanged(); this->sortList(); emit this->postListChanged(); this->setContentReady(true); }); connect(this->fm, &FM::warningMessage, [&](const QString &message) { emit this->warning(message); }); connect(this->fm, &FM::loadProgress, [&](const int &percent) { emit this->progress(percent); }); // with kio based on android it watches the directory itself, so better relay on that #ifdef Q_OS_ANDROID connect(this->watcher, &QFileSystemWatcher::directoryChanged, [&](const QString &path) { qDebug()<< "FOLDER PATH CHANGED" << path; this->reset(); }); #else connect(this->fm, &FM::pathContentChanged, [&](const QUrl &path) { qDebug()<< "FOLDER PATH CHANGED" << path; if(path.toString() != this->path) return; this->sortList(); }); #endif connect(this->fm, &FM::newItem, [&] (const FMH::MODEL &item, const QString &url) { if(this->path == url) { emit this->preItemAppended(); this->list << item; this->pathEmpty = this->list.isEmpty(); emit this->pathEmptyChanged(); emit this->postListChanged(); } }); connect(this, &FMList::pathChanged, this, &FMList::reset); // connect(this, &FMList::hiddenChanged, this, &FMList::setList); // connect(this, &FMList::onlyDirsChanged, this, &FMList::setList); // connect(this, &FMList::filtersChanged, this, &FMList::setList); const auto value = UTIL::loadSettings("SaveDirProps", "SETTINGS", this->saveDirProps).toBool(); this->setSaveDirProps(value); } FMList::~FMList() {} void FMList::pre() { emit this->preListChanged(); // this->setContentReady(false); } void FMList::pos() { // this->setContentReady(true); emit this->postListChanged(); } void FMList::watchPath(const QString& path, const bool& clear) { #ifdef Q_OS_ANDROID if(!this->watcher->directories().isEmpty() && clear) this->watcher->removePaths(this->watcher->directories()); if(path.isEmpty() || !FMH::fileExists(path)) return; this->watcher->addPath(QString(path).replace("file://", "")); qDebug()<< "WATCHING PATHS" << this->watcher->directories(); #else Q_UNUSED(path) Q_UNUSED(clear) #endif } void FMList::setList() { this->setContentReady(true); switch(this->pathType) { case FMList::PATHTYPE::FISH_PATH: case FMList::PATHTYPE::MTP_PATH: case FMList::PATHTYPE::DRIVES_PATH: case FMList::PATHTYPE::REMOTE_PATH: case FMList::PATHTYPE::PLACES_PATH: this->list.clear(); this->setContentReady(false); this->fm->getPathContent(this->path, this->hidden, this->onlyDirs, this->filters); return; //ASYNC case FMList::PATHTYPE::TRASH_PATH: this->list.clear(); this->setContentReady(false); this->fm->getTrashContent(); break;//ASYNC case FMList::PATHTYPE::SEARCH_PATH: this->list.clear(); this->setContentReady(false); this->search(QString(this->path).right(this->path.length()- 1 - this->path.lastIndexOf("/")), this->searchPath, this->hidden, this->onlyDirs, this->filters); return; //ASYNC case FMList::PATHTYPE::APPS_PATH: this->list = FM::getAppsContent(this->path); break; case FMList::PATHTYPE::TAGS_PATH: this->list = this->fm->getTagContent(QString(this->path).right(this->path.length()- 1 - this->path.lastIndexOf("/"))); break; case FMList::PATHTYPE::CLOUD_PATH: this->list.clear(); if(this->fm->getCloudServerContent(this->path, this->filters, this->cloudDepth)) { this->setContentReady(false); return; }else break; } this->pathEmpty = this->list.isEmpty() && FM::fileExists(this->path); emit this->pathEmptyChanged(); this->sortList(); } void FMList::reset() { this->pre(); switch(this->pathType) { case FMList::PATHTYPE::APPS_PATH: this->hidden = false; this->preview = false; break; case FMList::PATHTYPE::CLOUD_PATH: case FMList::PATHTYPE::SEARCH_PATH: case FMList::PATHTYPE::TAGS_PATH: this->hidden = false; this->preview = true; break; case FMList::PATHTYPE::PLACES_PATH: { if(this->saveDirProps) { auto conf = FMH::dirConf(this->path+"/.directory"); this->hidden = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::HIDDEN]].toBool(); this->preview = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::SHOWTHUMBNAIL]].toBool(); this->foldersFirst = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::FOLDERSFIRST]].toBool(); }else { this->hidden = UTIL::loadSettings("HiddenFilesShown", "SETTINGS", this->hidden).toBool(); this->preview = UTIL::loadSettings("ShowThumbnail", "SETTINGS", this->preview).toBool(); this->foldersFirst = UTIL::loadSettings("FoldersFirst", "SETTINGS", this->foldersFirst).toBool(); } break; } default: break; } if(this->saveDirProps) { auto conf = FMH::dirConf(this->path+"/.directory"); this->sort = static_cast(conf[FMH::MODEL_NAME[FMH::MODEL_KEY::SORTBY]].toInt()); this->viewType = static_cast(conf[FMH::MODEL_NAME[FMH::MODEL_KEY::VIEWTYPE]].toInt()); }else { this->sort = static_cast(UTIL::loadSettings("SortBy", "SETTINGS", this->sort).toInt()); this->viewType = static_cast(UTIL::loadSettings("ViewType", "SETTINGS", this->viewType).toInt()); } emit this->sortByChanged(); emit this->viewTypeChanged(); emit this->hiddenChanged(); emit this->previewChanged(); qDebug()<< "RESETING PATH CONTENTE" << this->path; this->setList(); this->pos(); } FMH::MODEL_LIST FMList::items() const { return this->list; } FMList::SORTBY FMList::getSortBy() const { return this->sort; } void FMList::setSortBy(const FMList::SORTBY &key) { if(this->sort == key) return; this->pre(); this->sort = key; this->sortList(); if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "SortBy", this->sort); else UTIL::saveSettings("SortBy", this->sort, "SETTINGS"); emit this->sortByChanged(); this->pos(); } void FMList::sortList() { FMH::MODEL_KEY key = static_cast(this->sort); auto index = 0; if(this->foldersFirst) { qSort(this->list.begin(), this->list.end(), [](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { Q_UNUSED(e2) const auto key = FMH::MODEL_KEY::MIME; if(e1[key] == "inode/directory") return true; return false; }); for(auto item : this->list) if(item[FMH::MODEL_KEY::MIME] == "inode/directory") index++; else break; qSort(this->list.begin(),this->list.begin() + index, [key](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { auto role = key; switch(role) { case FMH::MODEL_KEY::SIZE: { if(e1[role].toDouble() > e2[role].toDouble()) return true; break; } case FMH::MODEL_KEY::MODIFIED: case FMH::MODEL_KEY::DATE: { auto currentTime = QDateTime::currentDateTime(); auto date1 = QDateTime::fromString(e1[role], Qt::TextDate); auto date2 = QDateTime::fromString(e2[role], Qt::TextDate); if(date1.secsTo(currentTime) < date2.secsTo(currentTime)) return true; break; } case FMH::MODEL_KEY::LABEL: { const auto str1 = QString(e1[role]).toLower(); const auto str2 = QString(e2[role]).toLower(); if(str1 < str2) return true; break; } default: if(e1[role] < e2[role]) return true; } return false; }); } qSort(this->list.begin() + index, this->list.end(), [key](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { auto role = key; switch(role) { case FMH::MODEL_KEY::MIME: if(e1[role] == "inode/directory") return true; break; case FMH::MODEL_KEY::SIZE: { if(e1[role].toDouble() > e2[role].toDouble()) return true; break; } case FMH::MODEL_KEY::MODIFIED: case FMH::MODEL_KEY::DATE: { auto currentTime = QDateTime::currentDateTime(); auto date1 = QDateTime::fromString(e1[role], Qt::TextDate); auto date2 = QDateTime::fromString(e2[role], Qt::TextDate); if(date1.secsTo(currentTime) < date2.secsTo(currentTime)) return true; break; } case FMH::MODEL_KEY::LABEL: { const auto str1 = QString(e1[role]).toLower(); const auto str2 = QString(e2[role]).toLower(); if(str1 < str2) return true; break; } default: if(e1[role] < e2[role]) return true; } return false; }); } +QString FMList::getPathName() const +{ + return this->pathName; +} + + QString FMList::getPath() const { return this->path; } void FMList::setPath(const QString &path) { if(this->path == path) return; if(this->pathType == FMList::PATHTYPE::PLACES_PATH) this->searchPath = this->path; this->path = path; this->setPreviousPath(this->path); qDebug()<< "Prev History" << this->prevHistory; const auto __scheme = QUrl(this->path).scheme(); qDebug()<< "CurrentPath" <<__scheme; // if(path.startsWith(FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::SEARCH_PATH]+"/")) if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::SEARCH_PATH]) { this->pathExists = true; this->pathType = FMList::PATHTYPE::SEARCH_PATH; + this->pathName = "Search"; + emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::CLOUD_PATH]) { this->pathExists = true; this->pathType = FMList::PATHTYPE::CLOUD_PATH; + this->pathName = "Cloud"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::APPS_PATH]) { - qDebug()<< "GET APPS" ; this->pathExists = true; this->pathType = FMList::PATHTYPE::APPS_PATH; + this->pathName = "Apps"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::TAGS_PATH]) { this->pathExists = true; this->pathType = FMList::PATHTYPE::TAGS_PATH; + emit this->pathName = "Tags"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::TRASH_PATH]) { this->pathExists = true; this->pathType = FMList::PATHTYPE::TRASH_PATH; + this->pathName = "Trash"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::PLACES_PATH]) { this->watchPath(this->path); this->pathExists = FMH::fileExists(this->path); this->pathType = FMList::PATHTYPE::PLACES_PATH; + this->pathName = FMH::getDirInfoModel(this->path)[FMH::MODEL_KEY::LABEL]; emit this->pathExistsChanged(); emit this->pathTypeChanged(); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::MTP_PATH]) { this->pathExists = true; this->pathType = FMList::PATHTYPE::MTP_PATH; + this->pathName = "MTP"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::FISH_PATH] ) { this->pathExists = true; this->pathType = FMList::PATHTYPE::FISH_PATH; + this->pathName = "Fish"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::REMOTE_PATH] ) { this->pathExists = true; this->pathType = FMList::PATHTYPE::REMOTE_PATH; + this->pathName = "Remote"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::DRIVES_PATH] ) { this->pathExists = true; this->pathType = FMList::PATHTYPE::DRIVES_PATH; + this->pathName = "Drives"; emit this->pathExistsChanged(); emit this->pathTypeChanged(); } qDebug() << "PATHTYPE IS" << this->pathType << FMH::PATHTYPE_SCHEME[static_cast(this->pathType)]; emit this->pathChanged(); + emit this->pathNameChanged(); } FMList::PATHTYPE FMList::getPathType() const { return this->pathType; } QStringList FMList::getFilters() const { return this->filters; } void FMList::setFilters(const QStringList &filters) { if(this->filters == filters) return; this->filters = filters; emit this->filtersChanged(); this->reset(); } FMList::FILTER FMList::getFilterType() const { return this->filterType; } void FMList::setFilterType(const FMList::FILTER &type) { this->filterType = type; this->filters = FMH::FILTER_LIST[static_cast(this->filterType)]; emit this->filtersChanged(); emit this->filterTypeChanged(); this->reset(); } bool FMList::getHidden() const { return this->hidden; } void FMList::setHidden(const bool &state) { if(this->hidden == state) return; this->hidden = state; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "Settings", "HiddenFilesShown", this->hidden); else UTIL::saveSettings("HiddenFilesShown", this->hidden, "SETTINGS"); emit this->hiddenChanged(); this->reset(); } bool FMList::getPreview() const { return this->preview; } void FMList::setPreview(const bool &state) { if(this->preview == state) return; this->preview = state; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "ShowThumbnail", this->preview); else UTIL::saveSettings("ShowThumbnail", this->preview, "SETTINGS"); emit this->previewChanged(); } bool FMList::getOnlyDirs() const { return this->onlyDirs; } void FMList::setOnlyDirs(const bool &state) { if(this->onlyDirs == state) return; this->onlyDirs = state; emit this->onlyDirsChanged(); this->reset(); } QVariantMap FMList::get(const int &index) const { if(index >= this->list.size() || index < 0) return QVariantMap(); const auto model = this->list.at(index); return FM::toMap(model); } void FMList::refresh() { emit this->pathChanged(); } void FMList::createDir(const QString& name) { if(this->pathType == FMList::PATHTYPE::PLACES_PATH) this->fm->createDir(this->path, name); else if(this->pathType == FMList::PATHTYPE::CLOUD_PATH) { this->fm->createCloudDir(QString(this->path).replace(FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::CLOUD_PATH]+"/"+this->fm->sync->getUser(), ""), name); } } void FMList::copyInto(const QVariantList& files) { if(this->pathType == FMList::PATHTYPE::PLACES_PATH || this->pathType == FMList::PATHTYPE::CLOUD_PATH) this->fm->copy(files, this->path); } void FMList::cutInto(const QVariantList& files) { if(this->pathType == FMList::PATHTYPE::PLACES_PATH) this->fm->cut(files, this->path); // else if(this->pathType == FMList::PATHTYPE::CLOUD_PATH) // { // this->fm->createCloudDir(QString(this->path).replace(FMH::PATHTYPE_NAME[FMList::PATHTYPE::CLOUD_PATH]+"/"+this->fm->sync->getUser(), ""), name); // } } void FMList::setDirIcon(const int &index, const QString &iconName) { if(index >= this->list.size() || index < 0) return; const auto path = QUrl(this->list.at(index)[FMH::MODEL_KEY::PATH]); if(!FM::isDir(path)) return; FMH::setDirConf(path.toString()+"/.directory", "Desktop Entry", "Icon", iconName); this->list[index][FMH::MODEL_KEY::ICON] = iconName; emit this->updateModel(index, QVector {FMH::MODEL_KEY::ICON}); } QString FMList::getParentPath() { switch(this->pathType) { case FMList::PATHTYPE::PLACES_PATH: return FM::parentDir(this->path).toString(); default: return this->getPreviousPath(); } } QString FMList::getPosteriorPath() { if(this->postHistory.isEmpty()) return this->path; return this->postHistory.takeAt(this->postHistory.length()-1); } void FMList::setPosteriorPath(const QString& path) { this->postHistory.append(path); } QString FMList::getPreviousPath() { if(this->prevHistory.isEmpty()) return this->path; if(this->prevHistory.length() < 2) return this->prevHistory.at(0); auto post = this->prevHistory.takeAt(this->prevHistory.length()-1); this->setPosteriorPath(post); return this->prevHistory.takeAt(this->prevHistory.length()-1); } void FMList::setPreviousPath(const QString& path) { this->prevHistory.append(path); } bool FMList::getPathEmpty() const { return this->pathEmpty; } bool FMList::getPathExists() const { return this->pathExists; } bool FMList::getTrackChanges() const { return this->trackChanges; } void FMList::setTrackChanges(const bool& value) { if(this->trackChanges == value) return; this->trackChanges = value; emit this->trackChangesChanged(); } bool FMList::getFoldersFirst() const { return this->foldersFirst; } void FMList::setFoldersFirst(const bool &value) { if(this->foldersFirst == value) return; this->pre(); this->foldersFirst = value; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "FoldersFirst", this->foldersFirst); else UTIL::saveSettings("FoldersFirst", this->foldersFirst, "SETTINGS"); emit this->foldersFirstChanged(); this->sortList(); this->pos(); } void FMList::setSaveDirProps(const bool& value) { if(this->saveDirProps == value) return; this->saveDirProps = value; UTIL::saveSettings("SaveDirProps", this->saveDirProps, "SETTINGS"); emit this->saveDirPropsChanged(); } bool FMList::getSaveDirProps() const { return this->saveDirProps; } void FMList::setContentReady(const bool& value) { this->contentReady = value; emit this->contentReadyChanged(); } bool FMList::getContentReady() const { return this->contentReady; } FMList::VIEW_TYPE FMList::getViewType() const { return this->viewType; } void FMList::setViewType(const FMList::VIEW_TYPE& value) { if(this->viewType == value) return; this->viewType = value; if(this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "ViewType", this->viewType); else UTIL::saveSettings("ViewType", this->viewType, "SETTINGS"); emit this->viewTypeChanged(); } void FMList::search(const QString& query, const QUrl &path, const bool &hidden, const bool &onlyDirs, const QStringList &filters) { qDebug()<< "SEARCHING FOR" << query << path; if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file. search" << path; return; } QFutureWatcher *watcher = new QFutureWatcher; connect(watcher, &QFutureWatcher::finished, [=]() { if(this->pathType != FMList::PATHTYPE::SEARCH_PATH) return; const auto res = watcher->future().result(); if(res.path != this->searchPath) return; emit this->preListChanged(); this->list = res.content; emit this->postListChanged(); emit this->searchResultReady(); this->pathEmpty = this->list.isEmpty() && FM::fileExists(this->path); emit this->pathEmptyChanged(); this->sortList(); this->setContentReady(true); watcher->deleteLater(); }); QFuture t1 = QtConcurrent::run([=]() -> FMH::PATH_CONTENT { FMH::PATH_CONTENT res; res.path = path.toString(); res.content = FM::search(query, path, hidden, onlyDirs, filters); return res; }); watcher->setFuture(t1); } int FMList::getCloudDepth() const { return this->cloudDepth; } void FMList::setCloudDepth(const int& value) { if(this->cloudDepth == value) return; this->cloudDepth = value; emit this->cloudDepthChanged(); this->reset(); } diff --git a/src/fm/fmlist.h b/src/fm/fmlist.h index 3c7a824..ffd8c9f 100644 --- a/src/fm/fmlist.h +++ b/src/fm/fmlist.h @@ -1,245 +1,250 @@ /* * * Copyright (C) 2018 Camilo Higuita * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef FMLIST_H #define FMLIST_H #include #include "fmh.h" #include "mauilist.h" struct PathContent { QString path; FMH::MODEL_LIST content; }; class FM; class QFileSystemWatcher; class FMList : public MauiList { Q_OBJECT - Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged()) + Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged) + Q_PROPERTY(QString pathName READ getPathName NOTIFY pathNameChanged) - Q_PROPERTY(bool hidden READ getHidden WRITE setHidden NOTIFY hiddenChanged()) - Q_PROPERTY(bool onlyDirs READ getOnlyDirs WRITE setOnlyDirs NOTIFY onlyDirsChanged()) - Q_PROPERTY(bool preview READ getPreview WRITE setPreview NOTIFY previewChanged()) - Q_PROPERTY(FMList::VIEW_TYPE viewType READ getViewType WRITE setViewType NOTIFY viewTypeChanged()) - Q_PROPERTY(int cloudDepth READ getCloudDepth WRITE setCloudDepth NOTIFY cloudDepthChanged()) + Q_PROPERTY(bool hidden READ getHidden WRITE setHidden NOTIFY hiddenChanged) + Q_PROPERTY(bool onlyDirs READ getOnlyDirs WRITE setOnlyDirs NOTIFY onlyDirsChanged) + Q_PROPERTY(bool preview READ getPreview WRITE setPreview NOTIFY previewChanged) + Q_PROPERTY(FMList::VIEW_TYPE viewType READ getViewType WRITE setViewType NOTIFY viewTypeChanged) + Q_PROPERTY(int cloudDepth READ getCloudDepth WRITE setCloudDepth NOTIFY cloudDepthChanged) - Q_PROPERTY(bool contentReady READ getContentReady NOTIFY contentReadyChanged()) + Q_PROPERTY(bool contentReady READ getContentReady NOTIFY contentReadyChanged) - Q_PROPERTY(QStringList filters READ getFilters WRITE setFilters NOTIFY filtersChanged()) - Q_PROPERTY(FMList::FILTER filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged()) + Q_PROPERTY(QStringList filters READ getFilters WRITE setFilters NOTIFY filtersChanged) + Q_PROPERTY(FMList::FILTER filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged) - Q_PROPERTY(FMList::SORTBY sortBy READ getSortBy WRITE setSortBy NOTIFY sortByChanged()) - Q_PROPERTY(bool foldersFirst READ getFoldersFirst WRITE setFoldersFirst NOTIFY foldersFirstChanged()) - Q_PROPERTY(FMList::PATHTYPE pathType READ getPathType NOTIFY pathTypeChanged()) + Q_PROPERTY(FMList::SORTBY sortBy READ getSortBy WRITE setSortBy NOTIFY sortByChanged) + Q_PROPERTY(bool foldersFirst READ getFoldersFirst WRITE setFoldersFirst NOTIFY foldersFirstChanged) + Q_PROPERTY(FMList::PATHTYPE pathType READ getPathType NOTIFY pathTypeChanged) - Q_PROPERTY(bool trackChanges READ getTrackChanges WRITE setTrackChanges NOTIFY trackChangesChanged()) - Q_PROPERTY(bool saveDirProps READ getSaveDirProps WRITE setSaveDirProps NOTIFY saveDirPropsChanged()) + Q_PROPERTY(bool trackChanges READ getTrackChanges WRITE setTrackChanges NOTIFY trackChangesChanged) + Q_PROPERTY(bool saveDirProps READ getSaveDirProps WRITE setSaveDirProps NOTIFY saveDirPropsChanged) - Q_PROPERTY(bool pathExists READ getPathExists NOTIFY pathExistsChanged()) - Q_PROPERTY(bool pathEmpty READ getPathEmpty NOTIFY pathEmptyChanged()) + Q_PROPERTY(bool pathExists READ getPathExists NOTIFY pathExistsChanged) + Q_PROPERTY(bool pathEmpty READ getPathEmpty NOTIFY pathEmptyChanged) Q_PROPERTY(QString previousPath READ getPreviousPath) Q_PROPERTY(QString posteriorPath READ getPosteriorPath) Q_PROPERTY(QString parentPath READ getParentPath) public: enum SORTBY : uint_fast8_t { SIZE = FMH::MODEL_KEY::SIZE, MODIFIED = FMH::MODEL_KEY::MODIFIED, DATE = FMH::MODEL_KEY::DATE, LABEL = FMH::MODEL_KEY::LABEL, MIME = FMH::MODEL_KEY::MIME, ADDDATE = FMH::MODEL_KEY::MIME, TITLE = FMH::MODEL_KEY::TITLE, PLACE = FMH::MODEL_KEY::PLACE, FORMAT = FMH::MODEL_KEY::FORMAT }; Q_ENUM(SORTBY) enum FILTER : uint_fast8_t { AUDIO = FMH::FILTER_TYPE::AUDIO, VIDEO= FMH::FILTER_TYPE::VIDEO, TEXT = FMH::FILTER_TYPE::TEXT, IMAGE = FMH::FILTER_TYPE::IMAGE, NONE = FMH::FILTER_TYPE::NONE }; Q_ENUM(FILTER) enum PATHTYPE : uint_fast8_t { PLACES_PATH = FMH::PATHTYPE_KEY::PLACES_PATH, FISH_PATH = FMH::PATHTYPE_KEY::FISH_PATH, MTP_PATH = FMH::PATHTYPE_KEY::MTP_PATH, REMOTE_PATH = FMH::PATHTYPE_KEY::REMOTE_PATH, DRIVES_PATH = FMH::PATHTYPE_KEY::DRIVES_PATH, REMOVABLE_PATH = FMH::PATHTYPE_KEY::REMOVABLE_PATH, TAGS_PATH = FMH::PATHTYPE_KEY::TAGS_PATH, APPS_PATH = FMH::PATHTYPE_KEY::APPS_PATH, TRASH_PATH = FMH::PATHTYPE_KEY::TRASH_PATH, SEARCH_PATH = FMH::PATHTYPE_KEY::SEARCH_PATH, CLOUD_PATH = FMH::PATHTYPE_KEY::CLOUD_PATH }; Q_ENUM(PATHTYPE) enum VIEW_TYPE : uint_fast8_t { ICON_VIEW, LIST_VIEW, MILLERS_VIEW }; Q_ENUM(VIEW_TYPE) FMList(QObject *parent = nullptr); ~FMList(); FMH::MODEL_LIST items() const final override; FMList::SORTBY getSortBy() const; void setSortBy(const FMList::SORTBY &key); QString getPath() const; - void setPath(const QString &path); - + void setPath(const QString &path); + + QString getPathName() const; + FMList::PATHTYPE getPathType() const; QStringList getFilters() const; void setFilters(const QStringList &filters); FMList::FILTER getFilterType() const; void setFilterType(const FMList::FILTER &type); bool getHidden() const; void setHidden(const bool &state); bool getPreview() const; void setPreview(const bool &state); bool getOnlyDirs() const; void setOnlyDirs(const bool &state); QString getParentPath(); QString getPreviousPath(); void setPreviousPath(const QString &path); QString getPosteriorPath(); void setPosteriorPath(const QString &path); bool getPathEmpty() const; bool getPathExists() const; bool getTrackChanges() const; void setTrackChanges(const bool &value); bool getFoldersFirst() const; void setFoldersFirst(const bool &value); bool getSaveDirProps() const; void setSaveDirProps(const bool &value); bool getContentReady() const; void setContentReady(const bool &value); VIEW_TYPE getViewType() const; void setViewType(const VIEW_TYPE &value); int getCloudDepth() const; void setCloudDepth(const int &value); private: FM *fm; QFileSystemWatcher *watcher; void pre(); void pos(); void reset(); void setList(); void sortList(); void watchPath(const QString &path, const bool &clear = true); void search(const QString &query, const QUrl &path, const bool &hidden = false, const bool &onlyDirs = false, const QStringList &filters = QStringList()); FMH::MODEL_LIST list = {{}}; QString path = QString(); + QString pathName = QString(); QStringList filters = {}; bool onlyDirs = false; bool hidden = false; bool preview = false; bool pathExists = false; bool pathEmpty = true; bool trackChanges = true; bool foldersFirst = false; bool saveDirProps = false; bool contentReady = false; int cloudDepth = 1; QString searchPath; VIEW_TYPE viewType = VIEW_TYPE::ICON_VIEW; FMList::SORTBY sort = FMList::SORTBY::MODIFIED; FMList::FILTER filterType = FMList::FILTER::NONE; FMList::PATHTYPE pathType = FMList::PATHTYPE::PLACES_PATH; QStringList prevHistory = {}; QStringList postHistory = {}; public slots: QVariantMap get(const int &index) const; void refresh(); void createDir(const QString &name); void copyInto(const QVariantList &files); void cutInto(const QVariantList &files); void setDirIcon(const int &index, const QString &iconName); signals: void pathChanged(); + void pathNameChanged(); void pathTypeChanged(); void filtersChanged(); void filterTypeChanged(); void hiddenChanged(); void previewChanged(); void onlyDirsChanged(); void sortByChanged(); void trackChangesChanged(); void foldersFirstChanged(); void saveDirPropsChanged(); void contentReadyChanged(); void viewTypeChanged(); void cloudDepthChanged(); void pathEmptyChanged(); void pathExistsChanged(); void warning(QString message); void progress(int percent); void searchResultReady(); }; #endif // FMLIST_H diff --git a/src/mauikit.cpp b/src/mauikit.cpp index 13d1119..07413bc 100644 --- a/src/mauikit.cpp +++ b/src/mauikit.cpp @@ -1,194 +1,195 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mauikit.h" #include #include "fm.h" #include "fmh.h" #include "mauimodel.h" #include "mauilist.h" #include "placeslist.h" #include "fmlist.h" #include "pathlist.h" #include "tagsmodel.h" #include "tagslist.h" #include "storemodel.h" #include "storelist.h" #include "handy.h" #include "documenthandler.h" #include "syntaxhighlighterutil.h" #include "mauiaccounts.h" #include "mauiapp.h" #ifdef Q_OS_ANDROID #include "mauiandroid.h" #else #include "mauikde.h" #endif #if defined Q_OS_ANDROID || defined APPIMAGE_PACKAGE #include #include #endif /** * Global Variables */ SyntaxHighlighterUtil *syntaxHighlighterUtil = nullptr; QUrl MauiKit::componentUrl(const QString &fileName) const { #ifdef MAUI_APP return QUrl(QStringLiteral("qrc:/maui/kit/") + fileName); #else return QUrl(resolveFileUrl(fileName)); #endif } void MauiKit::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.mauikit")); qmlRegisterSingletonType(componentUrl(QStringLiteral("Style.qml")), uri, 1, 0, "Style"); qmlRegisterType(componentUrl(QStringLiteral("ToolBar.qml")), uri, 1, 0, "ToolBar"); qmlRegisterType(componentUrl(QStringLiteral("ApplicationWindow.qml")), uri, 1, 0, "ApplicationWindow"); qmlRegisterType(componentUrl(QStringLiteral("Page.qml")), uri, 1, 0, "Page"); qmlRegisterType(componentUrl(QStringLiteral("ShareDialog.qml")), uri, 1, 0, "ShareDialog"); qmlRegisterType(componentUrl(QStringLiteral("PieButton.qml")), uri, 1, 0, "PieButton"); qmlRegisterType(componentUrl(QStringLiteral("SideBar.qml")), uri, 1, 0, "SideBar"); qmlRegisterType(componentUrl(QStringLiteral("Holder.qml")), uri, 1, 0, "Holder"); qmlRegisterType(componentUrl(QStringLiteral("GlobalDrawer.qml")), uri, 1, 0, "GlobalDrawer"); qmlRegisterType(componentUrl(QStringLiteral("ListDelegate.qml")), uri, 1, 0, "ListDelegate"); qmlRegisterType(componentUrl(QStringLiteral("SelectionBar.qml")), uri, 1, 0, "SelectionBar"); qmlRegisterType(componentUrl(QStringLiteral("IconDelegate.qml")), uri, 1, 0, "IconDelegate"); qmlRegisterType(componentUrl(QStringLiteral("LabelDelegate.qml")), uri, 1, 0, "LabelDelegate"); qmlRegisterType(componentUrl(QStringLiteral("NewDialog.qml")), uri, 1, 0, "NewDialog"); qmlRegisterType(componentUrl(QStringLiteral("Dialog.qml")), uri, 1, 0, "Dialog"); qmlRegisterType(componentUrl(QStringLiteral("AboutDialog.qml")), uri, 1, 0, "AboutDialog"); qmlRegisterType(componentUrl(QStringLiteral("Popup.qml")), uri, 1, 0, "Popup"); qmlRegisterType(componentUrl(QStringLiteral("TextField.qml")), uri, 1, 0, "TextField"); qmlRegisterType(componentUrl(QStringLiteral("Badge.qml")), uri, 1, 0, "Badge"); qmlRegisterType(componentUrl(QStringLiteral("GridView.qml")), uri, 1, 0, "GridView"); qmlRegisterType(componentUrl(QStringLiteral("ColorsBar.qml")), uri, 1, 0, "ColorsBar"); qmlRegisterType(componentUrl(QStringLiteral("ImageViewer.qml")), uri, 1, 0, "ImageViewer"); /** STORE CONTROLS, MODELS AND INTERFACES **/ qmlRegisterType("StoreList", 1, 0, "StoreList"); qmlRegisterType("StoreModel", 1, 0, "StoreModel"); qmlRegisterType(componentUrl(QStringLiteral("private/StoreDelegate.qml")), uri, 1, 0, "StoreDelegate"); qmlRegisterType(componentUrl(QStringLiteral("Store.qml")), uri, 1, 0, "Store"); /** BROWSING CONTROLS **/ qmlRegisterType(componentUrl(QStringLiteral("ListBrowser.qml")), uri, 1, 0, "ListBrowser"); qmlRegisterType(componentUrl(QStringLiteral("GridBrowser.qml")), uri, 1, 0, "GridBrowser"); /** FM CONTROLS, MODELS AND INTERFACES **/ qmlRegisterType(uri, 1, 0, "PlacesList"); qmlRegisterType(uri, 1, 0, "FMList"); qmlRegisterType(uri, 1, 0, "PathList"); qmlRegisterSingletonType(uri, 1, 0, "FM", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new FM; }); +// qmlRegisterSingletonType(componentUrl(QStringLiteral("private/FileBrowser.qml")), uri, 1, 0, "FileMenu"); qmlRegisterType(componentUrl(QStringLiteral("FileBrowser.qml")), uri, 1, 0, "FileBrowser"); qmlRegisterType(componentUrl(QStringLiteral("PlacesSidebar.qml")), uri, 1, 0, "PlacesSidebar"); qmlRegisterType(componentUrl(QStringLiteral("FilePreviewer.qml")), uri, 1, 0, "FilePreviewer"); qmlRegisterType(componentUrl(QStringLiteral("FileDialog.qml")), uri, 1, 0, "FileDialog"); qmlRegisterType(componentUrl(QStringLiteral("PathBar.qml")), uri, 1, 0, "PathBar"); qmlRegisterType(componentUrl(QStringLiteral("SyncDialog.qml")), uri, 1, 0, "SyncDialog"); //to be rename to accountsDialog /** EDITOR CONTROLS **/ qmlRegisterType("DocumentHandler", 1, 0, "DocumentHandler"); qmlRegisterType(componentUrl(QStringLiteral("Editor.qml")), uri, 1, 0, "Editor"); qmlRegisterSingletonType("SyntaxHighlighterUtil", 1, 0, "SyntaxHighlighterUtil", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) if (syntaxHighlighterUtil == nullptr) { syntaxHighlighterUtil = new SyntaxHighlighterUtil(); } return syntaxHighlighterUtil; }); /** PLATFORMS SPECIFIC CONTROLS **/ #ifdef Q_OS_ANDROID qmlRegisterSingletonType(uri, 1, 0, "Android", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new MAUIAndroid; }); #else qmlRegisterType(componentUrl(QStringLiteral("Terminal.qml")), uri, 1, 0, "Terminal"); qmlRegisterSingletonType(uri, 1, 0, "KDE", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new MAUIKDE; }); #endif /** DATA MODELING TEMPLATED INTERFACES **/ qmlRegisterType(); //ABSTRACT BASE LIST qmlRegisterType(uri, 1, 0, "BaseModel"); //BASE MODEL /** TAGGING INTERFACES AND MODELS **/ qmlRegisterType("TagsList", 1, 0, "TagsList"); qmlRegisterType("TagsModel", 1, 0, "TagsModel"); qmlRegisterType(componentUrl(QStringLiteral("private/TagList.qml")), uri, 1, 0, "TagList"); qmlRegisterType(componentUrl(QStringLiteral("TagsBar.qml")), uri, 1, 0, "TagsBar"); qmlRegisterType(componentUrl(QStringLiteral("TagsDialog.qml")), uri, 1, 0, "TagsDialog"); /** MAUI APPLICATION SPECIFIC PROPS **/ qmlRegisterType(); qmlRegisterSingletonType(uri, 1, 0, "App", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return MauiApp::instance(); }); /** HELPERS **/ qmlRegisterSingletonType(uri, 1, 0, "Handy", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new Handy; }); #if defined Q_OS_ANDROID || defined APPIMAGE_PACKAGE QIcon::setThemeSearchPaths({":/icons/luv-icon-theme"}); QIcon::setThemeName("Luv"); QQuickStyle::setStyle(":/style"); #endif qmlProtectModule(uri, 1); }