Commit 3f425be4 authored by rjw's avatar rjw

Fixed 3127310 and 3127920.

        Implemented findWordBoundary.  We now correctly detect word boundaries.
        This function makes use of carbon unicode utilities.

        With help from hyatt, made selection correctly account for render
        continuations.  This fixes many of the 'unable to select' issues.

        Reviewed by trey and hyatt.

        * khtml/khtml_events.cpp:
        (khtml::MouseEvent::offset):
        * khtml/khtml_part.cpp:
        (findWordBoundary):
        (KHTMLPart::khtmlMousePressEvent):
        (KHTMLPart::khtmlMouseMoveEvent):
        * khtml/rendering/render_object.cpp:
        (RenderObject::checkSelectionPoint):
        * khtml/rendering/render_object.h:
        * khtml/rendering/render_text.cpp:
        (RenderText::checkSelectionPoint):
        * khtml/rendering/render_text.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3050 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3054327e
2002-12-13 Richard Williamson <rjw@apple.com>
Fixed 3127310 and 3127920.
Implemented findWordBoundary. We now correctly detect word boundaries.
This function makes use of carbon unicode utilities.
With help from hyatt, made selection correctly account for render
continuations. This fixes many of the 'unable to select' issues.
Reviewed by trey and hyatt.
* khtml/khtml_events.cpp:
(khtml::MouseEvent::offset):
* khtml/khtml_part.cpp:
(findWordBoundary):
(KHTMLPart::khtmlMousePressEvent):
(KHTMLPart::khtmlMouseMoveEvent):
* khtml/rendering/render_object.cpp:
(RenderObject::checkSelectionPoint):
* khtml/rendering/render_object.h:
* khtml/rendering/render_text.cpp:
(RenderText::checkSelectionPoint):
* khtml/rendering/render_text.h:
2002-12-13 Maciej Stachowiak <mjs@apple.com>
Reviewed by Don.
......
2002-12-13 Richard Williamson <rjw@apple.com>
Fixed 3127310 and 3127920.
Implemented findWordBoundary. We now correctly detect word boundaries.
This function makes use of carbon unicode utilities.
With help from hyatt, made selection correctly account for render
continuations. This fixes many of the 'unable to select' issues.
Reviewed by trey and hyatt.
* khtml/khtml_events.cpp:
(khtml::MouseEvent::offset):
* khtml/khtml_part.cpp:
(findWordBoundary):
(KHTMLPart::khtmlMousePressEvent):
(KHTMLPart::khtmlMouseMoveEvent):
* khtml/rendering/render_object.cpp:
(RenderObject::checkSelectionPoint):
* khtml/rendering/render_object.h:
* khtml/rendering/render_text.cpp:
(RenderText::checkSelectionPoint):
* khtml/rendering/render_text.h:
2002-12-13 Maciej Stachowiak <mjs@apple.com>
Reviewed by Don.
......
......@@ -51,7 +51,7 @@ long khtml::MouseEvent::offset() const
absX = absY = 0;
if (innerNode().handle()->renderer()) {
innerNode().handle()->renderer()->absolutePosition(absX, absY);
innerNode().handle()->renderer()->checkSelectionPoint( x(), y(), absX, absY, tempNode, offset );
innerNode().handle()->renderer()->checkSelectionPoint( this, absX, absY, tempNode, offset );
}
return offset;
}
......
......@@ -91,6 +91,10 @@ using namespace DOM;
#include "khtmlpart_p.h"
#ifdef APPLE_CHANGES
#include <CoreServices/CoreServices.h>
#endif
namespace khtml {
class PartStyleSheetLoader : public CachedObjectClient
{
......@@ -4056,6 +4060,52 @@ static bool startAndEndLineNodesIncludingNode (DOM::NodeImpl *node, int offset,
}
return false;
}
static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end){
OSStatus status, findStatus = 0;
TextBreakLocatorRef breakLocator;
status = UCCreateTextBreakLocator (NULL, 0, kUCTextBreakWordMask, &breakLocator);
if (status == 0){
findStatus = UCFindTextBreak (breakLocator, kUCTextBreakWordMask, NULL, (const UniChar *)chars, (UniCharCount)len, (UniCharArrayOffset)position, (UniCharArrayOffset *)end);
findStatus |= UCFindTextBreak (breakLocator, kUCTextBreakWordMask, kUCTextBreakGoBackwardsMask, (const UniChar *)chars, (UniCharCount)len, (UniCharArrayOffset)position, (UniCharArrayOffset *)start);
UCDisposeTextBreakLocator (&breakLocator);
}
// If carbon fails do a simple space/punctuation boundary check.
if (findStatus){
if (chars[position].isSpace()){
int pos = position;
while (chars[pos].isSpace() && pos >= 0)
pos--;
*start = pos+1;
pos = position;
while (chars[pos].isSpace() && pos < (int)len)
pos++;
*end = pos;
}
else if (chars[position].isPunct()){
int pos = position;
while (chars[pos].isPunct() && pos >= 0)
pos--;
*start = pos+1;
pos = position;
while (chars[pos].isPunct() && pos < (int)len)
pos++;
*end = pos;
}
else {
int pos = position;
while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos >= 0)
pos--;
*start = pos+1;
pos = position;
while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos < (int)len)
pos++;
*end = pos;
}
}
}
#endif
void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
......@@ -4098,7 +4148,7 @@ void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
int startOffset = 0, endOffset = 0;
DOM::NodeImpl* node = 0;
innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
innerNode.handle()->renderer()->checkSelectionPoint( event,
event->absX()-innerNode.handle()->renderer()->xPos(),
event->absY()-innerNode.handle()->renderer()->yPos(),
node, startOffset);
......@@ -4107,27 +4157,9 @@ void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
DOMString t = node->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
if (chars[startOffset] == ' '){
int pos = startOffset;
while (chars[pos].isSpace() && pos >= 0)
pos--;
startOffset = pos+1;
pos = startOffset;
while (chars[pos].isSpace() && pos < (int)len)
pos++;
endOffset = pos;
}
else {
int pos = startOffset;
while (!chars[pos].isSpace() && pos >= 0)
pos--;
startOffset = pos+1;
pos = startOffset;
while (!chars[pos].isSpace() && pos < (int)len)
pos++;
endOffset = pos;
}
findWordBoundary (chars, len, startOffset, &startOffset, &endOffset);
d->m_startBeforeEnd = true;
d->m_selectionStart = node;
d->m_startOffset = startOffset;
......@@ -4164,7 +4196,7 @@ void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
int startOffset = 0;
DOM::NodeImpl* node = 0;
innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
innerNode.handle()->renderer()->checkSelectionPoint( event,
event->absX()-innerNode.handle()->renderer()->xPos(),
event->absY()-innerNode.handle()->renderer()->yPos(),
node, startOffset);
......@@ -4194,7 +4226,8 @@ void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
int offset = 0;
DOM::NodeImpl* node = 0;
innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
innerNode.handle()->renderer()->checkSelectionPoint( event,
event->absX()-innerNode.handle()->renderer()->xPos(),
event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
......@@ -4348,7 +4381,7 @@ void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
// << " nodeAbsX=" << event->nodeAbsX() << " nodeAbsY=" << event->nodeAbsY()
// << endl;
DOM::NodeImpl* node=0;
innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
innerNode.handle()->renderer()->checkSelectionPoint( event,
event->absX()-innerNode.handle()->renderer()->xPos(),
event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
// if (d->m_selectionEnd.handle() && d->m_selectionEnd.handle()->renderer())
......@@ -4378,22 +4411,36 @@ void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
}
#if APPLE_CHANGES
if ( d->m_selectionInitiatedWithDoubleClick){
int wordStartOffset = offset, wordEndOffset = offset;
if (node && (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE)){
DOMString t = node->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
findWordBoundary (chars, len, offset, &wordStartOffset, &wordEndOffset);
}
if (d->m_startBeforeEnd) {
if (node == d->m_initialSelectionStart.handle() && node == d->m_initialSelectionEnd.handle()){
d->m_startOffset = MIN(d->m_initialSelectionStartOffset, offset);
offset = MAX(d->m_initialSelectionEndOffset, offset);
d->m_selectionStart = d->m_initialSelectionStart;
d->m_startOffset = MIN(d->m_initialSelectionStartOffset, wordStartOffset);
wordEndOffset = MAX(d->m_initialSelectionEndOffset, wordEndOffset);
d->m_selectionEnd = node;
d->m_endOffset = wordEndOffset;
}
else {
d->m_selectionStart = d->m_initialSelectionStart;
d->m_startOffset = d->m_initialSelectionStartOffset;
d->m_selectionEnd = node;
d->m_endOffset = wordEndOffset;
}
}
else {
d->m_selectionStart = d->m_initialSelectionEnd;
d->m_startOffset = d->m_initialSelectionEndOffset;
d->m_selectionEnd = node;
d->m_endOffset = wordStartOffset;
}
d->m_selectionEnd = node;
d->m_endOffset = offset;
}
else if (d->m_selectionInitiatedWithTripleClick ){
DOM::Node lineStart, lineEnd;
......
......@@ -967,14 +967,15 @@ void RenderObject::detach(RenderArena* renderArena)
renderArena->free(*sz, (void*)this);
}
FindSelectionResult RenderObject::checkSelectionPoint( int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int & offset )
FindSelectionResult RenderObject::checkSelectionPoint( const khtml::MouseEvent *event, int _tx, int _ty, DOM::NodeImpl*& node, int & offset )
{
int lastOffset=0;
int off = offset;
DOM::NodeImpl* nod = node;
DOM::NodeImpl* lastNode = 0;
for (RenderObject *child = firstChild(); child; child=child->nextSibling()) {
khtml::FindSelectionResult pos = child->checkSelectionPoint(_x, _y, _tx+xPos(), _ty+yPos(), nod, off);
khtml::FindSelectionResult pos = child->checkSelectionPoint(event, _tx+xPos(), _ty+yPos(), nod, off);
//kdDebug(6030) << this << " child->findSelectionNode returned " << pos << endl;
switch(pos) {
case SelectionPointBeforeInLine:
......@@ -1002,6 +1003,17 @@ FindSelectionResult RenderObject::checkSelectionPoint( int _x, int _y, int _tx,
lastOffset = off;
}
}
RenderObject* nextCont = continuation();
while (nextCont && !nextCont->isInline()) {
nextCont = nextCont->continuation();
}
if (nextCont){
int ncx, ncy;
nextCont->absolutePosition(ncx, ncy);
return nextCont->checkSelectionPoint(event, ncx-nextCont->xPos(), ncy-nextCont->yPos(), node, offset);
}
node = lastNode;
offset = lastOffset;
return SelectionPointAfter;
......
......@@ -32,6 +32,7 @@
#include "misc/loader_client.h"
#include "misc/helper.h"
#include "rendering/render_style.h"
#include "khtml_events.h"
class QPainter;
class QTextStream;
......@@ -341,7 +342,7 @@ public:
bool m_active;
};
virtual FindSelectionResult checkSelectionPoint( int _x, int _y, int _tx, int _ty,
virtual FindSelectionResult checkSelectionPoint( const khtml::MouseEvent *event, int _tx, int _ty,
DOM::NodeImpl*&, int & offset );
virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
void setHoverAndActive(NodeInfo& info, bool oldinside, bool inside);
......
......@@ -423,10 +423,12 @@ bool RenderText::nodeAtPoint(NodeInfo& /*info*/, int _x, int _y, int _tx, int _t
return inside;
}
FindSelectionResult RenderText::checkSelectionPoint(int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int &offset)
FindSelectionResult RenderText::checkSelectionPoint(const khtml::MouseEvent *event, int _tx, int _ty, DOM::NodeImpl*& node, int &offset)
{
// kdDebug(6040) << "RenderText::checkSelectionPoint " << this << " _x=" << _x << " _y=" << _y
// << " _tx=" << _tx << " _ty=" << _ty << endl;
int _x = event->x();
int _y = event->y();
TextSlave *lastPointAfterInline=0;
for(unsigned int si = 0; si < m_lines.count(); si++)
......
......@@ -153,7 +153,7 @@ public:
virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside = false);
// Return before, after (offset set to max), or inside the text, at @p offset
virtual FindSelectionResult checkSelectionPoint( int _x, int _y, int _tx, int _ty,
virtual FindSelectionResult checkSelectionPoint( const khtml::MouseEvent *event, int _tx, int _ty,
DOM::NodeImpl*& node, int & offset );
unsigned int length() const { return str->l; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment