#ifndef KHTML_EDITING_SELECTION_H
#define KHTML_EDITING_SELECTION_H
#include <qrect.h>
#include "xml/dom_position.h"
#include "text_granularity.h"
class KHTMLPart;
class QPainter;
namespace khtml {
class RenderObject;
class VisiblePosition;
class Selection
{
public:
enum EState { NONE, CARET, RANGE };
enum EAlter { MOVE, EXTEND };
enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
#define SEL_DEFAULT_AFFINITY DOWNSTREAM
#define SEL_PREFER_UPSTREAM_AFFINITY DOWNSTREAM
typedef DOM::Range Range;
typedef DOM::Position Position;
Selection();
Selection(const Range &, EAffinity baseAffinity, EAffinity extentAffinity);
Selection(const VisiblePosition &);
Selection(const VisiblePosition &, const VisiblePosition &);
Selection(const Position &, EAffinity affinity);
Selection(const Position &, EAffinity, const Position &, EAffinity);
Selection(const Selection &);
Selection &operator=(const Selection &o);
Selection &operator=(const VisiblePosition &r) { moveTo(r); return *this; }
void moveTo(const Range &, EAffinity baseAffinity, EAffinity extentAffinity);
void moveTo(const VisiblePosition &);
void moveTo(const VisiblePosition &, const VisiblePosition &);
void moveTo(const Position &, EAffinity);
void moveTo(const Position &, EAffinity, const Position &, EAffinity);
void moveTo(const Selection &);
EState state() const { return m_state; }
EAffinity startAffinity() const { return m_affinity; }
EAffinity endAffinity() const { return m_affinity; }
EAffinity baseAffinity() const { return m_affinity; }
EAffinity extentAffinity() const { return m_affinity; }
bool modify(EAlter, EDirection, ETextGranularity);
bool modify(EAlter, int verticalDistance);
bool expandUsingGranularity(ETextGranularity);
void clear();
void setBase(const VisiblePosition &);
void setExtent(const VisiblePosition &);
void setBaseAndExtent(const VisiblePosition &base, const VisiblePosition &extent);
void setBase(const Position &pos, EAffinity affinity);
void setExtent(const Position &pos, EAffinity affinity);
void setBaseAndExtent(const Position &base, EAffinity baseAffinity, const Position &extent, EAffinity extentAffinity);
Position base() const { return m_base; }
Position extent() const { return m_extent; }
Position start() const { return m_start; }
Position end() const { return m_end; }
QRect caretRect() const;
QRect expectedVisibleRect() const;
void setNeedsLayout(bool flag = true);
void clearModifyBias() { m_modifyBiasSet = false; }
void setModifyBias(EAlter, EDirection);
bool isNone() const { return state() == NONE; }
bool isCaret() const { return state() == CARET; }
bool isRange() const { return state() == RANGE; }
bool isCaretOrRange() const { return state() != NONE; }
Range toRange() const;
void debugPosition() const;
void debugRenderer(khtml::RenderObject *r, bool selected) const;
friend class KHTMLPart;
#ifndef NDEBUG
void formatForDebugger(char *buffer, unsigned length) const;
#endif
private:
enum EPositionType { START, END, BASE, EXTENT };
void init(EAffinity affinity);
void validate(ETextGranularity granularity = CHARACTER);
VisiblePosition modifyExtendingRightForward(ETextGranularity);
VisiblePosition modifyMovingRightForward(ETextGranularity);
VisiblePosition modifyExtendingLeftBackward(ETextGranularity);
VisiblePosition modifyMovingLeftBackward(ETextGranularity);
void layout();
void needsCaretRepaint();
void paintCaret(QPainter *p, const QRect &rect);
QRect caretRepaintRect() const;
int xPosForVerticalArrowNavigation(EPositionType, bool recalc = false) const;
Position m_base; Position m_extent; Position m_start; Position m_end;
EState m_state; EAffinity m_affinity;
QRect m_caretRect; QRect m_expectedVisibleRect;
bool m_baseIsStart : 1; bool m_needsLayout : 1; bool m_modifyBiasSet : 1; };
inline bool operator==(const Selection &a, const Selection &b)
{
return a.start() == b.start() && a.end() == b.end() && a.startAffinity() == b.startAffinity();
}
inline bool operator!=(const Selection &a, const Selection &b)
{
return !(a == b);
}
}
#endif // KHTML_EDITING_SELECTION_H