khtml_caret_p.h

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C头文件 代码 · 共 1,110 行 · 第 1/3 页

H
1,110
字号
/* This file is part of the KDE project * * Copyright (C) 2003-2004 Leo Savernik <l.savernik@aon.at> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#ifndef KHTML_CARET_P_H#define KHTML_CARET_P_H#include "rendering/render_table.h"#include <qvaluevector.h>#define DEBUG_CARETMODE 0class QFontMetrics;namespace DOM {  class NodeImpl;  class ElementImpl;}namespace khtml {/** caret advance policy. * * Used to determine which elements are taken into account when the caret is * advanced. Later policies pose refinements of all former * policies. * @param LeafsOnly advance from leave render object to leaf render object *	(It will allow outside flow positions if a flow wouldn't be reachable *	otherwise). * @param IndicatedFlows place caret also at the beginning/end of flows *	that have at least one visible border at any side. *	(It will allow not indicated flow positions if a flow wouldn't *	be reachable otherwise). * @param VisibleFlows place caret also at the beginning/end of any flow *	that has a renderer. */enum CaretAdvancePolicy {    LeafsOnly, IndicatedFlows, VisibleFlows};/** contextual information about the caret which is related to the view. * An object of this class is only instantiated when it is needed. */struct CaretViewContext {    int freqTimerId;		// caret blink frequency timer id    int x, y;			// caret position in viewport coordinates    				// (y specifies the top, not the baseline)    int width;			// width of caret in pixels    int height;			// height of caret in pixels    bool visible;		// true if currently visible.    bool displayed;		// true if caret is to be displayed at all.    bool caretMoved;		// set to true once caret has been moved in page    				// how to display the caret when view is not focused    KHTMLPart::CaretDisplayPolicy displayNonFocused;    /** For natural traversal of lines, the original x position is saved, and     * the actual x is set to the first character whose x position is     * greater than origX.     *     * origX is reset to x whenever the caret is moved horizontally or placed     * by the mouse.     */    int origX;    bool keyReleasePending;	// true if keypress under caret mode awaits    				// corresponding release event    CaretViewContext() : freqTimerId(-1), x(0), y(0), width(1), height(16),    	visible(true), displayed(false), caretMoved(false),	displayNonFocused(KHTMLPart::CaretInvisible), origX(0),	keyReleasePending(false)    {}};/** contextual information about the editing state. * An object of this class is only instantiated when it is needed. */struct EditorContext {    bool override;		// true if typed characters should override    				// the existing ones.    EditorContext() : override(false)    {}};class LinearDocument;/** * Stores objects of a certain type, and calls delete on each of them * when this data structure is destroyed. * * As this structure merely consists of a vector of pointers, all objects * allocated can be traversed as seen fit. * * @author Leo Savernik * @since 3.3 * @internal */template<class T> class MassDeleter : public QValueVector<T *> {public:  MassDeleter(size_t reserved = 1) { this->reserve(reserved); }  ~MassDeleter()  {    typename QValueVector<T *>::Iterator nd = this->end();    for (typename QValueVector<T *>::Iterator it = this->begin(); it != nd; ++it)      delete *it;  }};class CaretBoxLine;/** * Represents a rectangular box within which the caret is located. * * The caret box serves as a wrapper for inline boxes of all kind. It either * wraps an InlineBox, InlineTextBox, or InlineFlowBox, or if no such boxes * exist for a certain context, it contains the relevant information directly. * * This class will be constructed whenever a caret position has to be described. * @since 3.3 * @author Leo Savernik * @internal */class CaretBox {protected:  InlineBox *_box;		// associated inline box if available.  short _w;			// width of box in pixels  int _h;			// height of box in pixels  int _x;			// x coordinate relative to containing block  int _y;			// y coordinate relative to containing block  RenderBox *cb;		// containing block  bool _outside:1;		// true when representing the outside of the element  bool outside_end:1;		// at ending outside of element rather than at beginning  // 29 bits unusedpublic:  /** empty constructor for later assignment */  CaretBox() {}  /** initializes the caret box from the given inline box */  CaretBox(InlineBox *ibox, bool outside, bool outsideEnd) : _box(ibox),  	_w((short)ibox->width()), _h(ibox->height()), _x(ibox->xPos()),        _y(ibox->yPos()), cb(0), _outside(outside), outside_end(outsideEnd)  {    RenderObject *r = ibox->object();    if (r) cb = r->containingBlock();  }  /** initializes the caret box from scratch */  CaretBox(int x, int y, int w, int h, RenderBox *cb, bool outside, bool outsideEnd) :         _box(0), _w((short)w), _h(h), _x(x), _y(y), cb(cb), _outside(outside),         outside_end(outsideEnd)  {}  int width() const { return _w; }  int height() const { return _h; }  int xPos() const { return _x; }  int yPos() const { return _y; }  RenderBox *enclosingObject() const { return cb; }  InlineBox *inlineBox() const { return _box; }  /** returns the containing block of this caret box. If the caret box   * resembles a block itself, its containing block is returned.   */  RenderBlock *containingBlock() const { return _box ? static_cast<RenderBlock *>(cb) : cb->containingBlock(); }  /** returns the replaced render object if this caret box represents one,   * 0 otherwise.   */  /** returns true if this caret box represents an inline element, or text box,   * otherwise false.   */  bool isInline() const { return _box; }  /** returns true if this caret box represents an inline text box.   */  bool isInlineTextBox() const { return _box && _box->isInlineTextBox(); }  /** returns true if this caret box represents a line break   */  bool isLineBreak() const  {    return _box && _box->object() && _box->object()->isBR();  }  /** returns true when this caret box represents an ouside position of an   * element.   */  bool isOutside() const { return _outside; }  /** returns the position at which the outside is targeted at.   *   * This method's return value is meaningless if isOutside() is not true.   * @return true if the outside end is meant, false if the outside beginning   *	is meant.   */  bool isOutsideEnd() const { return outside_end; }  /** returns the associated render object. */  RenderObject *object() const { return _box ? _box->object() : cb; }  /** returns the minimum offset for this caret box.   */  long minOffset() const { return _box && !isLineBreak() ? _box->minOffset() : 0; }  /** returns the maximum offset for this caret box.   */  long maxOffset() const { return _box && !isLineBreak() ? _box->maxOffset() : 0; }#if DEBUG_CARETMODE > 0  void dump(QTextStream &ts, const QString &ind) const;#endif  friend class CaretBoxLine;};typedef MassDeleter<CaretBox> CaretBoxDeleter;/** * Iterates over the elements of a caret box line. * * @author Leo Savernik * @internal * @since 3.3 */class CaretBoxIterator {protected:  CaretBoxLine *cbl;		// associated caret box line  int index;			// current indexpublic:  // Let standard constructor/copy constructor/destructor/assignment operator  // be defined by the compiler. They do exactly what we want.  bool operator ==(const CaretBoxIterator &it) const  {    return cbl == it.cbl && index == it.index;  }  bool operator !=(const CaretBoxIterator &it) const  {    return !operator ==(it);  }  /** returns the current caret box.   * @return current caret box   */  CaretBox *data() const;  /** shortcut for \c data   * @return current caret box   */  CaretBox *operator *() const { return data(); }  /** increments the iterator to point to the next caret box.   */  CaretBoxIterator &operator ++() { index++; return *this; }  /** decrements the iterator to point to the previous caret box.   */  CaretBoxIterator &operator --() { index--; return *this; }  friend class CaretBoxLine;  friend class EditableCaretBoxIterator;};/** * Resembles a line consisting of caret boxes. * * To the contrary of InlineFlowBoxes which are nested as needed to map the * DOM to the rendered representation, it is sufficient for caret navigation * to provide a linear list of unnested caret boxes. * * \code * Example: The document fragment <p>a <i><b>c</b> f</i> g</p> will be * represented by three caret box lines which each one consists of caret boxes * as follows: * CaretBoxLine 1: *   CaretBox(cb=<p>, _box=0, _outside=true, outside_end=false) * CaretBoxLine 2: *   CaretBox(cb=<p>, _box=InlineTextBox("a "), _outside=false) *   CaretBox(cb=<p>, _box=InlineFlowBox(<i>), _outside=true, outside_end=false) *   CaretBox(cb=<p>, _box=InlineFlowBox(<b>), _outside=true, outside_end=false) *   CaretBox(cb=<p>, _box=InlineTextBox("c"), _outside=false) *   CaretBox(cb=<p>, _box=InlineFlowBox(<b>), _outside=true, outside_end=true) *   CaretBox(cb=<p>, _box=InlineTextBox(" f"), _outside=false) *   CaretBox(cb=<p>, _box=InlineFlowBox(<i>), _outside=true, outside_end=true) *   CaretBox(cb=<p>, _box=InlineTextBox(" g"), _outside=true, outside_end=true) * CaretBoxLine 3: *   CaretBox(cb=<p>, _box=0, _outside=true, outside_end=true) * \endcode */class CaretBoxLine {protected:  CaretBoxDeleter caret_boxes;  // base flow box which caret boxes have been constructed for  InlineFlowBox *basefb;  CaretBoxLine() : caret_boxes(8), basefb(0) {}  CaretBoxLine(InlineFlowBox *basefb) : caret_boxes(8), basefb(basefb) {}public:#if DEBUG_CARETMODE > 3  ~CaretBoxLine() { kdDebug(6200) << k_funcinfo << "called" << endl; }#endif  CaretBoxIterator begin()  {    CaretBoxIterator it;    it.cbl = this;    it.index = 0;    return it;  }  CaretBoxIterator end()  {    CaretBoxIterator it;    it.cbl = this;    it.index = caret_boxes.size();    return it;  }  CaretBoxIterator preBegin()  {    CaretBoxIterator it;    it.cbl = this;    it.index = -1;    return it;  }  CaretBoxIterator preEnd()  {    CaretBoxIterator it;    it.cbl = this;    it.index = caret_boxes.size() - 1;    return it;  }  /** returns the base inline flow box which the caret boxes of this   * caret box line have been constructed from.   *   * This is generally a root line box, but may be an inline flow box when the   * base is restricted to an inline element.   */  InlineFlowBox *baseFlowBox() const { return basefb; }  /** returns the containing block */  RenderBlock *containingBlock() const { return caret_boxes[0]->containingBlock(); }  /** returns the enclosing object */  RenderBox *enclosingObject() const { return caret_boxes[0]->enclosingObject(); }  /** returns whether this caret box line is outside.   * @return true if this caret box represents an outside position of this   *	line box' containing block, false otherwise.   */  bool isOutside() const  {    const CaretBox *cbox = caret_boxes[0];    return !cbox->isInline() && cbox->isOutside();  }  /** returns whether this caret box line is at the outside end.   *   * The result cannot be relied upon unless isOutside() returns true.   */  bool isOutsideEnd() const { return caret_boxes[0]->isOutsideEnd(); }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?