[education/cantor] /: Use KFontRequester for hierarchy font settings

Alexander Semke <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 522dcc0cef5bedd8b797bc2e95e2bb459c558f84 by Alexander Semke, on behalf of Nanhao Lv.
Committed on 26/07/2026 at 19:50.
Pushed by asemke into branch 'master'.

Use KFontRequester for hierarchy font settings

M  +1    -0    CMakeLists.txt
M  +2    -2    src/CMakeLists.txt
M  +5    -69   src/cantor.cpp
M  +4    -0    src/cantor.kcfg
M  +29   -244  src/formating.ui
M  +4    -24   src/hierarchyentry.cpp
A  +40   -0    src/hierarchyfontsettings.cpp     [License: GPL(v2.0+)]
A  +14   -0    src/hierarchyfontsettings.h     [License: GPL(v2.0+)]

https://invent.kde.org/education/cantor/-/commit/522dcc0cef5bedd8b797bc2e95e2bb459c558f84

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1da7de97..423ea20e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,6 +54,7 @@ find_package(KF6 ${KF_MIN_VERSION} REQUIRED
     Parts
     SyntaxHighlighting
     TextWidgets
+    WidgetsAddons
     KIO
     XmlGui
     I18n
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 86ea33a0..3fd08f1c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,7 +18,7 @@ add_subdirectory(panelplugins)
 
 #build the config object in a separate library, shared between shell and part
 kconfig_add_kcfg_files(config_SRCS settings.kcfgc)
-add_library( cantor_config SHARED ${config_SRCS} )
+add_library( cantor_config SHARED ${config_SRCS} hierarchyfontsettings.cpp )
 target_link_libraries( cantor_config KF6::ConfigGui Qt6::Widgets )
 generate_export_header( cantor_config BASE_NAME cantor_config )
 install( TARGETS cantor_config ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} )
@@ -42,7 +42,7 @@ ecm_add_app_icon(cantor_SRCS ICONS ${ICONS_SRCS})
 add_executable(cantor ${cantor_SRCS})
 
 target_link_libraries(cantor KF6::Parts KF6::NewStuffWidgets KF6::ConfigCore KF6::CoreAddons KF6::ConfigGui
-    KF6::Crash KF6::XmlGui KF6::TextEditor cantorlibs cantor_config)
+    KF6::Crash KF6::XmlGui KF6::TextEditor KF6::WidgetsAddons cantorlibs cantor_config)
 
 if (ENABLE_EMBEDDED_DOCUMENTATION)
     target_link_libraries(cantor Qt6::WebEngineCore)
diff --git a/src/cantor.cpp b/src/cantor.cpp
index ad689429..35bfd41f 100644
--- a/src/cantor.cpp
+++ b/src/cantor.cpp
@@ -9,9 +9,9 @@
 #include <cassert>
 
 #include <KActionCollection>
+#include <KConfig>
 #include <KConfigDialog>
 #include <KConfigGroup>
-#include <KConfig>
 #include <KMessageBox>
 #include <KShortcutsDialog>
 #include <KStandardAction>
@@ -29,22 +29,18 @@
 #include <QDir>
 #include <QDockWidget>
 #include <QFileDialog>
-#include <QFontComboBox>
-#include <QFormLayout>
 #include <QStatusBar>
 #include <QGraphicsView>
-#include <QHBoxLayout>
 #include <QLabel>
 #include <QPushButton>
 #include <QRegularExpression>
 #include <QMenuBar>
-#include <QSpinBox>
-#include <QToolButton>
 
 #include "lib/backend.h"
 #include "lib/worksheetaccess.h"
 
 #include "backendchoosedialog.h"
+#include "hierarchyfontsettings.h"
 #include "settings.h"
 #include "ui_settings.h"
 #include "ui_formating.h"
