BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // Let scrollbar have first dibs handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; if( !handled) { if( allowsEmbeddedItems() ) { setCursorAtLocalPos( x, y, FALSE ); llwchar wc = 0; if (mCursorPos < getLength()) { wc = getWText()[mCursorPos]; } LLPointer<LLInventoryItem> item_at_pos = LLEmbeddedItems::getEmbeddedItemPtr(wc); if (item_at_pos) { mDragItem = item_at_pos; mDragItemChar = wc; mDragItemSaved = LLEmbeddedItems::getEmbeddedItemSaved(wc); gFocusMgr.setMouseCapture( this ); mMouseDownX = x; mMouseDownY = y; S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y ); LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); if (hasTabStop()) { setFocus( TRUE ); } handled = TRUE; } else { mDragItem = NULL; } } if (!handled) { handled = LLTextEditor::handleMouseDown(x, y, mask); } } return handled; }
BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; if (!mDragItem) { // leave hover segment active during drag and drop mHoverSegment = NULL; } if(hasMouseCapture() ) { if( mIsSelecting ) { if (x != mLastSelectionX || y != mLastSelectionY) { mLastSelectionX = x; mLastSelectionY = y; } if( y > getTextRect().mTop ) { mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); } else if( y < getTextRect().mBottom ) { mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); } setCursorAtLocalPos( x, y, TRUE ); mSelectionEnd = mCursorPos; updateScrollFromCursor(); getWindow()->setCursor(UI_CURSOR_IBEAM); } else if( mDragItem ) { S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y ); if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) { LLToolDragAndDrop::getInstance()->beginDrag( LLViewerAssetType::lookupDragAndDropType( mDragItem->getType() ), mDragItem->getUUID(), LLToolDragAndDrop::SOURCE_NOTECARD, getSourceID(), mObjectID); return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); } getWindow()->setCursor(UI_CURSOR_HAND); } LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL; handled = TRUE; } if( !handled ) { // Pass to children handled = LLView::childrenHandleHover(x, y, mask) != NULL; } if( handled ) { // Delay cursor flashing resetKeystrokeTimer(); } // Opaque if( !handled && mTakesNonScrollClicks) { // Check to see if we're over an HTML-style link if( !mSegments.empty() ) { LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { if(cur_segment->getStyle()->isLink()) { LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (over link, inactive)" << LL_ENDL; getWindow()->setCursor(UI_CURSOR_HAND); handled = TRUE; } else if(cur_segment->getStyle()->getIsEmbeddedItem()) { LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (over embedded item, inactive)" << LL_ENDL; getWindow()->setCursor(UI_CURSOR_HAND); //getWindow()->setCursor(UI_CURSOR_ARROW); handled = TRUE; } mHoverSegment = cur_segment; } } if( !handled ) { LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL; if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE) { getWindow()->setCursor(UI_CURSOR_IBEAM); } else { getWindow()->setCursor(UI_CURSOR_ARROW); } handled = TRUE; } } return handled; }
BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // Let scrollbar have first dibs handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; // enable I Agree checkbox if the user scrolled through entire text BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { mOnScrollEndCallback(mOnScrollEndData); } if( !handled && mTakesNonScrollClicks) { if (!(mask & MASK_SHIFT)) { deselect(); } BOOL start_select = TRUE; if( allowsEmbeddedItems() ) { setCursorAtLocalPos( x, y, FALSE ); llwchar wc = 0; if (mCursorPos < getLength()) { wc = getWChar(mCursorPos); } LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc); if (item_at_pos) { mDragItem = item_at_pos; mDragItemChar = wc; mDragItemSaved = LLEmbeddedItems::getEmbeddedItemSaved(wc); gFocusMgr.setMouseCapture( this ); mMouseDownX = x; mMouseDownY = y; S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y ); LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); start_select = FALSE; } else { mDragItem = NULL; } } if( start_select ) { // If we're not scrolling (handled by child), then we're selecting if (mask & MASK_SHIFT) { S32 old_cursor_pos = mCursorPos; setCursorAtLocalPos( x, y, TRUE ); if (hasSelection()) { /* Mac-like behavior - extend selection towards the cursor if (mCursorPos < mSelectionStart && mCursorPos < mSelectionEnd) { // ...left of selection mSelectionStart = llmax(mSelectionStart, mSelectionEnd); mSelectionEnd = mCursorPos; } else if (mCursorPos > mSelectionStart && mCursorPos > mSelectionEnd) { // ...right of selection mSelectionStart = llmin(mSelectionStart, mSelectionEnd); mSelectionEnd = mCursorPos; } else { mSelectionEnd = mCursorPos; } */ // Windows behavior mSelectionEnd = mCursorPos; } else { mSelectionStart = old_cursor_pos; mSelectionEnd = mCursorPos; } // assume we're starting a drag select mIsSelecting = TRUE; } else { setCursorAtLocalPos( x, y, TRUE ); startSelection(); } gFocusMgr.setMouseCapture( this ); } handled = TRUE; } if (hasTabStop()) { setFocus(TRUE); handled = TRUE; } // Delay cursor flashing resetKeystrokeTimer(); return handled; }
// Allow calling cards to be dropped onto text fields. Append the name and // a carriage return. // virtual BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) { BOOL handled = FALSE; LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); if (LLToolDragAndDrop::SOURCE_NOTECARD == source) { // We currently do not handle dragging items from one notecard to another // since items in a notecard must be in Inventory to be verified. See DEV-2891. return FALSE; } if (mTakesNonScrollClicks) { if (getEnabled() && acceptsTextInput()) { switch( cargo_type ) { // <edit> // This does not even appear to be used maybe // Throwing it out so I can embed calling cards /* case DAD_CALLINGCARD: if(acceptsCallingCardNames()) { if (drop) { LLInventoryItem *item = (LLInventoryItem *)cargo_data; std::string name = item->getName(); appendText(name, true, true); } *accept = ACCEPT_YES_COPY_SINGLE; } else { *accept = ACCEPT_NO; } break; */ case DAD_CALLINGCARD: // </edit> case DAD_TEXTURE: case DAD_SOUND: case DAD_LANDMARK: case DAD_SCRIPT: case DAD_CLOTHING: case DAD_OBJECT: case DAD_NOTECARD: case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; // <edit> if((item->getPermissions().getMaskOwner() & PERM_ITEM_UNRESTRICTED) != PERM_ITEM_UNRESTRICTED) { if(gSavedSettings.getBOOL("ForceNotecardDragCargoPermissive")) { item = new LLInventoryItem((LLInventoryItem *)cargo_data); LLPermissions old = item->getPermissions(); LLPermissions perm; perm.init(old.getCreator(), old.getOwner(), old.getLastOwner(), old.getGroup()); perm.setMaskBase(PERM_ITEM_UNRESTRICTED); perm.setMaskEveryone(PERM_ITEM_UNRESTRICTED); perm.setMaskGroup(PERM_ITEM_UNRESTRICTED); perm.setMaskNext(PERM_ITEM_UNRESTRICTED); perm.setMaskOwner(PERM_ITEM_UNRESTRICTED); item->setPermissions(perm); } } // </edit> if( item && allowsEmbeddedItems() ) { U32 mask_next = item->getPermissions().getMaskNextOwner(); // <edit> //if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) if(((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) || gSavedSettings.getBOOL("ForceNotecardDragCargoAcceptance")) { if( drop ) { deselect(); S32 old_cursor = mCursorPos; setCursorAtLocalPos( x, y, TRUE ); S32 insert_pos = mCursorPos; setCursorPos(old_cursor); BOOL inserted = insertEmbeddedItem( insert_pos, item ); if( inserted && (old_cursor > mCursorPos) ) { setCursorPos(mCursorPos + 1); } updateLineStartList(); } *accept = ACCEPT_YES_COPY_MULTI; } else { *accept = ACCEPT_NO; if (tooltip_msg.empty()) { tooltip_msg.assign("Only items with unrestricted\n" "'next owner' permissions \n" "can be attached to notecards."); } } } else { *accept = ACCEPT_NO; } break; } default: *accept = ACCEPT_NO; break; } } else { // Not enabled *accept = ACCEPT_NO; } handled = TRUE; LL_DEBUGS("UserInput") << "dragAndDrop handled by LLViewerTextEditor " << getName() << LL_ENDL; } return handled; }
BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // let scrollbar have first dibs handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL; if( !handled && mTakesNonScrollClicks) { if( allowsEmbeddedItems() ) { const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment && cur_segment->getStyle()->getIsEmbeddedItem() ) { if( openEmbeddedItemAtPos( cur_segment->getStart() ) ) { deselect(); setFocus( FALSE ); return TRUE; } } } setCursorAtLocalPos( x, y, FALSE ); deselect(); const LLWString &text = getWText(); if( isPartOfWord( text[mCursorPos] ) ) { // Select word the cursor is over while ((mCursorPos > 0) && isPartOfWord(text[mCursorPos-1])) { mCursorPos--; } startSelection(); while ((mCursorPos < (S32)text.length()) && isPartOfWord( text[mCursorPos] ) ) { mCursorPos++; } mSelectionEnd = mCursorPos; } else if ((mCursorPos < (S32)text.length()) && !iswspace( text[mCursorPos]) ) { // Select the character the cursor is over startSelection(); mCursorPos++; mSelectionEnd = mCursorPos; } // We don't want handleMouseUp() to "finish" the selection (and thereby // set mSelectionEnd to where the mouse is), so we finish the selection here. mIsSelecting = FALSE; // delay cursor flashing resetKeystrokeTimer(); // take selection to 'primary' clipboard updatePrimary(); handled = TRUE; } return handled; }
// virtual BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) { BOOL handled = FALSE; LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); if (LLToolDragAndDrop::SOURCE_NOTECARD == source) { // We currently do not handle dragging items from one notecard to another // since items in a notecard must be in Inventory to be verified. See DEV-2891. return FALSE; } if (getEnabled() && acceptsTextInput()) { switch( cargo_type ) { case DAD_CALLINGCARD: case DAD_TEXTURE: case DAD_SOUND: case DAD_LANDMARK: case DAD_SCRIPT: case DAD_CLOTHING: case DAD_OBJECT: case DAD_NOTECARD: case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: case DAD_MESH: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; if( item && allowsEmbeddedItems() ) { U32 mask_next = item->getPermissions().getMaskNextOwner(); if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) { if( drop ) { deselect(); S32 old_cursor = mCursorPos; setCursorAtLocalPos( x, y, TRUE ); S32 insert_pos = mCursorPos; setCursorPos(old_cursor); BOOL inserted = insertEmbeddedItem( insert_pos, item ); if( inserted && (old_cursor > mCursorPos) ) { setCursorPos(mCursorPos + 1); } needsReflow(); } *accept = ACCEPT_YES_COPY_MULTI; } else { *accept = ACCEPT_NO; if (tooltip_msg.empty()) { // *TODO: Translate tooltip_msg.assign("Only items with unrestricted\n" "'next owner' permissions \n" "can be attached to notecards."); } } } else { *accept = ACCEPT_NO; } break; } default: *accept = ACCEPT_NO; break; } } else { // Not enabled *accept = ACCEPT_NO; } handled = TRUE; LL_DEBUGS("UserInput") << "dragAndDrop handled by LLViewerTextEditor " << getName() << LL_ENDL; return handled; }
BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // let scrollbar have first dibs handled = LLView::childrenHandleMouseUp(x, y, mask) != NULL; // Used to enable I Agree checkbox if the user scrolled through entire text BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { mOnScrollEndCallback(mOnScrollEndData); } if( !handled && mTakesNonScrollClicks) { if( mIsSelecting ) { // Finish selection if( y > getTextRect().mTop ) { mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); } else if( y < getTextRect().mBottom ) { mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); } setCursorAtLocalPos( x, y, TRUE ); endSelection(); updateScrollFromCursor(); } if( !hasSelection() ) { handleMouseUpOverSegment( x, y, mask ); } handled = TRUE; } // Delay cursor flashing resetKeystrokeTimer(); if( hasMouseCapture() ) { if (mDragItem) { // mouse down was on an item S32 dx = x - mMouseDownX; S32 dy = y - mMouseDownY; if (-2 < dx && dx < 2 && -2 < dy && dy < 2) { if(mDragItemSaved) { openEmbeddedItem(mDragItem); }else { showUnsavedAlertDialog(mDragItem); } } } mDragItem = NULL; gFocusMgr.setMouseCapture( NULL ); handled = TRUE; } return handled; }
// Allow calling cards to be dropped onto text fields. Append the name and // a carriage return. // virtual BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) { BOOL handled = FALSE; if (mTakesNonScrollClicks) { if (getEnabled() && acceptsTextInput()) { switch( cargo_type ) { case DAD_CALLINGCARD: if(acceptsCallingCardNames()) { if (drop) { LLInventoryItem *item = (LLInventoryItem *)cargo_data; std::string name = item->getName(); appendText(name, true, true); } *accept = ACCEPT_YES_COPY_SINGLE; } else { *accept = ACCEPT_NO; } break; case DAD_TEXTURE: case DAD_SOUND: case DAD_LANDMARK: case DAD_SCRIPT: case DAD_CLOTHING: case DAD_OBJECT: case DAD_NOTECARD: case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; if( allowsEmbeddedItems() ) { U32 mask_next = item->getPermissions().getMaskNextOwner(); if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) { if( drop ) { deselect(); S32 old_cursor = mCursorPos; setCursorAtLocalPos( x, y, TRUE ); S32 insert_pos = mCursorPos; setCursorPos(old_cursor); BOOL inserted = insertEmbeddedItem( insert_pos, item ); if( inserted && (old_cursor > mCursorPos) ) { setCursorPos(mCursorPos + 1); } updateLineStartList(); } *accept = ACCEPT_YES_COPY_MULTI; } else { *accept = ACCEPT_NO; if (tooltip_msg.empty()) { tooltip_msg.assign("Only items with unrestricted\n" "'next owner' permissions \n" "can be attached to notecards."); } } } else { *accept = ACCEPT_NO; } break; } default: *accept = ACCEPT_NO; break; } } else { // Not enabled *accept = ACCEPT_NO; } handled = TRUE; lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLViewerTextEditor " << getName() << llendl; } return handled; }