File indexing completed on 2024-05-05 16:11:41
0001 /* 0002 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 1. Redistributions of source code must retain the above copyright 0008 * notice, this list of conditions and the following disclaimer. 0009 * 2. Redistributions in binary form must reproduce the above copyright 0010 * notice, this list of conditions and the following disclaimer in the 0011 * documentation and/or other materials provided with the distribution. 0012 * 0013 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 0014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0015 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 0016 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 0017 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 0018 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 0019 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 0020 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 0021 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0023 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 0026 #ifndef __dom_selection_h__ 0027 #define __dom_selection_h__ 0028 0029 #include "xml/dom_position.h" 0030 0031 class KHTMLPart; 0032 class KHTMLView; 0033 class QPainter; 0034 class QRect; 0035 0036 namespace khtml 0037 { 0038 class RenderObject; 0039 } 0040 0041 namespace DOM 0042 { 0043 0044 class NodeImpl; 0045 class Position; 0046 class Range; 0047 0048 class Selection 0049 { 0050 public: 0051 enum EState { NONE, CARET, RANGE }; 0052 enum EAlter { MOVE, EXTEND }; 0053 enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT }; 0054 enum ETextGranularity { CHARACTER, WORD, LINE, PARAGRAPH }; 0055 0056 // These match the AppKit values for these concepts. 0057 // From NSTextView.h: 0058 // NSSelectionAffinityUpstream = 0 0059 // NSSelectionAffinityDownstream = 1 0060 enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 }; 0061 0062 Selection(); 0063 Selection(const Range &); 0064 Selection(const Position &); 0065 Selection(const Position &, const Position &); 0066 Selection(const Selection &); 0067 0068 EState state() const 0069 { 0070 return m_state; 0071 } 0072 EAffinity affinity() const 0073 { 0074 return m_affinity; 0075 } 0076 void setAffinity(EAffinity); 0077 0078 void moveTo(const Range &); 0079 void moveTo(const Selection &); 0080 void moveTo(const Position &); 0081 void moveTo(const Position &, const Position &); 0082 bool modify(EAlter, EDirection, ETextGranularity); 0083 bool expandUsingGranularity(ETextGranularity); 0084 void clear(); 0085 void collapse(); 0086 0087 bool moveToRenderedContent(); 0088 0089 void setBase(const Position &pos); 0090 void setExtent(const Position &pos); 0091 void setBaseAndExtent(const Position &base, const Position &extent); 0092 void setStart(const Position &pos); 0093 void setEnd(const Position &pos); 0094 void setStartAndEnd(const Position &start, const Position &end); 0095 0096 Position base() const 0097 { 0098 return m_base; 0099 } 0100 Position extent() const 0101 { 0102 return m_extent; 0103 } 0104 Position start() const 0105 { 0106 return m_start; 0107 } 0108 Position end() const 0109 { 0110 return m_end; 0111 } 0112 Position caretPos() const 0113 { 0114 return m_baseIsStart ? m_end : m_start; 0115 } 0116 Position nonCaretPos() const 0117 { 0118 return m_baseIsStart ? m_start : m_end; 0119 } 0120 0121 QRect getRepaintRect() const; 0122 void setNeedsLayout(bool flag = true); 0123 void clearModifyBias() 0124 { 0125 m_modifyBiasSet = false; 0126 } 0127 0128 bool isEmpty() const 0129 { 0130 return state() == NONE; 0131 } 0132 bool notEmpty() const 0133 { 0134 return !isEmpty(); 0135 } 0136 Range toRange() const; 0137 bool isCollapsed() const 0138 { 0139 return m_state == CARET; 0140 } 0141 0142 void getRange(NodeImpl *&start, long &so, NodeImpl *&end, long &eo) const; 0143 0144 void debugPosition() const; 0145 void debugRenderer(khtml::RenderObject *r, bool selected) const; 0146 0147 Selection &operator=(const Selection &o); 0148 Selection &operator=(const Range &r) 0149 { 0150 moveTo(r); 0151 return *this; 0152 } 0153 Selection &operator=(const Position &r) 0154 { 0155 moveTo(r); 0156 return *this; 0157 } 0158 0159 friend bool operator==(const Selection &a, const Selection &b); 0160 friend bool operator!=(const Selection &a, const Selection &b); 0161 0162 friend class ::KHTMLPart; 0163 friend class ::KHTMLView; 0164 0165 private: 0166 enum EPositionType { START, END, BASE, EXTENT, CARETPOS }; 0167 0168 void init(); 0169 void validate(ETextGranularity granularity = CHARACTER); 0170 void assignBase(const Position &pos) 0171 { 0172 m_base = pos; 0173 } 0174 void assignExtent(const Position &pos) 0175 { 0176 m_extent = pos; 0177 } 0178 void assignBaseAndExtent(const Position &base, const Position &extent) 0179 { 0180 m_base = base; 0181 m_extent = extent; 0182 } 0183 void assignStart(const Position &pos) 0184 { 0185 m_start = pos; 0186 } 0187 void assignEnd(const Position &pos) 0188 { 0189 m_end = pos; 0190 } 0191 void assignStartAndEnd(const Position &start, const Position &end) 0192 { 0193 m_start = start; 0194 m_end = end; 0195 } 0196 0197 void layoutCaret(); 0198 void needsCaretRepaint(); 0199 void paintCaret(QPainter *p, const QRect &rect); 0200 0201 bool nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2) const; 0202 int xPosForVerticalArrowNavigation(EPositionType, bool recalc = false) const; 0203 0204 Position m_base; // base position for the selection 0205 Position m_extent; // extent position for the selection 0206 Position m_start; // start position for the selection 0207 Position m_end; // end position for the selection 0208 0209 EState m_state; // the state of the selection 0210 EAffinity m_affinity; // the upstream/downstream affinity of the selection 0211 0212 int m_caretX; // caret coordinates and size 0213 int m_caretY; 0214 int m_caretSize; 0215 0216 bool m_baseIsStart : 1; // true if base node is before the extent node 0217 bool m_needsCaretLayout : 1; // true if the caret position needs to be calculated 0218 bool m_modifyBiasSet : 1; // true if the selection has been horizontally 0219 // modified with EAlter::EXTEND 0220 bool m_visible : 1; // true if caret should be painted 0221 }; 0222 0223 inline bool operator==(const Selection &a, const Selection &b) 0224 { 0225 return a.start() == b.start() && a.end() == b.end(); 0226 } 0227 0228 inline bool operator!=(const Selection &a, const Selection &b) 0229 { 0230 return !(a == b); 0231 } 0232 0233 QDebug operator<<(QDebug stream, const Selection &selection); 0234 0235 } // namespace DOM 0236 0237 #endif // __dom_selection_h__