@@ -737,6 +733,8 @@ void CantorShell::closeEvent(QCloseEvent* event) {
 
 void CantorShell::showSettings()
 {
+    migrateHierarchyFontSettings();
+
     KConfigDialog *dialog = new KConfigDialog(this,  QLatin1String("settings"), Settings::self());
     dialog->setFaceType(KPageDialog::FlatList);
     dialog->resize(1000, 700);
@@ -758,68 +756,6 @@ void CantorShell::showSettings()
     Ui::SettingsToc toc;
     toc.setupUi(tocSettings);
 
-    for (auto* fontFamilyEditor : tocSettings->findChildren<QFontComboBox*>())
-        fontFamilyEditor->setProperty("kcfg_property", QByteArray("currentFont"));
-
-    const auto addFontSizeButtons = [](QSpinBox* spinBox)
-    {
-        auto* formLayout = qobject_cast<QFormLayout*>(spinBox->parentWidget()->layout());
-        if (!formLayout)
-            return;
-
-        int row = -1;
-        QFormLayout::ItemRole role = QFormLayout::FieldRole;
-        formLayout->getWidgetPosition(spinBox, &row, &role);
-        if (row < 0)
-            return;
-
-        auto* editor = new QWidget(spinBox->parentWidget());
-        auto* layout = new QHBoxLayout(editor);
-        layout->setContentsMargins(0, 0, 0, 0);
-        layout->setSpacing(2);
-
-        formLayout->removeWidget(spinBox);
-        spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
-        spinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
-        layout->addWidget(spinBox);
-
-        auto* decreaseButton = new QToolButton(editor);
-        decreaseButton->setText(QStringLiteral("−"));
-        decreaseButton->setToolTip(i18n("Decrease font size"));
-        decreaseButton->setAutoRepeat(true);
-        layout->addWidget(decreaseButton);
-
-        auto* increaseButton = new QToolButton(editor);
-        increaseButton->setText(QStringLiteral("+"));
-        increaseButton->setToolTip(i18n("Increase font size"));
-        increaseButton->setAutoRepeat(true);
-        layout->addWidget(increaseButton);
-
-        connect(decreaseButton, &QToolButton::clicked, spinBox, &QSpinBox::stepDown);
-        connect(increaseButton, &QToolButton::clicked, spinBox, &QSpinBox::stepUp);
-
-        const auto updateButtons = [spinBox, decreaseButton, increaseButton](int value)
-        {
-            decreaseButton->setEnabled(value > spinBox->minimum());
-            increaseButton->setEnabled(value < spinBox->maximum());
-        };
-        connect(spinBox, &QSpinBox::valueChanged, editor, updateButtons);
-        updateButtons(spinBox->value());
-
-        formLayout->setWidget(row, role, editor);
-    };
-
-    const QList<QSpinBox*> fontSizeEditors = {
-        toc.kcfg_ChapterFontSize,
-        toc.kcfg_SubchapterFontSize,
-        toc.kcfg_SectionFontSize,
-        toc.kcfg_SubsectionFontSize,
-        toc.kcfg_ParagraphFontSize,
-        toc.kcfg_SubparagraphFontSize,
-    };
-    for (auto* fontSizeEditor : fontSizeEditors)
-        addFontSizeButtons(fontSizeEditor);
-
     const auto tocLabels = tocSettings->findChildren<QLabel*>();
     int tocLabelWidth = 0;
     for (const auto* label : tocLabels)
@@ -843,8 +779,8 @@ void CantorShell::showSettings()
             dialog->addPage(backend->settingsWidget(dialog), backend->config(), backend->name(),  backend->icon());
     }
 
-    dialog->show();
     connect(dialog, &KConfigDialog::settingsChanged, this, &CantorShell::settingsChanges);
+    dialog->show();
 }
 
 void CantorShell::openExample()
diff --git a/src/cantor.kcfg b/src/cantor.kcfg
index 333b6b76..00a33cee 100644
--- a/src/cantor.kcfg
+++ b/src/cantor.kcfg
@@ -82,6 +82,10 @@
       <label>Limit of visible lines for text result</label>
       <default>0</default>
     </entry>
