Commit 8ebe16d9 authored by Elvis Stansvik's avatar Elvis Stansvik

Fix update of block formats after paragraph style change.

REVIEW: 104032
parent d3b9fab2
......@@ -42,6 +42,7 @@
Q_DECLARE_METATYPE(QAbstractTextDocumentLayout::Selection)
Q_DECLARE_METATYPE(QTextFrame*)
Q_DECLARE_METATYPE(QTextCharFormat)
Q_DECLARE_METATYPE(QTextBlockFormat)
const QUrl KoTextDocument::StyleManagerURL = QUrl("kotext://stylemanager");
const QUrl KoTextDocument::ListsURL = QUrl("kotext://lists");
......@@ -58,6 +59,7 @@ const QUrl KoTextDocument::LayoutTextPageUrl = QUrl("kotext://layoutTextPage");
const QUrl KoTextDocument::ParaTableSpacingAtStartUrl = QUrl("kotext://spacingAtStart");
const QUrl KoTextDocument::IndexGeneratorManagerUrl = QUrl("kotext://indexGeneratorManager");
const QUrl KoTextDocument::FrameCharFormatUrl = QUrl("kotext://frameCharFormat");
const QUrl KoTextDocument::FrameBlockFormatUrl = QUrl("kotext://frameBlockFormat");
KoTextDocument::KoTextDocument(QTextDocument *document)
: m_document(document)
......@@ -348,3 +350,16 @@ void KoTextDocument::setFrameCharFormat(QTextCharFormat format)
m_document->addResource(KoTextDocument::FrameCharFormat, FrameCharFormatUrl, QVariant::fromValue(format));
}
QTextBlockFormat KoTextDocument::frameBlockFormat() const
{
QVariant resource = m_document->resource(KoTextDocument::FrameBlockFormat, FrameBlockFormatUrl);
if (resource.isValid())
return resource.value<QTextBlockFormat>();
else
return QTextBlockFormat();
}
void KoTextDocument::setFrameBlockFormat(QTextBlockFormat format)
{
m_document->addResource(KoTextDocument::FrameBlockFormat, FrameBlockFormatUrl, QVariant::fromValue(format));
}
......@@ -163,10 +163,38 @@ public:
void setParaTableSpacingAtStart(bool spacingAtStart);
bool paraTableSpacingAtStart() const;
/**
* Returns the character format for the frame of this document.
*
* @return the character format for the frame of this document.
* @see setFrameCharFormat
*/
QTextCharFormat frameCharFormat() const;
/**
* Sets the character format for the frame of this document.
*
* @param format the character format for the frame of this document.
* @see frameCharFormat
*/
void setFrameCharFormat(QTextCharFormat format);
/**
* Returns the block format for the frame of this document.
*
* @return the block format for the frame of this document.
* @see setFrameBlockFormat
*/
QTextBlockFormat frameBlockFormat() const;
/**
* Sets the block format for the frame of this document.
*
* @param format the block format for the frame of this document.
* @see frameBlockFormat
*/
void setFrameBlockFormat(QTextBlockFormat format);
/**
* Clears the text in the document. Unlike QTextDocument::clear(), this
* function does not clear the resources of the QTextDocument.
......@@ -188,8 +216,9 @@ public:
Selections,
LayoutTextPage, /// this is used for setting the correct page variable on the first resize and should not be used for other purposes
ParaTableSpacingAtStart, /// this is used during layouting to specify if at the first paragraph margin-top should be applied.
IndexGeneratorManager
, FrameCharFormat
IndexGeneratorManager,
FrameCharFormat,
FrameBlockFormat
};
static const QUrl StyleManagerURL;
......@@ -208,6 +237,7 @@ public:
static const QUrl ParaTableSpacingAtStartUrl;
static const QUrl IndexGeneratorManagerUrl;
static const QUrl FrameCharFormatUrl;
static const QUrl FrameBlockFormatUrl;
private:
QTextDocument *m_document;
......
......@@ -62,7 +62,7 @@ void ChangeStylesCommand::redo()
if (m_first) {
m_first = false;
m_changeFollower->processUpdates(m_changedStyles);
m_changeFollower->processUpdates();
}
}
......
......@@ -489,6 +489,7 @@ void KoTextLoader::loadBody(const KoXmlElement &bodyElem, QTextCursor &cursor)
d->defaultBlockFormat = cursor.blockFormat();
d->defaultCharFormat = cursor.charFormat();
KoTextDocument(document).setFrameCharFormat(cursor.blockCharFormat());
KoTextDocument(document).setFrameBlockFormat(cursor.blockFormat());
}
rootCallChecker++;
......
......@@ -60,7 +60,7 @@ void ChangeFollower::collectNeededInfo(const QSet<int> &changedStyles)
while (block.isValid()) {
memento->blockPosition = block.position();
memento->blockParentCharFormat = block.charFormat();
// FIXME memento->blockParentFormat = KoTextDocument(m_document).frameBlockFormat();
memento->blockParentFormat = KoTextDocument(m_document).frameBlockFormat();
memento->paragraphStyleId = 0;
if (!memento->blockParentCharFormat.isTableCellFormat()) {
......@@ -70,26 +70,20 @@ void ChangeFollower::collectNeededInfo(const QSet<int> &changedStyles)
bool blockChanged = false;
int id = block.blockFormat().intProperty(KoParagraphStyle::StyleId);
if (id > 0 && changedStyles.contains(id)) {
/* FIXME we should extract any direct formatting. Like this but needs testing:
KoParagraphStyle *style = sm->paragraphStyle(id);
Q_ASSERT(style);
style->applyStyle(bf);
memento->blockDirectFormat = block.blockFormat();
// Calculate block format of direct formatting.
memento->blockDirectFormat = block.blockFormat(); // frame + style + direct
style->applyStyle(memento->blockParentFormat);
clearCommonProperties(&memento->blockDirectFormat, memento->blockParentFormat);
QMap<int, QVariant> blockProperties = bf.properties();
foreach(int key, blockProperties.keys()) {
if (memento->blockDirectFormat.property(key) == bf.property(key)) {
memento->blockDirectFormat.clearProperty(key);
}
}
// Calculate char format of direct formatting.
memento->blockDirectCharFormat = block.charFormat(); // frame + style + direct
style->KoCharacterStyle::applyStyle(memento->blockParentCharFormat);
style->KoCharacterStyle::ensureMinimalProperties(memento->blockParentCharFormat);
clearCommonProperties(&memento->blockDirectCharFormat, memento->blockParentCharFormat);
QTextCharFormat basis = memento->blockParentCharFormat;
style->KoCharacterStyle::applyStyle(basis);
style->KoCharacterStyle::ensureMinimalProperties(basis);
memento->blockDirectCharFormat = block.charFormat();
memento->blockDirectCharFormat->removeDuplicates(basis);
*/
memento->paragraphStyleId = id;
blockChanged = true;
}
......@@ -111,12 +105,8 @@ void ChangeFollower::collectNeededInfo(const QSet<int> &changedStyles)
style->ensureMinimalProperties(blockCharFormat);
}
QMap<int, QVariant> props = blockCharFormat.properties();
foreach(int key, props.keys()) {
if (cf.property(key) == blockCharFormat.property(key)) {
cf.clearProperty(key);
}
}
clearCommonProperties(&cf, blockCharFormat);
memento->fragmentStyleId.append(id);
memento->fragmentDirectFormats.append(cf);
memento->fragmentCursors.append(cursor);
......@@ -133,7 +123,7 @@ void ChangeFollower::collectNeededInfo(const QSet<int> &changedStyles)
delete memento; // we always have one that is unused
}
void ChangeFollower::processUpdates(const QSet<int> &changedStyles)
void ChangeFollower::processUpdates()
{
KoStyleManager *sm = m_styleManager.data();
......@@ -146,19 +136,26 @@ void ChangeFollower::processUpdates(const QSet<int> &changedStyles)
KoParagraphStyle *style = sm->paragraphStyle(memento->paragraphStyleId);
Q_ASSERT(style);
// apply paragraph style with direct formatting on top.
style->applyStyle(memento->blockParentFormat);
memento->blockParentFormat.merge(memento->blockDirectFormat);
cursor.setBlockFormat(memento->blockParentFormat);
// apply list style formatting
if (KoTextDocument(m_document).list(block.textList())) {
if (style->list() == KoTextDocument(m_document).list(block.textList())) {
style->applyParagraphListStyle(block, block.blockFormat());
style->applyParagraphListStyle(block, memento->blockParentFormat);
}
} else {
style->applyParagraphListStyle(block, block.blockFormat());
style->applyParagraphListStyle(block, memento->blockParentFormat);
}
// apply character style with direct formatting on top.
style->KoCharacterStyle::applyStyle(memento->blockParentCharFormat);
style->KoCharacterStyle::ensureMinimalProperties(memento->blockParentCharFormat);
cursor.setBlockCharFormat(memento->blockParentCharFormat);
memento->blockParentCharFormat.merge(memento->blockDirectCharFormat);
//QTextBlockFormat bf = block.blockFormat();
cursor.setBlockCharFormat(memento->blockParentCharFormat);
}
QList<QTextCharFormat>::Iterator fmtIt = memento->fragmentDirectFormats.begin();
......@@ -185,5 +182,15 @@ void ChangeFollower::processUpdates(const QSet<int> &changedStyles)
m_mementos.clear();
}
void ChangeFollower::clearCommonProperties(QTextFormat *firstFormat, const QTextFormat &secondFormat)
{
Q_ASSERT(firstFormat);
foreach(int key, secondFormat.properties().keys()) {
if (firstFormat->property(key) == secondFormat.property(key)) {
firstFormat->clearProperty(key);
}
}
}
#include <ChangeFollower.moc>
......@@ -67,19 +67,25 @@ public:
void collectNeededInfo(const QSet<int> &changedStyles);
/**
* Will update all the text in the document that were identified during the build
* Will update all the text in the document that were identified during the collect
* stage.
* during the apply stage the updated styles are applied.
* @param changedStyles a list of styleIds. from KoParagraphStyle::styleId
* and KoCharacterStyle::styleId
*/
void processUpdates(const QSet<int> &changedStyles);
void processUpdates();
/// return the document this follower is following.
const QTextDocument *document() const {
return m_document;
}
private:
/**
* Helper function for clearing common properties.
*
* Clears properties in @a firstFormat that have the same value in @a secondFormat.
*/
void clearCommonProperties(QTextFormat *firstFormat, const QTextFormat &secondFormat);
private:
struct Memento
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment