From c285f59ce2a05703e3a1232fcaf3ee3aea714b3f Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sun, 18 Feb 2024 12:52:19 +0100 Subject: Replace BOOL with bool in llwindow and dependent classes --- indra/newview/llviewertexteditor.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'indra/newview/llviewertexteditor.cpp') diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index fa6b6dc156..97c5037053 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -240,12 +240,12 @@ public: /*virtual*/ bool canEdit() const { return false; } - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) + /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask) { LLUI::getInstance()->getWindow()->setCursor(UI_CURSOR_HAND); - return TRUE; + return true; } - virtual BOOL handleToolTip(S32 x, S32 y, MASK mask ) + virtual bool handleToolTip(S32 x, S32 y, MASK mask ) { if (mItem->getThumbnailUUID().notNull()) { @@ -259,15 +259,15 @@ public: .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) .create_params(params)); - return TRUE; + return true; } if (!mToolTip.empty()) { LLToolTipMgr::instance().show(mToolTip); - return TRUE; + return true; } - return FALSE; + return false; } /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; } @@ -712,9 +712,9 @@ void LLViewerTextEditor::onVisibilityChange( BOOL new_visibility ) LLUICtrl::onVisibilityChange(new_visibility); } -BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) +bool LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; + bool handled = false; // Let scrollbar have first dibs handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; @@ -748,7 +748,7 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) setFocus( TRUE ); } - handled = TRUE; + handled = true; } else { @@ -766,9 +766,9 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) } -BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) +bool LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) { - BOOL handled = LLTextEditor::handleHover(x, y, mask); + bool handled = LLTextEditor::handleHover(x, y, mask); if(hasMouseCapture() && mDragItem) { @@ -788,16 +788,16 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); } getWindow()->setCursor(UI_CURSOR_HAND); - handled = TRUE; + handled = true; } return handled; } -BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) +bool LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; + bool handled = false; if( hasMouseCapture() ) { @@ -826,9 +826,9 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) return handled; } -BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) +bool LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; + bool handled = false; // let scrollbar have first dibs handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL; @@ -845,7 +845,7 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { deselect(); setFocus( FALSE ); - return TRUE; + return true; } } } -- cgit v1.2.3 From a5261a5fa8fad810ecb5c260d92c3e771822bf58 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Feb 2024 23:46:23 +0100 Subject: Convert BOOL to bool in llui --- indra/newview/llviewertexteditor.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'indra/newview/llviewertexteditor.cpp') diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 97c5037053..f46544e1ef 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -622,7 +622,7 @@ public: mItem = item; } - virtual BOOL execute( LLTextBase* editor, S32* delta ) + virtual bool execute( LLTextBase* editor, S32* delta ) { LLViewerTextEditor* viewer_editor = (LLViewerTextEditor*)editor; // Take this opportunity to remove any unused embedded items from this editor @@ -634,7 +634,7 @@ public: *delta = insert(editor, getPosition(), ws ); return (*delta != 0); } - return FALSE; + return false; } virtual S32 undo( LLTextBase* editor ) @@ -650,7 +650,7 @@ public: insert(editor, getPosition(), ws ); return getPosition() + 1; } - virtual BOOL hasExtCharValue( llwchar value ) const + virtual bool hasExtCharValue( llwchar value ) const { return (value == mExtCharValue); } @@ -707,7 +707,7 @@ void LLViewerTextEditor::makePristine() LLTextEditor::makePristine(); } -void LLViewerTextEditor::onVisibilityChange( BOOL new_visibility ) +void LLViewerTextEditor::onVisibilityChange( bool new_visibility ) { LLUICtrl::onVisibilityChange(new_visibility); } @@ -856,19 +856,19 @@ bool LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) // virtual -BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, void *cargo_data, +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; + 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; + return false; } if (getEnabled() && acceptsTextInput()) @@ -951,7 +951,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, *accept = ACCEPT_NO; } - handled = TRUE; + handled = true; LL_DEBUGS("UserInput") << "dragAndDrop handled by LLViewerTextEditor " << getName() << LL_ENDL; return handled; @@ -1355,13 +1355,13 @@ bool LLViewerTextEditor::hasEmbeddedInventory() //////////////////////////////////////////////////////////////////////////// -BOOL LLViewerTextEditor::importBuffer( const char* buffer, S32 length ) +bool LLViewerTextEditor::importBuffer( const char* buffer, S32 length ) { LLMemoryStream str((U8*)buffer, length); return importStream(str); } -BOOL LLViewerTextEditor::exportBuffer( std::string& buffer ) +bool LLViewerTextEditor::exportBuffer( std::string& buffer ) { LLNotecard nc(LLNotecard::MAX_SIZE); @@ -1378,6 +1378,6 @@ BOOL LLViewerTextEditor::exportBuffer( std::string& buffer ) buffer = out_stream.str(); - return TRUE; + return true; } -- cgit v1.2.3 From 60d3dd98a44230c21803c1606552ee098ed9fa7c Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 21 Feb 2024 21:05:14 +0100 Subject: Convert remaining BOOL to bool --- indra/newview/llviewertexteditor.cpp | 78 ++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'indra/newview/llviewertexteditor.cpp') diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index f46544e1ef..9109f49945 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -305,10 +305,10 @@ public: // return true if there are no embedded items. bool empty(); - BOOL insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new); - BOOL removeEmbeddedItem( llwchar ext_char ); + bool insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new); + bool removeEmbeddedItem( llwchar ext_char ); - BOOL hasEmbeddedItem(llwchar ext_char); // returns TRUE if /this/ editor has an entry for this item + bool hasEmbeddedItem(llwchar ext_char); // returns true if /this/ editor has an entry for this item LLUIImagePtr getItemImage(llwchar ext_char) const; void getEmbeddedItemList( std::vector >& items ); @@ -323,14 +323,14 @@ public: void markSaved(); static LLPointer getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list - static BOOL getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved + static bool getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved private: struct embedded_info_t { LLPointer mItemPtr; - BOOL mSaved; + bool mSaved; }; typedef std::map item_map_t; static item_map_t sEntries; @@ -375,7 +375,7 @@ bool LLEmbeddedItems::empty() } // Inserts a new unique entry -BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_char, bool is_new) +bool LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_char, bool is_new) { // Now insert a new one llwchar wc_emb; @@ -395,20 +395,20 @@ BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch wc_emb = last->first; if (wc_emb >= LLTextEditor::LAST_EMBEDDED_CHAR) { - return FALSE; + return false; } ++wc_emb; } sEntries[wc_emb].mItemPtr = item; - sEntries[wc_emb].mSaved = is_new ? FALSE : TRUE; + sEntries[wc_emb].mSaved = is_new ? false : true; *ext_char = wc_emb; mEmbeddedUsedChars.insert(wc_emb); - return TRUE; + return true; } // Removes an entry (all entries are unique) -BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char ) +bool LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char ) { mEmbeddedUsedChars.erase(ext_char); item_map_t::iterator iter = sEntries.find(ext_char); @@ -416,9 +416,9 @@ BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char ) { sEntries.erase(ext_char); sFreeEntries.push(ext_char); - return TRUE; + return true; } - return FALSE; + return false; } // static @@ -436,7 +436,7 @@ LLPointer LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char) } // static -BOOL LLEmbeddedItems::getEmbeddedItemSaved(llwchar ext_char) +bool LLEmbeddedItems::getEmbeddedItemSaved(llwchar ext_char) { if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) { @@ -446,7 +446,7 @@ BOOL LLEmbeddedItems::getEmbeddedItemSaved(llwchar ext_char) return iter->second.mSaved; } } - return FALSE; + return false; } llwchar LLEmbeddedItems::getEmbeddedCharFromIndex(S32 index) @@ -514,14 +514,14 @@ S32 LLEmbeddedItems::getIndexFromEmbeddedChar(llwchar wch) } } -BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char) +bool LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char) { std::set::iterator iter = mEmbeddedUsedChars.find(ext_char); if (iter != mEmbeddedUsedChars.end()) { - return TRUE; + return true; } - return FALSE; + return false; } @@ -606,7 +606,7 @@ void LLEmbeddedItems::markSaved() for (std::set::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter) { llwchar wc = *iter; - sEntries[wc].mSaved = TRUE; + sEntries[wc].mSaved = true; } } @@ -616,7 +616,7 @@ class LLViewerTextEditor::TextCmdInsertEmbeddedItem : public LLTextBase::TextCmd { public: TextCmdInsertEmbeddedItem( S32 pos, LLInventoryItem* item ) - : TextCmd(pos, FALSE), + : TextCmd(pos, false), mExtCharValue(0) { mItem = item; @@ -682,7 +682,7 @@ struct LLNotecardCopyInfo LLViewerTextEditor::LLViewerTextEditor(const LLViewerTextEditor::Params& p) : LLTextEditor(p), mDragItemChar(0), - mDragItemSaved(FALSE), + mDragItemSaved(false), mInventoryCallback(new LLEmbeddedNotecardOpener) { mEmbeddedItemList = new LLEmbeddedItems(this); @@ -723,7 +723,7 @@ bool LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { if( allowsEmbeddedItems() ) { - setCursorAtLocalPos( x, y, FALSE ); + setCursorAtLocalPos( x, y, false ); llwchar wc = 0; if (mCursorPos < getLength()) { @@ -745,7 +745,7 @@ bool LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) if (hasTabStop()) { - setFocus( TRUE ); + setFocus( true ); } handled = true; @@ -837,14 +837,14 @@ bool LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { if( allowsEmbeddedItems() ) { - S32 doc_index = getDocIndexFromLocalCoord(x, y, FALSE); + S32 doc_index = getDocIndexFromLocalCoord(x, y, false); llwchar doc_char = getWText()[doc_index]; if (mEmbeddedItemList->hasEmbeddedItem(doc_char)) { if( openEmbeddedItemAtPos( doc_index )) { deselect(); - setFocus( FALSE ); + setFocus( false ); return true; } } @@ -918,10 +918,10 @@ bool LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, { deselect(); S32 old_cursor = mCursorPos; - setCursorAtLocalPos( x, y, TRUE ); + setCursorAtLocalPos( x, y, true ); S32 insert_pos = mCursorPos; setCursorPos(old_cursor); - BOOL inserted = insertEmbeddedItem( insert_pos, item ); + bool inserted = insertEmbeddedItem( insert_pos, item ); if( inserted && (old_cursor > mCursorPos) ) { setCursorPos(mCursorPos + 1); @@ -1099,7 +1099,7 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end) } } -BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) +bool LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) { if( pos < getLength()) { @@ -1107,7 +1107,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) LLPointer item = LLEmbeddedItems::getEmbeddedItemPtr( wc ); if( item ) { - BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( wc ); + bool saved = LLEmbeddedItems::getEmbeddedItemSaved( wc ); if (saved) { return openEmbeddedItem(item, wc); @@ -1118,36 +1118,36 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) } } } - return FALSE; + return false; } -BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer item, llwchar wc) +bool LLViewerTextEditor::openEmbeddedItem(LLPointer item, llwchar wc) { switch( item->getType() ) { case LLAssetType::AT_TEXTURE: openEmbeddedTexture( item, wc ); - return TRUE; + return true; case LLAssetType::AT_SOUND: openEmbeddedSound( item, wc ); - return TRUE; + return true; case LLAssetType::AT_LANDMARK: openEmbeddedLandmark( item, wc ); - return TRUE; + return true; case LLAssetType::AT_CALLINGCARD: openEmbeddedCallingcard( item, wc ); - return TRUE; + return true; case LLAssetType::AT_SETTINGS: openEmbeddedSetting(item, wc); - return TRUE; + return true; case LLAssetType::AT_MATERIAL: openEmbeddedGLTFMaterial(item, wc); - return TRUE; + return true; case LLAssetType::AT_NOTECARD: case LLAssetType::AT_LSL_TEXT: case LLAssetType::AT_CLOTHING: @@ -1156,9 +1156,9 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer item, llwch case LLAssetType::AT_ANIMATION: case LLAssetType::AT_GESTURE: showCopyToInvDialog( item, wc ); - return TRUE; + return true; default: - return FALSE; + return false; } } @@ -1254,7 +1254,7 @@ void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar preview->setAuxItem(item); preview->setNotecardInfo(mNotecardInventoryID, mObjectID); preview->openFloater(floater_key); - preview->setFocus(TRUE); + preview->setFocus(true); } } -- cgit v1.2.3 From f9473e8afcb624cc1b101195bf15943ec372b56f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 6 May 2024 16:52:34 +0200 Subject: secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries --- indra/newview/llviewertexteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llviewertexteditor.cpp') diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 9109f49945..28e637cc68 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -401,7 +401,7 @@ bool LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch } sEntries[wc_emb].mItemPtr = item; - sEntries[wc_emb].mSaved = is_new ? false : true; + sEntries[wc_emb].mSaved = !is_new; *ext_char = wc_emb; mEmbeddedUsedChars.insert(wc_emb); return true; -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/newview/llviewertexteditor.cpp | 2766 +++++++++++++++++----------------- 1 file changed, 1383 insertions(+), 1383 deletions(-) (limited to 'indra/newview/llviewertexteditor.cpp') diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index bb8b5dc837..82d0caecb5 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1,1383 +1,1383 @@ -/** - * @file llviewertexteditor.cpp - * @brief Text editor widget to let users enter a multi-line document. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llviewertexteditor.h" - -#include "llagent.h" -#include "llaudioengine.h" -#include "llavataractions.h" -#include "llenvironment.h" -#include "llfloaterreg.h" -#include "llfloatersidepanelcontainer.h" -#include "llfloaterworldmap.h" -#include "llfocusmgr.h" -#include "llinspecttexture.h" -#include "llinventorybridge.h" -#include "llinventorydefines.h" -#include "llinventorymodel.h" -#include "lllandmark.h" -#include "lllandmarkactions.h" -#include "lllandmarklist.h" -#include "llmaterialeditor.h" -#include "llmemorystream.h" -#include "llmenugl.h" -#include "llnotecard.h" -#include "llnotificationsutil.h" -#include "llpanelplaces.h" -#include "llpreview.h" -#include "llpreviewnotecard.h" -#include "llpreviewtexture.h" -#include "llscrollbar.h" -#include "llscrollcontainer.h" -#include "lltooldraganddrop.h" -#include "lltooltip.h" -#include "lltrans.h" -#include "lluictrlfactory.h" -#include "llviewerassettype.h" -#include "llviewercontrol.h" -#include "llviewerinventory.h" -#include "llviewertexturelist.h" -#include "llviewerwindow.h" - -static LLDefaultChildRegistry::Register r("text_editor"); - -///----------------------------------------------------------------------- -/// Class LLEmbeddedLandmarkCopied -///----------------------------------------------------------------------- -class LLEmbeddedLandmarkCopied: public LLInventoryCallback -{ -public: - - LLEmbeddedLandmarkCopied(){} - void fire(const LLUUID& inv_item) - { - showInfo(inv_item); - } - static void showInfo(const LLUUID& landmark_inv_id) - { - LLSD key; - key["type"] = "landmark"; - key["id"] = landmark_inv_id; - LLFloaterSidePanelContainer::showPanel("places", key); - } - static void processForeignLandmark(LLLandmark* landmark, - const LLUUID& object_id, const LLUUID& notecard_inventory_id, - LLPointer item_ptr) - { - LLVector3d global_pos; - landmark->getGlobalPos(global_pos); - LLViewerInventoryItem* agent_landmark = - LLLandmarkActions::findLandmarkForGlobalPos(global_pos); - - if (agent_landmark) - { - showInfo(agent_landmark->getUUID()); - } - else - { - if (item_ptr.isNull()) - { - // check to prevent a crash. See EXT-8459. - LL_WARNS() << "Passed handle contains a dead inventory item. Most likely notecard has been closed and embedded item was destroyed." << LL_ENDL; - } - else - { - LLInventoryItem* item = item_ptr.get(); - LLPointer cb = new LLEmbeddedLandmarkCopied(); - copy_inventory_from_notecard(get_folder_by_itemtype(item), - object_id, - notecard_inventory_id, - item, - gInventoryCallbacks.registerCB(cb)); - } - } - } -}; -///---------------------------------------------------------------------------- -/// Class LLEmbeddedNotecardOpener -///---------------------------------------------------------------------------- -class LLEmbeddedNotecardOpener : public LLInventoryCallback -{ - LLViewerTextEditor* mTextEditor; - -public: - LLEmbeddedNotecardOpener() - : mTextEditor(NULL) - { - } - - void setEditor(LLViewerTextEditor* e) {mTextEditor = e;} - - // override - void fire(const LLUUID& inv_item) - { - if(!mTextEditor) - { - // The parent text editor may have vanished by now. - // In that case just quit. - return; - } - - LLInventoryItem* item = gInventory.getItem(inv_item); - if(!item) - { - LL_WARNS() << "Item add reported, but not found in inventory!: " << inv_item << LL_ENDL; - } - else - { - if(!gSavedSettings.getBOOL("ShowNewInventory")) - { - LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); - } - } - } -}; - -// -// class LLEmbeddedItemSegment -// - -const S32 EMBEDDED_ITEM_LABEL_PADDING = 2; - -class LLEmbeddedItemSegment : public LLTextSegment -{ -public: - LLEmbeddedItemSegment(S32 pos, LLUIImagePtr image, LLPointer inv_item, LLTextEditor& editor) - : LLTextSegment(pos, pos + 1), - mImage(image), - mLabel(utf8str_to_wstring(inv_item->getName())), - mItem(inv_item), - mEditor(editor) - { - - mStyle = new LLStyle(LLStyle::Params().font(LLFontGL::getFontSansSerif())); - mToolTip = inv_item->getName() + '\n' + inv_item->getDescription(); - } - - /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const - { - if (num_chars == 0) - { - width = 0; - height = 0; - } - else - { - width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidthF32(mLabel.c_str()); - height = llmax(mImage->getHeight(), mStyle->getFont()->getLineHeight()); - } - return false; - } - - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const - { - // always draw at beginning of line - if (line_offset == 0) - { - return 1; - } - else - { - S32 width, height; - getDimensions(mStart, 1, width, height); - if (width > num_pixels) - { - return 0; - } - else - { - return 1; - } - } - } - /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) - { - LLRectf image_rect = draw_rect; - image_rect.mRight = image_rect.mLeft + mImage->getWidth(); - image_rect.mTop = image_rect.mBottom + mImage->getHeight(); - mImage->draw(LLRect(image_rect.mLeft, image_rect.mTop, image_rect.mRight, image_rect.mBottom)); - - LLColor4 color; - if (mEditor.getReadOnly()) - { - color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor"); - } - else - { - color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor"); - } - - F32 right_x; - mStyle->getFont()->render(mLabel, 0, image_rect.mRight + EMBEDDED_ITEM_LABEL_PADDING, draw_rect.mTop, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::UNDERLINE, LLFontGL::NO_SHADOW, mLabel.length(), S32_MAX, &right_x); - return right_x; - } - - /*virtual*/ bool canEdit() const { return false; } - - - /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask) - { - LLUI::getInstance()->getWindow()->setCursor(UI_CURSOR_HAND); - return true; - } - virtual bool handleToolTip(S32 x, S32 y, MASK mask ) - { - if (mItem->getThumbnailUUID().notNull()) - { - LLSD params; - params["inv_type"] = mItem->getInventoryType(); - params["thumbnail_id"] = mItem->getThumbnailUUID(); - params["asset_id"] = mItem->getAssetUUID(); - - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(mToolTip) - .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) - .create_params(params)); - - return true; - } - - if (!mToolTip.empty()) - { - LLToolTipMgr::instance().show(mToolTip); - return true; - } - return false; - } - - /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; } - -private: - LLUIImagePtr mImage; - LLWString mLabel; - LLStyleSP mStyle; - std::string mToolTip; - LLPointer mItem; - LLTextEditor& mEditor; -}; - - - -//////////////////////////////////////////////////////////// -// LLEmbeddedItems -// -// Embedded items are stored as: -// * A global map of llwchar to LLInventoryItem -// ** This is unique for each item embedded in any notecard -// to support copy/paste across notecards -// * A per-notecard set of embeded llwchars for easy removal -// from the global list -// * A per-notecard vector of embedded lwchars for mapping from -// old style 0x80 + item format notechards - -class LLEmbeddedItems -{ -public: - LLEmbeddedItems(const LLViewerTextEditor* editor); - ~LLEmbeddedItems(); - void clear(); - - // return true if there are no embedded items. - bool empty(); - - bool insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new); - bool removeEmbeddedItem( llwchar ext_char ); - - bool hasEmbeddedItem(llwchar ext_char); // returns true if /this/ editor has an entry for this item - LLUIImagePtr getItemImage(llwchar ext_char) const; - - void getEmbeddedItemList( std::vector >& items ); - void addItems(const std::vector >& items); - - llwchar getEmbeddedCharFromIndex(S32 index); - - void removeUnusedChars(); - void copyUsedCharsToIndexed(); - S32 getIndexFromEmbeddedChar(llwchar wch); - - void markSaved(); - - static LLPointer getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list - static bool getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved - -private: - - struct embedded_info_t - { - LLPointer mItemPtr; - bool mSaved; - }; - typedef std::map item_map_t; - static item_map_t sEntries; - static std::stack sFreeEntries; - - std::set mEmbeddedUsedChars; // list of used llwchars - std::vector mEmbeddedIndexedChars; // index -> wchar for 0x80 + index format - const LLViewerTextEditor* mEditor; -}; - -//statics -LLEmbeddedItems::item_map_t LLEmbeddedItems::sEntries; -std::stack LLEmbeddedItems::sFreeEntries; - -LLEmbeddedItems::LLEmbeddedItems(const LLViewerTextEditor* editor) - : mEditor(editor) -{ -} - -LLEmbeddedItems::~LLEmbeddedItems() -{ - clear(); -} - -void LLEmbeddedItems::clear() -{ - // Remove entries for this editor from static list - for (std::set::iterator iter = mEmbeddedUsedChars.begin(); - iter != mEmbeddedUsedChars.end();) - { - std::set::iterator nextiter = iter++; - removeEmbeddedItem(*nextiter); - } - mEmbeddedUsedChars.clear(); - mEmbeddedIndexedChars.clear(); -} - -bool LLEmbeddedItems::empty() -{ - removeUnusedChars(); - return mEmbeddedUsedChars.empty(); -} - -// Inserts a new unique entry -bool LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_char, bool is_new) -{ - // Now insert a new one - llwchar wc_emb; - if (!sFreeEntries.empty()) - { - wc_emb = sFreeEntries.top(); - sFreeEntries.pop(); - } - else if (sEntries.empty()) - { - wc_emb = LLTextEditor::FIRST_EMBEDDED_CHAR; - } - else - { - item_map_t::iterator last = sEntries.end(); - --last; - wc_emb = last->first; - if (wc_emb >= LLTextEditor::LAST_EMBEDDED_CHAR) - { - return false; - } - ++wc_emb; - } - - sEntries[wc_emb].mItemPtr = item; - sEntries[wc_emb].mSaved = !is_new; - *ext_char = wc_emb; - mEmbeddedUsedChars.insert(wc_emb); - return true; -} - -// Removes an entry (all entries are unique) -bool LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char ) -{ - mEmbeddedUsedChars.erase(ext_char); - item_map_t::iterator iter = sEntries.find(ext_char); - if (iter != sEntries.end()) - { - sEntries.erase(ext_char); - sFreeEntries.push(ext_char); - return true; - } - return false; -} - -// static -LLPointer LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char) -{ - if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) - { - item_map_t::iterator iter = sEntries.find(ext_char); - if (iter != sEntries.end()) - { - return iter->second.mItemPtr; - } - } - return NULL; -} - -// static -bool LLEmbeddedItems::getEmbeddedItemSaved(llwchar ext_char) -{ - if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) - { - item_map_t::iterator iter = sEntries.find(ext_char); - if (iter != sEntries.end()) - { - return iter->second.mSaved; - } - } - return false; -} - -llwchar LLEmbeddedItems::getEmbeddedCharFromIndex(S32 index) -{ - if (index >= (S32)mEmbeddedIndexedChars.size()) - { - LL_WARNS() << "No item for embedded char " << index << " using LL_UNKNOWN_CHAR" << LL_ENDL; - return LL_UNKNOWN_CHAR; - } - return mEmbeddedIndexedChars[index]; -} - -void LLEmbeddedItems::removeUnusedChars() -{ - std::set used = mEmbeddedUsedChars; - const LLWString& wtext = mEditor->getWText(); - for (S32 i=0; i<(S32)wtext.size(); i++) - { - llwchar wc = wtext[i]; - if( wc >= LLTextEditor::FIRST_EMBEDDED_CHAR && wc <= LLTextEditor::LAST_EMBEDDED_CHAR ) - { - used.erase(wc); - } - } - // Remove chars not actually used - for (std::set::iterator iter = used.begin(); - iter != used.end(); ++iter) - { - removeEmbeddedItem(*iter); - } -} - -void LLEmbeddedItems::copyUsedCharsToIndexed() -{ - // Prune unused items - removeUnusedChars(); - - // Copy all used llwchars to mEmbeddedIndexedChars - mEmbeddedIndexedChars.clear(); - for (std::set::iterator iter = mEmbeddedUsedChars.begin(); - iter != mEmbeddedUsedChars.end(); ++iter) - { - mEmbeddedIndexedChars.push_back(*iter); - } -} - -S32 LLEmbeddedItems::getIndexFromEmbeddedChar(llwchar wch) -{ - S32 idx = 0; - for (std::vector::iterator iter = mEmbeddedIndexedChars.begin(); - iter != mEmbeddedIndexedChars.end(); ++iter) - { - if (wch == *iter) - break; - ++idx; - } - if (idx < (S32)mEmbeddedIndexedChars.size()) - { - return idx; - } - else - { - LL_WARNS() << "Embedded char " << wch << " not found, using 0" << LL_ENDL; - return 0; - } -} - -bool LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char) -{ - std::set::iterator iter = mEmbeddedUsedChars.find(ext_char); - if (iter != mEmbeddedUsedChars.end()) - { - return true; - } - return false; -} - - -LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const -{ - LLInventoryItem* item = getEmbeddedItemPtr(ext_char); - if (item) - { - const char* img_name = ""; - switch( item->getType() ) - { - case LLAssetType::AT_TEXTURE: - if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT) - { - img_name = "Inv_Snapshot"; - } - else - { - img_name = "Inv_Texture"; - } - - break; - case LLAssetType::AT_SOUND: img_name = "Inv_Sound"; break; - case LLAssetType::AT_CLOTHING: img_name = "Inv_Clothing"; break; - case LLAssetType::AT_OBJECT: - img_name = LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS & item->getFlags() ? - "Inv_Object_Multi" : "Inv_Object"; - break; - case LLAssetType::AT_CALLINGCARD: img_name = "Inv_CallingCard"; break; - case LLAssetType::AT_LANDMARK: img_name = "Inv_Landmark"; break; - case LLAssetType::AT_NOTECARD: img_name = "Inv_Notecard"; break; - case LLAssetType::AT_LSL_TEXT: img_name = "Inv_Script"; break; - case LLAssetType::AT_BODYPART: img_name = "Inv_Skin"; break; - case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break; - case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break; - case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break; - case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break; - case LLAssetType::AT_MATERIAL: img_name = "Inv_Material"; break; - default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981) - - } - - return LLUI::getUIImage(img_name); - } - return LLUIImagePtr(); -} - - -void LLEmbeddedItems::addItems(const std::vector >& items) -{ - for (std::vector >::const_iterator iter = items.begin(); - iter != items.end(); ++iter) - { - LLInventoryItem* item = *iter; - if (item) - { - llwchar wc; - if (!insertEmbeddedItem( item, &wc, false )) - { - break; - } - mEmbeddedIndexedChars.push_back(wc); - } - } -} - -void LLEmbeddedItems::getEmbeddedItemList( std::vector >& items ) -{ - for (std::set::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter) - { - llwchar wc = *iter; - LLPointer item = getEmbeddedItemPtr(wc); - if (item) - { - items.push_back(item); - } - } -} - -void LLEmbeddedItems::markSaved() -{ - for (std::set::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter) - { - llwchar wc = *iter; - sEntries[wc].mSaved = true; - } -} - -/////////////////////////////////////////////////////////////////// - -class LLViewerTextEditor::TextCmdInsertEmbeddedItem : public LLTextBase::TextCmd -{ -public: - TextCmdInsertEmbeddedItem( S32 pos, LLInventoryItem* item ) - : TextCmd(pos, false), - mExtCharValue(0) - { - mItem = item; - } - - virtual bool execute( LLTextBase* editor, S32* delta ) - { - LLViewerTextEditor* viewer_editor = (LLViewerTextEditor*)editor; - // Take this opportunity to remove any unused embedded items from this editor - viewer_editor->mEmbeddedItemList->removeUnusedChars(); - if(viewer_editor->mEmbeddedItemList->insertEmbeddedItem( mItem, &mExtCharValue, true ) ) - { - LLWString ws; - ws.assign(1, mExtCharValue); - *delta = insert(editor, getPosition(), ws ); - return (*delta != 0); - } - return false; - } - - virtual S32 undo( LLTextBase* editor ) - { - remove(editor, getPosition(), 1); - return getPosition(); - } - - virtual S32 redo( LLTextBase* editor ) - { - LLWString ws; - ws += mExtCharValue; - insert(editor, getPosition(), ws ); - return getPosition() + 1; - } - virtual bool hasExtCharValue( llwchar value ) const - { - return (value == mExtCharValue); - } - -private: - LLPointer mItem; - llwchar mExtCharValue; -}; - -struct LLNotecardCopyInfo -{ - LLNotecardCopyInfo(LLViewerTextEditor *ed, LLInventoryItem *item) - : mTextEd(ed) - { - mItem = item; - } - - LLViewerTextEditor* mTextEd; - // need to make this be a copy (not a * here) because it isn't stable. - // I wish we had passed LLPointers all the way down, but we didn't - LLPointer mItem; -}; - -//---------------------------------------------------------------------------- - -// -// Member functions -// -LLViewerTextEditor::LLViewerTextEditor(const LLViewerTextEditor::Params& p) -: LLTextEditor(p), - mDragItemChar(0), - mDragItemSaved(false), - mInventoryCallback(new LLEmbeddedNotecardOpener) -{ - mEmbeddedItemList = new LLEmbeddedItems(this); - mInventoryCallback->setEditor(this); -} - -LLViewerTextEditor::~LLViewerTextEditor() -{ - delete mEmbeddedItemList; - - - // The inventory callback may still be in use by gInventoryCallbackManager... - // so set its reference to this to null. - mInventoryCallback->setEditor(NULL); -} - -/////////////////////////////////////////////////////////////////// -// virtual -void LLViewerTextEditor::makePristine() -{ - mEmbeddedItemList->markSaved(); - LLTextEditor::makePristine(); -} - -void LLViewerTextEditor::onVisibilityChange( bool new_visibility ) -{ - LLUICtrl::onVisibilityChange(new_visibility); -} - -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 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 = LLTextEditor::handleHover(x, y, mask); - - if(hasMouseCapture() && mDragItem) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - - mScroller->autoScroll(x, y); - - if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) - { - LLToolDragAndDrop::getInstance()->beginDrag( - LLViewerAssetType::lookupDragAndDropType( mDragItem->getType() ), - mDragItem->getUUID(), - LLToolDragAndDrop::SOURCE_NOTECARD, - mPreviewID, mObjectID); - return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); - } - getWindow()->setCursor(UI_CURSOR_HAND); - handled = true; - } - - return handled; -} - - -bool LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) -{ - bool handled = false; - - 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, mDragItemChar); - } - else - { - showUnsavedAlertDialog(mDragItem); - } - } - } - mDragItem = NULL; - } - - handled = LLTextEditor::handleMouseUp(x,y,mask); - - 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) - { - if( allowsEmbeddedItems() ) - { - S32 doc_index = getDocIndexFromLocalCoord(x, y, false); - llwchar doc_char = getWText()[doc_index]; - if (mEmbeddedItemList->hasEmbeddedItem(doc_char)) - { - if( openEmbeddedItemAtPos( doc_index )) - { - deselect(); - setFocus( false ); - return true; - } - } - } - handled = LLTextEditor::handleDoubleClick(x, y, mask); - } - 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()) - { - bool supported = false; - switch( cargo_type ) - { - case DAD_SETTINGS: - { - supported = LLEnvironment::instance().isExtendedEnvironmentEnabled(); - if (!supported && tooltip_msg.empty()) - { - tooltip_msg.assign(LLTrans::getString("TooltipNotecardNotAllowedTypeDrop")); - } - break; - } - 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: - case DAD_MATERIAL: - { - supported = true; - break; - } - - default: - supported = false; - break; - } - - LLInventoryItem *item = (LLInventoryItem *)cargo_data; - if (item && allowsEmbeddedItems() && supported) - { - 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()) - { - tooltip_msg.assign(LLTrans::getString("TooltipNotecardOwnerRestrictedDrop")); - } - } - } - else - { - *accept = ACCEPT_NO; - } - } - else - { - // Not enabled - *accept = ACCEPT_NO; - } - - handled = true; - LL_DEBUGS("UserInput") << "dragAndDrop handled by LLViewerTextEditor " << getName() << LL_ENDL; - - return handled; -} - -void LLViewerTextEditor::setASCIIEmbeddedText(const std::string& instr) -{ - LLWString wtext; - const U8* buffer = (U8*)(instr.c_str()); - while (*buffer) - { - llwchar wch; - U8 c = *buffer++; - if (c >= 0x80) - { - S32 index = (S32)(c - 0x80); - wch = mEmbeddedItemList->getEmbeddedCharFromIndex(index); - } - else - { - wch = (llwchar)c; - } - wtext.push_back(wch); - } - setWText(wtext); -} - -void LLViewerTextEditor::setEmbeddedText(const std::string& instr) -{ - LLWString wtext = utf8str_to_wstring(instr); - for (S32 i=0; i<(S32)wtext.size(); i++) - { - llwchar wch = wtext[i]; - if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) - { - S32 index = wch - FIRST_EMBEDDED_CHAR; - wtext[i] = mEmbeddedItemList->getEmbeddedCharFromIndex(index); - } - } - setWText(wtext); -} - -std::string LLViewerTextEditor::getEmbeddedText() -{ -#if 1 - // New version (Version 2) - mEmbeddedItemList->copyUsedCharsToIndexed(); - LLWString outtextw; - for (S32 i=0; i<(S32)getWText().size(); i++) - { - llwchar wch = getWText()[i]; - if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) - { - S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); - wch = FIRST_EMBEDDED_CHAR + index; - } - outtextw.push_back(wch); - } - std::string outtext = wstring_to_utf8str(outtextw); - return outtext; -#else - // Old version (Version 1) - mEmbeddedItemList->copyUsedCharsToIndexed(); - std::string outtext; - for (S32 i=0; i<(S32)mWText.size(); i++) - { - llwchar wch = mWText[i]; - if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) - { - S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); - wch = 0x80 | index % 128; - } - else if (wch >= 0x80) - { - wch = LL_UNKNOWN_CHAR; - } - outtext.push_back((U8)wch); - } - return outtext; -#endif -} - -std::string LLViewerTextEditor::appendTime(bool prepend_newline) -{ - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr ="[["+ LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"]] "; - - LLSD substitution; - - substitution["datetime"] = (S32) utc_time; - LLStringUtil::format (timeStr, substitution); - appendText(timeStr, prepend_newline, LLStyle::Params().color(LLColor4::grey)); - blockUndo(); - - return timeStr; -} - -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- - -llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char) -{ - if (mEmbeddedItemList->hasEmbeddedItem(ext_char)) - { - return ext_char; // already exists in my list - } - LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItemPtr(ext_char); - if (item) - { - // Add item to my list and return new llwchar associated with it - llwchar new_wc; - if (mEmbeddedItemList->insertEmbeddedItem( item, &new_wc, true )) - { - return new_wc; - } - } - return LL_UNKNOWN_CHAR; // item not found or list full -} - -void LLViewerTextEditor::onValueChange(S32 start, S32 end) -{ - updateSegments(); - updateLinkSegments(); - findEmbeddedItemSegments(start, end); -} - -void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end) -{ - LLWString text = getWText(); - - // Start with i just after the first embedded item - for(S32 idx = start; idx < end; idx++ ) - { - llwchar embedded_char = text[idx]; - if( embedded_char >= FIRST_EMBEDDED_CHAR - && embedded_char <= LAST_EMBEDDED_CHAR - && mEmbeddedItemList->hasEmbeddedItem(embedded_char) ) - { - LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char); - LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char); - insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this)); - } - } -} - -bool LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) -{ - if( pos < getLength()) - { - llwchar wc = getWText()[pos]; - LLPointer item = LLEmbeddedItems::getEmbeddedItemPtr( wc ); - if( item ) - { - bool saved = LLEmbeddedItems::getEmbeddedItemSaved( wc ); - if (saved) - { - return openEmbeddedItem(item, wc); - } - else - { - showUnsavedAlertDialog(item); - } - } - } - return false; -} - - -bool LLViewerTextEditor::openEmbeddedItem(LLPointer item, llwchar wc) -{ - - switch( item->getType() ) - { - case LLAssetType::AT_TEXTURE: - openEmbeddedTexture( item, wc ); - return true; - - case LLAssetType::AT_SOUND: - openEmbeddedSound( item, wc ); - return true; - - case LLAssetType::AT_LANDMARK: - openEmbeddedLandmark( item, wc ); - return true; - - case LLAssetType::AT_CALLINGCARD: - openEmbeddedCallingcard( item, wc ); - return true; - case LLAssetType::AT_SETTINGS: - openEmbeddedSetting(item, wc); - return true; - case LLAssetType::AT_MATERIAL: - openEmbeddedGLTFMaterial(item, wc); - return true; - case LLAssetType::AT_NOTECARD: - case LLAssetType::AT_LSL_TEXT: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_OBJECT: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - showCopyToInvDialog( item, wc ); - return true; - default: - return false; - } - -} - - -void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc ) -{ - // *NOTE: Just for embedded Texture , we should use getAssetUUID(), - // not getUUID(), because LLPreviewTexture pass in AssetUUID into - // LLPreview constructor ItemUUID parameter. - if (!item) - return; - LLPreviewTexture* preview = LLFloaterReg::showTypedInstance("preview_texture", LLSD(item->getAssetUUID()), TAKE_FOCUS_YES); - if (preview) - { - preview->setAuxItem( item ); - preview->setNotecardInfo(mNotecardInventoryID, mObjectID); - if (preview->hasString("Title")) - { - LLStringUtil::format_map_t args; - args["[NAME]"] = item->getName(); - LLUIString title = preview->getString("Title", args); - preview->setTitle(title.getString()); - } - preview->getChild("desc")->setValue(item->getDescription()); - } -} - -void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc ) -{ - // Play sound locally - LLVector3d lpos_global = gAgent.getPositionGlobal(); - const F32 SOUND_GAIN = 1.0f; - if(gAudiop) - { - gAudiop->triggerSound(item->getAssetUUID(), gAgentID, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global); - } - showCopyToInvDialog( item, wc ); -} - - -void LLViewerTextEditor::openEmbeddedLandmark( LLPointer item_ptr, llwchar wc ) -{ - if (item_ptr.isNull()) - return; - - LLLandmark* landmark = gLandmarkList.getAsset(item_ptr->getAssetUUID(), - boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item_ptr)); - if (landmark) - { - LLEmbeddedLandmarkCopied::processForeignLandmark(landmark, mObjectID, - mNotecardInventoryID, item_ptr); - } -} - -void LLViewerTextEditor::openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc ) -{ - if (item && !item->getDescription().empty()) - { - LLAvatarActions::showProfile(LLUUID(item->getDescription())); - } - else if (item && !item->getCreatorUUID().isNull()) - { - LLAvatarActions::showProfile(item->getCreatorUUID()); - } -} - -void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc) -{ - if (LLEnvironment::instance().isInventoryEnabled()) - { - showCopyToInvDialog(item, wc); - } - else - { - LLNotificationsUtil::add("NoEnvironmentSettings"); - } -} - -void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc) -{ - if (!item) - { - return; - } - - LLSD floater_key; - floater_key["objectid"] = mObjectID; - floater_key["notecardid"] = mNotecardInventoryID; - LLMaterialEditor* preview = LLFloaterReg::getTypedInstance("material_editor", floater_key); - if (preview) - { - preview->setAuxItem(item); - preview->setNotecardInfo(mNotecardInventoryID, mObjectID); - preview->openFloater(floater_key); - preview->setFocus(true); - } -} - -void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item ) -{ - LLSD payload; - payload["item_id"] = item->getUUID(); - payload["notecard_id"] = mNotecardInventoryID; - LLNotificationsUtil::add( "ConfirmNotecardSave", LLSD(), payload, LLViewerTextEditor::onNotecardDialog); -} - -// static -bool LLViewerTextEditor::onNotecardDialog(const LLSD& notification, const LLSD& response ) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if( option == 0 ) - { - LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance("preview_notecard", notification["payload"]["notecard_id"]);; - if (preview) - { - preview->saveItem(); - } - } - return false; -} - - - -void LLViewerTextEditor::showCopyToInvDialog( LLInventoryItem* item, llwchar wc ) -{ - LLSD payload; - LLUUID item_id = item->getUUID(); - payload["item_id"] = item_id; - payload["item_wc"] = LLSD::Integer(wc); - LLNotificationsUtil::add( "ConfirmItemCopy", LLSD(), payload, - boost::bind(&LLViewerTextEditor::onCopyToInvDialog, this, _1, _2)); -} - -bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if( 0 == option ) - { - llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); - LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc); - if (itemp) - copyInventory(itemp); - } - return false; -} - - - -// Returns change in number of characters in mWText -S32 LLViewerTextEditor::insertEmbeddedItem( S32 pos, LLInventoryItem* item ) -{ - return execute( new TextCmdInsertEmbeddedItem( pos, item ) ); -} - -bool LLViewerTextEditor::importStream(std::istream& str) -{ - LLNotecard nc(LLNotecard::MAX_SIZE); - bool success = nc.importStream(str); - if (success) - { - mEmbeddedItemList->clear(); - const std::vector >& items = nc.getItems(); - mEmbeddedItemList->addItems(items); - // Actually set the text - if (allowsEmbeddedItems()) - { - if (nc.getVersion() == 1) - setASCIIEmbeddedText( nc.getText() ); - else - setEmbeddedText( nc.getText() ); - } - else - { - setText( nc.getText() ); - } - } - return success; -} - -void LLViewerTextEditor::copyInventory(const LLInventoryItem* item, U32 callback_id) -{ - copy_inventory_from_notecard(LLUUID::null, // Don't specify a destination -- let the sim do that - mObjectID, - mNotecardInventoryID, - item, - callback_id); -} - -bool LLViewerTextEditor::hasEmbeddedInventory() -{ - return ! mEmbeddedItemList->empty(); -} - -//////////////////////////////////////////////////////////////////////////// - -bool LLViewerTextEditor::importBuffer( const char* buffer, S32 length ) -{ - LLMemoryStream str((U8*)buffer, length); - return importStream(str); -} - -bool LLViewerTextEditor::exportBuffer( std::string& buffer ) -{ - LLNotecard nc(LLNotecard::MAX_SIZE); - - // Get the embedded text and update the item list to just be the used items - nc.setText(getEmbeddedText()); - - // Now get the used items and copy the list to the notecard - std::vector > embedded_items; - mEmbeddedItemList->getEmbeddedItemList(embedded_items); - nc.setItems(embedded_items); - - std::stringstream out_stream; - nc.exportStream(out_stream); - - buffer = out_stream.str(); - - return true; -} - +/** + * @file llviewertexteditor.cpp + * @brief Text editor widget to let users enter a multi-line document. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewertexteditor.h" + +#include "llagent.h" +#include "llaudioengine.h" +#include "llavataractions.h" +#include "llenvironment.h" +#include "llfloaterreg.h" +#include "llfloatersidepanelcontainer.h" +#include "llfloaterworldmap.h" +#include "llfocusmgr.h" +#include "llinspecttexture.h" +#include "llinventorybridge.h" +#include "llinventorydefines.h" +#include "llinventorymodel.h" +#include "lllandmark.h" +#include "lllandmarkactions.h" +#include "lllandmarklist.h" +#include "llmaterialeditor.h" +#include "llmemorystream.h" +#include "llmenugl.h" +#include "llnotecard.h" +#include "llnotificationsutil.h" +#include "llpanelplaces.h" +#include "llpreview.h" +#include "llpreviewnotecard.h" +#include "llpreviewtexture.h" +#include "llscrollbar.h" +#include "llscrollcontainer.h" +#include "lltooldraganddrop.h" +#include "lltooltip.h" +#include "lltrans.h" +#include "lluictrlfactory.h" +#include "llviewerassettype.h" +#include "llviewercontrol.h" +#include "llviewerinventory.h" +#include "llviewertexturelist.h" +#include "llviewerwindow.h" + +static LLDefaultChildRegistry::Register r("text_editor"); + +///----------------------------------------------------------------------- +/// Class LLEmbeddedLandmarkCopied +///----------------------------------------------------------------------- +class LLEmbeddedLandmarkCopied: public LLInventoryCallback +{ +public: + + LLEmbeddedLandmarkCopied(){} + void fire(const LLUUID& inv_item) + { + showInfo(inv_item); + } + static void showInfo(const LLUUID& landmark_inv_id) + { + LLSD key; + key["type"] = "landmark"; + key["id"] = landmark_inv_id; + LLFloaterSidePanelContainer::showPanel("places", key); + } + static void processForeignLandmark(LLLandmark* landmark, + const LLUUID& object_id, const LLUUID& notecard_inventory_id, + LLPointer item_ptr) + { + LLVector3d global_pos; + landmark->getGlobalPos(global_pos); + LLViewerInventoryItem* agent_landmark = + LLLandmarkActions::findLandmarkForGlobalPos(global_pos); + + if (agent_landmark) + { + showInfo(agent_landmark->getUUID()); + } + else + { + if (item_ptr.isNull()) + { + // check to prevent a crash. See EXT-8459. + LL_WARNS() << "Passed handle contains a dead inventory item. Most likely notecard has been closed and embedded item was destroyed." << LL_ENDL; + } + else + { + LLInventoryItem* item = item_ptr.get(); + LLPointer cb = new LLEmbeddedLandmarkCopied(); + copy_inventory_from_notecard(get_folder_by_itemtype(item), + object_id, + notecard_inventory_id, + item, + gInventoryCallbacks.registerCB(cb)); + } + } + } +}; +///---------------------------------------------------------------------------- +/// Class LLEmbeddedNotecardOpener +///---------------------------------------------------------------------------- +class LLEmbeddedNotecardOpener : public LLInventoryCallback +{ + LLViewerTextEditor* mTextEditor; + +public: + LLEmbeddedNotecardOpener() + : mTextEditor(NULL) + { + } + + void setEditor(LLViewerTextEditor* e) {mTextEditor = e;} + + // override + void fire(const LLUUID& inv_item) + { + if(!mTextEditor) + { + // The parent text editor may have vanished by now. + // In that case just quit. + return; + } + + LLInventoryItem* item = gInventory.getItem(inv_item); + if(!item) + { + LL_WARNS() << "Item add reported, but not found in inventory!: " << inv_item << LL_ENDL; + } + else + { + if(!gSavedSettings.getBOOL("ShowNewInventory")) + { + LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); + } + } + } +}; + +// +// class LLEmbeddedItemSegment +// + +const S32 EMBEDDED_ITEM_LABEL_PADDING = 2; + +class LLEmbeddedItemSegment : public LLTextSegment +{ +public: + LLEmbeddedItemSegment(S32 pos, LLUIImagePtr image, LLPointer inv_item, LLTextEditor& editor) + : LLTextSegment(pos, pos + 1), + mImage(image), + mLabel(utf8str_to_wstring(inv_item->getName())), + mItem(inv_item), + mEditor(editor) + { + + mStyle = new LLStyle(LLStyle::Params().font(LLFontGL::getFontSansSerif())); + mToolTip = inv_item->getName() + '\n' + inv_item->getDescription(); + } + + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const + { + if (num_chars == 0) + { + width = 0; + height = 0; + } + else + { + width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidthF32(mLabel.c_str()); + height = llmax(mImage->getHeight(), mStyle->getFont()->getLineHeight()); + } + return false; + } + + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const + { + // always draw at beginning of line + if (line_offset == 0) + { + return 1; + } + else + { + S32 width, height; + getDimensions(mStart, 1, width, height); + if (width > num_pixels) + { + return 0; + } + else + { + return 1; + } + } + } + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) + { + LLRectf image_rect = draw_rect; + image_rect.mRight = image_rect.mLeft + mImage->getWidth(); + image_rect.mTop = image_rect.mBottom + mImage->getHeight(); + mImage->draw(LLRect(image_rect.mLeft, image_rect.mTop, image_rect.mRight, image_rect.mBottom)); + + LLColor4 color; + if (mEditor.getReadOnly()) + { + color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor"); + } + else + { + color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor"); + } + + F32 right_x; + mStyle->getFont()->render(mLabel, 0, image_rect.mRight + EMBEDDED_ITEM_LABEL_PADDING, draw_rect.mTop, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::UNDERLINE, LLFontGL::NO_SHADOW, mLabel.length(), S32_MAX, &right_x); + return right_x; + } + + /*virtual*/ bool canEdit() const { return false; } + + + /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask) + { + LLUI::getInstance()->getWindow()->setCursor(UI_CURSOR_HAND); + return true; + } + virtual bool handleToolTip(S32 x, S32 y, MASK mask ) + { + if (mItem->getThumbnailUUID().notNull()) + { + LLSD params; + params["inv_type"] = mItem->getInventoryType(); + params["thumbnail_id"] = mItem->getThumbnailUUID(); + params["asset_id"] = mItem->getAssetUUID(); + + LLToolTipMgr::instance().show(LLToolTip::Params() + .message(mToolTip) + .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) + .create_params(params)); + + return true; + } + + if (!mToolTip.empty()) + { + LLToolTipMgr::instance().show(mToolTip); + return true; + } + return false; + } + + /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; } + +private: + LLUIImagePtr mImage; + LLWString mLabel; + LLStyleSP mStyle; + std::string mToolTip; + LLPointer mItem; + LLTextEditor& mEditor; +}; + + + +//////////////////////////////////////////////////////////// +// LLEmbeddedItems +// +// Embedded items are stored as: +// * A global map of llwchar to LLInventoryItem +// ** This is unique for each item embedded in any notecard +// to support copy/paste across notecards +// * A per-notecard set of embeded llwchars for easy removal +// from the global list +// * A per-notecard vector of embedded lwchars for mapping from +// old style 0x80 + item format notechards + +class LLEmbeddedItems +{ +public: + LLEmbeddedItems(const LLViewerTextEditor* editor); + ~LLEmbeddedItems(); + void clear(); + + // return true if there are no embedded items. + bool empty(); + + bool insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new); + bool removeEmbeddedItem( llwchar ext_char ); + + bool hasEmbeddedItem(llwchar ext_char); // returns true if /this/ editor has an entry for this item + LLUIImagePtr getItemImage(llwchar ext_char) const; + + void getEmbeddedItemList( std::vector >& items ); + void addItems(const std::vector >& items); + + llwchar getEmbeddedCharFromIndex(S32 index); + + void removeUnusedChars(); + void copyUsedCharsToIndexed(); + S32 getIndexFromEmbeddedChar(llwchar wch); + + void markSaved(); + + static LLPointer getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list + static bool getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved + +private: + + struct embedded_info_t + { + LLPointer mItemPtr; + bool mSaved; + }; + typedef std::map item_map_t; + static item_map_t sEntries; + static std::stack sFreeEntries; + + std::set mEmbeddedUsedChars; // list of used llwchars + std::vector mEmbeddedIndexedChars; // index -> wchar for 0x80 + index format + const LLViewerTextEditor* mEditor; +}; + +//statics +LLEmbeddedItems::item_map_t LLEmbeddedItems::sEntries; +std::stack LLEmbeddedItems::sFreeEntries; + +LLEmbeddedItems::LLEmbeddedItems(const LLViewerTextEditor* editor) + : mEditor(editor) +{ +} + +LLEmbeddedItems::~LLEmbeddedItems() +{ + clear(); +} + +void LLEmbeddedItems::clear() +{ + // Remove entries for this editor from static list + for (std::set::iterator iter = mEmbeddedUsedChars.begin(); + iter != mEmbeddedUsedChars.end();) + { + std::set::iterator nextiter = iter++; + removeEmbeddedItem(*nextiter); + } + mEmbeddedUsedChars.clear(); + mEmbeddedIndexedChars.clear(); +} + +bool LLEmbeddedItems::empty() +{ + removeUnusedChars(); + return mEmbeddedUsedChars.empty(); +} + +// Inserts a new unique entry +bool LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_char, bool is_new) +{ + // Now insert a new one + llwchar wc_emb; + if (!sFreeEntries.empty()) + { + wc_emb = sFreeEntries.top(); + sFreeEntries.pop(); + } + else if (sEntries.empty()) + { + wc_emb = LLTextEditor::FIRST_EMBEDDED_CHAR; + } + else + { + item_map_t::iterator last = sEntries.end(); + --last; + wc_emb = last->first; + if (wc_emb >= LLTextEditor::LAST_EMBEDDED_CHAR) + { + return false; + } + ++wc_emb; + } + + sEntries[wc_emb].mItemPtr = item; + sEntries[wc_emb].mSaved = !is_new; + *ext_char = wc_emb; + mEmbeddedUsedChars.insert(wc_emb); + return true; +} + +// Removes an entry (all entries are unique) +bool LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char ) +{ + mEmbeddedUsedChars.erase(ext_char); + item_map_t::iterator iter = sEntries.find(ext_char); + if (iter != sEntries.end()) + { + sEntries.erase(ext_char); + sFreeEntries.push(ext_char); + return true; + } + return false; +} + +// static +LLPointer LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char) +{ + if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) + { + item_map_t::iterator iter = sEntries.find(ext_char); + if (iter != sEntries.end()) + { + return iter->second.mItemPtr; + } + } + return NULL; +} + +// static +bool LLEmbeddedItems::getEmbeddedItemSaved(llwchar ext_char) +{ + if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) + { + item_map_t::iterator iter = sEntries.find(ext_char); + if (iter != sEntries.end()) + { + return iter->second.mSaved; + } + } + return false; +} + +llwchar LLEmbeddedItems::getEmbeddedCharFromIndex(S32 index) +{ + if (index >= (S32)mEmbeddedIndexedChars.size()) + { + LL_WARNS() << "No item for embedded char " << index << " using LL_UNKNOWN_CHAR" << LL_ENDL; + return LL_UNKNOWN_CHAR; + } + return mEmbeddedIndexedChars[index]; +} + +void LLEmbeddedItems::removeUnusedChars() +{ + std::set used = mEmbeddedUsedChars; + const LLWString& wtext = mEditor->getWText(); + for (S32 i=0; i<(S32)wtext.size(); i++) + { + llwchar wc = wtext[i]; + if( wc >= LLTextEditor::FIRST_EMBEDDED_CHAR && wc <= LLTextEditor::LAST_EMBEDDED_CHAR ) + { + used.erase(wc); + } + } + // Remove chars not actually used + for (std::set::iterator iter = used.begin(); + iter != used.end(); ++iter) + { + removeEmbeddedItem(*iter); + } +} + +void LLEmbeddedItems::copyUsedCharsToIndexed() +{ + // Prune unused items + removeUnusedChars(); + + // Copy all used llwchars to mEmbeddedIndexedChars + mEmbeddedIndexedChars.clear(); + for (std::set::iterator iter = mEmbeddedUsedChars.begin(); + iter != mEmbeddedUsedChars.end(); ++iter) + { + mEmbeddedIndexedChars.push_back(*iter); + } +} + +S32 LLEmbeddedItems::getIndexFromEmbeddedChar(llwchar wch) +{ + S32 idx = 0; + for (std::vector::iterator iter = mEmbeddedIndexedChars.begin(); + iter != mEmbeddedIndexedChars.end(); ++iter) + { + if (wch == *iter) + break; + ++idx; + } + if (idx < (S32)mEmbeddedIndexedChars.size()) + { + return idx; + } + else + { + LL_WARNS() << "Embedded char " << wch << " not found, using 0" << LL_ENDL; + return 0; + } +} + +bool LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char) +{ + std::set::iterator iter = mEmbeddedUsedChars.find(ext_char); + if (iter != mEmbeddedUsedChars.end()) + { + return true; + } + return false; +} + + +LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const +{ + LLInventoryItem* item = getEmbeddedItemPtr(ext_char); + if (item) + { + const char* img_name = ""; + switch( item->getType() ) + { + case LLAssetType::AT_TEXTURE: + if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT) + { + img_name = "Inv_Snapshot"; + } + else + { + img_name = "Inv_Texture"; + } + + break; + case LLAssetType::AT_SOUND: img_name = "Inv_Sound"; break; + case LLAssetType::AT_CLOTHING: img_name = "Inv_Clothing"; break; + case LLAssetType::AT_OBJECT: + img_name = LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS & item->getFlags() ? + "Inv_Object_Multi" : "Inv_Object"; + break; + case LLAssetType::AT_CALLINGCARD: img_name = "Inv_CallingCard"; break; + case LLAssetType::AT_LANDMARK: img_name = "Inv_Landmark"; break; + case LLAssetType::AT_NOTECARD: img_name = "Inv_Notecard"; break; + case LLAssetType::AT_LSL_TEXT: img_name = "Inv_Script"; break; + case LLAssetType::AT_BODYPART: img_name = "Inv_Skin"; break; + case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break; + case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break; + case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break; + case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break; + case LLAssetType::AT_MATERIAL: img_name = "Inv_Material"; break; + default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981) + + } + + return LLUI::getUIImage(img_name); + } + return LLUIImagePtr(); +} + + +void LLEmbeddedItems::addItems(const std::vector >& items) +{ + for (std::vector >::const_iterator iter = items.begin(); + iter != items.end(); ++iter) + { + LLInventoryItem* item = *iter; + if (item) + { + llwchar wc; + if (!insertEmbeddedItem( item, &wc, false )) + { + break; + } + mEmbeddedIndexedChars.push_back(wc); + } + } +} + +void LLEmbeddedItems::getEmbeddedItemList( std::vector >& items ) +{ + for (std::set::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter) + { + llwchar wc = *iter; + LLPointer item = getEmbeddedItemPtr(wc); + if (item) + { + items.push_back(item); + } + } +} + +void LLEmbeddedItems::markSaved() +{ + for (std::set::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter) + { + llwchar wc = *iter; + sEntries[wc].mSaved = true; + } +} + +/////////////////////////////////////////////////////////////////// + +class LLViewerTextEditor::TextCmdInsertEmbeddedItem : public LLTextBase::TextCmd +{ +public: + TextCmdInsertEmbeddedItem( S32 pos, LLInventoryItem* item ) + : TextCmd(pos, false), + mExtCharValue(0) + { + mItem = item; + } + + virtual bool execute( LLTextBase* editor, S32* delta ) + { + LLViewerTextEditor* viewer_editor = (LLViewerTextEditor*)editor; + // Take this opportunity to remove any unused embedded items from this editor + viewer_editor->mEmbeddedItemList->removeUnusedChars(); + if(viewer_editor->mEmbeddedItemList->insertEmbeddedItem( mItem, &mExtCharValue, true ) ) + { + LLWString ws; + ws.assign(1, mExtCharValue); + *delta = insert(editor, getPosition(), ws ); + return (*delta != 0); + } + return false; + } + + virtual S32 undo( LLTextBase* editor ) + { + remove(editor, getPosition(), 1); + return getPosition(); + } + + virtual S32 redo( LLTextBase* editor ) + { + LLWString ws; + ws += mExtCharValue; + insert(editor, getPosition(), ws ); + return getPosition() + 1; + } + virtual bool hasExtCharValue( llwchar value ) const + { + return (value == mExtCharValue); + } + +private: + LLPointer mItem; + llwchar mExtCharValue; +}; + +struct LLNotecardCopyInfo +{ + LLNotecardCopyInfo(LLViewerTextEditor *ed, LLInventoryItem *item) + : mTextEd(ed) + { + mItem = item; + } + + LLViewerTextEditor* mTextEd; + // need to make this be a copy (not a * here) because it isn't stable. + // I wish we had passed LLPointers all the way down, but we didn't + LLPointer mItem; +}; + +//---------------------------------------------------------------------------- + +// +// Member functions +// +LLViewerTextEditor::LLViewerTextEditor(const LLViewerTextEditor::Params& p) +: LLTextEditor(p), + mDragItemChar(0), + mDragItemSaved(false), + mInventoryCallback(new LLEmbeddedNotecardOpener) +{ + mEmbeddedItemList = new LLEmbeddedItems(this); + mInventoryCallback->setEditor(this); +} + +LLViewerTextEditor::~LLViewerTextEditor() +{ + delete mEmbeddedItemList; + + + // The inventory callback may still be in use by gInventoryCallbackManager... + // so set its reference to this to null. + mInventoryCallback->setEditor(NULL); +} + +/////////////////////////////////////////////////////////////////// +// virtual +void LLViewerTextEditor::makePristine() +{ + mEmbeddedItemList->markSaved(); + LLTextEditor::makePristine(); +} + +void LLViewerTextEditor::onVisibilityChange( bool new_visibility ) +{ + LLUICtrl::onVisibilityChange(new_visibility); +} + +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 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 = LLTextEditor::handleHover(x, y, mask); + + if(hasMouseCapture() && mDragItem) + { + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y ); + + mScroller->autoScroll(x, y); + + if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) + { + LLToolDragAndDrop::getInstance()->beginDrag( + LLViewerAssetType::lookupDragAndDropType( mDragItem->getType() ), + mDragItem->getUUID(), + LLToolDragAndDrop::SOURCE_NOTECARD, + mPreviewID, mObjectID); + return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); + } + getWindow()->setCursor(UI_CURSOR_HAND); + handled = true; + } + + return handled; +} + + +bool LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) +{ + bool handled = false; + + 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, mDragItemChar); + } + else + { + showUnsavedAlertDialog(mDragItem); + } + } + } + mDragItem = NULL; + } + + handled = LLTextEditor::handleMouseUp(x,y,mask); + + 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) + { + if( allowsEmbeddedItems() ) + { + S32 doc_index = getDocIndexFromLocalCoord(x, y, false); + llwchar doc_char = getWText()[doc_index]; + if (mEmbeddedItemList->hasEmbeddedItem(doc_char)) + { + if( openEmbeddedItemAtPos( doc_index )) + { + deselect(); + setFocus( false ); + return true; + } + } + } + handled = LLTextEditor::handleDoubleClick(x, y, mask); + } + 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()) + { + bool supported = false; + switch( cargo_type ) + { + case DAD_SETTINGS: + { + supported = LLEnvironment::instance().isExtendedEnvironmentEnabled(); + if (!supported && tooltip_msg.empty()) + { + tooltip_msg.assign(LLTrans::getString("TooltipNotecardNotAllowedTypeDrop")); + } + break; + } + 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: + case DAD_MATERIAL: + { + supported = true; + break; + } + + default: + supported = false; + break; + } + + LLInventoryItem *item = (LLInventoryItem *)cargo_data; + if (item && allowsEmbeddedItems() && supported) + { + 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()) + { + tooltip_msg.assign(LLTrans::getString("TooltipNotecardOwnerRestrictedDrop")); + } + } + } + else + { + *accept = ACCEPT_NO; + } + } + else + { + // Not enabled + *accept = ACCEPT_NO; + } + + handled = true; + LL_DEBUGS("UserInput") << "dragAndDrop handled by LLViewerTextEditor " << getName() << LL_ENDL; + + return handled; +} + +void LLViewerTextEditor::setASCIIEmbeddedText(const std::string& instr) +{ + LLWString wtext; + const U8* buffer = (U8*)(instr.c_str()); + while (*buffer) + { + llwchar wch; + U8 c = *buffer++; + if (c >= 0x80) + { + S32 index = (S32)(c - 0x80); + wch = mEmbeddedItemList->getEmbeddedCharFromIndex(index); + } + else + { + wch = (llwchar)c; + } + wtext.push_back(wch); + } + setWText(wtext); +} + +void LLViewerTextEditor::setEmbeddedText(const std::string& instr) +{ + LLWString wtext = utf8str_to_wstring(instr); + for (S32 i=0; i<(S32)wtext.size(); i++) + { + llwchar wch = wtext[i]; + if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) + { + S32 index = wch - FIRST_EMBEDDED_CHAR; + wtext[i] = mEmbeddedItemList->getEmbeddedCharFromIndex(index); + } + } + setWText(wtext); +} + +std::string LLViewerTextEditor::getEmbeddedText() +{ +#if 1 + // New version (Version 2) + mEmbeddedItemList->copyUsedCharsToIndexed(); + LLWString outtextw; + for (S32 i=0; i<(S32)getWText().size(); i++) + { + llwchar wch = getWText()[i]; + if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) + { + S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); + wch = FIRST_EMBEDDED_CHAR + index; + } + outtextw.push_back(wch); + } + std::string outtext = wstring_to_utf8str(outtextw); + return outtext; +#else + // Old version (Version 1) + mEmbeddedItemList->copyUsedCharsToIndexed(); + std::string outtext; + for (S32 i=0; i<(S32)mWText.size(); i++) + { + llwchar wch = mWText[i]; + if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) + { + S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); + wch = 0x80 | index % 128; + } + else if (wch >= 0x80) + { + wch = LL_UNKNOWN_CHAR; + } + outtext.push_back((U8)wch); + } + return outtext; +#endif +} + +std::string LLViewerTextEditor::appendTime(bool prepend_newline) +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="[["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"]] "; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + appendText(timeStr, prepend_newline, LLStyle::Params().color(LLColor4::grey)); + blockUndo(); + + return timeStr; +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char) +{ + if (mEmbeddedItemList->hasEmbeddedItem(ext_char)) + { + return ext_char; // already exists in my list + } + LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItemPtr(ext_char); + if (item) + { + // Add item to my list and return new llwchar associated with it + llwchar new_wc; + if (mEmbeddedItemList->insertEmbeddedItem( item, &new_wc, true )) + { + return new_wc; + } + } + return LL_UNKNOWN_CHAR; // item not found or list full +} + +void LLViewerTextEditor::onValueChange(S32 start, S32 end) +{ + updateSegments(); + updateLinkSegments(); + findEmbeddedItemSegments(start, end); +} + +void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end) +{ + LLWString text = getWText(); + + // Start with i just after the first embedded item + for(S32 idx = start; idx < end; idx++ ) + { + llwchar embedded_char = text[idx]; + if( embedded_char >= FIRST_EMBEDDED_CHAR + && embedded_char <= LAST_EMBEDDED_CHAR + && mEmbeddedItemList->hasEmbeddedItem(embedded_char) ) + { + LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char); + LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char); + insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this)); + } + } +} + +bool LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) +{ + if( pos < getLength()) + { + llwchar wc = getWText()[pos]; + LLPointer item = LLEmbeddedItems::getEmbeddedItemPtr( wc ); + if( item ) + { + bool saved = LLEmbeddedItems::getEmbeddedItemSaved( wc ); + if (saved) + { + return openEmbeddedItem(item, wc); + } + else + { + showUnsavedAlertDialog(item); + } + } + } + return false; +} + + +bool LLViewerTextEditor::openEmbeddedItem(LLPointer item, llwchar wc) +{ + + switch( item->getType() ) + { + case LLAssetType::AT_TEXTURE: + openEmbeddedTexture( item, wc ); + return true; + + case LLAssetType::AT_SOUND: + openEmbeddedSound( item, wc ); + return true; + + case LLAssetType::AT_LANDMARK: + openEmbeddedLandmark( item, wc ); + return true; + + case LLAssetType::AT_CALLINGCARD: + openEmbeddedCallingcard( item, wc ); + return true; + case LLAssetType::AT_SETTINGS: + openEmbeddedSetting(item, wc); + return true; + case LLAssetType::AT_MATERIAL: + openEmbeddedGLTFMaterial(item, wc); + return true; + case LLAssetType::AT_NOTECARD: + case LLAssetType::AT_LSL_TEXT: + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_OBJECT: + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_ANIMATION: + case LLAssetType::AT_GESTURE: + showCopyToInvDialog( item, wc ); + return true; + default: + return false; + } + +} + + +void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc ) +{ + // *NOTE: Just for embedded Texture , we should use getAssetUUID(), + // not getUUID(), because LLPreviewTexture pass in AssetUUID into + // LLPreview constructor ItemUUID parameter. + if (!item) + return; + LLPreviewTexture* preview = LLFloaterReg::showTypedInstance("preview_texture", LLSD(item->getAssetUUID()), TAKE_FOCUS_YES); + if (preview) + { + preview->setAuxItem( item ); + preview->setNotecardInfo(mNotecardInventoryID, mObjectID); + if (preview->hasString("Title")) + { + LLStringUtil::format_map_t args; + args["[NAME]"] = item->getName(); + LLUIString title = preview->getString("Title", args); + preview->setTitle(title.getString()); + } + preview->getChild("desc")->setValue(item->getDescription()); + } +} + +void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc ) +{ + // Play sound locally + LLVector3d lpos_global = gAgent.getPositionGlobal(); + const F32 SOUND_GAIN = 1.0f; + if(gAudiop) + { + gAudiop->triggerSound(item->getAssetUUID(), gAgentID, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global); + } + showCopyToInvDialog( item, wc ); +} + + +void LLViewerTextEditor::openEmbeddedLandmark( LLPointer item_ptr, llwchar wc ) +{ + if (item_ptr.isNull()) + return; + + LLLandmark* landmark = gLandmarkList.getAsset(item_ptr->getAssetUUID(), + boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item_ptr)); + if (landmark) + { + LLEmbeddedLandmarkCopied::processForeignLandmark(landmark, mObjectID, + mNotecardInventoryID, item_ptr); + } +} + +void LLViewerTextEditor::openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc ) +{ + if (item && !item->getDescription().empty()) + { + LLAvatarActions::showProfile(LLUUID(item->getDescription())); + } + else if (item && !item->getCreatorUUID().isNull()) + { + LLAvatarActions::showProfile(item->getCreatorUUID()); + } +} + +void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc) +{ + if (LLEnvironment::instance().isInventoryEnabled()) + { + showCopyToInvDialog(item, wc); + } + else + { + LLNotificationsUtil::add("NoEnvironmentSettings"); + } +} + +void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc) +{ + if (!item) + { + return; + } + + LLSD floater_key; + floater_key["objectid"] = mObjectID; + floater_key["notecardid"] = mNotecardInventoryID; + LLMaterialEditor* preview = LLFloaterReg::getTypedInstance("material_editor", floater_key); + if (preview) + { + preview->setAuxItem(item); + preview->setNotecardInfo(mNotecardInventoryID, mObjectID); + preview->openFloater(floater_key); + preview->setFocus(true); + } +} + +void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item ) +{ + LLSD payload; + payload["item_id"] = item->getUUID(); + payload["notecard_id"] = mNotecardInventoryID; + LLNotificationsUtil::add( "ConfirmNotecardSave", LLSD(), payload, LLViewerTextEditor::onNotecardDialog); +} + +// static +bool LLViewerTextEditor::onNotecardDialog(const LLSD& notification, const LLSD& response ) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if( option == 0 ) + { + LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance("preview_notecard", notification["payload"]["notecard_id"]);; + if (preview) + { + preview->saveItem(); + } + } + return false; +} + + + +void LLViewerTextEditor::showCopyToInvDialog( LLInventoryItem* item, llwchar wc ) +{ + LLSD payload; + LLUUID item_id = item->getUUID(); + payload["item_id"] = item_id; + payload["item_wc"] = LLSD::Integer(wc); + LLNotificationsUtil::add( "ConfirmItemCopy", LLSD(), payload, + boost::bind(&LLViewerTextEditor::onCopyToInvDialog, this, _1, _2)); +} + +bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if( 0 == option ) + { + llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); + LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc); + if (itemp) + copyInventory(itemp); + } + return false; +} + + + +// Returns change in number of characters in mWText +S32 LLViewerTextEditor::insertEmbeddedItem( S32 pos, LLInventoryItem* item ) +{ + return execute( new TextCmdInsertEmbeddedItem( pos, item ) ); +} + +bool LLViewerTextEditor::importStream(std::istream& str) +{ + LLNotecard nc(LLNotecard::MAX_SIZE); + bool success = nc.importStream(str); + if (success) + { + mEmbeddedItemList->clear(); + const std::vector >& items = nc.getItems(); + mEmbeddedItemList->addItems(items); + // Actually set the text + if (allowsEmbeddedItems()) + { + if (nc.getVersion() == 1) + setASCIIEmbeddedText( nc.getText() ); + else + setEmbeddedText( nc.getText() ); + } + else + { + setText( nc.getText() ); + } + } + return success; +} + +void LLViewerTextEditor::copyInventory(const LLInventoryItem* item, U32 callback_id) +{ + copy_inventory_from_notecard(LLUUID::null, // Don't specify a destination -- let the sim do that + mObjectID, + mNotecardInventoryID, + item, + callback_id); +} + +bool LLViewerTextEditor::hasEmbeddedInventory() +{ + return ! mEmbeddedItemList->empty(); +} + +//////////////////////////////////////////////////////////////////////////// + +bool LLViewerTextEditor::importBuffer( const char* buffer, S32 length ) +{ + LLMemoryStream str((U8*)buffer, length); + return importStream(str); +} + +bool LLViewerTextEditor::exportBuffer( std::string& buffer ) +{ + LLNotecard nc(LLNotecard::MAX_SIZE); + + // Get the embedded text and update the item list to just be the used items + nc.setText(getEmbeddedText()); + + // Now get the used items and copy the list to the notecard + std::vector > embedded_items; + mEmbeddedItemList->getEmbeddedItemList(embedded_items); + nc.setItems(embedded_items); + + std::stringstream out_stream; + nc.exportStream(out_stream); + + buffer = out_stream.str(); + + return true; +} + -- cgit v1.2.3 From b42f9d836b4c0f7fbd4bdae1734021e2a09fdbe8 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 1 Jun 2024 15:49:26 +0200 Subject: Re-enable a lot of compiler warnings for MSVC and address the C4267 "possible loss of precision" warnings --- indra/newview/llviewertexteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llviewertexteditor.cpp') diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 82d0caecb5..0ab0265586 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -233,7 +233,7 @@ public: } F32 right_x; - mStyle->getFont()->render(mLabel, 0, image_rect.mRight + EMBEDDED_ITEM_LABEL_PADDING, draw_rect.mTop, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::UNDERLINE, LLFontGL::NO_SHADOW, mLabel.length(), S32_MAX, &right_x); + mStyle->getFont()->render(mLabel, 0, image_rect.mRight + EMBEDDED_ITEM_LABEL_PADDING, draw_rect.mTop, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::UNDERLINE, LLFontGL::NO_SHADOW, static_cast(mLabel.length()), S32_MAX, &right_x); return right_x; } -- cgit v1.2.3