Dillo v3.1.1-14-g8f67d6e0
Loading...
Searching...
No Matches
iterator.cc
Go to the documentation of this file.
1/*
2 * Dillo Widget
3 *
4 * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21
22#include "core.hh"
23#include <limits.h>
24
25using namespace lout;
26
27namespace dw {
28namespace core {
29
30// --------------
31// Iterator
32// --------------
33
34Iterator::Iterator(Widget *widget, Content::Type mask, bool atEnd)
35{
36 this->widget = widget;
37 this->mask = mask;
38}
39
41{
42 widget = it.widget;
43 content = it.content;
44}
45
49
51{
52 Iterator *otherIt = (Iterator*)other;
53 return
54 this == otherIt ||
55 (getWidget() == otherIt->getWidget() && compareTo(otherIt) == 0);
56}
57
59{
60 sb->append ("{ widget = ");
61 //widget->intoStringBuffer (sb);
63 sb->append (" (");
64 sb->append (widget->getClassName());
65 sb->append (")>");
66
67 sb->append (", mask = ");
69
70 sb->append (", content = ");
72
73 sb->append (" }");
74}
75
83{
84 delete this;
85}
86
98void Iterator::scrollTo (Iterator *it1, Iterator *it2, int start, int end,
99 HPosition hpos, VPosition vpos)
100{
101 Allocation alloc1, alloc2, alloc;
102 int x1, x2, y1, y2;
103 DeepIterator *eit1, *eit2, *eit3;
104 int curStart, curEnd, cmp;
105 bool atStart;
106
107 if (it1->equals(it2)) {
108 it1->getAllocation (start, end, &alloc);
109 it1->getWidget()->getLayout()->scrollTo (hpos, vpos, alloc.x, alloc.y,
110 alloc.width,
111 alloc.ascent + alloc.descent);
112 } else {
113 // First, determine the rectangle all iterators from it1 and it2
114 // allocate, i.e. the smallest rectangle containing all allocations of
115 // these iterators.
116 eit1 = new DeepIterator (it1);
117 eit2 = new DeepIterator (it2);
118
119 x1 = INT_MAX;
120 x2 = INT_MIN;
121 y1 = INT_MAX;
122 y2 = INT_MIN;
123
124 for (atStart = true, eit3 = (DeepIterator*)eit1->clone ();
125 (cmp = eit3->compareTo (eit2)) <= 0;
126 eit3->next (), atStart = false) {
127 if (atStart)
128 curStart = start;
129 else
130 curStart = 0;
131
132 if (cmp == 0)
133 curEnd = end;
134 else
135 curEnd = INT_MAX;
136
137 eit3->getAllocation (curStart, curEnd, &alloc);
138 x1 = misc::min (x1, alloc.x);
139 x2 = misc::max (x2, alloc.x + alloc.width);
140 y1 = misc::min (y1, alloc.y);
141 y2 = misc::max (y2, alloc.y + alloc.ascent + alloc.descent);
142 }
143
144 delete eit3;
145 delete eit2;
146 delete eit1;
147
148 it1->getAllocation (start, INT_MAX, &alloc1);
149 it2->getAllocation (0, end, &alloc2);
150
151 if (alloc1.x > alloc2.x) {
152 //
153 // This is due to a line break within the region. When the line is
154 // longer than the viewport, and the region is actually quite short,
155 // the user would not see anything of the region, as in this figure
156 // (with region marked as "#"):
157 //
158 // +----------+ ,-- alloc1
159 // | | V
160 // | | ### ###
161 // ### ### | |
162 // ^ | | <-- viewport
163 // | +----------+
164 // `-- alloc2
165 // |----------------------------|
166 // width
167 //
168 // Therefore, we make the region smaller, so that the region will be
169 // displayed like this:
170 //
171 // ,-- alloc1
172 // +----|-----+
173 // | V |
174 // | ### ###|
175 // ### ### | |
176 // ^ | | <-- viewport
177 // `-- alloc2 +----------+
178 // |----------|
179 // width
180 //
181
185 if (it1->getWidget()->getLayout()->getUsesViewport() &&
186 x2 - x1 > it1->getWidget()->getLayout()->getWidthViewport()) {
187 x1 = x2 - it1->getWidget()->getLayout()->getWidthViewport();
188 x2 = x1 + it1->getWidget()->getLayout()->getWidthViewport();
189 }
190 }
191
192 if (alloc1.y > alloc2.y) {
193 // This is similar to the case above, e.g. if the region ends in
194 // another table column.
195 if (it1->getWidget()->getLayout()->getUsesViewport() &&
196 y2 - y1 > it1->getWidget()->getLayout()->getHeightViewport()) {
197 y1 = y2 - it1->getWidget()->getLayout()->getHeightViewport();
198 y2 = y1 + it1->getWidget()->getLayout()->getHeightViewport();
199 }
200 }
201
202 it1->getWidget()->getLayout()->scrollTo (hpos, vpos,
203 x1, y1, x2 - x1, y2 - y1);
204 }
205}
206
207// -------------------
208// EmptyIterator
209// -------------------
210
212 Iterator (widget, mask, atEnd)
213{
214 this->content.type = (atEnd ? Content::END : Content::START);
215}
216
220
222{
223 return new EmptyIterator (*this);
224}
225
227{
228 EmptyIterator *otherIt = (EmptyIterator*)other;
229
230 if (content.type == otherIt->content.type)
231 return 0;
232 else if (content.type == Content::START)
233 return -1;
234 else
235 return +1;
236}
237
239{
241 return false;
242}
243
245{
247 return false;
248}
249
250void EmptyIterator::highlight (int start, int end, HighlightLayer layer)
251{
252}
253
255{
256}
257
258void EmptyIterator::getAllocation (int start, int end, Allocation *allocation)
259{
260}
261
262// ------------------
263// TextIterator
264// ------------------
265
267 const char *text): Iterator (widget, mask, atEnd)
268{
269 this->content.type = (atEnd ? Content::END : Content::START);
270 this->text = (mask & Content::TEXT) ? text : NULL;
271}
272
277
279{
280 TextIterator *otherIt = (TextIterator*)other;
281
282 if (content.type == otherIt->content.type)
283 return 0;
284
285 switch (content.type) {
286 case Content::START:
287 return -1;
288
289 case Content::TEXT:
290 if (otherIt->content.type == Content::START)
291 return +1;
292 else
293 return -1;
294
295 case Content::END:
296 return +1;
297
298 default:
300 return 0;
301 }
302}
303
305{
306 if (content.type == Content::START && text != NULL) {
308 content.text = text;
309 return true;
310 } else {
312 return false;
313 }
314}
315
317{
318 if (content.type == Content::END && text != NULL) {
320 content.text = text;
321 return true;
322 } else {
324 return false;
325 }
326}
327
328void TextIterator::getAllocation (int start, int end, Allocation *allocation)
329{
330 // Return the allocation of the widget.
331 *allocation = *(getWidget()->getAllocation ());
332}
333
334// ------------------
335// DeepIterator
336// ------------------
337
339{
340 for (int i = 0; i < size (); i++)
341 get(i)->unref ();
342}
343
344/*
345 * The following two methods are used by dw::core::DeepIterator::DeepIterator,
346 * when the passed dw::core::Iterator points to a widget. Since a
347 * dw::core::DeepIterator never returns a widget, the dw::core::Iterator has
348 * to be corrected, by searching for the next content downwards (within the
349 * widget pointed to), forwards, and backwards (in the traversed tree).
350 */
351
352/*
353 * Search downwards. If fromEnd is true, start search at the end,
354 * otherwise at the beginning.
355 */
357 bool fromEnd)
358{
359 Iterator *it2, *it3;
360
361 //DEBUG_MSG (1, "%*smoving down (%swards) from %s\n",
362 // indent, "", from_end ? "back" : "for", a_Dw_iterator_text (it));
363
364 assert (it->getContent()->type & Content::ANY_WIDGET);
365 it2 = it->getContent()->getWidget()->iterator (mask, fromEnd);
366
367 if (it2 == NULL) {
368 // Moving downwards failed.
369 //DEBUG_MSG (1, "%*smoving down failed\n", indent, "");
370 return NULL;
371 }
372
373 while (fromEnd ? it2->prev () : it2->next ()) {
374 //DEBUG_MSG (1, "%*sexamining %s\n",
375 // indent, "", a_Dw_iterator_text (it2));
376
377 if (it2->getContent()->type & Content::ANY_WIDGET) {
378 // Another widget. Search in it downwards.
379 it3 = searchDownward (it2, mask, fromEnd);
380 if (it3 != NULL) {
381 it2->unref ();
382 return it3;
383 }
384 // Else continue in this widget.
385 } else {
386 // Success!
387 //DEBUG_MSG (1, "%*smoving down succeeded: %s\n",
388 // indent, "", a_Dw_iterator_text (it2));
389 return it2;
390 }
391 }
392
393 // Nothing found.
394 it2->unref ();
395 //DEBUG_MSG (1, "%*smoving down failed (nothing found)\n", indent, "");
396 return NULL;
397}
398
399/*
400 * Search sidewards. fromEnd specifies the direction, false means forwards,
401 * true means backwards.
402 */
404 bool fromEnd)
405{
406 Iterator *it2, *it3;
407
408 //DEBUG_MSG (1, "%*smoving %swards from %s\n",
409 // indent, "", from_end ? "back" : "for", a_Dw_iterator_text (it));
410
411 assert (it->getContent()->type & Content::ANY_WIDGET);
412 it2 = it->cloneIterator ();
413
414 while (fromEnd ? it2->prev () : it2->next ()) {
415 if (it2->getContent()->type & Content::ANY_WIDGET) {
416 // Search downwards in this widget.
417 it3 = searchDownward (it2, mask, fromEnd);
418 if (it3 != NULL) {
419 it2->unref ();
420 //DEBUG_MSG (1, "%*smoving %swards succeeded: %s\n",
421 // indent, "", from_end ? "back" : "for",
422 // a_Dw_iterator_text (it3));
423 return it3;
424 }
425 // Else continue in this widget.
426 } else {
427 // Success!
428 // DEBUG_MSG (1, "%*smoving %swards succeeded: %s\n",
429 // indent, "", from_end ? "back" : "for",
430 // a_Dw_iterator_text (it2));
431 return it2;
432 }
433 }
434
435 /* Nothing found, go upwards in the tree (if possible). */
436 it2->unref ();
437 Widget *respParent = getRespectiveParent (it->getWidget(), it->getMask());
438 if (respParent) {
439 it2 = respParent->iterator (mask, false);
440 while (true) {
441 if (!it2->next ())
443
444 if (it2->getContent()->type & Content::ANY_WIDGET &&
445 it2->getContent()->getWidget () == it->getWidget ()) {
446 it3 = searchSideward (it2, mask, fromEnd);
447 it2->unref ();
448 //DEBUG_MSG (1, "%*smoving %swards succeeded: %s\n",
449 // indent, "", from_end ? "back" : "for",
450 // a_Dw_iterator_text (it3));
451 return it3;
452 }
453 }
454 }
455
456 // Nothing found at all.
457 // DEBUG_MSG (1, "%*smoving %swards failed (nothing found)\n",
458 // indent, "", from_end ? "back" : "for");
459 return NULL;
460}
461
463{
464 // Return, depending on which is requested indirectly (follow
465 // references or containments) the parent (container) or the
466 // generator. At this point, the type of the parent/generator is
467 // not known (since the parent/generator is not known), so we have
468 // to examine the mask. This is the reason why only one of
469 // WIDGET_OOF_CONT and WIDGET_OOF_REF is allowed.
470
471 return (mask & Content::WIDGET_OOF_REF) ?
472 widget->getGenerator() : widget->getParent();
473}
474
476{
477 // Similar to getRespectiveParent.
478
479 return (mask & Content::WIDGET_OOF_REF) ?
480 widget->getGeneratorLevel() : widget->getLevel();
481}
482
498{
499 //printf ("Starting creating DeepIterator %p ...\n", this);
500 //printf ("Initial iterator: ");
501 //it->print ();
502 //printf ("\n");
503
504 // Widgets out of flow are either followed widtin containers, or
505 // generators. Both (and also nothing at all) is not allowed. See
506 // also comment in getRespectiveParent.
507 int oofMask =
509 assert (oofMask == Content::WIDGET_OOF_CONT ||
510 oofMask == Content::WIDGET_OOF_REF);
511
512 //DEBUG_MSG (1, "a_Dw_ext_iterator_new: %s\n", a_Dw_iterator_text (it));
513
514 // Clone input iterator, so the iterator passed as parameter
515 // remains untouched.
516 it = it->cloneIterator ();
517 this->mask = it->getMask ();
518
519 hasContents = true;
520
521 // If it points to a widget, find a near non-widget content,
522 // since an DeepIterator should never return widgets.
523 if (it->getContent()->type & Content::ANY_WIDGET) {
524 Iterator *it2;
525
526 // The second argument of searchDownward is actually a matter of
527 // taste :-)
528 if ((it2 = searchDownward (it, mask, false)) ||
529 (it2 = searchSideward (it, mask, false)) ||
530 (it2 = searchSideward (it, mask, true))) {
531 it->unref ();
532 it = it2;
533 } else {
534 // This may happen, when a page does not contain any non-widget
535 // content.
536 //DEBUG_MSG (1, "a_Dw_ext_iterator_new got totally helpless!\n");
537 it->unref ();
538 hasContents = false;
539 }
540 }
541
542 //DEBUG_MSG (1, " => %s\n", a_Dw_iterator_text (it));
543
544 if (hasContents) {
545 // If this widget has parents, we must construct appropriate iterators.
546 //
547 // \todo There may be a faster way instead of iterating through the
548 // parent widgets.
549
550 //printf ("Starting with: ");
551 //it->print ();
552 //printf ("\n");
553
554 // Construct the iterators.
555 int thisLevel = getRespectiveLevel (it->getWidget()), level;
556 Widget *w;
557 for (w = it->getWidget (), level = thisLevel;
558 getRespectiveParent (w) != NULL;
559 w = getRespectiveParent (w), level--) {
560 Iterator *it = getRespectiveParent(w)->iterator (mask, false);
561
562 //printf (" parent: %s %p\n", w->getClassName (), w);
563
564 stack.put (it, level - 1);
565 while (true) {
566 //printf (" ");
567 //it->print ();
568 //printf ("\n");
569
570 bool hasNext = it->next();
571 assert (hasNext);
572
573 if (it->getContent()->type & Content::ANY_WIDGET &&
574 it->getContent()->getWidget () == w)
575 break;
576 }
577
578 //printf (" %d: ", level - 1);
579 //it->print ();
580 //printf ("\n");
581 }
582
583 stack.put (it, thisLevel);
584 content = *(it->getContent());
585 }
586
587 //printf ("... done creating DeepIterator %p.\n", this);
588}
589
590
592{
593 //printf ("Deleting DeepIterator %p ...\n", this);
594}
595
597{
598 DeepIterator *it = new DeepIterator ();
599
600 for (int i = 0; i < stack.size (); i++)
601 it->stack.put (stack.get(i)->cloneIterator (), i);
602
603 it->mask = mask;
604 it->content = content;
606
607 return it;
608}
609
611{
612 DeepIterator *otherDeepIterator = (DeepIterator*)other;
613
614 //printf ("Compare: %s\n", stack.toString ());
615 //printf (" to: %s\n", otherDeepIterator->stack.toString ());
616
617 // Search the highest level, where the widgets are the same.
618 int level = 0;
619
620 // The Comparable interface does not define "uncomparable". Deep
621 // iterators are only comparable if they belong to the same widget
622 // tree, so have the same widget at the bottom at the
623 // stack. If this is not the case, we abort.
624
625 assert (stack.size() > 0);
626 assert (otherDeepIterator->stack.size() > 0);
627
628 //printf ("Equal? The %s %p (of %p) and the %s %p (of %p)?\n",
629 // stack.get(0)->getWidget()->getClassName(),
630 // stack.get(0)->getWidget(), this,
631 // otherDeepIterator->stack.get(0)->getWidget()->getClassName(),
632 // otherDeepIterator->stack.get(0)->getWidget(), otherDeepIterator);
633
634 assert (stack.get(0)->getWidget()
635 == otherDeepIterator->stack.get(level)->getWidget());
636
637 while (stack.get(level)->getWidget ()
638 == otherDeepIterator->stack.get(level)->getWidget ()) {
639 if (level == stack.size() - 1 ||
640 level == otherDeepIterator->stack.size() - 1)
641 break;
642 level++;
643 }
644
645 //printf (" => level = %d (temorally)\n", level);
646
647 while (stack.get(level)->getWidget ()
648 != otherDeepIterator->stack.get(level)->getWidget ())
649 level--;
650
651 //printf (" => level = %d (finally)\n", level);
652
653 return stack.get(level)->compareTo (otherDeepIterator->stack.get(level));
654}
655
661
663 return !hasContents;
664}
665
672{
673 Iterator *it = stack.getTop ();
674
675 if (it->next ()) {
676 if (it->getContent()->type & Content::ANY_WIDGET) {
677 // Widget: new iterator on stack, to search in this widget.
678 stack.push (it->getContent()->getWidget()->iterator (mask, false));
679 return next ();
680 } else {
681 // Simply return the content of the iterartor.
682 content = *(it->getContent ());
683 return true;
684 }
685 } else {
686 // No more data in the top-most widget.
687 if (stack.size () > 1) {
688 // Pop iterator from stack, and move to next item in the old one.
689 stack.pop ();
690 return next ();
691 } else {
692 // Stack is empty.
694 return false;
695 }
696 }
697}
698
705{
706 Iterator *it = stack.getTop ();
707
708 if (it->prev ()) {
709 if (it->getContent()->type & Content::ANY_WIDGET) {
710 // Widget: new iterator on stack, to search in this widget.
711 stack.push (it->getContent()->getWidget()->iterator (mask, true));
712 return prev ();
713 } else {
714 // Simply return the content of the iterartor.
715 content = *(it->getContent ());
716 return true;
717 }
718 } else {
719 // No more data in the top-most widget.
720 if (stack.size () > 1) {
721 // Pop iterator from stack, and move to next item in the old one.
722 stack.pop ();
723 return prev ();
724 } else {
725 // Stack is empty.
727 return false;
728 }
729 }
730}
731
732// -----------------
733// CharIterator
734// -----------------
735
737{
738 it = NULL;
739}
740
748CharIterator::CharIterator (Widget *widget, bool followReferences)
749{
750 Iterator *i =
751 widget->iterator (Content::maskForSelection (followReferences), false);
752 it = new DeepIterator (i);
753 i->unref ();
754 ch = START;
755}
756
758{
759 if (it)
760 delete it;
761}
762
764{
765 CharIterator *cloned = new CharIterator ();
766 cloned->it = it->cloneDeepIterator ();
767 cloned->ch = ch;
768 cloned->pos = pos;
769 return cloned;
770}
771
773{
774 CharIterator *otherIt = (CharIterator*)other;
775 int c = it->compareTo(otherIt->it);
776 if (c != 0)
777 return c;
778 else
779 return pos - otherIt->pos;
780}
781
783{
784 if (ch == START || it->getContent()->type == Content::BREAK ||
785 (it->getContent()->type == Content::TEXT &&
786 it->getContent()->text[pos] == 0)) {
787 if (it->next()) {
788 if (it->getContent()->type == Content::BREAK)
789 ch = '\n';
790 else { // if (it->getContent()->type == Content::TEXT)
791 pos = 0;
792 ch = it->getContent()->text[pos];
793 if (ch == 0)
794 // should not happen, actually
795 return next ();
796 }
797 return true;
798 }
799 else {
800 ch = END;
801 return false;
802 }
803 } else if (ch == END)
804 return false;
805 else {
806 // at this point, it->getContent()->type == Content::TEXT
807 pos++;
808 ch = it->getContent()->text[pos];
809 if (ch == 0) {
810 if (it->getContent()->space) {
811 ch = ' ';
812 } else {
813 return next ();
814 }
815 }
816
817 return true;
818 }
819}
820
822{
823 if (ch == END || it->getContent()->type == Content::BREAK ||
824 (it->getContent()->type == Content::TEXT && pos == 0)) {
825 if (it->prev()) {
826 if (it->getContent()->type == Content::BREAK)
827 ch = '\n';
828 else { // if (it->getContent()->type == Content::TEXT)
829 if (it->getContent()->text[0] == 0)
830 return prev ();
831 else {
832 pos = strlen (it->getContent()->text);
833 if (it->getContent()->space) {
834 ch = ' ';
835 } else {
836 pos--;
837 ch = it->getContent()->text[pos];
838 }
839 }
840 }
841 return true;
842 }
843 else {
844 ch = START;
845 return false;
846 }
847 } else if (ch == START)
848 return false;
849 else {
850 // at this point, it->getContent()->type == Content::TEXT
851 pos--;
852 ch = it->getContent()->text[pos];
853 return true;
854 }
855}
856
858 HighlightLayer layer)
859{
860 if (it2->getChar () == CharIterator::END)
861 it2->prev ();
862
863 if (it1->it->compareTo (it2->it) == 0)
864 // Only one content => highlight part of it.
865 it1->it->highlight (it1->pos, it2->pos, layer);
866 else {
867 DeepIterator *it = it1->it->cloneDeepIterator ();
868 int c;
869 bool start;
870 for (start = true;
871 (c = it->compareTo (it2->it)) <= 0;
872 it->next (), start = false) {
873 int endOfWord =
874 it->getContent()->type == Content::TEXT ?
875 strlen (it->getContent()->text) : 1;
876 if (start) // first iteration
877 it->highlight (it1->pos, endOfWord, layer);
878 else if (c == 0) // last iteration
879 it->highlight (0, it2->pos, layer);
880 else
881 it->highlight (0, endOfWord, layer);
882 }
883 delete it;
884 }
885}
886
888 HighlightLayer layer)
889{
890 if (it1->it->compareTo (it2->it) == 0)
891 // Only one content => unhighlight it (only for efficiency).
892 it1->it->unhighlight (0, layer);
893 else {
894 DeepIterator *it = it1->it->cloneDeepIterator ();
895 for (; it->compareTo (it2->it) <= 0; it->next ())
896 it->unhighlight (-1, layer);
897 delete it;
898 }
899}
900
901} // namespace core
902} // namespace dw
static void highlight(CharIterator *it1, CharIterator *it2, HighlightLayer layer)
Definition iterator.cc:857
int compareTo(lout::object::Comparable *other)
Compare two objects, this and other.
Definition iterator.cc:772
static void unhighlight(CharIterator *it1, CharIterator *it2, HighlightLayer layer)
Definition iterator.cc:887
DeepIterator * it
Definition iterator.hh:238
lout::object::Object * clone()
Return an exact copy of the object.
Definition iterator.cc:763
void push(Iterator *it)
Definition iterator.hh:155
A stack of iterators, to iterate recursively through a widget tree.
Definition iterator.hh:147
static Iterator * searchDownward(Iterator *it, Content::Type mask, bool fromEnd)
Definition iterator.cc:356
static Iterator * searchSideward(Iterator *it, Content::Type mask, bool fromEnd)
Definition iterator.cc:403
DeepIterator * cloneDeepIterator()
Definition iterator.hh:196
static int getRespectiveLevel(Widget *widget, Content::Type mask)
Definition iterator.cc:475
Content::Type mask
Definition iterator.hh:166
DeepIterator * createVariant(Iterator *it)
Definition iterator.cc:656
void highlight(int start, int end, HighlightLayer layer)
Highlight a part of the current content.
Definition iterator.hh:207
int compareTo(lout::object::Comparable *other)
Compare two objects, this and other.
Definition iterator.cc:610
Content * getContent()
Definition iterator.hh:190
bool prev()
Move iterator backward and store content it.
Definition iterator.cc:704
lout::object::Object * clone()
Return an exact copy of the object.
Definition iterator.cc:596
static Widget * getRespectiveParent(Widget *widget, Content::Type mask)
Definition iterator.cc:462
bool next()
Move iterator forward and store content it.
Definition iterator.cc:671
void getAllocation(int start, int end, Allocation *allocation)
Return the shape, which a part of the item, the iterator points on, allocates.
Definition iterator.hh:217
void unhighlight(int direction, HighlightLayer layer)
Definition iterator.hh:220
This implementation of dw::core::Iterator can be used by widgets with no contents.
Definition iterator.hh:97
bool next()
Move iterator forward and store content it.
Definition iterator.cc:238
EmptyIterator(EmptyIterator &it)
Definition iterator.cc:217
lout::object::Object * clone()
Return an exact copy of the object.
Definition iterator.cc:221
void unhighlight(int direction, HighlightLayer layer)
Shrink highlighted region to no longer contain the current content.
Definition iterator.cc:254
int compareTo(lout::object::Comparable *other)
Compare two objects, this and other.
Definition iterator.cc:226
void getAllocation(int start, int end, Allocation *allocation)
Return the shape, which a part of the item, the iterator points on, allocates.
Definition iterator.cc:258
bool prev()
Move iterator backward and store content it.
Definition iterator.cc:244
void highlight(int start, int end, HighlightLayer layer)
Extend highlighted region to contain part of the current content.
Definition iterator.cc:250
Iterators are used to iterate through the contents of a widget.
Definition iterator.hh:20
Widget * getWidget()
Definition iterator.hh:36
virtual void getAllocation(int start, int end, Allocation *allocation)=0
Return the shape, which a part of the item, the iterator points on, allocates.
virtual void unref()
Delete the iterator.
Definition iterator.cc:82
static void scrollTo(Iterator *it1, Iterator *it2, int start, int end, HPosition hpos, VPosition vpos)
Scrolls the viewport, so that the region between it1 and it2 is seen, according to hpos and vpos.
Definition iterator.cc:98
void intoStringBuffer(lout::misc::StringBuffer *sb)
Store a textual representation of the object in a misc::StringBuffer.
Definition iterator.cc:58
virtual bool next()=0
Move iterator forward and store content it.
Iterator(Widget *widget, Content::Type mask, bool atEnd)
Definition iterator.cc:34
Content * getContent()
Definition iterator.hh:37
virtual bool prev()=0
Move iterator backward and store content it.
bool equals(Object *other)
Returns, whether two objects are equal.
Definition iterator.cc:50
Iterator * cloneIterator()
Definition iterator.hh:85
Content::Type getMask()
Definition iterator.hh:38
Content::Type mask
Definition iterator.hh:30
int getWidthViewport()
Definition layout.hh:285
bool getUsesViewport()
Definition layout.hh:284
int getHeightViewport()
Definition layout.hh:286
void scrollTo(HPosition hpos, VPosition vpos, int x, int y, int width, int height)
Scrolls all viewports, so that the region [x, y, width, height] is seen, according to hpos and vpos.
Definition layout.cc:531
This implementation of dw::core::Iterator can be used by widgets having one text word as contents.
Definition iterator.hh:119
const char * text
May be NULL, in this case, the next is skipped.
Definition iterator.hh:122
TextIterator(TextIterator &it)
Definition iterator.cc:273
bool next()
Move iterator forward and store content it.
Definition iterator.cc:304
bool prev()
Move iterator backward and store content it.
Definition iterator.cc:316
void getAllocation(int start, int end, Allocation *allocation)
Return the shape, which a part of the item, the iterator points on, allocates.
Definition iterator.cc:328
int compareTo(lout::object::Comparable *other)
Compare two objects, this and other.
Definition iterator.cc:278
The base class of all dillo widgets.
Definition widget.hh:24
Allocation * getAllocation()
Definition widget.hh:450
virtual Iterator * iterator(Content::Type mask, bool atEnd)=0
Return an iterator for this widget.
Widget * getParent()
Definition widget.hh:552
int getLevel()
Get the level of the widget within the tree.
Definition widget.cc:1493
Widget * getGenerator()
Definition widget.hh:565
Layout * getLayout()
Definition widget.hh:567
int getGeneratorLevel()
Get the level of the widget within the tree, regarting the generators, not the parents.
Definition widget.cc:1512
void put(T *newElement, int newPos=-1)
Definition container.hh:452
const char * getClassName()
Return the name, under which the class of this object was registered.
Definition identity.hh:140
A class for fast concatenation of a large number of strings.
Definition misc.hh:566
void appendPointer(void *p)
Definition misc.hh:592
void append(const char *str)
Append a NUL-terminated string to the buffer, with copying.
Definition misc.hh:589
Instances of a sub class of may be compared (less, greater).
Definition object.hh:42
virtual int compareTo(Comparable *other)=0
Compare two objects, this and other.
This is the base class for many other classes, which defines very common virtual methods.
Definition object.hh:25
HighlightLayer
Definition types.hh:43
VPosition
Definition types.hh:26
HPosition
Definition types.hh:16
Dw is in this namespace, or sub namespaces of this one.
T min(T a, T b)
Definition misc.hh:19
T max(T a, T b)
Definition misc.hh:20
void assertNotReached()
Definition misc.hh:35
Represents the allocation, i.e.
Definition types.hh:164
@ WIDGET_OOF_REF
reference to a widget out of flow (OOF); this widget (containing this content) is only the generator ...
Definition types.hh:217
@ WIDGET_OOF_CONT
widget out of flow (OOF); this widget (containing this content) is only the container (parent),...
Definition types.hh:212
const char * text
Definition types.hh:236
Widget * getWidget()
Definition types.hh:249
static Content::Type maskForSelection(bool followReferences)
Definition types.cc:271
static void maskIntoStringBuffer(Type mask, lout::misc::StringBuffer *sb)
Definition types.cc:327
static void intoStringBuffer(Content *content, lout::misc::StringBuffer *sb)
Definition types.cc:279