+    <entry name="HierarchyFontSettingsMigrated" type="Bool">
+      <label>Whether the hierarchy font settings have been migrated to complete fonts</label>
+      <default>false</default>
+    </entry>
     <entry name="ChapterFontFamily" type="Font">
       <label>Hierarchy font for chapter</label>
       <default code="true">QApplication::font()</default>
diff --git a/src/formating.ui b/src/formating.ui
index 8c33ac98..1a1dd7d4 100644
--- a/src/formating.ui
+++ b/src/formating.ui
@@ -110,9 +110,9 @@
         <number>9</number>
        </property>
        <item row="0" column="0">
-        <widget class="QLabel" name="lChapterFontFamily">
+        <widget class="QLabel" name="lChapterFont">
          <property name="text">
-          <string>Fon&amp;t Family:</string>
+          <string>&amp;Font:</string>
          </property>
          <property name="buddy">
           <cstring>kcfg_ChapterFontFamily</cstring>
@@ -120,44 +120,7 @@
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="QFontComboBox" name="kcfg_ChapterFontFamily"/>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lChapterFontSize">
-         <property name="text">
-          <string>Font Si&amp;ze:</string>
-         </property>
-         <property name="buddy">
-          <cstring>kcfg_ChapterFontSize</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QSpinBox" name="kcfg_ChapterFontSize">
-         <property name="minimum">
-          <number>8</number>
-         </property>
-         <property name="maximum">
-          <number>40</number>
-         </property>
-         <property name="value">
-          <number>14</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QCheckBox" name="kcfg_ChapterFontBold">
-         <property name="text">
-          <string>Bold</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QCheckBox" name="kcfg_ChapterFontItalic">
-         <property name="text">
-          <string>Italic</string>
-         </property>
-        </widget>
+        <widget class="KFontRequester" name="kcfg_ChapterFontFamily"/>
        </item>
       </layout>
      </widget>
@@ -170,9 +133,9 @@
         <number>9</number>
        </property>
        <item row="0" column="0">
-        <widget class="QLabel" name="lSubchapterFontFamily">
+        <widget class="QLabel" name="lSubchapterFont">
          <property name="text">
-          <string>Fon&amp;t Family:</string>
+          <string>&amp;Font:</string>
          </property>
          <property name="buddy">
           <cstring>kcfg_SubchapterFontFamily</cstring>
@@ -180,44 +143,7 @@
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="QFontComboBox" name="kcfg_SubchapterFontFamily"/>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lSubchapterFontSize">
-         <property name="text">
-          <string>Font Si&amp;ze:</string>
-         </property>
-         <property name="buddy">
-          <cstring>kcfg_SubchapterFontSize</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QSpinBox" name="kcfg_SubchapterFontSize">
-         <property name="minimum">
-          <number>8</number>
-         </property>
-         <property name="maximum">
-          <number>40</number>
-         </property>
-         <property name="value">
-          <number>14</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QCheckBox" name="kcfg_SubchapterFontBold">
-         <property name="text">
-          <string>Bold</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QCheckBox" name="kcfg_SubchapterFontItalic">
-         <property name="text">
-          <string>Italic</string>
-         </property>
-        </widget>
+        <widget class="KFontRequester" name="kcfg_SubchapterFontFamily"/>
        </item>
       </layout>
      </widget>
@@ -230,9 +156,9 @@
         <number>9</number>
        </property>
        <item row="0" column="0">
-        <widget class="QLabel" name="lSectionFontFamily">
+        <widget class="QLabel" name="lSectionFont">
          <property name="text">
-          <string>Fon&amp;t Family:</string>
+          <string>&amp;Font:</string>
          </property>
          <property name="buddy">
           <cstring>kcfg_SectionFontFamily</cstring>
