diff --git a/CMakeLists.txt b/CMakeLists.txt index 379dccc..bf0c642 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,356 +1,361 @@ cmake_minimum_required(VERSION 3.0) set(REQUIRED_QT_VERSION 5.8.0) set(CMAKE_CXX_STANDARD 17) set(MAUIKIT_VERSION 0.0.5) set(CMAKE_AUTOMOC ON) set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.maui) set(CMAKE_INCLUDE_CURRENT_DIR ON) project(mauikit VERSION ${MAUIKIT_VERSION}) find_package(ECM 5.45.0 NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) include(ECMPoQmTools) include(ECMQMLModules) include(KDEInstallDirs) include(KDECMakeSettings) include(ECMQtDeclareLoggingCategory) include(ECMAddQch) include(KDECompilerSettings NO_POLICY_SCOPE) #options - for the appimage find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Qml Sql Core Quick Gui Svg QuickControls2 Network DBus Xml) ecm_find_qmlmodule(QtGraphicalEffects 1.0) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/utils ${CMAKE_CURRENT_BINARY_DIR}/src/utils ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/model_template ${CMAKE_CURRENT_BINARY_DIR}/src/utils/model_template ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/tagging ${CMAKE_CURRENT_BINARY_DIR}/src/utils/tagging ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/editor ${CMAKE_CURRENT_BINARY_DIR}/src/utils/editor ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing ${CMAKE_CURRENT_BINARY_DIR}/src/utils/syncing ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/store ${CMAKE_CURRENT_BINARY_DIR}/src/utils/store ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing/libwebdavclient/lib ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing/libwebdavclient/lib/utils ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing/libwebdavclient/lib/dto ${CMAKE_CURRENT_SOURCE_DIR}/src/fm ${CMAKE_CURRENT_BINARY_DIR}/src/fm ${CMAKE_CURRENT_SOURCE_DIR}/src/kde ${CMAKE_CURRENT_BINARY_DIR}/src/kde ) set(mauikit_SRCS src/mauikit.cpp src/utils/mauiapp.cpp src/utils/mauiaccounts.cpp src/utils/handy.cpp src/utils/model_template/mauilist.cpp src/utils/model_template/mauimodel.cpp ) set(mauikit_HDRS src/mauikit.h src/utils.h src/utils/handy.h src/utils/mauiapp.h src/utils/mauiaccounts.h src/utils/model_template/mauilist.h src/utils/model_template/mauimodel.h ) set(editor_SRCS src/utils/editor/documenthandler.cpp + src/utils/editor/syntaxhighlighterutil.cpp ) set(editor_HDRS src/utils/editor/documenthandler.cpp + src/utils/editor/syntaxhighlighterutil.h ) set(fm_SRCS src/fm/fm.cpp src/fm/fmdb.cpp src/fm/fmlist.cpp src/fm/placeslist.cpp src/fm/pathlist.cpp ) set(fm_HDRS src/fm/fmh.h src/fm/fm.h src/fm/fmdb.h src/fm/fmlist.h src/fm/placeslist.h src/fm/pathlist.h ) set(tagging_SRCS src/utils/tagging/tagging.cpp src/utils/tagging/tagdb.cpp src/utils/tagging/tagsmodel.cpp src/utils/tagging/tagslist.cpp ) set(tagging_HDRS src/utils/tagging/tag.h src/utils/tagging/tagging.h src/utils/tagging/tagdb.h src/utils/tagging/tagsmodel.h src/utils/tagging/tagslist.h ) set(syncing_SRCS src/utils/syncing/syncing.cpp src/utils/syncing/libwebdavclient/lib/WebDAVClient.cpp src/utils/syncing/libwebdavclient/lib/dto/WebDAVItem.cpp src/utils/syncing/libwebdavclient/lib/utils/Environment.cpp src/utils/syncing/libwebdavclient/lib/utils/NetworkHelper.cpp src/utils/syncing/libwebdavclient/lib/utils/WebDAVReply.cpp src/utils/syncing/libwebdavclient/lib/utils/XMLHelper.cpp ) set(syncing_HDRS src/utils/syncing/syncing.h src/utils/syncing/libwebdavclient/lib/WebDAVClient.hpp src/utils/syncing/libwebdavclient/lib/dto/WebDAVItem.hpp src/utils/syncing/libwebdavclient/lib/utils/Environment.hpp src/utils/syncing/libwebdavclient/lib/utils/NetworkHelper.hpp src/utils/syncing/libwebdavclient/lib/utils/WebDAVReply.hpp src/utils/syncing/libwebdavclient/lib/utils/XMLHelper.hpp ) set(store_SRCS src/utils/store/store.cpp src/utils/store/storemodel.cpp src/utils/store/storelist.cpp ) set(store_HDRS src/utils/store/store.h src/utils/store/storemodel.h src/utils/store/storelist.h ) #use dbus on linux, bsd etc, but not andoid and apple stuff option(IS_APPIMAGE_PACKAGE "If set to true then the icons and styled is packaged as well") if(ANDROID OR IS_APPIMAGE_PACKAGE) qt5_add_resources(MauiIcon_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/android/icons.qrc) qt5_add_resources(MauiStyle_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/maui-style/style.qrc) if (NOT EXISTS ${CMAKE_SOURCE_DIR}/src/android/icons/luv-icon-theme/.git) find_package(Git REQUIRED) execute_process(COMMAND ${GIT_EXECUTABLE} clone --depth 1 https://github.com/Nitrux/luv-icon-theme.git ${CMAKE_SOURCE_DIR}/src/android/icons/luv-icon-theme) endif() set(mauikit_style_QRCS ${MauiIcon_RESOURCES} ${MauiStyle_RESOURCES} ) endif() if(ANDROID) find_package(Qt5 REQUIRED COMPONENTS AndroidExtras Xml WebView Network) set(MAUIANDROID_LIBS Qt5::Xml Qt5::AndroidExtras Qt5::Network Qt5::WebView ) set(mauikit_Android_SRCS src/android/mauiandroid.cpp ) else() find_package(Qt5 REQUIRED COMPONENTS WebEngine) find_package(KF5 ${KF5_VERSION} REQUIRED COMPONENTS I18n Notifications - Config Service KIO ConfigWidgets Attica) + Config Service KIO ConfigWidgets Attica SyntaxHighlighting) + find_package(/usr/lib/x86_64-linux-gnu/qt5/qml/org/kde/kquicksyntaxhighlighter/libkquicksyntaxhighlighterplugin.so) set(mauikit_KDE_SRCS src/kde/mauikde.cpp src/kde/kdeconnect.cpp ) set(mauikit_KDE_HDRS src/kde/mauikde.h src/kde/kdeconnect.h ) set(MAUIKDE_KF5LIBS KF5::ConfigCore KF5::Notifications KF5::I18n KF5::Service KF5::KIOCore KF5::KIOWidgets KF5::KIOFileWidgets KF5::Service KF5::KIONTLM KF5::ConfigWidgets KF5::Attica + KF5::SyntaxHighlighting Qt5::WebEngine + /usr/lib/x86_64-linux-gnu/qt5/qml/org/kde/kquicksyntaxhighlighter/libkquicksyntaxhighlighterplugin.so ) endif() # set(CMAKE_AUTORCC ON) qt5_add_resources(mauikit_ASSETS ${CMAKE_CURRENT_SOURCE_DIR}/assets.qrc) qt5_add_resources(tagging_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/tagging/tagging.qrc) qt5_add_resources(fm_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/fm/fm.qrc) qt5_add_resources(store_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/store/store.qrc) # qt5_add_resources(mauikit_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mauikit.qrc) add_library(MauiKit ${fm_HDRS} ${fm_SRCS} ${fm_RESOURCES} ${editor_HDRS} ${editor_SRCS} ${syncing_HDRS} ${syncing_SRCS} ${store_SRCS} ${store_HDRS} ${store_RESOURCES} ${tagging_HDRS} ${tagging_SRCS} ${tagging_RESOURCES} ${mauikit_HDRS} ${mauikit_SRCS} ${mauikit_RESOURCES} ${mauikit_ASSETS} ${MauiIcon_RESOURCES} ${MauiStyle_RESOURCES} ${mauikit_Android_SRCS} ${mauikit_KDE_HDRS} ${mauikit_KDE_SRCS} ) target_link_libraries(MauiKit PUBLIC Qt5::Core Qt5::Sql Qt5::Qml Qt5::Quick Qt5::QuickControls2 Qt5::Svg Qt5::Gui Qt5::Network Qt5::Xml ${MAUIKDE_KF5LIBS} ${MAUIANDROID_LIBS} # # webdavclient ) if(IS_APPIMAGE_PACKAGE) target_compile_definitions(MauiKit PUBLIC APPIMAGE_PACKAGE) endif() if (ANDROID) kde_enable_exceptions(MauiKit PRIVATE) target_include_directories(MauiKit PRIVATE src/android) install(FILES src/android/mauiandroid.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/MauiKit COMPONENT Devel) install(DIRECTORY src/android/ DESTINATION ${KDE_INSTALL_DATAROOTDIR}/MauiKitAndroid COMPONENT Devel) endif() generate_export_header(MauiKit BASE_NAME MauiKit) install(TARGETS MauiKit EXPORT MauiKitTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) target_include_directories(MauiKit INTERFACE "$") add_custom_target(copy) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/mauikit) add_custom_command(TARGET copy PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/controls ${CMAKE_BINARY_DIR}/bin/org/kde/mauikit/) add_dependencies(MauiKit copy) install(DIRECTORY src/controls/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/mauikit) install(TARGETS MauiKit DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/mauikit) install(FILES ${mauikit_HDRS} ${mauikit_KDE_HDRS} ${tagging_HDRS} ${fm_HDRS} ${syncing_HDRS} ${store_HDRS} ${CMAKE_CURRENT_BINARY_DIR}/mauikit_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/MauiKit COMPONENT Devel) ##INSTALL MAUI STYLE install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/maui-style DESTINATION ${KDE_INSTALL_QMLDIR}/QtQuick/Controls.2) ##CMAKE PARTS set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/MauiKit") ecm_setup_version(${MAUIKIT_VERSION} VARIABLE_PREFIX MAUIKIT VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/mauikit_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfigVersion.cmake" SOVERSION 5 ) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/MauiKitConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} PATH_VARS KF5_INCLUDE_INSTALL_DIR CMAKE_INSTALL_PREFIX ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT MauiKitTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE MauiKitTargets.cmake ) diff --git a/src/controls/Editor.qml b/src/controls/Editor.qml index 42e2e2a..0c56eab 100644 --- a/src/controls/Editor.qml +++ b/src/controls/Editor.qml @@ -1,241 +1,275 @@ import QtQuick 2.9 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import org.kde.mauikit 1.0 as Maui import org.kde.kirigami 2.6 as Kirigami +import org.kde.kquicksyntaxhighlighter 0.1 +import SyntaxHighlighterUtil 1.0 import DocumentHandler 1.0 import "private" Item { id: control property bool showLineCount : true property bool stickyHeadBar : true property alias body : body property alias document : document property alias scrollView: _scrollView property alias text: body.text property alias uppercase: document.uppercase property alias underline: document.underline property alias italic: document.italic property alias bold: document.bold property alias canRedo: body.canRedo - property alias headBar: _editorToolBar - - - DocumentHandler + property alias headBar: _editorToolBar + + DocumentHandler { id: document document: body.textDocument cursorPosition: body.cursorPosition selectionStart: body.selectionStart selectionEnd: body.selectionEnd // textColor: TODO // onLoaded: { // body.text = text // } onError: { body.text = message body.visible = true } onLoaded: { body.text = text + + var formatName = SyntaxHighlighterUtil.getLanguageNameFromFileName(document.fileName); + + for (var i=0; i * * 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; }); 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); } diff --git a/src/utils/editor/documenthandler.cpp b/src/utils/editor/documenthandler.cpp index 253d1e8..a703ab7 100644 --- a/src/utils/editor/documenthandler.cpp +++ b/src/utils/editor/documenthandler.cpp @@ -1,408 +1,408 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** 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 https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** BSD License Usage ** Alternatively, you may use this file under the terms of the BSD license ** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "documenthandler.h" #include #include #include #include #include #include #include #include #include #include #include DocumentHandler::DocumentHandler(QObject *parent) : QObject(parent) , m_document(nullptr) , m_cursorPosition(-1) , m_selectionStart(0) , m_selectionEnd(0) { } QQuickTextDocument *DocumentHandler::document() const { return m_document; } void DocumentHandler::setDocument(QQuickTextDocument *document) { if (document == m_document) return; m_document = document; emit documentChanged(); } int DocumentHandler::cursorPosition() const { return m_cursorPosition; } void DocumentHandler::setCursorPosition(int position) { if (position == m_cursorPosition) return; m_cursorPosition = position; reset(); emit cursorPositionChanged(); } int DocumentHandler::selectionStart() const { return m_selectionStart; } void DocumentHandler::setSelectionStart(int position) { if (position == m_selectionStart) return; m_selectionStart = position; emit selectionStartChanged(); } int DocumentHandler::selectionEnd() const { return m_selectionEnd; } void DocumentHandler::setSelectionEnd(int position) { if (position == m_selectionEnd) return; m_selectionEnd = position; emit selectionEndChanged(); } QString DocumentHandler::fontFamily() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return QString(); QTextCharFormat format = cursor.charFormat(); return format.font().family(); } void DocumentHandler::setFontFamily(const QString &family) { QTextCharFormat format; format.setFontFamily(family); mergeFormatOnWordOrSelection(format); emit fontFamilyChanged(); } QColor DocumentHandler::textColor() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return QColor(Qt::black); QTextCharFormat format = cursor.charFormat(); return format.foreground().color(); } void DocumentHandler::setTextColor(const QColor &color) { QTextCharFormat format; format.setForeground(QBrush(color)); mergeFormatOnWordOrSelection(format); emit textColorChanged(); } Qt::Alignment DocumentHandler::alignment() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return Qt::AlignLeft; return textCursor().blockFormat().alignment(); } void DocumentHandler::setAlignment(Qt::Alignment alignment) { QTextBlockFormat format; format.setAlignment(alignment); QTextCursor cursor = textCursor(); cursor.mergeBlockFormat(format); emit alignmentChanged(); } bool DocumentHandler::bold() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return false; return textCursor().charFormat().fontWeight() == QFont::Bold; } void DocumentHandler::setBold(bool bold) { QTextCharFormat format; format.setFontWeight(bold ? QFont::Bold : QFont::Normal); mergeFormatOnWordOrSelection(format); emit boldChanged(); } bool DocumentHandler::uppercase() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return false; return textCursor().charFormat().fontCapitalization() == QFont::AllUppercase; } void DocumentHandler::setUppercase(bool uppercase) { QTextCharFormat format; format.setFontCapitalization(uppercase ? QFont::AllUppercase : QFont::AllLowercase); mergeFormatOnWordOrSelection(format); emit uppercaseChanged(); } bool DocumentHandler::italic() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return false; return textCursor().charFormat().fontItalic(); } void DocumentHandler::setItalic(bool italic) { QTextCharFormat format; format.setFontItalic(italic); mergeFormatOnWordOrSelection(format); emit italicChanged(); } bool DocumentHandler::underline() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return false; return textCursor().charFormat().fontUnderline(); } void DocumentHandler::setUnderline(bool underline) { QTextCharFormat format; format.setFontUnderline(underline); mergeFormatOnWordOrSelection(format); emit underlineChanged(); } bool DocumentHandler::isRich() const { const QString filePath = fileUrl().fileName(); const bool isRtf = QFileInfo(filePath).suffix().contains(QLatin1String("rtf")); return isRtf; } int DocumentHandler::fontSize() const { QTextCursor cursor = textCursor(); if (cursor.isNull()) return 0; QTextCharFormat format = cursor.charFormat(); return format.font().pointSize(); } void DocumentHandler::setFontSize(int size) { if (size <= 0) return; QTextCursor cursor = textCursor(); if (cursor.isNull()) return; if (!cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); if (cursor.charFormat().property(QTextFormat::FontPointSize).toInt() == size) return; QTextCharFormat format; format.setFontPointSize(size); mergeFormatOnWordOrSelection(format); emit fontSizeChanged(); } QString DocumentHandler::fileName() const { const QString filePath = QQmlFile::urlToLocalFileOrQrc(m_fileUrl); const QString fileName = QFileInfo(filePath).fileName(); if (fileName.isEmpty()) return QStringLiteral("untitled.txt"); return fileName; } QString DocumentHandler::fileType() const { return QFileInfo(fileName()).suffix(); } QUrl DocumentHandler::fileUrl() const { return m_fileUrl; } void DocumentHandler::load(const QUrl &fileUrl) { qDebug()<< "TRYING TO LOAD FILE << " << fileUrl; if (fileUrl == m_fileUrl) return; QQmlEngine *engine = qmlEngine(this); if (!engine) { qWarning() << "load() called before DocumentHandler has QQmlEngine"; return; } const QUrl path = QQmlFileSelector::get(engine)->selector()->select(fileUrl); const QString fileName = QQmlFile::urlToLocalFileOrQrc(path); + + m_fileUrl = fileUrl; + emit fileUrlChanged(); if (QFile::exists(fileName)) { qDebug()<< "LOAD FILE EXISTS << "; QFile file(fileName); if (file.open(QFile::ReadOnly)) { qDebug()<< "LOAD FILE OPENDED << "; QByteArray data = file.readAll(); QTextCodec *codec = QTextCodec::codecForHtml(data); if (QTextDocument *doc = textDocument()) doc->setModified(false); emit loaded(codec->toUnicode(data)); reset(); } } - - m_fileUrl = fileUrl; - emit fileUrlChanged(); } void DocumentHandler::saveAs(const QUrl &fileUrl) { QTextDocument *doc = textDocument(); if (!doc) return; const QString filePath = fileUrl.toLocalFile(); const bool isHtml = QFileInfo(filePath).suffix().contains(QLatin1String("htm")); QFile file(filePath); if (!file.open(QFile::WriteOnly | QFile::Truncate | (isHtml ? QFile::NotOpen : QFile::Text))) { emit error(tr("Cannot save: ") + file.errorString()); return; } file.write((isHtml ? doc->toHtml() : doc->toPlainText()).toUtf8()); file.close(); if (fileUrl == m_fileUrl) return; m_fileUrl = fileUrl; emit fileUrlChanged(); } void DocumentHandler::reset() { emit fontFamilyChanged(); emit alignmentChanged(); emit boldChanged(); emit italicChanged(); emit underlineChanged(); emit fontSizeChanged(); emit textColorChanged(); } QTextCursor DocumentHandler::textCursor() const { QTextDocument *doc = textDocument(); if (!doc) return QTextCursor(); QTextCursor cursor = QTextCursor(doc); if (m_selectionStart != m_selectionEnd) { cursor.setPosition(m_selectionStart); cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); } else { cursor.setPosition(m_cursorPosition); } return cursor; } QTextDocument *DocumentHandler::textDocument() const { if (!m_document) return nullptr; return m_document->textDocument(); } void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { QTextCursor cursor = textCursor(); if (!cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); cursor.mergeCharFormat(format); } diff --git a/src/utils/editor/syntaxhighlighterutil.cpp b/src/utils/editor/syntaxhighlighterutil.cpp new file mode 100644 index 0000000..12fbdbf --- /dev/null +++ b/src/utils/editor/syntaxhighlighterutil.cpp @@ -0,0 +1,27 @@ +#include "syntaxhighlighterutil.h" + +#include +#include +#include +#include + +SyntaxHighlighterUtil::SyntaxHighlighterUtil() +{ + repo = new KSyntaxHighlighting::Repository(); +} + +QList SyntaxHighlighterUtil::getLanguageNameList() +{ + QList languages; + + for (KSyntaxHighlighting::Definition def : repo->definitions()) { + languages.append(def.name()); + } + + return languages; +} + +QString SyntaxHighlighterUtil::getLanguageNameFromFileName(QString fileName) +{ + return repo->definitionForFileName(fileName).name(); +} diff --git a/src/utils/editor/syntaxhighlighterutil.h b/src/utils/editor/syntaxhighlighterutil.h new file mode 100644 index 0000000..a62abb1 --- /dev/null +++ b/src/utils/editor/syntaxhighlighterutil.h @@ -0,0 +1,24 @@ +#ifndef SYNTAXHIGHLIGHTERUTIL_H +#define SYNTAXHIGHLIGHTERUTIL_H + +#include + +namespace KSyntaxHighlighting { + class Repository; +} + +class SyntaxHighlighterUtil: public QObject { + Q_OBJECT + + private: + KSyntaxHighlighting::Repository *repo = nullptr; + + public: + SyntaxHighlighterUtil(); + + public slots: + QList getLanguageNameList(); + QString getLanguageNameFromFileName(QString fileName); +}; + +#endif