commit a75a4aeee84e09432c16830ee8d2d6a9d90df8f0 Author: Gary Wang Date: Sat Jun 22 20:01:42 2024 +0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca54a51 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Common build folder +[Bb]uild/ + +# IDE stuff +CMakeLists.txt.user* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0cc7114 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2024 Gary Wang + +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 +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..dcc3f99 --- /dev/null +++ b/README.md @@ -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 构造之前调用初始化,并且看上去需要配合什么别的东西才能做到颜色正确... diff --git a/appsettings.kcfg b/appsettings.kcfg new file mode 100644 index 0000000..bf03ead --- /dev/null +++ b/appsettings.kcfg @@ -0,0 +1,17 @@ + + + + + QFontDatabase + + + 4 + + + QFontDatabase::systemFont(QFontDatabase::FixedFont) + + + diff --git a/appsettings.kcfgc b/appsettings.kcfgc new file mode 100644 index 0000000..2353954 --- /dev/null +++ b/appsettings.kcfgc @@ -0,0 +1,8 @@ +File=appsettings.kcfg +ClassName=AppSettings +Mutators=true +DefaultValueGetters=true +GenerateProperties=true +ParentInConstructor=true +Notifiers=true +Singleton=true diff --git a/generalsettings.ui b/generalsettings.ui new file mode 100644 index 0000000..594093c --- /dev/null +++ b/generalsettings.ui @@ -0,0 +1,58 @@ + + + GeneralSettings + + + + 0 + 0 + 406 + 300 + + + + Form + + + + + + tAB wIDTH + + + + + + + 1 + + + 16 + + + 4 + + + + + + + eDITOR fONT + + + + + + + + + + + KFontRequester + QWidget +
kfontrequester.h
+
+
+ + +
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..49e87f6 --- /dev/null +++ b/main.cpp @@ -0,0 +1,35 @@ +#include + +#include "mainwindow.h" + +#include +#include +#include +#include + +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(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..7925bbf --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,149 @@ +#include "mainwindow.h" + +#include "appsettings.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +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(dialog), "Appearance", "preferences-desktop-theme-global"); + + connect(dialog, &KConfigDialog::settingsChanged, this, [](const QString &dialogName){ + qDebug() << dialogName << "changed"; + }); + + dialog->show(); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..b9a15b2 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,35 @@ +#include + +#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 +class SettingsPage : public QWidget +{ +public: + SettingsPage(QWidget *parent) + : QWidget(parent) + { + ui.setupUi(this); + } + +private: + T ui; +}; diff --git a/pineapple-notepadui.rc b/pineapple-notepadui.rc new file mode 100644 index 0000000..8cc0f6e --- /dev/null +++ b/pineapple-notepadui.rc @@ -0,0 +1,51 @@ + + + + + + + + + &Search + + + + + + &View + + + + E&ncoding + + &Language + + + &Settings + + + + + + Main Toolbar + + + + +