#include "TextSelection.h"
#include "EditorState.h"
+#include "EwkViewImpl.h"
#include "NativeWebMouseEvent.h"
#include "ewk_view.h"
#include <Elementary.h>
namespace WebKit {
-TextSelection::TextSelection(Evas_Object* viewWidget, WebPageProxy* page, PageClientImpl* pageClient)
- : m_object(viewWidget)
- , m_page(page)
- , m_pageClient(pageClient)
+TextSelection::TextSelection(EwkViewImpl* viewImpl)
+ : m_viewImpl(viewImpl)
, m_isTextSelectionDowned(false)
, m_isTextSelectionMode(false)
, m_moveAnimator(0)
, m_showTimer(0)
+#if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
+ , m_selectedHandle(0)
+#endif
+ , m_handleMovingDirection(HandleMovingDirectionNormal)
{
ASSERT(viewWidget);
- m_viewImpl = EwkViewImpl::fromEvasObject(m_object);
-
const Eina_List* defaultThemeList = elm_theme_list_get(0);
const Eina_List* l;
char* themePath = elm_theme_list_item_path_get((const char*)theme, 0);
if (themePath) {
- m_leftHandle = new TextSelectionHandle(m_object, themePath, "elm/entry/selection/block_handle_left", true, this);
- m_rightHandle = new TextSelectionHandle(m_object, themePath, "elm/entry/selection/block_handle_right", false, this);
+ m_leftHandle = new TextSelectionHandle(m_viewImpl->view(), themePath, "elm/entry/selection/block_handle_left", true, this);
+ m_rightHandle = new TextSelectionHandle(m_viewImpl->view(), themePath, "elm/entry/selection/block_handle_right", false, this);
free(themePath);
break;
}
}
- m_magnifier = new TextSelectionMagnifier(m_object, page, pageClient);
+ m_magnifier = new TextSelectionMagnifier(m_viewImpl);
- evas_object_event_callback_add(m_object, EVAS_CALLBACK_MOUSE_UP, onMouseUp, this);
+ evas_object_event_callback_add(m_viewImpl->view(), EVAS_CALLBACK_MOUSE_UP, onMouseUp, this);
}
TextSelection::~TextSelection()
delete m_magnifier;
- evas_object_event_callback_del(m_object, EVAS_CALLBACK_MOUSE_UP, onMouseUp);
+ if (m_moveAnimator) {
+ ecore_animator_del(m_moveAnimator);
+ m_moveAnimator = 0;
+ }
+
+ if (m_showTimer) {
+ ecore_timer_del(m_showTimer);
+ m_showTimer = 0;
+ }
+ evas_object_event_callback_del(m_viewImpl->view(), EVAS_CALLBACK_MOUSE_UP, onMouseUp);
}
void TextSelection::update()
{
- EditorState editorState = m_page->editorState();
+ EditorState editorState = m_viewImpl->page()->editorState();
if (editorState.updateEditorRectOnly)
return;
+#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
+ if (!editorState.shouldIgnoreCompositionSelectionChange)
+ informTextStyleState();
+#endif
+
if (isTextSelectionMode()) {
if (!editorState.selectionIsRange) {
- if (editorState.isContentEditable && !evas_object_focus_get(m_object)) {
+ if (editorState.isContentEditable && !evas_object_focus_get(m_viewImpl->view())) {
WebCore::IntRect caretRect;
- m_page->getCaretPosition(caretRect);
+ m_viewImpl->page()->getCaretPosition(caretRect);
if (!caretRect.isEmpty())
return;
} else {
WebCore::IntRect leftRect;
WebCore::IntRect rightRect;
- if (isTextSelectionDowned() || m_page->getSelectionHandlers(leftRect, rightRect))
+ if (isTextSelectionDowned() || m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect))
return;
setIsTextSelectionMode(false);
}
-#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
- m_page->getTextStyleStateForSelection();
-#endif
} else {
if (!isTextSelectionDowned() && !isTextSelectionHandleDowned()) {
updateHandlers();
showContextMenu();
-#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
- m_page->getTextStyleStateForSelection();
-#endif
}
}
}
-#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
- else {
- if (editorState.isContentEditable && !editorState.selectionIsRange) {
- WebCore::IntRect caretRect;
- m_page->getCaretPosition(caretRect);
- if (!caretRect.isEmpty()) {
- m_page->getTextStyleStateForSelection();
- }
- }
- }
-#endif
}
void TextSelection::setIsTextSelectionMode(bool isTextSelectionMode)
if (!isTextSelectionMode) {
hide();
clear();
+ initHandlesMouseDownedStatus();
+ setIsTextSelectionDowned(false);
}
m_isTextSelectionMode = isTextSelectionMode;
void TextSelection::clear()
{
- EditorState editorState = m_page->editorState();
+ EditorState editorState = m_viewImpl->page()->editorState();
if (!editorState.selectionIsRange)
return;
- m_page->selectionRangeClear();
+ m_viewImpl->page()->selectionRangeClear();
}
void TextSelection::hide()
void TextSelection::updateHandlers()
{
WebCore::IntRect leftRect, rightRect;
- if (!m_page->getSelectionHandlers(leftRect, rightRect))
+ if (!m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect))
return;
m_lastLeftHandleRect = leftRect;
WebCore::IntPoint leftEvasPoint = toEvasTransform.mapPoint(leftRect.minXMaxYCorner());
WebCore::IntPoint rightEvasPoint = toEvasTransform.mapPoint(rightRect.maxXMaxYCorner());
- EditorState editorState = m_page->editorState();
+ TextSelectionHandle* shownLeftHandle = m_leftHandle;
+ TextSelectionHandle* shownRightHandle = m_rightHandle;
+
+ if (m_handleMovingDirection == HandleMovingDirectionReverse) {
+ shownLeftHandle = m_rightHandle;
+ shownRightHandle = m_leftHandle;
+ }
+
+ EditorState editorState = m_viewImpl->page()->editorState();
if (editorState.isContentEditable) {
- m_leftHandle->hide();
- m_rightHandle->hide();
+ shownLeftHandle->hide();
+ shownRightHandle->hide();
WebCore::IntRect editorRect = editorState.editorRect;
WebCore::IntPoint editorLeftEvasPoint = toEvasTransform.mapPoint(editorRect.location());
WebCore::IntPoint editorRightEvasPoint = toEvasTransform.mapPoint(editorRect.maxXMaxYCorner());
int webViewX, webViewY, webViewWidth, webViewHeight;
- evas_object_geometry_get(m_object, &webViewX, &webViewY, &webViewWidth, &webViewHeight);
+ evas_object_geometry_get(m_viewImpl->view(), &webViewX, &webViewY, &webViewWidth, &webViewHeight);
if ((editorLeftEvasPoint.x() <= leftEvasPoint.x() && editorLeftEvasPoint.y() <= leftEvasPoint.y())
&& (webViewX <= leftEvasPoint.x() && webViewY <= leftEvasPoint.y())) {
- m_leftHandle->move(leftEvasPoint);
- m_leftHandle->show();
+ shownLeftHandle->move(leftEvasPoint, m_viewImpl->transformToScene().mapRect(leftRect));
+ shownLeftHandle->show();
}
if ((editorRightEvasPoint.x() >= rightEvasPoint.x() && editorRightEvasPoint.y() >= rightEvasPoint.y())
&& ((webViewX + webViewWidth) >= rightEvasPoint.x() && (webViewY <= rightEvasPoint.y() && (webViewY + webViewHeight) >= rightEvasPoint.y()))) {
- m_rightHandle->move(rightEvasPoint);
- m_rightHandle->show();
+ shownRightHandle->move(rightEvasPoint, m_viewImpl->transformToScene().mapRect(rightRect));
+ shownRightHandle->show();
}
} else {
- m_leftHandle->move(leftEvasPoint);
- m_leftHandle->show();
+ shownLeftHandle->move(leftEvasPoint, m_viewImpl->transformToScene().mapRect(leftRect));
+ shownLeftHandle->show();
- m_rightHandle->move(rightEvasPoint);
- m_rightHandle->show();
+ shownRightHandle->move(rightEvasPoint, m_viewImpl->transformToScene().mapRect(rightRect));
+ shownRightHandle->show();
}
}
if (!isEnabled())
return;
- EditorState editorState = m_page->editorState();
+ EditorState editorState = m_viewImpl->page()->editorState();
if (!editorState.selectionIsRange && !editorState.isContentEditable)
return;
#endif
if (editorState.selectionIsRange) {
WebCore::IntRect leftRect, rightRect;
- if (!m_page->getSelectionHandlers(leftRect, rightRect))
+ if (!m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect))
return;
#if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
// Checking if this point is in viewport area. If the calcualated
// point/Left/Right point are in view port then draw else do not draw the
// context menu. Only draw the selection points.
- FloatRect unscaledRect = FloatRect(m_pageClient->visibleContentRect());
- unscaledRect.scale(1 / m_pageClient->scaleFactor());
+ FloatRect unscaledRect = FloatRect(m_viewImpl->pageClient->visibleContentRect());
+ unscaledRect.scale(1 / m_viewImpl->pageClient->scaleFactor());
IntRect viewportRect = enclosingIntRect(unscaledRect);
WebCore::IntPoint visiblePoint = leftRect.center();
point = rightRect.maxXMinYCorner();
isPresentInViewPort = true;
}
+
+ if (isPresentInViewPort && editorState.isContentEditable) {
+ // In case of single line editor box.
+ if (leftRect == rightRect) {
+ // draw context menu at center point of visible selection range in the editor box
+ IntRect editorRect = editorState.editorRect;
+ leftRect.intersect(editorRect);
+ if (!leftRect.isEmpty())
+ point = leftRect.center();
+ else {
+ // not draw context menu if there is no visible selection range in the editor box
+ isPresentInViewPort = false;
+ }
+ }
+ }
#else
point = leftRect.center();
#endif
} else if (editorState.isContentEditable) {
WebCore::IntRect caretRect;
- m_page->getCaretPosition(caretRect);
+ m_viewImpl->page()->getCaretPosition(caretRect);
if (caretRect.isEmpty())
return;
// show context menu if its in viewport else do not show the contextmenu
- Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_object));
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_viewImpl->view()));
if (!smartData || !smartData->api || !smartData->api->mouse_down || !smartData->api->mouse_up)
return;
point = m_viewImpl->transformToScene().mapPoint(point);
- Evas* evas = evas_object_evas_get(m_object);
+ Evas* evas = evas_object_evas_get(m_viewImpl->view());
// send mouse down.
Evas_Event_Mouse_Down mouseDown;
if (!isEnabled())
return;
- m_page->hideContextMenu();
+ m_viewImpl->page()->hideContextMenu();
}
void TextSelection::setLeftSelectionToEvasPoint(const IntPoint& evasPoint)
{
- m_page->setLeftSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint));
+ int result = m_viewImpl->page()->setLeftSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint), m_handleMovingDirection);
+ if (result)
+ m_handleMovingDirection = result;
updateHandlers();
}
void TextSelection::setRightSelectionToEvasPoint(const IntPoint& evasPoint)
{
- m_page->setRightSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint));
+ int result = m_viewImpl->page()->setRightSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint), m_handleMovingDirection);
+ if (result)
+ m_handleMovingDirection = result;
updateHandlers();
}
void TextSelection::handleMouseDown(TextSelectionHandle* handle, const IntPoint& /*position*/)
{
WebCore::IntPoint basePosition;
- EditorState editorState = m_page->editorState();
+ EditorState editorState = m_viewImpl->page()->editorState();
if (editorState.selectionIsRange) {
WebCore::IntRect leftRect, rightRect;
- if (!m_page->getSelectionHandlers(leftRect, rightRect)) {
+ if (!m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect)) {
clear();
return;
}
void TextSelection::handleMouseUp(TextSelectionHandle* /* handle */, const IntPoint& /* position */)
{
+ m_handleMovingDirection = HandleMovingDirectionNormal;
+
hideMagnifier();
+ updateHandlers();
showContextMenu();
-#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
- m_page->getTextStyleStateForSelection();
-#endif
}
bool TextSelection::isMagnifierVisible()
return;
}
+ EditorState editorState = m_viewImpl->page()->editorState();
+ if (!editorState.selectionIsRange && editorState.isContentEditable)
+ setIsTextSelectionMode(false);
+
if (isShow) {
+#if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
+ if (m_viewImpl->pageClient->isClipboardWindowOpened())
+ return;
+#endif
+ if (m_viewImpl->gestureClient->isGestureWorking())
+ return;
+
updateHandlers();
showContextMenu();
} else {
TextSelection* textSelection = static_cast<TextSelection*>(data);
Evas_Coord_Point point;
- evas_pointer_canvas_xy_get(evas_object_evas_get(textSelection->m_object), &point.x, &point.y);
+ evas_pointer_canvas_xy_get(evas_object_evas_get(textSelection->m_viewImpl->view()), &point.x, &point.y);
textSelection->textSelectionMove(IntPoint(point.x, point.y));
return ECORE_CALLBACK_RENEW;
// 'return false' means text selection is not possible for point.
// 'return true' means text selection is possible.
-bool TextSelection::textSelectionDown(const IntPoint& point, bool isStartedTextSelectionFromOutside)
+bool TextSelection::textSelectionDown(const IntPoint& point)
{
+ // text selection should be ignored when longtap on handle from osp
+ if (!isEnabled() && isTextSelectionHandleDowned())
+ return false;
+
+#if ENABLE(TIZEN_ISF_PORT)
+ m_viewImpl->inputMethodContext()->resetIMFContext();
+#endif
setIsTextSelectionMode(false);
IntPoint contentsPoint = m_viewImpl->transformFromScene().mapPoint(point);
- bool result = m_page->selectClosestWord(contentsPoint, isStartedTextSelectionFromOutside);
+ bool result = m_viewImpl->page()->selectClosestWord(contentsPoint);
if (!result)
return false;
return true;
}
-void TextSelection::textSelectionMove(const IntPoint& point, bool isStartedTextSelectionFromOutside)
+static int s_textSelectionMargin = 5;
+
+void TextSelection::textSelectionMove(const IntPoint& point)
{
+ // text selection should be ignored when longtap on handle from osp
+ if (!isEnabled() && isTextSelectionHandleDowned())
+ return;
+
if (!isTextSelectionMode()) {
stopMoveAnimator();
return;
}
- WebCore::IntPoint viewPoint = m_viewImpl->transformFromScene().mapPoint(point);
- EditorState editorState = m_page->editorState();
+ WebCore::IntPoint viewPoint;
+ EditorState editorState = m_viewImpl->page()->editorState();
+ bool isInEditablePicker = false;
+
+#if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
if (editorState.isContentEditable) {
+ if (editorState.inputMethodHints == "date"
+ || editorState.inputMethodHints == "datetime"
+ || editorState.inputMethodHints == "datetime-local"
+ || editorState.inputMethodHints == "month"
+ || editorState.inputMethodHints == "time"
+ || editorState.inputMethodHints == "week")
+ isInEditablePicker = true;
+ }
+#endif
+
+ if (editorState.isContentEditable && !isInEditablePicker) {
IntRect mapRect = m_viewImpl->transformToScene().mapRect(editorState.editorRect);
- if(mapRect.contains(point)) {
- m_page->selectClosestWord(viewPoint, isStartedTextSelectionFromOutside);
- updateMagnifier(point);
+ IntPoint updatedPoint = point;
+ bool scrolledY = false;
+ if (point.y() < mapRect.y()) {
+ updatedPoint.setY(mapRect.y() + s_textSelectionMargin);
+ if (m_viewImpl->page()->scrollContentByLine(point,WebCore::DirectionBackward)) {
+ scrolledY = true;
+ updateMagnifier(updatedPoint);
+ }
+ } else if (point.y() > mapRect.maxY()) {
+ updatedPoint.setY(mapRect.maxY() - s_textSelectionMargin);
+ if (m_viewImpl->page()->scrollContentByLine(point,WebCore::DirectionForward)) {
+ scrolledY = true;
+ updateMagnifier(updatedPoint);
+ }
+ }
+
+ bool scrolledX = false;
+ if (point.x() < mapRect.x()) {
+ updatedPoint.setX(mapRect.x() + s_textSelectionMargin);
+ if (m_viewImpl->page()->scrollContentByCharacter(point,WebCore::DirectionBackward)) {
+ scrolledX = true;
+ updateMagnifier(updatedPoint);
+ }
+ } else if (point.x() > mapRect.maxX()) {
+ updatedPoint.setX(mapRect.maxX() - s_textSelectionMargin);
+ if (m_viewImpl->page()->scrollContentByCharacter(point,WebCore::DirectionForward)) {
+ scrolledX = true;
+ updateMagnifier(updatedPoint);
+ }
+ }
+
+ if (!scrolledX && !scrolledY) {
+ viewPoint = m_viewImpl->transformFromScene().mapPoint(updatedPoint);
+ m_viewImpl->page()->selectClosestWord(viewPoint);
+ updateMagnifier(updatedPoint);
}
} else {
- m_page->selectClosestWord(viewPoint, isStartedTextSelectionFromOutside);
+ viewPoint = m_viewImpl->transformFromScene().mapPoint(point);
+ m_viewImpl->page()->selectClosestWord(viewPoint);
updateMagnifier(point);
}
showMagnifier();
void TextSelection::textSelectionUp(const IntPoint& point, bool isStartedTextSelectionFromOutside)
{
+ // text selection should be ignored when longtap on handle from osp
+ if (!isEnabled() && isTextSelectionHandleDowned())
+ return;
+
stopMoveAnimator();
if (!isTextSelectionMode() || !isTextSelectionDowned())
setIsTextSelectionDowned(false);
hideMagnifier();
- EditorState editorState = m_page->editorState();
+ EditorState editorState = m_viewImpl->page()->editorState();
if (editorState.selectionIsRange || editorState.isContentEditable) {
if (editorState.selectionIsRange)
updateHandlers();
showContextMenu();
} else if (!isStartedTextSelectionFromOutside)
setIsTextSelectionMode(false);
-
-#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
- m_page->getTextStyleStateForSelection();
-#endif
}
#if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
TextSelectionHandle* TextSelection::getSelectedHandle(const IntPoint& position)
{
WebCore::IntRect leftHandleRect = m_leftHandle->getHandleRect();
- if (leftHandleRect.contains(position))
+ if (!leftHandleRect.isEmpty() && leftHandleRect.contains(position))
return m_leftHandle;
WebCore::IntRect rightHandleRect = m_rightHandle->getHandleRect();
- if (rightHandleRect.contains(position))
+ if (!rightHandleRect.isEmpty() && rightHandleRect.contains(position))
return m_rightHandle;
return 0;
void TextSelection::textSelectionHandleDown(const IntPoint& position)
{
- TextSelectionHandle* selectedHandle = getSelectedHandle(position);
- if (selectedHandle) {
- selectedHandle->mouseDown(position);
- if (selectedHandle->isMouseDowned())
- return;
- }
+ m_selectedHandle = getSelectedHandle(position);
+ if (m_selectedHandle)
+ m_selectedHandle->mouseDown(position);
+ else
+ initHandlesMouseDownedStatus();
}
void TextSelection::textSelectionHandleMove(const IntPoint& position)
{
- if (isTextSelectionHandleDowned()) {
- TextSelectionHandle* selectedHandle = m_leftHandle->isMouseDowned() ? m_leftHandle : m_rightHandle;
- selectedHandle->mouseMove(position);
- }
+ if (m_selectedHandle && isTextSelectionHandleDowned())
+ m_selectedHandle->mouseMove(position);
}
void TextSelection::textSelectionHandleUp()
{
- if (isTextSelectionHandleDowned()) {
- TextSelectionHandle* selectedHandle = m_leftHandle->isMouseDowned() ? m_leftHandle : m_rightHandle;
- selectedHandle->mouseUp();
+ if (m_selectedHandle && isTextSelectionHandleDowned()) {
+ m_selectedHandle->mouseUp();
+ m_selectedHandle = 0;
}
}
#endif
bool TextSelection::isEnabled()
{
- return ewk_settings_text_selection_enabled_get(ewk_view_settings_get(m_object));
+ return ewk_settings_text_selection_enabled_get(ewk_view_settings_get(m_viewImpl->view()));
}
bool TextSelection::isAutomaticClearEnabled()
{
- return ewk_settings_clear_text_selection_automatically_get(ewk_view_settings_get(m_object));
+ return ewk_settings_clear_text_selection_automatically_get(ewk_view_settings_get(m_viewImpl->view()));
}
void TextSelection::requestToShow()
void TextSelection::showHandlesAndContextMenu()
{
WebCore::IntRect leftRect, rightRect;
- if (m_page->getSelectionHandlers(leftRect, rightRect)) {
+ if (m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect)) {
if ((leftRect == m_lastLeftHandleRect) && (rightRect == m_lastRightHandleRect)) {
if (m_showTimer) {
ecore_timer_del(m_showTimer);
}
}
+void TextSelection::initHandlesMouseDownedStatus()
+{
+ m_leftHandle->setIsMouseDowned(false);
+ m_rightHandle->setIsMouseDowned(false);
+}
+
+void TextSelection::changeContextMenuPosition(WebCore::IntPoint& position)
+{
+ if (m_leftHandle->isTop()) {
+ IntRect handleRect = m_leftHandle->getHandleRect();
+ position.setY(position.y() - handleRect.height());
+ }
+}
+
+#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
+void TextSelection::informTextStyleState()
+{
+ WebCore::IntPoint startPoint, endPoint;
+ WebCore::IntRect leftRect, rightRect;
+
+ WebCore::IntRect caretRect;
+ m_viewImpl->page()->getCaretPosition(caretRect);
+ if (!caretRect.isEmpty()) {
+ startPoint.setX(caretRect.x());
+ startPoint.setY(caretRect.y() + caretRect.height());
+
+ endPoint.setX(caretRect.x() + caretRect.width());
+ endPoint.setY(caretRect.y() + caretRect.height());
+ }
+ else if (m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect)) {
+ startPoint.setX(leftRect.x());
+ startPoint.setY(leftRect.y() + leftRect.height());
+
+ endPoint.setX(rightRect.x() + rightRect.width());
+ endPoint.setY(rightRect.y() + rightRect.height());
+ }
+
+ AffineTransform toEvasTransform = m_viewImpl->transformToScene();
+ WebCore::IntPoint startEvasPoint = toEvasTransform.mapPoint(startPoint);
+ WebCore::IntPoint endEvasPoint = toEvasTransform.mapPoint(endPoint);
+
+ ewkViewTextStyleState(m_viewImpl->view(), startEvasPoint, endEvasPoint);
+}
+#endif
} // namespace WebKit
#endif // TIZEN_WEBKIT2_TEXT_SELECTION