Commit f9868df9 authored by camilo higuita's avatar camilo higuita

re structure folder content and make use of qmltermwidget for an embeded...

re structure folder content and make use of qmltermwidget for an embeded terminal on the browser and basic syncing between the current folder and terminal
parent 0294f2e7
function bookmarkFolder(path)
{
inx.bookmark(path)
placesSidebar.populate()
}
QT += qml quick quickcontrols2 sql widgets
CONFIG += c++11
TARGET = index
DESTDIR = $$OUT_PWD/../
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp \
index.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
index.h \
inx.h
#include "index.h"
#include <QFileInfo>
#include <QMimeType>
#include <QDirIterator>
#include <QDesktopServices>
#include <QUrl>
#include <QStorageInfo>
#include "inx.h"
Index::Index(QObject *parent) : QObject(parent)
{
}
QVariantList Index::getPathContent(const QString &path)
{
QVariantList content;
if (QFileInfo(path).isDir())
{
QDirIterator it(path, QDir::Files | QDir::AllDirs | QDir::NoDotDot | QDir::NoDot, QDirIterator::NoIteratorFlags);
while (it.hasNext())
{
auto url = it.next();
QFileInfo file(url);
QVariantMap item =
{
{"iconName", INX::getIconName(url)},
{"label", file.isDir() ? file.baseName() : file.baseName() + "."+file.suffix()},
{"path", url}
};
content << item;
}
}
return content;
}
QVariantList Index::getDefaultPaths()
{
return packItems(INX::defaultPaths, "Places");
}
bool Index::isDefaultPath(const QString &path)
{
return INX::defaultPaths.contains(path);
}
QVariantList Index::getDevices()
{
QVariantList drives;
auto devices = QStorageInfo::mountedVolumes();
for(auto device : devices)
{
if(device.isValid() && !device.isReadOnly())
{
QVariantMap drive =
{
{"iconName", "drive-harddisk"},
{"label", device.displayName()},
{"path", device.rootPath()},
{"type", "Drives"}
};
drives << drive;
}
}
// for(auto device : QDir::drives())
// {
// QVariantMap drive =
// {
// {"iconName", "drive-harddisk"},
// {"label", device.baseName()},
// {"path", device.absoluteFilePath()},
// {"type", "Drives"}
// };
// drives << drive;
// }
return drives;
}
QString Index::homePath()
{
return INX::HomePath;
}
QString Index::parentDir(const QString &path)
{
auto dir = QDir(path);
dir.cdUp();
return dir.absolutePath();
}
bool Index::isDir(const QString &path)
{
return QFileInfo(path).isDir();
}
bool Index::openFile(const QString &path)
{
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}
bool Index::bookmark(const QString &path)
{
auto bookmarks = INX::loadSettings("BOOKMARKS", "INX", QStringList()).toStringList();
bookmarks.append(path);
INX::saveSettings("BOOKMARKS", bookmarks, "INX");
return true;
}
QVariantList Index::getBookmarks()
{
auto bookmarks = INX::loadSettings("BOOKMARKS", "INX", QStringList()).toStringList();
return packItems(bookmarks, "Bookmarks");
}
QVariantList Index::packItems(const QStringList &items, const QString &type)
{
QVariantList data;
for(auto path : items)
data << getDirInfo(path, type);
return data;
}
QVariantMap Index::getDirInfo(const QString &path, const QString &type)
{
QFileInfo file (path);
QVariantMap data =
{
{"iconName", INX::getIconName(path)},
{"label", file.baseName()},
{"path", path},
{"type", type}
};
return data;
}
void Index::saveSettings(const QString &key, const QVariant &value, const QString &group)
{
INX::saveSettings(key, value, group);
}
QVariant Index::loadSettings(const QString &key, const QString &group, const QVariant &defaultValue)
{
return INX::loadSettings(key, group, defaultValue);
}
#ifndef INDEX_H
#define INDEX_H
#include <QObject>
#include <QVariantList>
#include <QStringList>
class Index : public QObject
{
Q_OBJECT
public:
explicit Index(QObject *parent = nullptr);
Q_INVOKABLE static QVariantList getPathContent(const QString &path);
Q_INVOKABLE static QVariantList getDefaultPaths();
Q_INVOKABLE static bool isDefaultPath(const QString &path);
Q_INVOKABLE static QVariantList getDevices();
Q_INVOKABLE static QString homePath();
Q_INVOKABLE static QString parentDir(const QString &path);
Q_INVOKABLE static bool isDir(const QString &path);
Q_INVOKABLE static bool openFile(const QString &path);
Q_INVOKABLE static bool bookmark(const QString &path);
Q_INVOKABLE static QVariantList getBookmarks();
Q_INVOKABLE static QVariantList packItems(const QStringList &items, const QString &type);
Q_INVOKABLE static void saveSettings(const QString &key, const QVariant &value, const QString &group);
Q_INVOKABLE static QVariant loadSettings(const QString &key, const QString &group, const QVariant &defaultValue);
Q_INVOKABLE static QVariantMap getDirInfo(const QString &path, const QString &type);
signals:
public slots:
};
#endif // INDEX_H
#ifndef INX_H
#define INX_H
#include <QString>
#include <QDebug>
#include <QStandardPaths>
#include <QFileInfo>
#include <QImage>
#include <QTime>
#include <QSettings>
#include <QDirIterator>
#include <QVariantList>
#include <QMimeType>
#include <QMimeData>
#include <QMimeDatabase>
namespace INX
{
Q_NAMESPACE
inline QString getNameFromLocation(const QString &str)
{
QString ret;
int index = 0;
for(int i = str.size() - 1; i >= 0; i--)
if(str[i] == '/')
{
index = i + 1;
i = -1;
}
for(; index < str.size(); index++)
ret.push_back(str[index]);
return ret;
}
const QString PicturesPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
const QString DownloadsPath = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
const QString DocumentsPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
const QString HomePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
const QString MusicPath = QStandardPaths::writableLocation(QStandardPaths::MusicLocation);
const QString VideosPath = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
const QString DesktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
const QStringList defaultPaths = {HomePath, DocumentsPath, MusicPath, VideosPath,PicturesPath, DownloadsPath, DesktopPath};
const QMap<QString, QString> folderIcon
{
{PicturesPath, "folder-pictures"},
{DownloadsPath, "folder-download"},
{DocumentsPath, "folder-documents"},
{HomePath, "user-home"},
{MusicPath, "folder-music"},
{VideosPath, "folder-videos"},
{DesktopPath, "user-desktop"}
};
inline QString getIconName(const QString &path)
{
if(QFileInfo(path).isDir())
{
if(folderIcon.contains(path))
return folderIcon[path];
else return "folder";
}else
{
QMimeDatabase mime;
auto type = mime.mimeTypeForFile(path);
qDebug()<< type.genericIconName();
return type.iconName();
}
return "text-css";
}
const QString SettingPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)+"/pix/";
const QString CachePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)+"/pix/";
const QString NotifyDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
const QString App = "Index";
const QString version = "1.0";
inline QString ucfirst(const QString &str)/*uppercase first letter*/
{
if (str.isEmpty()) return "";
QStringList tokens;
QStringList result;
QString output;
if(str.contains(" "))
{
tokens = str.split(" ");
for(auto str : tokens)
{
str = str.toLower();
str[0] = str[0].toUpper();
result<<str;
}
output = result.join(" ");
}else output = str;
return output.simplified();
}
inline bool fileExists(const QString &url)
{
QFileInfo path(url);
if (path.exists()) return true;
else return false;
}
inline void saveSettings(const QString &key, const QVariant &value, const QString &group)
{
QSettings setting("Babe","babe");
setting.beginGroup(group);
setting.setValue(key,value);
setting.endGroup();
}
inline QVariant loadSettings(const QString &key, const QString &group, const QVariant &defaultValue)
{
QVariant variant;
QSettings setting("Babe","babe");
setting.beginGroup(group);
variant = setting.value(key,defaultValue);
setting.endGroup();
return variant;
}
inline bool isMobile()
{
#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 true;
#elif defined(Q_OS_HAIKU)
return false;
#endif
}
}
#endif // INX_H
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickStyle>
#include <QIcon>
#include <QCommandLineParser>
#include <QFileInfo>
#include <QDebug>
#include <index.h>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
Index index;
QQmlApplicationEngine engine;
auto context = engine.rootContext();
context->setContextProperty("inx", &index);
QStringList importPathList = engine.importPathList();
qDebug()<< QCoreApplication::applicationDirPath() + "/qmltermwidget";
importPathList.prepend(QCoreApplication::applicationDirPath() + "/qmltermwidget");
engine.setImportPathList(importPathList);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.0 as Kirigami
import "widgets"
import "widgets/views"
import "widgets/sidebar"
import "widgets_templates"
import "Index.js" as INX
Kirigami.ApplicationWindow
{
id: root
visible: true
width: 640
height: 480
title: qsTr("Index")
property int sidebarWidth: Kirigami.Units.gridUnit * 11
pageStack.defaultColumnWidth: sidebarWidth
pageStack.initialPage: [placesSidebar, browser]
pageStack.interactive: isMobile
pageStack.separatorVisible: pageStack.wideMode
readonly property bool isMobile : Kirigami.Settings.isMobile
readonly property int contentMargins: isMobile ? 8 : 10
readonly property int defaultFontSize: Kirigami.Theme.defaultFont.pointSize
readonly property var fontSizes: ({
tiny: defaultFontSize - 2,
small: defaultFontSize -1,
default: defaultFontSize,
big: defaultFontSize + 1,
large: defaultFontSize + 2
})
property string backgroundColor: Kirigami.Theme.backgroundColor
property string textColor: Kirigami.Theme.textColor
property string highlightColor: Kirigami.Theme.highlightColor
property string highlightedTextColor: Kirigami.Theme.highlightedTextColor
property string buttonBackgroundColor: Kirigami.Theme.buttonBackgroundColor
property string viewBackgroundColor: Kirigami.Theme.viewBackgroundColor
property string altColor: Kirigami.Theme.complementaryBackgroundColor
property var iconSizes : ({
small : 16,
medium : 22,
large: 48,
})
property int iconSize : iconSizes.medium
property int rowHeight : 32
overlay.modal: Rectangle {
color: isMobile ? darkColor : "transparent"
opacity: 0.5
height: root.height
}
overlay.modeless: Rectangle {
color: "transparent"
}
header: IndexToolbar
{
id: mainHeader
}
PlacesSidebar
{
id: placesSidebar
anchors.fill: parent
onPlaceClicked: browser.openFolder(path)
}
Browser
{
id: browser
anchors.fill: parent
Component.onCompleted:
{
browser.openFolder(inx.homePath())
}
}
ItemMenu
{
id: itemMenu
onBookmarkClicked: INX.bookmarkFolder(path)
}
}
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>widgets/IndexToolbar.qml</file>
<file>widgets/views/icons/IconsView.qml</file>
<file>widgets_templates/IndexPage.qml</file>
<file>widgets_templates/IndexListDelegate.qml</file>
<file>widgets_templates/IndexList.qml</file>
<file>widgets_templates/IndexIconDelegate.qml</file>
<file>widgets_templates/IndexGrid.qml</file>
<file>widgets_templates/IndexButton.qml</file>
<file>widgets/sidebar/SidebarDelegate.qml</file>
<file>widgets/sidebar/PlacesSidebar.qml</file>
<file>widgets_templates/IndexDelegate.qml</file>
<file>widgets/views/Browser.qml</file>
<file>widgets/views/BrowserFooter.qml</file>
<file>widgets_templates/ItemMenu.qml</file>
<file>Index.js</file>
<file>widgets/views/PathBar.qml</file>
<file>widgets/views/PathBarDelegate.qml</file>
<file>widgets/terminal/Terminal.qml</file>
</qresource>
</RCC>
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import "../widgets_templates"
import "views"
ToolBar
{
position: ToolBar.Header
property alias pathBar : pathBar
property string accentColor : highlightColor
signal searchClicked()
signal menuClicked()
id: pixBar
RowLayout
{
anchors.fill: parent
Item
{
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumWidth: 44
IndexButton
{
anchors.centerIn: parent
iconName: "application-menu"
onClicked: menuClicked()
// iconColor: globalDrawer.visible ? accentColor : textColor
hoverEnabled: !isMobile
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: qsTr("Menu")
}
}
Item { Layout.fillWidth: true; Layout.maximumWidth: parent.width*0.05 }
PathBar
{
id: pathBar
Layout.fillWidth: true
}
Item { Layout.fillWidth: true; Layout.maximumWidth: parent.width*0.05 }
Item
{
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumWidth: 44
IndexButton
{
id: searchView
anchors.centerIn: parent
// iconColor: currentIndex === views.search? accentColor : textColor
iconName: "edit-find"
onClicked: searchClicked()
hoverEnabled: !isMobile
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: qsTr("Search")
}
}
}
}
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import "../../widgets_templates"
ColumnLayout
{
property alias placesList : placesList
signal placeClicked (string path)
focus: true
ListView
{
id: placesList
clip: true
Layout.fillHeight: true
Layout.fillWidth: true
keyNavigationEnabled: true
highlight: Rectangle
{
width: placesList.width
height: placesList.currentItem.height
color: highlightColor
}
focus: true
interactive: true
highlightFollowsCurrentItem: true
highlightMoveDuration: 0
snapMode: ListView.SnapToItem
section.property : "type"
section.criteria: ViewSection.FullString
section.delegate: IndexDelegate
{
id: delegate
label: section
isSection: true
boldLabel: true
height: mainHeader.height
}
model: ListModel
{}
delegate: SidebarDelegate
{
id: placeDelegate
Connections
{
target: placeDelegate
onClicked:
{
placesList.currentIndex = index
placeClicked(placesList.model.get(index).path)
}
}
}
}
Component.onCompleted: populate()
function populate()
{
clear()
var places = inx.getDefaultPaths()
places.push(inx.getBookmarks())
places.push(inx.getDevices())
if(places.length > 0)
for(var i in places)
placesList.model.append(places[i])
}
function clear()
{
placesList.model.clear()
}
}