View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0017830 | Scribus | Text Frames / Story Editor | public | 2026-06-03 07:17 | 2026-06-07 11:50 |
| Reporter | soerendanielkarch | Assigned To | |||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | new | Resolution | open | ||
| Product Version | 1.7.3 | ||||
| Summary | 0017830: The character style is not preserved across paragraphs and empty lines, resulting in newly inserted text receiving incorrect for | ||||
| Description | When working with styled text, I noticed that the assigned character style is not reliably preserved in empty lines or empty paragraphs after a paragraph. For example, a text frame/story has a paragraph style and a character style assigned. The visible text is formatted correctly. However, when I click into an empty line after a paragraph and continue typing, paste text, or insert copied text, the inserted text is formatted incorrectly. Font size, character formatting, or other style properties can differ from the surrounding styled text. It appears that the empty paragraph/empty line does not keep the expected character style, even though the surrounding text uses the correct styles. | ||||
| Steps To Reproduce | Create a text frame. Apply a paragraph style and a character style to the text. Write one or more paragraphs. Add an empty line after a paragraph. Click into this empty line. Type new text or paste copied text. Compare the formatting of the newly inserted text with the surrounding styled text. | ||||
| Additional Information | Actual result: The newly inserted text uses wrong formatting. The assigned character style does not seem to be active in the empty paragraph/empty line. Expected result: Empty paragraphs or empty lines inside styled text should preserve the active paragraph and character styling. When the user clicks into such an empty line and starts typing or pasting text, the inserted text should use the same expected style as the surrounding text. Why this matters: This causes inconsistent formatting in longer documents. It is easy to accidentally insert text with the wrong font size or wrong character formatting. The error may not be noticed immediately and can create extra correction work later. Workaround: Manually reapply the correct style after inserting text, or avoid empty lines and restructure the text manually. This is not ideal for normal layout work. | ||||
| Tags | No tags attached. | ||||
| Patch | No | ||||
|
|
I am new to contributing code and not an experienced programmer, but I have ideas and would like to help improve Scribus. This patch attempts to preserve the active character style when inserting text into empty paragraphs or after paragraph breaks. I developed and tested this patch with assistance from AI. On my macOS Apple Silicon system with Scribus 1.7.3, it works very well and resolves the reported problem. Please consider this a proposed patch for review and testing. I would appreciate it if experienced developers could verify the implementation and confirm that it does not cause regressions on other platforms or in other text-editing situations. Thank you for reviewing my contribution. preserve-character-style-in-empty-paragraphs.diff (4,273 bytes)
diff --git a/scribus/tests/testStoryText.cpp b/scribus/tests/testStoryText.cpp
index a6ede8bf5..b8ec351cf 100644
--- a/scribus/tests/testStoryText.cpp
+++ b/scribus/tests/testStoryText.cpp
@@ -14,7 +14,7 @@ void TestStoryText::initST()
{
StoryText story;
QCOMPARE(story.length(), 0);
- story.insertChars(0, "Hallo Welt");
+ story.insertChars(0, QString("Hallo Welt"));
QCOMPARE(story.nrOfParagraphs(), 1u);
QCOMPARE(story.nrOfRuns(), 1u);
}
@@ -25,7 +25,7 @@ void TestStoryText::addText()
story.insertChars(0, QString("Hallo Welt"));
QCOMPARE(story.length(), 10);
QCOMPARE(story.text(0, story.length()), QString("Hallo Welt"));
- story.insertChars(5, " schöne neue");
+ story.insertChars(5, QString(" schöne neue"));
QCOMPARE(story.text(0, story.length()), QString("Hallo schöne neue Welt"));
}
@@ -127,3 +127,23 @@ void TestStoryText::removeCharStyle()
QCOMPARE(story.startOfRun(2), 5 + 26 + 1);
QCOMPARE(story.endOfRun(2), 11 + 26);
}
+
+void TestStoryText::preserveCharStyleInEmptyParagraph()
+{
+ CharStyle charStyle;
+ charStyle.setFontSize(240);
+
+ StoryText trailingParagraph;
+ trailingParagraph.insertChars(0, QString("Styled"));
+ trailingParagraph.applyCharStyle(0, trailingParagraph.length(), charStyle);
+ trailingParagraph.insertChars(trailingParagraph.length(), SpecialChars::PARSEP, true);
+ trailingParagraph.insertChars(trailingParagraph.length(), QString("Text"), true);
+ QCOMPARE(trailingParagraph.charStyle(trailingParagraph.length() - 1).fontSize(), 240.0);
+
+ StoryText emptyParagraph;
+ emptyParagraph.insertChars(0, QString("Before") + SpecialChars::PARSEP + SpecialChars::PARSEP + QString("After"));
+ emptyParagraph.applyCharStyle(0, emptyParagraph.length(), charStyle);
+ const int emptyParagraphPosition = emptyParagraph.indexOf(SpecialChars::PARSEP, 0) + 1;
+ emptyParagraph.insertChars(emptyParagraphPosition, QString("Text"), true);
+ QCOMPARE(emptyParagraph.charStyle(emptyParagraphPosition).fontSize(), 240.0);
+}
diff --git a/scribus/tests/testStoryText.h b/scribus/tests/testStoryText.h
index 655875237..4a2ba28e1 100644
--- a/scribus/tests/testStoryText.h
+++ b/scribus/tests/testStoryText.h
@@ -27,4 +27,5 @@ private slots:
void removePars();
void applyCharStyle();
void removeCharStyle();
+ void preserveCharStyleInEmptyParagraph();
};
diff --git a/scribus/text/storytext.cpp b/scribus/text/storytext.cpp
index d8281d5e0..6fa17dac4 100644
--- a/scribus/text/storytext.cpp
+++ b/scribus/text/storytext.cpp
@@ -689,6 +689,14 @@ void StoryText::insertChars(const QString& txt, bool applyNeighbourStyle) //, co
insertChars(d->cursorPosition, txt, applyNeighbourStyle);
}
+const CharStyle& StoryText::charStyleForInsertion(int pos) const
+{
+ int referenceChar = qMax(0, qMin(pos, length() - 1));
+ if (isNotEmpty() && text(referenceChar) == SpecialChars::PARSEP)
+ return *item(referenceChar);
+ return charStyle(referenceChar);
+}
+
void StoryText::insertChars(int pos, const QString& txt, bool applyNeighbourStyle) //, const CharStyle & charstyle)
{
if (pos < 0)
@@ -705,8 +713,7 @@ void StoryText::insertChars(int pos, const QString& txt, bool applyNeighbourStyl
ScText clone;
if (applyNeighbourStyle)
{
- int referenceChar = qMax(0, qMin(pos, length()-1));
- clone.applyCharStyle(charStyle(referenceChar));
+ clone.applyCharStyle(charStyleForInsertion(pos));
clone.setEffects(ScStyle_Default);
}
@@ -748,8 +755,7 @@ void StoryText::insertCharsWithSoftHyphens(int pos, const QString& txt, bool app
ScText clone;
if (applyNeighbourStyle)
{
- int referenceChar = qMax(0, qMin(pos, length() - 1));
- clone.applyCharStyle(charStyle(referenceChar));
+ clone.applyCharStyle(charStyleForInsertion(pos));
clone.setEffects(ScStyle_Default);
}
diff --git a/scribus/text/storytext.h b/scribus/text/storytext.h
index 4f2fee40d..86ef5df67 100644
--- a/scribus/text/storytext.h
+++ b/scribus/text/storytext.h
@@ -328,6 +328,7 @@ private:
QString textWithSoftHyphens (int pos, uint len) const;
void insertCharsWithSoftHyphens(int pos, const QString& txt, bool applyNeighbourStyle = false);
+ const CharStyle& charStyleForInsertion(int pos) const;
/// mark these runs as invalid, ie. need itemize and shaping
void invalidate(int firstRun, int lastRun);
|
|
|
Hello, As mentioned in the other post, this patch was also developed with assistance from AI. Below, I would like to document the starting point, the identified cause, the changes made, and the tests I performed. Starting Point and Prompt As the starting point, I copied the complete text of my bug report 0017830 into Codex without modification. It contained the issue description, reproduction steps, expected behavior, and actual behavior. The additional instruction was essentially: Analyze this problem in the Scribus source code, identify the cause, and implement a possible fix. Then compile Scribus 1.7.3 so that I can test the change in practice. The reported problem occurred when working with paragraph and character styles. Existing text was displayed correctly. However, when continuing to type or inserting text into an empty paragraph or after a paragraph break, Scribus could apply different character formatting. As a result, newly inserted text could receive an incorrect font size or other unexpected character properties, even though the surrounding text used the intended character style. Analysis of the Cause The investigation focused on how StoryText determines the character style for newly inserted text. The relevant insertion functions are: StoryText::insertChars() StoryText::insertCharsWithSoftHyphens() When text is inserted with neighboring-style inheritance enabled, these functions first determine a reference character. Its character style was previously obtained through StoryText::charStyle(). The problem occurred when this reference character was a paragraph separator (PARSEP). For paragraph separators, the public charStyle() function intentionally returns the character style associated with the paragraph style. However, the paragraph separator itself may also contain a directly assigned or named character style in its underlying ScText object. During insertion, the character style actually stored on the paragraph separator was therefore not considered. Newly typed or inserted text inherited the paragraph style’s default character formatting instead. This explains why the existing text could appear correct while text inserted into an empty paragraph suddenly received a different font size or formatting. Changes Made by the Patch The patch adds a private helper function: StoryText::charStyleForInsertion(int pos) const This function is used specifically when Scribus needs to determine the style for newly inserted text. Its behavior is: For a normal character, the existing public charStyle() function continues to be used. If the reference character is a paragraph separator, the character style stored directly in the underlying ScText object is used. The two relevant insertion functions now use this new helper: StoryText::insertChars() StoryText::insertCharsWithSoftHyphens() The normal public behavior of StoryText::charStyle() remains unchanged. The modification is therefore limited specifically to style inheritance during text insertion. As a result, newly typed or inserted text should now retain the active character style in the following situations: after a paragraph break, in a trailing empty paragraph, in an empty paragraph between existing paragraphs, when inserting copied text, and through insertion paths that process soft hyphens. Practical Tests Performed I tested the patch with Scribus 1.7.3 on an Apple Silicon Mac. In particular, I tested: entering text with paragraph and character styles applied, creating a new paragraph and continuing to type, typing into an empty paragraph, inserting unformatted text into an empty paragraph, inserting text between existing styled paragraphs, and comparing the font size and character formatting of the inserted text with the surrounding text. In my practical tests, the character style is now preserved correctly. Typing or inserting text no longer changes the formatting unexpectedly. Automated Regression Test An automated regression test was also added to the existing TestStoryText test suite. It covers two cases: Inserting text after a trailing paragraph separator with neighboring-style inheritance enabled. Inserting text into an empty paragraph between two existing paragraphs. The test uses a clearly distinguishable character style with a font size of 240 and verifies that newly inserted text retains this value. Before the fix, the test failed because the inserted text received the paragraph style’s font size of 200 instead. With the patch applied, the new test passes. The targeted test completed with three successful checks and no failures. The complete pre-existing StoryText test suite still contains several unrelated failures involving older nrOfRuns() expectations. These were not changed as part of this patch. Build Verification Additionally: the modified source code was successfully compiled as a native ARM64 build, the resulting macOS application was launched, the application bundle’s code signature was verified, and the bundle was checked for unintended absolute Homebrew dependencies. In my practical tests, the patch reliably resolves the reported problem. However, I cannot provide a complete assessment for other platforms, every possible combination of paragraph and character styles, or potential side effects. I am therefore submitting this patch expressly as a proposal for technical review and further testing by experienced Scribus developers. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-06-03 07:17 | soerendanielkarch | New Issue | |
| 2026-06-07 06:28 | soerendanielkarch | Note Added: 0053787 | |
| 2026-06-07 06:28 | soerendanielkarch | File Added: 0017830-preserve-character-style-in-empty-paragraphs.diff | |
| 2026-06-07 11:50 | soerendanielkarch | Note Added: 0053791 |