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