@@ -240,44 +166,7 @@
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="QFontComboBox" name="kcfg_SectionFontFamily"/>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lSectionFontSize">
-         <property name="text">
-          <string>Font Si&amp;ze:</string>
-         </property>
-         <property name="buddy">
-          <cstring>kcfg_SectionFontSize</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QSpinBox" name="kcfg_SectionFontSize">
-         <property name="minimum">
-          <number>8</number>
-         </property>
-         <property name="maximum">
-          <number>40</number>
-         </property>
-         <property name="value">
-          <number>14</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QCheckBox" name="kcfg_SectionFontBold">
-         <property name="text">
-          <string>Bold</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QCheckBox" name="kcfg_SectionFontItalic">
-         <property name="text">
-          <string>Italic</string>
-         </property>
-        </widget>
+        <widget class="KFontRequester" name="kcfg_SectionFontFamily"/>
        </item>
       </layout>
      </widget>
@@ -290,9 +179,9 @@
         <number>9</number>
        </property>
        <item row="0" column="0">
-        <widget class="QLabel" name="lSubsectionFontFamily">
+        <widget class="QLabel" name="lSubsectionFont">
          <property name="text">
-          <string>Fon&amp;t Family:</string>
+          <string>&amp;Font:</string>
          </property>
          <property name="buddy">
           <cstring>kcfg_SubsectionFontFamily</cstring>
@@ -300,44 +189,7 @@
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="QFontComboBox" name="kcfg_SubsectionFontFamily"/>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lSubsetctionFontSize">
-         <property name="text">
-          <string>Font Si&amp;ze:</string>
-         </property>
-         <property name="buddy">
-          <cstring>kcfg_SubsectionFontSize</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QSpinBox" name="kcfg_SubsectionFontSize">
-         <property name="minimum">
-          <number>8</number>
-         </property>
-         <property name="maximum">
-          <number>40</number>
-         </property>
-         <property name="value">
-          <number>14</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QCheckBox" name="kcfg_SubsectionFontBold">
-         <property name="text">
-          <string>Bold</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QCheckBox" name="kcfg_SubsectionFontItalic">
-         <property name="text">
-          <string>Italic</string>
-         </property>
-        </widget>
+        <widget class="KFontRequester" name="kcfg_SubsectionFontFamily"/>
        </item>
       </layout>
      </widget>
@@ -350,9 +202,9 @@
         <number>9</number>
        </property>
        <item row="0" column="0">
-        <widget class="QLabel" name="lParagraphFontFamily">
+        <widget class="QLabel" name="lParagraphFont">
          <property name="text">
-          <string>Fon&amp;t Family:</string>
+          <string>&amp;Font:</string>
          </property>
          <property name="buddy">
           <cstring>kcfg_ParagraphFontFamily</cstring>
@@ -360,44 +212,7 @@
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="QFontComboBox" name="kcfg_ParagraphFontFamily"/>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lParagrapshFontSize">
-         <property name="text">
-          <string>Font Si&amp;ze:</string>
-         </property>
-         <property name="buddy">
-          <cstring>kcfg_ParagraphFontSize</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QSpinBox" name="kcfg_ParagraphFontSize">
-         <property name="minimum">
-          <number>8</number>
-         </property>
-         <property name="maximum">
-          <number>40</number>
-         </property>
-         <property name="value">
-          <number>14</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QCheckBox" name="kcfg_ParagraphFontBold">
-         <property name="text">
-          <string>Bold</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QCheckBox" name="kcfg_ParagraphFontItalic">
-         <property name="text">
-          <string>Italic</string>
-         </property>
-        </widget>
+        <widget class="KFontRequester" name="kcfg_ParagraphFontFamily"/>
        </item>
       </layout>
      </widget>
@@ -410,9 +225,9 @@
         <number>9</number>
        </property>
        <item row="0" column="0">
-        <widget class="QLabel" name="lSubparagraphFontFamily">
+        <widget class="QLabel" name="lSubparagraphFont">
          <property name="text">
-          <string>Fon&amp;t Family:</string>
+          <string>&amp;Font:</string>
          </property>
          <property name="buddy">
           <cstring>kcfg_SubparagraphFontFamily</cstring>
