diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cc7114..5ef0b83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ target_sources(pineapple-notepad PRIVATE main.cpp mainwindow.cpp mainwindow.h + editorviewhelper.cpp editorviewhelper.h generalsettings.ui appsettings.kcfg diff --git a/editorviewhelper.cpp b/editorviewhelper.cpp new file mode 100644 index 0000000..4affb69 --- /dev/null +++ b/editorviewhelper.cpp @@ -0,0 +1,165 @@ +#include "editorviewhelper.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const QStringList languages_group[] = { + QStringList{ + "Bash", "Batch" + }, + QStringList{ + "C", "C++", "C#", "CMake", "CSS" + }, + QStringList{ + "D", "Diff" + }, + QStringList{ + "HTML" + }, + QStringList{ + "Java", "JavaScript", "JSON" + }, + QStringList{ + "Lua" + }, + QStringList{ + "Makefile", "Markdown" + }, + QStringList{ + "Pascal", "Perl", "PO", "Python" + }, + QStringList{ + "Ruby" + }, + QStringList{ + "XML" + }, + QStringList{ + "YAML" + }, +}; + +QString LexerGroupActionMenu::groupName(LanguageGroup grp) +{ + switch (grp) { + case LANG_GRP_B: + return QLatin1String("B"); + case LANG_GRP_C: + return QLatin1String("C"); + case LANG_GRP_D: + return QLatin1String("D"); + case LANG_GRP_H: + return QLatin1String("H"); + case LANG_GRP_J: + return QLatin1String("J"); + case LANG_GRP_L: + return QLatin1String("L"); + case LANG_GRP_M: + return QLatin1String("M"); + case LANG_GRP_P: + return QLatin1String("P"); + case LANG_GRP_R: + return QLatin1String("R"); + case LANG_GRP_X: + return QLatin1String("X"); + case LANG_GRP_Y: + return QLatin1String("Y"); + } + + Q_UNREACHABLE_RETURN(""); +} + +QsciLexer * LexerGroupActionMenu::createLexerByLanguage(const QString &languageName) +{ + QsciLexer * ret = nullptr; + if (languageName == "Bash") { + ret = new QsciLexerBash(); + } else if (languageName == "Batch") { + ret = new QsciLexerBatch(); + } else if (languageName == "C" || languageName == "C++") { + ret = new QsciLexerCPP(); + } else if (languageName == "C#") { + ret = new QsciLexerCSharp(); + } else if (languageName == "CMake") { + ret = new QsciLexerCMake(); + } else if (languageName == "CSS") { + ret = new QsciLexerCSS(); + } else if (languageName == "D") { + ret = new QsciLexerD(); + } else if (languageName == "Diff") { + ret = new QsciLexerDiff(); + } else if (languageName == "HTML") { + ret = new QsciLexerHTML(); + } else if (languageName == "Java") { + ret = new QsciLexerJava(); + } else if (languageName == "JavaScript") { + ret = new QsciLexerJavaScript(); + } else if (languageName == "JSON") { + ret = new QsciLexerJSON(); + } else if (languageName == "Lua") { + ret = new QsciLexerLua(); + } else if (languageName == "Makefile") { + ret = new QsciLexerMakefile(); + } else if (languageName == "Markdown") { + ret = new QsciLexerMarkdown(); + } else if (languageName == "Pascal") { + ret = new QsciLexerPascal(); + } else if (languageName == "Perl") { + ret = new QsciLexerPerl(); + } else if (languageName == "PO") { + ret = new QsciLexerPO(); + } else if (languageName == "Python") { + ret = new QsciLexerPython(); + } else if (languageName == "Ruby") { + ret = new QsciLexerRuby(); + } else if (languageName == "XML") { + ret = new QsciLexerXML(); + } else if (languageName == "YAML") { + ret = new QsciLexerYAML(); + } + return ret; +} + +void LexerGroupActionMenu::slotAboutToShow() +{ + if (!m_group) { + m_group = new QActionGroup(menu()); + } else { + return; + } + + for (const QString & name : languages_group[m_languageGroup]) { + QAction *a = menu()->addAction(name, this, [this, name](){ + emit lexerSelected(name); + }); + a->setActionGroup(m_group); + } +} diff --git a/editorviewhelper.h b/editorviewhelper.h new file mode 100644 index 0000000..a0a2d4f --- /dev/null +++ b/editorviewhelper.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +class QsciLexer; +class LexerGroupActionMenu : public KActionMenu +{ + Q_OBJECT +public: + enum LanguageGroup { + LANG_GRP_B, + LANG_GRP_C, + LANG_GRP_D, + LANG_GRP_H, + LANG_GRP_J, + LANG_GRP_L, + LANG_GRP_M, + LANG_GRP_P, + LANG_GRP_R, + LANG_GRP_X, + LANG_GRP_Y, + LANG_GRP_LAST = LANG_GRP_Y + }; + LexerGroupActionMenu(const QString &text, enum LanguageGroup grp, QObject *parent) + : KActionMenu(text, parent) + { + m_group = nullptr; + m_languageGroup = grp; + connect(menu(), &QMenu::aboutToShow, this, &LexerGroupActionMenu::slotAboutToShow); + setPopupMode(QToolButton::InstantPopup); + } + + static QString groupName(enum LanguageGroup grp); + static QsciLexer * createLexerByLanguage(const QString & languageName); + +signals: + void lexerSelected(const QString lexerName); + +private: + QActionGroup *m_group; + enum LanguageGroup m_languageGroup; + +public: + void slotAboutToShow(); +}; diff --git a/main.cpp b/main.cpp index 49e87f6..9d0e97e 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include int main(int argc, char *argv[]) { @@ -25,6 +26,8 @@ int main(int argc, char *argv[]) QString(), QString(), QStringLiteral("https://blumia.net")); + aboutData.addComponent("QsciScintilla", "A port to Qt6 of Neil Hodgson's Scintilla C++ editor class", + QSCINTILLA_VERSION_STR, "https://www.riverbankcomputing.com/software/qscintilla/intro"); KAboutData::setApplicationData(aboutData); a.setWindowIcon(QIcon::fromTheme(QStringLiteral("accessories-text-editor"))); diff --git a/mainwindow.cpp b/mainwindow.cpp index 7925bbf..d45bbb6 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,9 +1,13 @@ #include "mainwindow.h" #include "appsettings.h" +#include "editorviewhelper.h" +#include #include #include +#include +#include #include #include @@ -14,24 +18,35 @@ #include #include +#include MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent) , m_editor(new QsciScintilla(this)) + , m_cursorPosStatusLabel(new QLabel(QString("Ln: ? Col: ?"))) { setCentralWidget(m_editor); + statusBar()->addPermanentWidget(m_cursorPosStatusLabel); + 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->setFolding(QsciScintilla::BoxedTreeFoldStyle); m_editor->setBraceMatching(QsciScintilla::SloppyBraceMatch); m_editor->setTabWidth(AppSettings::self()->tabWidth()); m_editor->setEolMode(QsciScintilla::EolUnix); + connect(m_editor, &QsciScintilla::cursorPositionChanged, this, [this](int line, int index){ + // FIXME: not get called at all? + qDebug() << line << index; + m_cursorPosStatusLabel->setText(QString("Ln: %1 Col: %2").arg(line, index)); + }); + setupActions(); } @@ -82,6 +97,14 @@ void MainWindow::setupActions() m_editor->setLexer(nullptr); }); + for (int i = 0; i <= LexerGroupActionMenu::LANG_GRP_LAST; i++) { + LexerGroupActionMenu::LanguageGroup group = static_cast(i); + const QString groupName(LexerGroupActionMenu::groupName(group)); + LexerGroupActionMenu *lexerGroupMenu = new LexerGroupActionMenu(groupName, group, this); + actionCollection()->addAction(QStringLiteral("lexer_group_") % groupName.toLower(), lexerGroupMenu); + connect(lexerGroupMenu, &LexerGroupActionMenu::lexerSelected, this, &MainWindow::applyLexer); + } + // Toolbar actions KStandardAction::zoomIn(this, [this](){ m_editor->zoomIn(); @@ -147,3 +170,12 @@ void MainWindow::showSettings() dialog->show(); } + +void MainWindow::applyLexer(const QString &lexer) +{ + QsciLexer * ret = LexerGroupActionMenu::createLexerByLanguage(lexer); + if (ret) { + ret->setFont(AppSettings::self()->editorFont()); + } + m_editor->setLexer(ret); +} diff --git a/mainwindow.h b/mainwindow.h index b9a15b2..44970fe 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,7 +1,10 @@ +#pragma once + #include #include "ui_GeneralSettings.h" +class QLabel; class QsciScintilla; class MainWindow : public KXmlGuiWindow { @@ -14,8 +17,10 @@ public: private: void setupActions(); void showSettings(); + void applyLexer(const QString & lexer); QsciScintilla * m_editor; + QLabel * m_cursorPosStatusLabel; }; // plainly for KConfigDialog diff --git a/pineapple-notepadui.rc b/pineapple-notepadui.rc index 8cc0f6e..136aaf1 100644 --- a/pineapple-notepadui.rc +++ b/pineapple-notepadui.rc @@ -20,7 +20,7 @@ Template: https://github.com/KDE/kxmlgui/blob/master/src/ui_standards.rc - &View + + + + + + + + + + + + - &Settings + - + + + Main Toolbar