Commit 65e28df5 authored by C. Boemann's avatar C. Boemann

Ensure that runthrough levels are evaluated all the way to the top

run through levels are a kind of super-z-index used in textdocuments
parent f0b05cae
...@@ -468,17 +468,53 @@ KoShape::ChildZOrderPolicy KoShape::childZOrderPolicy() ...@@ -468,17 +468,53 @@ KoShape::ChildZOrderPolicy KoShape::childZOrderPolicy()
bool KoShape::compareShapeZIndex(KoShape *s1, KoShape *s2) bool KoShape::compareShapeZIndex(KoShape *s1, KoShape *s2)
{ {
// First sort according to runThrough which is sort of a master level
KoShape *parentShapeS1 = s1->parent();
KoShape *parentShapeS2 = s2->parent();
int runThrough1 = s1->runThrough();
int runThrough2 = s2->runThrough();
while (parentShapeS1) {
if (parentShapeS1->childZOrderPolicy() == KoShape::ChildZParentChild) {
runThrough1 = parentShapeS1->runThrough();
} else {
runThrough1 = runThrough1 + parentShapeS1->runThrough();
}
parentShapeS1 = parentShapeS1->parent();
}
while (parentShapeS2) {
if (parentShapeS2->childZOrderPolicy() == KoShape::ChildZParentChild) {
runThrough2 = parentShapeS2->runThrough();
} else {
runThrough2 = runThrough2 + parentShapeS2->runThrough();
}
parentShapeS2 = parentShapeS2->parent();
}
if (runThrough1 > runThrough2) {
return false;
}
if (runThrough1 < runThrough2) {
return true;
}
// If on the same runThrough level then the zIndex is all that matters.
//
// We basically walk up through the parents until we find a common base parent
// To do that we need two loops where the inner loop walks up through the parents
// of s2 every time we step up one parent level on s1
//
// We don't update the index value until after we have seen that it's not a common base
// That way we ensure that two children of a common base are sorted according to their respective
// z value
bool foundCommonParent = false; bool foundCommonParent = false;
KoShape *parentShapeS1 = s1; int index1 = s1->zIndex();
KoShape *parentShapeS2 = s2; int index2 = s2->zIndex();
int index1 = parentShapeS1->zIndex(); parentShapeS1 = s1;
int index2 = parentShapeS2->zIndex(); parentShapeS2 = s2;
int runThrough1 = parentShapeS1->runThrough();
int runThrough2 = parentShapeS2->runThrough();
while (parentShapeS1 && !foundCommonParent) { while (parentShapeS1 && !foundCommonParent) {
parentShapeS2 = s2; parentShapeS2 = s2;
index2 = parentShapeS2->zIndex(); index2 = parentShapeS2->zIndex();
runThrough2 = parentShapeS2->runThrough();
while (parentShapeS2) { while (parentShapeS2) {
if (parentShapeS2 == parentShapeS1) { if (parentShapeS2 == parentShapeS1) {
foundCommonParent = true; foundCommonParent = true;
...@@ -486,9 +522,6 @@ bool KoShape::compareShapeZIndex(KoShape *s1, KoShape *s2) ...@@ -486,9 +522,6 @@ bool KoShape::compareShapeZIndex(KoShape *s1, KoShape *s2)
} }
if (parentShapeS2->childZOrderPolicy() == KoShape::ChildZParentChild) { if (parentShapeS2->childZOrderPolicy() == KoShape::ChildZParentChild) {
index2 = parentShapeS2->zIndex(); index2 = parentShapeS2->zIndex();
runThrough2 = parentShapeS2->runThrough();
} else {
runThrough2 = runThrough2 + parentShapeS2->runThrough();
} }
parentShapeS2 = parentShapeS2->parent(); parentShapeS2 = parentShapeS2->parent();
} }
...@@ -496,22 +529,11 @@ bool KoShape::compareShapeZIndex(KoShape *s1, KoShape *s2) ...@@ -496,22 +529,11 @@ bool KoShape::compareShapeZIndex(KoShape *s1, KoShape *s2)
if (!foundCommonParent) { if (!foundCommonParent) {
if (parentShapeS1->childZOrderPolicy() == KoShape::ChildZParentChild) { if (parentShapeS1->childZOrderPolicy() == KoShape::ChildZParentChild) {
index1 = parentShapeS1->zIndex(); index1 = parentShapeS1->zIndex();
runThrough1 = parentShapeS1->runThrough();
} else {
runThrough1 = runThrough1 + parentShapeS1->runThrough();
} }
parentShapeS1 = parentShapeS1->parent(); parentShapeS1 = parentShapeS1->parent();
} }
} }
// If the shape runs through the foreground or background.
if (runThrough1 > runThrough2) {
return false;
}
if (runThrough1 < runThrough2) {
return true;
}
// If the one shape is a parent/child of the other then sort so. // If the one shape is a parent/child of the other then sort so.
if (s1 == parentShapeS2) { if (s1 == parentShapeS2) {
return true; return true;
......
...@@ -124,7 +124,7 @@ void TestShapeReorderCommand::testParentChildSorting() ...@@ -124,7 +124,7 @@ void TestShapeReorderCommand::testParentChildSorting()
container1.setTextRunAroundSide(KoShape::RunThrough, KoShape::Foreground); container1.setTextRunAroundSide(KoShape::RunThrough, KoShape::Foreground);
container1.addShape(&shape1); container1.addShape(&shape1);
container1.addShape(&shape2); //container1.addShape(&shape2); //we shouldn't parent combine fg and bg
container2.addShape(&shape4); container2.addShape(&shape4);
container2.addShape(&shape5); container2.addShape(&shape5);
container1.addShape(&container2); container1.addShape(&container2);
...@@ -144,17 +144,31 @@ void TestShapeReorderCommand::testParentChildSorting() ...@@ -144,17 +144,31 @@ void TestShapeReorderCommand::testParentChildSorting()
qSort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex); qSort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
QCOMPARE(shapes.indexOf(&shape1), 3); /* This is the expected result
QCOMPARE(shapes.indexOf(&shape2), 2); s3 0 fg
s4 9999
s5 -9999
c2 57
c3 0
s1 -2
c1 -55 fg
s7 7
s6 3
s2 5 bg
*/
QCOMPARE(shapes.indexOf(&shape1), 4);
QCOMPARE(shapes.indexOf(&shape2), 0);
QCOMPARE(shapes.indexOf(&shape3), 9); QCOMPARE(shapes.indexOf(&shape3), 9);
QCOMPARE(shapes.indexOf(&shape4), 7); QCOMPARE(shapes.indexOf(&shape4), 8);
QCOMPARE(shapes.indexOf(&shape5), 6); QCOMPARE(shapes.indexOf(&shape5), 7);
QCOMPARE(shapes.indexOf(&shape6), 0); QCOMPARE(shapes.indexOf(&shape6), 1);
QCOMPARE(shapes.indexOf(&shape7), 1); QCOMPARE(shapes.indexOf(&shape7), 2);
QCOMPARE(shapes.indexOf(&container1), 3);
QCOMPARE(shapes.indexOf(&container1), 8); QCOMPARE(shapes.indexOf(&container2), 6);
QCOMPARE(shapes.indexOf(&container2), 5); QCOMPARE(shapes.indexOf(&container3), 5);
QCOMPARE(shapes.indexOf(&container3), 4);
} }
void TestShapeReorderCommand::testBringToFront() void TestShapeReorderCommand::testBringToFront()
......
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