Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d67a977c5 |
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#define APP_VERSION_MAJOR 0
|
#define APP_VERSION_MAJOR 0
|
||||||
#define APP_VERSION_MINOR 9
|
#define APP_VERSION_MINOR 9
|
||||||
#define APP_VERSION_SUFFIX 6
|
#define APP_VERSION_SUFFIX 8
|
||||||
|
|
||||||
//#ifdef TARGET_OSX
|
//#ifdef TARGET_OSX
|
||||||
#define ICONS ":/assets/images"
|
#define ICONS ":/assets/images"
|
||||||
|
|||||||
@ -187,5 +187,5 @@ void IV::Generate(QByteArray &buffer)
|
|||||||
{
|
{
|
||||||
uint8_t* data = (uint8_t*)buffer.data();
|
uint8_t* data = (uint8_t*)buffer.data();
|
||||||
for (int i=0; i<buffer.length(); i++)
|
for (int i=0; i<buffer.length(); i++)
|
||||||
data[i] = qrand() % 256;
|
data[i] = rand() % 256;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,7 +143,7 @@ void TaskSearch::run()
|
|||||||
if (mRequest.startsWith("\"") && mRequest.endsWith("\""))
|
if (mRequest.startsWith("\"") && mRequest.endsWith("\""))
|
||||||
sl.append(mRequest);
|
sl.append(mRequest);
|
||||||
else
|
else
|
||||||
sl = mRequest.split(" ", QString::SkipEmptyParts);
|
sl = mRequest.split(" ", Qt::SkipEmptyParts);
|
||||||
|
|
||||||
if (!sl.empty())
|
if (!sl.empty())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QFile>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
@ -208,22 +210,14 @@ time_t chrono::strToTime(const std::string& s)
|
|||||||
|
|
||||||
QString path::pathToSettings()
|
QString path::pathToSettings()
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
QString folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
QString folder = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
|
||||||
#else
|
|
||||||
QString folder = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
|
||||||
#endif
|
|
||||||
QString path = folder + "/" + SETTINGS_FILENAME;
|
QString path = folder + "/" + SETTINGS_FILENAME;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString path::pathToDatabase()
|
QString path::pathToDatabase()
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
QString folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
QString folder = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
|
||||||
#else
|
|
||||||
QString folder = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
|
||||||
#endif
|
|
||||||
QString path = folder + "/" + DATABASENAME;
|
QString path = folder + "/" + DATABASENAME;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@ -255,11 +249,7 @@ QString path::pathToDatabaseTemplate()
|
|||||||
|
|
||||||
QString path::pathToLog()
|
QString path::pathToLog()
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
QString folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
QString folder = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
|
||||||
#else
|
|
||||||
QString folder = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
|
||||||
#endif
|
|
||||||
return folder + "/" + LOGNAME;
|
return folder + "/" + LOGNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
# include "platforms/linux/autostart.h"
|
# include "platforms/linux/autostart.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QDesktopWidget>
|
// #include <QDesktopWidget>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ void MainWindow::connectUiToDatabase()
|
|||||||
|
|
||||||
// Load recent tasks
|
// Load recent tasks
|
||||||
QString recent = SETTINGS.data()[KEY_RECENT_TASKS].toString();
|
QString recent = SETTINGS.data()[KEY_RECENT_TASKS].toString();
|
||||||
QStringList recentList = recent.split(";", QString::SkipEmptyParts);
|
QStringList recentList = recent.split(";", Qt::SkipEmptyParts);
|
||||||
for (QString& s: recentList)
|
for (QString& s: recentList)
|
||||||
{
|
{
|
||||||
Task::Id id = s.toULongLong();
|
Task::Id id = s.toULongLong();
|
||||||
@ -1016,7 +1016,7 @@ void MainWindow::updateData()
|
|||||||
|
|
||||||
if (saveToDb)
|
if (saveToDb)
|
||||||
mLogger->log("Flushing timeline to DB start");
|
mLogger->log("Flushing timeline to DB start");
|
||||||
mCurrentTask->timeline()->flush(saveToDb, QDateTime::currentDateTimeUtc().toTime_t());
|
mCurrentTask->timeline()->flush(saveToDb, QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
||||||
if (saveToDb)
|
if (saveToDb)
|
||||||
{
|
{
|
||||||
mLastTimelineFlush = QDateTime::currentDateTimeUtc();
|
mLastTimelineFlush = QDateTime::currentDateTimeUtc();
|
||||||
@ -1191,9 +1191,9 @@ int MainWindow::showTrayWindow(QDialog* dlg)
|
|||||||
|
|
||||||
int w = dlg->geometry().width();
|
int w = dlg->geometry().width();
|
||||||
int h = dlg->geometry().height();
|
int h = dlg->geometry().height();
|
||||||
QRect rec = QApplication::desktop()->screenGeometry();
|
auto screen_size = QGuiApplication::primaryScreen()->size();
|
||||||
int desktopHeight = rec.height();
|
int desktopHeight = screen_size.height();
|
||||||
int desktopWidth = rec.width();
|
int desktopWidth = screen_size.width();
|
||||||
|
|
||||||
QRect iconRect;
|
QRect iconRect;
|
||||||
if (mTrayIcon)
|
if (mTrayIcon)
|
||||||
@ -1412,7 +1412,7 @@ void MainWindow::checkForUpdates()
|
|||||||
void MainWindow::systemSleep()
|
void MainWindow::systemSleep()
|
||||||
{
|
{
|
||||||
//qDebug() << "System goes to sleep";
|
//qDebug() << "System goes to sleep";
|
||||||
stopTracking(TSR_Automatic, QDateTime::currentDateTimeUtc().toTime_t());
|
stopTracking(TSR_Automatic, QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::systemResume()
|
void MainWindow::systemResume()
|
||||||
@ -1484,11 +1484,11 @@ void MainWindow::findRequested()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ui->mFindEdit->setVisible(false);
|
//ui->mFindEdit->setVisible(false);
|
||||||
QTextCursor c = ui->mNoteEdit->document()->find(pattern, mFindStartIndex, nullptr);
|
QTextCursor c = ui->mNoteEdit->document()->find(pattern, mFindStartIndex);
|
||||||
if (c.isNull())
|
if (c.isNull())
|
||||||
{
|
{
|
||||||
mFindStartIndex = 0;
|
mFindStartIndex = 0;
|
||||||
c = ui->mNoteEdit->document()->find(pattern, mFindStartIndex, nullptr);
|
c = ui->mNoteEdit->document()->find(pattern, mFindStartIndex);
|
||||||
}
|
}
|
||||||
if (!c.isNull())
|
if (!c.isNull())
|
||||||
{
|
{
|
||||||
@ -1575,7 +1575,7 @@ void MainWindow::continueOnIdle()
|
|||||||
void MainWindow::breakOnIdle(const QDateTime& stopTime)
|
void MainWindow::breakOnIdle(const QDateTime& stopTime)
|
||||||
{
|
{
|
||||||
// Stop tracking
|
// Stop tracking
|
||||||
stopTracking(TSR_Manual, stopTime.toUTC().toTime_t());
|
stopTracking(TSR_Manual, stopTime.toUTC().toSecsSinceEpoch());
|
||||||
showTimeForSelectedTask();
|
showTimeForSelectedTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,49 +1,106 @@
|
|||||||
cmake_minimum_required(VERSION 3.3)
|
cmake_minimum_required(VERSION 3.16) # Qt requires CMake 3.16
|
||||||
project(qmarkdowntextedit)
|
project(qmarkdowntextedit LANGUAGES CXX VERSION 1.0.0)
|
||||||
|
|
||||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
find_package( Qt5Core REQUIRED )
|
# add option to disable test executable
|
||||||
find_package( Qt5Widgets REQUIRED )
|
option(QMARKDOWNTEXTEDIT_EXE "Build test executable" ON)
|
||||||
find_package( Qt5Gui REQUIRED )
|
|
||||||
|
|
||||||
qt5_wrap_ui(ui_qplaintexteditsearchwidget.h qplaintexteditsearchwidget.ui)
|
# find qt
|
||||||
|
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} OPTIONAL_COMPONENTS Quick)
|
||||||
|
|
||||||
set(RESOURCE_FILES
|
# needed for windows
|
||||||
|
if(WIN32)
|
||||||
|
set(INTL_LDFLAGS -lintl)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
# QMarkdownTextEdit library
|
||||||
|
set(RC_FILES
|
||||||
media.qrc
|
media.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
qt5_add_resources(RESOURCE_ADDED ${RESOURCE_FILES})
|
# Translations arent loaded so don't include them
|
||||||
|
set(TS_FILES
|
||||||
|
trans/qmarkdowntextedit_de.ts
|
||||||
|
trans/qmarkdowntextedit_ur.ts
|
||||||
|
trans/qmarkdowntextedit_zh_CN.ts
|
||||||
|
)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(QMARKDOWNTEXTEDIT_SOURCES
|
||||||
|
${RC_FILES}
|
||||||
|
linenumberarea.h # We need to keep this here, otherwise the build fails
|
||||||
markdownhighlighter.cpp
|
markdownhighlighter.cpp
|
||||||
|
qmarkdowntextedit.cpp
|
||||||
|
qownlanguagedata.cpp
|
||||||
|
qownlanguagedata.h
|
||||||
|
qplaintexteditsearchwidget.cpp
|
||||||
|
qplaintexteditsearchwidget.ui
|
||||||
|
)
|
||||||
|
set(QMARKDOWNTEXTEDIT_HEADERS
|
||||||
markdownhighlighter.h
|
markdownhighlighter.h
|
||||||
|
qmarkdowntextedit.h
|
||||||
|
qplaintexteditsearchwidget.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(qmarkdowntextedit ${QMARKDOWNTEXTEDIT_SOURCES})
|
||||||
|
set_target_properties(qmarkdowntextedit PROPERTIES
|
||||||
|
PUBLIC_HEADER "${QMARKDOWNTEXTEDIT_HEADERS}"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(qmarkdowntextedit PUBLIC
|
||||||
|
Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
|
${INTL_LDFLAGS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (Qt${QT_VERSION_MAJOR}Quick_FOUND)
|
||||||
|
target_link_libraries(qmarkdowntextedit PUBLIC Qt${QT_VERSION_MAJOR}::Quick)
|
||||||
|
|
||||||
|
add_executable(QtQuickExample examples/qml/example.cpp examples/qml/ressources.qrc)
|
||||||
|
target_link_libraries(QtQuickExample PRIVATE Qt${QT_VERSION_MAJOR}::Quick qmarkdowntextedit)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# QMarkdownTextEdit executable
|
||||||
|
if(QMARKDOWNTEXTEDIT_EXE)
|
||||||
|
set(SOURCE_FILES
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
mainwindow.h
|
mainwindow.h
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
qmarkdowntextedit.cpp
|
|
||||||
qmarkdowntextedit.h
|
|
||||||
qplaintexteditsearchwidget.ui
|
|
||||||
qplaintexteditsearchwidget.cpp
|
|
||||||
qplaintexteditsearchwidget.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(qmarkdowntextedit ${SOURCE_FILES} ${RESOURCE_ADDED})
|
add_executable(qmarkdowntextedit-exe ${SOURCE_FILES})
|
||||||
|
set_target_properties(qmarkdowntextedit-exe PROPERTIES OUTPUT_NAME "qmarkdowntextedit")
|
||||||
|
target_link_libraries(qmarkdowntextedit-exe PRIVATE
|
||||||
|
Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
|
${INTL_LDFLAGS}
|
||||||
|
qmarkdowntextedit
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(${Qt5Widgets_INCLUDES})
|
include(GNUInstallDirs) # Doesn't fail on windows
|
||||||
|
|
||||||
# We need add -DQT_WIDGETS_LIB when using QtWidgets in Qt 5.
|
# Install the lib
|
||||||
add_definitions(${Qt5Widgets_DEFINITIONS})
|
install(TARGETS qmarkdowntextedit
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
|
)
|
||||||
|
|
||||||
# Executables fail to build with Qt 5 in the default configuration
|
# Add PkgConfig config file
|
||||||
# without -fPIE. We add that here.
|
configure_file(qmarkdowntextedit.pc.in ${CMAKE_BINARY_DIR}/qmarkdowntextedit.pc @ONLY)
|
||||||
set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
install(FILES ${CMAKE_BINARY_DIR}/qmarkdowntextedit.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
|
||||||
|
|
||||||
# The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore
|
# Install exe
|
||||||
target_link_libraries(qmarkdowntextedit Qt5::Widgets)
|
if(QMARKDOWNTEXTEDIT_EXE)
|
||||||
|
install(TARGETS qmarkdowntextedit-exe DESTINATION bin)
|
||||||
|
endif()
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
Copyright (c) 2014-2019 Patrizio Bekerle
|
Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|||||||
@ -1,33 +1,83 @@
|
|||||||
# [QMarkdownTextEdit](https://github.com/pbek/qmarkdowntextedit)
|
# [QMarkdownTextEdit](https://github.com/pbek/qmarkdowntextedit)
|
||||||
[](https://travis-ci.org/pbek/qmarkdowntextedit)
|
|
||||||
|
[](https://github.com/pbek/qmarkdowntextedit/actions)
|
||||||
|
[](https://travis-ci.org/pbek/qmarkdowntextedit)
|
||||||
[](https://ci.appveyor.com/project/pbek/qmarkdowntextedit)
|
[](https://ci.appveyor.com/project/pbek/qmarkdowntextedit)
|
||||||
|
|
||||||
QMarkdownTextEdit is a C++ Qt [QPlainTextEdit](http://doc.qt.io/qt-5/qtextplainedit.html) widget with [markdown](https://en.wikipedia.org/wiki/Markdown) highlighting and some other goodies.
|
QMarkdownTextEdit is a C++ Qt [QPlainTextEdit](http://doc.qt.io/qt-5/qplaintextedit.html) widget with [markdown](https://en.wikipedia.org/wiki/Markdown) highlighting and some other goodies.
|
||||||
|
|
||||||
## Features
|
## Widget Features
|
||||||
- markdown highlighting
|
|
||||||
- clickable links with `Ctrl + Click`
|
- Markdown highlighting
|
||||||
- block indent with `Tab` and `Shift + Tab`
|
- Code syntax highlighting
|
||||||
- duplicate text with `Ctrl + Alt + Down`
|
- Clickable links with `Ctrl + Click`
|
||||||
- searching of text with `Ctrl + F`
|
- Block indent with `Tab` and `Shift + Tab`
|
||||||
- jump between search results with `Up` and `Down`
|
- Duplicate text with `Ctrl + Alt + Down`
|
||||||
- close search field with `Escape`
|
- Searching of text with `Ctrl + F`
|
||||||
- replacing of text with `Ctrl + R`
|
- Jump between search results with `Up` and `Down`
|
||||||
- you can also replace text with regular expressions or whole words
|
- Close search field with `Escape`
|
||||||
- and much more...
|
- Replacing of text with `Ctrl + R`
|
||||||
|
- You can also replace text with regular expressions or whole words
|
||||||
|
- Line numbers (Qt >= 5.5)
|
||||||
|
- Very fast
|
||||||
|
- And much more...
|
||||||
|
|
||||||
|
## Supported Markdown Features
|
||||||
|
|
||||||
|
Commonmark compliance is enforced where possible however we are not fully Commonmark compliant yet. Following is a list of features/extensions supported by the highlighter. Please note that this is just a plaintext editor and as such, it only does the highlighting and not rendering of the markdown to HTML.
|
||||||
|
|
||||||
|
| Feature | Availablity |
|
||||||
|
| --------------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
||||||
|
| Bolds and Italics | Yes |
|
||||||
|
| Lists (Unordered/Orderered) | Yes |
|
||||||
|
| Links and Images<br/>(Inline/Reference/Autolinks/E-mail) | Yes (Cannot handle nested links or complex cases yet) |
|
||||||
|
| Heading (ATX and Setext) | Yes |
|
||||||
|
| Codeblocks (indented and fenced)<br/> Both backtick and tilde code fences are supported | Yes (Only fenced code block has syntax highlighting) |
|
||||||
|
| Inline code | Yes |
|
||||||
|
| Strikethrough | Yes |
|
||||||
|
| Underline | Yes (Optional) |
|
||||||
|
| Blockquotes | Yes |
|
||||||
|
| Table | Yes |
|
||||||
|
|
||||||
## Screenshot
|
## Screenshot
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## How to use this widget
|
## Usage
|
||||||
- include [qmarkdowntextedit.pri](https://github.com/pbek/qmarkdowntextedit/blob/develop/qmarkdowntextedit.pri)
|
|
||||||
|
There are multiple ways to use this. You can use the editor directly, or you can subclass it or you can just use the highlighter.
|
||||||
|
|
||||||
|
### Using the editor
|
||||||
|
|
||||||
|
#### QMake
|
||||||
|
|
||||||
|
- Include [qmarkdowntextedit.pri](https://github.com/pbek/qmarkdowntextedit/blob/main/qmarkdowntextedit.pri)
|
||||||
to your project like this `include (qmarkdowntextedit/qmarkdowntextedit.pri)`
|
to your project like this `include (qmarkdowntextedit/qmarkdowntextedit.pri)`
|
||||||
- add a normal `QPlainTextEdit` to your UI and promote it to `QMarkdownTextEdit` (base class `QPlainTextEdit`)
|
- add a normal `QPlainTextEdit` to your UI and promote it to `QMarkdownTextEdit` (base class `QPlainTextEdit`)
|
||||||
|
|
||||||
## References
|
#### CMake
|
||||||
- [QOwnNotes - cross-platform open source plain-text file notepad](http://www.qownnotes.org)
|
|
||||||
|
- Include [CMakeLists.txt](https://github.com/pbek/qmarkdowntextedit/blob/main/CMakeLists.txt)
|
||||||
|
to your project like this `add_subdirectory(qmarkdowntextedit)`
|
||||||
|
- add a normal `QPlainTextEdit` to your UI and promote it to `QMarkdownTextEdit` (base class `QPlainTextEdit`)
|
||||||
|
|
||||||
|
### Using the highlighter only
|
||||||
|
|
||||||
|
Highlighter can work with both `QPlainTextEdit` and `QTextEdit`. Example:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto doc = ui->plainTextEdit->document();
|
||||||
|
auto *highlighter = new MarkdownHighlighter(doc);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Projects using QMarkdownTextEdit
|
||||||
|
|
||||||
|
- [QOwnNotes](https://github.com/pbek/QOwnNotes)
|
||||||
|
- [Notes](https://github.com/nuttyartist/notes)
|
||||||
|
- [CuteMarkEd-NG](https://github.com/Waqar144/CuteMarkEd-NG)
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
This SOFTWARE PRODUCT is provided by THE PROVIDER "as is" and "with all faults." THE PROVIDER makes no representations or warranties of any kind concerning the safety, suitability, lack of viruses, inaccuracies, typographical errors, or other harmful components of this SOFTWARE PRODUCT.
|
This SOFTWARE PRODUCT is provided by THE PROVIDER "as is" and "with all faults." THE PROVIDER makes no representations or warranties of any kind concerning the safety, suitability, lack of viruses, inaccuracies, typographical errors, or other harmful components of this SOFTWARE PRODUCT.
|
||||||
|
|
||||||
There are inherent dangers in the use of any software, and you are solely responsible for determining whether this SOFTWARE PRODUCT is compatible with your equipment and other software installed on your equipment. You are also solely responsible for the protection of your equipment and backup of your data, and THE PROVIDER will not be liable for any damages you may suffer in connection with using, modifying, or distributing this SOFTWARE PRODUCT.
|
There are inherent dangers in the use of any software, and you are solely responsible for determining whether this SOFTWARE PRODUCT is compatible with your equipment and other software installed on your equipment. You are also solely responsible for the protection of your equipment and backup of your data, and THE PROVIDER will not be liable for any damages you may suffer in connection with using, modifying, or distributing this SOFTWARE PRODUCT.
|
||||||
|
|||||||
24
client/qmarkdowntextedit/examples/qml/example.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
|
#include "markdownhighlighter.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
qmlRegisterType<MarkdownHighlighter>("MarkdownHighlighter", 1, 0,
|
||||||
|
"MarkdownHighlighter");
|
||||||
|
|
||||||
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
const QUrl url(QStringLiteral("qrc:/example.qml"));
|
||||||
|
QObject::connect(
|
||||||
|
&engine, &QQmlApplicationEngine::objectCreated, &app,
|
||||||
|
[url](QObject *obj, const QUrl &objUrl) {
|
||||||
|
if (!obj && url == objUrl) QCoreApplication::exit(-1);
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
engine.load(url);
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
22
client/qmarkdowntextedit/examples/qml/example.qml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Window 2.0
|
||||||
|
import MarkdownHighlighter 1.0
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: mainwindow
|
||||||
|
width: 640
|
||||||
|
height: 400
|
||||||
|
visible: true
|
||||||
|
title: qsTr("QtQuick Project")
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
id: editor
|
||||||
|
text: "# Hello world!"
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MarkdownHighlighter {
|
||||||
|
id: syntaxHighlighter
|
||||||
|
textDocument: editor.textDocument
|
||||||
|
}
|
||||||
|
}
|
||||||
5
client/qmarkdowntextedit/examples/qml/ressources.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>example.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
22
client/qmarkdowntextedit/justfile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Use `just <recipe>` to run a recipe
|
||||||
|
# https://just.systems/man/en/
|
||||||
|
|
||||||
|
# By default, run the `--list` command
|
||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
|
# Aliases
|
||||||
|
|
||||||
|
alias fmt := format
|
||||||
|
|
||||||
|
# Format all files
|
||||||
|
[group('linter')]
|
||||||
|
format:
|
||||||
|
nix-shell -p treefmt libclang nodePackages.prettier shfmt nixfmt-rfc-style taplo --run treefmt
|
||||||
|
|
||||||
|
# Add git commit hashes to the .git-blame-ignore-revs file
|
||||||
|
[group('linter')]
|
||||||
|
add-git-blame-ignore-revs:
|
||||||
|
git log --pretty=format:"%H" --grep="^lint" >> .git-blame-ignore-revs
|
||||||
|
sort .git-blame-ignore-revs | uniq > .git-blame-ignore-revs.tmp
|
||||||
|
mv .git-blame-ignore-revs.tmp .git-blame-ignore-revs
|
||||||
112
client/qmarkdowntextedit/linenumberarea.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#ifndef LINENUMBERAREA_H
|
||||||
|
#define LINENUMBERAREA_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "qmarkdowntextedit.h"
|
||||||
|
|
||||||
|
class LineNumArea final : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LineNumArea(QMarkdownTextEdit *parent)
|
||||||
|
: QWidget(parent), textEdit(parent) {
|
||||||
|
Q_ASSERT(parent);
|
||||||
|
|
||||||
|
_currentLineColor = QColor(QStringLiteral("#eef067"));
|
||||||
|
_otherLinesColor = QColor(QStringLiteral("#a6a6a6"));
|
||||||
|
setHidden(true);
|
||||||
|
|
||||||
|
// We always use fixed font to avoid "width" issues
|
||||||
|
setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCurrentLineColor(QColor color) { _currentLineColor = color; }
|
||||||
|
|
||||||
|
void setOtherLineColor(QColor color) {
|
||||||
|
_otherLinesColor = std::move(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lineNumAreaWidth() const {
|
||||||
|
if (!enabled) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int digits = 2;
|
||||||
|
int max = std::max(1, textEdit->blockCount());
|
||||||
|
while (max >= 10) {
|
||||||
|
max /= 10;
|
||||||
|
++digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050B00
|
||||||
|
int space =
|
||||||
|
13 + textEdit->fontMetrics().horizontalAdvance(u'9') * digits;
|
||||||
|
#else
|
||||||
|
int space =
|
||||||
|
13 + textEdit->fontMetrics().width(QLatin1Char('9')) * digits;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineNumAreaEnabled() const { return enabled; }
|
||||||
|
|
||||||
|
void setLineNumAreaEnabled(bool e) {
|
||||||
|
enabled = e;
|
||||||
|
setHidden(!e);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize sizeHint() const override { return {lineNumAreaWidth(), 0}; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event) override {
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
painter.fillRect(event->rect(),
|
||||||
|
palette().color(QPalette::Active, QPalette::Window));
|
||||||
|
|
||||||
|
auto block = textEdit->firstVisibleBlock();
|
||||||
|
int blockNumber = block.blockNumber();
|
||||||
|
qreal top = textEdit->blockBoundingGeometry(block)
|
||||||
|
.translated(textEdit->contentOffset())
|
||||||
|
.top();
|
||||||
|
// Maybe the top is not 0?
|
||||||
|
top += textEdit->viewportMargins().top();
|
||||||
|
qreal bottom = top;
|
||||||
|
|
||||||
|
const QPen currentLine = _currentLineColor;
|
||||||
|
const QPen otherLines = _otherLinesColor;
|
||||||
|
painter.setFont(font());
|
||||||
|
|
||||||
|
while (block.isValid() && top <= event->rect().bottom()) {
|
||||||
|
top = bottom;
|
||||||
|
bottom = top + textEdit->blockBoundingRect(block).height();
|
||||||
|
if (block.isVisible() && bottom >= event->rect().top()) {
|
||||||
|
QString number = QString::number(blockNumber + 1);
|
||||||
|
|
||||||
|
auto isCurrentLine =
|
||||||
|
textEdit->textCursor().blockNumber() == blockNumber;
|
||||||
|
painter.setPen(isCurrentLine ? currentLine : otherLines);
|
||||||
|
|
||||||
|
painter.drawText(-5, top, sizeHint().width(),
|
||||||
|
textEdit->fontMetrics().height(),
|
||||||
|
Qt::AlignRight, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
block = block.next();
|
||||||
|
++blockNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool enabled = false;
|
||||||
|
QMarkdownTextEdit *textEdit;
|
||||||
|
QColor _currentLineColor;
|
||||||
|
QColor _otherLinesColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LINENUMBERAREA_H
|
||||||
@ -1,41 +1,35 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
#include "mainwindow.h"
|
||||||
{
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
QString filename;
|
|
||||||
if (argc > 1) {
|
|
||||||
filename = argv[1];
|
|
||||||
}
|
|
||||||
if (!filename.isEmpty() && !QFileInfo(filename).isReadable()) {
|
|
||||||
qWarning() << filename << "is not a readable file";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
if (!filename.isEmpty()) {
|
|
||||||
w.loadFile(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
* mainwindow.cpp
|
* mainwindow.cpp
|
||||||
*
|
*
|
||||||
@ -16,103 +27,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include "qmarkdowntextedit.h"
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
QMainWindow(parent),
|
: QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||||
ui(new Ui::MainWindow)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
QToolBar *toolBar = new QToolBar;
|
|
||||||
addToolBar(toolBar);
|
|
||||||
QAction *openAction = new QAction(QIcon::fromTheme("document-open"), tr("Open..."));
|
|
||||||
openAction->setShortcut(QKeySequence::Open);
|
|
||||||
connect(openAction, &QAction::triggered, this, &MainWindow::open);
|
|
||||||
|
|
||||||
QAction *saveAction = new QAction(QIcon::fromTheme("document-save"), tr("Save"));
|
|
||||||
saveAction->setShortcut(QKeySequence::Save);
|
|
||||||
QAction *saveAsAction = new QAction(QIcon::fromTheme("document-save-as"), tr("Save as..."));
|
|
||||||
saveAsAction->setShortcut(QKeySequence::SaveAs);
|
|
||||||
QAction *quitAction = new QAction(QIcon::fromTheme("view-close"), tr("Quit"));
|
|
||||||
quitAction->setShortcut(QKeySequence::Quit);
|
|
||||||
connect(quitAction, &QAction::triggered, this, &MainWindow::onQuit);
|
|
||||||
|
|
||||||
m_loadedContent = ui->textEdit->toPlainText();
|
|
||||||
|
|
||||||
toolBar->addActions({openAction, saveAction, saveAsAction, quitAction});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow() { delete ui; }
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::loadFile(const QString &filename)
|
|
||||||
{
|
|
||||||
QFile file(filename);
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning() << "Failed to open" << filename;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_filename = filename;
|
|
||||||
m_loadedContent = QString::fromLocal8Bit(file.readAll());
|
|
||||||
ui->textEdit->setPlainText(m_loadedContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::saveToFile(const QString &filename)
|
|
||||||
{
|
|
||||||
QFile file(filename);
|
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
|
||||||
qWarning() << "Failed to open" << filename;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_filename = filename;
|
|
||||||
|
|
||||||
m_loadedContent = ui->textEdit->toPlainText();
|
|
||||||
file.write(m_loadedContent.toLocal8Bit());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::open()
|
|
||||||
{
|
|
||||||
QString filename = QFileDialog::getOpenFileName();
|
|
||||||
if (filename.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loadFile(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::save()
|
|
||||||
{
|
|
||||||
if (!m_filename.isEmpty()) {
|
|
||||||
saveAs();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveToFile(m_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::saveAs()
|
|
||||||
{
|
|
||||||
QString filename = QFileDialog::getSaveFileName();
|
|
||||||
if (filename.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveToFile(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onQuit()
|
|
||||||
{
|
|
||||||
if (ui->textEdit->toPlainText() != m_loadedContent) {
|
|
||||||
if (QMessageBox::question(this, tr("Not saved"), tr("Document not saved, sure you want to quit?")) != QMessageBox::Yes) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,15 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -20,25 +30,13 @@ namespace Ui {
|
|||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = nullptr);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
void loadFile(const QString &filename);
|
private:
|
||||||
void saveToFile(const QString &filename);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void open();
|
|
||||||
void save();
|
|
||||||
void saveAs();
|
|
||||||
void onQuit();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QString m_loadedContent;
|
|
||||||
QString m_filename;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- markdown highlighting
|
- markdown highlighting
|
||||||
|
- syntax highlighting
|
||||||
- clickable links with `Ctrl + Click`
|
- clickable links with `Ctrl + Click`
|
||||||
|
- ~strikedout~ text and `inline code;`
|
||||||
- block indent with `Tab` and `Shift + Tab`
|
- block indent with `Tab` and `Shift + Tab`
|
||||||
- duplicate text with `Ctrl + Alt + Down`
|
- duplicate text with `Ctrl + Alt + Down`
|
||||||
- searching of text with `Ctrl + F`
|
- searching of text with `Ctrl + F`
|
||||||
@ -36,7 +38,7 @@
|
|||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [QOwnNotes - cross-platform open source plain-text notepad](http://www.qownnotes.org)
|
- [QOwnNotes - cross-platform open source plain-text file markdown note taking](https://www.qownnotes.org)
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ There are inherent dangers in the use of any software, and you are solely respon
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1070</width>
|
<width>1070</width>
|
||||||
<height>25</height>
|
<height>23</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
@ -1,52 +1,127 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* QPlainTextEdit markdown highlighter
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* QPlainTextEdit Markdown highlighter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QTextCharFormat>
|
|
||||||
#include <QSyntaxHighlighter>
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QTextCharFormat>
|
||||||
|
|
||||||
|
#ifdef QT_QUICK_LIB
|
||||||
|
#include <QQuickTextDocument>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QTextDocument;
|
class QTextDocument;
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
class MarkdownHighlighter : public QSyntaxHighlighter
|
class MarkdownHighlighter : public QSyntaxHighlighter {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
#ifdef QT_QUICK_LIB
|
||||||
enum HighlightingOption{
|
Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument WRITE
|
||||||
|
setTextDocument NOTIFY textDocumentChanged)
|
||||||
|
|
||||||
|
QQuickTextDocument *m_quickDocument = nullptr;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void textDocumentChanged();
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline QQuickTextDocument *textDocument() const { return m_quickDocument; };
|
||||||
|
void setTextDocument(QQuickTextDocument *textDocument) {
|
||||||
|
if (!textDocument) return;
|
||||||
|
m_quickDocument = textDocument;
|
||||||
|
setDocument(m_quickDocument->textDocument());
|
||||||
|
Q_EMIT textDocumentChanged();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum HighlightingOption {
|
||||||
None = 0,
|
None = 0,
|
||||||
FullyHighlightedBlockQuote = 0x01
|
FullyHighlightedBlockQuote = 0x01,
|
||||||
|
Underline = 0x02
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(HighlightingOptions, HighlightingOption)
|
Q_DECLARE_FLAGS(HighlightingOptions, HighlightingOption)
|
||||||
|
|
||||||
MarkdownHighlighter(QTextDocument *parent = nullptr,
|
MarkdownHighlighter(
|
||||||
HighlightingOptions highlightingOptions =
|
QTextDocument *parent = nullptr,
|
||||||
HighlightingOption::None);
|
HighlightingOptions highlightingOptions = HighlightingOption::None);
|
||||||
|
|
||||||
// we use some predefined numbers here to be compatible with
|
static inline QColor codeBlockBackgroundColor() {
|
||||||
// the peg-markdown parser
|
const QBrush brush = _formats[CodeBlock].background();
|
||||||
|
|
||||||
|
if (!brush.isOpaque()) {
|
||||||
|
return QColor(Qt::transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return brush.color();
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr inline bool isOctal(const char c) {
|
||||||
|
return (c >= '0' && c <= '7');
|
||||||
|
}
|
||||||
|
static constexpr inline bool isHex(const char c) {
|
||||||
|
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
|
||||||
|
(c >= 'A' && c <= 'F');
|
||||||
|
}
|
||||||
|
static constexpr inline bool isCodeBlock(const int state) {
|
||||||
|
return state == MarkdownHighlighter::CodeBlock ||
|
||||||
|
state == MarkdownHighlighter::CodeBlockTilde ||
|
||||||
|
state == MarkdownHighlighter::CodeBlockComment ||
|
||||||
|
state == MarkdownHighlighter::CodeBlockTildeComment ||
|
||||||
|
state >= MarkdownHighlighter::CodeCpp;
|
||||||
|
}
|
||||||
|
static constexpr inline bool isCodeBlockEnd(const int state) {
|
||||||
|
return state == MarkdownHighlighter::CodeBlockEnd ||
|
||||||
|
state == MarkdownHighlighter::CodeBlockTildeEnd;
|
||||||
|
}
|
||||||
|
static constexpr inline bool isHeading(const int state) {
|
||||||
|
return state >= H1 && state <= H6;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class RangeType { CodeSpan, Emphasis, Link };
|
||||||
|
|
||||||
|
QPair<int, int> findPositionInRanges(MarkdownHighlighter::RangeType type,
|
||||||
|
int blockNum, int pos) const;
|
||||||
|
bool isPosInACodeSpan(int blockNumber, int position) const;
|
||||||
|
bool isPosInALink(int blockNumber, int position) const;
|
||||||
|
QPair<int, int> getSpanRange(RangeType rangeType, int blockNumber,
|
||||||
|
int position) const;
|
||||||
|
|
||||||
|
// we used some predefined numbers here to be compatible with
|
||||||
|
// the peg-Markdown parser
|
||||||
enum HighlighterState {
|
enum HighlighterState {
|
||||||
NoState = -1,
|
NoState = -1,
|
||||||
Link = 0,
|
Link = 0,
|
||||||
Image = 3,
|
Image = 3,
|
||||||
CodeBlock,
|
CodeBlock,
|
||||||
|
CodeBlockComment,
|
||||||
Italic = 7,
|
Italic = 7,
|
||||||
Bold,
|
Bold,
|
||||||
List,
|
List,
|
||||||
@ -64,74 +139,222 @@ public:
|
|||||||
MaskedSyntax,
|
MaskedSyntax,
|
||||||
CurrentLineBackgroundColor,
|
CurrentLineBackgroundColor,
|
||||||
BrokenLink,
|
BrokenLink,
|
||||||
|
FrontmatterBlock,
|
||||||
|
TrailingSpace,
|
||||||
|
CheckBoxUnChecked,
|
||||||
|
CheckBoxChecked,
|
||||||
|
StUnderline,
|
||||||
|
|
||||||
|
// code highlighting
|
||||||
|
CodeKeyWord = 1000,
|
||||||
|
CodeString = 1001,
|
||||||
|
CodeComment = 1002,
|
||||||
|
CodeType = 1003,
|
||||||
|
CodeOther = 1004,
|
||||||
|
CodeNumLiteral = 1005,
|
||||||
|
CodeBuiltIn = 1006,
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
|
CodeBlockIndented = 96,
|
||||||
|
CodeBlockTildeEnd = 97,
|
||||||
|
CodeBlockTilde = 98,
|
||||||
|
CodeBlockTildeComment,
|
||||||
CodeBlockEnd = 100,
|
CodeBlockEnd = 100,
|
||||||
HeadlineEnd
|
HeadlineEnd,
|
||||||
|
FrontmatterBlockEnd,
|
||||||
|
|
||||||
|
// languages
|
||||||
|
/*********
|
||||||
|
* When adding a language make sure that its value is a multiple of 2
|
||||||
|
* This is because we use the next number as comment for that language
|
||||||
|
* In case the language doesn't support multiline comments in the
|
||||||
|
* traditional C++ sense, leave the next value empty. Otherwise mark the
|
||||||
|
* next value as comment for that language. e.g CodeCpp = 200
|
||||||
|
* CodeCppComment = 201
|
||||||
|
*/
|
||||||
|
CodeCpp = 200,
|
||||||
|
CodeCppComment = 201,
|
||||||
|
CodeJs = 202,
|
||||||
|
CodeJsComment = 203,
|
||||||
|
CodeC = 204,
|
||||||
|
CodeCComment = 205,
|
||||||
|
CodeBash = 206,
|
||||||
|
CodePHP = 208,
|
||||||
|
CodePHPComment = 209,
|
||||||
|
CodeQML = 210,
|
||||||
|
CodeQMLComment = 211,
|
||||||
|
CodePython = 212,
|
||||||
|
CodeRust = 214,
|
||||||
|
CodeRustComment = 215,
|
||||||
|
CodeJava = 216,
|
||||||
|
CodeJavaComment = 217,
|
||||||
|
CodeCSharp = 218,
|
||||||
|
CodeCSharpComment = 219,
|
||||||
|
CodeGo = 220,
|
||||||
|
CodeGoComment = 221,
|
||||||
|
CodeV = 222,
|
||||||
|
CodeVComment = 223,
|
||||||
|
CodeSQL = 224,
|
||||||
|
CodeSQLComment = 225,
|
||||||
|
CodeJSON = 226,
|
||||||
|
CodeXML = 228,
|
||||||
|
CodeCSS = 230,
|
||||||
|
CodeCSSComment = 231,
|
||||||
|
CodeTypeScript = 232,
|
||||||
|
CodeTypeScriptComment = 233,
|
||||||
|
CodeYAML = 234,
|
||||||
|
CodeINI = 236,
|
||||||
|
CodeTaggerScript = 238,
|
||||||
|
CodeVex = 240,
|
||||||
|
CodeVexComment = 241,
|
||||||
|
CodeCMake = 242,
|
||||||
|
CodeMake = 244,
|
||||||
|
CodeNix = 246,
|
||||||
|
CodeForth = 248,
|
||||||
|
CodeForthComment = 249,
|
||||||
|
CodeSystemVerilog = 250,
|
||||||
|
CodeSystemVerilogComment = 251,
|
||||||
|
CodeGDScript = 252,
|
||||||
|
CodeTOML = 254,
|
||||||
|
CodeTOMLString = 255
|
||||||
};
|
};
|
||||||
Q_ENUM(HighlighterState)
|
Q_ENUM(HighlighterState)
|
||||||
|
|
||||||
// enum BlockState {
|
static void setTextFormats(
|
||||||
// NoBlockState = 0,
|
QHash<HighlighterState, QTextCharFormat> formats);
|
||||||
// H1,
|
static void setTextFormat(HighlighterState state, QTextCharFormat format);
|
||||||
// H2,
|
|
||||||
// H3,
|
|
||||||
// Table,
|
|
||||||
// CodeBlock,
|
|
||||||
// CodeBlockEnd
|
|
||||||
// };
|
|
||||||
|
|
||||||
void setTextFormats(QHash<HighlighterState, QTextCharFormat> formats);
|
|
||||||
void setTextFormat(HighlighterState state, QTextCharFormat format);
|
|
||||||
void clearDirtyBlocks();
|
void clearDirtyBlocks();
|
||||||
void setHighlightingOptions(HighlightingOptions options);
|
void setHighlightingOptions(const HighlightingOptions options);
|
||||||
void initHighlightingRules();
|
void initHighlightingRules();
|
||||||
|
|
||||||
signals:
|
Q_SIGNALS:
|
||||||
void highlightingFinished();
|
void highlightingFinished();
|
||||||
|
|
||||||
protected slots:
|
protected Q_SLOTS:
|
||||||
void timerTick();
|
void timerTick();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct HighlightingRule {
|
struct HighlightingRule {
|
||||||
HighlightingRule(const HighlighterState state_) : state(state_) {}
|
explicit HighlightingRule(const HighlighterState state_)
|
||||||
|
: state(state_) {}
|
||||||
HighlightingRule() = default;
|
HighlightingRule() = default;
|
||||||
|
|
||||||
QRegularExpression pattern;
|
QRegularExpression pattern;
|
||||||
|
QString shouldContain;
|
||||||
HighlighterState state = NoState;
|
HighlighterState state = NoState;
|
||||||
int capturingGroup = 0;
|
uint8_t capturingGroup = 0;
|
||||||
int maskedGroup = 0;
|
uint8_t maskedGroup = 0;
|
||||||
bool useStateAsCurrentBlockState = false;
|
};
|
||||||
bool disableIfCurrentStateIsSet = false;
|
struct InlineRange {
|
||||||
|
int begin;
|
||||||
|
int end;
|
||||||
|
RangeType type;
|
||||||
|
InlineRange() = default;
|
||||||
|
InlineRange(int begin_, int end_, RangeType type_)
|
||||||
|
: begin{begin_}, end{end_}, type{type_} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void highlightBlock(const QString &text) Q_DECL_OVERRIDE;
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
void initTextFormats(int defaultFontSize = 12);
|
static void initTextFormats(int defaultFontSize = 12);
|
||||||
|
|
||||||
void highlightMarkdown(QString text);
|
static void initCodeLangs();
|
||||||
|
|
||||||
void highlightHeadline(QString text);
|
void highlightMarkdown(const QString &text);
|
||||||
|
|
||||||
void highlightAdditionalRules(QVector<HighlightingRule> &rules,
|
void formatAndMaskRemaining(int formatBegin, int formatLength,
|
||||||
QString text);
|
int beginningText, int endText,
|
||||||
|
const QTextCharFormat &format);
|
||||||
|
|
||||||
void highlightCodeBlock(QString text);
|
/******************************
|
||||||
|
* BLOCK LEVEL FUNCTIONS
|
||||||
|
******************************/
|
||||||
|
|
||||||
void highlightCommentBlock(QString text);
|
void highlightHeadline(const QString &text);
|
||||||
|
|
||||||
void addDirtyBlock(QTextBlock block);
|
void highlightSubHeadline(const QString &text, HighlighterState state);
|
||||||
|
|
||||||
|
void highlightAdditionalRules(const QVector<HighlightingRule> &rules,
|
||||||
|
const QString &text);
|
||||||
|
|
||||||
|
void highlightFrontmatterBlock(const QString &text);
|
||||||
|
|
||||||
|
void highlightCommentBlock(const QString &text);
|
||||||
|
|
||||||
|
void highlightThematicBreak(const QString &text);
|
||||||
|
|
||||||
|
void highlightLists(const QString &text);
|
||||||
|
|
||||||
|
void highlightCheckbox(const QString &text, int curPos);
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* INLINE FUNCTIONS
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
void highlightInlineRules(const QString &text);
|
||||||
|
|
||||||
|
int highlightInlineSpans(const QString &text, int currentPos,
|
||||||
|
const QChar c);
|
||||||
|
|
||||||
|
void highlightEmAndStrong(const QString &text, const int pos);
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT int highlightInlineComment(const QString &text, int pos);
|
||||||
|
|
||||||
|
int highlightLinkOrImage(const QString &text, int startIndex);
|
||||||
|
|
||||||
|
void setHeadingStyles(MarkdownHighlighter::HighlighterState rule,
|
||||||
|
const QRegularExpressionMatch &match,
|
||||||
|
const int capturedGroup);
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* CODE HIGHLIGHTING FUNCTIONS
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
void highlightIndentedCodeBlock(const QString &text);
|
||||||
|
|
||||||
|
void highlightCodeFence(const QString &text);
|
||||||
|
|
||||||
|
void highlightCodeBlock(const QString &text,
|
||||||
|
const QString &opener = QStringLiteral("```"));
|
||||||
|
|
||||||
|
void highlightSyntax(const QString &text);
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT int highlightNumericLiterals(const QString &text, int i);
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT int highlightStringLiterals(QChar strType,
|
||||||
|
const QString &text, int i);
|
||||||
|
|
||||||
|
void ymlHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void iniHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void cssHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void xmlHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void makeHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void forthHighlighter(const QString &text);
|
||||||
|
void taggerScriptHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void gdscriptHighlighter(const QString &text);
|
||||||
|
void sqlHighlighter(const QString &text);
|
||||||
|
void tomlHighlighter(const QString &text);
|
||||||
|
|
||||||
|
void addDirtyBlock(const QTextBlock &block);
|
||||||
|
|
||||||
void reHighlightDirtyBlocks();
|
void reHighlightDirtyBlocks();
|
||||||
|
|
||||||
QVector<HighlightingRule> _highlightingRulesPre;
|
|
||||||
QVector<HighlightingRule> _highlightingRulesAfter;
|
|
||||||
QVector<QTextBlock> _dirtyTextBlocks;
|
|
||||||
QHash<HighlighterState, QTextCharFormat> _formats;
|
|
||||||
QTimer *_timer;
|
|
||||||
bool _highlightingFinished;
|
bool _highlightingFinished;
|
||||||
HighlightingOptions _highlightingOptions;
|
HighlightingOptions _highlightingOptions;
|
||||||
|
QTimer *_timer;
|
||||||
|
QVector<QTextBlock> _dirtyTextBlocks;
|
||||||
|
QVector<QPair<int, int>> _linkRanges;
|
||||||
|
|
||||||
void setCurrentBlockMargin(HighlighterState state);
|
QHash<int, QVector<InlineRange>> _ranges;
|
||||||
|
|
||||||
|
static QVector<HighlightingRule> _highlightingRules;
|
||||||
|
static QHash<HighlighterState, QTextCharFormat> _formats;
|
||||||
|
static QHash<QString, HighlighterState> _langStringToEnum;
|
||||||
|
static constexpr int tildeOffset = 300;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,15 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M10 4c-3.324 0-6 2.676-6 6s2.676 6 6 6a5.976 5.976 0 0 0 3.875-1.418L19.293 20l.707-.707-5.418-5.418A5.976 5.976 0 0 0 16 10c0-3.324-2.676-6-6-6zm0 1a4.99 4.99 0 0 1 5 5 4.99 4.99 0 0 1-5 5 4.99 4.99 0 0 1-5-5 4.99 4.99 0 0 1 5-5zM5 18a1 1 0 1 0 0 2 1 1 0 1 0 0-2zm4 0a1 1 0 1 0 0 2 1 1 0 1 0 0-2zm4 0a1 1 0 1 0 0 2 1 1 0 1 0 0-2z" fill="#4d4d4d"/></svg>
|
||||||
<defs id="defs3051">
|
|
||||||
<style type="text/css" id="current-color-scheme">
|
|
||||||
.ColorScheme-Text {
|
|
||||||
color:#4d4d4d;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<path
|
|
||||||
transform="translate(1,1)"
|
|
||||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
|
||||||
d="M 9 3 C 5.6759952 3 3 5.6759952 3 9 C 3 12.324005 5.6759952 15 9 15 C 10.481205 15 11.830584 14.465318 12.875 13.582031 L 18.292969 19 L 19 18.292969 L 13.582031 12.875 C 14.465318 11.830584 15 10.481205 15 9 C 15 5.6759952 12.324005 3 9 3 z M 9 4 C 11.770005 4 14 6.2299952 14 9 C 14 11.770005 11.770005 14 9 14 C 6.2299952 14 4 11.770005 4 9 C 4 6.2299952 6.2299952 4 9 4 z M 4 17 C 3.4460048 17 3 17.446005 3 18 C 3 18.553995 3.4460048 19 4 19 C 4.5539952 19 5 18.553995 5 18 C 5 17.446005 4.5539952 17 4 17 z M 8 17 C 7.4460048 17 7 17.446005 7 18 C 7 18.553995 7.4460048 19 8 19 C 8.5539952 19 9 18.553995 9 18 C 9 17.446005 8.5539952 17 8 17 z M 12 17 C 11.446005 17 11 17.446005 11 18 C 11 18.553995 11.446005 19 12 19 C 12.553995 19 13 18.553995 13 18 C 13 17.446005 12.553995 17 12 17 z "
|
|
||||||
class="ColorScheme-Text"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 423 B |
@ -1,16 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><a transform="translate(1 1)"><path d="M14 3v6h3a1.996 1.996 0 0 0 .828-3.816c.106-.206.172-.435.172-.684 0-.831-.669-1.5-1.5-1.5H15zm1 1h1.5a.5.5 0 1 1 0 1H15zM8.217 5 3 19h1.688l1.668-4.43h5.563L13.451 19h1.689L10.21 5zM15 6h2a1 1 0 1 1 0 2h-2zm-5.768.611 2.129 6.674H6.873z" fill="#4d4d4d"/></a></svg>
|
||||||
<defs id="defs3051">
|
|
||||||
<style type="text/css" id="current-color-scheme">
|
|
||||||
.ColorScheme-Text {
|
|
||||||
color:#4d4d4d;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<a transform="translate(1,1)">
|
|
||||||
<path
|
|
||||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
|
||||||
d="M 14 3 L 14 5 L 14 6 L 14 8 L 14 9 L 15 9 L 17 9 C 18.108 9 19 8.108 19 7 C 19 6.1891 18.518727 5.4980937 17.828125 5.1835938 C 17.934063 4.9776938 18 4.7483 18 4.5 C 18 3.669 17.330999 3 16.5 3 L 15 3 L 14 3 z M 15 4 L 16.5 4 C 16.777 4 17 4.223 17 4.5 C 17 4.777 16.777 5 16.5 5 L 15 5 L 15 4 z M 8.2167969 5 L 3 19 L 4.6875 19 L 6.3554688 14.570312 L 11.917969 14.570312 L 13.451172 19 L 15.140625 19 L 10.210938 5 L 8.2167969 5 z M 15 6 L 16.5 6 L 17 6 C 17.553999 6 18 6.446 18 7 C 18 7.554 17.553999 8 17 8 L 15 8 L 15 6 z M 9.2324219 6.6113281 L 11.361328 13.285156 L 6.8730469 13.285156 L 9.2324219 6.6113281 z "
|
|
||||||
class="ColorScheme-Text"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 998 B After Width: | Height: | Size: 364 B |
@ -1,156 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg fill="#4d4d4d" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M4.707 6 4 6.707l6.125 6.125L12 14.707l1.875-1.875L20 6.707 19.293 6l-6.125 6.125L12 13.293l-1.168-1.168zM4 17h16v1H4z"/></svg>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
id="svg3869"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="go-bottom.svg">
|
|
||||||
<defs
|
|
||||||
id="defs3871">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3257">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#a50000;stop-opacity:1"
|
|
||||||
id="stop3259" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#e73800;stop-opacity:1"
|
|
||||||
id="stop3261" />
|
|
||||||
</linearGradient>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath4210">
|
|
||||||
<rect
|
|
||||||
y="1024.3622"
|
|
||||||
x="-7"
|
|
||||||
height="34"
|
|
||||||
width="34"
|
|
||||||
id="rect4212"
|
|
||||||
style="opacity:1;fill:#0000ff;fill-opacity:0.51376145;stroke:none;stroke-opacity:1" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath4160">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#aade87;fill-opacity:0.47247709;stroke:none;stroke-opacity:1"
|
|
||||||
id="rect4162"
|
|
||||||
width="32"
|
|
||||||
height="32.000015"
|
|
||||||
x="-6"
|
|
||||||
y="1028.3619" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="22.627416"
|
|
||||||
inkscape:cx="5.4926209"
|
|
||||||
inkscape:cy="10.264796"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:window-width="1366"
|
|
||||||
inkscape:window-height="709"
|
|
||||||
inkscape:window-x="-4"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:showpageshadow="false"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-bbox="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4132" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="4,18"
|
|
||||||
orientation="18,0"
|
|
||||||
id="guide4138" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="5,3"
|
|
||||||
orientation="0,18"
|
|
||||||
id="guide4140" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="20,2.0000174"
|
|
||||||
orientation="-18,0"
|
|
||||||
id="guide4142" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,21"
|
|
||||||
orientation="0,-18"
|
|
||||||
id="guide4144" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="3,19.000017"
|
|
||||||
orientation="16,0"
|
|
||||||
id="guide4146" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,4"
|
|
||||||
orientation="0,16"
|
|
||||||
id="guide4148" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="21,20"
|
|
||||||
orientation="-16,0"
|
|
||||||
id="guide4150" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,20"
|
|
||||||
orientation="0,-16"
|
|
||||||
id="guide4152" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata3874">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Capa 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-326,-532.3622)">
|
|
||||||
<g
|
|
||||||
transform="translate(327,507.3622)"
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
id="layer1-68">
|
|
||||||
<g
|
|
||||||
inkscape:label="Capa 1"
|
|
||||||
id="layer1-6"
|
|
||||||
transform="translate(5e-7,-1006.3622)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#4d4d4d;fill-opacity:1;stroke:none"
|
|
||||||
d="M 3.7070312,7 3,7.7070312 l 6.125,6.1249998 1.875,1.875 1.875,-1.875 L 19,7.7070312 18.292969,7 12.167969,13.125 11,14.292969 9.8320312,13.125 3.7070312,7 Z"
|
|
||||||
transform="translate(-5e-7,1030.3622)"
|
|
||||||
id="rect4176" />
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
y="42"
|
|
||||||
x="3"
|
|
||||||
height="1"
|
|
||||||
width="16"
|
|
||||||
id="rect4186"
|
|
||||||
style="opacity:1;fill:#4d4d4d;fill-opacity:1;stroke:none" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 214 B |
@ -1,476 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg fill="#4d4d4d" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M4.707 18 4 17.293l6.125-6.125L12 9.293l1.875 1.875L20 17.293l-.707.707-6.125-6.125L12 10.707l-1.168 1.168zM4 7h16V6H4z"/></svg>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
id="svg3869"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="go-top.svg">
|
|
||||||
<defs
|
|
||||||
id="defs3871">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3257">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#a50000;stop-opacity:1"
|
|
||||||
id="stop3259" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#e73800;stop-opacity:1"
|
|
||||||
id="stop3261" />
|
|
||||||
</linearGradient>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath4210">
|
|
||||||
<rect
|
|
||||||
y="1024.3622"
|
|
||||||
x="-7"
|
|
||||||
height="34"
|
|
||||||
width="34"
|
|
||||||
id="rect4212"
|
|
||||||
style="opacity:1;fill:#0000ff;fill-opacity:0.51376145;stroke:none;stroke-opacity:1" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath4160">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#aade87;fill-opacity:0.47247709;stroke:none;stroke-opacity:1"
|
|
||||||
id="rect4162"
|
|
||||||
width="32"
|
|
||||||
height="32.000015"
|
|
||||||
x="-6"
|
|
||||||
y="1028.3619" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
id="clipPath4160-4"
|
|
||||||
clipPathUnits="userSpaceOnUse">
|
|
||||||
<rect
|
|
||||||
y="1023.3622"
|
|
||||||
x="7"
|
|
||||||
height="1"
|
|
||||||
width="1"
|
|
||||||
id="rect4162-5"
|
|
||||||
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-opacity:1" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath16">
|
|
||||||
<path
|
|
||||||
d="m 0,706.465 1490.926,0 L 1490.926,0 0,0 0,706.465 Z"
|
|
||||||
id="path18" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath24">
|
|
||||||
<path
|
|
||||||
d="m 22.1953,686.117 1447.7347,0 0,-667.1902 -1447.7347,0 L 22.1953,686.117 Z"
|
|
||||||
id="path26" />
|
|
||||||
</clipPath>
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36-7"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7-6" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0-6"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8-7" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3-9"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-2" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36-4"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7-7" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0-0"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8-6" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3-81"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-6" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36-7-2"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7-6-3" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0-6-4"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8-7-6" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3-9-0"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-2-1" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36-8"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7-0" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0-3"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8-78" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3-1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-05" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36-3"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7-8" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0-9"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8-3" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3-4"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-9" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-36-7-6"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-7-6-0" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-0-6-7"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-3-8-7-7" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective4146-3-9-7"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 12 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="24 : 12 : 1"
|
|
||||||
inkscape:persp3d-origin="12 : 8 : 1"
|
|
||||||
id="perspective4146-2-13" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="22.627416"
|
|
||||||
inkscape:cx="5.4926209"
|
|
||||||
inkscape:cy="10.264796"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:window-width="1366"
|
|
||||||
inkscape:window-height="709"
|
|
||||||
inkscape:window-x="-4"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:showpageshadow="false"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-bbox="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4132" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="4,18"
|
|
||||||
orientation="18,0"
|
|
||||||
id="guide4138" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="5,3"
|
|
||||||
orientation="0,18"
|
|
||||||
id="guide4140" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="20,2.0000174"
|
|
||||||
orientation="-18,0"
|
|
||||||
id="guide4142" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,21"
|
|
||||||
orientation="0,-18"
|
|
||||||
id="guide4144" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="3,19.000017"
|
|
||||||
orientation="16,0"
|
|
||||||
id="guide4146" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,4"
|
|
||||||
orientation="0,16"
|
|
||||||
id="guide4148" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="21,20"
|
|
||||||
orientation="-16,0"
|
|
||||||
id="guide4150" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,20"
|
|
||||||
orientation="0,-16"
|
|
||||||
id="guide4152" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata3874">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Capa 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-326,-532.3622)">
|
|
||||||
<g
|
|
||||||
transform="translate(327,507.3622)"
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
id="layer1-2">
|
|
||||||
<g
|
|
||||||
inkscape:label="Capa 1"
|
|
||||||
id="layer1-6"
|
|
||||||
transform="matrix(1,0,0,-1,5e-7,1080.3622)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#4d4d4d;fill-opacity:1;stroke:none"
|
|
||||||
d="M 3.7070312,7 3,7.7070312 l 6.125,6.1249998 1.875,1.875 1.875,-1.875 L 19,7.7070312 18.292969,7 12.167969,13.125 11,14.292969 9.8320312,13.125 3.7070312,7 Z"
|
|
||||||
transform="translate(-5e-7,1030.3622)"
|
|
||||||
id="rect4176" />
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
transform="scale(1,-1)"
|
|
||||||
y="-32"
|
|
||||||
x="3"
|
|
||||||
height="1"
|
|
||||||
width="16"
|
|
||||||
id="rect4186"
|
|
||||||
style="opacity:1;fill:#4d4d4d;fill-opacity:1;stroke:none" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 215 B |
@ -1,148 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12 4a8 8 0 1 0 0 16 8 8 0 1 0 0-16zM8.707 8 12 11.293 15.293 8l.707.707L12.707 12 16 15.293l-.707.707L12 12.707 8.707 16 8 15.293 11.293 12 8 8.707z" fill="#da4453"/></svg>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
id="svg3869"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="window-close.svg">
|
|
||||||
<defs
|
|
||||||
id="defs3871">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3257">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#a50000;stop-opacity:1"
|
|
||||||
id="stop3259" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#e73800;stop-opacity:1"
|
|
||||||
id="stop3261" />
|
|
||||||
</linearGradient>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath4210">
|
|
||||||
<rect
|
|
||||||
y="1024.3622"
|
|
||||||
x="-7"
|
|
||||||
height="34"
|
|
||||||
width="34"
|
|
||||||
id="rect4212"
|
|
||||||
style="opacity:1;fill:#0000ff;fill-opacity:0.51376145;stroke:none;stroke-opacity:1" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath4160">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#aade87;fill-opacity:0.47247709;stroke:none;stroke-opacity:1"
|
|
||||||
id="rect4162"
|
|
||||||
width="32"
|
|
||||||
height="32.000015"
|
|
||||||
x="-6"
|
|
||||||
y="1028.3619" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="22.627416"
|
|
||||||
inkscape:cx="5.4926209"
|
|
||||||
inkscape:cy="10.264796"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:window-width="1366"
|
|
||||||
inkscape:window-height="709"
|
|
||||||
inkscape:window-x="-4"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:showpageshadow="false"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-bbox="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4132" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="4,18"
|
|
||||||
orientation="18,0"
|
|
||||||
id="guide4138" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="5,3"
|
|
||||||
orientation="0,18"
|
|
||||||
id="guide4140" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="20,2.0000174"
|
|
||||||
orientation="-18,0"
|
|
||||||
id="guide4142" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,21"
|
|
||||||
orientation="0,-18"
|
|
||||||
id="guide4144" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="3,19.000017"
|
|
||||||
orientation="16,0"
|
|
||||||
id="guide4146" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,4"
|
|
||||||
orientation="0,16"
|
|
||||||
id="guide4148" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="21,20"
|
|
||||||
orientation="-16,0"
|
|
||||||
id="guide4150" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="2,20"
|
|
||||||
orientation="0,-16"
|
|
||||||
id="guide4152" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata3874">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Capa 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-326,-532.3622)">
|
|
||||||
<g
|
|
||||||
transform="translate(-94.71429,7.57146)"
|
|
||||||
id="layer1-7"
|
|
||||||
inkscape:label="Capa 1">
|
|
||||||
<circle
|
|
||||||
id="circle16"
|
|
||||||
cx="421.71429"
|
|
||||||
cy="-504.57132"
|
|
||||||
r="0" />
|
|
||||||
<path
|
|
||||||
id="path4144"
|
|
||||||
d="m 432.71429,528.79074 a 7.9999995,8.0000081 0 0 0 -8,8 7.9999995,8.0000081 0 0 0 8,8 7.9999995,8.0000081 0 0 0 8,-8 7.9999995,8.0000081 0 0 0 -8,-8 z m -3.29297,4 3.29297,3.29297 3.29297,-3.29297 0.70703,0.70703 -3.29297,3.29297 3.29297,3.29297 -0.70703,0.70703 -3.29297,-3.29297 -3.29297,3.29297 -0.70703,-0.70703 3.29297,-3.29297 -3.29297,-3.29297 0.70703,-0.70703 z"
|
|
||||||
style="opacity:1;fill:#da4453;fill-opacity:1"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 245 B |
BIN
client/qmarkdowntextedit/old_screenshot.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
17
client/qmarkdowntextedit/qmarkdowntextedit-app.pro
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
TARGET = QMarkdownTextedit
|
||||||
|
TEMPLATE = app
|
||||||
|
QT += core gui widgets
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
SOURCES = main.cpp mainwindow.cpp
|
||||||
|
HEADERS = mainwindow.h
|
||||||
|
FORMS = mainwindow.ui
|
||||||
|
|
||||||
|
LIBS += -lQMarkdownTextedit -L$$OUT_PWD
|
||||||
|
|
||||||
|
win32: LIBS += -L$$OUT_PWD/release -L$$OUT_PWD/debug
|
||||||
|
|
||||||
|
target.path = $$[QT_INSTALL_BINS]
|
||||||
|
|
||||||
|
INSTALLS += target
|
||||||
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
INCLUDEPATH += $$PWD/
|
INCLUDEPATH += $$PWD/
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
$$PWD/linenumberarea.h \
|
||||||
$$PWD/markdownhighlighter.h \
|
$$PWD/markdownhighlighter.h \
|
||||||
$$PWD/qmarkdowntextedit.h \
|
$$PWD/qmarkdowntextedit.h \
|
||||||
|
$$PWD/qownlanguagedata.h \
|
||||||
$$PWD/qplaintexteditsearchwidget.h
|
$$PWD/qplaintexteditsearchwidget.h
|
||||||
|
|||||||
34
client/qmarkdowntextedit/qmarkdowntextedit-lib.pro
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
TARGET = QMarkdownTextedit
|
||||||
|
TEMPLATE = lib
|
||||||
|
QT += core gui widgets
|
||||||
|
CONFIG += c++11 create_prl no_install_prl create_pc
|
||||||
|
|
||||||
|
include(qmarkdowntextedit.pri)
|
||||||
|
|
||||||
|
TRANSLATIONS += trans/qmarkdowntextedit_de.ts \
|
||||||
|
trans/qmarkdowntextedit_zh_CN.ts \
|
||||||
|
trans/qmarkdowntextedit_es.ts
|
||||||
|
|
||||||
|
isEmpty(PREFIX):PREFIX=$$[QT_INSTALL_PREFIX]
|
||||||
|
isEmpty(LIBDIR):LIBDIR=$$[QT_INSTALL_LIBS]
|
||||||
|
isEmpty(HEADERDIR):HEADERDIR=$${PREFIX}/include/$$TARGET/
|
||||||
|
isEmpty(DSRDIR):DSRDIR=$${PREFIX}/share/$$TARGET
|
||||||
|
|
||||||
|
target.path = $${LIBDIR}
|
||||||
|
|
||||||
|
headers.files = $$HEADERS
|
||||||
|
headers.path = $${HEADERDIR}
|
||||||
|
|
||||||
|
license.files = LICENSE
|
||||||
|
license.path = $${DSRDIR}/licenses/
|
||||||
|
|
||||||
|
trans.files = trans/*.qm
|
||||||
|
trans.path = $${DSRDIR}/translations/
|
||||||
|
|
||||||
|
QMAKE_PKGCONFIG_NAME = QMarkdownTextedit
|
||||||
|
QMAKE_PKGCONFIG_DESCRIPTION = C++ Qt QPlainTextEdit widget with markdown highlighting and some other goodies
|
||||||
|
QMAKE_PKGCONFIG_INCDIR = $${headers.path}
|
||||||
|
QMAKE_PKGCONFIG_LIBDIR = $${LIBDIR}
|
||||||
|
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
|
||||||
|
|
||||||
|
INSTALLS += target license headers trans
|
||||||
@ -6,6 +6,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/markdownhighlighter.cpp \
|
$$PWD/markdownhighlighter.cpp \
|
||||||
$$PWD/qmarkdowntextedit.cpp \
|
$$PWD/qmarkdowntextedit.cpp \
|
||||||
|
$$PWD/qownlanguagedata.cpp \
|
||||||
$$PWD/qplaintexteditsearchwidget.cpp
|
$$PWD/qplaintexteditsearchwidget.cpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
|
|||||||
@ -1,87 +1,144 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QPlainTextEdit>
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
#include "markdownhighlighter.h"
|
#include "markdownhighlighter.h"
|
||||||
#include "qplaintexteditsearchwidget.h"
|
#include "qplaintexteditsearchwidget.h"
|
||||||
|
|
||||||
|
class LineNumArea;
|
||||||
|
|
||||||
class QMarkdownTextEdit : public QPlainTextEdit
|
class QMarkdownTextEdit : public QPlainTextEdit {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(
|
||||||
|
bool highlighting READ highlightingEnabled WRITE setHighlightingEnabled)
|
||||||
|
|
||||||
public:
|
friend class LineNumArea;
|
||||||
|
|
||||||
|
public:
|
||||||
enum AutoTextOption {
|
enum AutoTextOption {
|
||||||
None = 0x0000,
|
None = 0x0000,
|
||||||
|
|
||||||
// inserts closing characters for brackets and markdown characters
|
// inserts closing characters for brackets and Markdown characters
|
||||||
BracketClosing = 0x0001,
|
BracketClosing = 0x0001,
|
||||||
|
|
||||||
// removes matching brackets and markdown characters
|
// removes matching brackets and Markdown characters
|
||||||
BracketRemoval = 0x0002
|
BracketRemoval = 0x0002
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(AutoTextOptions, AutoTextOption)
|
Q_DECLARE_FLAGS(AutoTextOptions, AutoTextOption)
|
||||||
|
|
||||||
explicit QMarkdownTextEdit(QWidget *parent = 0, bool initHighlighter = true);
|
explicit QMarkdownTextEdit(QWidget *parent = nullptr,
|
||||||
|
bool initHighlighter = true);
|
||||||
MarkdownHighlighter *highlighter();
|
MarkdownHighlighter *highlighter();
|
||||||
QPlainTextEditSearchWidget *searchWidget();
|
QPlainTextEditSearchWidget *searchWidget();
|
||||||
void setIgnoredClickUrlSchemata(QStringList ignoredUrlSchemata);
|
void setIgnoredClickUrlSchemata(QStringList ignoredUrlSchemata);
|
||||||
virtual void openUrl(QString urlString);
|
virtual void openUrl(const QString &urlString);
|
||||||
QString getMarkdownUrlAtPosition(QString text, int position);
|
QString getMarkdownUrlAtPosition(const QString &text, int position);
|
||||||
void initSearchFrame(QWidget *searchFrame, bool darkMode = false);
|
void initSearchFrame(QWidget *searchFrame, bool darkMode = false);
|
||||||
void setAutoTextOptions(AutoTextOptions options);
|
void setAutoTextOptions(AutoTextOptions options);
|
||||||
void setHighlightingEnabled(bool enabled);
|
static bool isValidUrl(const QString &urlString);
|
||||||
static bool isValidUrl(QString urlString);
|
|
||||||
void resetMouseCursor() const;
|
void resetMouseCursor() const;
|
||||||
void setReadOnly(bool ro);
|
void setReadOnly(bool ro);
|
||||||
|
void doSearch(QString &searchText,
|
||||||
|
QPlainTextEditSearchWidget::SearchMode searchMode =
|
||||||
|
QPlainTextEditSearchWidget::SearchMode::PlainTextMode);
|
||||||
|
void hideSearchWidget(bool reset);
|
||||||
|
void updateSettings();
|
||||||
|
void setLineNumbersCurrentLineColor(QColor color);
|
||||||
|
void setLineNumbersOtherLineColor(QColor color);
|
||||||
|
void setSearchWidgetDebounceDelay(uint debounceDelay);
|
||||||
|
|
||||||
public slots:
|
void setHighlightingEnabled(bool enabled);
|
||||||
|
[[nodiscard]] bool highlightingEnabled() const;
|
||||||
|
|
||||||
|
void setHighlightCurrentLine(bool set);
|
||||||
|
bool highlightCurrentLine();
|
||||||
|
|
||||||
|
void setCurrentLineHighlightColor(const QColor &c);
|
||||||
|
QColor currentLineHighlightColor();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
void duplicateText();
|
void duplicateText();
|
||||||
void setText(const QString & text);
|
void setText(const QString &text);
|
||||||
void setPlainText(const QString & text);
|
void setPlainText(const QString &text);
|
||||||
void adjustRightMargin();
|
void adjustRightMargin();
|
||||||
void hide();
|
void hide();
|
||||||
bool openLinkAtCursorPosition();
|
bool openLinkAtCursorPosition();
|
||||||
bool handleBracketRemoval();
|
bool handleBackspaceEntered();
|
||||||
|
void centerTheCursor();
|
||||||
|
void undo();
|
||||||
|
void moveTextUpDown(bool up);
|
||||||
|
void setLineNumberEnabled(bool enabled);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MarkdownHighlighter *_highlighter;
|
QTextCursor _textCursor;
|
||||||
|
MarkdownHighlighter *_highlighter = nullptr;
|
||||||
bool _highlightingEnabled;
|
bool _highlightingEnabled;
|
||||||
QStringList _ignoredClickUrlSchemata;
|
QStringList _ignoredClickUrlSchemata;
|
||||||
QPlainTextEditSearchWidget *_searchWidget;
|
QPlainTextEditSearchWidget *_searchWidget;
|
||||||
QWidget *_searchFrame;
|
QWidget *_searchFrame;
|
||||||
AutoTextOptions _autoTextOptions;
|
AutoTextOptions _autoTextOptions;
|
||||||
QStringList _openingCharacters;
|
bool _mouseButtonDown = false;
|
||||||
QStringList _closingCharacters;
|
bool _centerCursor = false;
|
||||||
|
bool _highlightCurrentLine = false;
|
||||||
|
QColor _currentLineHighlightColor = QColor();
|
||||||
|
uint _debounceDelay = 0;
|
||||||
|
|
||||||
bool eventFilter(QObject *obj, QEvent *event);
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
bool increaseSelectedTextIndention(bool reverse);
|
QMargins viewportMargins();
|
||||||
bool handleTabEntered(bool reverse);
|
bool increaseSelectedTextIndention(
|
||||||
QMap<QString, QString> parseMarkdownUrlsFromText(QString text);
|
bool reverse,
|
||||||
|
const QString &indentCharacters = QChar::fromLatin1('\t'));
|
||||||
|
bool handleTabEntered(bool reverse, const QString &indentCharacters =
|
||||||
|
QChar::fromLatin1('\t'));
|
||||||
|
QMap<QString, QString> parseMarkdownUrlsFromText(const QString &text);
|
||||||
bool handleReturnEntered();
|
bool handleReturnEntered();
|
||||||
bool handleBracketClosing(QString openingCharacter,
|
bool handleBracketClosing(const QChar openingCharacter,
|
||||||
QString closingCharacter = "");
|
QChar closingCharacter = QChar());
|
||||||
bool bracketClosingCheck(QString openingCharacter,
|
bool bracketClosingCheck(const QChar openingCharacter,
|
||||||
QString closingCharacter);
|
QChar closingCharacter);
|
||||||
bool quotationMarkCheck(QString quotationCharacter);
|
bool quotationMarkCheck(const QChar quotationCharacter);
|
||||||
void focusOutEvent(QFocusEvent *event);
|
void focusOutEvent(QFocusEvent *event) override;
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
bool handleCharRemoval(MarkdownHighlighter::RangeType type, int block,
|
||||||
|
int position);
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
void setLineNumberLeftMarginOffset(int offset);
|
||||||
|
int _lineNumberLeftMarginOffset = 0;
|
||||||
|
LineNumArea *lineNumberArea() { return _lineNumArea; }
|
||||||
|
void updateLineNumAreaGeometry();
|
||||||
|
void updateLineNumberArea(const QRect rect, int dy);
|
||||||
|
Q_SLOT void updateLineNumberAreaWidth(int);
|
||||||
|
bool _handleBracketClosingUsed;
|
||||||
|
LineNumArea *_lineNumArea;
|
||||||
|
|
||||||
signals:
|
Q_SIGNALS:
|
||||||
void urlClicked(QString url);
|
void urlClicked(QString url);
|
||||||
|
void zoomIn();
|
||||||
|
void zoomOut();
|
||||||
};
|
};
|
||||||
|
|||||||
12
client/qmarkdowntextedit/qmarkdowntextedit.pc.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||||
|
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/
|
||||||
|
|
||||||
|
Name: @PROJECT_NAME@
|
||||||
|
Description: @PROJECT_DESCRIPTION@
|
||||||
|
Version: @PROJECT_VERSION@
|
||||||
|
|
||||||
|
Requires:
|
||||||
|
Libs: -L${libdir} -lqmarkdowntextedit
|
||||||
|
Cflags: -I${includedir}
|
||||||
@ -1,23 +1,5 @@
|
|||||||
#-------------------------------------------------
|
TEMPLATE = subdirs
|
||||||
#
|
SUBDIRS = app lib
|
||||||
# Project created by QtCreator 2016-01-11T16:56:21
|
app.file = qmarkdowntextedit-app.pro
|
||||||
#
|
lib.file = qmarkdowntextedit-lib.pro
|
||||||
#-------------------------------------------------
|
app.depends = lib
|
||||||
|
|
||||||
QT += core gui
|
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|
||||||
|
|
||||||
TARGET = QMarkdownTextedit
|
|
||||||
TEMPLATE = app
|
|
||||||
TRANSLATIONS = trans/qmarkdowntextedit_de.ts
|
|
||||||
CONFIG += c++11
|
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
|
||||||
mainwindow.cpp \
|
|
||||||
|
|
||||||
HEADERS += mainwindow.h
|
|
||||||
|
|
||||||
FORMS += mainwindow.ui
|
|
||||||
|
|
||||||
include(qmarkdowntextedit.pri)
|
|
||||||
|
|||||||
7303
client/qmarkdowntextedit/qownlanguagedata.cpp
Normal file
270
client/qmarkdowntextedit/qownlanguagedata.h
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Waqar Ahmed -- <waqar.17a@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef QOWNLANGUAGEDATA_H
|
||||||
|
#define QOWNLANGUAGEDATA_H
|
||||||
|
|
||||||
|
#include <QMultiHash>
|
||||||
|
|
||||||
|
/* ------------------------
|
||||||
|
* TEMPLATE FOR LANG DATA
|
||||||
|
* -------------------------
|
||||||
|
*
|
||||||
|
* loadXXXData, where XXX is the language
|
||||||
|
* keywords are the language keywords e.g, const
|
||||||
|
* types are built-in types i.e, int, char, var
|
||||||
|
* literals are words like, true false
|
||||||
|
* builtin are the library functions
|
||||||
|
* other can contain any other thing, for e.g, in cpp it contains the
|
||||||
|
preprocessor
|
||||||
|
|
||||||
|
static const QMultiHash<char, QLatin1String> xxx_keywords = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QMultiHash<char, QLatin1String> xxx_types = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QMultiHash<char, QLatin1String> xxx_literals = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QMultiHash<char, QLatin1String> xxx_builtin = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QMultiHash<char, QLatin1String> xxx_other = {
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* C/C++ Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadCppData(QMultiHash<char, QLatin1String> &typess,
|
||||||
|
QMultiHash<char, QLatin1String> &keywordss,
|
||||||
|
QMultiHash<char, QLatin1String> &builtins,
|
||||||
|
QMultiHash<char, QLatin1String> &literalss,
|
||||||
|
QMultiHash<char, QLatin1String> &others);
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Shell Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadShellData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* JS Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadJSData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* JS Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadNixData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* PHP Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadPHPData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* QML Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadQMLData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Python Data *********************************************/
|
||||||
|
/**********************************************************/
|
||||||
|
void loadPythonData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** Rust DATA ***********************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadRustData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** Java DATA ***********************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadJavaData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** C# DATA *************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadCSharpData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** Go DATA *************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadGoData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** V DATA **************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadVData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** SQL DATA ************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadSQLData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** System Verilog DATA *************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadSystemVerilogData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** JSON DATA ***********************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadJSONData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** CSS DATA ***********************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadCSSData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** Typescript DATA *********************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadTypescriptData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** YAML DATA ***************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadYAMLData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** VEX DATA ****************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadVEXData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** CMake DATA **************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadCMakeData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/*** Make DATA ***************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadMakeData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
/********************************************************/
|
||||||
|
/*** Forth DATA **************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadForthData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
/********************************************************/
|
||||||
|
/*** GDScript DATA **************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadGDScriptData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
/********************************************************/
|
||||||
|
/*** TOML DATA **************************************/
|
||||||
|
/********************************************************/
|
||||||
|
void loadTOMLData(QMultiHash<char, QLatin1String> &types,
|
||||||
|
QMultiHash<char, QLatin1String> &keywords,
|
||||||
|
QMultiHash<char, QLatin1String> &builtin,
|
||||||
|
QMultiHash<char, QLatin1String> &literals,
|
||||||
|
QMultiHash<char, QLatin1String> &other);
|
||||||
|
#endif
|
||||||
@ -1,46 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qplaintexteditsearchwidget.h"
|
#include "qplaintexteditsearchwidget.h"
|
||||||
#include "ui_qplaintexteditsearchwidget.h"
|
|
||||||
|
#include <QDebug>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
QPlainTextEditSearchWidget::QPlainTextEditSearchWidget(QPlainTextEdit *parent) :
|
#include "ui_qplaintexteditsearchwidget.h"
|
||||||
QWidget(parent),
|
|
||||||
ui(new Ui::QPlainTextEditSearchWidget)
|
QPlainTextEditSearchWidget::QPlainTextEditSearchWidget(QPlainTextEdit *parent)
|
||||||
{
|
: QWidget(parent),
|
||||||
|
ui(new Ui::QPlainTextEditSearchWidget),
|
||||||
|
selectionColor(0, 180, 0, 100) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
_textEdit = parent;
|
_textEdit = parent;
|
||||||
_darkMode = false;
|
_darkMode = false;
|
||||||
hide();
|
hide();
|
||||||
|
ui->searchCountLabel->setStyleSheet(QStringLiteral("* {color: grey}"));
|
||||||
|
// hiding will leave a open space in the horizontal layout
|
||||||
|
ui->searchCountLabel->setEnabled(false);
|
||||||
|
_currentSearchResult = 0;
|
||||||
|
_searchResultCount = 0;
|
||||||
|
|
||||||
QObject::connect(ui->closeButton, SIGNAL(clicked()),
|
connect(ui->closeButton, &QPushButton::clicked, this,
|
||||||
this, SLOT(deactivate()));
|
&QPlainTextEditSearchWidget::deactivate);
|
||||||
QObject::connect(ui->searchLineEdit, SIGNAL(textChanged(const QString &)),
|
connect(ui->searchLineEdit, &QLineEdit::textChanged, this,
|
||||||
this, SLOT(searchLineEditTextChanged(const QString &)));
|
&QPlainTextEditSearchWidget::searchLineEditTextChanged);
|
||||||
QObject::connect(ui->searchDownButton, SIGNAL(clicked()),
|
connect(ui->searchDownButton, &QPushButton::clicked, this,
|
||||||
this, SLOT(doSearchDown()));
|
&QPlainTextEditSearchWidget::doSearchDown);
|
||||||
QObject::connect(ui->searchUpButton, SIGNAL(clicked()),
|
connect(ui->searchUpButton, &QPushButton::clicked, this,
|
||||||
this, SLOT(doSearchUp()));
|
&QPlainTextEditSearchWidget::doSearchUp);
|
||||||
QObject::connect(ui->replaceToggleButton, SIGNAL(toggled(bool)),
|
connect(ui->replaceToggleButton, &QPushButton::toggled, this,
|
||||||
this, SLOT(setReplaceMode(bool)));
|
&QPlainTextEditSearchWidget::setReplaceMode);
|
||||||
QObject::connect(ui->replaceButton, SIGNAL(clicked()),
|
connect(ui->replaceButton, &QPushButton::clicked, this,
|
||||||
this, SLOT(doReplace()));
|
&QPlainTextEditSearchWidget::doReplace);
|
||||||
QObject::connect(ui->replaceAllButton, SIGNAL(clicked()),
|
connect(ui->replaceAllButton, &QPushButton::clicked, this,
|
||||||
this, SLOT(doReplaceAll()));
|
&QPlainTextEditSearchWidget::doReplaceAll);
|
||||||
|
|
||||||
|
connect(&_debounceTimer, &QTimer::timeout, this,
|
||||||
|
&QPlainTextEditSearchWidget::performSearch);
|
||||||
|
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
ui->searchLineEdit->installEventFilter(this);
|
ui->searchLineEdit->installEventFilter(this);
|
||||||
@ -52,7 +72,7 @@ QPlainTextEditSearchWidget::QPlainTextEditSearchWidget(QPlainTextEdit *parent) :
|
|||||||
ui->buttonFrame->layout()->setSpacing(9);
|
ui->buttonFrame->layout()->setSpacing(9);
|
||||||
|
|
||||||
// set the margin to 0 for the top buttons for OS X
|
// set the margin to 0 for the top buttons for OS X
|
||||||
QString buttonStyle = "QPushButton {margin: 0}";
|
QString buttonStyle = QStringLiteral("QPushButton {margin: 0}");
|
||||||
ui->closeButton->setStyleSheet(buttonStyle);
|
ui->closeButton->setStyleSheet(buttonStyle);
|
||||||
ui->searchDownButton->setStyleSheet(buttonStyle);
|
ui->searchDownButton->setStyleSheet(buttonStyle);
|
||||||
ui->searchUpButton->setStyleSheet(buttonStyle);
|
ui->searchUpButton->setStyleSheet(buttonStyle);
|
||||||
@ -61,25 +81,9 @@ QPlainTextEditSearchWidget::QPlainTextEditSearchWidget(QPlainTextEdit *parent) :
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QPlainTextEditSearchWidget::~QPlainTextEditSearchWidget() {
|
QPlainTextEditSearchWidget::~QPlainTextEditSearchWidget() { delete ui; }
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::activate() {
|
void QPlainTextEditSearchWidget::activate() { activate(true); }
|
||||||
setReplaceMode(false);
|
|
||||||
show();
|
|
||||||
|
|
||||||
// preset the selected text as search text if there is any and there is no
|
|
||||||
// other search text
|
|
||||||
QString selectedText = _textEdit->textCursor().selectedText();
|
|
||||||
if (!selectedText.isEmpty() && ui->searchLineEdit->text().isEmpty()) {
|
|
||||||
ui->searchLineEdit->setText(selectedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->searchLineEdit->setFocus();
|
|
||||||
ui->searchLineEdit->selectAll();
|
|
||||||
doSearchDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::activateReplace() {
|
void QPlainTextEditSearchWidget::activateReplace() {
|
||||||
// replacing is prohibited if the text edit is readonly
|
// replacing is prohibited if the text edit is readonly
|
||||||
@ -94,7 +98,13 @@ void QPlainTextEditSearchWidget::activateReplace() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::deactivate() {
|
void QPlainTextEditSearchWidget::deactivate() {
|
||||||
|
stopDebounce();
|
||||||
|
|
||||||
hide();
|
hide();
|
||||||
|
|
||||||
|
// Clear the search extra selections when closing the search bar
|
||||||
|
clearSearchExtraSelections();
|
||||||
|
|
||||||
_textEdit->setFocus();
|
_textEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,29 +119,33 @@ void QPlainTextEditSearchWidget::setReplaceMode(bool enabled) {
|
|||||||
|
|
||||||
bool QPlainTextEditSearchWidget::eventFilter(QObject *obj, QEvent *event) {
|
bool QPlainTextEditSearchWidget::eventFilter(QObject *obj, QEvent *event) {
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
auto *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
|
|
||||||
if (keyEvent->key() == Qt::Key_Escape) {
|
if (keyEvent->key() == Qt::Key_Escape) {
|
||||||
deactivate();
|
deactivate();
|
||||||
return true;
|
return true;
|
||||||
} else if ((keyEvent->modifiers().testFlag(Qt::ShiftModifier) &&
|
} else if ((!_debounceTimer.isActive() &&
|
||||||
|
keyEvent->modifiers().testFlag(Qt::ShiftModifier) &&
|
||||||
(keyEvent->key() == Qt::Key_Return)) ||
|
(keyEvent->key() == Qt::Key_Return)) ||
|
||||||
(keyEvent->key() == Qt::Key_Up)) {
|
(keyEvent->key() == Qt::Key_Up)) {
|
||||||
doSearchUp();
|
doSearchUp();
|
||||||
return true;
|
return true;
|
||||||
} else if ((keyEvent->key() == Qt::Key_Return) ||
|
} else if (!_debounceTimer.isActive() &&
|
||||||
(keyEvent->key() == Qt::Key_Down)) {
|
((keyEvent->key() == Qt::Key_Return) ||
|
||||||
|
(keyEvent->key() == Qt::Key_Down))) {
|
||||||
doSearchDown();
|
doSearchDown();
|
||||||
return true;
|
return true;
|
||||||
} else if (keyEvent->key() == Qt::Key_F3) {
|
} else if (!_debounceTimer.isActive() &&
|
||||||
|
keyEvent->key() == Qt::Key_F3) {
|
||||||
doSearch(!keyEvent->modifiers().testFlag(Qt::ShiftModifier));
|
doSearch(!keyEvent->modifiers().testFlag(Qt::ShiftModifier));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ((obj == ui->replaceLineEdit) && (keyEvent->key() == Qt::Key_Tab)
|
// if ((obj == ui->replaceLineEdit) && (keyEvent->key() ==
|
||||||
// && ui->replaceToggleButton->isChecked()) {
|
// Qt::Key_Tab)
|
||||||
// ui->replaceLineEdit->setFocus();
|
// && ui->replaceToggleButton->isChecked()) {
|
||||||
// }
|
// ui->replaceLineEdit->setFocus();
|
||||||
|
// }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -139,19 +153,74 @@ bool QPlainTextEditSearchWidget::eventFilter(QObject *obj, QEvent *event) {
|
|||||||
return QWidget::eventFilter(obj, event);
|
return QWidget::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::searchLineEditTextChanged(const QString &arg1) {
|
void QPlainTextEditSearchWidget::searchLineEditTextChanged(
|
||||||
Q_UNUSED(arg1);
|
const QString &arg1) {
|
||||||
|
_searchTerm = arg1;
|
||||||
|
|
||||||
|
if (_debounceTimer.interval() != 0 && !_searchTerm.isEmpty()) {
|
||||||
|
_debounceTimer.start();
|
||||||
|
ui->searchDownButton->setEnabled(false);
|
||||||
|
ui->searchUpButton->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
performSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::performSearch() {
|
||||||
|
doSearchCount();
|
||||||
|
updateSearchExtraSelections();
|
||||||
doSearchDown();
|
doSearchDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::doSearchUp() {
|
void QPlainTextEditSearchWidget::clearSearchExtraSelections() {
|
||||||
doSearch(false);
|
_searchExtraSelections.clear();
|
||||||
|
setSearchExtraSelections();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::doSearchDown() {
|
void QPlainTextEditSearchWidget::updateSearchExtraSelections() {
|
||||||
doSearch(true);
|
_searchExtraSelections.clear();
|
||||||
|
const auto textCursor = _textEdit->textCursor();
|
||||||
|
_textEdit->moveCursor(QTextCursor::Start);
|
||||||
|
const QColor color = selectionColor;
|
||||||
|
QTextCharFormat extraFmt;
|
||||||
|
extraFmt.setBackground(color);
|
||||||
|
int findCounter = 0;
|
||||||
|
const int searchMode = ui->modeComboBox->currentIndex();
|
||||||
|
|
||||||
|
while (doSearch(true, false, false)) {
|
||||||
|
findCounter++;
|
||||||
|
|
||||||
|
// prevent infinite loops from regular expression searches like "$", "^"
|
||||||
|
// or "\b"
|
||||||
|
if (searchMode == RegularExpressionMode && findCounter >= 10000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection extra = QTextEdit::ExtraSelection();
|
||||||
|
extra.format = extraFmt;
|
||||||
|
|
||||||
|
extra.cursor = _textEdit->textCursor();
|
||||||
|
_searchExtraSelections.append(extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
_textEdit->setTextCursor(textCursor);
|
||||||
|
this->setSearchExtraSelections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::setSearchExtraSelections() const {
|
||||||
|
this->_textEdit->setExtraSelections(this->_searchExtraSelections);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::stopDebounce() {
|
||||||
|
_debounceTimer.stop();
|
||||||
|
ui->searchDownButton->setEnabled(true);
|
||||||
|
ui->searchUpButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::doSearchUp() { doSearch(false); }
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::doSearchDown() { doSearch(true); }
|
||||||
|
|
||||||
bool QPlainTextEditSearchWidget::doReplace(bool forAll) {
|
bool QPlainTextEditSearchWidget::doReplace(bool forAll) {
|
||||||
if (_textEdit->isReadOnly()) {
|
if (_textEdit->isReadOnly()) {
|
||||||
return false;
|
return false;
|
||||||
@ -163,10 +232,10 @@ bool QPlainTextEditSearchWidget::doReplace(bool forAll) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int searchMode = ui->modeComboBox->currentIndex();
|
const int searchMode = ui->modeComboBox->currentIndex();
|
||||||
if (searchMode == RegularExpressionMode) {
|
if (searchMode == RegularExpressionMode) {
|
||||||
QString text = cursor.selectedText();
|
QString text = cursor.selectedText();
|
||||||
text.replace(QRegExp(ui->searchLineEdit->text()),
|
text.replace(QRegularExpression(ui->searchLineEdit->text()),
|
||||||
ui->replaceLineEdit->text());
|
ui->replaceLineEdit->text());
|
||||||
cursor.insertText(text);
|
cursor.insertText(text);
|
||||||
} else {
|
} else {
|
||||||
@ -174,7 +243,7 @@ bool QPlainTextEditSearchWidget::doReplace(bool forAll) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!forAll) {
|
if (!forAll) {
|
||||||
int position = cursor.position();
|
const int position = cursor.position();
|
||||||
|
|
||||||
if (!doSearch(true)) {
|
if (!doSearch(true)) {
|
||||||
// restore the last cursor position if text wasn't found any more
|
// restore the last cursor position if text wasn't found any more
|
||||||
@ -195,53 +264,112 @@ void QPlainTextEditSearchWidget::doReplaceAll() {
|
|||||||
_textEdit->moveCursor(QTextCursor::Start);
|
_textEdit->moveCursor(QTextCursor::Start);
|
||||||
|
|
||||||
// replace until everything to the bottom is replaced
|
// replace until everything to the bottom is replaced
|
||||||
while (doSearch(true, false) && doReplace(true)) {}
|
while (doSearch(true, false) && doReplace(true)) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Searches for text in the text edit
|
* @brief Searches for text in the text edit
|
||||||
* @returns true if found
|
* @returns true if found
|
||||||
*/
|
*/
|
||||||
bool QPlainTextEditSearchWidget::doSearch(bool searchDown, bool allowRestartAtTop) {
|
bool QPlainTextEditSearchWidget::doSearch(bool searchDown,
|
||||||
QString text = ui->searchLineEdit->text();
|
bool allowRestartAtTop,
|
||||||
|
bool updateUI) {
|
||||||
|
if (_debounceTimer.isActive()) {
|
||||||
|
stopDebounce();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString text = ui->searchLineEdit->text();
|
||||||
|
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
if (updateUI) {
|
||||||
|
ui->searchLineEdit->setStyleSheet(QLatin1String(""));
|
||||||
|
}
|
||||||
|
|
||||||
if (text == "") {
|
|
||||||
ui->searchLineEdit->setStyleSheet("");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int searchMode = ui->modeComboBox->currentIndex();
|
const int searchMode = ui->modeComboBox->currentIndex();
|
||||||
|
const bool caseSensitive = ui->matchCaseSensitiveButton->isChecked();
|
||||||
|
|
||||||
QFlags<QTextDocument::FindFlag> options = searchDown ?
|
QFlags<QTextDocument::FindFlag> options =
|
||||||
QTextDocument::FindFlag(0)
|
searchDown ? QTextDocument::FindFlag(0) : QTextDocument::FindBackward;
|
||||||
: QTextDocument::FindBackward;
|
|
||||||
if (searchMode == WholeWordsMode) {
|
if (searchMode == WholeWordsMode) {
|
||||||
options |= QTextDocument::FindWholeWords;
|
options |= QTextDocument::FindWholeWords;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui->matchCaseSensitiveButton->isChecked()) {
|
if (caseSensitive) {
|
||||||
options |= QTextDocument::FindCaseSensitively;
|
options |= QTextDocument::FindCaseSensitively;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found;
|
// block signal to reduce too many signals being fired and too many updates
|
||||||
if (searchMode == RegularExpressionMode) {
|
_textEdit->blockSignals(true);
|
||||||
found = _textEdit->find(QRegExp(text), options);
|
|
||||||
} else {
|
bool found =
|
||||||
found = _textEdit->find(text, options);
|
searchMode == RegularExpressionMode
|
||||||
|
?
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||||
|
_textEdit->find(
|
||||||
|
QRegularExpression(
|
||||||
|
text, caseSensitive
|
||||||
|
? QRegularExpression::NoPatternOption
|
||||||
|
: QRegularExpression::CaseInsensitiveOption),
|
||||||
|
options)
|
||||||
|
:
|
||||||
|
#else
|
||||||
|
_textEdit->find(QRegExp(text, caseSensitive ? Qt::CaseSensitive
|
||||||
|
: Qt::CaseInsensitive),
|
||||||
|
options)
|
||||||
|
:
|
||||||
|
#endif
|
||||||
|
_textEdit->find(text, options);
|
||||||
|
|
||||||
|
_textEdit->blockSignals(false);
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
const int result =
|
||||||
|
searchDown ? ++_currentSearchResult : --_currentSearchResult;
|
||||||
|
_currentSearchResult = std::min(result, _searchResultCount);
|
||||||
|
|
||||||
|
updateSearchCountLabelText();
|
||||||
}
|
}
|
||||||
|
|
||||||
// start at the top (or bottom) if not found
|
// start at the top (or bottom) if not found
|
||||||
if (!found && allowRestartAtTop) {
|
if (!found && allowRestartAtTop) {
|
||||||
_textEdit->moveCursor(
|
_textEdit->moveCursor(searchDown ? QTextCursor::Start
|
||||||
searchDown ? QTextCursor::Start : QTextCursor::End);
|
: QTextCursor::End);
|
||||||
found = _textEdit->find(text, options);
|
found =
|
||||||
|
searchMode == RegularExpressionMode
|
||||||
|
?
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||||
|
_textEdit->find(
|
||||||
|
QRegularExpression(
|
||||||
|
text, caseSensitive
|
||||||
|
? QRegularExpression::NoPatternOption
|
||||||
|
: QRegularExpression::CaseInsensitiveOption),
|
||||||
|
options)
|
||||||
|
:
|
||||||
|
#else
|
||||||
|
_textEdit->find(
|
||||||
|
QRegExp(text, caseSensitive ? Qt::CaseSensitive
|
||||||
|
: Qt::CaseInsensitive),
|
||||||
|
options)
|
||||||
|
:
|
||||||
|
#endif
|
||||||
|
_textEdit->find(text, options);
|
||||||
|
|
||||||
|
if (found && updateUI) {
|
||||||
|
_currentSearchResult = searchDown ? 1 : _searchResultCount;
|
||||||
|
updateSearchCountLabelText();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect rect = _textEdit->cursorRect();
|
if (updateUI) {
|
||||||
|
const QRect rect = _textEdit->cursorRect();
|
||||||
QMargins margins = _textEdit->layout()->contentsMargins();
|
QMargins margins = _textEdit->layout()->contentsMargins();
|
||||||
int searchWidgetHotArea = _textEdit->height() - this->height();
|
const int searchWidgetHotArea = _textEdit->height() - this->height();
|
||||||
int marginBottom = (rect.y() > searchWidgetHotArea) ? (this->height() + 10)
|
const int marginBottom =
|
||||||
: 0;
|
(rect.y() > searchWidgetHotArea) ? (this->height() + 10) : 0;
|
||||||
|
|
||||||
// move the search box a bit up if we would block the search result
|
// move the search box a bit up if we would block the search result
|
||||||
if (margins.bottom() != marginBottom) {
|
if (margins.bottom() != marginBottom) {
|
||||||
@ -250,17 +378,124 @@ bool QPlainTextEditSearchWidget::doSearch(bool searchDown, bool allowRestartAtTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add a background color according if we found the text or not
|
// add a background color according if we found the text or not
|
||||||
QString colorCode = found ? "#D5FAE2" : "#FAE9EB";
|
const QString bgColorCode = _darkMode
|
||||||
|
? (found ? QStringLiteral("#135a13")
|
||||||
|
: QStringLiteral("#8d2b36"))
|
||||||
|
: found ? QStringLiteral("#D5FAE2")
|
||||||
|
: QStringLiteral("#FAE9EB");
|
||||||
|
const QString fgColorCode =
|
||||||
|
_darkMode ? QStringLiteral("#cccccc") : QStringLiteral("#404040");
|
||||||
|
|
||||||
if (_darkMode) {
|
ui->searchLineEdit->setStyleSheet(
|
||||||
colorCode = found ? "#135a13" : "#8d2b36";
|
QStringLiteral("* { background: ") + bgColorCode +
|
||||||
|
QStringLiteral("; color: ") + fgColorCode + QStringLiteral("; }"));
|
||||||
|
|
||||||
|
// restore the search extra selections after the find command
|
||||||
|
this->setSearchExtraSelections();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->searchLineEdit->setStyleSheet("* { background: " + colorCode + "; }");
|
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Counts the search results
|
||||||
|
*/
|
||||||
|
void QPlainTextEditSearchWidget::doSearchCount() {
|
||||||
|
// Note that we are moving the anchor, so the search will start from the top
|
||||||
|
// again! Alternative: Restore cursor position afterward, but then we will
|
||||||
|
// not know
|
||||||
|
// at what _currentSearchResult we currently are
|
||||||
|
_textEdit->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||||
|
|
||||||
|
bool found;
|
||||||
|
_searchResultCount = 0;
|
||||||
|
_currentSearchResult = 0;
|
||||||
|
const int searchMode = ui->modeComboBox->currentIndex();
|
||||||
|
|
||||||
|
do {
|
||||||
|
found = doSearch(true, false, false);
|
||||||
|
if (found) {
|
||||||
|
_searchResultCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent infinite loops from regular expression searches like "$", "^"
|
||||||
|
// or "\b"
|
||||||
|
if (searchMode == RegularExpressionMode &&
|
||||||
|
_searchResultCount >= 10000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (found);
|
||||||
|
|
||||||
|
updateSearchCountLabelText();
|
||||||
|
}
|
||||||
|
|
||||||
void QPlainTextEditSearchWidget::setDarkMode(bool enabled) {
|
void QPlainTextEditSearchWidget::setDarkMode(bool enabled) {
|
||||||
_darkMode = enabled;
|
_darkMode = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::setSearchText(const QString &searchText) {
|
||||||
|
ui->searchLineEdit->setText(searchText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::setSearchMode(SearchMode searchMode) {
|
||||||
|
ui->modeComboBox->setCurrentIndex(searchMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::setDebounceDelay(uint debounceDelay) {
|
||||||
|
_debounceTimer.setInterval(static_cast<int>(debounceDelay));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::activate(bool focus) {
|
||||||
|
setReplaceMode(ui->modeComboBox->currentIndex() !=
|
||||||
|
SearchMode::PlainTextMode);
|
||||||
|
show();
|
||||||
|
|
||||||
|
// preset the selected text as search text if there is any and there is no
|
||||||
|
// other search text
|
||||||
|
const QString selectedText = _textEdit->textCursor().selectedText();
|
||||||
|
if (!selectedText.isEmpty() && ui->searchLineEdit->text().isEmpty()) {
|
||||||
|
ui->searchLineEdit->setText(selectedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focus) {
|
||||||
|
ui->searchLineEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->searchLineEdit->selectAll();
|
||||||
|
updateSearchExtraSelections();
|
||||||
|
doSearchDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::reset() {
|
||||||
|
ui->searchLineEdit->clear();
|
||||||
|
setSearchMode(SearchMode::PlainTextMode);
|
||||||
|
setReplaceMode(false);
|
||||||
|
ui->searchCountLabel->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::updateSearchCountLabelText() {
|
||||||
|
ui->searchCountLabel->setEnabled(true);
|
||||||
|
ui->searchCountLabel->setText(QStringLiteral("%1/%2").arg(
|
||||||
|
_currentSearchResult == 0 ? QChar('-')
|
||||||
|
: QString::number(_currentSearchResult),
|
||||||
|
_searchResultCount == 0 ? QChar('-')
|
||||||
|
: QString::number(_searchResultCount)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::setSearchSelectionColor(const QColor &color) {
|
||||||
|
selectionColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::on_modeComboBox_currentIndexChanged(
|
||||||
|
int index) {
|
||||||
|
Q_UNUSED(index)
|
||||||
|
doSearchCount();
|
||||||
|
doSearchDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QPlainTextEditSearchWidget::on_matchCaseSensitiveButton_toggled(
|
||||||
|
bool checked) {
|
||||||
|
Q_UNUSED(checked)
|
||||||
|
doSearchCount();
|
||||||
|
doSearchDown();
|
||||||
|
}
|
||||||
|
|||||||
@ -1,51 +1,73 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2019 Patrizio Bekerle -- http://www.bekerle.com
|
* MIT License
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2014-2025 Patrizio Bekerle -- <patrizio@bekerle.com>
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* in the Software without restriction, including without limitation the rights
|
||||||
* for more details.
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class QPlainTextEditSearchWidget;
|
class QPlainTextEditSearchWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
class QPlainTextEditSearchWidget : public QWidget
|
class QPlainTextEditSearchWidget : public QWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum SearchMode {
|
enum SearchMode { PlainTextMode, WholeWordsMode, RegularExpressionMode };
|
||||||
PlainTextMode,
|
|
||||||
WholeWordsMode,
|
|
||||||
RegularExpressionMode
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit QPlainTextEditSearchWidget(QPlainTextEdit *parent = 0);
|
explicit QPlainTextEditSearchWidget(QPlainTextEdit *parent = nullptr);
|
||||||
bool doSearch(bool searchDown = true, bool allowRestartAtTop = true);
|
bool doSearch(bool searchDown = true, bool allowRestartAtTop = true,
|
||||||
|
bool updateUI = true);
|
||||||
void setDarkMode(bool enabled);
|
void setDarkMode(bool enabled);
|
||||||
~QPlainTextEditSearchWidget();
|
~QPlainTextEditSearchWidget();
|
||||||
|
|
||||||
private:
|
void setSearchText(const QString &searchText);
|
||||||
Ui::QPlainTextEditSearchWidget *ui;
|
void setSearchMode(SearchMode searchMode);
|
||||||
|
void setDebounceDelay(uint debounceDelay);
|
||||||
|
void activate(bool focus);
|
||||||
|
void clearSearchExtraSelections();
|
||||||
|
void updateSearchExtraSelections();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
Ui::QPlainTextEditSearchWidget *ui;
|
||||||
|
int _searchResultCount;
|
||||||
|
int _currentSearchResult;
|
||||||
|
QList<QTextEdit::ExtraSelection> _searchExtraSelections;
|
||||||
|
QColor selectionColor;
|
||||||
|
QTimer _debounceTimer;
|
||||||
|
QString _searchTerm;
|
||||||
|
void setSearchExtraSelections() const;
|
||||||
|
void stopDebounce();
|
||||||
|
|
||||||
|
protected:
|
||||||
QPlainTextEdit *_textEdit;
|
QPlainTextEdit *_textEdit;
|
||||||
bool _darkMode;
|
bool _darkMode;
|
||||||
bool eventFilter(QObject *obj, QEvent *event);
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
public slots:
|
public Q_SLOTS:
|
||||||
void activate();
|
void activate();
|
||||||
void deactivate();
|
void deactivate();
|
||||||
void doSearchDown();
|
void doSearchDown();
|
||||||
@ -54,7 +76,15 @@ public slots:
|
|||||||
void activateReplace();
|
void activateReplace();
|
||||||
bool doReplace(bool forAll = false);
|
bool doReplace(bool forAll = false);
|
||||||
void doReplaceAll();
|
void doReplaceAll();
|
||||||
|
void reset();
|
||||||
|
void doSearchCount();
|
||||||
|
|
||||||
protected slots:
|
protected Q_SLOTS:
|
||||||
void searchLineEditTextChanged(const QString &arg1);
|
void searchLineEditTextChanged(const QString &arg1);
|
||||||
|
void performSearch();
|
||||||
|
void updateSearchCountLabelText();
|
||||||
|
void setSearchSelectionColor(const QColor &color);
|
||||||
|
private Q_SLOTS:
|
||||||
|
void on_modeComboBox_currentIndexChanged(int index);
|
||||||
|
void on_matchCaseSensitiveButton_toggled(bool checked);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,10 +26,85 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QLineEdit" name="searchLineEdit">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Find in text</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="replaceLineEdit">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Replace with</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4">
|
||||||
|
<widget class="QLabel" name="searchCountLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">-/-</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="searchLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Find:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="6">
|
<item row="0" column="6">
|
||||||
|
<widget class="QPushButton" name="searchUpButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Search backward</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-top" resource="media.qrc">
|
||||||
|
<normaloff>:/media/go-top.svg</normaloff>:/media/go-top.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="replaceLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Replace:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPushButton" name="closeButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Close search</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="window-close" resource="media.qrc">
|
||||||
|
<normaloff>:/media/window-close.svg</normaloff>:/media/window-close.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="7">
|
||||||
<widget class="QPushButton" name="replaceToggleButton">
|
<widget class="QPushButton" name="replaceToggleButton">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>replace text</string>
|
<string>Advanced search / replace text</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@ -46,44 +121,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="5">
|
||||||
<widget class="QLabel" name="searchLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Find:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QPushButton" name="closeButton">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>close search</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="window-close" resource="media.qrc">
|
|
||||||
<normaloff>:/media/window-close.svg</normaloff>:/media/window-close.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QLineEdit" name="searchLineEdit">
|
|
||||||
<property name="placeholderText">
|
|
||||||
<string>find in text</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="4">
|
|
||||||
<widget class="QPushButton" name="searchDownButton">
|
<widget class="QPushButton" name="searchDownButton">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>search forward</string>
|
<string>Search forward</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@ -97,41 +138,37 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="5">
|
<item row="1" column="5">
|
||||||
<widget class="QPushButton" name="searchUpButton">
|
<widget class="QPushButton" name="matchCaseSensitiveButton">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>search backward</string>
|
<string>Match case sensitive</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="go-top" resource="media.qrc">
|
<iconset theme="format-text-superscript" resource="media.qrc">
|
||||||
<normaloff>:/media/go-top.svg</normaloff>:/media/go-top.svg</iconset>
|
<normaloff>:/media/format-text-superscript.svg</normaloff>:/media/format-text-superscript.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="3">
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="QLineEdit" name="replaceLineEdit">
|
<widget class="QLabel" name="modeLabel">
|
||||||
<property name="placeholderText">
|
|
||||||
<string>replace with</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="replaceLabel">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Replace:</string>
|
<string>Mode:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="3">
|
<item row="2" column="3" colspan="2">
|
||||||
<widget class="QFrame" name="buttonFrame">
|
<widget class="QFrame" name="buttonFrame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
@ -147,7 +184,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>9</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="modeComboBox">
|
<widget class="QComboBox" name="modeComboBox">
|
||||||
@ -183,6 +220,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="replaceButton">
|
<widget class="QPushButton" name="replaceButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Replace one text occurrence</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Replace</string>
|
<string>Replace</string>
|
||||||
</property>
|
</property>
|
||||||
@ -193,8 +233,11 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="replaceAllButton">
|
<widget class="QPushButton" name="replaceAllButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Replace all text occurrences</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Replace All</string>
|
<string>Replace all</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -204,36 +247,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="modeLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Mode:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="4">
|
|
||||||
<widget class="QPushButton" name="matchCaseSensitiveButton">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Match case sensitive</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="format-text-superscript" resource="media.qrc">
|
|
||||||
<normaloff>:/media/format-text-superscript.svg</normaloff>:/media/format-text-superscript.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 24 KiB |
28
client/qmarkdowntextedit/scripts/clang-format-project.sh
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# A tool to run clang-format on the entire project
|
||||||
|
#
|
||||||
|
# Some inspirations were taken from https://github.com/eklitzke/clang-format-all
|
||||||
|
|
||||||
|
# Variable that will hold the name of the clang-format command
|
||||||
|
FMT=""
|
||||||
|
|
||||||
|
# Some distros just call it clang-format. Others (e.g. Ubuntu) are insistent
|
||||||
|
# that the version number be part of the command. We prefer clang-format if
|
||||||
|
# that's present, otherwise we work backwards from highest version to lowest
|
||||||
|
# version.
|
||||||
|
for clangfmt in clang-format{,-{4,3}.{9,8,7,6,5,4,3,2,1,0}}; do
|
||||||
|
if which "$clangfmt" &>/dev/null; then
|
||||||
|
FMT="$clangfmt"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if we found a working clang-format
|
||||||
|
if [ -z "$FMT" ]; then
|
||||||
|
echo "failed to find clang-format"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$FMT -i *.cpp
|
||||||
|
$FMT -i *.h
|
||||||
BIN
client/qmarkdowntextedit/trans/qmarkdowntextedit_es.qm
Normal file
92
client/qmarkdowntextedit/trans/qmarkdowntextedit_es.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="es_ES">
|
||||||
|
<context>
|
||||||
|
<name>QPlainTextEditSearchWidget</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="32"/>
|
||||||
|
<source>Find in text</source>
|
||||||
|
<translation>Buscar en el texto</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="39"/>
|
||||||
|
<source>Replace with</source>
|
||||||
|
<translation>Reemplazar por</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="53"/>
|
||||||
|
<source>Find:</source>
|
||||||
|
<translation>Buscar:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="63"/>
|
||||||
|
<source>Search backward</source>
|
||||||
|
<translation>Buscar hacia atrás</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="80"/>
|
||||||
|
<source>Replace:</source>
|
||||||
|
<translation>Reemplazar:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="90"/>
|
||||||
|
<source>Close search</source>
|
||||||
|
<translation>Cerrar búsqueda</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="107"/>
|
||||||
|
<source>Advanced search / replace text</source>
|
||||||
|
<translation>Búsqueda avanzada / reemplazar texto</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="127"/>
|
||||||
|
<source>Search forward</source>
|
||||||
|
<translation>Buscar hacia adelante</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="144"/>
|
||||||
|
<source>Match case sensitive</source>
|
||||||
|
<translation>Distingue mayúsculas y minúsculas</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="164"/>
|
||||||
|
<source>Mode:</source>
|
||||||
|
<translation>Modo:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="193"/>
|
||||||
|
<source>Plain text</source>
|
||||||
|
<translation>Texto plano</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="198"/>
|
||||||
|
<source>Whole words</source>
|
||||||
|
<translation>Palabras enteras</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="203"/>
|
||||||
|
<source>Regular expression</source>
|
||||||
|
<translation>Expresión regular</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="224"/>
|
||||||
|
<source>Replace one text occurrence</source>
|
||||||
|
<translation>Reemplazar una ocurrencia del texto</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="227"/>
|
||||||
|
<source>Replace</source>
|
||||||
|
<translation>Reemplazar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="237"/>
|
||||||
|
<source>Replace all text occurrences</source>
|
||||||
|
<translation>Reemplazar todas las ocurrencias del texto</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="240"/>
|
||||||
|
<source>Replace all</source>
|
||||||
|
<translation>Reemplazar todo</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
BIN
client/qmarkdowntextedit/trans/qmarkdowntextedit_ur.qm
Normal file
57
client/qmarkdowntextedit/trans/qmarkdowntextedit_ur.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="ur_PK">
|
||||||
|
<context>
|
||||||
|
<name>QPlainTextEditSearchWidget</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="62"/>
|
||||||
|
<source>close search</source>
|
||||||
|
<translation>تلاش بند کریں</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="52"/>
|
||||||
|
<source>Find:</source>
|
||||||
|
<translation>تلاش:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="32"/>
|
||||||
|
<source>replace text</source>
|
||||||
|
<translation>ٹیکصٹ بدلیں</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="79"/>
|
||||||
|
<source>find in text</source>
|
||||||
|
<translation>متن میں تلاش کریں</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="86"/>
|
||||||
|
<source>search forward</source>
|
||||||
|
<translation>آگے تلاش کریں</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="103"/>
|
||||||
|
<source>search backward</source>
|
||||||
|
<translation>پیچھے تلاش کریں</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="120"/>
|
||||||
|
<source>replace with</source>
|
||||||
|
<translation>بدلیں اس سے</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="127"/>
|
||||||
|
<source>Replace:</source>
|
||||||
|
<translation>بدلیں:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="168"/>
|
||||||
|
<source>Replace</source>
|
||||||
|
<translation>بدلیں</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="178"/>
|
||||||
|
<source>Replace All</source>
|
||||||
|
<translation>تمام کو بدل دیں</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
BIN
client/qmarkdowntextedit/trans/qmarkdowntextedit_zh_CN.qm
Normal file
92
client/qmarkdowntextedit/trans/qmarkdowntextedit_zh_CN.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="zh_CN">
|
||||||
|
<context>
|
||||||
|
<name>QPlainTextEditSearchWidget</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="32"/>
|
||||||
|
<source>Find in text</source>
|
||||||
|
<translation>在文本中查找</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="39"/>
|
||||||
|
<source>Replace with</source>
|
||||||
|
<translation>替换为</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="53"/>
|
||||||
|
<source>Find:</source>
|
||||||
|
<translation>查找</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="63"/>
|
||||||
|
<source>Search backward</source>
|
||||||
|
<translation>上一个匹配项</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="80"/>
|
||||||
|
<source>Replace:</source>
|
||||||
|
<translation>替换</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="90"/>
|
||||||
|
<source>Close search</source>
|
||||||
|
<translation>关闭搜索框</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="107"/>
|
||||||
|
<source>Advanced search / replace text</source>
|
||||||
|
<translation>高级搜索/替换</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="127"/>
|
||||||
|
<source>Search forward</source>
|
||||||
|
<translation>下一个匹配项</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="144"/>
|
||||||
|
<source>Match case sensitive</source>
|
||||||
|
<translation>区分大小写</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="164"/>
|
||||||
|
<source>Mode:</source>
|
||||||
|
<translation>模式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="193"/>
|
||||||
|
<source>Plain text</source>
|
||||||
|
<translation>字符匹配</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="198"/>
|
||||||
|
<source>Whole words</source>
|
||||||
|
<translation>全字匹配</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="203"/>
|
||||||
|
<source>Regular expression</source>
|
||||||
|
<translation>正则表达式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="224"/>
|
||||||
|
<source>Replace one text occurrence</source>
|
||||||
|
<translation>替换第一个匹配的文本</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="227"/>
|
||||||
|
<source>Replace</source>
|
||||||
|
<translation>替换</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="237"/>
|
||||||
|
<source>Replace all text occurrences</source>
|
||||||
|
<translation>替换所有匹配的文本</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qplaintexteditsearchwidget.ui" line="240"/>
|
||||||
|
<source>Replace all</source>
|
||||||
|
<translation>全部替换</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
39
client/qmarkdowntextedit/treefmt.toml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# https://github.com/numtide/treefmt
|
||||||
|
# https://github.com/numtide/treefmt-nix
|
||||||
|
|
||||||
|
on-unmatched = "info"
|
||||||
|
|
||||||
|
[formatter.clang-format]
|
||||||
|
command = "clang-format"
|
||||||
|
|
||||||
|
# Only target the exact directories we want
|
||||||
|
includes = [
|
||||||
|
"*.cpp",
|
||||||
|
"*.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
[formatter.prettier]
|
||||||
|
command = "prettier"
|
||||||
|
options = ["--write"]
|
||||||
|
includes = ["*.md", "*.yaml", "*.yml"]
|
||||||
|
|
||||||
|
[formatter.shfmt]
|
||||||
|
command = "shfmt"
|
||||||
|
excludes = []
|
||||||
|
includes = ["*.sh", "*.bash", "*.envrc", "*.envrc.*"]
|
||||||
|
options = ["-s", "-w", "-i", "2"]
|
||||||
|
|
||||||
|
[formatter.just]
|
||||||
|
command = "just"
|
||||||
|
includes = ["*.just"]
|
||||||
|
|
||||||
|
[formatter.taplo]
|
||||||
|
command = "taplo"
|
||||||
|
includes = ["*.toml"]
|
||||||
|
options = ["format"]
|
||||||
|
|
||||||
|
[formatter.nixfmt-rfc-style]
|
||||||
|
command = "nixfmt"
|
||||||
|
excludes = []
|
||||||
|
includes = ["*.nix"]
|
||||||
|
options = []
|
||||||
@ -608,7 +608,7 @@ int TimeLine::getTime(int year, int month, int day, std::vector<TimeRecord>* int
|
|||||||
// Find range of related records [lowest, higher)
|
// Find range of related records [lowest, higher)
|
||||||
TimeArray::iterator lowest = std::lower_bound(mData.begin(), mData.end(), d, [] (const TimeRecord& tr, const QDate& d)
|
TimeArray::iterator lowest = std::lower_bound(mData.begin(), mData.end(), d, [] (const TimeRecord& tr, const QDate& d)
|
||||||
{
|
{
|
||||||
return tr.endTime() < QDateTime(d).toTime_t();
|
return tr.endTime() < QDateTime(d, QTime()).toSecsSinceEpoch();
|
||||||
});
|
});
|
||||||
//TimeArray::iterator higher = std::upper_bound(mData.begin(), mData.end(), d, [] (const QDate& d, const TimeRecord& tr) { return tr.startTime().toLocalTime().date() < d;});
|
//TimeArray::iterator higher = std::upper_bound(mData.begin(), mData.end(), d, [] (const QDate& d, const TimeRecord& tr) { return tr.startTime().toLocalTime().date() < d;});
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,9 @@ QDateTime TimeIntervalDlg::finishDate()
|
|||||||
void TimeIntervalDlg::accept()
|
void TimeIntervalDlg::accept()
|
||||||
{
|
{
|
||||||
// Insert interval
|
// Insert interval
|
||||||
mModel->insertInterval(TimeRecord(startDate().toUTC().toTime_t(), finishDate().toUTC().toTime_t(), mTimeline->taskId()));
|
mModel->insertInterval(TimeRecord(startDate().toUTC().toSecsSinceEpoch(),
|
||||||
|
finishDate().toUTC().toSecsSinceEpoch(),
|
||||||
|
mTimeline->taskId()));
|
||||||
emit accepted();
|
emit accepted();
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
@ -68,7 +70,9 @@ void TimeIntervalDlg::closeEvent(QCloseEvent *event)
|
|||||||
bool TimeIntervalDlg::validate()
|
bool TimeIntervalDlg::validate()
|
||||||
{
|
{
|
||||||
assert(mTimeline);
|
assert(mTimeline);
|
||||||
return !mTimeline->hasIntersection(TimeRecord(startDate().toUTC().toTime_t(), finishDate().toUTC().toTime_t(), mTimeline->taskId()));
|
return !mTimeline->hasIntersection(TimeRecord(startDate().toUTC().toSecsSinceEpoch(),
|
||||||
|
finishDate().toUTC().toSecsSinceEpoch(),
|
||||||
|
mTimeline->taskId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeIntervalDlg::dataChanged(const QDateTime& changed)
|
void TimeIntervalDlg::dataChanged(const QDateTime& changed)
|
||||||
|
|||||||
@ -275,7 +275,7 @@ int TimeTreeModel::columnCount(const QModelIndex &parent) const
|
|||||||
|
|
||||||
static QString monthToString(int month)
|
static QString monthToString(int month)
|
||||||
{
|
{
|
||||||
return QDate::longMonthName(month);
|
return QLocale::system().monthName(month);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant TimeTreeModel::data(const QModelIndex &index, int role) const
|
QVariant TimeTreeModel::data(const QModelIndex &index, int role) const
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
# I use this script on two different hosts so there are logic to find proper Qt installation
|
# I use this script on two different hosts so there are logic to find proper Qt installation
|
||||||
|
|
||||||
export QT_HOME=/home/$USER/qt5.15/5.15.2/gcc_64
|
export QT_HOME=/home/$USER/tools/qt/6.8.0/gcc_64
|
||||||
if [ ! -d "$QT_HOME" ] ; then
|
if [ ! -d "$QT_HOME" ] ; then
|
||||||
export QT_HOME=/home/$USER/qt5.15/5.15.2/gcc_64
|
export QT_HOME=/home/$USER/tools/qt/6.8.0/gcc_64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build .appimage
|
# Build .appimage
|
||||||
|
|||||||