@@ -420,44 +235,7 @@
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="QFontComboBox" name="kcfg_SubparagraphFontFamily"/>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lSubparagraphFontSize">
-         <property name="text">
-          <string>Font Si&amp;ze:</string>
-         </property>
-         <property name="buddy">
-          <cstring>kcfg_SubparagraphFontSize</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QSpinBox" name="kcfg_SubparagraphFontSize">
-         <property name="minimum">
-          <number>8</number>
-         </property>
-         <property name="maximum">
-          <number>40</number>
-         </property>
-         <property name="value">
-          <number>14</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QCheckBox" name="kcfg_SubparagraphFontBold">
-         <property name="text">
-          <string>Bold</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QCheckBox" name="kcfg_SubparagraphFontItalic">
-         <property name="text">
-          <string>Italic</string>
-         </property>
-        </widget>
+        <widget class="KFontRequester" name="kcfg_SubparagraphFontFamily"/>
        </item>
       </layout>
      </widget>
@@ -481,28 +259,28 @@
      <item row="0" column="0">
       <widget class="QCheckBox" name="kcfg_ShowTocChaptersDefault">
        <property name="text">
-        <string>Show chapters</string>
+        <string>Chapters</string>
        </property>
       </widget>
      </item>
      <item row="1" column="0">
       <widget class="QCheckBox" name="kcfg_ShowTocSectionsDefault">
        <property name="text">
-        <string>Show sections</string>
+        <string>Sections</string>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
       <widget class="QCheckBox" name="kcfg_ShowTocCommandEntriesDefault">
        <property name="text">
-        <string>Show command entries</string>
+        <string>Command entries</string>
        </property>
       </widget>
      </item>
      <item row="1" column="1">
       <widget class="QCheckBox" name="kcfg_ShowTocPlotsDefault">
        <property name="text">
-        <string>Show plots</string>
+        <string>Plots</string>
        </property>
       </widget>
      </item>
@@ -523,6 +301,13 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KFontRequester</class>
+   <extends>QWidget</extends>
+   <header>kfontrequester.h</header>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections>
   <connection>
diff --git a/src/hierarchyentry.cpp b/src/hierarchyentry.cpp
index 91982c3f..f944faaf 100644
--- a/src/hierarchyentry.cpp
+++ b/src/hierarchyentry.cpp
@@ -4,6 +4,7 @@
 */
 
 #include "hierarchyentry.h"
+#include "hierarchyfontsettings.h"
 #include "settings.h"
 #include "worksheetview.h"
 #include "lib/jupyterutils.h"
