• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.4 API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • khtml
khtml_caret_p.h
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2003-2004 Leo Savernik <l.savernik@aon.at>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifndef KHTML_CARET_P_H
22 #define KHTML_CARET_P_H
23 
24 #include "rendering/render_table.h"
25 
26 
27 #define DEBUG_CARETMODE 0
28 
29 class QFontMetrics;
30 
31 namespace DOM {
32  class NodeImpl;
33  class ElementImpl;
34 }
35 
36 namespace khtml {
37 
53 enum CaretAdvancePolicy {
54  LeafsOnly, IndicatedFlows, VisibleFlows
55 };
56 
60 struct CaretViewContext {
61  int freqTimerId; // caret blink frequency timer id
62  int x, y; // caret position in viewport coordinates
63  // (y specifies the top, not the baseline)
64  int width; // width of caret in pixels
65  int height; // height of caret in pixels
66  bool visible; // true if currently visible.
67  bool displayed; // true if caret is to be displayed at all.
68  bool caretMoved; // set to true once caret has been moved in page
69  // how to display the caret when view is not focused
70  KHTMLPart::CaretDisplayPolicy displayNonFocused;
71 
79  int origX;
80 
81  bool keyReleasePending; // true if keypress under caret mode awaits
82  // corresponding release event
83  CaretViewContext() : freqTimerId(-1), x(0), y(0), width(1), height(16),
84  visible(true), displayed(false), caretMoved(false),
85  displayNonFocused(KHTMLPart::CaretInvisible), origX(0),
86  keyReleasePending(false)
87  {}
88 };
89 
90 class LinearDocument;
91 
102 template<class T> class MassDeleter : public QVector<T *> {
103 public:
104  MassDeleter(size_t reserved = 1) { this->reserve(reserved); }
105  ~MassDeleter()
106  {
107  typename QVector<T *>::Iterator nd = this->end();
108  for (typename QVector<T *>::Iterator it = this->begin(); it != nd; ++it)
109  delete *it;
110  }
111 };
112 
113 class CaretBoxLine;
114 
126 class CaretBox {
127 protected:
128  InlineBox *_box; // associated inline box if available.
129  short _w; // width of box in pixels
130  int _h; // height of box in pixels
131  int _x; // x coordinate relative to containing block
132  int _y; // y coordinate relative to containing block
133  RenderBox *cb; // containing block
134  bool _outside:1; // true when representing the outside of the element
135  bool outside_end:1; // at ending outside of element rather than at beginning
136  // 29 bits unused
137 
138 public:
140  CaretBox() {}
142  CaretBox(InlineBox *ibox, bool outside, bool outsideEnd) : _box(ibox),
143  _w((short)ibox->width()), _h(ibox->height()), _x(ibox->xPos()),
144  _y(ibox->yPos()), cb(0), _outside(outside), outside_end(outsideEnd)
145  {
146  RenderObject *r = ibox->object();
147  if (r) cb = r->containingBlock();
148  }
150  CaretBox(int x, int y, int w, int h, RenderBox *cb, bool outside, bool outsideEnd) :
151  _box(0), _w((short)w), _h(h), _x(x), _y(y), cb(cb), _outside(outside),
152  outside_end(outsideEnd)
153  {}
154 
155  int width() const { return _w; }
156  int height() const { return _h; }
157  int xPos() const { return _x; }
158  int yPos() const { return _y; }
159  RenderBox *enclosingObject() const { return cb; }
160  InlineBox *inlineBox() const { return _box; }
161 
165  RenderBlock *containingBlock() const { return _box ? static_cast<RenderBlock *>(cb) : cb->containingBlock(); }
166 
175  bool isInline() const { return _box; }
178  bool isInlineTextBox() const { return _box && _box->isInlineTextBox(); }
181  bool isLineBreak() const
182  {
183  return _box && _box->object() && _box->object()->isBR();
184  }
188  bool isOutside() const { return _outside; }
195  bool isOutsideEnd() const { return outside_end; }
197  RenderObject *object() const { return _box ? _box->object() : cb; }
198 
201  long minOffset() const { return _box && !isLineBreak() ? _box->minOffset() : 0; }
204  long maxOffset() const { return _box && !isLineBreak() ? _box->maxOffset() : 0; }
205 
206 #if DEBUG_CARETMODE > 0
207  void dump(QTextStream &ts, const QString &ind) const;
208 #endif
209 
210  friend class CaretBoxLine;
211 };
212 
213 typedef MassDeleter<CaretBox> CaretBoxDeleter;
214 
221 class CaretBoxIterator {
222 protected:
223  CaretBoxLine *cbl; // associated caret box line
224  int index; // current index
225 
226 public:
227  // Let standard constructor/copy constructor/destructor/assignment operator
228  // be defined by the compiler. They do exactly what we want.
229  CaretBoxIterator()
230  : cbl( 0 ), index( 0 )
231  {
232  }
233 
234  bool operator ==(const CaretBoxIterator &it) const
235  {
236  return cbl == it.cbl && index == it.index;
237  }
238 
239  bool operator !=(const CaretBoxIterator &it) const
240  {
241  return !operator ==(it);
242  }
243 
247  CaretBox *data() const;
251  CaretBox *operator *() const { return data(); }
252 
255  CaretBoxIterator &operator ++() { index++; return *this; }
258  CaretBoxIterator &operator --() { index--; return *this; }
259 
260  friend class CaretBoxLine;
261  friend class EditableCaretBoxIterator;
262 };
263 
290 class CaretBoxLine {
291 protected:
292  CaretBoxDeleter caret_boxes;
293  // base flow box which caret boxes have been constructed for
294  InlineFlowBox *basefb;
295 
296  CaretBoxLine() : caret_boxes(8), basefb(0) {}
297  CaretBoxLine(InlineFlowBox *basefb) : caret_boxes(8), basefb(basefb) {}
298 public:
299 #if DEBUG_CARETMODE > 3
300  ~CaretBoxLine() { kDebug(6200) << "called"; }
301 #endif
302 
303  CaretBoxIterator begin()
304  {
305  CaretBoxIterator it;
306  it.cbl = this;
307  it.index = 0;
308  return it;
309  }
310  CaretBoxIterator end()
311  {
312  CaretBoxIterator it;
313  it.cbl = this;
314  it.index = caret_boxes.size();
315  return it;
316  }
317  CaretBoxIterator preBegin()
318  {
319  CaretBoxIterator it;
320  it.cbl = this;
321  it.index = -1;
322  return it;
323  }
324  CaretBoxIterator preEnd()
325  {
326  CaretBoxIterator it;
327  it.cbl = this;
328  it.index = caret_boxes.size() - 1;
329  return it;
330  }
331 
338  InlineFlowBox *baseFlowBox() const { return basefb; }
339 
341  RenderBlock *containingBlock() const { return caret_boxes[0]->containingBlock(); }
343  RenderBox *enclosingObject() const { return caret_boxes[0]->enclosingObject(); }
344 
349  bool isOutside() const
350  {
351  const CaretBox *cbox = caret_boxes[0];
352  return !cbox->isInline() && cbox->isOutside();
353  }
354 
359  bool isOutsideEnd() const { return caret_boxes[0]->isOutsideEnd(); }
360 
373  static CaretBoxLine *constructCaretBoxLine(MassDeleter<CaretBoxLine> *deleter,
374  InlineFlowBox *baseFlowBox, InlineBox *seekBox, bool seekOutside,
375  bool seekOutsideEnd, CaretBoxIterator &iter,
376  RenderObject *seekObject = 0) /*KDE_NO_EXPORT*/;
377 
386  static CaretBoxLine *constructCaretBoxLine(MassDeleter<CaretBoxLine> *deleter,
387  RenderBox *cb, bool outside, bool outsideEnd, CaretBoxIterator &iter) /*KDE_NO_EXPORT*/;
388 
389 #if DEBUG_CARETMODE > 0
390  void dump(QTextStream &ts, const QString &ind) const;
391  QString information() const
392  {
393  QString result;
394  QTextStream ts(&result, QIODevice::WriteOnly);
395  dump(ts, QString());
396  return result;
397  }
398 #endif
399 
400 protected:
402  struct SeekBoxParams {
403  InlineBox *box;
404  bool outside;
405  bool outsideEnd;
406  bool found;
407  RenderObject *r; // if box is 0, seek for equal render objects instead
408  CaretBoxIterator &it;
409 
410  SeekBoxParams(InlineBox *box, bool outside, bool outsideEnd, RenderObject *obj, CaretBoxIterator &it)
411  : box(box), outside(outside), outsideEnd(outsideEnd), found(false), r(obj), it(it)
412  {}
413 
415  bool equalsBox(const InlineBox *box, bool outside, bool outsideEnd) const
416  {
417  return (this->box && this->box == box
418  || this->r == box->object())
419  && this->outside == outside
420  && (!this->outside || this->outsideEnd == outsideEnd);
421  }
423  bool operator ==(const CaretBox *cbox) const
424  {
425  return equalsBox(cbox->inlineBox(), cbox->isOutside(), cbox->isOutsideEnd());
426  }
432  bool check(const CaretBoxIterator &chit)
433  {
434  if (*this == *chit) {
435  Q_ASSERT(!found);
436  found = true;
437  it = chit;
438  }
439  return found;
440  }
441  };
442 
448  void addConvertedInlineBox(InlineBox *, SeekBoxParams &) /*KDE_NO_EXPORT*/;
449 
456  void addCreatedInlineBoxEdge(InlineBox *box, const QFontMetrics &fm,
457  bool left, bool rtl) /*KDE_NO_EXPORT*/;
464  void addCreatedFlowBoxEdge(InlineFlowBox *flowBox, const QFontMetrics &fm,
465  bool left, bool rtl) /*KDE_NO_EXPORT*/;
470  void addCreatedFlowBoxInside(InlineFlowBox *flowBox, const QFontMetrics &fm) /*KDE_NO_EXPORT*/;
471 
472  friend class CaretBoxIterator;
473 };
474 
475 typedef MassDeleter<CaretBoxLine> CaretBoxLineDeleter;
476 
477 inline CaretBox *CaretBoxIterator::data() const { return cbl->caret_boxes[index]; }
478 
487 class LineIterator
488 {
489 protected:
490  LinearDocument *lines; // associated document
491  CaretBoxLine *cbl; // current caret box line
492 
493  static CaretBoxIterator currentBox; // current inline box
494  static long currentOffset;
495 
496  // Note: cbl == 0 indicates a position beyond the beginning or the
497  // end of a document.
498 
501  LineIterator() {}
502 
509  LineIterator(LinearDocument *l, DOM::NodeImpl *node, long offset);
510 
511 public:
516  CaretBoxLine *operator *() const { return cbl; }
517 
520  LinearDocument *linearDocument() const { return lines; }
521 
526  LineIterator &operator ++() { advance(false); return *this; }
527 
532  LineIterator &operator --() { advance(true); return *this; }
533 
537  bool operator ==(const LineIterator &it) const
538  {
539  return lines == it.lines && cbl == it.cbl;
540  }
541 
544  bool operator !=(const LineIterator &it) const
545  {
546  return !operator ==(it);
547  }
548 
554  bool isOutsideEnd() { return cbl->isOutsideEnd(); }
555 
559  bool isOutside() const { return cbl->isOutside(); }
560 
564  void advance(bool toBegin);
565 
576  static CaretBoxIterator &currentCaretBox() { return currentBox; }
577 
586  static long currentModifiedOffset() { return currentOffset; }
587 
588 protected:
591  void nextBlock();
594  void prevBlock();
595 
596  friend class CaretBoxIterator;
597  friend class EditableLineIterator;
598  friend class EditableCaretBoxIterator;
599  friend class EditableCharacterIterator;
600  friend class LinearDocument;
601 };
602 
622 class LinearDocument {
623 public:
624  typedef LineIterator Iterator;
625 
640  LinearDocument(KHTMLPart *part, DOM::NodeImpl *node, long offset,
641  CaretAdvancePolicy advancePolicy, DOM::ElementImpl *baseElem);
642 
643  virtual ~LinearDocument();
644 
653  bool isValid() const // FIXME: not yet impl'd
654  {
655  return true;
656  }
657 
665  int count() const;
666 
671  Iterator current();
672 
676  const Iterator &end() const { return _end; }
677 
681  Iterator preEnd();
682 
686  Iterator begin();
687 
692  const Iterator &preBegin() const { return _preBegin; }
693 
697  CaretAdvancePolicy advancePolicy() const { return advPol; }
698 
706  RenderObject *baseObject() const { return base; }
707 
708 protected:
709  void initPreBeginIterator();
710  void initEndIterator();
711 
712 protected:
713  CaretBoxLineDeleter cblDeleter; // mass deleter for caret box lines
714  DOM::NodeImpl *node;
715  long offset;
716 
717  Iterator _preBegin;
718  Iterator _end;
719 
720  KHTMLPart *m_part;
721  CaretAdvancePolicy advPol;
722  RenderObject *base;
723 
724  friend class LineIterator;
725  friend class EditableLineIterator;
726  friend class ErgonomicEditableLineIterator;
727  friend class CaretBoxIterator;
728  friend class EditableCaretBoxIterator;
729  friend class EditableCharacterIterator;
730 };
731 
742 class EditableCaretBoxIterator : public CaretBoxIterator {
743  KHTMLPart *m_part;
744  bool adjacent;
745  CaretAdvancePolicy advpol; // caret advance policy
746 
747 public:
751  EditableCaretBoxIterator(LineIterator &lit, bool fromEnd = false,
752  CaretBoxIterator *it = 0)
753  : CaretBoxIterator(it ? *it : (fromEnd ? (*lit)->end() : (*lit)->preBegin())),
754  m_part(lit.lines->m_part), adjacent(false),
755  advpol(lit.lines->advancePolicy())
756  {
757  if (!it) {
758  if (fromEnd) --*this; else ++*this;
759  }
760  }
761 
764  EditableCaretBoxIterator() {}
765 
769  bool isAdjacent() const { return adjacent; }
770 
773  EditableCaretBoxIterator &operator ++() { advance(false); return *this; }
774 
777  EditableCaretBoxIterator &operator --() { advance(true); return *this; }
778 
782  void advance(bool toBegin);
783 
784 protected:
790  bool isEditable(const CaretBoxIterator &boxit, bool fromEnd);
791 };
792 
807 class EditableLineIterator : public LineIterator {
808 public:
817  EditableLineIterator(const LineIterator &it, bool fromEnd = false)
818  : LineIterator(it)
819  {
820  if (!cbl) return;
821  if (!isEditable(*this)) advance(fromEnd);
822  }
823 
828  EditableLineIterator() {}
829 
834  EditableLineIterator &operator ++() { advance(false); return *this; }
835 
840  EditableLineIterator &operator --() { advance(true); return *this; }
841 
845  void advance(bool toBegin);
846 
847 protected:
853  bool isEditable(LineIterator &it)
854  {
855  EditableCaretBoxIterator fbit = it;
856  return fbit != (*it)->end();
857  }
858 
859 };
860 
868 class TableRowIterator {
869 protected:
870  TableSectionIterator sec; // current section
871  int index; // index of row within section
872 public:
879  TableRowIterator(RenderTable *table, bool fromEnd = false,
880  RenderTableSection::RowStruct *row = 0);
881 
886  TableRowIterator(RenderTableSection *section, int index)
887  : sec(section), index(index)
888  {}
889 
893  TableRowIterator() {}
894 
898  RenderTableSection::RowStruct *operator *()
899  {
900  if (!*sec) return 0;
901  return &(*sec)->grid[index];
902  }
903 
906  TableRowIterator &operator ++();
907 
910  TableRowIterator &operator --();
911 
912 protected:
913 };
914 
929 class ErgonomicEditableLineIterator : public EditableLineIterator {
930 protected:
931  int xCoor; // x-coordinate to determine cell position
932 public:
937  ErgonomicEditableLineIterator(const LineIterator &it, int x)
938  : EditableLineIterator(it), xCoor(x) {}
939 
943  ErgonomicEditableLineIterator() {}
944 
949  ErgonomicEditableLineIterator &operator ++();
950 
955  ErgonomicEditableLineIterator &operator --();
956 
957 protected:
965  void determineTopologicalElement(RenderTableCell *oldCell,
966  RenderObject *newObject, bool toBegin);
967 
973  void calcAndStoreNewLine(RenderBlock *newBlock, bool toBegin);
974 
975 };
976 
984 class EditableCharacterIterator {
985 protected:
986  EditableLineIterator _it;
987  EditableCaretBoxIterator ebit;
988  long _offset; // offset within current caret box.
989  int _char;
990  bool _end:1; // true when end of document has been reached
991 
992 public:
993 
999  EditableCharacterIterator() {}
1000 
1005  EditableCharacterIterator(LinearDocument *ld)
1006  : _it(ld->current()),
1007  ebit(_it, false, &_it.currentCaretBox()),
1008  _offset(_it.currentModifiedOffset()), _char(-1), _end(false)
1009  {
1010  // ### temporary fix for illegal nodes
1011  if (_it == ld->end()) { _end = true; return; }
1012  initFirstChar();
1013  }
1014 
1018  int chr() const { return _char; }
1019 
1023  QChar operator *() const { return QChar(_char >= 0 ? _char : ' '); }
1024 
1027  bool isEnd() const { return _end; }
1030  long offset() const { return _offset; }
1033  RenderObject *renderer() const { return (*ebit)->object(); }
1038  CaretBox *caretBox() const { return *ebit; }
1045  InlineBox *inlineBox() const { return (*ebit)->inlineBox(); }
1049 // bool boxIsOutside() const { return _it.isOutside(); }
1050 
1053  EditableCharacterIterator &operator ++();
1054 
1057  EditableCharacterIterator &operator --();
1058 
1059 protected:
1063  void initFirstChar();
1066  void peekNext()
1067  {
1068  EditableCaretBoxIterator copy = ebit;
1069  ++copy;
1070  if (copy == (*_it)->end()) { _char = -1; return; }
1071 
1072  CaretBox *box = *copy;
1073  InlineBox *b = box->inlineBox();
1074  if (b && !box->isOutside() && b->isInlineTextBox())
1075  _char = static_cast<RenderText *>(b->object())->str->s[b->minOffset()].unicode();
1076  else
1077  _char = -1;
1078  }
1081  void peekPrev()
1082  {
1083  --ebit;
1084  }
1085 
1086 };
1087 
1088 
1089 }/*namespace khtml*/
1090 
1091 
1092 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jun 1 2013 22:07:27 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.10.4 API Reference

Skip menu "kdelibs-4.10.4 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal