initial commit
This commit is contained in:
commit
a75a4aeee8
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Common build folder
|
||||||
|
[Bb]uild/
|
||||||
|
|
||||||
|
# IDE stuff
|
||||||
|
CMakeLists.txt.user*
|
51
CMakeLists.txt
Normal file
51
CMakeLists.txt
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# SPDX-FileCopyrightText: 2024 Gary Wang <git@blumia.net>
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.9.5)
|
||||||
|
|
||||||
|
project(pineapple-notepad)
|
||||||
|
|
||||||
|
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
|
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON) # kconfig generated header file is in binary dir
|
||||||
|
|
||||||
|
find_package(Qt6 6.4 REQUIRED
|
||||||
|
COMPONENTS Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package(KF6 6.3 REQUIRED
|
||||||
|
COMPONENTS XmlGui ConfigWidgets CoreAddons I18n IconThemes
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(pineapple-notepad
|
||||||
|
generalsettings.ui)
|
||||||
|
|
||||||
|
target_sources(pineapple-notepad
|
||||||
|
PRIVATE
|
||||||
|
main.cpp
|
||||||
|
mainwindow.cpp mainwindow.h
|
||||||
|
generalsettings.ui
|
||||||
|
|
||||||
|
appsettings.kcfg
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_resources(pineapple-notepad xmlgui.qrc
|
||||||
|
PREFIX "/kxmlgui5/pineapple-notepad"
|
||||||
|
FILES pineapple-notepadui.rc
|
||||||
|
)
|
||||||
|
|
||||||
|
kconfig_add_kcfg_files(pineapple-notepad GENERATE_MOC appsettings.kcfgc)
|
||||||
|
|
||||||
|
target_link_libraries(pineapple-notepad
|
||||||
|
PRIVATE
|
||||||
|
Qt6::Widgets
|
||||||
|
KF6::XmlGui
|
||||||
|
KF6::CoreAddons
|
||||||
|
KF6::I18n
|
||||||
|
KF6::ConfigWidgets
|
||||||
|
KF6::IconThemes
|
||||||
|
qscintilla2_qt6
|
||||||
|
)
|
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Pineapple Notepad?
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
|
||||||
|
这是一个用来实验 KDE Framework 的项目(主要是 Widgets 相关的组件),此项目本身(至少目前)不是一个能用的文本编辑器,甚至可以说实际上什么功能都没有。
|
||||||
|
|
||||||
|
现阶段,MSYS2 仓库的 KF6 组件已足以构建基本的应用程序,并包括一些优点。
|
||||||
|
|
||||||
|
- KXmlGui: 提供了一个便于创建与管理 QAction 的框架,可以便于将 Action 注册到菜单栏、工具栏,甚至还有一个命令搜索条。工具栏中的项目可由用户自由调整。`xxxxui.rc`
|
||||||
|
- KConfig: 提供了一个基于 XML 文件生成配置管理工具类的解决方案。`xxx.kcfg`(配置文件结构本体)与 `xxx.kcfgc`(如何生成工具类的配置)
|
||||||
|
- KConfigWidgets: 一系列配套组件,包括:
|
||||||
|
- KConfigDialog: 提供一个包括多个页的配置对话框,将若干页面加入此对话框,且根据 KConfig 生成的工具类自动更新每个页面的控件(页面内的控件需使用 `kcfg_配置名称` 作为对象名称)。
|
||||||
|
- KHamburgerMenu: 汉堡菜单
|
||||||
|
- KStyleManager: 用于初始化 breeze 主题(和配置似乎没啥关系..)
|
||||||
|
- KColorSchemeMenu: 提供切换主题的菜单项(MSYS2 下,KColorSchemeMenu 实际列出的可用主题只有默认和暗色两个?)
|
||||||
|
- KIconTheme: 初始化图标主题,需要在 QApplication 构造之前调用初始化,并且看上去需要配合什么别的东西才能做到颜色正确...
|
17
appsettings.kcfg
Normal file
17
appsettings.kcfg
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||||
|
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||||
|
<kcfgfile name="pineapple-notepadrc" />
|
||||||
|
<include>QFontDatabase</include>
|
||||||
|
<group name="Editor">
|
||||||
|
<entry name="tabWidth" type="int">
|
||||||
|
<default>4</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="editorFont" type="Font" key="editor-font">
|
||||||
|
<default code="true">QFontDatabase::systemFont(QFontDatabase::FixedFont)</default>
|
||||||
|
</entry>
|
||||||
|
</group>
|
||||||
|
</kcfg>
|
8
appsettings.kcfgc
Normal file
8
appsettings.kcfgc
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
File=appsettings.kcfg
|
||||||
|
ClassName=AppSettings
|
||||||
|
Mutators=true
|
||||||
|
DefaultValueGetters=true
|
||||||
|
GenerateProperties=true
|
||||||
|
ParentInConstructor=true
|
||||||
|
Notifiers=true
|
||||||
|
Singleton=true
|
58
generalsettings.ui
Normal file
58
generalsettings.ui
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>GeneralSettings</class>
|
||||||
|
<widget class="QWidget" name="GeneralSettings">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>406</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>tAB wIDTH</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="kcfg_tabWidth">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>eDITOR fONT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="KFontRequester" name="kcfg_editorFont"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>KFontRequester</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>kfontrequester.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
35
main.cpp
Normal file
35
main.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include <KAboutData>
|
||||||
|
#include <KLocalizedString>
|
||||||
|
#include <KIconTheme>
|
||||||
|
#include <KStyleManager>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
KIconTheme::initTheme();
|
||||||
|
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
KStyleManager::initStyle();
|
||||||
|
|
||||||
|
KLocalizedString::setApplicationDomain(QByteArrayLiteral("pineapple-notepad"));
|
||||||
|
|
||||||
|
KAboutData aboutData(QStringLiteral("pineapple-notepad"),
|
||||||
|
"Pineapple Notepad(迫真)",
|
||||||
|
QStringLiteral("0.1"),
|
||||||
|
"A Scintilla-based Text Editor",
|
||||||
|
KAboutLicense::Unknown,
|
||||||
|
QString(),
|
||||||
|
QString(),
|
||||||
|
QStringLiteral("https://blumia.net"));
|
||||||
|
KAboutData::setApplicationData(aboutData);
|
||||||
|
a.setWindowIcon(QIcon::fromTheme(QStringLiteral("accessories-text-editor")));
|
||||||
|
|
||||||
|
MainWindow mw;
|
||||||
|
mw.show();
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
149
mainwindow.cpp
Normal file
149
mainwindow.cpp
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include "appsettings.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include <KActionCollection>
|
||||||
|
#include <KStandardAction>
|
||||||
|
#include <KActionMenu>
|
||||||
|
#include <KConfigDialog>
|
||||||
|
#include <KColorSchemeManager>
|
||||||
|
#include <KColorSchemeMenu>
|
||||||
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
#include <Qsci/qsciscintilla.h>
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: KXmlGuiWindow(parent)
|
||||||
|
, m_editor(new QsciScintilla(this))
|
||||||
|
{
|
||||||
|
setCentralWidget(m_editor);
|
||||||
|
|
||||||
|
QFont font(AppSettings::self()->editorFont());
|
||||||
|
m_editor->setFont(font);
|
||||||
|
m_editor->setMarginsFont(font);
|
||||||
|
|
||||||
|
m_editor->setMarginLineNumbers(1, true);
|
||||||
|
m_editor->setMarginWidth(1, 40);
|
||||||
|
m_editor->setBraceMatching(QsciScintilla::SloppyBraceMatch);
|
||||||
|
|
||||||
|
m_editor->setTabWidth(AppSettings::self()->tabWidth());
|
||||||
|
m_editor->setEolMode(QsciScintilla::EolUnix);
|
||||||
|
|
||||||
|
setupActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupActions()
|
||||||
|
{
|
||||||
|
using namespace Qt::Literals::StringLiterals;
|
||||||
|
|
||||||
|
// "File" menu
|
||||||
|
KStandardAction::openNew(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::open(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::save(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::close(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::quit(qApp, &QApplication::quit, actionCollection());
|
||||||
|
|
||||||
|
// "Edit" menu
|
||||||
|
KStandardAction::undo(this, [this](){
|
||||||
|
m_editor->undo();
|
||||||
|
}, actionCollection());
|
||||||
|
KStandardAction::redo(this, [this](){
|
||||||
|
m_editor->redo();
|
||||||
|
}, actionCollection());
|
||||||
|
KStandardAction::cut(this, [this](){
|
||||||
|
m_editor->cut();
|
||||||
|
}, actionCollection());
|
||||||
|
KStandardAction::copy(this, [this](){
|
||||||
|
m_editor->copy();
|
||||||
|
}, actionCollection());
|
||||||
|
KStandardAction::paste(this, [this](){
|
||||||
|
m_editor->paste();
|
||||||
|
}, actionCollection());
|
||||||
|
|
||||||
|
// "Search" menu
|
||||||
|
KStandardAction::find(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::findNext(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::findPrev(this, [](){}, actionCollection());
|
||||||
|
KStandardAction::replace(this, [](){}, actionCollection());
|
||||||
|
qDebug() << KStandardAction::name(KStandardAction::Replace);
|
||||||
|
|
||||||
|
// "Language" menu
|
||||||
|
QAction *lexerNoneAction = new QAction(this);
|
||||||
|
lexerNoneAction->setText("None (Normal Text)");
|
||||||
|
actionCollection()->addAction(u"lexer_none"_s, lexerNoneAction);
|
||||||
|
connect(lexerNoneAction, &QAction::triggered, this, [this](){
|
||||||
|
m_editor->setLexer(nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toolbar actions
|
||||||
|
KStandardAction::zoomIn(this, [this](){
|
||||||
|
m_editor->zoomIn();
|
||||||
|
}, actionCollection());
|
||||||
|
KStandardAction::zoomOut(this, [this](){
|
||||||
|
m_editor->zoomOut();
|
||||||
|
}, actionCollection());
|
||||||
|
|
||||||
|
KStandardAction::preferences(this, &MainWindow::showSettings, actionCollection());
|
||||||
|
|
||||||
|
QAction *toggleWrapModeAction = new QAction(this);
|
||||||
|
toggleWrapModeAction->setText("Toggle Wrap Mode");
|
||||||
|
toggleWrapModeAction->setIcon(QIcon::fromTheme(u"text-wrap"_s));
|
||||||
|
toggleWrapModeAction->setCheckable(true);
|
||||||
|
actionCollection()->addAction(u"toggle_wrap_mode"_s, toggleWrapModeAction);
|
||||||
|
connect(toggleWrapModeAction, &QAction::triggered, this, [this, toggleWrapModeAction](){
|
||||||
|
bool switchToWrapNone = m_editor->wrapMode() == QsciScintilla::WrapWord;
|
||||||
|
m_editor->setWrapMode(switchToWrapNone ? QsciScintilla::WrapNone : QsciScintilla::WrapWord);
|
||||||
|
toggleWrapModeAction->setChecked(!switchToWrapNone);
|
||||||
|
});
|
||||||
|
|
||||||
|
QAction *toggleWhitespaceVisibilityAction = new QAction(this);
|
||||||
|
toggleWhitespaceVisibilityAction->setText("Show All Characters");
|
||||||
|
toggleWhitespaceVisibilityAction->setCheckable(true);
|
||||||
|
// toggleWhitespaceVisibilityAction->setIcon(QIcon::fromTheme(u"text-wrap"_s));
|
||||||
|
actionCollection()->addAction(u"toggle_show_all_characters"_s, toggleWhitespaceVisibilityAction);
|
||||||
|
connect(toggleWhitespaceVisibilityAction, &QAction::triggered, this, [this, toggleWhitespaceVisibilityAction](){
|
||||||
|
bool switchToVisible = m_editor->whitespaceVisibility() == QsciScintilla::WsInvisible;
|
||||||
|
m_editor->setWhitespaceVisibility(switchToVisible ? QsciScintilla::WsVisible : QsciScintilla::WsInvisible);
|
||||||
|
m_editor->setEolVisibility(switchToVisible);
|
||||||
|
toggleWhitespaceVisibilityAction->setChecked(switchToVisible);
|
||||||
|
});
|
||||||
|
|
||||||
|
QAction *toggleIndentGuideAction = new QAction(this);
|
||||||
|
toggleIndentGuideAction->setText("Toggle Indent Guide");
|
||||||
|
toggleIndentGuideAction->setIcon(QIcon::fromTheme(u"show-guides"_s));
|
||||||
|
actionCollection()->addAction(u"toggle_indent_guide"_s, toggleIndentGuideAction);
|
||||||
|
connect(toggleIndentGuideAction, &QAction::triggered, this, [this](){
|
||||||
|
m_editor->setIndentationGuides(!m_editor->indentationGuides());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load themes
|
||||||
|
KColorSchemeManager *manager = new KColorSchemeManager(this);
|
||||||
|
auto *colorSelectionMenu = KColorSchemeMenu::createMenu(manager, this);
|
||||||
|
colorSelectionMenu->menu()->setTitle("&Window Color Scheme");
|
||||||
|
actionCollection()->addAction(QStringLiteral("colorscheme_menu"), colorSelectionMenu);
|
||||||
|
|
||||||
|
setupGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showSettings()
|
||||||
|
{
|
||||||
|
if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
KConfigDialog *dialog = new KConfigDialog(this, QStringLiteral("settings"), AppSettings::self());
|
||||||
|
dialog->setFaceType(KPageDialog::FlatList);
|
||||||
|
dialog->addPage(new SettingsPage<Ui::GeneralSettings>(dialog), "Appearance", "preferences-desktop-theme-global");
|
||||||
|
|
||||||
|
connect(dialog, &KConfigDialog::settingsChanged, this, [](const QString &dialogName){
|
||||||
|
qDebug() << dialogName << "changed";
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog->show();
|
||||||
|
}
|
35
mainwindow.h
Normal file
35
mainwindow.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <KXmlGuiWindow>
|
||||||
|
|
||||||
|
#include "ui_GeneralSettings.h"
|
||||||
|
|
||||||
|
class QsciScintilla;
|
||||||
|
class MainWindow : public KXmlGuiWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupActions();
|
||||||
|
void showSettings();
|
||||||
|
|
||||||
|
QsciScintilla * m_editor;
|
||||||
|
};
|
||||||
|
|
||||||
|
// plainly for KConfigDialog
|
||||||
|
// void setupUi(QWidget *GeneralSettings)
|
||||||
|
template <typename T>
|
||||||
|
class SettingsPage : public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SettingsPage(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
ui.setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T ui;
|
||||||
|
};
|
51
pineapple-notepadui.rc
Normal file
51
pineapple-notepadui.rc
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
DTD: https://github.com/KDE/kxmlgui/blob/master/src/kpartgui.dtd
|
||||||
|
Template: https://github.com/KDE/kxmlgui/blob/master/src/ui_standards.rc
|
||||||
|
-->
|
||||||
|
<gui name="pineapple-notepad"
|
||||||
|
version="1"
|
||||||
|
xmlns="http://www.kde.org/standards/kxmlgui/1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0
|
||||||
|
http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd">
|
||||||
|
<MenuBar>
|
||||||
|
<Menu name="file" >
|
||||||
|
</Menu>
|
||||||
|
<Menu name="edit">
|
||||||
|
</Menu>
|
||||||
|
<Menu name="search"><text>&Search</text>
|
||||||
|
<Action name="edit_find" />
|
||||||
|
<Action name="edit_find_next" />
|
||||||
|
<Action name="edit_find_prev" />
|
||||||
|
<Action name="edit_replace" />
|
||||||
|
</Menu>
|
||||||
|
<Menu name="view"><text>&View</text>
|
||||||
|
<!-- <Menu><text>&Zoom</text>
|
||||||
|
<Action name="view_zoom_in"/>
|
||||||
|
<Action name="view_zoom_out"/>
|
||||||
|
</Menu>-->
|
||||||
|
<Action name="toggle_wrap_mode" />
|
||||||
|
</Menu>
|
||||||
|
<Menu name="encoding"><text>E&ncoding</text>
|
||||||
|
</Menu>
|
||||||
|
<Menu name="language"><text>&Language</text>
|
||||||
|
<Action name="lexer_none" />
|
||||||
|
</Menu>
|
||||||
|
<Menu name="settings"><text>&Settings</text>
|
||||||
|
<Action name="colorscheme_menu"/>
|
||||||
|
</Menu>
|
||||||
|
<!-- this is not enough, user can still see actions like About KDE from other places
|
||||||
|
<menu name="help" noMerge="1"><text>&Help</text>
|
||||||
|
<Action name="open_kcommand_bar"/>
|
||||||
|
<Separator/>
|
||||||
|
<Action name="help_about_app"/>
|
||||||
|
</menu> -->
|
||||||
|
</MenuBar>
|
||||||
|
<ToolBar name="mainToolBar" >
|
||||||
|
<text>Main Toolbar</text>
|
||||||
|
<Action name="toggle_wrap_mode" />
|
||||||
|
<Action name="toggle_show_all_characters" />
|
||||||
|
<Action name="toggle_indent_guide" />
|
||||||
|
</ToolBar>
|
||||||
|
</gui>
|
Loading…
Reference in New Issue
Block a user