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 + -
显示快捷键?