24 #include "html/html_documentimpl.h" 70 r = toBegin ? obj->lastChild() : obj->firstChild();
83 r = toBegin ? obj->previousSibling() : obj->nextSibling();
109 RenderObject *r = obj;
112 #if DEBUG_CARETMODE > 3 113 kDebug(6200) <<
"renderObjectBelow: r " << r <<
" trav " << trav;
129 RenderObject *r = obj;
132 #if DEBUG_CARETMODE > 3 133 kDebug(6200) <<
"renderObjectAbove: r " << r <<
" trav " << trav;
147 if (box->isInlineTextBox())
return false;
148 RenderStyle *s = box->object()->style();
149 return s->borderLeftWidth() || s->borderRightWidth()
150 || s->borderTopWidth() || s->borderBottomWidth()
151 || s->paddingLeft().value() || s->paddingRight().value()
152 || s->paddingTop().value() || s->paddingBottom().value()
155 || s->marginLeft().value() || s->marginRight().value();
164 RenderStyle *s = r->style();
165 return s->borderLeftStyle() != BNONE || s->borderRightStyle() != BNONE
166 || s->borderTopStyle() != BNONE || s->borderBottomStyle() != BNONE
170 || s->hasClip() || s->hidesOverflow()
171 || s->backgroundColor().isValid() || s->backgroundImage();
189 RenderObject *base,
int &state)
198 RenderObject *la = 0;
203 #if DEBUG_CARETMODE > 5 204 kDebug(6200) <<
"a " << a <<
" trav " << trav;
207 #if DEBUG_CARETMODE > 4 208 kDebug(6200) <<
"a " << a <<
" trav " << trav <<
" origtrav " << origtrav <<
" ignoreOD " << ignoreOutsideDesc;
221 if (trav == OutsideAscending)
return a;
224 if (trav == OutsideAscending)
return a;
230 la = a; latrav = trav;
231 ignoreOutsideDesc =
false;
254 if (trav == OutsideAscending) {
258 la = a; latrav = trav;
270 if (la) trav = latrav, a = la;
285 if (!r)
return false;
286 return r->isTableCol() || r->isTableSection() || r->isTableRow()
287 || (r->isText() && !
static_cast<RenderText *
>(r)->firstTextBox());
307 RenderObject *base,
int &state)
311 #if DEBUG_CARETMODE > 2 312 kDebug(6200) <<
"after advanceSWP: r " << r <<
" trav " << trav <<
" toBegin " << toBegin;
329 NodeImpl *n = r->firstChild();
331 while (n) { r = n; n = n->firstChild(); }
332 return const_cast<NodeImpl *
>(r);
334 n = r->nextSibling();
337 while (n) { r = n; n = n->firstChild(); }
338 return const_cast<NodeImpl *
>(r);
342 if (n == baseElem) n = 0;
345 n = r->nextSibling();
349 while (n) { r = n; n = n->firstChild(); }
350 return const_cast<NodeImpl *
>(r);
353 if (n == baseElem) n = 0;
358 #if 0 // currently not used 368 static NodeImpl *prevLeafNode(NodeImpl *r, NodeImpl *baseElem)
370 NodeImpl *n = r->firstChild();
372 while (n) { r = n; n = n->firstChild(); }
373 return const_cast<NodeImpl *
>(r);
375 n = r->previousSibling();
378 while (n) { r = n; n = n->firstChild(); }
379 return const_cast<NodeImpl *
>(r);
383 if (n == baseElem) n = 0;
386 n = r->previousSibling();
390 while (n) { r = n; n = n->lastChild(); }
391 return const_cast<NodeImpl *
>(r);
394 if (n == baseElem) n = 0;
412 RenderObject *&r,
long &r_ofs,
bool &outside,
bool &outsideEnd)
414 if (node->nodeType() == Node::TEXT_NODE) {
417 r = node->renderer();
419 }
else if (node->nodeType() == Node::ELEMENT_NODE || node->nodeType() == Node::DOCUMENT_NODE) {
423 if (node->firstChild()) {
425 NodeImpl *child = offset <= 0 ? node->firstChild()
427 : node->childNode((
unsigned long)offset);
430 #if DEBUG_CARETMODE > 5 431 kDebug(6200) <<
"mapDTR: child " << child <<
"@" << (child ? child->nodeName().string() : QString()) <<
" atEnd " << atEnd;
433 if (atEnd) child = node->lastChild();
435 r = child->renderer();
441 if (r && child->nodeType() == Node::TEXT_NODE) {
443 RenderObject *o = node->renderer();
444 while (o->continuation() && o->continuation() != r)
445 o = o->continuation();
446 if (!r || o->continuation() != r) {
447 r = child->renderer();
453 if (r && r->isBR()) {
454 r = r->objectAbove();
462 r = node->renderer();
468 kWarning() <<
"Mapping from nodes of type " << node->nodeType()
469 <<
" not supported!" << endl;
484 bool outside,
bool outsideEnd, NodeImpl *&node,
long &offset)
488 #if DEBUG_CARETMODE > 5 489 kDebug(6200) <<
"mapRTD: r " << r <<
'@' << (r ? r->renderName() : QString()) << (r && r->element() ? QString(
".node ") + QString::number((
unsigned)r->element(),16) +
'@' + r->element()->nodeName().string() : QString()) <<
" outside " << outside <<
" outsideEnd " << outsideEnd;
491 if (node->nodeType() == Node::ELEMENT_NODE || node->nodeType() == Node::TEXT_NODE) {
494 NodeImpl *parent = node->parent();
498 if (r != node->renderer()) {
499 RenderObject *o = node->renderer();
500 while (o->continuation() && o->continuation() != r)
501 o = o->continuation();
502 if (o->continuation() == r) {
506 node = r->firstChild() ? r->firstChild()->element() : node;
510 if (!parent)
goto inside;
512 offset = (long)node->nodeIndex() + outsideEnd;
514 #if DEBUG_CARETMODE > 5 515 kDebug(6200) << node <<
"@" << (node ? node->nodeName().string() : QString()) <<
" offset " << offset;
524 kWarning() <<
"Mapping to nodes of type " << node->nodeType()
525 <<
" not supported!" << endl;
532 if (node && node->hasChildNodes()) node =
nextLeafNode(node, base);
544 if (!outside) atEnd = !toBegin;
545 if (!atEnd ^ toBegin)
558 bool toBegin,
bool &outside,
bool &atEnd)
585 RenderObject *base,
long &r_ofs,
586 bool &outside,
bool &outsideEnd)
591 #if DEBUG_CARETMODE > 2 592 kDebug(6200) <<
"findRenderer: node " << node <<
" " << (node ? node->nodeName().string() : QString()) <<
" offset " << offset <<
" r " << r <<
"[" << (r ? r->renderName() : QString()) <<
"] r_ofs " << r_ofs <<
" outside " << outside <<
" outsideEnd " << outsideEnd;
595 NodeImpl *baseElem = base ? base->element() : 0;
599 r = node->renderer();
600 if (r) r_ofs = offset;
602 #if DEBUG_CARETMODE > 3 603 kDebug(6200) <<
"1r " << r;
611 if (r) r_ofs = r->minOffset();
613 #if DEBUG_CARETMODE > 3 614 kDebug(6200) <<
"2r " << r;
627 DocumentImpl *doc = caretNode->getDocument();
630 if (doc->isHTMLDocument())
631 return static_cast<HTMLDocumentImpl *>(doc)->body();
638 #if DEBUG_CARETMODE > 0 639 void CaretBox::dump(QTextStream &ts,
const QString &
ind)
const 641 ts << ind <<
"b@" <<
_box;
644 ts <<
"<" << _box->object() <<
":" << _box->object()->renderName() <<
">";
647 ts <<
" " <<
_x <<
"+" <<
_y <<
"+" <<
_w <<
"*" <<
_h;
650 if (cb) ts <<
":" << cb->renderName();
659 #if DEBUG_CARETMODE > 0 660 # define DEBUG_ACIB 1 662 # define DEBUG_ACIB DEBUG_CARETMODE 668 bool coalesceOutsideBoxes =
false;
670 for (; box; box = box->nextOnLine()) {
672 kDebug(6200) <<
"box " << box;
673 kDebug(6200) <<
"box->object " << box->object();
674 kDebug(6200) <<
"x " << box->m_x <<
" y " << box->m_y <<
" w " << box->m_width <<
" h " << box->m_height <<
" baseline " << box->m_baseline <<
" ifb " << box->isInlineFlowBox() <<
" itb " << box->isInlineTextBox() <<
" rlb " << box->isRootInlineBox();
677 if (!box->object())
continue;
679 RenderStyle *s = box->object()->style(box->m_firstLine);
681 RenderStyle *ps = box->parent() && box->parent()->object()
682 ? box->parent()->object()->style(box->parent()->m_firstLine)
685 if (box->isInlineFlowBox()) {
687 kDebug(6200) <<
"isinlineflowbox " << box;
689 InlineFlowBox *flowBox =
static_cast<InlineFlowBox *
>(box);
690 bool rtl = ps->direction() == RTL;
691 const QFontMetrics &pfm = ps->fontMetrics();
693 if (flowBox->includeLeftEdge()) {
697 if (coalesceOutsideBoxes) {
698 if (sbp.
equalsBox(flowBox,
true,
false)) {
699 sbp.
it = lastCoalescedBox;
700 Q_ASSERT(!sbp.
found);
704 addCreatedFlowBoxEdge(flowBox, pfm,
true, rtl);
709 if (flowBox->firstChild()) {
711 kDebug(6200) <<
"this " <<
this <<
" flowBox " << flowBox <<
" firstChild " << flowBox->firstChild();
712 kDebug(6200) <<
"== recursive invocation";
714 addConvertedInlineBox(flowBox->firstChild(), sbp);
716 kDebug(6200) <<
"== recursive invocation end";
720 addCreatedFlowBoxInside(flowBox, s->fontMetrics());
724 if (flowBox->includeRightEdge()) {
725 addCreatedFlowBoxEdge(flowBox, pfm,
false, rtl);
726 lastCoalescedBox = preEnd();
727 sbp.
check(lastCoalescedBox);
728 coalesceOutsideBoxes =
true;
731 }
else if (box->isInlineTextBox()) {
733 kDebug(6200) <<
"isinlinetextbox " << box << (box->object() ? QString(
" contains \"%1\"").arg(QConstString(static_cast<RenderText *>(box->object())->str->s+box->minOffset(), qMin(box->maxOffset() - box->minOffset(), 15L)).string()) : QString());
735 caret_boxes.append(
new CaretBox(box,
false,
false));
738 coalesceOutsideBoxes =
false;
742 kDebug(6200) <<
"some replaced or what " << box;
745 bool rtl = ps->direction() == RTL;
746 const QFontMetrics &pfm = ps->fontMetrics();
748 if (coalesceOutsideBoxes) {
750 sbp.
it = lastCoalescedBox;
751 Q_ASSERT(!sbp.
found);
755 addCreatedInlineBoxEdge(box, pfm,
true, rtl);
759 caret_boxes.append(
new CaretBox(box,
false,
false));
762 addCreatedInlineBoxEdge(box, pfm,
false, rtl);
763 lastCoalescedBox = preEnd();
764 sbp.
check(lastCoalescedBox);
765 coalesceOutsideBoxes =
true;
775 caret_boxes.append(caretBox);
781 caretBox->
_y += flowBox->baseline() - fm.ascent();
782 caretBox->
_h = fm.height();
788 caret_boxes.append(caretBox);
790 if (left ^ rtl) caretBox->
_x -= flowBox->paddingLeft() + flowBox->borderLeft() + 1;
791 else caretBox->
_x += caretBox->
_w + flowBox->paddingRight() + flowBox->borderRight();
793 caretBox->
_y += flowBox->baseline() - fm.ascent();
794 caretBox->
_h = fm.height();
801 caret_boxes.append(caretBox);
803 if (left ^ rtl) caretBox->
_x--;
804 else caretBox->
_x += caretBox->
_w;
806 caretBox->
_y += box->baseline() - fm.ascent();
807 caretBox->
_h = fm.height();
812 InlineFlowBox *basicFlowBox, InlineBox *seekBox,
bool seekOutside,
827 deleter->append(result);
829 SeekBoxParams sbp(seekBox, seekOutside, seekOutsideEnd, seekObject, iter);
849 RenderStyle *s = cb->element() && cb->element()->parent()
850 && cb->element()->parent()->renderer()
851 ? cb->element()->parent()->renderer()->style()
853 bool rtl = s->direction() == RTL;
855 const QFontMetrics &fm = s->fontMetrics();
856 height = fm.height();
864 int hl = fm.leading() / 2;
865 int baseline = cb->baselinePosition(
false);
866 if (!cb->isReplaced() || cb->style()->display() == BLOCK) {
867 if (!outsideEnd ^ rtl)
868 _y -= fm.leading() / 2;
870 _y += qMax(cb->height() - fm.ascent() - hl, 0);
872 _y += baseline - fm.ascent() - hl;
877 RenderStyle *s = cb->style();
878 const QFontMetrics &fm = s->fontMetrics();
879 height = fm.height();
881 _x += cb->borderLeft() + cb->paddingLeft();
882 _y += cb->borderTop() + cb->paddingTop();
885 switch (s->textAlign()) {
893 _x += cb->contentWidth() / 2;
897 _x += cb->contentWidth();
903 deleter->append(result);
905 outside, outsideEnd));
906 iter = result->
begin();
910 #if DEBUG_CARETMODE > 0 911 void CaretBoxLine::dump(QTextStream &ts,
const QString &ind)
const 913 ts << ind <<
"cbl: baseFlowBox@" << basefb << endl;
914 QString ind2 = ind +
" ";
915 for (
size_t i = 0; i < caret_boxes.size(); i++) {
916 if (i > 0) ts << endl;
917 caret_boxes[i]->dump(ts, ind2);
934 while (b->parent() && b->object() != base) {
937 Q_ASSERT(b->isInlineFlowBox());
938 return static_cast<InlineFlowBox *
>(b);
945 return r->isRenderReplaced() && r->style()->display() == BLOCK;
968 bool outside, outsideEnd;
969 RenderObject *r =
findRenderer(node, offset, base, r_ofs, outside, outsideEnd);
970 if (!r) {
return 0; }
971 #if DEBUG_CARETMODE > 0 972 kDebug(6200) <<
"=================== findCaretBoxLine";
973 kDebug(6200) <<
"node " << node <<
" offset: " << offset <<
" r " << r->renderName() <<
"[" << r <<
"].node " << r->element()->nodeName().string() <<
"[" << r->element() <<
"]" <<
" r_ofs " << r_ofs <<
" outside " << outside <<
" outsideEnd " << outsideEnd;
986 if (r->isText())
do {
987 RenderText *t =
static_cast<RenderText *
>(r);
989 InlineBox *b = t->findInlineTextBox(offset, dummy,
true);
994 if (!t->lastTextBox())
996 b = t->lastTextBox();
1001 #if DEBUG_CARETMODE > 2 1002 kDebug(6200) <<
"text-box b: " << b <<
" baseFlowBox: " << baseFlowBox << (b && b->object() ? QString(
" contains \"%1\"").arg(QConstString(static_cast<RenderText *>(b->object())->str->s+b->minOffset(), qMin(b->maxOffset() - b->minOffset(), 15L)).string()) : QString());
1005 if (t->containingBlock()->isListItem()) dumpLineBoxes(static_cast<RenderFlow *>(t->containingBlock()));
1007 #if DEBUG_CARETMODE > 0 1008 kDebug(6200) <<
"=================== end findCaretBoxLine (renderText)";
1011 b, outside, outsideEnd, caretBoxIt);
1016 if (r->isRenderBlock() || r->isRenderInline() || isrepl) {
1017 RenderFlow *flow =
static_cast<RenderFlow *
>(r);
1018 InlineFlowBox *firstLineBox = isrepl ? 0 : flow->firstLineBox();
1023 if (isrepl || r->isRenderBlock() && (outside || !firstLineBox)
1024 || r->isRenderInline() && !firstLineBox) {
1025 #if DEBUG_CARETMODE > 0 1026 kDebug(6200) <<
"=================== end findCaretBoxLine (box " << (outside ? (outsideEnd ?
"outside end" :
"outside begin") :
"inside") <<
")";
1028 Q_ASSERT(r->isBox());
1030 static_cast<RenderBox *>(r), outside, outsideEnd, caretBoxIt);
1033 kDebug(6200) <<
"firstlinebox " << firstLineBox;
1036 firstLineBox, outside, outsideEnd, caretBoxIt);
1039 RenderBlock *cb = r->containingBlock();
1045 if (!cb->isRenderBlock()) {
1046 kWarning() <<
"containing block is no render block!!! crash imminent";
1049 InlineFlowBox *flowBox = cb->firstLineBox();
1059 #if DEBUG_CARETMODE > 0 1060 kDebug(6200) <<
"=================== end findCaretBoxLine (2)";
1063 outside, outsideEnd, caretBoxIt);
1069 for (; flowBox; flowBox =
static_cast<InlineFlowBox *
>(flowBox->nextLineBox())) {
1070 #if DEBUG_CARETMODE > 0 1071 kDebug(6200) <<
"[scan line]";
1077 baseFlowBox, 0, outside, outsideEnd, caretBoxIt, r);
1078 #if DEBUG_CARETMODE > 5 1079 kDebug(6200) << cbl->information();
1081 if (caretBoxIt != cbl->
end()) {
1082 #if DEBUG_CARETMODE > 0 1083 kDebug(6200) <<
"=================== end findCaretBoxLine (3)";
1094 #if DEBUG_CARETMODE > 0 1095 kDebug(6200) <<
"=================== end findCaretBoxLine";
1108 while (r && r != cb && !r->isTable()) r = r->parent();
1109 return r && r->isTable() ?
static_cast<RenderTable *
>(r) : 0;
1116 while (r && r != cb) r = r->parent();
1131 RenderTable *&table,
bool fromEnd =
false)
1133 RenderObject *r =
cb;
1135 while (r->lastChild()) r = r->lastChild();
1137 while (r->firstChild()) r = r->firstChild();
1139 RenderTable *tempTable = 0;
1154 #if DEBUG_CARETMODE > 1 1155 kDebug(6201) <<
"cee: r " << (r ? r->renderName() : QString()) <<
"@" << r <<
" cb " << cb <<
" withinCb " << withinCb <<
" modWithinCb " << modWithinCb <<
" tempTable " << tempTable;
1157 if (r && modWithinCb && r->element() && !
isUnsuitable(r, trav)
1159 || r->style()->userInput() == UI_ENABLED)) {
1161 #if DEBUG_CARETMODE > 1 1162 kDebug(6201) <<
"cee: editable";
1170 r = fromEnd ? r->objectAbove() : r->objectBelow();
1171 }
while (r && withinCb);
1188 RenderTable *&table,
bool fromEnd, RenderObject *start)
1193 RenderObject *r = start;
1201 if (!r)
return false;
1204 while (r->firstChild()) r = r->firstChild();
1206 while (r->lastChild()) r = r->lastChild();
1208 if (!r)
return false;
1210 RenderTable *tempTable = 0;
1212 bool withinCb =
false;
1224 #if DEBUG_CARETMODE > 1 1225 kDebug(6201) <<
"cece: r " << (r ? r->renderName() : QString()) <<
"@" << r <<
" cb " << cb <<
" withinCb " << withinCb <<
" modWithinCb " << modWithinCb <<
" tempTable " << tempTable;
1227 if (r && withinCb && r->element() && !
isUnsuitable(r, trav)
1229 || r->style()->userInput() == UI_ENABLED)) {
1231 #if DEBUG_CARETMODE > 1 1232 kDebug(6201) <<
"cece: editable";
1237 r = fromEnd ? r->objectAbove() : r->objectBelow();
1246 : node(node), offset(offset), m_part(part),
1247 advPol(advancePolicy), base(0)
1249 if (node == 0)
return;
1252 RenderObject *b = baseElem->renderer();
1253 if (b && (b->isRenderBlock() || b->isRenderInline()))
1278 NodeImpl *n =
base ?
base->element() : 0;
1280 if (!n)
return end();
1282 n = n->firstChild();
1284 while (n->firstChild()) n = n->firstChild();
1286 if (!n)
return end();
1292 NodeImpl *n =
base ?
base->element() : 0;
1298 while (n->lastChild()) n = n->lastChild();
1323 if (!node) {
cbl = 0;
return; }
1327 #if DEBUG_CARETMODE > 0 1328 if (!
cbl)
kDebug(6200) <<
"no render object found!";
1331 #if DEBUG_CARETMODE > 1 1332 kDebug(6200) <<
"LineIterator: offset " << offset <<
" outside " <<
cbl->
isOutside();
1334 #if DEBUG_CARETMODE > 3 1338 #if DEBUG_CARETMODE > 0 1339 kDebug(6200) <<
"LineIterator: findCaretBoxLine failed";
1358 #if DEBUG_CARETMODE > 1 1359 kDebug(6200) <<
"nextBlock: before adv r" << r <<
' ' << (r ? r->renderName() : QString()) << (r && r->isText() ?
" contains \"" + QString(((RenderText *)r)->str->s, qMin(((RenderText *)r)->str->l,15)) +
"\"" : QString()) <<
" trav " << trav <<
" cb_outside " << cb_outside <<
" cb_outside_end " << cb_outside_end;
1368 #if DEBUG_CARETMODE > 1 1369 kDebug(6200) <<
"nextBlock: after r" << r <<
" trav " << trav <<
" cb_outside " << cb_outside <<
" cb_outside_end " << cb_outside_end;
1371 #if DEBUG_CARETMODE > 0 1372 kDebug(6200) <<
"++: r " << r <<
"[" << (r?r->renderName():QString()) <<
"]";
1379 if (r->isRenderBlock() || isrepl) {
1380 RenderBox *cb =
static_cast<RenderBox *
>(r);
1385 #if DEBUG_CARETMODE > 0 1386 kDebug(6200) <<
"r->isFlow is cb. continuation @" << cb->continuation();
1390 cb = r->containingBlock();
1391 Q_ASSERT(cb->isRenderBlock());
1393 InlineFlowBox *flowBox = cb->firstLineBox();
1394 #if DEBUG_CARETMODE > 0 1395 kDebug(6200) <<
"++: flowBox " << flowBox <<
" cb " << cb <<
'[' << (cb?cb->renderName()+QString(
".node ")+QString::number((
unsigned)cb->element(),16)+(cb->element()?
'@'+cb->element()->nodeName().string():QString()):QString()) <<
']';
1399 cb_outside = cb_outside_end =
true;
1405 bool seekOutside =
false, seekOutsideEnd =
false;
1408 flowBox, flowBox->firstChild(), seekOutside, seekOutsideEnd, it);
1421 if (r->isAnonymous() && !cb_outside)
1422 cb_outside =
true, cb_outside_end =
false;
1427 #if DEBUG_CARETMODE > 1 1428 kDebug(6200) <<
"prevBlock: before adv r" << r <<
" " << (r ? r->renderName() : QString()) << (r && r->isText() ?
" contains \"" + QString(((RenderText *)r)->str->s, qMin(((RenderText *)r)->str->l,15)) +
"\"" : QString()) <<
" trav " << trav <<
" cb_outside " << cb_outside <<
" cb_outside_end " << cb_outside_end;
1437 #if DEBUG_CARETMODE > 1 1438 kDebug(6200) <<
"prevBlock: after r" << r <<
" trav " << trav <<
" cb_outside " << cb_outside <<
" cb_outside_end " << cb_outside_end;
1440 #if DEBUG_CARETMODE > 0 1441 kDebug(6200) <<
"--: r " << r <<
"[" << (r?r->renderName():QString()) <<
"]";
1449 if (r->isRenderBlock() || isrepl) {
1450 RenderBox *cb =
static_cast<RenderBox *
>(r);
1455 #if DEBUG_CARETMODE > 0 1456 kDebug(6200) <<
"r->isFlow is cb. continuation @" << cb->continuation();
1460 cb = r->containingBlock();
1461 Q_ASSERT(cb->isRenderBlock());
1463 InlineFlowBox *flowBox = cb->lastLineBox();
1464 #if DEBUG_CARETMODE > 0 1465 kDebug(6200) <<
"--: flowBox " << flowBox <<
" cb " << cb <<
"[" << (cb?cb->renderName()+QString(
".node ")+QString::number((
unsigned)cb->element(),16)+(cb->element()?
"@"+cb->element()->nodeName().string():QString()):QString()) <<
"]";
1469 cb_outside =
true; cb_outside_end =
false;
1475 bool seekOutside =
false, seekOutsideEnd =
false;
1478 flowBox, flowBox->firstChild(), seekOutside, seekOutsideEnd, it);
1486 flowBox =
static_cast<InlineFlowBox *
>(toBegin ? flowBox->prevLineBox() : flowBox->nextLineBox());
1488 bool seekOutside =
false, seekOutsideEnd =
false;
1491 flowBox, flowBox->firstChild(), seekOutside, seekOutsideEnd, it);
1498 #if DEBUG_CARETMODE > 3 1507 #if DEBUG_CARETMODE > 3 1508 kDebug(6200) <<
"---------------" <<
"toBegin " << toBegin;
1514 bool islastuseable =
true;
1519 #if DEBUG_CARETMODE > 4 1524 bool curAtEnd = *
this == preBegin || *
this == end;
1528 iscuruseable = isEditable(curbox, toBegin);
1530 atEnd = *
this == preBegin || *
this == end;
1533 bool haslast = lastbox != end && lastbox != preBegin;
1534 bool hascoming = !atEnd;
1535 bool iscominguseable =
true;
1537 if (!atEnd) iscominguseable = isEditable(*
this, toBegin);
1539 #if DEBUG_CARETMODE > 3 1540 kDebug(6200) <<
"ebit::advance: " << (*curbox)->object() <<
"@" << (*curbox)->object()->renderName() <<
".node " << (*curbox)->object()->element() <<
"[" << ((*curbox)->object()->element() ? (*curbox)->object()->element()->nodeName().string() : QString()) <<
"] inline " << (*curbox)->isInline() <<
" outside " << (*curbox)->isOutside() <<
" outsideEnd " << (*curbox)->isOutsideEnd();
1555 InlineBox *prev = box->
isOutsideEnd() ? ibox : ibox->prevOnLine();
1561 const bool last = haslast && !islastuseable;
1562 const bool coming = hascoming && !iscominguseable;
1563 const bool left = !prev || prev->isInlineFlowBox() && isprevindicated
1564 || (toBegin && coming || !toBegin && last);
1565 const bool right = !next || next->isInlineFlowBox() && isnextindicated
1566 || (!toBegin && coming || toBegin && last);
1567 const bool text2indicated = toBegin && next && next->isInlineTextBox()
1569 || !toBegin && prev && prev->isInlineTextBox() && isnextindicated;
1570 const bool indicated2text = !toBegin && next && next->isInlineTextBox()
1571 && prev && isprevindicated
1574 #if DEBUG_CARETMODE > 5 1575 kDebug(6200) <<
"prev " << prev <<
" haslast " << haslast <<
" islastuseable " << islastuseable <<
" left " << left <<
" next " << next <<
" hascoming " << hascoming <<
" iscominguseable " << iscominguseable <<
" right " << right <<
" text2indicated " << text2indicated <<
" indicated2text " << indicated2text;
1578 if (left && right && !text2indicated || indicated2text) {
1580 #if DEBUG_CARETMODE > 4 1581 kDebug(6200) <<
"left && right && !text2indicated || indicated2text";
1588 #if DEBUG_CARETMODE > 4 1591 kDebug(6200) <<
"inside " << (!ibox->isInlineFlowBox() ||
static_cast<InlineFlowBox *
>(ibox)->firstChild() ?
"non-empty" :
"empty") << (
isIndicatedInlineBox(ibox) ?
" indicated" :
"") <<
" adjacent=" << adjacent;
1594 RenderStyle *s = ibox->object()->style();
1595 kDebug(6200) <<
"bordls " << s->borderLeftStyle()
1596 <<
" bordl " << (s->borderLeftStyle() != BNONE)
1597 <<
" bordr " << (s->borderRightStyle() != BNONE)
1598 <<
" bordt " << (s->borderTopStyle() != BNONE)
1599 <<
" bordb " << (s->borderBottomStyle() != BNONE)
1600 <<
" padl " << s->paddingLeft().value()
1601 <<
" padr " << s->paddingRight().value()
1602 <<
" padt " << s->paddingTop().value()
1603 <<
" padb " << s->paddingBottom().value()
1606 <<
" marl " << s->marginLeft().value()
1607 <<
" marr " << s->marginRight().value()
1616 if (!(*curbox)->isOutside()) {
1623 islastuseable = iscuruseable;
1625 iscuruseable = iscominguseable;
1629 atEnd = *
this == preBegin || *
this == end;
1634 #if DEBUG_CARETMODE > 4 1637 #if DEBUG_CARETMODE > 3 1638 kDebug(6200) <<
"---------------" <<
"end ";
1646 RenderObject *r = b->object();
1647 #if DEBUG_CARETMODE > 0 1649 kDebug(6200) <<
"isEditable r" << r <<
": " << (r ? r->renderName() : QString()) << (r && r->isText() ?
" contains \"" + QString(((RenderText *)r)->str->s, qMin(((RenderText *)r)->str->l,15)) +
"\"" : QString());
1654 NodeImpl *node = r->element();
1662 if (!b->isOutside() && r->isRenderReplaced() && !r->firstChild())
1665 RenderObject *eff_r = r;
1666 bool globallyNavigable = m_part->isCaretMode() || m_part->isEditable();
1669 if (b->isOutside() && !globallyNavigable) {
1670 NodeImpl *par = node->parent();
1674 if (par) node = par;
1675 eff_r = node->renderer();
1679 bool result = globallyNavigable || eff_r->style()->userInput() == UI_ENABLED;
1680 #if DEBUG_CARETMODE > 0 1692 bool haslasteditable =
false;
1693 bool haslastindicated =
false;
1694 bool uselasteditable =
false;
1698 if (isEditable(*
this)) {
1699 #if DEBUG_CARETMODE > 3 1705 haslastindicated =
true;
1706 lastindicated = *
this;
1711 if (hasindicated)
goto wend;
1720 lasteditable = *
this;
1721 haslasteditable =
true;
1722 #if DEBUG_CARETMODE > 4 1723 kDebug(6200) <<
"remembered lasteditable " << *lasteditable;
1731 if (haslasteditable) { uselasteditable =
true;
break; }
1738 if (uselasteditable) *
this = haslastindicated ? lastindicated : lasteditable;
1739 if (!
cbl && haslastindicated) *
this = lastindicated;
1750 else if (b && !box->
isOutside() && b->isInlineTextBox())
1751 _char = static_cast<RenderText *>(b->object())->str->s[_offset].unicode();
1760 if (!box->
isInline())
return false;
1762 return ibox->isInlineFlowBox()
1763 && !
static_cast<InlineFlowBox *
>(ibox)->firstChild()
1774 #if DEBUG_CARETMODE > 0 1777 if (_offset == maxofs) {
1778 #if DEBUG_CARETMODE > 2 1779 kDebug(6200) <<
"_offset == maxofs: " << _offset <<
" == " << maxofs;
1782 }
else if (_offset > maxofs) {
1783 #if DEBUG_CARETMODE > 2 1784 kDebug(6200) <<
"_offset > maxofs: " << _offset <<
" > " << maxofs ;
1788 if (ebit == (*_it)->end()) {
1790 #if DEBUG_CARETMODE > 3 1793 if (_it != _it.lines->end()) {
1797 #if DEBUG_CARETMODE > 3 1801 #if DEBUG_CARETMODE > 3 1802 RenderObject *_r = box->
object();
1803 kDebug(6200) <<
"_r " << _r <<
":" << _r->element()->nodeName().string();
1806 #if DEBUG_CARETMODE > 3 1807 kDebug(6200) <<
"_offset " << _offset;
1817 bool adjacent = ebit.isAdjacent();
1820 if (adjacent && !(*ebit)->isInlineTextBox()) {
1823 if (ebit != (*_it)->end() && (*ebit)->isInlineTextBox()
1831 if (adjacent && !(*ebit)->isInlineTextBox()) {
1832 bool noemptybox =
true;
1837 if (ebit == (*_it)->end()) { ebit = copy;
break; }
1839 if (noemptybox) adjacent =
false;
1842 _offset = (*ebit)->minOffset() + adjacent;
1850 if (b && !box->
isOutside() && b->isInlineTextBox() && _offset < b->maxOffset())
1851 _char = static_cast<RenderText *>(b->object())->str->s[_offset].unicode();
1855 #if DEBUG_CARETMODE > 2 1856 kDebug(6200) <<
"_offset: " << _offset <<
" char '" << (char)_char <<
"'";
1859 #if DEBUG_CARETMODE > 0 1860 if (!_end && ebit != (*_it)->end()) {
1862 RenderObject *_r = box->
object();
1863 kDebug(6200) <<
"echit++(1): box " << box << (box && box->
isInlineTextBox() ? QString(
" contains \"%1\"").arg(QConstString(static_cast<RenderText *>(box->
object())->str->s+box->
minOffset(), box->
maxOffset() - box->
minOffset()).
string()) : QString()) <<
" _r " << (_r ? _r->element()->nodeName().string() : QString(
"<nil>"));
1879 #if DEBUG_CARETMODE > 0 1882 if (_offset == minofs) {
1883 #if DEBUG_CARETMODE > 2 1884 kDebug(6200) <<
"_offset == minofs: " << _offset <<
" == " << minofs;
1888 if (b && !box->
isOutside() && b->isInlineTextBox())
1889 _char = static_cast<RenderText *>(b->object())->text()[_offset].unicode();
1894 bool do_prev =
false;
1901 if (ebit == (*_it)->preBegin()) { ebit = copy;
break; }
1904 if (ebit.isAdjacent() && ebit != (*_it)->preBegin() && (*ebit)->isInlineTextBox()) {
1910 if (do_prev)
goto prev;
1911 }
else if (_offset < minofs) {
1913 #if DEBUG_CARETMODE > 2 1914 kDebug(6200) <<
"_offset < minofs: " << _offset <<
" < " << minofs ;
1919 if (ebit == (*_it)->preBegin()) {
1921 #if DEBUG_CARETMODE > 3 1924 if (_it != _it.lines->preBegin()) {
1929 #if DEBUG_CARETMODE > 3 1935 #if DEBUG_CARETMODE > 0 1944 #if DEBUG_CARETMODE > 0 1945 bool adjacent = ebit.isAdjacent();
1946 kDebug(6200) <<
"adjacent " << adjacent <<
" _peekNext " << _peekNext <<
" _peekNext->isInlineTextBox: " << (_peekNext ? _peekNext->
isInlineTextBox() :
false) <<
" !((*ebit)->isInlineTextBox): " << (*ebit ? !(*ebit)->isInlineTextBox() :
true);
1951 && !(*ebit)->isInlineTextBox()) {
1954 if (ebit == (*_it)->preBegin())
1961 && !(*ebit)->isInlineTextBox()) {
1962 bool noemptybox =
true;
1967 if (ebit == (*_it)->preBegin()) { ebit = copy;
break; }
1968 else _peekNext = *copy;
1970 if (noemptybox) adjacent =
false;
1973 #if DEBUG_CARETMODE > 0 1974 kDebug(6200) <<
"(*ebit)->obj " << (*ebit)->object()->renderName() <<
"[" << (*ebit)->object() <<
"]" <<
" minOffset: " << (*ebit)->minOffset() <<
" maxOffset: " << (*ebit)->maxOffset();
1976 #if DEBUG_CARETMODE > 3 1977 RenderObject *_r = (*ebit)->object();
1978 kDebug(6200) <<
"_r " << _r <<
":" << _r->element()->nodeName().string();
1980 _offset = (*ebit)->maxOffset();
1982 #if DEBUG_CARETMODE > 3 1983 kDebug(6200) <<
"_offset " << _offset;
1987 #if DEBUG_CARETMODE > 0 1988 kDebug(6200) <<
"_offset: " << _offset <<
" _peekNext: " << _peekNext;
1991 if (_peekNext && _offset >= box->
maxOffset() && _peekNext->isInlineTextBox())
1992 _char = static_cast<RenderText *>(_peekNext->object())->text()[_peekNext->minOffset()].unicode();
1993 else if (b && _offset < b->maxOffset() && b->isInlineTextBox())
1994 _char = static_cast<RenderText *>(b->object())->text()[_offset].unicode();
1999 #if DEBUG_CARETMODE > 0 2000 if (!_end && ebit != (*_it)->preBegin()) {
2011 RenderTableSection::RowStruct *row)
2012 : sec(table, fromEnd)
2016 if (fromEnd)
index = (*sec)->grid.size() - 1;
2022 while (
operator *() != row)
2031 if (
index >= (
int)(*sec)->grid.size()) {
2046 if (*
sec)
index = (*sec)->grid.size() - 1;
2055 RenderTableSection::RowStruct *row,
bool fromEnd);
2073 RenderTableCell *result = 0;
2079 if (fromEnd) --it;
else ++it;
2099 RenderTableSection::RowStruct *row,
bool fromEnd)
2102 int n = (int)row->row->size();
2104 for (i = 0; i < n; i++) {
2105 RenderTableCell *cell = row->row->at(i);
2106 if (!cell || (
long)cell == -1)
continue;
2109 cell->absolutePosition(absx, absy,
false);
2110 #if DEBUG_CARETMODE > 1 2111 kDebug(6201) <<
"i/n " << i <<
"/" << n <<
" absx " << absx <<
" absy " << absy;
2116 #if DEBUG_CARETMODE > 1 2117 kDebug(6201) <<
"x " << x <<
" < " << (absx + cell->width()) <<
"?";
2119 if (x < absx + cell->width())
break;
2121 if (i >= n) i = n - 1;
2125 for (
int cnt = 0; cnt < 2*n; cnt++) {
2126 int index = i - ((cnt >> 1) + 1)*(cnt & 1) + (cnt >> 1)*!(cnt & 1);
2127 if (index < 0 || index >= n)
continue;
2129 RenderTableCell *cell = row->row->at(index);
2130 if (!cell || (
long)cell == -1)
continue;
2132 #if DEBUG_CARETMODE > 1 2133 kDebug(6201) <<
"index " << index <<
" cell " << cell;
2135 RenderTable *nestedTable;
2144 if (fromEnd) --it;
else ++it;
2163 if (!r1 || !r2)
return 0;
2164 RenderTableSection *
sec = 0;
2165 int start_depth=0, end_depth=0;
2167 RenderObject *n = r1;
2168 while (n->parent()) {
2173 while( n->parent()) {
2178 while (end_depth > start_depth) {
2182 while (start_depth > end_depth) {
2190 if (r1->isTableSection()) sec = static_cast<RenderTableSection *>(r1);
2196 while (r1 && !r1->isTableCell() && !r1->isTableSection() && !r1->isTable())
2199 return r1 && r1->isTable() ?
sec : r1;
2210 RenderTableSection::RowStruct *&row, RenderTableCell *&directCell)
2213 RenderObject *r = cell;
2214 while (r != section) {
2215 if (r->isTableCell()) directCell = static_cast<RenderTableCell *>(r);
2222 int n = section->numRows();
2223 for (
int i = 0; i < n; i++) {
2224 row = §ion->grid[i];
2227 int m = row->row->size();
2228 for (
int j = 0; j < m; j++) {
2229 RenderTableCell *c = row->row->at(j);
2230 if (c == directCell)
return i;
2245 RenderTable *result = 0;
2246 while (leaf && leaf != block) {
2247 if (leaf->isTable()) result = static_cast<RenderTable *>(leaf);
2248 leaf = leaf->parent();
2258 while (r && !r->isTableCell()) r = r->parent();
2259 return static_cast<RenderTableCell *
>(r);
2263 RenderBlock *newBlock,
bool toBegin)
2269 newBlock,
true, toBegin, it);
2270 #if DEBUG_CARETMODE > 3 2271 kDebug(6201) << cbl->information();
2283 RenderTableCell *oldCell, RenderObject *newObject,
bool toBegin)
2293 #if DEBUG_CARETMODE > 1 2294 kDebug(6201) <<
" ancestor " << commonAncestor;
2298 if (!commonAncestor || commonAncestor->isTableCell()) {
2300 RenderTableCell *cell =
static_cast<RenderTableCell *
>(commonAncestor);
2303 #if DEBUG_CARETMODE > 0 2304 kDebug(6201) <<
"table cell: " << cell;
2313 }
else if (commonAncestor->isTableSection()) {
2315 RenderTableSection *section =
static_cast<RenderTableSection *
>(commonAncestor);
2316 RenderTableSection::RowStruct *row;
2318 #if DEBUG_CARETMODE > 1 2319 kDebug(6201) <<
"table section: row idx " << idx;
2325 int rowspan = oldCell->rowSpan();
2326 while (*it && rowspan--) {
2327 if (toBegin) --it;
else ++it;
2331 kError(6201) <<
"Neither common cell nor section! " << commonAncestor->renderName() << endl;
2336 #if DEBUG_CARETMODE > 1 2337 kDebug(6201) <<
"findNearestTableCell result: " << cell;
2340 RenderBlock *newBlock = cell;
2342 Q_ASSERT(commonAncestor->isTableSection());
2343 RenderTableSection *section =
static_cast<RenderTableSection *
>(commonAncestor);
2345 #if DEBUG_CARETMODE > 1 2346 kDebug(6201) <<
"containing cell: " << cell;
2349 RenderTable *nestedTable;
2351 cell, nestedTable, toBegin, section->table());
2353 if (cell && !editableChild) {
2354 #if DEBUG_CARETMODE > 1 2355 kDebug(6201) <<
"========= recursive invocation outer =========";
2357 determineTopologicalElement(cell, cell->section(), toBegin);
2358 #if DEBUG_CARETMODE > 1 2359 kDebug(6201) <<
"========= end recursive invocation outer =========";
2363 }
else if (cell && nestedTable) {
2364 #if DEBUG_CARETMODE > 1 2365 kDebug(6201) <<
"========= recursive invocation inner =========";
2367 determineTopologicalElement(cell, nestedTable, toBegin);
2368 #if DEBUG_CARETMODE > 1 2369 kDebug(6201) <<
"========= end recursive invocation inner =========";
2374 #if DEBUG_CARETMODE > 1 2375 kDebug(6201) <<
"newBlock is table: " << section->table();
2377 RenderObject *r = section->table();
2381 if (!r) { cbl = 0;
return; }
2383 newBlock =
static_cast<RenderBlock *
>(!r || r->isRenderBlock() ? r : r->containingBlock());
2392 RenderObject *r = newBlock;
2396 newBlock =
static_cast<RenderBlock *
>(!r || r->isRenderBlock() ? r : r->containingBlock());
2401 calcAndStoreNewLine(newBlock, toBegin);
2409 if (*
this == lines->end() || *
this == lines->preBegin())
return *
this;
2413 if (!newCell || newCell == oldCell)
return *
this;
2415 determineTopologicalElement(oldCell, newCell,
false);
2425 if (*
this == lines->end() || *
this == lines->preBegin())
return *
this;
2429 if (!newCell || newCell == oldCell)
return *
this;
2431 determineTopologicalElement(oldCell, newCell,
true);
2448 int &x,
int &absx,
int &absy)
2452 #if DEBUG_CARETMODE > 4 2453 kDebug(6200) <<
"nearestCB: cb " << cb <<
"@" << (cb ? cb->renderName() :
"");
2456 if (cb) cb->absolutePosition(absx, absy);
2457 else absx = absy = 0;
2462 x = cv->
origX - absx;
2468 #if DEBUG_CARETMODE > 0 2474 for (
CaretBox *b; fbit != (*it)->end(); ++fbit) {
2477 #if DEBUG_CARETMODE > 0 2487 if (oldXPos < 0 || x - (oldXPos + caretBox->
width()) > xPos - x) {
2496 if (x >= xPos && x < xPos + caretBox->width())
2514 #if DEBUG_CARETMODE > 0 2515 kDebug(6200) <<
"%%%%%%%%%%%%%%%%%%%%% moveItToNextWord";
2518 while (!it.
isEnd() && !(*it).isSpace() && !(*it).isPunct()) {
2519 #if DEBUG_CARETMODE > 2 2520 kDebug(6200) <<
"reading1 '" << (*it).toLatin1().constData() <<
"'";
2531 while (!it.
isEnd() && ((*it).isSpace() || (*it).isPunct())) {
2532 #if DEBUG_CARETMODE > 2 2533 kDebug(6200) <<
"reading2 '" << (*it).toLatin1().constData() <<
"'";
2539 if (it.
isEnd()) it = copy;
2549 if (it.
isEnd())
return;
2551 #if DEBUG_CARETMODE > 0 2552 kDebug(6200) <<
"%%%%%%%%%%%%%%%%%%%%% moveItToPrevWord";
2560 #if DEBUG_CARETMODE > 2 2561 if (!it.
isEnd())
kDebug(6200) <<
"reading1 '" << (*it).toLatin1().constData() <<
"'";
2563 }
while (!it.
isEnd() && ((*it).isSpace() || (*it).isPunct()));
2573 #if DEBUG_CARETMODE > 0 2574 if (!it.
isEnd())
kDebug(6200) <<
"reading2 '" << (*it).toLatin1().constData() <<
"' (" << (int)(*it).toLatin1().constData() <<
") box " << it.
caretBox();
2576 }
while (!it.
isEnd() && !(*it).isSpace() && !(*it).isPunct());
2579 #if DEBUG_CARETMODE > 1 2580 if (!it.
isEnd())
kDebug(6200) <<
"effective '" << (*it).toLatin1().constData() <<
"' (" << (int)(*it).toLatin1().constData() <<
") box " << it.
caretBox();
2596 if (it == ld.
end() || it == ld.
preBegin())
return;
2599 #if DEBUG_CARETMODE > 0 2600 kDebug(6200) <<
" mindist: " << mindist;
2604 int absx = 0, absy = 0;
2607 Q_ASSERT(lastcb->isRenderBlock());
2608 lastcb->absolutePosition(absx, absy,
false);
2614 if (next) ++copy;
else --copy;
2615 if (copy == ld.
end() || copy == ld.
preBegin())
break;
2626 diff = absy + lastfby + lastheight;
2627 cb->absolutePosition(absx, absy,
false);
2628 diff = absy - diff + fby;
2632 cb->absolutePosition(absx, absy,
false);
2633 diff -= absy + fby + lastheight;
2634 lastfby = fby - lastheight;
2636 #if DEBUG_CARETMODE > 2 2637 kDebug(6200) <<
"absdiff " << diff;
2640 diff = qAbs(fby - lastfby);
2642 #if DEBUG_CARETMODE > 2 2643 kDebug(6200) <<
"cbl->begin().data()->yPos(): " << fby <<
" diff " << diff;
2648 lastheight = qAbs(fby - lastfby);
2652 #if DEBUG_CARETMODE > 0 2653 kDebug(6200) <<
" mindist: " << mindist;
2659 }
while (mindist - lastheight > 0 && --rescue);
RenderObject * baseObject() const
Returns the base render object which the caret must not advance beyond.
static RenderTableCell * containingTableCell(RenderObject *r)
looks for the table cell the given object r is contained within.
static RenderTableCell * findNearestTableCellInRow(KHTMLPart *part, int x, RenderTableSection::RowStruct *row, bool fromEnd)
finds the nearest editable cell around the given absolute x-coordinate
static RenderObject * commonAncestorTableSectionOrCell(RenderObject *r1, RenderObject *r2)
returns the nearest common ancestor of two objects that is a table cell, a table section, or 0 if not inside a common table.
CaretBox * data() const
returns the current caret box.
static bool containsEditableChildElement(KHTMLPart *part, RenderBlock *cb, RenderTable *&table, bool fromEnd, RenderObject *start)
checks whether the given block contains at least one editable child element, beginning with but exclu...
int origX
For natural traversal of lines, the original x position is saved, and the actual x is set to the firs...
CaretAdvancePolicy advPol
bool isOutside() const
returns true when this caret box represents an ouside position of an element.
void mapDOMPosToRenderPos(NodeImpl *node, long offset, RenderObject *&r, long &r_ofs, bool &outside, bool &outsideEnd)
Maps a DOM Range position to the corresponding caret position.
static void mapRenderPosToTraversalState(bool outside, bool atEnd, bool toBegin, ObjectTraversalState &trav)
Converts a caret position to its respective object traversal state.
static CaretBoxIterator currentBox
virtual ~LinearDocument()
static RenderObject * advanceObject(RenderObject *r, ObjectTraversalState &trav, bool toBegin, RenderObject *base, int &state)
Advances to the next render object, taking into account the current traversal state.
Iterator begin()
Returns a line iterator pointing to the very first line of the document.
static bool isDescendant(RenderObject *r, RenderObject *cb)
checks whether r is a descendant of cb, or r == cb
KAction * copy(const QObject *recvr, const char *slot, QObject *parent)
static void mapTraversalStateToRenderPos(ObjectTraversalState trav, bool toBegin, bool &outside, bool &atEnd)
Converts a traversal state to its respective caret position.
Iterator preEnd()
Returns a line iterator pointing to the very last line of the document.
static RenderObject * traverseRenderObjects(RenderObject *obj, ObjectTraversalState &trav, bool toBegin, RenderObject *base, int &state)
Traverses the render object tree in a fine granularity.
bool check(const CaretBoxIterator &chit)
checks whether this box matches the given iterator.
This class is khtml's main class.
void mapRenderPosToDOMPos(RenderObject *r, long r_ofs, bool outside, bool outsideEnd, NodeImpl *&node, long &offset)
Maps a caret position to the corresponding DOM Range position.
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
ObjectAdvanceState
Flags representing the type of advance that has been made.
TableRowIterator()
empty constructor.
ObjectTraversalState
All possible states that may occur during render object traversal.
Represents a render table as a linear list of rows.
EditableLineIterator & operator++()
seek next line
static RenderTable * findTableUpTo(RenderObject *r, RenderFlow *cb)
finds the innermost table object r is contained within, but no farther than cb.
static RenderTable * findFirstDescendantTable(RenderObject *leaf, RenderBlock *block)
finds the table that is the first direct or indirect descendant of block.
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
bool isOutside() const
returns whether this caret box line is outside.
Iterates through the editable lines of a document, in a topological order.
const Iterator & end() const
Returns a line iterator pointing right after the end of the document.
void addCreatedInlineBoxEdge(InlineBox *box, const QFontMetrics &fm, bool left, bool rtl)
creates and adds the edge of a generic inline box
TableRowIterator & operator++()
advances to the next row
CaretBox * caretBox() const
returns the current caret box.
InlineBox * inlineBox() const
CaretBox()
empty constructor for later assignment
bool isCaretMode() const
Returns whether caret mode is on/off.
void calcAndStoreNewLine(RenderBlock *newBlock, bool toBegin)
initializes the iterator to point to the first previous/following editable line.
friend class EditableCaretBoxIterator
void prevBlock()
seeks previous block.
void advance(bool toBegin)
advances to the editable caret box to come
CaretBoxLineDeleter cblDeleter
InlineFlowBox * seekBaseFlowBox(InlineBox *b, RenderObject *base=0)
seeks the root line box that is the parent of the given inline box.
Iterator current()
Returns a line iterator containing the current position as its starting value.
static bool isIndicatedInlineBox(InlineBox *box)
Checks whether the given inline box matches the IndicatedFlows policy.
bool isOutsideEnd() const
returns whether this caret box line is at the outside end.
static bool containsEditableElement(KHTMLPart *part, RenderBlock *cb, RenderTable *&table, bool fromEnd=false)
checks whether the given block contains at least one editable element.
bool equalsBox(const InlineBox *box, bool outside, bool outsideEnd) const
compares whether this seek box matches the given specification
int count() const
Returns the count of lines.
void addConvertedInlineBox(InlineBox *, SeekBoxParams &)
recursively converts the given inline box into caret boxes and adds them to this caret box line...
RenderObject * object() const
returns the associated render object.
TableRowIterator & operator--()
advances to the previous row
RenderBlock * containingBlock() const
returns the containing block
long maxOffset() const
returns the maximum offset for this caret box.
bool isInline() const
returns the replaced render object if this caret box represents one, 0 otherwise. ...
static RenderObject * findRenderer(NodeImpl *&node, long offset, RenderObject *base, long &r_ofs, bool &outside, bool &outsideEnd)
Finds the next node that has a renderer.
CaretAdvancePolicy
caret advance policy.
static NodeImpl * nextLeafNode(NodeImpl *r, NodeImpl *baseElem)
Returns the next leaf node.
CaretBoxDeleter caret_boxes
bool isBlockRenderReplaced(RenderObject *r)
determines whether the given element is a block level replaced element.
void addCreatedFlowBoxEdge(InlineFlowBox *flowBox, const QFontMetrics &fm, bool left, bool rtl)
creates and adds the edge of an inline flow box
CaretAdvancePolicy advancePolicy() const
Returns the current caret advance policy.
CaretBoxIterator preBegin()
static long currentOffset
Resembles a line consisting of caret boxes.
static CaretBox * nearestCaretBox(LineIterator &it, CaretViewContext *cv, int &x, int &absx, int &absy)
seeks the caret box which contains or is the nearest to x
static int findRowInSection(RenderTableSection *section, RenderTableCell *cell, RenderTableSection::RowStruct *&row, RenderTableCell *&directCell)
Finds the row that contains the given cell, directly, or indirectly.
ErgonomicEditableLineIterator & operator--()
seek previous line.
static CaretBoxLine * constructCaretBoxLine(MassDeleter< CaretBoxLine > *deleter, InlineFlowBox *baseFlowBox, InlineBox *seekBox, bool seekOutside, bool seekOutsideEnd, CaretBoxIterator &iter, RenderObject *seekObject=0)
constructs a new caret box line out of the given inline flow box
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
Iterates over the elements of a caret box line.
RenderBox * enclosingObject() const
returns the enclosing object
static RenderObject * advanceSuitableObject(RenderObject *r, ObjectTraversalState &trav, bool toBegin, RenderObject *base, int &state)
Advances to the next render object, taking into account the current traversal state, but skipping render objects which are not suitable for having placed the caret into them.
static void moveIteratorByPage(LinearDocument &ld, ErgonomicEditableLineIterator &it, int mindist, bool next)
moves the iterator by one page.
LinearDocument(KHTMLPart *part, DOM::NodeImpl *node, long offset, CaretAdvancePolicy advancePolicy, DOM::ElementImpl *baseElem)
Creates a new instance, and initializes it to the line specified by the parameters below...
CaretBoxIterator & operator++()
increments the iterator to point to the next caret box.
bool isInlineTextBox() const
returns true if this caret box represents an inline text box.
long minOffset() const
returns the minimum offset for this caret box.
contextual information about the caret which is related to the view.
bool isEnd() const
returns true when the end of the document has been reached.
friend class LineIterator
static bool isUnsuitable(RenderObject *r, ObjectTraversalState trav)
Check whether the current render object is unsuitable in caret mode handling.
void determineTopologicalElement(RenderTableCell *oldCell, RenderObject *newObject, bool toBegin)
determines the topologically next render object.
void nextBlock()
seeks next block.
static ElementImpl * determineBaseElement(NodeImpl *caretNode)
returns a suitable base element
void initFirstChar()
initializes the _char member by reading the character at the current offset, peeking ahead as necessa...
ErgonomicEditableLineIterator & operator++()
seek next line.
static void moveItToNextWord(EditableCharacterIterator &it)
moves the given iterator to the beginning of the next word.
friend class CaretBoxLine
void advance(bool toBegin)
advances to the line to come.
static void ensureLeafNode(NodeImpl *&node, NodeImpl *base)
Make sure the given node is a leaf node.
static void moveItToPrevWord(EditableCharacterIterator &it)
moves the given iterator to the beginning of the previous word.
Iterates through the lines of a document.
Represents the whole document in terms of lines.
Represents a rectangular box within which the caret is located.
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
RenderBlock * containingBlock() const
returns the containing block of this caret box.
bool isEditable() const
Returns true if the document is editable, false otherwise.
EditableCharacterIterator & operator--()
moves to the previous editable character.
static RenderObject * renderObjectAbove(RenderObject *obj, ObjectTraversalState &trav, RenderObject *base)
Like RenderObject::objectAbove, but confined to stay within base.
CaretBoxIterator & operator--()
decrements the iterator to point to the previous caret box.
static RenderTableCell * findNearestTableCell(KHTMLPart *part, int x, TableRowIterator &it, bool fromEnd)
finds the cell corresponding to absolute x-coordinate x in the given table.
static RenderObject * renderObjectBelow(RenderObject *obj, ObjectTraversalState &trav, RenderObject *base)
Like RenderObject::objectBelow, but confined to stay within base.
void initPreBeginIterator()
Provides iterating through the document in terms of characters.
static QDebug & ind(const QDebug &dbgIn, int ind)
bool isOutsideEnd() const
returns the position at which the outside is targeted at.
void advance(bool toBegin)
advances to the line to come.
EditableCharacterIterator & operator++()
returns whether the current line box represents the outside of its render object. ...
static bool isIndicatedFlow(RenderObject *r)
Checks whether the given render object matches the IndicatedFlows policy.
static bool isCaretBoxEmpty(CaretBox *box)
returns true when the given caret box is empty, i.
static CaretBoxLine * findCaretBoxLine(DOM::NodeImpl *node, long offset, CaretBoxLineDeleter *cblDeleter, RenderObject *base, long &r_ofs, CaretBoxIterator &caretBoxIt)
determines the caret line box that contains the given position.
EditableLineIterator & operator--()
seek previous line.
bool isEditable(const CaretBoxIterator &boxit, bool fromEnd)
finds out if the given box is editable.
Iterates over the editable inner elements of a caret line box.
contains the seek parameters
void addCreatedFlowBoxInside(InlineFlowBox *flowBox, const QFontMetrics &fm)
creates and adds the inside of an inline flow box
const Iterator & preBegin() const
Returns a line iterator pointing just before the very first line of the document (this is somewhat an...
LineIterator()
Default constructor, only for internal use.
InlineFlowBox * baseFlowBox() const
returns the base inline flow box which the caret boxes of this caret box line have been constructed f...