@@ -506,49 +507,33 @@ void HierarchyEntry::startDrag(QPointF grabPos)
 
 void HierarchyEntry::updateFonts(bool force)
 {
+    migrateHierarchyFontSettings();
+
     QFont font;
     switch(m_depth)
     {
         case HierarchyLevel::Chapter:
             font = Settings::chapterFontFamily();
-            font.setPointSize(Settings::chapterFontSize());
-            font.setItalic(Settings::chapterFontItalic());
-            font.setBold(Settings::chapterFontBold());
             break;
 
         case HierarchyLevel::Subchapter:
             font = Settings::subchapterFontFamily();
-            font.setPointSize(Settings::subchapterFontSize());
-            font.setItalic(Settings::subchapterFontItalic());
-            font.setBold(Settings::subchapterFontBold());
             break;
 
         case HierarchyLevel::Section:
             font = Settings::sectionFontFamily();
-            font.setPointSize(Settings::sectionFontSize());
-            font.setItalic(Settings::sectionFontItalic());
-            font.setBold(Settings::sectionFontBold());
             break;
 
         case HierarchyLevel::Subsection:
             font = Settings::subsectionFontFamily();
-            font.setPointSize(Settings::subsectionFontSize());
-            font.setItalic(Settings::subsectionFontItalic());
-            font.setBold(Settings::subsectionFontBold());
             break;
 
         case HierarchyLevel::Paragraph:
             font = Settings::paragraphFontFamily();
-            font.setPointSize(Settings::paragraphFontSize());
-            font.setItalic(Settings::paragraphFontItalic());
-            font.setBold(Settings::paragraphFontBold());
             break;
 
         case HierarchyLevel::Subparagraph:
             font = Settings::subparagraphFontFamily();
-            font.setPointSize(Settings::subparagraphFontSize());
-            font.setItalic(Settings::subparagraphFontItalic());
-            font.setBold(Settings::subparagraphFontBold());
             break;
 
         default:
@@ -556,12 +541,7 @@ void HierarchyEntry::updateFonts(bool force)
             break;
     }
 
-    const QFont& currectFont = m_textItem->font();
-    bool isSameFont =
-           currectFont.family() == font.family()
-        && currectFont.pointSize() == font.pointSize()
-        && currectFont.bold() == font.bold()
-        && currectFont.italic() == font.italic();
+    const bool isSameFont = m_textItem->font() == font;
 
     if (force || !isSameFont)
     {
diff --git a/src/hierarchyfontsettings.cpp b/src/hierarchyfontsettings.cpp
new file mode 100644
index 00000000..6b77a74b
--- /dev/null
+++ b/src/hierarchyfontsettings.cpp
@@ -0,0 +1,40 @@
+/*
+    SPDX-FileCopyrightText: 2026 Nanhao Lv <[email protected]>
+
+    SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#include "hierarchyfontsettings.h"
+
+#include "settings.h"
+
+void migrateHierarchyFontSettings()
+{
+    if (Settings::hierarchyFontSettingsMigrated())
+        return;
+
+    const auto completeFont = [](QFont font, int pointSize, bool italic, bool bold)
+    {
+        if (pointSize > 0)
+            font.setPointSize(pointSize);
+        font.setItalic(italic);
+        font.setBold(bold);
+        return font;
+    };
+
+    Settings::setChapterFontFamily(
+        completeFont(Settings::chapterFontFamily(), Settings::chapterFontSize(), Settings::chapterFontItalic(), Settings::chapterFontBold()));
+    Settings::setSubchapterFontFamily(
+        completeFont(Settings::subchapterFontFamily(), Settings::subchapterFontSize(), Settings::subchapterFontItalic(), Settings::subchapterFontBold()));
+    Settings::setSectionFontFamily(
+        completeFont(Settings::sectionFontFamily(), Settings::sectionFontSize(), Settings::sectionFontItalic(), Settings::sectionFontBold()));
+    Settings::setSubsectionFontFamily(
+        completeFont(Settings::subsectionFontFamily(), Settings::subsectionFontSize(), Settings::subsectionFontItalic(), Settings::subsectionFontBold()));
+    Settings::setParagraphFontFamily(
+        completeFont(Settings::paragraphFontFamily(), Settings::paragraphFontSize(), Settings::paragraphFontItalic(), Settings::paragraphFontBold()));
+    Settings::setSubparagraphFontFamily(
+        completeFont(Settings::subparagraphFontFamily(), Settings::subparagraphFontSize(), Settings::subparagraphFontItalic(), Settings::subparagraphFontBold()));
+
+    Settings::setHierarchyFontSettingsMigrated(true);
+    Settings::self()->save();
+}
diff --git a/src/hierarchyfontsettings.h b/src/hierarchyfontsettings.h
new file mode 100644
index 00000000..0c4df50f
--- /dev/null
+++ b/src/hierarchyfontsettings.h
@@ -0,0 +1,14 @@
+/*
+    SPDX-FileCopyrightText: 2026 Nanhao Lv <[email protected]>
+
+    SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#ifndef HIERARCHYFONTSETTINGS_H
+#define HIERARCHYFONTSETTINGS_H
+
+#include "cantor_config_export.h"
+
+CANTOR_CONFIG_EXPORT void migrateHierarchyFontSettings();
+
+#endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.