Merge from v2 trunk.
commit
9e0920df2c
|
|
@ -76,11 +76,16 @@ public:
|
|||
return dictionary_iter->first;
|
||||
}
|
||||
}
|
||||
llassert(false);
|
||||
return Index(-1);
|
||||
return notFound();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Index notFound() const
|
||||
{
|
||||
// default is to assert
|
||||
llassert(false);
|
||||
return Index(-1);
|
||||
}
|
||||
void addEntry(Index index, Entry *entry)
|
||||
{
|
||||
if (lookup(index))
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
|
|||
#define SHOW_ASSERT
|
||||
#else // _DEBUG
|
||||
|
||||
#ifdef LL_RELEASE_WITH_DEBUG_INFO
|
||||
#define SHOW_ASSERT
|
||||
#endif // LL_RELEASE_WITH_DEBUG_INFO
|
||||
|
||||
#ifdef RELEASE_SHOW_DEBUG
|
||||
#define SHOW_DEBUG
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -59,6 +59,11 @@ class LLFolderDictionary : public LLSingleton<LLFolderDictionary>,
|
|||
{
|
||||
public:
|
||||
LLFolderDictionary();
|
||||
protected:
|
||||
virtual LLFolderType::EType notFound() const
|
||||
{
|
||||
return LLFolderType::FT_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
LLFolderDictionary::LLFolderDictionary()
|
||||
|
|
|
|||
|
|
@ -668,6 +668,12 @@ void LLImageRaw::fill( const LLColor4U& color )
|
|||
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
|
||||
void LLImageRaw::copy(LLImageRaw* src)
|
||||
{
|
||||
if (!src)
|
||||
{
|
||||
llwarns << "LLImageRaw::copy called with a null src pointer" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
|
||||
|
|
|
|||
|
|
@ -89,6 +89,10 @@ S32 gCurlMultiCount = 0;
|
|||
std::vector<LLMutex*> LLCurl::sSSLMutex;
|
||||
std::string LLCurl::sCAPath;
|
||||
std::string LLCurl::sCAFile;
|
||||
// Verify SSL certificates by default (matches libcurl default). The ability
|
||||
// to alter this flag is only to allow us to suppress verification if it's
|
||||
// broken for some reason.
|
||||
bool LLCurl::sSSLVerify = true;
|
||||
|
||||
//static
|
||||
void LLCurl::setCAPath(const std::string& path)
|
||||
|
|
@ -102,6 +106,18 @@ void LLCurl::setCAFile(const std::string& file)
|
|||
sCAFile = file;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCurl::setSSLVerify(bool verify)
|
||||
{
|
||||
sSSLVerify = verify;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLCurl::getSSLVerify()
|
||||
{
|
||||
return sSSLVerify;
|
||||
}
|
||||
|
||||
//static
|
||||
std::string LLCurl::getVersionString()
|
||||
{
|
||||
|
|
@ -465,7 +481,8 @@ void LLCurl::Easy::prepRequest(const std::string& url,
|
|||
setErrorBuffer();
|
||||
setCA();
|
||||
|
||||
setopt(CURLOPT_SSL_VERIFYPEER, true);
|
||||
setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
|
||||
setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify()? 2 : 0);
|
||||
setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
|
||||
|
||||
setoptString(CURLOPT_URL, url);
|
||||
|
|
@ -1044,4 +1061,3 @@ void LLCurl::cleanupClass()
|
|||
#endif
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,16 @@ public:
|
|||
*/
|
||||
static const std::string& getCAPath() { return sCAPath; }
|
||||
|
||||
/**
|
||||
* @ brief Set flag controlling whether to verify HTTPS certs.
|
||||
*/
|
||||
static void setSSLVerify(bool verify);
|
||||
|
||||
/**
|
||||
* @ brief Get flag controlling whether to verify HTTPS certs.
|
||||
*/
|
||||
static bool getSSLVerify();
|
||||
|
||||
/**
|
||||
* @ brief Initialize LLCurl class
|
||||
*/
|
||||
|
|
@ -182,6 +192,7 @@ public:
|
|||
private:
|
||||
static std::string sCAPath;
|
||||
static std::string sCAFile;
|
||||
static bool sSSLVerify;
|
||||
};
|
||||
|
||||
namespace boost
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ static void request(
|
|||
LLPumpIO::chain_t chain;
|
||||
|
||||
LLURLRequest* req = new LLURLRequest(method, url);
|
||||
req->checkRootCertificate(true);
|
||||
req->checkRootCertificate(LLCurl::getSSLVerify());
|
||||
|
||||
|
||||
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ void LLURLRequest::setBodyLimit(U32 size)
|
|||
void LLURLRequest::checkRootCertificate(bool check)
|
||||
{
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, (check? 2 : 0));
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1022,6 +1022,20 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a
|
|||
}
|
||||
}
|
||||
|
||||
void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment, const LLColor4& color)
|
||||
{
|
||||
if (image_id.isNull())
|
||||
{
|
||||
mImageOverlay = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mImageOverlay = LLUI::getUIImageByID(image_id);
|
||||
mImageOverlayAlignment = alignment;
|
||||
mImageOverlayColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
void LLButton::onMouseCaptureLost()
|
||||
{
|
||||
resetMouseDownTimer();
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ public:
|
|||
void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
|
||||
|
||||
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
|
||||
void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
|
||||
LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
|
||||
|
||||
void autoResize(); // resize with label of current btn state
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
|
|||
// virtual
|
||||
void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
|
||||
{
|
||||
gFocusMgr.setTopCtrl(NULL);
|
||||
setVisible(TRUE);
|
||||
setFrontmost(take_focus);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1507,6 +1507,37 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
|
|||
}
|
||||
}
|
||||
|
||||
void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color)
|
||||
{
|
||||
static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
|
||||
LLTabTuple* tuple = getTabByPanel(child);
|
||||
if( tuple )
|
||||
{
|
||||
tuple->mButton->setImageOverlay(image_id, LLFontGL::RIGHT, color);
|
||||
|
||||
if (!mIsVertical)
|
||||
{
|
||||
// remove current width from total tab strip width
|
||||
mTotalTabWidth -= tuple->mButton->getRect().getWidth();
|
||||
|
||||
S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
|
||||
tuple->mButton->getImageOverlay()->getImage()->getWidth(0) :
|
||||
0;
|
||||
|
||||
tuple->mPadding = image_overlay_width;
|
||||
|
||||
tuple->mButton->setRightHPad(6);
|
||||
tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
|
||||
tuple->mButton->getRect().getHeight());
|
||||
// add back in button width to total tab strip width
|
||||
mTotalTabWidth += tuple->mButton->getRect().getWidth();
|
||||
|
||||
// tabs have changed size, might need to scroll to see current tab
|
||||
updateMaxScrollPos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTabContainer::setTitle(const std::string& title)
|
||||
{
|
||||
if (mTitleBox)
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ public:
|
|||
BOOL getTabPanelFlashing(LLPanel* child);
|
||||
void setTabPanelFlashing(LLPanel* child, BOOL state);
|
||||
void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
|
||||
void setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white);
|
||||
void setTitle( const std::string& title );
|
||||
const std::string getPanelTitle(S32 index);
|
||||
|
||||
|
|
|
|||
|
|
@ -268,8 +268,8 @@ ATTACH_LHIP Passed to llAttachToAvatar to attach task to left hip
|
|||
ATTACH_LULEG Passed to llAttachToAvatar to attach task to left upper leg
|
||||
ATTACH_LLLEG Passed to llAttachToAvatar to attach task to left lower leg
|
||||
ATTACH_BELLY Passed to llAttachToAvatar to attach task to belly
|
||||
ATTACH_RPEC Passed to llAttachToAvatar to attach task to right pectoral
|
||||
ATTACH_LPEC Passed to llAttachToAvatar to attach task to left pectoral
|
||||
ATTACH_LEFT_PEC Passed to llAttachToAvatar to attach task to left pectoral
|
||||
ATTACH_RIGHT_PEC Passed to llAttachToAvatar to attach task to right pectoral
|
||||
|
||||
LAND_LEVEL Passed to llModifyLand to level terrain
|
||||
LAND_RAISE Passed to llModifyLand to raise terrain
|
||||
|
|
|
|||
|
|
@ -1145,17 +1145,6 @@
|
|||
<key>Value</key>
|
||||
<integer>5</integer>
|
||||
</map>
|
||||
<key>CallFloaterMaxItems</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max number of visible participants in voice controls window</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>CameraAngle</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -3629,7 +3618,7 @@
|
|||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>http://int.searchwww-phx0.damballah.lindenlab.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]</string>
|
||||
<string>http://search.secondlife.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]</string>
|
||||
</map>
|
||||
<key>HighResSnapshot</key>
|
||||
<map>
|
||||
|
|
@ -10104,6 +10093,18 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SpeakerParticipantRemoveDelay</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Timeout to remove participants who is not in channel before removed from list of active speakers (text/voice chat)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>10.0</real>
|
||||
</map>
|
||||
|
||||
<key>UseStartScreen</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -274,6 +274,7 @@ private:
|
|||
|
||||
struct LLFoundData
|
||||
{
|
||||
LLFoundData() {}
|
||||
LLFoundData(const LLUUID& item_id,
|
||||
const LLUUID& asset_id,
|
||||
const std::string& name,
|
||||
|
|
@ -292,20 +293,94 @@ struct LLFoundData
|
|||
};
|
||||
|
||||
|
||||
struct LLWearableHoldingPattern
|
||||
class LLWearableHoldingPattern
|
||||
{
|
||||
LLWearableHoldingPattern() : mResolved(0) {}
|
||||
~LLWearableHoldingPattern()
|
||||
{
|
||||
for_each(mFoundList.begin(), mFoundList.end(), DeletePointer());
|
||||
mFoundList.clear();
|
||||
}
|
||||
typedef std::list<LLFoundData*> found_list_t;
|
||||
public:
|
||||
LLWearableHoldingPattern();
|
||||
~LLWearableHoldingPattern();
|
||||
|
||||
bool pollCompletion();
|
||||
bool isDone();
|
||||
bool isTimedOut();
|
||||
|
||||
typedef std::list<LLFoundData> found_list_t;
|
||||
found_list_t mFoundList;
|
||||
LLInventoryModel::item_array_t mObjItems;
|
||||
LLInventoryModel::item_array_t mGestItems;
|
||||
S32 mResolved;
|
||||
bool append;
|
||||
LLTimer mWaitTime;
|
||||
};
|
||||
|
||||
LLWearableHoldingPattern::LLWearableHoldingPattern():
|
||||
mResolved(0)
|
||||
{
|
||||
}
|
||||
|
||||
LLWearableHoldingPattern::~LLWearableHoldingPattern()
|
||||
{
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::isDone()
|
||||
{
|
||||
if (mResolved >= (S32)mFoundList.size())
|
||||
return true; // have everything we were waiting for
|
||||
else if (isTimedOut())
|
||||
{
|
||||
llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::isTimedOut()
|
||||
{
|
||||
static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
|
||||
return mWaitTime.getElapsedTimeF32() > max_wait_time;
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::pollCompletion()
|
||||
{
|
||||
bool done = isDone();
|
||||
llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
|
||||
if (done)
|
||||
{
|
||||
// Activate all gestures in this folder
|
||||
if (mGestItems.count() > 0)
|
||||
{
|
||||
llinfos << "Activating " << mGestItems.count() << " gestures" << llendl;
|
||||
|
||||
LLGestureManager::instance().activateGestures(mGestItems);
|
||||
|
||||
// Update the inventory item labels to reflect the fact
|
||||
// they are active.
|
||||
LLViewerInventoryCategory* catp =
|
||||
gInventory.getCategory(LLAppearanceManager::instance().getCOF());
|
||||
|
||||
if (catp)
|
||||
{
|
||||
gInventory.updateCategory(catp);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
// Update wearables.
|
||||
llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl;
|
||||
LLAppearanceManager::instance().updateAgentWearables(this, false);
|
||||
|
||||
// Update attachments to match those requested.
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
if( avatar )
|
||||
{
|
||||
llinfos << "Updating " << mObjItems.count() << " attachments" << llendl;
|
||||
LLAgentWearables::userUpdateAttachments(mObjItems);
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
|
||||
{
|
||||
LLInventoryModel::item_array_t new_items;
|
||||
|
|
@ -336,29 +411,24 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
|
|||
static void onWearableAssetFetch(LLWearable* wearable, void* data)
|
||||
{
|
||||
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
|
||||
bool append = holder->append;
|
||||
|
||||
if(wearable)
|
||||
{
|
||||
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
|
||||
iter != holder->mFoundList.end(); ++iter)
|
||||
{
|
||||
LLFoundData* data = *iter;
|
||||
if(wearable->getAssetID() == data->mAssetID)
|
||||
LLFoundData& data = *iter;
|
||||
if(wearable->getAssetID() == data.mAssetID)
|
||||
{
|
||||
data->mWearable = wearable;
|
||||
data.mWearable = wearable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
holder->mResolved += 1;
|
||||
if(holder->mResolved >= (S32)holder->mFoundList.size())
|
||||
{
|
||||
LLAppearanceManager::instance().updateAgentWearables(holder, append);
|
||||
}
|
||||
}
|
||||
|
||||
LLUUID LLAppearanceManager::getCOF()
|
||||
const LLUUID LLAppearanceManager::getCOF() const
|
||||
{
|
||||
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
|
||||
}
|
||||
|
|
@ -662,12 +732,12 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
|
|||
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
|
||||
iter != holder->mFoundList.end(); ++iter)
|
||||
{
|
||||
LLFoundData* data = *iter;
|
||||
LLWearable* wearable = data->mWearable;
|
||||
LLFoundData& data = *iter;
|
||||
LLWearable* wearable = data.mWearable;
|
||||
if( wearable && ((S32)wearable->getType() == i) )
|
||||
{
|
||||
LLViewerInventoryItem* item;
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID);
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
|
||||
if( item && (item->getAssetUUID() == wearable->getAssetID()) )
|
||||
{
|
||||
items.put(item);
|
||||
|
|
@ -683,8 +753,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
|
|||
gAgentWearables.setWearableOutfit(items, wearables, !append);
|
||||
}
|
||||
|
||||
delete holder;
|
||||
|
||||
// dec_busy_count();
|
||||
}
|
||||
|
||||
|
|
@ -706,86 +774,66 @@ void LLAppearanceManager::updateAppearanceFromCOF()
|
|||
LLInventoryModel::item_array_t gest_items;
|
||||
getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items, follow_folder_links);
|
||||
|
||||
if( !wear_items.count() && !obj_items.count() && !gest_items.count())
|
||||
if(!wear_items.count())
|
||||
{
|
||||
LLNotificationsUtil::add("CouldNotPutOnOutfit");
|
||||
return;
|
||||
}
|
||||
|
||||
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
|
||||
|
||||
holder->mObjItems = obj_items;
|
||||
holder->mGestItems = gest_items;
|
||||
|
||||
// Processes that take time should show the busy cursor
|
||||
//inc_busy_count(); // BAP this is currently a no-op in llinventorybridge.cpp - do we need it?
|
||||
|
||||
// Activate all gestures in this folder
|
||||
if (gest_items.count() > 0)
|
||||
// Note: can't do normal iteration, because if all the
|
||||
// wearables can be resolved immediately, then the
|
||||
// callback will be called (and this object deleted)
|
||||
// before the final getNextData().
|
||||
LLDynamicArray<LLFoundData> found_container;
|
||||
for(S32 i = 0; i < wear_items.count(); ++i)
|
||||
{
|
||||
llinfos << "Activating " << gest_items.count() << " gestures" << llendl;
|
||||
|
||||
LLGestureManager::instance().activateGestures(gest_items);
|
||||
|
||||
// Update the inventory item labels to reflect the fact
|
||||
// they are active.
|
||||
LLViewerInventoryCategory* catp = gInventory.getCategory(current_outfit_id);
|
||||
if (catp)
|
||||
LLViewerInventoryItem *item = wear_items.get(i);
|
||||
LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
|
||||
if (item && linked_item)
|
||||
{
|
||||
gInventory.updateCategory(catp);
|
||||
gInventory.notifyObservers();
|
||||
LLFoundData found(linked_item->getUUID(),
|
||||
linked_item->getAssetUUID(),
|
||||
linked_item->getName(),
|
||||
linked_item->getType());
|
||||
holder->mFoundList.push_front(found);
|
||||
found_container.put(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!item)
|
||||
{
|
||||
llwarns << "attempt to wear a null item " << llendl;
|
||||
}
|
||||
else if (!linked_item)
|
||||
{
|
||||
llwarns << "attempt to wear a broken link " << item->getName() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(wear_items.count() > 0)
|
||||
for(S32 i = 0; i < found_container.count(); ++i)
|
||||
{
|
||||
// Note: can't do normal iteration, because if all the
|
||||
// wearables can be resolved immediately, then the
|
||||
// callback will be called (and this object deleted)
|
||||
// before the final getNextData().
|
||||
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
|
||||
LLFoundData* found;
|
||||
LLDynamicArray<LLFoundData*> found_container;
|
||||
for(S32 i = 0; i < wear_items.count(); ++i)
|
||||
{
|
||||
LLViewerInventoryItem *item = wear_items.get(i);
|
||||
LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
|
||||
if (item && linked_item)
|
||||
{
|
||||
found = new LLFoundData(linked_item->getUUID(),
|
||||
linked_item->getAssetUUID(),
|
||||
linked_item->getName(),
|
||||
linked_item->getType());
|
||||
holder->mFoundList.push_front(found);
|
||||
found_container.put(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!item)
|
||||
{
|
||||
llwarns << "attempt to wear a null item " << llendl;
|
||||
}
|
||||
else if (!linked_item)
|
||||
{
|
||||
llwarns << "attempt to wear a broken link " << item->getName() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(S32 i = 0; i < found_container.count(); ++i)
|
||||
{
|
||||
holder->append = false;
|
||||
found = found_container.get(i);
|
||||
LLFoundData& found = found_container.get(i);
|
||||
|
||||
// Fetch the wearables about to be worn.
|
||||
LLWearableList::instance().getAsset(found->mAssetID,
|
||||
found->mName,
|
||||
found->mAssetType,
|
||||
onWearableAssetFetch,
|
||||
(void*)holder);
|
||||
}
|
||||
// Fetch the wearables about to be worn.
|
||||
LLWearableList::instance().getAsset(found.mAssetID,
|
||||
found.mName,
|
||||
found.mAssetType,
|
||||
onWearableAssetFetch,
|
||||
(void*)holder);
|
||||
|
||||
}
|
||||
|
||||
// Update attachments to match those requested.
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
if( avatar )
|
||||
if (!holder->pollCompletion())
|
||||
{
|
||||
LLAgentWearables::userUpdateAttachments(obj_items);
|
||||
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLAppearanceManager::getDescendentsOfAssetType(const LLUUID& category,
|
||||
|
|
@ -1263,3 +1311,23 @@ void LLAppearanceManager::linkRegisteredAttachments()
|
|||
}
|
||||
mRegisteredAttachments.clear();
|
||||
}
|
||||
|
||||
BOOL LLAppearanceManager::getIsInCOF(const LLUUID& obj_id) const
|
||||
{
|
||||
return gInventory.isObjectDescendentOf(obj_id, getCOF());
|
||||
}
|
||||
|
||||
BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const
|
||||
{
|
||||
if (!getIsInCOF(obj_id)) return FALSE;
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (!obj) return FALSE;
|
||||
|
||||
// Can't delete bodyparts, since this would be equivalent to removing the item.
|
||||
if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE;
|
||||
|
||||
// Can't delete the folder link, since this is saved for bookkeeping.
|
||||
if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include "llcallbacklist.h"
|
||||
|
||||
class LLWearable;
|
||||
struct LLWearableHoldingPattern;
|
||||
class LLWearableHoldingPattern;
|
||||
|
||||
class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
|
||||
{
|
||||
|
|
@ -59,7 +59,7 @@ public:
|
|||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Find the Current Outfit folder.
|
||||
LLUUID getCOF();
|
||||
const LLUUID getCOF() const;
|
||||
|
||||
// Finds the folder link to the currently worn outfit
|
||||
const LLViewerInventoryItem *getBaseOutfitLink();
|
||||
|
|
@ -132,6 +132,14 @@ private:
|
|||
std::set<LLUUID> mRegisteredAttachments;
|
||||
bool mAttachmentInvLinkEnabled;
|
||||
bool mOutfitIsDirty;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Item-specific convenience functions
|
||||
public:
|
||||
// Is this in the COF?
|
||||
BOOL getIsInCOF(const LLUUID& obj_id) const;
|
||||
// Is this in the COF and can the user delete it from the COF?
|
||||
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
|
||||
};
|
||||
|
||||
#define SUPPORT_ENSEMBLES 0
|
||||
|
|
@ -168,4 +176,40 @@ void doOnIdle(T callable)
|
|||
gIdleCallbacks.addFunction(&OnIdleCallback<T>::onIdle,cb_functor);
|
||||
}
|
||||
|
||||
// Shim class and template function to allow arbitrary boost::bind
|
||||
// expressions to be run as recurring idle callbacks.
|
||||
template <typename T>
|
||||
class OnIdleCallbackRepeating
|
||||
{
|
||||
public:
|
||||
OnIdleCallbackRepeating(T callable):
|
||||
mCallable(callable)
|
||||
{
|
||||
}
|
||||
// Will keep getting called until the callable returns false.
|
||||
static void onIdle(void *data)
|
||||
{
|
||||
OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data);
|
||||
bool done = self->call();
|
||||
if (done)
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(onIdle, data);
|
||||
delete self;
|
||||
}
|
||||
}
|
||||
bool call()
|
||||
{
|
||||
return mCallable();
|
||||
}
|
||||
private:
|
||||
T mCallable;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void doOnIdleRepeating(T callable)
|
||||
{
|
||||
OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable);
|
||||
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -930,7 +930,6 @@ bool LLAppViewer::mainLoop()
|
|||
{
|
||||
LLMemType mt1(LLMemType::MTYPE_MAIN);
|
||||
mMainloopTimeout = new LLWatchdogTimeout();
|
||||
// *FIX:Mani - Make this a setting, once new settings exist in this branch.
|
||||
|
||||
//-------------------------------------------
|
||||
// Run main loop until time to quit
|
||||
|
|
@ -940,12 +939,13 @@ bool LLAppViewer::mainLoop()
|
|||
gServicePump = new LLPumpIO(gAPRPoolp);
|
||||
LLHTTPClient::setPump(*gServicePump);
|
||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
||||
LLCurl::setSSLVerify(! gSavedSettings.getBOOL("NoVerifySSLCert"));
|
||||
|
||||
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
|
||||
|
||||
LLVoiceChannel::initClass();
|
||||
LLVoiceClient::init(gServicePump);
|
||||
|
||||
|
||||
LLTimer frameTimer,idleTimer;
|
||||
LLTimer debugTime;
|
||||
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ void LLBottomTray::setVisible(BOOL visible)
|
|||
|
||||
// Chat bar and gesture button are shown even in mouselook mode.
|
||||
// But the move, camera and snapshot buttons shouldn't be displayed. See EXT-3988.
|
||||
if ("chat_bar" == name || "gesture_panel" == name)
|
||||
if ("chat_bar" == name || "gesture_panel" == name || (visibility && ("movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name)))
|
||||
continue;
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@
|
|||
#include "lltransientfloatermgr.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llvoicechannel.h"
|
||||
#include "lllayoutstack.h"
|
||||
|
||||
static void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids);
|
||||
void reshape_floater(LLCallFloater* floater, S32 delta_height);
|
||||
|
||||
class LLNonAvatarCaller : public LLAvatarListItem
|
||||
{
|
||||
|
|
@ -93,22 +93,6 @@ static void* create_non_avatar_caller(void*)
|
|||
return new LLNonAvatarCaller;
|
||||
}
|
||||
|
||||
LLCallFloater::LLAvatarListItemRemoveTimer::LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id)
|
||||
: LLEventTimer(period)
|
||||
, mRemoveCallback(remove_cb)
|
||||
, mSpeakerId(speaker_id)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick()
|
||||
{
|
||||
if (mRemoveCallback)
|
||||
{
|
||||
mRemoveCallback(mSpeakerId);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLVoiceChannel* LLCallFloater::sCurrentVoiceCanel = NULL;
|
||||
|
||||
LLCallFloater::LLCallFloater(const LLSD& key)
|
||||
|
|
@ -122,10 +106,9 @@ LLCallFloater::LLCallFloater(const LLSD& key)
|
|||
, mSpeakingIndicator(NULL)
|
||||
, mIsModeratorMutedVoice(false)
|
||||
, mInitParticipantsVoiceState(false)
|
||||
, mVoiceLeftRemoveDelay(10)
|
||||
{
|
||||
static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
|
||||
mVoiceLeftRemoveDelay = voice_left_remove_delay;
|
||||
mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
|
||||
|
||||
mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);
|
||||
LLVoiceClient::getInstance()->addObserver(this);
|
||||
|
|
@ -135,6 +118,7 @@ LLCallFloater::LLCallFloater(const LLSD& key)
|
|||
LLCallFloater::~LLCallFloater()
|
||||
{
|
||||
resetVoiceRemoveTimers();
|
||||
delete mSpeakerDelayRemover;
|
||||
|
||||
delete mParticipants;
|
||||
mParticipants = NULL;
|
||||
|
|
@ -225,16 +209,6 @@ void LLCallFloater::onChange()
|
|||
}
|
||||
}
|
||||
|
||||
S32 LLCallFloater::notifyParent(const LLSD& info)
|
||||
{
|
||||
if("size_changes" == info["action"])
|
||||
{
|
||||
reshapeToFitContent();
|
||||
return 1;
|
||||
}
|
||||
return LLDockableFloater::notifyParent(info);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// PRIVATE SECTION
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -316,7 +290,7 @@ void LLCallFloater::updateSession()
|
|||
//hide "Leave Call" button for nearby chat
|
||||
bool is_local_chat = mVoiceType == VC_LOCAL_CHAT;
|
||||
childSetVisible("leave_call_btn_panel", !is_local_chat);
|
||||
|
||||
|
||||
refreshParticipantList();
|
||||
updateAgentModeratorState();
|
||||
|
||||
|
|
@ -658,33 +632,11 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state)
|
|||
|
||||
void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id)
|
||||
{
|
||||
|
||||
// If there is already a started timer for the current panel don't do anything.
|
||||
bool no_timer_for_current_panel = true;
|
||||
if (mVoiceLeftTimersMap.size() > 0)
|
||||
{
|
||||
timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id);
|
||||
if (found_it != mVoiceLeftTimersMap.end())
|
||||
{
|
||||
no_timer_for_current_panel = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (no_timer_for_current_panel)
|
||||
{
|
||||
// Starting a timer to remove an avatar row panel after timeout
|
||||
mVoiceLeftTimersMap.insert(timer_pair(voice_speaker_id,
|
||||
new LLAvatarListItemRemoveTimer(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), mVoiceLeftRemoveDelay, voice_speaker_id)));
|
||||
}
|
||||
mSpeakerDelayRemover->setActionTimer(voice_speaker_id);
|
||||
}
|
||||
|
||||
void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
|
||||
bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
|
||||
{
|
||||
if (mVoiceLeftTimersMap.size() > 0)
|
||||
{
|
||||
mVoiceLeftTimersMap.erase(mVoiceLeftTimersMap.find(voice_speaker_id));
|
||||
}
|
||||
|
||||
LLAvatarList::uuid_vector_t& speaker_uuids = mAvatarList->getIDs();
|
||||
LLAvatarList::uuid_vector_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id);
|
||||
if(pos != speaker_uuids.end())
|
||||
|
|
@ -692,34 +644,19 @@ void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
|
|||
speaker_uuids.erase(pos);
|
||||
mAvatarList->setDirty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LLCallFloater::resetVoiceRemoveTimers()
|
||||
{
|
||||
if (mVoiceLeftTimersMap.size() > 0)
|
||||
{
|
||||
for (timers_map::iterator iter = mVoiceLeftTimersMap.begin();
|
||||
iter != mVoiceLeftTimersMap.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
}
|
||||
mVoiceLeftTimersMap.clear();
|
||||
mSpeakerDelayRemover->removeAllTimers();
|
||||
}
|
||||
|
||||
void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
|
||||
{
|
||||
// Remove the timer if it has been already started
|
||||
if (mVoiceLeftTimersMap.size() > 0)
|
||||
{
|
||||
timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id);
|
||||
if (found_it != mVoiceLeftTimersMap.end())
|
||||
{
|
||||
delete found_it->second;
|
||||
mVoiceLeftTimersMap.erase(found_it);
|
||||
}
|
||||
}
|
||||
mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
|
||||
}
|
||||
|
||||
bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
|
||||
|
|
@ -798,90 +735,4 @@ void LLCallFloater::reset()
|
|||
mSpeakerManager = NULL;
|
||||
}
|
||||
|
||||
void reshape_floater(LLCallFloater* floater, S32 delta_height)
|
||||
{
|
||||
// Try to update floater top side if it is docked(to bottom bar).
|
||||
// Try to update floater bottom side or top side if it is un-docked.
|
||||
// If world rect is too small, floater will not be reshaped at all.
|
||||
|
||||
LLRect floater_rect = floater->getRect();
|
||||
LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
|
||||
|
||||
// floater is docked to bottom bar
|
||||
if(floater->isDocked())
|
||||
{
|
||||
// can update floater top side
|
||||
if(floater_rect.mTop + delta_height < world_rect.mTop)
|
||||
{
|
||||
floater_rect.set(floater_rect.mLeft, floater_rect.mTop + delta_height,
|
||||
floater_rect.mRight, floater_rect.mBottom);
|
||||
}
|
||||
}
|
||||
// floater is un-docked
|
||||
else
|
||||
{
|
||||
// can update floater bottom side
|
||||
if( floater_rect.mBottom - delta_height >= world_rect.mBottom )
|
||||
{
|
||||
floater_rect.set(floater_rect.mLeft, floater_rect.mTop,
|
||||
floater_rect.mRight, floater_rect.mBottom - delta_height);
|
||||
}
|
||||
// could not update floater bottom side, check if we can update floater top side
|
||||
else if( floater_rect.mTop + delta_height < world_rect.mTop )
|
||||
{
|
||||
floater_rect.set(floater_rect.mLeft, floater_rect.mTop + delta_height,
|
||||
floater_rect.mRight, floater_rect.mBottom);
|
||||
}
|
||||
}
|
||||
|
||||
floater->setShape(floater_rect);
|
||||
floater->getChild<LLLayoutStack>("my_call_stack")->updateLayout(FALSE);
|
||||
}
|
||||
|
||||
void LLCallFloater::reshapeToFitContent()
|
||||
{
|
||||
const S32 ITEM_HEIGHT = getParticipantItemHeight();
|
||||
static const S32 MAX_VISIBLE_ITEMS = getMaxVisibleItems();
|
||||
|
||||
static S32 items_pad = mAvatarList->getItemsPad();
|
||||
S32 list_height = mAvatarList->getRect().getHeight();
|
||||
S32 items_height = mAvatarList->getItemsRect().getHeight();
|
||||
if(items_height <= 0)
|
||||
{
|
||||
// make "no one near" text visible
|
||||
items_height = ITEM_HEIGHT + items_pad;
|
||||
}
|
||||
S32 max_list_height = MAX_VISIBLE_ITEMS * ITEM_HEIGHT + items_pad * (MAX_VISIBLE_ITEMS - 1);
|
||||
max_list_height += 2* mAvatarList->getBorderWidth();
|
||||
|
||||
S32 delta = items_height - list_height;
|
||||
// too many items, don't reshape floater anymore, let scroll bar appear.
|
||||
if(items_height > max_list_height)
|
||||
{
|
||||
delta = max_list_height - list_height;
|
||||
}
|
||||
|
||||
reshape_floater(this, delta);
|
||||
}
|
||||
|
||||
S32 LLCallFloater::getParticipantItemHeight()
|
||||
{
|
||||
std::vector<LLPanel*> items;
|
||||
mAvatarList->getItems(items);
|
||||
if(items.size() > 0)
|
||||
{
|
||||
return items[0]->getRect().getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getChild<LLPanel>("non_avatar_caller")->getRect().getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLCallFloater::getMaxVisibleItems()
|
||||
{
|
||||
static LLCachedControl<S32> max_visible_items(*LLUI::sSettingGroups["config"],"CallFloaterMaxItems");
|
||||
return max_visible_items;
|
||||
}
|
||||
|
||||
//EOF
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ class LLNonAvatarCaller;
|
|||
class LLOutputMonitorCtrl;
|
||||
class LLParticipantList;
|
||||
class LLSpeakerMgr;
|
||||
class LLSpeakersDelayActionsStorage;
|
||||
|
||||
/**
|
||||
* The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button.
|
||||
* It can be torn-off and freely positioned onscreen.
|
||||
|
|
@ -75,11 +77,6 @@ public:
|
|||
*/
|
||||
/*virtual*/ void onChange();
|
||||
|
||||
/**
|
||||
* Will reshape floater when participant list size changes
|
||||
*/
|
||||
/*virtual*/ S32 notifyParent(const LLSD& info);
|
||||
|
||||
static void sOnCurrentChannelChanged(const LLUUID& session_id);
|
||||
|
||||
private:
|
||||
|
|
@ -174,7 +171,7 @@ private:
|
|||
*
|
||||
* @param voice_speaker_id LLUUID of Avatar List item to be removed from the list.
|
||||
*/
|
||||
void removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
|
||||
bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
|
||||
|
||||
/**
|
||||
* Deletes all timers from the list to prevent started timers from ticking after destruction
|
||||
|
|
@ -221,21 +218,6 @@ private:
|
|||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Reshapes floater to fit participant list height
|
||||
*/
|
||||
void reshapeToFitContent();
|
||||
|
||||
/**
|
||||
* Returns height of participant list item
|
||||
*/
|
||||
S32 getParticipantItemHeight();
|
||||
|
||||
/**
|
||||
* Returns predefined max visible participants.
|
||||
*/
|
||||
S32 getMaxVisibleItems();
|
||||
|
||||
private:
|
||||
speaker_state_map_t mSpeakerStateMap;
|
||||
LLSpeakerMgr* mSpeakerManager;
|
||||
|
|
@ -260,32 +242,11 @@ private:
|
|||
|
||||
boost::signals2::connection mAvatarListRefreshConnection;
|
||||
|
||||
|
||||
/**
|
||||
* class LLAvatarListItemRemoveTimer
|
||||
*
|
||||
* Implements a timer that removes avatar list item of a participant
|
||||
* who has left the call.
|
||||
* time out speakers when they are not part of current session
|
||||
*/
|
||||
class LLAvatarListItemRemoveTimer : public LLEventTimer
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void(const LLUUID&)> callback_t;
|
||||
|
||||
LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id);
|
||||
virtual ~LLAvatarListItemRemoveTimer() {};
|
||||
|
||||
virtual BOOL tick();
|
||||
|
||||
private:
|
||||
callback_t mRemoveCallback;
|
||||
LLUUID mSpeakerId;
|
||||
};
|
||||
|
||||
typedef std::pair<LLUUID, LLAvatarListItemRemoveTimer*> timer_pair;
|
||||
typedef std::map<LLUUID, LLAvatarListItemRemoveTimer*> timers_map;
|
||||
|
||||
timers_map mVoiceLeftTimersMap;
|
||||
S32 mVoiceLeftRemoveDelay;
|
||||
LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
|
||||
|
||||
/**
|
||||
* Stores reference to current voice channel.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "llnotificationsutil.h"
|
||||
#include "lloutputmonitorctrl.h"
|
||||
#include "llscriptfloater.h"
|
||||
#include "llspeakers.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llvoiceclient.h"
|
||||
#include "llgroupmgr.h"
|
||||
|
|
@ -1271,6 +1272,7 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
|
|||
chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
|
||||
|
||||
arrange();
|
||||
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, chiclet);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1298,6 +1300,7 @@ void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
|
|||
mChicletList.erase(it);
|
||||
|
||||
arrange();
|
||||
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, chiclet);
|
||||
chiclet->die();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "llinventorymodel.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "lllandmarkactions.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsidetray.h"
|
||||
#include "lltoggleablemenu.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
|
@ -975,6 +976,10 @@ BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
void copy_slurl_to_clipboard_cb(std::string& slurl)
|
||||
{
|
||||
gClipboard.copyFromString(utf8str_to_wstring(slurl));
|
||||
|
||||
LLSD args;
|
||||
args["SLURL"] = slurl;
|
||||
LLNotificationsUtil::add("CopySLURL", args);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -277,13 +277,8 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
|
|||
{
|
||||
object_owner.append("Unknown");
|
||||
}
|
||||
childSetText("object_name", object_owner);
|
||||
std::string owner_link =
|
||||
LLSLURL::buildCommand("agent", mObjectID, "inspect");
|
||||
childSetText("owner_name", owner_link);
|
||||
childSetText("abuser_name_edit", object_owner);
|
||||
mAbuserID = object_id;
|
||||
mOwnerName = object_owner;
|
||||
|
||||
setFromAvatar(object_id, object_owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -305,7 +300,6 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterReporter::onClickSelectAbuser()
|
||||
{
|
||||
gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE ));
|
||||
|
|
@ -323,6 +317,17 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,
|
|||
|
||||
}
|
||||
|
||||
void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name)
|
||||
{
|
||||
mAbuserID = mObjectID = avatar_id;
|
||||
mOwnerName = avatar_name;
|
||||
|
||||
std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");
|
||||
childSetText("owner_name", avatar_link);
|
||||
childSetText("object_name", avatar_name); // name
|
||||
childSetText("abuser_name_edit", avatar_name);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::onClickSend(void *userdata)
|
||||
{
|
||||
|
|
@ -458,9 +463,8 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::showFromObject(const LLUUID& object_id)
|
||||
void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name)
|
||||
{
|
||||
LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter");
|
||||
|
||||
|
|
@ -469,8 +473,11 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)
|
|||
LLAgentUI::buildFullname(fullname);
|
||||
f->childSetText("reporter_field", fullname);
|
||||
|
||||
// Request info for this object
|
||||
f->getObjectInfo(object_id);
|
||||
if (avatar_name.empty())
|
||||
// Request info for this object
|
||||
f->getObjectInfo(object_id);
|
||||
else
|
||||
f->setFromAvatar(object_id, avatar_name);
|
||||
|
||||
// Need to deselect on close
|
||||
f->mDeselectOnClose = TRUE;
|
||||
|
|
@ -479,6 +486,18 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)
|
|||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::showFromObject(const LLUUID& object_id)
|
||||
{
|
||||
show(object_id);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name)
|
||||
{
|
||||
show(avatar_id, avatar_name);
|
||||
}
|
||||
|
||||
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
|
||||
{
|
||||
childSetText("object_name", object_name);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public:
|
|||
static void showFromMenu(EReportType report_type);
|
||||
|
||||
static void showFromObject(const LLUUID& object_id);
|
||||
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
|
||||
|
||||
static void onClickSend (void *userdata);
|
||||
static void onClickCancel (void *userdata);
|
||||
|
|
@ -109,6 +110,8 @@ public:
|
|||
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
|
||||
|
||||
private:
|
||||
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null);
|
||||
|
||||
void takeScreenshot();
|
||||
void sendReportViaCaps(std::string url);
|
||||
void uploadImage();
|
||||
|
|
@ -121,6 +124,7 @@ private:
|
|||
void enableControls(BOOL own_avatar);
|
||||
void getObjectInfo(const LLUUID& object_id);
|
||||
void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids);
|
||||
void setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name = LLStringUtil::null);
|
||||
|
||||
private:
|
||||
EReportType mReportType;
|
||||
|
|
|
|||
|
|
@ -1391,6 +1391,7 @@ void LLFolderView::startRenamingSelectedItem( void )
|
|||
// set focus will fail unless item is visible
|
||||
mRenamer->setFocus( TRUE );
|
||||
mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1));
|
||||
mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1));
|
||||
gFocusMgr.setTopCtrl( mRenamer );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,41 @@ void LLGestureManager::init()
|
|||
// TODO
|
||||
}
|
||||
|
||||
void LLGestureManager::changed(U32 mask)
|
||||
{
|
||||
LLInventoryFetchObserver::changed(mask);
|
||||
|
||||
if (mask & LLInventoryObserver::GESTURE)
|
||||
{
|
||||
// If there was a gesture label changed, update all the names in the
|
||||
// active gestures and then notify observers
|
||||
if (mask & LLInventoryObserver::LABEL)
|
||||
{
|
||||
for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
|
||||
{
|
||||
if(it->second)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(it->first);
|
||||
if(item)
|
||||
{
|
||||
it->second->mName = item->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyObservers();
|
||||
}
|
||||
// If there was a gesture added or removed notify observers
|
||||
// STRUCTURE denotes that the inventory item has been moved
|
||||
// In the case of deleting gesture, it is moved to the trash
|
||||
else if(mask & LLInventoryObserver::ADD ||
|
||||
mask & LLInventoryObserver::REMOVE ||
|
||||
mask & LLInventoryObserver::STRUCTURE)
|
||||
{
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use this version when you have the item_id but not the asset_id,
|
||||
// and you KNOW the inventory is loaded.
|
||||
|
|
|
|||
|
|
@ -140,6 +140,9 @@ public:
|
|||
void removeObserver(LLGestureManagerObserver* observer);
|
||||
void notifyObservers();
|
||||
|
||||
// Overriding so we can update active gesture names and notify observers
|
||||
void changed(U32 mask);
|
||||
|
||||
BOOL matchPrefix(const std::string& in_str, std::string* out_str);
|
||||
|
||||
// Copy item ids into the vector
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "llinventorymodel.h"
|
||||
#include "llrootview.h"
|
||||
|
||||
#include "llspeakers.h"
|
||||
|
||||
|
||||
LLIMFloater::LLIMFloater(const LLUUID& session_id)
|
||||
|
|
@ -109,6 +110,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
|
|||
}
|
||||
}
|
||||
setOverlapsScreenChannel(true);
|
||||
|
||||
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
|
||||
}
|
||||
|
||||
void LLIMFloater::onFocusLost()
|
||||
|
|
@ -227,6 +230,7 @@ void LLIMFloater::sendMsg()
|
|||
|
||||
LLIMFloater::~LLIMFloater()
|
||||
{
|
||||
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -350,13 +354,15 @@ void* LLIMFloater::createPanelAdHocControl(void* userdata)
|
|||
|
||||
void LLIMFloater::onSlide()
|
||||
{
|
||||
LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
|
||||
im_control_panel->setVisible(!im_control_panel->getVisible());
|
||||
mControlPanel->setVisible(!mControlPanel->getVisible());
|
||||
|
||||
gSavedSettings.setBOOL("IMShowControlPanel", im_control_panel->getVisible());
|
||||
gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getVisible());
|
||||
|
||||
getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
|
||||
getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
|
||||
getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getVisible());
|
||||
getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getVisible());
|
||||
|
||||
LLLayoutStack* stack = getChild<LLLayoutStack>("im_panels");
|
||||
if (stack) stack->setAnimate(true);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -510,14 +516,14 @@ bool LLIMFloater::toggle(const LLUUID& session_id)
|
|||
if(!isChatMultiTab())
|
||||
{
|
||||
LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
|
||||
if (floater && floater->getVisible())
|
||||
if (floater && floater->getVisible() && floater->hasFocus())
|
||||
{
|
||||
// clicking on chiclet to close floater just hides it to maintain existing
|
||||
// scroll/text entry state
|
||||
floater->setVisible(false);
|
||||
return false;
|
||||
}
|
||||
else if(floater && !floater->isDocked())
|
||||
else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
|
||||
{
|
||||
floater->setVisible(TRUE);
|
||||
floater->setFocus(TRUE);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ public:
|
|||
|
||||
static void onIMChicletCreated(const LLUUID& session_id);
|
||||
|
||||
virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
|
||||
|
||||
private:
|
||||
// process focus events to set a currently active session
|
||||
/* virtual */ void onFocusLost();
|
||||
|
|
|
|||
|
|
@ -35,19 +35,22 @@
|
|||
|
||||
#include "llimfloatercontainer.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llimview.h"
|
||||
#include "llavatariconctrl.h"
|
||||
#include "llagent.h"
|
||||
|
||||
//
|
||||
// LLIMFloaterContainer
|
||||
//
|
||||
LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
|
||||
: LLMultiFloater(seed),
|
||||
mActiveVoiceFloater(NULL)
|
||||
: LLMultiFloater(seed)
|
||||
{
|
||||
mAutoResize = FALSE;
|
||||
}
|
||||
|
||||
LLIMFloaterContainer::~LLIMFloaterContainer()
|
||||
{
|
||||
LLGroupMgr::getInstance()->removeObserver(this);
|
||||
}
|
||||
|
||||
BOOL LLIMFloaterContainer::postBuild()
|
||||
|
|
@ -87,11 +90,82 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
|
|||
|
||||
LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
|
||||
|
||||
// make sure active voice icon shows up for new tab
|
||||
if (floaterp == mActiveVoiceFloater)
|
||||
LLUUID session_id = floaterp->getKey();
|
||||
|
||||
if(gAgent.isInGroup(session_id))
|
||||
{
|
||||
mTabContainer->setTabImage(floaterp, "active_voice_tab.tga");
|
||||
mSessions[session_id] = floaterp;
|
||||
mID = session_id;
|
||||
mGroupID.push_back(session_id);
|
||||
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(session_id);
|
||||
LLGroupMgr* gm = LLGroupMgr::getInstance();
|
||||
gm->addObserver(this);
|
||||
|
||||
if (group_data && group_data->mInsigniaID.notNull())
|
||||
{
|
||||
mTabContainer->setTabImage(get_ptr_in_map(mSessions, session_id), group_data->mInsigniaID);
|
||||
}
|
||||
else
|
||||
{
|
||||
gm->sendGroupPropertiesRequest(session_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id);
|
||||
LLAvatarPropertiesProcessor& app = LLAvatarPropertiesProcessor::instance();
|
||||
app.addObserver(avatar_id, this);
|
||||
floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, avatar_id));
|
||||
mSessions[avatar_id] = floaterp;
|
||||
|
||||
LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(avatar_id);
|
||||
if(!icon_id_ptr)
|
||||
{
|
||||
app.sendAvatarPropertiesRequest(avatar_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
mTabContainer->setTabImage(floaterp, *icon_id_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLIMFloaterContainer::processProperties(void* data, enum EAvatarProcessorType type)
|
||||
{
|
||||
if (APT_PROPERTIES == type)
|
||||
{
|
||||
LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
|
||||
if (avatar_data)
|
||||
{
|
||||
LLUUID avatar_id = avatar_data->avatar_id;
|
||||
if(avatar_data->image_id != *LLAvatarIconIDCache::getInstance()->get(avatar_id))
|
||||
{
|
||||
LLAvatarIconIDCache::getInstance()->add(avatar_id,avatar_data->image_id);
|
||||
}
|
||||
mTabContainer->setTabImage(get_ptr_in_map(mSessions, avatar_id), avatar_data->image_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLIMFloaterContainer::changed(LLGroupChange gc)
|
||||
{
|
||||
if (GC_PROPERTIES == gc)
|
||||
{
|
||||
for(groupIDs_t::iterator it = mGroupID.begin(); it!=mGroupID.end(); it++)
|
||||
{
|
||||
LLUUID group_id = *it;
|
||||
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id);
|
||||
if (group_data && group_data->mInsigniaID.notNull())
|
||||
{
|
||||
mTabContainer->setTabImage(get_ptr_in_map(mSessions, group_id), group_data->mInsigniaID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLIMFloaterContainer::onCloseFloater(LLUUID id)
|
||||
{
|
||||
LLAvatarPropertiesProcessor::instance().removeObserver(id, this);
|
||||
}
|
||||
|
||||
LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
|
||||
|
|
|
|||
|
|
@ -33,12 +33,17 @@
|
|||
#ifndef LL_LLIMFLOATERCONTAINER_H
|
||||
#define LL_LLIMFLOATERCONTAINER_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llmultifloater.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llgroupmgr.h"
|
||||
|
||||
class LLTabContainer;
|
||||
|
||||
class LLIMFloaterContainer : public LLMultiFloater
|
||||
class LLIMFloaterContainer : public LLMultiFloater, public LLAvatarPropertiesObserver, public LLGroupMgrObserver
|
||||
{
|
||||
public:
|
||||
LLIMFloaterContainer(const LLSD& seed);
|
||||
|
|
@ -51,15 +56,23 @@ public:
|
|||
BOOL select_added_floater,
|
||||
LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
|
||||
|
||||
void processProperties(void* data, EAvatarProcessorType type);
|
||||
void changed(LLGroupChange gc);
|
||||
|
||||
static LLFloater* getCurrentVoiceFloater();
|
||||
|
||||
static LLIMFloaterContainer* findInstance();
|
||||
|
||||
static LLIMFloaterContainer* getInstance();
|
||||
|
||||
protected:
|
||||
|
||||
LLFloater* mActiveVoiceFloater;
|
||||
private:
|
||||
typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t;
|
||||
avatarID_panel_map_t mSessions;
|
||||
|
||||
typedef std::vector<LLUUID> groupIDs_t;
|
||||
groupIDs_t mGroupID;
|
||||
|
||||
void onCloseFloater(LLUUID avatar_id);
|
||||
};
|
||||
|
||||
#endif // LL_LLIMFLOATERCONTAINER_H
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "llfontgl.h"
|
||||
#include "llrect.h"
|
||||
#include "llerror.h"
|
||||
#include "llmultifloater.h"
|
||||
#include "llstring.h"
|
||||
#include "message.h"
|
||||
#include "lltextbox.h"
|
||||
|
|
|
|||
|
|
@ -42,47 +42,31 @@
|
|||
#include "llhttpclient.h"
|
||||
#include "llsdutil_math.h"
|
||||
#include "llstring.h"
|
||||
#include "lltrans.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentui.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llavatariconctrl.h"
|
||||
#include "llbottomtray.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llchat.h"
|
||||
#include "llchiclet.h"
|
||||
#include "llresmgr.h"
|
||||
#include "llfloaterchatterbox.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llhttpnode.h"
|
||||
#include "llimfloater.h"
|
||||
#include "llimpanel.h"
|
||||
#include "llgroupiconctrl.h"
|
||||
#include "llresizebar.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llfloater.h"
|
||||
#include "llmd5.h"
|
||||
#include "llmutelist.h"
|
||||
#include "llresizehandle.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "llui.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "lltoolbar.h"
|
||||
#include "llrecentpeople.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llnearbychat.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llvoicechannel.h"
|
||||
#include "lltrans.h"
|
||||
#include "llrecentpeople.h"
|
||||
#include "llsyswellwindow.h"
|
||||
|
||||
//#include "llfirstuse.h"
|
||||
#include "llagentui.h"
|
||||
#include "llspeakers.h" //for LLIMSpeakerMgr
|
||||
#include "lltextutil.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
|
||||
const static std::string IM_TIME("time");
|
||||
const static std::string IM_TEXT("message");
|
||||
|
|
@ -232,12 +216,14 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
|
|||
mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID);
|
||||
}
|
||||
|
||||
buildHistoryFileName();
|
||||
|
||||
if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
|
||||
{
|
||||
std::list<LLSD> chat_history;
|
||||
|
||||
//involves parsing of a chat history
|
||||
LLLogChat::loadAllHistory(mName, chat_history);
|
||||
LLLogChat::loadAllHistory(mHistoryFileName, chat_history);
|
||||
addMessagesFromHistory(chat_history);
|
||||
}
|
||||
}
|
||||
|
|
@ -484,6 +470,44 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
|
|||
return !mOtherParticipantIsAvatar;
|
||||
}
|
||||
|
||||
void LLIMModel::LLIMSession::buildHistoryFileName()
|
||||
{
|
||||
mHistoryFileName = mName;
|
||||
|
||||
//ad-hoc requires sophisticated chat history saving schemes
|
||||
if (isAdHoc())
|
||||
{
|
||||
//in case of outgoing ad-hoc sessions
|
||||
if (mInitialTargetIDs.size())
|
||||
{
|
||||
std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
|
||||
mHistoryFileName = mName + " hash" + generateHash(sorted_uuids);
|
||||
return;
|
||||
}
|
||||
|
||||
//in case of incoming ad-hoc sessions
|
||||
mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
|
||||
{
|
||||
LLMD5 md5_uuid;
|
||||
|
||||
std::set<LLUUID>::const_iterator it = sorted_uuids.begin();
|
||||
while (it != sorted_uuids.end())
|
||||
{
|
||||
md5_uuid.update((unsigned char*)(*it).mData, 16);
|
||||
it++;
|
||||
}
|
||||
md5_uuid.finalize();
|
||||
|
||||
LLUUID participants_md5_hash;
|
||||
md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData);
|
||||
return participants_md5_hash.asString();
|
||||
}
|
||||
|
||||
|
||||
void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
|
||||
{
|
||||
|
|
@ -631,11 +655,11 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLIMModel::logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
|
||||
bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
|
||||
{
|
||||
if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
|
||||
{
|
||||
LLLogChat::saveHistory(session_name, from, from_id, utf8_text);
|
||||
LLLogChat::saveHistory(file_name, from, from_id, utf8_text);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -646,15 +670,7 @@ bool LLIMModel::logToFile(const std::string& session_name, const std::string& fr
|
|||
|
||||
bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
|
||||
{
|
||||
if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
|
||||
{
|
||||
LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return logToFile(LLIMModel::getInstance()->getHistoryFileName(session_id), from, from_id, utf8_text);
|
||||
}
|
||||
|
||||
bool LLIMModel::proccessOnlineOfflineNotification(
|
||||
|
|
@ -799,6 +815,18 @@ LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
|
|||
return session->mSpeakers;
|
||||
}
|
||||
|
||||
const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const
|
||||
{
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << " does not exist " << llendl;
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
return session->mHistoryFileName;
|
||||
}
|
||||
|
||||
|
||||
// TODO get rid of other participant ID
|
||||
void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
|
||||
|
|
|
|||
|
|
@ -33,22 +33,19 @@
|
|||
#ifndef LL_LLIMVIEW_H
|
||||
#define LL_LLIMVIEW_H
|
||||
|
||||
#include "lldarray.h"
|
||||
#include "lldockablefloater.h"
|
||||
#include "llspeakers.h" //for LLIMSpeakerMgr
|
||||
#include "llimpanel.h" //for voice channels
|
||||
#include "llmodaldialog.h"
|
||||
#include "lldockablefloater.h"
|
||||
#include "llinstantmessage.h"
|
||||
#include "lluuid.h"
|
||||
#include "llmultifloater.h"
|
||||
|
||||
#include "lllogchat.h"
|
||||
#include "llvoicechannel.h"
|
||||
|
||||
class LLFloaterChatterBox;
|
||||
class LLUUID;
|
||||
class LLFloaterIMPanel;
|
||||
class LLFriendObserver;
|
||||
class LLCallDialogManager;
|
||||
class LLIMSpeakerMgr;
|
||||
|
||||
|
||||
class LLIMModel : public LLSingleton<LLIMModel>
|
||||
{
|
||||
|
|
@ -72,6 +69,8 @@ public:
|
|||
void addMessagesFromHistory(const std::list<LLSD>& history);
|
||||
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time);
|
||||
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
|
||||
|
||||
/** @deprecated */
|
||||
static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
|
||||
|
||||
bool isAdHoc();
|
||||
|
|
@ -83,12 +82,20 @@ public:
|
|||
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
|
||||
bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
|
||||
|
||||
//*TODO make private
|
||||
/** ad-hoc sessions involve sophisticated chat history file naming schemes */
|
||||
void buildHistoryFileName();
|
||||
|
||||
//*TODO make private
|
||||
static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
|
||||
|
||||
LLUUID mSessionID;
|
||||
std::string mName;
|
||||
EInstantMessage mType;
|
||||
SType mSessionType;
|
||||
LLUUID mOtherParticipantID;
|
||||
std::vector<LLUUID> mInitialTargetIDs;
|
||||
std::string mHistoryFileName;
|
||||
|
||||
// connection to voice channel state change signal
|
||||
boost::signals2::connection mVoiceChannelStateChangeConnection;
|
||||
|
|
@ -234,6 +241,8 @@ public:
|
|||
*/
|
||||
LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
|
||||
|
||||
const std::string& getHistoryFileName(const LLUUID& session_id) const;
|
||||
|
||||
static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id);
|
||||
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
|
||||
const std::vector<LLUUID>& ids, EInstantMessage dialog);
|
||||
|
|
@ -246,7 +255,7 @@ public:
|
|||
/**
|
||||
* Saves an IM message into a file
|
||||
*/
|
||||
bool logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
|
||||
bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -689,7 +689,7 @@ void LLInspectAvatar::onToggleMute()
|
|||
|
||||
void LLInspectAvatar::onClickReport()
|
||||
{
|
||||
LLFloaterReporter::showFromObject(mAvatarID);
|
||||
LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName);
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,6 +187,11 @@ BOOL LLInvFVBridge::isItemRemovable()
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (LLAppearanceManager::instance().getIsProtectedCOFItem(mUUID))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const LLInventoryObject *obj = model->getItem(mUUID);
|
||||
if (obj && obj->getIsLinkType())
|
||||
{
|
||||
|
|
@ -576,8 +581,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
|
|||
disabled_items.push_back(std::string("Paste As Link"));
|
||||
}
|
||||
}
|
||||
items.push_back(std::string("Paste Separator"));
|
||||
|
||||
items.push_back(std::string("Paste Separator"));
|
||||
|
||||
if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
|
||||
{
|
||||
|
|
@ -714,14 +719,7 @@ BOOL LLInvFVBridge::isAgentInventory() const
|
|||
|
||||
BOOL LLInvFVBridge::isCOFFolder() const
|
||||
{
|
||||
const LLInventoryModel* model = getInventoryModel();
|
||||
if(!model) return TRUE;
|
||||
const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
|
||||
if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
return LLAppearanceManager::instance().getIsInCOF(mUUID);
|
||||
}
|
||||
|
||||
BOOL LLInvFVBridge::isItemPermissive() const
|
||||
|
|
@ -3702,18 +3700,6 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
|
|||
return rv;
|
||||
}
|
||||
|
||||
BOOL LLCallingCardBridge::removeItem()
|
||||
{
|
||||
if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem()))
|
||||
{
|
||||
LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID());
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LLItemBridge::removeItem();
|
||||
}
|
||||
}
|
||||
// +=================================================+
|
||||
// | LLNotecardBridge |
|
||||
// +=================================================+
|
||||
|
|
@ -3825,8 +3811,25 @@ void LLGestureBridge::openItem()
|
|||
|
||||
BOOL LLGestureBridge::removeItem()
|
||||
{
|
||||
// Force close the preview window, if it exists
|
||||
LLGestureManager::instance().deactivateGesture(mUUID);
|
||||
// Grab class information locally since *this may be deleted
|
||||
// within this function. Not a great pattern...
|
||||
const LLInventoryModel* model = getInventoryModel();
|
||||
if(!model)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
const LLUUID item_id = mUUID;
|
||||
|
||||
// This will also force close the preview window, if it exists.
|
||||
// This may actually delete *this, if mUUID is in the COF.
|
||||
LLGestureManager::instance().deactivateGesture(item_id);
|
||||
|
||||
// If deactivateGesture deleted *this, then return out immediately.
|
||||
if (!model->getObject(item_id))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return LLItemBridge::removeItem();
|
||||
}
|
||||
|
||||
|
|
@ -4620,7 +4623,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
|
||||
getClipboardEntries(true, items, disabled_items, flags);
|
||||
|
||||
items.push_back(std::string("Wearable Separator"));
|
||||
if (!is_sidepanel)
|
||||
{
|
||||
items.push_back(std::string("Wearable Separator"));
|
||||
}
|
||||
|
||||
items.push_back(std::string("Wearable Edit"));
|
||||
|
||||
|
|
@ -5150,8 +5156,12 @@ void LLLandmarkBridgeAction::doIt()
|
|||
// Opening (double-clicking) a landmark immediately teleports,
|
||||
// but warns you the first time.
|
||||
LLSD payload;
|
||||
payload["asset_id"] = item->getAssetUUID();
|
||||
LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload);
|
||||
payload["asset_id"] = item->getAssetUUID();
|
||||
|
||||
LLSD args;
|
||||
args["LOCATION"] = item->getDisplayName();
|
||||
|
||||
LLNotificationsUtil::add("TeleportFromLandmark", args, payload);
|
||||
}
|
||||
|
||||
LLInvFVBridgeAction::doIt();
|
||||
|
|
|
|||
|
|
@ -450,7 +450,6 @@ public:
|
|||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
void refreshFolderViewItem();
|
||||
BOOL removeItem();
|
||||
|
||||
protected:
|
||||
LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid );
|
||||
|
|
|
|||
|
|
@ -755,6 +755,10 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
|
|||
gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3));
|
||||
}
|
||||
}
|
||||
else if (new_item->getType() == LLAssetType::AT_GESTURE)
|
||||
{
|
||||
mask |= LLInventoryObserver::GESTURE;
|
||||
}
|
||||
addChangedMask(mask, new_item->getUUID());
|
||||
return mask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ public:
|
|||
REMOVE = 8, // something deleted
|
||||
STRUCTURE = 16, // structural change (eg item or folder moved)
|
||||
CALLING_CARD = 32, // (eg online, grant status, cancel)
|
||||
REBUILD = 64, // item UI changed (eg item type different)
|
||||
SORT = 128, // folder needs to be resorted.
|
||||
GESTURE = 64,
|
||||
REBUILD = 128, // item UI changed (eg item type different)
|
||||
SORT = 256, // folder needs to be resorted.
|
||||
ALL = 0xffffffff
|
||||
};
|
||||
LLInventoryObserver();
|
||||
|
|
|
|||
|
|
@ -682,6 +682,14 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
|
|||
mFolders->setSelectionByID(obj_id, take_keyboard_focus);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
|
||||
{
|
||||
if (mFolders)
|
||||
{
|
||||
mFolders->setSelectCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryPanel::clearSelection()
|
||||
{
|
||||
mFolders->clearSelection();
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public:
|
|||
// Call this method to set the selection.
|
||||
void openAllFolders();
|
||||
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
|
||||
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
|
||||
void clearSelection();
|
||||
LLInventoryFilter* getFilter();
|
||||
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
|
||||
|
|
|
|||
|
|
@ -43,8 +43,11 @@
|
|||
#include "lltrans.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lltooltip.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llregionflags.h"
|
||||
|
||||
// newview includes
|
||||
#include "llagent.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "lllandmarkactions.h"
|
||||
#include "lllandmarklist.h"
|
||||
|
|
@ -56,6 +59,7 @@
|
|||
#include "lltrans.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "llurllineeditorctrl.h"
|
||||
|
|
@ -256,36 +260,42 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
|
|||
voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip");
|
||||
voice_icon.mouse_opaque = true;
|
||||
mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon);
|
||||
mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON));
|
||||
addChild(mParcelIcon[VOICE_ICON]);
|
||||
|
||||
LLIconCtrl::Params fly_icon = p.fly_icon;
|
||||
fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip");
|
||||
fly_icon.mouse_opaque = true;
|
||||
mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon);
|
||||
mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON));
|
||||
addChild(mParcelIcon[FLY_ICON]);
|
||||
|
||||
LLIconCtrl::Params push_icon = p.push_icon;
|
||||
push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip");
|
||||
push_icon.mouse_opaque = true;
|
||||
mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon);
|
||||
mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON));
|
||||
addChild(mParcelIcon[PUSH_ICON]);
|
||||
|
||||
LLIconCtrl::Params build_icon = p.build_icon;
|
||||
build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip");
|
||||
build_icon.mouse_opaque = true;
|
||||
mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon);
|
||||
mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON));
|
||||
addChild(mParcelIcon[BUILD_ICON]);
|
||||
|
||||
LLIconCtrl::Params scripts_icon = p.scripts_icon;
|
||||
scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip");
|
||||
scripts_icon.mouse_opaque = true;
|
||||
mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon);
|
||||
mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON));
|
||||
addChild(mParcelIcon[SCRIPTS_ICON]);
|
||||
|
||||
LLIconCtrl::Params damage_icon = p.damage_icon;
|
||||
damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
|
||||
damage_icon.mouse_opaque = true;
|
||||
mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon);
|
||||
mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON));
|
||||
addChild(mParcelIcon[DAMAGE_ICON]);
|
||||
|
||||
LLTextBox::Params damage_text = p.damage_text;
|
||||
|
|
@ -918,3 +928,45 @@ bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
|
||||
{
|
||||
switch (icon)
|
||||
{
|
||||
case VOICE_ICON:
|
||||
LLNotificationsUtil::add("NoVoice");
|
||||
break;
|
||||
case FLY_ICON:
|
||||
LLNotificationsUtil::add("NoFly");
|
||||
break;
|
||||
case PUSH_ICON:
|
||||
LLNotificationsUtil::add("PushRestricted");
|
||||
break;
|
||||
case BUILD_ICON:
|
||||
LLNotificationsUtil::add("NoBuild");
|
||||
break;
|
||||
case SCRIPTS_ICON:
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
|
||||
{
|
||||
LLNotificationsUtil::add("ScriptsStopped");
|
||||
}
|
||||
else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
|
||||
{
|
||||
LLNotificationsUtil::add("ScriptsNotRunning");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("NoOutsideScripts");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DAMAGE_ICON:
|
||||
LLNotificationsUtil::add("NotSafe");
|
||||
break;
|
||||
case ICON_COUNT:
|
||||
break;
|
||||
// no default to get compiler warning when a new icon gets added
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,18 @@ public:
|
|||
void handleLoginComplete();
|
||||
|
||||
private:
|
||||
|
||||
enum EParcelIcon
|
||||
{
|
||||
VOICE_ICON = 0,
|
||||
FLY_ICON,
|
||||
PUSH_ICON,
|
||||
BUILD_ICON,
|
||||
SCRIPTS_ICON,
|
||||
DAMAGE_ICON,
|
||||
ICON_COUNT
|
||||
};
|
||||
|
||||
friend class LLUICtrlFactory;
|
||||
LLLocationInputCtrl(const Params&);
|
||||
virtual ~LLLocationInputCtrl();
|
||||
|
|
@ -138,6 +150,7 @@ private:
|
|||
// callbacks
|
||||
bool onLocationContextMenuItemEnabled(const LLSD& userdata);
|
||||
void onLocationContextMenuItemClicked(const LLSD& userdata);
|
||||
void onParcelIconClick(EParcelIcon icon);
|
||||
|
||||
LLMenuGL* mLocationContextMenu;
|
||||
LLButton* mAddLandmarkBtn;
|
||||
|
|
@ -146,16 +159,6 @@ private:
|
|||
S32 mIconHPad; // pad between all icons
|
||||
S32 mAddLandmarkHPad; // pad to left of landmark star
|
||||
|
||||
enum EParcelIcon
|
||||
{
|
||||
VOICE_ICON = 0,
|
||||
FLY_ICON,
|
||||
PUSH_ICON,
|
||||
BUILD_ICON,
|
||||
SCRIPTS_ICON,
|
||||
DAMAGE_ICON,
|
||||
ICON_COUNT
|
||||
};
|
||||
LLIconCtrl* mParcelIcon[ICON_COUNT];
|
||||
LLTextBox* mDamageText;
|
||||
|
||||
|
|
|
|||
|
|
@ -237,15 +237,15 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
|
|||
messages.back()[IM_TEXT] = im_text;
|
||||
}
|
||||
|
||||
void LLLogChat::loadAllHistory(const std::string& session_name, std::list<LLSD>& messages)
|
||||
void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)
|
||||
{
|
||||
if (session_name.empty())
|
||||
if (file_name.empty())
|
||||
{
|
||||
llwarns << "Session name is Empty!" << llendl;
|
||||
return ;
|
||||
}
|
||||
|
||||
LLFILE* fptr = LLFile::fopen(makeLogFileName(session_name), "r"); /*Flawfinder: ignore*/
|
||||
LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r"); /*Flawfinder: ignore*/
|
||||
if (!fptr) return; //No previous conversation with this name.
|
||||
|
||||
char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
void (*callback)(ELogLineType, const LLSD&, void*),
|
||||
void* userdata);
|
||||
|
||||
static void loadAllHistory(const std::string& session_name, std::list<LLSD>& messages);
|
||||
static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);
|
||||
private:
|
||||
static std::string cleanFileName(std::string filename);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -869,38 +869,6 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
|
|||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static
|
||||
bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if ( 0 == option )
|
||||
{
|
||||
LLSD payload = notification["payload"];
|
||||
std::string url = payload["url"].asString();
|
||||
S32 target_type = payload["target_type"].asInteger();
|
||||
|
||||
switch (target_type)
|
||||
{
|
||||
case LLPluginClassMedia::TARGET_EXTERNAL:
|
||||
// load target in an external browser
|
||||
LLWeb::loadURLExternal(url);
|
||||
break;
|
||||
|
||||
case LLPluginClassMedia::TARGET_BLANK:
|
||||
// load target in the user's preferred browser
|
||||
LLWeb::loadURL(url);
|
||||
break;
|
||||
|
||||
default:
|
||||
// unsupported link target - shouldn't happen
|
||||
LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// inherited from LLViewerMediaObserver
|
||||
//virtual
|
||||
|
|
@ -1014,40 +982,79 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
|
|||
U32 target_type = self->getClickTargetType();
|
||||
|
||||
// is there is a target specified for the link?
|
||||
if (target_type == LLPluginClassMedia::TARGET_EXTERNAL ||
|
||||
target_type == LLPluginClassMedia::TARGET_BLANK)
|
||||
if (gSavedSettings.getBOOL("UseExternalBrowser") || target_type == LLPluginClassMedia::TARGET_EXTERNAL)
|
||||
{
|
||||
LLSD payload;
|
||||
payload["url"] = url;
|
||||
payload["target_type"] = LLSD::Integer(target_type);
|
||||
LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget);
|
||||
return;
|
||||
}
|
||||
else if (target_type == LLPluginClassMedia::TARGET_BLANK)
|
||||
{
|
||||
clickLinkWithTarget(url, target_type);
|
||||
}
|
||||
else {
|
||||
const std::string protocol1( "http://" );
|
||||
const std::string protocol2( "https://" );
|
||||
if( mOpenLinksInExternalBrowser )
|
||||
{
|
||||
if ( !url.empty() )
|
||||
{
|
||||
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
|
||||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
|
||||
{
|
||||
LLWeb::loadURLExternal( url );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if( mOpenLinksInInternalBrowser )
|
||||
{
|
||||
if ( !url.empty() )
|
||||
{
|
||||
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
|
||||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
|
||||
{
|
||||
llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string protocol1( "http://" );
|
||||
const std::string protocol2( "https://" );
|
||||
if( mOpenLinksInExternalBrowser )
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static
|
||||
bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if ( 0 == option )
|
||||
{
|
||||
if ( !url.empty() )
|
||||
{
|
||||
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
|
||||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
|
||||
{
|
||||
LLWeb::loadURLExternal( url );
|
||||
}
|
||||
}
|
||||
LLSD payload = notification["payload"];
|
||||
std::string url = payload["url"].asString();
|
||||
S32 target_type = payload["target_type"].asInteger();
|
||||
clickLinkWithTarget(url, target_type);
|
||||
}
|
||||
else
|
||||
if( mOpenLinksInInternalBrowser )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static
|
||||
void LLMediaCtrl::clickLinkWithTarget(const std::string& url, const S32& target_type )
|
||||
{
|
||||
if (gSavedSettings.getBOOL("UseExternalBrowser") || target_type == LLPluginClassMedia::TARGET_EXTERNAL)
|
||||
{
|
||||
if ( !url.empty() )
|
||||
{
|
||||
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
|
||||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
|
||||
{
|
||||
llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
|
||||
}
|
||||
}
|
||||
// load target in an external browser
|
||||
LLWeb::loadURLExternal(url);
|
||||
}
|
||||
else if (target_type == LLPluginClassMedia::TARGET_BLANK)
|
||||
{
|
||||
// load target in the user's preferred browser
|
||||
LLWeb::loadURL(url);
|
||||
}
|
||||
else {
|
||||
// unsupported link target - shouldn't happen
|
||||
LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ public:
|
|||
private:
|
||||
void onVisibilityChange ( const LLSD& new_visibility );
|
||||
static bool onClickLinkExternalTarget( const LLSD&, const LLSD& );
|
||||
static void clickLinkWithTarget(const std::string& url, const S32& target_type );
|
||||
|
||||
const S32 mTextureDepthBytes;
|
||||
LLUUID mMediaTextureID;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include "llviewerwindow.h"
|
||||
#include "llworld.h" //for particle system banning
|
||||
#include "llchat.h"
|
||||
#include "llimpanel.h"
|
||||
#include "llimview.h"
|
||||
#include "llnotifications.h"
|
||||
#include "lluistring.h"
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
#include "llvovolume.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llpluginclassmedia.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
||||
//
|
||||
// Methods
|
||||
|
|
@ -406,14 +407,40 @@ void LLPanelFace::getState()
|
|||
LLUUID id;
|
||||
struct f1 : public LLSelectedTEGetFunctor<LLUUID>
|
||||
{
|
||||
LLUUID get(LLViewerObject* object, S32 te)
|
||||
LLUUID get(LLViewerObject* object, S32 te_index)
|
||||
{
|
||||
LLViewerTexture* image = object->getTEImage(te);
|
||||
return image ? image->getID() : LLUUID::null;
|
||||
LLUUID id;
|
||||
|
||||
LLViewerTexture* image = object->getTEImage(te_index);
|
||||
if (image) id = image->getID();
|
||||
|
||||
if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
|
||||
{
|
||||
LLTextureEntry *te = object->getTE(te_index);
|
||||
if (te)
|
||||
{
|
||||
LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
|
||||
if(!tex)
|
||||
{
|
||||
tex = LLViewerFetchedTexture::sDefaultImagep;
|
||||
}
|
||||
if (tex)
|
||||
{
|
||||
id = tex->getID();
|
||||
}
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
} func;
|
||||
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
|
||||
|
||||
if(LLViewerMedia::textureHasMedia(id))
|
||||
{
|
||||
childSetEnabled("textbox autofix",editable);
|
||||
childSetEnabled("button align",editable);
|
||||
}
|
||||
|
||||
if (identical)
|
||||
{
|
||||
// All selected have the same texture
|
||||
|
|
@ -444,13 +471,6 @@ void LLPanelFace::getState()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(LLViewerMedia::textureHasMedia(id))
|
||||
{
|
||||
childSetEnabled("textbox autofix",editable);
|
||||
childSetEnabled("button align",editable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -356,13 +356,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
|
|||
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
|
||||
(*it)->setGroupID(group_id);
|
||||
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
|
||||
if(gdatap)
|
||||
{
|
||||
childSetValue("group_name", gdatap->mName);
|
||||
childSetToolTip("group_name",gdatap->mName);
|
||||
}
|
||||
|
||||
LLButton* button_apply = findChild<LLButton>("btn_apply");
|
||||
LLButton* button_refresh = findChild<LLButton>("btn_refresh");
|
||||
LLButton* button_create = findChild<LLButton>("btn_create");
|
||||
|
|
@ -425,6 +418,11 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
|
|||
|
||||
getChild<LLUICtrl>("group_name")->setVisible(false);
|
||||
getChild<LLUICtrl>("group_name_editor")->setVisible(true);
|
||||
|
||||
if(button_call)
|
||||
button_call->setVisible(false);
|
||||
if(button_chat)
|
||||
button_chat->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -452,9 +450,24 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
|
|||
|
||||
if(button_apply)
|
||||
button_apply->setVisible(is_member);
|
||||
if(button_call)
|
||||
button_call->setVisible(is_member);
|
||||
if(button_chat)
|
||||
button_chat->setVisible(is_member);
|
||||
}
|
||||
|
||||
reposButtons();
|
||||
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
|
||||
|
||||
if(gdatap)
|
||||
{
|
||||
childSetValue("group_name", gdatap->mName);
|
||||
childSetToolTip("group_name",gdatap->mName);
|
||||
|
||||
//group data is already present, call update manually
|
||||
update(GC_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelGroup::apply(LLPanelGroupTab* tab)
|
||||
|
|
|
|||
|
|
@ -452,6 +452,7 @@ LLPanelGroupSubTab::LLPanelGroupSubTab()
|
|||
: LLPanelGroupTab(),
|
||||
mHeader(NULL),
|
||||
mFooter(NULL),
|
||||
mActivated(false),
|
||||
mSearchEditor(NULL)
|
||||
{
|
||||
}
|
||||
|
|
@ -504,13 +505,14 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
|
|||
mSearchEditor->clear();
|
||||
setSearchFilter("");
|
||||
}
|
||||
|
||||
mActivated = false;
|
||||
}
|
||||
|
||||
void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
|
||||
{
|
||||
if(mSearchFilter == filter)
|
||||
return;
|
||||
lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl;
|
||||
mSearchFilter = filter;
|
||||
LLStringUtil::toLower(mSearchFilter);
|
||||
update(GC_ALL);
|
||||
|
|
@ -518,13 +520,11 @@ void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
|
|||
|
||||
void LLPanelGroupSubTab::activate()
|
||||
{
|
||||
lldebugs << "LLPanelGroupSubTab::activate()" << llendl;
|
||||
setOthersVisible(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelGroupSubTab::deactivate()
|
||||
{
|
||||
lldebugs << "LLPanelGroupSubTab::deactivate()" << llendl;
|
||||
setOthersVisible(FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -534,19 +534,11 @@ void LLPanelGroupSubTab::setOthersVisible(BOOL b)
|
|||
{
|
||||
mHeader->setVisible( b );
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "LLPanelGroupSubTab missing header!" << llendl;
|
||||
}
|
||||
|
||||
if (mFooter)
|
||||
{
|
||||
mFooter->setVisible( b );
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "LLPanelGroupSubTab missing footer!" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action)
|
||||
|
|
@ -875,10 +867,12 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
|||
for (itor = selection.begin();
|
||||
itor != selection.end(); ++itor)
|
||||
{
|
||||
selected_members.push_back( (*itor)->getUUID() );
|
||||
LLUUID member_id = (*itor)->getValue()["uuid"];
|
||||
|
||||
selected_members.push_back( member_id );
|
||||
// Get this member's power mask including any unsaved changes
|
||||
|
||||
U64 powers = getAgentPowersBasedOnRoleChanges((*itor)->getUUID());
|
||||
U64 powers = getAgentPowersBasedOnRoleChanges( member_id );
|
||||
|
||||
allowed_by_all &= powers;
|
||||
allowed_by_some |= powers;
|
||||
|
|
@ -1022,6 +1016,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
|||
//last owner. We should check for this special case
|
||||
// -jwolk
|
||||
check->setEnabled(cb_enable);
|
||||
item->setEnabled(cb_enable);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1098,7 +1093,8 @@ void LLPanelGroupMembersSubTab::handleEjectMembers()
|
|||
for (itor = selection.begin() ;
|
||||
itor != selection.end(); ++itor)
|
||||
{
|
||||
selected_members.push_back((*itor)->getUUID());
|
||||
LLUUID member_id = (*itor)->getValue()["uuid"];
|
||||
selected_members.push_back( member_id );
|
||||
}
|
||||
|
||||
mMembersList->deleteSelectedItems();
|
||||
|
|
@ -1154,7 +1150,8 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
|
|||
for (std::vector<LLScrollListItem*>::iterator itor = selection.begin() ;
|
||||
itor != selection.end(); ++itor)
|
||||
{
|
||||
member_id = (*itor)->getUUID();
|
||||
|
||||
member_id = (*itor)->getValue()["uuid"];
|
||||
|
||||
//see if we requested a change for this member before
|
||||
if ( mMemberRoleChangeData.find(member_id) == mMemberRoleChangeData.end() )
|
||||
|
|
@ -1245,15 +1242,19 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
|
|||
LLScrollListItem* selected = mMembersList->getFirstSelected();
|
||||
if (selected)
|
||||
{
|
||||
LLAvatarActions::showProfile(selected->getUUID());
|
||||
LLUUID member_id = selected->getValue()["uuid"];
|
||||
LLAvatarActions::showProfile( member_id );
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::activate()
|
||||
{
|
||||
LLPanelGroupSubTab::activate();
|
||||
|
||||
update(GC_ALL);
|
||||
if(!mActivated)
|
||||
{
|
||||
update(GC_ALL);
|
||||
mActivated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::deactivate()
|
||||
|
|
@ -1629,7 +1630,9 @@ void LLPanelGroupMembersSubTab::updateMembers()
|
|||
row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
|
||||
row["columns"][2]["font"] = "SANSSERIF_SMALL";
|
||||
|
||||
mMembersList->addElement(row);//, ADD_SORTED);
|
||||
LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED);
|
||||
|
||||
LLUUID id = member->getValue()["uuid"];
|
||||
mHasMatch = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ protected:
|
|||
|
||||
icon_map_t mActionIcons;
|
||||
|
||||
bool mActivated;
|
||||
|
||||
void setOthersVisible(BOOL b);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "llimview.h"
|
||||
#include "llvoicechannel.h"
|
||||
#include "llsidetray.h"
|
||||
#include "llspeakers.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
void LLPanelChatControlPanel::onCallButtonClicked()
|
||||
|
|
@ -244,7 +245,6 @@ void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::str
|
|||
LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
|
||||
mParticipantList(NULL)
|
||||
{
|
||||
mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);
|
||||
}
|
||||
|
||||
BOOL LLPanelGroupControlPanel::postBuild()
|
||||
|
|
@ -263,9 +263,6 @@ LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
|
|||
// virtual
|
||||
void LLPanelGroupControlPanel::draw()
|
||||
{
|
||||
//Remove event does not raised until speakerp->mActivityTimer.hasExpired() is false, see LLSpeakerManager::update()
|
||||
//so we need update it to raise needed event
|
||||
mSpeakerManager->update(true);
|
||||
// Need to resort the participant list if it's in sort by recent speaker order.
|
||||
if (mParticipantList)
|
||||
mParticipantList->updateRecentSpeakersOrder();
|
||||
|
|
@ -306,7 +303,10 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
|
|||
|
||||
// for group and Ad-hoc chat we need to include agent into list
|
||||
if(!mParticipantList)
|
||||
mParticipantList = new LLParticipantList(mSpeakerManager, getChild<LLAvatarList>("speakers_list"), true,false);
|
||||
{
|
||||
LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
|
||||
mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
#include "llvoicechannel.h"
|
||||
#include "llcallingcard.h"
|
||||
|
||||
class LLSpeakerMgr;
|
||||
class LLAvatarList;
|
||||
class LLParticipantList;
|
||||
|
||||
class LLPanelChatControlPanel : public LLPanel
|
||||
|
|
@ -110,7 +108,6 @@ public:
|
|||
|
||||
protected:
|
||||
LLUUID mGroupID;
|
||||
LLSpeakerMgr* mSpeakerManager;
|
||||
|
||||
LLParticipantList* mParticipantList;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
// viewer includes
|
||||
#include "llmimetypes.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
// library includes
|
||||
|
|
@ -83,8 +84,14 @@ BOOL LLPanelLandAudio::postBuild()
|
|||
mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local");
|
||||
childSetCommitCallback("check sound local", onCommitAny, this);
|
||||
|
||||
mRadioVoiceChat = getChild<LLRadioGroup>("parcel_voice_channel");
|
||||
childSetCommitCallback("parcel_voice_channel", onCommitAny, this);
|
||||
mCheckParcelEnableVoice = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel");
|
||||
childSetCommitCallback("parcel_enable_voice_channel", onCommitAny, this);
|
||||
|
||||
// This one is always disabled so no need for a commit callback
|
||||
mCheckEstateDisabledVoice = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_is_estate_disabled");
|
||||
|
||||
mCheckParcelVoiceLocal = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_local");
|
||||
childSetCommitCallback("parcel_enable_voice_channel_local", onCommitAny, this);
|
||||
|
||||
mMusicURLEdit = getChild<LLLineEditor>("music_url");
|
||||
childSetCommitCallback("music_url", onCommitAny, this);
|
||||
|
|
@ -118,19 +125,33 @@ void LLPanelLandAudio::refresh()
|
|||
mMusicUrlCheck->set( parcel->getObscureMusic() );
|
||||
mMusicUrlCheck->setEnabled( can_change_media );
|
||||
|
||||
if(parcel->getParcelFlagAllowVoice())
|
||||
bool allow_voice = parcel->getParcelFlagAllowVoice();
|
||||
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
if (region && region->isVoiceEnabled())
|
||||
{
|
||||
if(parcel->getParcelFlagUseEstateVoiceChannel())
|
||||
mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate);
|
||||
else
|
||||
mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate);
|
||||
mCheckEstateDisabledVoice->setVisible(false);
|
||||
|
||||
mCheckParcelEnableVoice->setVisible(true);
|
||||
mCheckParcelEnableVoice->setEnabled( can_change_media );
|
||||
mCheckParcelEnableVoice->set(allow_voice);
|
||||
|
||||
mCheckParcelVoiceLocal->setEnabled( can_change_media && allow_voice );
|
||||
}
|
||||
else
|
||||
{
|
||||
mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable);
|
||||
// Voice disabled at estate level, overrides parcel settings
|
||||
// Replace the parcel voice checkbox with a disabled one
|
||||
// labelled with an explanatory message
|
||||
mCheckEstateDisabledVoice->setVisible(true);
|
||||
|
||||
mCheckParcelEnableVoice->setVisible(false);
|
||||
mCheckParcelEnableVoice->setEnabled(false);
|
||||
mCheckParcelVoiceLocal->setEnabled(false);
|
||||
}
|
||||
|
||||
mRadioVoiceChat->setEnabled( can_change_media );
|
||||
mCheckParcelEnableVoice->set(allow_voice);
|
||||
mCheckParcelVoiceLocal->set(!parcel->getParcelFlagUseEstateVoiceChannel());
|
||||
|
||||
mMusicURLEdit->setText(parcel->getMusicURL());
|
||||
mMusicURLEdit->setEnabled( can_change_media );
|
||||
|
|
@ -149,30 +170,11 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
|
|||
|
||||
// Extract data from UI
|
||||
BOOL sound_local = self->mCheckSoundLocal->get();
|
||||
int voice_setting = self->mRadioVoiceChat->getSelectedIndex();
|
||||
std::string music_url = self->mMusicURLEdit->getText();
|
||||
U8 obscure_music = self->mMusicUrlCheck->get();
|
||||
|
||||
|
||||
BOOL voice_enabled;
|
||||
BOOL voice_estate_chan;
|
||||
|
||||
switch(voice_setting)
|
||||
{
|
||||
default:
|
||||
case kRadioVoiceChatEstate:
|
||||
voice_enabled = TRUE;
|
||||
voice_estate_chan = TRUE;
|
||||
break;
|
||||
case kRadioVoiceChatPrivate:
|
||||
voice_enabled = TRUE;
|
||||
voice_estate_chan = FALSE;
|
||||
break;
|
||||
case kRadioVoiceChatDisable:
|
||||
voice_enabled = FALSE;
|
||||
voice_estate_chan = FALSE;
|
||||
break;
|
||||
}
|
||||
BOOL voice_enabled = self->mCheckParcelEnableVoice->get();
|
||||
BOOL voice_estate_chan = !self->mCheckParcelVoiceLocal->get();
|
||||
|
||||
// Remove leading/trailing whitespace (common when copying/pasting)
|
||||
LLStringUtil::trim(music_url);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ private:
|
|||
|
||||
private:
|
||||
LLCheckBoxCtrl* mCheckSoundLocal;
|
||||
LLRadioGroup* mRadioVoiceChat;
|
||||
LLCheckBoxCtrl* mCheckParcelEnableVoice;
|
||||
LLCheckBoxCtrl* mCheckEstateDisabledVoice;
|
||||
LLCheckBoxCtrl* mCheckParcelVoiceLocal;
|
||||
LLLineEditor* mMusicURLEdit;
|
||||
LLCheckBoxCtrl* mMusicUrlCheck;
|
||||
|
||||
|
|
|
|||
|
|
@ -305,6 +305,29 @@ void LLLandmarksPanel::updateShowFolderState()
|
|||
);
|
||||
}
|
||||
|
||||
void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus)
|
||||
{
|
||||
if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PROTECTED METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -350,6 +373,36 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
|
|||
return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL;
|
||||
}
|
||||
|
||||
LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
|
||||
const std::string& tab_name,
|
||||
const LLUUID& obj_id,
|
||||
BOOL take_keyboard_focus) const
|
||||
{
|
||||
if (!inventory_list)
|
||||
return NULL;
|
||||
|
||||
LLFolderView* folder_view = inventory_list->getRootFolder();
|
||||
|
||||
LLFolderViewItem* item = folder_view->getItemByID(obj_id);
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name);
|
||||
if (!tab->isExpanded())
|
||||
{
|
||||
tab->changeOpenClose(false);
|
||||
}
|
||||
|
||||
folder_view->setSelection(item, FALSE, take_keyboard_focus);
|
||||
|
||||
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
|
||||
LLRect screen_rc;
|
||||
localRectToScreen(item->getRect(), &screen_rc);
|
||||
accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue()));
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
|
||||
{
|
||||
if(!panel) return;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,11 @@ public:
|
|||
*/
|
||||
void updateShowFolderState();
|
||||
|
||||
/**
|
||||
* Selects item with "obj_id" in one of accordion tabs.
|
||||
*/
|
||||
void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @return true - if current selected panel is not null and selected item is a landmark
|
||||
|
|
@ -81,6 +86,17 @@ protected:
|
|||
bool isReceivedFolderSelected() const;
|
||||
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
|
||||
LLFolderViewItem* getCurSelectedItem() const;
|
||||
|
||||
/**
|
||||
* Selects item with "obj_id" in "inventory_list" and scrolls accordion
|
||||
* scrollbar to show the item.
|
||||
* Returns pointer to the item if it is found in "inventory_list", otherwise NULL.
|
||||
*/
|
||||
LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
|
||||
const std::string& tab_name,
|
||||
const LLUUID& obj_id,
|
||||
BOOL take_keyboard_focus) const;
|
||||
|
||||
void updateSortOrder(LLInventoryPanel* panel, bool byDate);
|
||||
|
||||
//LLRemoteParcelInfoObserver interface
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@
|
|||
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
|
||||
static const std::string COF_TAB_NAME = "cof_tab";
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
|
||||
bool LLPanelOutfitsInventory::sShowDebugEditor = false;
|
||||
|
||||
|
|
@ -267,7 +270,7 @@ void LLPanelOutfitsInventory::onSaveCommit(const std::string& outfit_name)
|
|||
|
||||
if (mAppearanceTabs)
|
||||
{
|
||||
mAppearanceTabs->selectTabByName("outfitslist_tab");
|
||||
mAppearanceTabs->selectTabByName(OUTFITS_TAB_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -503,8 +506,7 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
|
|||
|
||||
if (command_name == "wear")
|
||||
{
|
||||
const BOOL is_my_outfits = (mActivePanel->getName() == "outfitslist_tab");
|
||||
if (!is_my_outfits)
|
||||
if (isCOFPanelActive())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -558,17 +560,15 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
|
|||
|
||||
void LLPanelOutfitsInventory::initTabPanels()
|
||||
{
|
||||
mTabPanels.resize(2);
|
||||
|
||||
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_tab");
|
||||
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>(COF_TAB_NAME);
|
||||
cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mTabPanels[0] = cof_panel;
|
||||
|
||||
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_tab");
|
||||
mTabPanels.push_back(cof_panel);
|
||||
|
||||
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME);
|
||||
myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY);
|
||||
myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mTabPanels[1] = myoutfits_panel;
|
||||
|
||||
mTabPanels.push_back(myoutfits_panel);
|
||||
|
||||
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
|
||||
iter != mTabPanels.end();
|
||||
++iter)
|
||||
|
|
@ -615,19 +615,19 @@ void LLPanelOutfitsInventory::onTabChange()
|
|||
updateVerbs();
|
||||
}
|
||||
|
||||
LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel()
|
||||
BOOL LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) const
|
||||
{
|
||||
return mActivePanel;
|
||||
}
|
||||
|
||||
bool LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel)
|
||||
{
|
||||
for(tabpanels_vec_t::iterator it = mTabPanels.begin();
|
||||
for(tabpanels_vec_t::const_iterator it = mTabPanels.begin();
|
||||
it != mTabPanels.end();
|
||||
++it)
|
||||
{
|
||||
if (*it == panel)
|
||||
return true;
|
||||
return TRUE;
|
||||
}
|
||||
return false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLPanelOutfitsInventory::isCOFPanelActive() const
|
||||
{
|
||||
return (getActivePanel()->getName() == COF_TAB_NAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,24 +78,26 @@ protected:
|
|||
bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const;
|
||||
|
||||
private:
|
||||
LLSidepanelAppearance* mParent;
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
LLTabContainer* mAppearanceTabs;
|
||||
std::string mFilterSubString;
|
||||
LLSidepanelAppearance* mParent;
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
LLTabContainer* mAppearanceTabs;
|
||||
std::string mFilterSubString;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// tab panels
|
||||
LLInventoryPanel* getActivePanel();
|
||||
bool isTabPanel(LLInventoryPanel *panel);
|
||||
LLInventoryPanel* getActivePanel() { return mActivePanel; }
|
||||
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
|
||||
BOOL isTabPanel(LLInventoryPanel *panel) const;
|
||||
|
||||
protected:
|
||||
void initTabPanels();
|
||||
void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
void onTabChange();
|
||||
|
||||
void initTabPanels();
|
||||
void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
void onTabChange();
|
||||
BOOL isCOFPanelActive() const;
|
||||
|
||||
private:
|
||||
LLInventoryPanel* mActivePanel;
|
||||
LLInventoryPanel* mActivePanel;
|
||||
typedef std::vector<LLInventoryPanel *> tabpanels_vec_t;
|
||||
tabpanels_vec_t mTabPanels;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,26 +34,20 @@
|
|||
|
||||
#include "llpanelplaceinfo.h"
|
||||
|
||||
#include "roles_constants.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsecondlifeurls.h"
|
||||
|
||||
#include "llsdutil_math.h"
|
||||
|
||||
#include "llregionhandle.h"
|
||||
#include "message.h"
|
||||
|
||||
#include "lliconctrl.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llexpandabletextbox.h"
|
||||
#include "llpanelpick.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewertexteditor.h"
|
||||
|
||||
LLPanelPlaceInfo::LLPanelPlaceInfo()
|
||||
: LLPanel(),
|
||||
|
|
@ -265,25 +259,6 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelPlaceInfo::handleVisibilityChange(BOOL new_visibility)
|
||||
{
|
||||
LLPanel::handleVisibilityChange(new_visibility);
|
||||
|
||||
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
|
||||
if (!parcel_mgr)
|
||||
return;
|
||||
|
||||
// Remove land selection when panel hides.
|
||||
if (!new_visibility)
|
||||
{
|
||||
if (!parcel_mgr->selectionEmpty())
|
||||
{
|
||||
parcel_mgr->deselectLand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
|
||||
{
|
||||
std::string region_name = mRegionName->getText();
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ public:
|
|||
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
|
||||
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ void handleVisibilityChange (BOOL new_visibility);
|
||||
|
||||
// Create a pick for the location specified
|
||||
// by global_pos.
|
||||
|
|
|
|||
|
|
@ -257,6 +257,25 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data)
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
|
||||
{
|
||||
LLPanel::handleVisibilityChange(new_visibility);
|
||||
|
||||
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
|
||||
if (!parcel_mgr)
|
||||
return;
|
||||
|
||||
// Remove land selection when panel hides.
|
||||
if (!new_visibility)
|
||||
{
|
||||
if (!parcel_mgr->selectionEmpty())
|
||||
{
|
||||
parcel_mgr->deselectUnused();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
|
||||
LLViewerRegion* region,
|
||||
const LLVector3d& pos_global,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ public:
|
|||
|
||||
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
|
||||
|
||||
/*virtual*/ void handleVisibilityChange(BOOL new_visibility);
|
||||
|
||||
// Displays information about the currently selected parcel
|
||||
// without sending a request to the server.
|
||||
// If is_current_parcel true shows "You Are Here" banner.
|
||||
|
|
|
|||
|
|
@ -289,88 +289,91 @@ BOOL LLPanelPlaces::postBuild()
|
|||
|
||||
void LLPanelPlaces::onOpen(const LLSD& key)
|
||||
{
|
||||
if(!mPlaceProfile || !mLandmarkInfo || key.size() == 0)
|
||||
if (!mPlaceProfile || !mLandmarkInfo)
|
||||
return;
|
||||
|
||||
mFilterEditor->clear();
|
||||
onFilterEdit("", false);
|
||||
|
||||
mPlaceInfoType = key["type"].asString();
|
||||
mPosGlobal.setZero();
|
||||
mItem = NULL;
|
||||
isLandmarkEditModeOn = false;
|
||||
togglePlaceInfoPanel(TRUE);
|
||||
|
||||
if (mPlaceInfoType == AGENT_INFO_TYPE)
|
||||
if (key.size() != 0)
|
||||
{
|
||||
mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
|
||||
}
|
||||
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
|
||||
{
|
||||
mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
|
||||
mFilterEditor->clear();
|
||||
onFilterEdit("", false);
|
||||
|
||||
if (key.has("x") && key.has("y") && key.has("z"))
|
||||
mPlaceInfoType = key["type"].asString();
|
||||
mPosGlobal.setZero();
|
||||
mItem = NULL;
|
||||
isLandmarkEditModeOn = false;
|
||||
togglePlaceInfoPanel(TRUE);
|
||||
|
||||
if (mPlaceInfoType == AGENT_INFO_TYPE)
|
||||
{
|
||||
mPosGlobal = LLVector3d(key["x"].asReal(),
|
||||
key["y"].asReal(),
|
||||
key["z"].asReal());
|
||||
mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
|
||||
}
|
||||
else
|
||||
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
|
||||
{
|
||||
mPosGlobal = gAgent.getPositionGlobal();
|
||||
mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
|
||||
|
||||
if (key.has("x") && key.has("y") && key.has("z"))
|
||||
{
|
||||
mPosGlobal = LLVector3d(key["x"].asReal(),
|
||||
key["y"].asReal(),
|
||||
key["z"].asReal());
|
||||
}
|
||||
else
|
||||
{
|
||||
mPosGlobal = gAgent.getPositionGlobal();
|
||||
}
|
||||
|
||||
mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
|
||||
|
||||
// Disable Save button because there is no item to save yet.
|
||||
// The button will be enabled in onLandmarkLoaded callback.
|
||||
mSaveBtn->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
|
||||
|
||||
// Disable Save button because there is no item to save yet.
|
||||
// The button will be enabled in onLandmarkLoaded callback.
|
||||
mSaveBtn->setEnabled(FALSE);
|
||||
}
|
||||
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
|
||||
{
|
||||
mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
|
||||
|
||||
LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
setItem(item);
|
||||
}
|
||||
else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
|
||||
{
|
||||
if (key.has("id"))
|
||||
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
|
||||
{
|
||||
LLUUID parcel_id = key["id"].asUUID();
|
||||
mPlaceProfile->setParcelID(parcel_id);
|
||||
mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
|
||||
|
||||
// query the server to get the global 3D position of this
|
||||
// parcel - we need this for teleport/mapping functions.
|
||||
mRemoteParcelObserver->setParcelID(parcel_id);
|
||||
LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
setItem(item);
|
||||
}
|
||||
else
|
||||
else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
|
||||
{
|
||||
mPosGlobal = LLVector3d(key["x"].asReal(),
|
||||
key["y"].asReal(),
|
||||
key["z"].asReal());
|
||||
if (key.has("id"))
|
||||
{
|
||||
LLUUID parcel_id = key["id"].asUUID();
|
||||
mPlaceProfile->setParcelID(parcel_id);
|
||||
|
||||
// query the server to get the global 3D position of this
|
||||
// parcel - we need this for teleport/mapping functions.
|
||||
mRemoteParcelObserver->setParcelID(parcel_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPosGlobal = LLVector3d(key["x"].asReal(),
|
||||
key["y"].asReal(),
|
||||
key["z"].asReal());
|
||||
mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
|
||||
}
|
||||
|
||||
mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
|
||||
}
|
||||
else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
|
||||
{
|
||||
S32 index = key["id"].asInteger();
|
||||
|
||||
const LLTeleportHistoryStorage::slurl_list_t& hist_items =
|
||||
LLTeleportHistoryStorage::getInstance()->getItems();
|
||||
|
||||
mPosGlobal = hist_items[index].mGlobalPos;
|
||||
|
||||
mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
|
||||
mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
|
||||
}
|
||||
|
||||
mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
|
||||
updateVerbs();
|
||||
}
|
||||
else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
|
||||
{
|
||||
S32 index = key["id"].asInteger();
|
||||
|
||||
const LLTeleportHistoryStorage::slurl_list_t& hist_items =
|
||||
LLTeleportHistoryStorage::getInstance()->getItems();
|
||||
|
||||
mPosGlobal = hist_items[index].mGlobalPos;
|
||||
|
||||
mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
|
||||
mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
|
||||
}
|
||||
|
||||
updateVerbs();
|
||||
|
||||
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
|
||||
if (!parcel_mgr)
|
||||
|
|
@ -388,9 +391,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)
|
|||
{
|
||||
parcel_mgr->removeObserver(mParcelObserver);
|
||||
|
||||
// Clear the reference to selection to allow its removal in deselectUnused().
|
||||
mParcel.clear();
|
||||
|
||||
if (!parcel_mgr->selectionEmpty())
|
||||
{
|
||||
parcel_mgr->deselectLand();
|
||||
parcel_mgr->deselectUnused();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -765,23 +771,23 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
|
|||
mPickPanel->reshape(rect.getWidth(), rect.getHeight());
|
||||
mPickPanel->setRect(rect);
|
||||
}
|
||||
else if (item == "add_to_favbar")
|
||||
{
|
||||
if ( mItem.notNull() )
|
||||
{
|
||||
const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
if ( favorites_id.notNull() )
|
||||
{
|
||||
copy_inventory_item(gAgent.getID(),
|
||||
mItem->getPermissions().getOwner(),
|
||||
mItem->getUUID(),
|
||||
favorites_id,
|
||||
std::string(),
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item == "add_to_favbar")
|
||||
{
|
||||
if ( mItem.notNull() )
|
||||
{
|
||||
const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
if ( favorites_id.notNull() )
|
||||
{
|
||||
copy_inventory_item(gAgent.getID(),
|
||||
mItem->getPermissions().getOwner(),
|
||||
mItem->getUUID(),
|
||||
favorites_id,
|
||||
std::string(),
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPlaces::onBackButtonClicked()
|
||||
|
|
@ -826,6 +832,14 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
|
|||
|
||||
mLandmarkInfo->setVisible(FALSE);
|
||||
}
|
||||
else if (mPlaceInfoType == AGENT_INFO_TYPE)
|
||||
{
|
||||
LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
|
||||
|
||||
// Clear reference to parcel selection when closing place profile panel.
|
||||
// LLViewerParcelMgr removes the selection if it has 1 reference to it.
|
||||
mParcel.clear();
|
||||
}
|
||||
}
|
||||
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE ||
|
||||
mPlaceInfoType == LANDMARK_INFO_TYPE)
|
||||
|
|
@ -842,6 +856,33 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
|
|||
|
||||
mPlaceProfile->setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLLandmarksPanel* landmarks_panel =
|
||||
dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
|
||||
if (landmarks_panel && mItem.notNull())
|
||||
{
|
||||
// If a landmark info is being closed we open the landmarks tab
|
||||
// and set this landmark selected.
|
||||
mTabContainer->selectTabPanel(landmarks_panel);
|
||||
|
||||
landmarks_panel->setItemSelected(mItem->getUUID(), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility)
|
||||
{
|
||||
LLPanel::handleVisibilityChange(new_visibility);
|
||||
|
||||
if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE)
|
||||
{
|
||||
LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
|
||||
|
||||
// Clear reference to parcel selection when closing places panel.
|
||||
mParcel.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ private:
|
|||
void togglePickPanel(BOOL visible);
|
||||
void togglePlaceInfoPanel(BOOL visible);
|
||||
|
||||
/*virtual*/ void handleVisibilityChange(BOOL new_visibility);
|
||||
|
||||
void updateVerbs();
|
||||
|
||||
LLPanelPlaceInfo* getCurrentInfoPanel();
|
||||
|
|
|
|||
|
|
@ -1036,7 +1036,7 @@ void LLTeleportHistoryPanel::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool
|
|||
bool LLTeleportHistoryPanel::isAccordionCollapsedByUser(LLUICtrl* acc_tab)
|
||||
{
|
||||
LLSD param = acc_tab->getValue();
|
||||
if(!param.has("acc_collapsed"))
|
||||
if(!param.has(COLLAPSED_BY_USER))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ LLParticipantList::~LLParticipantList()
|
|||
delete mParticipantListMenu;
|
||||
mParticipantListMenu = NULL;
|
||||
}
|
||||
|
||||
mAvatarList->setContextMenu(NULL);
|
||||
}
|
||||
|
||||
void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
|
||||
|
|
@ -431,6 +433,10 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
|
|||
LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
|
||||
"menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
|
||||
// Don't show sort options for P2P chat
|
||||
bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
|
||||
main_menu->setItemVisible("SortByName", is_sort_visible);
|
||||
main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible);
|
||||
main_menu->setItemVisible("Moderator Options", isGroupModerator());
|
||||
main_menu->arrangeAndClear();
|
||||
|
||||
|
|
@ -456,11 +462,6 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const
|
|||
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false);
|
||||
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false);
|
||||
}
|
||||
|
||||
// Don't show sort options for P2P chat
|
||||
bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
|
||||
LLMenuGL::sMenuContainer->childSetVisible("SortByName", is_sort_visible);
|
||||
LLMenuGL::sMenuContainer->childSetVisible("SortByRecentSpeakers", is_sort_visible);
|
||||
}
|
||||
|
||||
void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata)
|
||||
|
|
|
|||
|
|
@ -380,138 +380,53 @@ void LLPreviewTexture::updateDimensions()
|
|||
|
||||
mUpdateDimensions = FALSE;
|
||||
|
||||
S32 image_height = llmax(1, mImage->getFullHeight());
|
||||
S32 image_width = llmax(1, mImage->getFullWidth());
|
||||
// Attempt to make the image 1:1 on screen.
|
||||
// If that fails, cut width by half.
|
||||
S32 client_width = image_width;
|
||||
S32 client_height = image_height;
|
||||
S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
|
||||
S32 vert_pad = PREVIEW_HEADER_SIZE + 2 * CLIENT_RECT_VPAD + LLPANEL_BORDER_WIDTH;
|
||||
S32 max_client_width = gViewerWindow->getWindowWidthScaled() - horiz_pad;
|
||||
S32 max_client_height = gViewerWindow->getWindowHeightScaled() - vert_pad;
|
||||
|
||||
if (mAspectRatio > 0.f)
|
||||
{
|
||||
client_height = llceil((F32)client_width / mAspectRatio);
|
||||
}
|
||||
|
||||
while ((client_width > max_client_width) ||
|
||||
(client_height > max_client_height ))
|
||||
{
|
||||
client_width /= 2;
|
||||
client_height /= 2;
|
||||
}
|
||||
|
||||
S32 view_width = client_width + horiz_pad;
|
||||
S32 view_height = client_height + vert_pad;
|
||||
|
||||
// set text on dimensions display (should be moved out of here and into a callback of some sort)
|
||||
childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth()));
|
||||
childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight()));
|
||||
|
||||
|
||||
LLRect dim_rect;
|
||||
childGetRect("dimensions", dim_rect);
|
||||
|
||||
S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
|
||||
|
||||
// add space for dimensions and aspect ratio
|
||||
S32 info_height = 0;
|
||||
LLRect aspect_rect;
|
||||
childGetRect("combo_aspect_ratio", aspect_rect);
|
||||
S32 aspect_height = aspect_rect.getHeight();
|
||||
info_height += aspect_height + CLIENT_RECT_VPAD;
|
||||
view_height += info_height;
|
||||
|
||||
S32 button_height = 0;
|
||||
|
||||
// add space for buttons
|
||||
view_height += (BTN_HEIGHT + CLIENT_RECT_VPAD) * 3;
|
||||
button_height = (BTN_HEIGHT + PREVIEW_PAD) * 3;
|
||||
S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
|
||||
|
||||
view_width = llmax(view_width, getMinWidth());
|
||||
view_height = llmax(view_height, getMinHeight());
|
||||
|
||||
if (view_height != mLastHeight || view_width != mLastWidth)
|
||||
{
|
||||
if (getHost())
|
||||
{
|
||||
getHost()->growToFit(view_width, view_height);
|
||||
reshape( view_width, view_height );
|
||||
setOrigin( 0, getHost()->getRect().getHeight() - (view_height + PREVIEW_HEADER_SIZE) );
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 old_top = getRect().mTop;
|
||||
S32 old_left = getRect().mLeft;
|
||||
reshape( view_width, view_height );
|
||||
S32 new_bottom = old_top - getRect().getHeight();
|
||||
setOrigin( old_left, new_bottom );
|
||||
}
|
||||
|
||||
// Try to keep whole view onscreen, don't allow partial offscreen.
|
||||
if (getHost())
|
||||
gFloaterView->adjustToFitScreen(getHost(), FALSE);
|
||||
else
|
||||
gFloaterView->adjustToFitScreen(this, FALSE);
|
||||
|
||||
if (image_height > 1 && image_width > 1)
|
||||
{
|
||||
// Resize until we know the image's height
|
||||
mLastWidth = view_width;
|
||||
mLastHeight = view_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mUserResized)
|
||||
{
|
||||
// clamp texture size to fit within actual size of floater after attempting resize
|
||||
client_width = llmin(client_width, getRect().getWidth() - horiz_pad);
|
||||
client_height = llmin(client_height, getRect().getHeight() - PREVIEW_HEADER_SIZE
|
||||
- (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height);
|
||||
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
|
||||
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
|
||||
client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
client_width = getRect().getWidth() - horiz_pad;
|
||||
if (mAspectRatio > 0)
|
||||
{
|
||||
client_height = llround(client_width / mAspectRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
client_height = getRect().getHeight() - vert_pad;
|
||||
}
|
||||
}
|
||||
|
||||
S32 max_height = getRect().getHeight() - PREVIEW_BORDER - button_height
|
||||
- CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE;
|
||||
S32 client_width = client_rect.getWidth();
|
||||
S32 client_height = client_rect.getHeight();
|
||||
|
||||
if (mAspectRatio > 0.f)
|
||||
{
|
||||
max_height = llmax(max_height, 1);
|
||||
|
||||
if (client_height > max_height)
|
||||
if(mAspectRatio > 1.f)
|
||||
{
|
||||
client_height = max_height;
|
||||
client_width = llround(client_height * mAspectRatio);
|
||||
client_height = llceil((F32)client_width / mAspectRatio);
|
||||
if(client_height > client_rect.getHeight())
|
||||
{
|
||||
client_height = client_rect.getHeight();
|
||||
client_width = llceil((F32)client_height * mAspectRatio);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
client_width = llceil((F32)client_height * mAspectRatio);
|
||||
if(client_width > client_rect.getWidth())
|
||||
{
|
||||
client_width = client_rect.getWidth();
|
||||
client_height = llceil((F32)client_width / mAspectRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 max_width = getRect().getWidth() - horiz_pad;
|
||||
|
||||
client_height = llclamp(client_height, 1, max_height);
|
||||
client_width = llclamp(client_width, 1, max_width);
|
||||
}
|
||||
|
||||
LLRect window_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
|
||||
window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD;
|
||||
mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() + (client_height / 2), client_width, client_height);
|
||||
|
||||
mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height);
|
||||
|
||||
// Hide the aspect ratio label if the window is too narrow
|
||||
// Assumes the label should be to the right of the dimensions
|
||||
LLRect dim_rect, aspect_label_rect;
|
||||
LLRect aspect_label_rect;
|
||||
childGetRect("aspect_ratio", aspect_label_rect);
|
||||
childGetRect("dimensions", dim_rect);
|
||||
childSetVisible("aspect_ratio", dim_rect.mRight < aspect_label_rect.mLeft);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
#include "llvoavatar.h"
|
||||
#include "llworld.h"
|
||||
|
||||
const F32 SPEAKER_TIMEOUT = 10.f; // seconds of not being on voice channel before removed from list of active speakers
|
||||
const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
|
||||
const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
|
||||
|
||||
|
|
@ -73,8 +72,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy
|
|||
}
|
||||
|
||||
gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id));
|
||||
|
||||
mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -164,6 +161,89 @@ bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPo
|
|||
return( lhs->mDisplayName.compare(rhs->mDisplayName) < 0 );
|
||||
}
|
||||
|
||||
LLSpeakerActionTimer::LLSpeakerActionTimer(action_callback_t action_cb, F32 action_period, const LLUUID& speaker_id)
|
||||
: LLEventTimer(action_period)
|
||||
, mActionCallback(action_cb)
|
||||
, mSpeakerId(speaker_id)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLSpeakerActionTimer::tick()
|
||||
{
|
||||
if (mActionCallback)
|
||||
{
|
||||
return (BOOL)mActionCallback(mSpeakerId);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLSpeakersDelayActionsStorage::LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay)
|
||||
: mActionCallback(action_cb)
|
||||
, mActionDelay(action_delay)
|
||||
{
|
||||
}
|
||||
|
||||
LLSpeakersDelayActionsStorage::~LLSpeakersDelayActionsStorage()
|
||||
{
|
||||
removeAllTimers();
|
||||
}
|
||||
|
||||
void LLSpeakersDelayActionsStorage::setActionTimer(const LLUUID& speaker_id)
|
||||
{
|
||||
bool not_found = true;
|
||||
if (mActionTimersMap.size() > 0)
|
||||
{
|
||||
not_found = mActionTimersMap.find(speaker_id) == mActionTimersMap.end();
|
||||
}
|
||||
|
||||
// If there is already a started timer for the passed UUID don't do anything.
|
||||
if (not_found)
|
||||
{
|
||||
// Starting a timer to remove an participant after delay is completed
|
||||
mActionTimersMap.insert(LLSpeakerActionTimer::action_value_t(speaker_id,
|
||||
new LLSpeakerActionTimer(
|
||||
boost::bind(&LLSpeakersDelayActionsStorage::onTimerActionCallback, this, _1),
|
||||
mActionDelay, speaker_id)));
|
||||
}
|
||||
}
|
||||
|
||||
void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
|
||||
{
|
||||
if (mActionTimersMap.size() == 0) return;
|
||||
|
||||
LLSpeakerActionTimer::action_timer_iter_t it_speaker = mActionTimersMap.find(speaker_id);
|
||||
|
||||
if (it_speaker != mActionTimersMap.end())
|
||||
{
|
||||
delete it_speaker->second;
|
||||
mActionTimersMap.erase(it_speaker);
|
||||
}
|
||||
}
|
||||
|
||||
void LLSpeakersDelayActionsStorage::removeAllTimers()
|
||||
{
|
||||
LLSpeakerActionTimer::action_timer_iter_t iter = mActionTimersMap.begin();
|
||||
for (; iter != mActionTimersMap.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
mActionTimersMap.clear();
|
||||
}
|
||||
|
||||
bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_id)
|
||||
{
|
||||
unsetActionTimer(speaker_id);
|
||||
|
||||
if (mActionCallback)
|
||||
{
|
||||
mActionCallback(speaker_id);
|
||||
}
|
||||
|
||||
// do not return true to avoid deleting of an timer twice:
|
||||
// in LLSpeakersDelayActionsStorage::unsetActionTimer() & LLEventTimer::updateClass()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLSpeakerMgr
|
||||
|
|
@ -172,10 +252,14 @@ bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPo
|
|||
LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
|
||||
mVoiceChannel(channelp)
|
||||
{
|
||||
static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
|
||||
|
||||
mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
|
||||
}
|
||||
|
||||
LLSpeakerMgr::~LLSpeakerMgr()
|
||||
{
|
||||
delete mSpeakerDelayRemover;
|
||||
}
|
||||
|
||||
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
|
||||
|
|
@ -198,7 +282,6 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
|
|||
{
|
||||
// keep highest priority status (lowest value) instead of overriding current value
|
||||
speakerp->mStatus = llmin(speakerp->mStatus, status);
|
||||
speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
|
||||
// RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
|
||||
// we need to override speakers that we think are objects when we find out they are really
|
||||
// residents
|
||||
|
|
@ -210,6 +293,8 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
|
|||
}
|
||||
}
|
||||
|
||||
mSpeakerDelayRemover->unsetActionTimer(speakerp->mID);
|
||||
|
||||
return speakerp;
|
||||
}
|
||||
|
||||
|
|
@ -314,7 +399,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
|
|||
S32 sort_index = 0;
|
||||
speaker_list_t::iterator sorted_speaker_it;
|
||||
for(sorted_speaker_it = mSpeakersSorted.begin();
|
||||
sorted_speaker_it != mSpeakersSorted.end(); )
|
||||
sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it)
|
||||
{
|
||||
LLPointer<LLSpeaker> speakerp = *sorted_speaker_it;
|
||||
|
||||
|
|
@ -327,19 +412,6 @@ void LLSpeakerMgr::update(BOOL resort_ok)
|
|||
|
||||
// stuff sort ordinal into speaker so the ui can sort by this value
|
||||
speakerp->mSortIndex = sort_index++;
|
||||
|
||||
// remove speakers that have been gone too long
|
||||
if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL && speakerp->mActivityTimer.hasExpired())
|
||||
{
|
||||
fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "remove");
|
||||
|
||||
mSpeakers.erase(speakerp->mID);
|
||||
sorted_speaker_it = mSpeakersSorted.erase(sorted_speaker_it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++sorted_speaker_it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,6 +435,35 @@ void LLSpeakerMgr::updateSpeakerList()
|
|||
}
|
||||
}
|
||||
|
||||
void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
|
||||
{
|
||||
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
|
||||
speakerp->mDotColor = INACTIVE_COLOR;
|
||||
mSpeakerDelayRemover->setActionTimer(speakerp->mID);
|
||||
}
|
||||
|
||||
bool LLSpeakerMgr::removeSpeaker(const LLUUID& speaker_id)
|
||||
{
|
||||
mSpeakers.erase(speaker_id);
|
||||
|
||||
speaker_list_t::iterator sorted_speaker_it = mSpeakersSorted.begin();
|
||||
|
||||
for(; sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it)
|
||||
{
|
||||
if (speaker_id == (*sorted_speaker_it)->mID)
|
||||
{
|
||||
mSpeakersSorted.erase(sorted_speaker_it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fireEvent(new LLSpeakerListChangeEvent(this, speaker_id), "remove");
|
||||
|
||||
update(TRUE);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LLPointer<LLSpeaker> LLSpeakerMgr::findSpeaker(const LLUUID& speaker_id)
|
||||
{
|
||||
//In some conditions map causes crash if it is empty(Windows only), adding check (EK)
|
||||
|
|
@ -511,9 +612,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
|||
{
|
||||
if (agent_data["transition"].asString() == "LEAVE" && speakerp.notNull())
|
||||
{
|
||||
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
|
||||
speakerp->mDotColor = INACTIVE_COLOR;
|
||||
speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
|
||||
setSpeakerNotInChannel(speakerp);
|
||||
}
|
||||
else if (agent_data["transition"].asString() == "ENTER")
|
||||
{
|
||||
|
|
@ -563,9 +662,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
|||
std::string agent_transition = update_it->second.asString();
|
||||
if (agent_transition == "LEAVE" && speakerp.notNull())
|
||||
{
|
||||
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
|
||||
speakerp->mDotColor = INACTIVE_COLOR;
|
||||
speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
|
||||
setSpeakerNotInChannel(speakerp);
|
||||
}
|
||||
else if ( agent_transition == "ENTER")
|
||||
{
|
||||
|
|
@ -734,12 +831,13 @@ void LLActiveSpeakerMgr::updateSpeakerList()
|
|||
mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
|
||||
|
||||
// always populate from active voice channel
|
||||
if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel)
|
||||
if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel) //MA: seems this is always false
|
||||
{
|
||||
fireEvent(new LLSpeakerListChangeEvent(this, LLUUID::null), "clear");
|
||||
mSpeakers.clear();
|
||||
mSpeakersSorted.clear();
|
||||
mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
|
||||
mSpeakerDelayRemover->removeAllTimers();
|
||||
}
|
||||
LLSpeakerMgr::updateSpeakerList();
|
||||
|
||||
|
|
@ -800,9 +898,7 @@ void LLLocalSpeakerMgr::updateSpeakerList()
|
|||
LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
|
||||
if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
|
||||
{
|
||||
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
|
||||
speakerp->mDotColor = INACTIVE_COLOR;
|
||||
speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
|
||||
setSpeakerNotInChannel(speakerp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ public:
|
|||
F32 mLastSpokeTime; // timestamp when this speaker last spoke
|
||||
F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?)
|
||||
std::string mDisplayName; // cache user name for this speaker
|
||||
LLFrameTimer mActivityTimer; // time out speakers when they are not part of current voice channel
|
||||
BOOL mHasSpoken; // has this speaker said anything this session?
|
||||
BOOL mHasLeftCurrentCall; // has this speaker left the current voice call?
|
||||
LLColor4 mDotColor;
|
||||
|
|
@ -120,6 +119,92 @@ private:
|
|||
const LLUUID& mSpeakerID;
|
||||
};
|
||||
|
||||
/**
|
||||
* class LLSpeakerActionTimer
|
||||
*
|
||||
* Implements a timer that calls stored callback action for stored speaker after passed period.
|
||||
*
|
||||
* Action is called until callback returns "true".
|
||||
* In this case the timer will be removed via LLEventTimer::updateClass().
|
||||
* Otherwise it should be deleted manually in place where it is used.
|
||||
* If action callback is not set timer will tick only once and deleted.
|
||||
*/
|
||||
class LLSpeakerActionTimer : public LLEventTimer
|
||||
{
|
||||
public:
|
||||
typedef boost::function<bool(const LLUUID&)> action_callback_t;
|
||||
typedef std::map<LLUUID, LLSpeakerActionTimer*> action_timers_map_t;
|
||||
typedef action_timers_map_t::value_type action_value_t;
|
||||
typedef action_timers_map_t::const_iterator action_timer_const_iter_t;
|
||||
typedef action_timers_map_t::iterator action_timer_iter_t;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param action_cb - callback which will be called each time after passed action period.
|
||||
* @param action_period - time in seconds timer should tick.
|
||||
* @param speaker_id - LLUUID of speaker which will be passed into action callback.
|
||||
*/
|
||||
LLSpeakerActionTimer(action_callback_t action_cb, F32 action_period, const LLUUID& speaker_id);
|
||||
virtual ~LLSpeakerActionTimer() {};
|
||||
|
||||
/**
|
||||
* Implements timer "tick".
|
||||
*
|
||||
* If action callback is not specified returns true. Instance will be deleted by LLEventTimer::updateClass().
|
||||
*/
|
||||
virtual BOOL tick();
|
||||
|
||||
private:
|
||||
action_callback_t mActionCallback;
|
||||
LLUUID mSpeakerId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a functionality to store actions for speakers with delay.
|
||||
* Is based on LLSpeakerActionTimer.
|
||||
*/
|
||||
class LLSpeakersDelayActionsStorage
|
||||
{
|
||||
public:
|
||||
LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay);
|
||||
~LLSpeakersDelayActionsStorage();
|
||||
|
||||
/**
|
||||
* Sets new LLSpeakerActionTimer with passed speaker UUID.
|
||||
*/
|
||||
void setActionTimer(const LLUUID& speaker_id);
|
||||
|
||||
/**
|
||||
* Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and deletes it.
|
||||
*
|
||||
* @see onTimerActionCallback()
|
||||
*/
|
||||
void unsetActionTimer(const LLUUID& speaker_id);
|
||||
|
||||
void removeAllTimers();
|
||||
private:
|
||||
/**
|
||||
* Callback of the each instance of LLSpeakerActionTimer.
|
||||
*
|
||||
* Unsets an appropriate timer instance and calls action callback for specified speacker_id.
|
||||
* It always returns false to not use LLEventTimer::updateClass functionality of timer deleting.
|
||||
*
|
||||
* @see unsetActionTimer()
|
||||
*/
|
||||
bool onTimerActionCallback(const LLUUID& speaker_id);
|
||||
|
||||
LLSpeakerActionTimer::action_timers_map_t mActionTimersMap;
|
||||
LLSpeakerActionTimer::action_callback_t mActionCallback;
|
||||
|
||||
/**
|
||||
* Delay to call action callback for speakers after timer was set.
|
||||
*/
|
||||
F32 mActionDelay;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLSpeakerMgr : public LLOldEvents::LLObservable
|
||||
{
|
||||
public:
|
||||
|
|
@ -144,6 +229,8 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void updateSpeakerList();
|
||||
void setSpeakerNotInChannel(LLSpeaker* speackerp);
|
||||
bool removeSpeaker(const LLUUID& speaker_id);
|
||||
|
||||
typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
|
||||
speaker_map_t mSpeakers;
|
||||
|
|
@ -151,6 +238,11 @@ protected:
|
|||
speaker_list_t mSpeakersSorted;
|
||||
LLFrameTimer mSpeechTimer;
|
||||
LLVoiceChannel* mVoiceChannel;
|
||||
|
||||
/**
|
||||
* time out speakers when they are not part of current session
|
||||
*/
|
||||
LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
|
||||
};
|
||||
|
||||
class LLIMSpeakerMgr : public LLSpeakerMgr
|
||||
|
|
|
|||
|
|
@ -1140,6 +1140,10 @@ LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWea
|
|||
BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions
|
||||
{
|
||||
//llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating
|
||||
if (mInfo != NULL) // above llassert(), but softened into a warning
|
||||
{
|
||||
llwarns << "BAD STUFF! mInfo != NULL" << llendl;
|
||||
}
|
||||
mInfo = info;
|
||||
//mID = info->mID; // No ID
|
||||
|
||||
|
|
|
|||
|
|
@ -1103,7 +1103,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
|
|||
{
|
||||
if (op == TEXTURE_CANCEL)
|
||||
mViewModel->resetDirty();
|
||||
else
|
||||
// If the "no_commit_on_selection" parameter is set
|
||||
// we get dirty only when user presses OK in the picker
|
||||
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
|
||||
else if (mCommitOnSelection || op == TEXTURE_SELECT)
|
||||
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
|
||||
|
||||
if( floaterp->isDirty() )
|
||||
|
|
@ -1125,7 +1128,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
|
|||
{
|
||||
// If the "no_commit_on_selection" parameter is set
|
||||
// we commit only when user presses OK in the picker
|
||||
// (i.e. op == TEXTURE_SELECT) or changes texture via DnD.
|
||||
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
|
||||
if (mCommitOnSelection || op == TEXTURE_SELECT)
|
||||
onCommit();
|
||||
}
|
||||
|
|
@ -1167,6 +1170,9 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
|||
{
|
||||
if(doDrop(item))
|
||||
{
|
||||
if (!mCommitOnSelection)
|
||||
mViewModel->setDirty();
|
||||
|
||||
// This removes the 'Multiple' overlay, since
|
||||
// there is now only one texture selected.
|
||||
setTentative( FALSE );
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ public:
|
|||
Optional<std::string> default_image_name;
|
||||
Optional<bool> allow_no_texture;
|
||||
Optional<bool> can_apply_immediately;
|
||||
Optional<bool> no_commit_on_selection; // don't commit unless it's DnD or OK button press
|
||||
Optional<bool> no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty
|
||||
// only on DnD or when OK is pressed in the picker
|
||||
Optional<S32> label_width;
|
||||
Optional<LLUIColor> border_color;
|
||||
|
||||
|
|
|
|||
|
|
@ -661,78 +661,317 @@ static bool needs_tooltip(LLSelectNode* nodep)
|
|||
return false;
|
||||
}
|
||||
|
||||
BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
|
||||
|
||||
BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
|
||||
{
|
||||
if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
|
||||
if (!mHoverPick.isValid()) return TRUE;
|
||||
|
||||
LLViewerObject* hover_object = mHoverPick.getObject();
|
||||
|
||||
// update hover object and hover parcel
|
||||
LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace);
|
||||
|
||||
if (mHoverPick.mPickType == LLPickInfo::PICK_LAND)
|
||||
LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
|
||||
//
|
||||
// Do not show hover for land unless prefs are set to allow it.
|
||||
//
|
||||
|
||||
if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE;
|
||||
|
||||
// Didn't hit an object, but since we have a land point we
|
||||
// must be hovering over land.
|
||||
|
||||
LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
|
||||
LLUUID owner;
|
||||
S32 width = 0;
|
||||
S32 height = 0;
|
||||
|
||||
if ( hover_parcel )
|
||||
{
|
||||
LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
|
||||
owner = hover_parcel->getOwnerID();
|
||||
width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
|
||||
height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
|
||||
}
|
||||
|
||||
std::string tooltip_msg;
|
||||
std::string line;
|
||||
|
||||
if ( hover_object )
|
||||
|
||||
// Line: "Land"
|
||||
line.clear();
|
||||
line.append(LLTrans::getString("TooltipLand"));
|
||||
if (hover_parcel)
|
||||
{
|
||||
if ( hover_object->isHUDAttachment() )
|
||||
line.append(hover_parcel->getName());
|
||||
}
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
|
||||
// Line: "Owner: James Linden"
|
||||
line.clear();
|
||||
line.append(LLTrans::getString("TooltipOwner") + " ");
|
||||
|
||||
if ( hover_parcel )
|
||||
{
|
||||
std::string name;
|
||||
if (LLUUID::null == owner)
|
||||
{
|
||||
// no hover tips for HUD elements, since they can obscure
|
||||
// what the HUD is displaying
|
||||
line.append(LLTrans::getString("TooltipPublic"));
|
||||
}
|
||||
else if (hover_parcel->getIsGroupOwned())
|
||||
{
|
||||
if (gCacheName->getGroupName(owner, name))
|
||||
{
|
||||
line.append(name);
|
||||
line.append(LLTrans::getString("TooltipIsGroup"));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("RetrievingData"));
|
||||
}
|
||||
}
|
||||
else if(gCacheName->getFullName(owner, name))
|
||||
{
|
||||
line.append(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("RetrievingData"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("RetrievingData"));
|
||||
}
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
|
||||
// Line: "no fly, not safe, no build"
|
||||
|
||||
// Don't display properties for your land. This is just
|
||||
// confusing, because you can do anything on your own land.
|
||||
if ( hover_parcel && owner != gAgent.getID() )
|
||||
{
|
||||
S32 words = 0;
|
||||
|
||||
line.clear();
|
||||
// JC - Keep this in the same order as the checkboxes
|
||||
// on the land info panel
|
||||
if ( !hover_parcel->getAllowModify() )
|
||||
{
|
||||
if ( hover_parcel->getAllowGroupModify() )
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagGroupBuild"));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagNoBuild"));
|
||||
}
|
||||
words++;
|
||||
}
|
||||
|
||||
if ( !hover_parcel->getAllowTerraform() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
line.append(LLTrans::getString("TooltipFlagNoEdit"));
|
||||
words++;
|
||||
}
|
||||
|
||||
if ( hover_parcel->getAllowDamage() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
line.append(LLTrans::getString("TooltipFlagNotSafe"));
|
||||
words++;
|
||||
}
|
||||
|
||||
// Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04
|
||||
if ( !hover_parcel->getAllowFly() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
line.append(LLTrans::getString("TooltipFlagNoFly"));
|
||||
words++;
|
||||
}
|
||||
|
||||
if ( !hover_parcel->getAllowOtherScripts() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
if ( hover_parcel->getAllowGroupScripts() )
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagGroupScripts"));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagNoScripts"));
|
||||
}
|
||||
|
||||
words++;
|
||||
}
|
||||
|
||||
if (words)
|
||||
{
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
}
|
||||
}
|
||||
|
||||
if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
|
||||
line = LLTrans::getString("TooltipForSaleL$", args);
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
}
|
||||
|
||||
// trim last newlines
|
||||
if (!tooltip_msg.empty())
|
||||
{
|
||||
tooltip_msg.erase(tooltip_msg.size() - 1);
|
||||
LLToolTipMgr::instance().show(tooltip_msg);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg)
|
||||
{
|
||||
if ( hover_object->isHUDAttachment() )
|
||||
{
|
||||
// no hover tips for HUD elements, since they can obscure
|
||||
// what the HUD is displaying
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( hover_object->isAttachment() )
|
||||
{
|
||||
// get root of attachment then parent, which is avatar
|
||||
LLViewerObject* root_edit = hover_object->getRootEdit();
|
||||
if (!root_edit)
|
||||
{
|
||||
// Strange parenting issue, don't show any text
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( hover_object->isAttachment() )
|
||||
hover_object = (LLViewerObject*)root_edit->getParent();
|
||||
if (!hover_object)
|
||||
{
|
||||
// get root of attachment then parent, which is avatar
|
||||
LLViewerObject* root_edit = hover_object->getRootEdit();
|
||||
if (!root_edit)
|
||||
{
|
||||
// Strange parenting issue, don't show any text
|
||||
return TRUE;
|
||||
}
|
||||
hover_object = (LLViewerObject*)root_edit->getParent();
|
||||
if (!hover_object)
|
||||
{
|
||||
// another strange parenting issue, bail out
|
||||
return TRUE;
|
||||
}
|
||||
// another strange parenting issue, bail out
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
line.clear();
|
||||
if (hover_object->isAvatar())
|
||||
}
|
||||
|
||||
line.clear();
|
||||
if (hover_object->isAvatar())
|
||||
{
|
||||
// only show tooltip if same inspector not already open
|
||||
LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar");
|
||||
if (!existing_inspector
|
||||
|| !existing_inspector->getVisible()
|
||||
|| existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
|
||||
{
|
||||
// only show tooltip if same inspector not already open
|
||||
LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar");
|
||||
if (!existing_inspector
|
||||
|| !existing_inspector->getVisible()
|
||||
|| existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
|
||||
std::string avatar_name;
|
||||
LLNameValue* firstname = hover_object->getNVPair("FirstName");
|
||||
LLNameValue* lastname = hover_object->getNVPair("LastName");
|
||||
if (firstname && lastname)
|
||||
{
|
||||
std::string avatar_name;
|
||||
LLNameValue* firstname = hover_object->getNVPair("FirstName");
|
||||
LLNameValue* lastname = hover_object->getNVPair("LastName");
|
||||
if (firstname && lastname)
|
||||
avatar_name = llformat("%s %s", firstname->getString(), lastname->getString());
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar_name = LLTrans::getString("TooltipPerson");
|
||||
}
|
||||
|
||||
// *HACK: We may select this object, so pretend it was clicked
|
||||
mPick = mHoverPick;
|
||||
LLInspector::Params p;
|
||||
p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
|
||||
p.message(avatar_name);
|
||||
p.image.name("Inspector_I");
|
||||
p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
|
||||
p.visible_time_near(6.f);
|
||||
p.visible_time_far(3.f);
|
||||
p.delay_time(0.35f);
|
||||
p.wrap(false);
|
||||
|
||||
LLToolTipMgr::instance().show(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// We have hit a regular object (not an avatar or attachment)
|
||||
//
|
||||
|
||||
//
|
||||
// Default prefs will suppress display unless the object is interactive
|
||||
//
|
||||
bool show_all_object_tips =
|
||||
(bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip");
|
||||
LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
|
||||
|
||||
// only show tooltip if same inspector not already open
|
||||
LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object");
|
||||
if (nodep &&
|
||||
(!existing_inspector
|
||||
|| !existing_inspector->getVisible()
|
||||
|| existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID()))
|
||||
{
|
||||
if (nodep->mName.empty())
|
||||
{
|
||||
tooltip_msg.append(LLTrans::getString("TooltipNoName"));
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltip_msg.append( nodep->mName );
|
||||
}
|
||||
|
||||
bool is_time_based_media = false;
|
||||
bool is_web_based_media = false;
|
||||
bool is_media_playing = false;
|
||||
|
||||
// Does this face have media?
|
||||
const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace);
|
||||
|
||||
if(tep)
|
||||
{
|
||||
const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
|
||||
if (mep)
|
||||
{
|
||||
avatar_name = llformat("%s %s", firstname->getString(), lastname->getString());
|
||||
viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
|
||||
LLPluginClassMedia* media_plugin = NULL;
|
||||
|
||||
if (media_impl.notNull() && (media_impl->hasMedia()))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
|
||||
media_plugin = media_impl->getMediaPlugin();
|
||||
if(media_plugin)
|
||||
{ if(media_plugin->pluginSupportsMediaTime())
|
||||
{
|
||||
is_time_based_media = true;
|
||||
is_web_based_media = false;
|
||||
//args["[CurrentURL]"] = media_impl->getMediaURL();
|
||||
is_media_playing = media_impl->isMediaPlaying();
|
||||
}
|
||||
else
|
||||
{
|
||||
is_time_based_media = false;
|
||||
is_web_based_media = true;
|
||||
//args["[CurrentURL]"] = media_plugin->getLocation();
|
||||
}
|
||||
//tooltip_msg.append(LLTrans::getString("CurrentURL", args));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar_name = LLTrans::getString("TooltipPerson");
|
||||
}
|
||||
|
||||
// *HACK: We may select this object, so pretend it was clicked
|
||||
}
|
||||
|
||||
// also check the primary node since sometimes it can have an action even though
|
||||
// the root node doesn't
|
||||
bool needs_tip = needs_tooltip(nodep) ||
|
||||
needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode());
|
||||
|
||||
if (show_all_object_tips || needs_tip)
|
||||
{
|
||||
// We may select this object, so pretend it was clicked
|
||||
mPick = mHoverPick;
|
||||
LLInspector::Params p;
|
||||
p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
|
||||
p.message(avatar_name);
|
||||
p.message(tooltip_msg);
|
||||
p.image.name("Inspector_I");
|
||||
p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
|
||||
p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace));
|
||||
p.time_based_media(is_time_based_media);
|
||||
p.web_based_media(is_web_based_media);
|
||||
p.media_playing(is_media_playing);
|
||||
p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick));
|
||||
p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick));
|
||||
p.visible_time_near(6.f);
|
||||
p.visible_time_far(3.f);
|
||||
p.delay_time(0.35f);
|
||||
|
|
@ -741,261 +980,33 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
|
|||
LLToolTipMgr::instance().show(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// We have hit a regular object (not an avatar or attachment)
|
||||
//
|
||||
|
||||
//
|
||||
// Default prefs will suppress display unless the object is interactive
|
||||
//
|
||||
bool show_all_object_tips =
|
||||
(bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip");
|
||||
LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
|
||||
|
||||
// only show tooltip if same inspector not already open
|
||||
LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object");
|
||||
if (nodep &&
|
||||
(!existing_inspector
|
||||
|| !existing_inspector->getVisible()
|
||||
|| existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID()))
|
||||
{
|
||||
if (nodep->mName.empty())
|
||||
{
|
||||
tooltip_msg.append(LLTrans::getString("TooltipNoName"));
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltip_msg.append( nodep->mName );
|
||||
}
|
||||
|
||||
bool is_time_based_media = false;
|
||||
bool is_web_based_media = false;
|
||||
bool is_media_playing = false;
|
||||
|
||||
// Does this face have media?
|
||||
const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace);
|
||||
|
||||
if(tep)
|
||||
{
|
||||
const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
|
||||
if (mep)
|
||||
{
|
||||
viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
|
||||
LLPluginClassMedia* media_plugin = NULL;
|
||||
|
||||
if (media_impl.notNull() && (media_impl->hasMedia()))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
|
||||
media_plugin = media_impl->getMediaPlugin();
|
||||
if(media_plugin)
|
||||
{ if(media_plugin->pluginSupportsMediaTime())
|
||||
{
|
||||
is_time_based_media = true;
|
||||
is_web_based_media = false;
|
||||
//args["[CurrentURL]"] = media_impl->getMediaURL();
|
||||
is_media_playing = media_impl->isMediaPlaying();
|
||||
}
|
||||
else
|
||||
{
|
||||
is_time_based_media = false;
|
||||
is_web_based_media = true;
|
||||
//args["[CurrentURL]"] = media_plugin->getLocation();
|
||||
}
|
||||
//tooltip_msg.append(LLTrans::getString("CurrentURL", args));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// also check the primary node since sometimes it can have an action even though
|
||||
// the root node doesn't
|
||||
bool needs_tip = needs_tooltip(nodep) ||
|
||||
needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode());
|
||||
|
||||
if (show_all_object_tips || needs_tip)
|
||||
{
|
||||
// We may select this object, so pretend it was clicked
|
||||
mPick = mHoverPick;
|
||||
LLInspector::Params p;
|
||||
p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
|
||||
p.message(tooltip_msg);
|
||||
p.image.name("Inspector_I");
|
||||
p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace));
|
||||
p.time_based_media(is_time_based_media);
|
||||
p.web_based_media(is_web_based_media);
|
||||
p.media_playing(is_media_playing);
|
||||
p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick));
|
||||
p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick));
|
||||
p.visible_time_near(6.f);
|
||||
p.visible_time_far(3.f);
|
||||
p.delay_time(0.35f);
|
||||
p.wrap(false);
|
||||
|
||||
LLToolTipMgr::instance().show(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( mHoverPick.mPickType == LLPickInfo::PICK_LAND )
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
|
||||
{
|
||||
if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
|
||||
if (!mHoverPick.isValid()) return TRUE;
|
||||
|
||||
LLViewerObject* hover_object = mHoverPick.getObject();
|
||||
|
||||
// update hover object and hover parcel
|
||||
LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace);
|
||||
|
||||
|
||||
std::string tooltip_msg;
|
||||
std::string line;
|
||||
|
||||
if ( hover_object )
|
||||
{
|
||||
//
|
||||
// Do not show hover for land unless prefs are set to allow it.
|
||||
//
|
||||
|
||||
if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE;
|
||||
|
||||
// Didn't hit an object, but since we have a land point we
|
||||
// must be hovering over land.
|
||||
|
||||
LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
|
||||
LLUUID owner;
|
||||
S32 width = 0;
|
||||
S32 height = 0;
|
||||
|
||||
if ( hover_parcel )
|
||||
{
|
||||
owner = hover_parcel->getOwnerID();
|
||||
width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
|
||||
height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
|
||||
}
|
||||
|
||||
// Line: "Land"
|
||||
line.clear();
|
||||
line.append(LLTrans::getString("TooltipLand"));
|
||||
if (hover_parcel)
|
||||
{
|
||||
line.append(hover_parcel->getName());
|
||||
}
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
|
||||
// Line: "Owner: James Linden"
|
||||
line.clear();
|
||||
line.append(LLTrans::getString("TooltipOwner") + " ");
|
||||
|
||||
if ( hover_parcel )
|
||||
{
|
||||
std::string name;
|
||||
if (LLUUID::null == owner)
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipPublic"));
|
||||
}
|
||||
else if (hover_parcel->getIsGroupOwned())
|
||||
{
|
||||
if (gCacheName->getGroupName(owner, name))
|
||||
{
|
||||
line.append(name);
|
||||
line.append(LLTrans::getString("TooltipIsGroup"));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("RetrievingData"));
|
||||
}
|
||||
}
|
||||
else if(gCacheName->getFullName(owner, name))
|
||||
{
|
||||
line.append(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("RetrievingData"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("RetrievingData"));
|
||||
}
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
|
||||
// Line: "no fly, not safe, no build"
|
||||
|
||||
// Don't display properties for your land. This is just
|
||||
// confusing, because you can do anything on your own land.
|
||||
if ( hover_parcel && owner != gAgent.getID() )
|
||||
{
|
||||
S32 words = 0;
|
||||
|
||||
line.clear();
|
||||
// JC - Keep this in the same order as the checkboxes
|
||||
// on the land info panel
|
||||
if ( !hover_parcel->getAllowModify() )
|
||||
{
|
||||
if ( hover_parcel->getAllowGroupModify() )
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagGroupBuild"));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagNoBuild"));
|
||||
}
|
||||
words++;
|
||||
}
|
||||
|
||||
if ( !hover_parcel->getAllowTerraform() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
line.append(LLTrans::getString("TooltipFlagNoEdit"));
|
||||
words++;
|
||||
}
|
||||
|
||||
if ( hover_parcel->getAllowDamage() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
line.append(LLTrans::getString("TooltipFlagNotSafe"));
|
||||
words++;
|
||||
}
|
||||
|
||||
// Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04
|
||||
if ( !hover_parcel->getAllowFly() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
line.append(LLTrans::getString("TooltipFlagNoFly"));
|
||||
words++;
|
||||
}
|
||||
|
||||
if ( !hover_parcel->getAllowOtherScripts() )
|
||||
{
|
||||
if (words) line.append(", ");
|
||||
if ( hover_parcel->getAllowGroupScripts() )
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagGroupScripts"));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagNoScripts"));
|
||||
}
|
||||
|
||||
words++;
|
||||
}
|
||||
|
||||
if (words)
|
||||
{
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
}
|
||||
}
|
||||
|
||||
if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
|
||||
line = LLTrans::getString("TooltipForSaleL$", args);
|
||||
tooltip_msg.append(line);
|
||||
tooltip_msg.push_back('\n');
|
||||
}
|
||||
|
||||
// trim last newlines
|
||||
if (!tooltip_msg.empty())
|
||||
{
|
||||
tooltip_msg.erase(tooltip_msg.size() - 1);
|
||||
LLToolTipMgr::instance().show(tooltip_msg);
|
||||
}
|
||||
handleTooltipObject(hover_object, line, tooltip_msg );
|
||||
}
|
||||
else if (mHoverPick.mPickType == LLPickInfo::PICK_LAND)
|
||||
{
|
||||
handleTooltipLand(line, tooltip_msg);
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,9 @@ private:
|
|||
|
||||
bool handleMediaClick(const LLPickInfo& info);
|
||||
bool handleMediaHover(const LLPickInfo& info);
|
||||
bool handleMediaMouseUp();
|
||||
bool handleMediaMouseUp();
|
||||
BOOL handleTooltipLand(std::string line, std::string tooltip_msg);
|
||||
BOOL handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg);
|
||||
|
||||
private:
|
||||
BOOL mGrabMouseButtonDown;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro
|
|||
LLDockableFloater(dockControl, uniqueDocking, key, params)
|
||||
{
|
||||
LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
|
||||
LLTransientFloater::init(this);
|
||||
}
|
||||
|
||||
LLTransientDockableFloater::~LLTransientDockableFloater()
|
||||
|
|
|
|||
|
|
@ -37,12 +37,13 @@
|
|||
#include "llfloater.h"
|
||||
#include "lldockcontrol.h"
|
||||
#include "lldockablefloater.h"
|
||||
#include "lltransientfloatermgr.h"
|
||||
|
||||
/**
|
||||
* Represents floater that can dock and managed by transient floater manager.
|
||||
* Transient floaters should be hidden if user click anywhere except defined view list.
|
||||
*/
|
||||
class LLTransientDockableFloater : public LLDockableFloater
|
||||
class LLTransientDockableFloater : public LLDockableFloater, LLTransientFloater
|
||||
{
|
||||
public:
|
||||
LOG_CLASS(LLTransientDockableFloater);
|
||||
|
|
@ -52,6 +53,7 @@ public:
|
|||
|
||||
/*virtual*/ void setVisible(BOOL visible);
|
||||
/* virtual */void setDocked(bool docked, bool pop_on_undock = true);
|
||||
virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
|
||||
};
|
||||
|
||||
#endif /* LL_TRANSIENTDOCKABLEFLOATER_H */
|
||||
|
|
|
|||
|
|
@ -44,57 +44,68 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
|
|||
{
|
||||
gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(
|
||||
&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
|
||||
|
||||
mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
|
||||
mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::registerTransientFloater(LLFloater* floater)
|
||||
void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater)
|
||||
{
|
||||
mTransSet.insert(floater);
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::unregisterTransientFloater(LLFloater* floater)
|
||||
void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* floater)
|
||||
{
|
||||
mTransSet.erase(floater);
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view)
|
||||
{
|
||||
mGroupControls.find(group)->second.insert(view);
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view)
|
||||
{
|
||||
mGroupControls.find(group)->second.erase(view);
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::addControlView(LLView* view)
|
||||
{
|
||||
mControlsSet.insert(view);
|
||||
addControlView(GLOBAL, view);
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::removeControlView(LLView* view)
|
||||
{
|
||||
// we will still get focus lost callbacks on this view, but that's ok
|
||||
// since we run sanity checking logic every time
|
||||
mControlsSet.erase(view);
|
||||
removeControlView(GLOBAL, view);
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::hideTransientFloaters()
|
||||
void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)
|
||||
{
|
||||
for (std::set<LLFloater*>::iterator it = mTransSet.begin(); it
|
||||
for (std::set<LLTransientFloater*>::iterator it = mTransSet.begin(); it
|
||||
!= mTransSet.end(); it++)
|
||||
{
|
||||
LLFloater* floater = *it;
|
||||
if (floater->isDocked())
|
||||
LLTransientFloater* floater = *it;
|
||||
if (floater->isTransientDocked())
|
||||
{
|
||||
floater->setVisible(FALSE);
|
||||
ETransientGroup group = floater->getGroup();
|
||||
|
||||
bool hide = isControlClicked(mGroupControls.find(group)->second, x, y);
|
||||
if (hide)
|
||||
{
|
||||
floater->setTransientVisible(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
|
||||
MASK mask)
|
||||
bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y)
|
||||
{
|
||||
bool hide = true;
|
||||
for (controls_set_t::iterator it = mControlsSet.begin(); it
|
||||
!= mControlsSet.end(); it++)
|
||||
bool res = true;
|
||||
for (controls_set_t::iterator it = set.begin(); it
|
||||
!= set.end(); it++)
|
||||
{
|
||||
// don't hide transient floater if any context menu opened
|
||||
if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL)
|
||||
{
|
||||
hide = false;
|
||||
break;
|
||||
}
|
||||
|
||||
LLView* control_view = *it;
|
||||
if (!control_view->getVisible())
|
||||
{
|
||||
|
|
@ -105,14 +116,32 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
|
|||
// if click inside view rect
|
||||
if (rect.pointInRect(x, y))
|
||||
{
|
||||
hide = false;
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
|
||||
MASK mask)
|
||||
{
|
||||
// don't hide transient floater if any context menu opened
|
||||
if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
|
||||
if (hide)
|
||||
{
|
||||
hideTransientFloaters();
|
||||
hideTransientFloaters(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void LLTransientFloater::init(LLFloater* thiz)
|
||||
{
|
||||
// used since LLTransientFloater(this) can't be used in descendant constructor parameter initialization.
|
||||
mFloater = thiz;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,27 +37,60 @@
|
|||
#include "llsingleton.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLTransientFloater;
|
||||
|
||||
/**
|
||||
* Provides functionality to hide transient floaters.
|
||||
*/
|
||||
class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
LLTransientFloaterMgr();
|
||||
void registerTransientFloater(LLFloater* floater);
|
||||
void unregisterTransientFloater(LLFloater* floater);
|
||||
friend class LLSingleton<LLTransientFloaterMgr>;
|
||||
|
||||
public:
|
||||
enum ETransientGroup
|
||||
{
|
||||
GLOBAL, IM
|
||||
};
|
||||
|
||||
void registerTransientFloater(LLTransientFloater* floater);
|
||||
void unregisterTransientFloater(LLTransientFloater* floater);
|
||||
void addControlView(ETransientGroup group, LLView* view);
|
||||
void removeControlView(ETransientGroup group, LLView* view);
|
||||
void addControlView(LLView* view);
|
||||
void removeControlView(LLView* view);
|
||||
|
||||
private:
|
||||
void hideTransientFloaters();
|
||||
void hideTransientFloaters(S32 x, S32 y);
|
||||
void leftMouseClickCallback(S32 x, S32 y, MASK mask);
|
||||
bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y);
|
||||
private:
|
||||
std::set<LLTransientFloater*> mTransSet;
|
||||
|
||||
typedef std::set<LLView*> controls_set_t;
|
||||
typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t;
|
||||
group_controls_t mGroupControls;
|
||||
};
|
||||
|
||||
/**
|
||||
* An abstract class declares transient floater interfaces.
|
||||
*/
|
||||
class LLTransientFloater
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Class initialization method.
|
||||
* Should be called from descendant constructor.
|
||||
*/
|
||||
void init(LLFloater* thiz);
|
||||
public:
|
||||
virtual LLTransientFloaterMgr::ETransientGroup getGroup() = 0;
|
||||
bool isTransientDocked() { return mFloater->isDocked(); };
|
||||
void setTransientVisible(BOOL visible) {mFloater->setVisible(visible); }
|
||||
|
||||
private:
|
||||
std::set<LLFloater*> mTransSet;
|
||||
typedef std::set<LLView*> controls_set_t;
|
||||
controls_set_t mControlsSet;
|
||||
LLFloater* mFloater;
|
||||
};
|
||||
|
||||
#endif // LL_LLTRANSIENTFLOATERMGR_H
|
||||
|
|
|
|||
|
|
@ -483,7 +483,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
{
|
||||
LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
|
||||
render_ui();
|
||||
render_disconnected_background();
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
|
|
@ -1135,6 +1134,10 @@ void render_ui(F32 zoom_factor, int subfield)
|
|||
render_ui_3d();
|
||||
LLGLState::checkStates();
|
||||
}
|
||||
else
|
||||
{
|
||||
render_disconnected_background();
|
||||
}
|
||||
|
||||
render_ui_2d();
|
||||
LLGLState::checkStates();
|
||||
|
|
|
|||
|
|
@ -752,6 +752,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
|
|||
new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
|
||||
impl_count_interest_normal++;
|
||||
}
|
||||
else if(pimpl->isParcelMedia())
|
||||
{
|
||||
new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
|
||||
impl_count_interest_normal++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look at interest and CPU usage for instances that aren't in any of the above states.
|
||||
|
|
|
|||
|
|
@ -6099,7 +6099,8 @@ class LLAttachmentEnableDrop : public view_listener_t
|
|||
LLViewerJointAttachment* attachment = NULL;
|
||||
LLInventoryItem* item = NULL;
|
||||
|
||||
if (object)
|
||||
// Do not enable drop if all faces of object are not enabled
|
||||
if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
|
||||
{
|
||||
S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState());
|
||||
attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
|
||||
|
|
@ -6141,8 +6142,14 @@ class LLAttachmentEnableDrop : public view_listener_t
|
|||
BOOL enable_detach(const LLSD&)
|
||||
{
|
||||
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (!object) return FALSE;
|
||||
if (!object->isAttachment()) return FALSE;
|
||||
|
||||
// Only enable detach if all faces of object are selected
|
||||
if (!object ||
|
||||
!object->isAttachment() ||
|
||||
!LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Find the avatar who owns this attachment
|
||||
LLViewerObject* avatar = object;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
#include "llstatenums.h"
|
||||
#include "llstatusbar.h"
|
||||
#include "llimview.h"
|
||||
#include "llspeakers.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "lluri.h"
|
||||
|
|
@ -1471,7 +1472,12 @@ void inventory_offer_handler(LLOfferInfo* info)
|
|||
{
|
||||
LLStringUtil::truncate(msg, indx);
|
||||
}
|
||||
|
||||
|
||||
if(LLAssetType::AT_LANDMARK == info->mType)
|
||||
{
|
||||
msg = LLViewerInventoryItem::getDisplayName(msg);
|
||||
}
|
||||
|
||||
LLSD args;
|
||||
args["[OBJECTNAME]"] = msg;
|
||||
|
||||
|
|
@ -2008,7 +2014,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
|
|||
// Someone has offered us some inventory.
|
||||
{
|
||||
LLOfferInfo* info = new LLOfferInfo;
|
||||
bool mute_im = false;
|
||||
if (IM_INVENTORY_OFFERED == dialog)
|
||||
{
|
||||
struct offer_agent_bucket_t
|
||||
|
|
@ -2025,11 +2030,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
|
|||
bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
|
||||
info->mType = (LLAssetType::EType) bucketp->asset_type;
|
||||
info->mObjectID = bucketp->object_id;
|
||||
|
||||
if(accept_im_from_only_friend&&!is_friend)
|
||||
{
|
||||
mute_im = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2060,7 +2060,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
|
|||
info->mDesc = message;
|
||||
info->mHost = msg->getSender();
|
||||
//if (((is_busy && !is_owned_by_me) || is_muted))
|
||||
if ( is_muted || mute_im)
|
||||
if (is_muted)
|
||||
{
|
||||
// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
|
||||
LLInventoryFetchObserver::item_ref_t items;
|
||||
|
|
|
|||
|
|
@ -212,22 +212,15 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
|
|||
else
|
||||
{
|
||||
// Since the texture id is different, we need to generate a new impl
|
||||
LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL;
|
||||
|
||||
// Delete the old one first so they don't fight over the texture.
|
||||
sMediaImpl = NULL;
|
||||
|
||||
sMediaImpl = LLViewerMedia::newMediaImpl(
|
||||
placeholder_texture_id,
|
||||
media_width,
|
||||
media_height,
|
||||
media_auto_scale,
|
||||
media_loop);
|
||||
sMediaImpl->setIsParcelMedia(true);
|
||||
sMediaImpl->navigateTo(media_url, mime_type, true);
|
||||
|
||||
// A new impl will be created below.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if(!sMediaImpl)
|
||||
{
|
||||
LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1560,7 +1560,11 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
|
|||
|
||||
void LLViewerFetchedTexture::setDecodePriority(F32 priority)
|
||||
{
|
||||
llassert(!mInImageList);
|
||||
//llassert(!mInImageList); // firing a lot, figure out why
|
||||
if (mInImageList) // above llassert() softened to a warning
|
||||
{
|
||||
llwarns << "BAD STUFF! mInImageList" << llendl;
|
||||
}
|
||||
mDecodePriority = priority;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -502,7 +502,10 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
|
|||
{
|
||||
llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl;
|
||||
}
|
||||
llverify((mImageList.insert(image)).second == true);
|
||||
if ((mImageList.insert(image)).second != true)
|
||||
{
|
||||
llwarns << "BAD STUFF! (mImageList.insert(image)).second != true" << llendl;
|
||||
}
|
||||
image->setInImageList(TRUE) ;
|
||||
}
|
||||
|
||||
|
|
@ -519,7 +522,10 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
|
|||
}
|
||||
llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl;
|
||||
}
|
||||
llverify(mImageList.erase(image) == 1);
|
||||
if (mImageList.erase(image) != 1)
|
||||
{
|
||||
llwarns << "BAD STUFF! mImageList.erase(image) != 1" << llendl;
|
||||
}
|
||||
image->setInImageList(FALSE) ;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "llparcel.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
//#include "llfirstuse.h"
|
||||
#include "llspeakers.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewercamera.h"
|
||||
|
|
|
|||
|
|
@ -252,9 +252,8 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
|||
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
|
||||
mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
|
||||
mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this);
|
||||
BOOL vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
|
||||
mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, vefifySSLCert);
|
||||
mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, vefifySSLCert ? 2 : 0);
|
||||
mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
|
||||
mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify() ? 2 : 0);
|
||||
// Be a little impatient about establishing connections.
|
||||
mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L);
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 309 B |
Binary file not shown.
|
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 309 B |
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="floater_about" title="OM [APP_NAME]">
|
||||
<floater name="floater_about" title="OM [CAPITALIZED_APP_NAME]">
|
||||
<floater.string name="AboutHeader">
|
||||
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
|
||||
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="floater_about" title="INFO ÜBER [APP_NAME]">
|
||||
<floater name="floater_about" title="INFO ÜBER [CAPITALIZED_APP_NAME]">
|
||||
<floater.string name="AboutHeader">
|
||||
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
|
||||
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
<line_editor name="homepage_edit" value="http://"/>
|
||||
<check_box label="In Suchergebnissen anzeigen" name="show_in_search_checkbox"/>
|
||||
<text name="title_acc_status_text" value="Mein Konto:"/>
|
||||
<text name="my_account_link" value="Meine Startseite aufrufen"/>
|
||||
<text name="my_account_link" value="[[URL] Meine Startseite aufrufen]"/>
|
||||
<text name="acc_status_text" value="Einwohner. Keine Zahlungsinfo archiviert."/>
|
||||
<text name="title_partner_text" value="Mein Partner:"/>
|
||||
<text name="partner_edit_link" value="[[URL] bearbeiten]"/>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
<!-- All buttons in the Favorites bar will be created from this one -->
|
||||
<button
|
||||
follows="left|bottom"
|
||||
font_halign="center"
|
||||
halign="center"
|
||||
height="15"
|
||||
image_disabled="transparent.j2c"
|
||||
|
|
@ -11,6 +10,8 @@
|
|||
image_selected="transparent.j2c"
|
||||
image_unselected="transparent.j2c"
|
||||
image_pressed="Favorite_Link_Over"
|
||||
image_hover_selected="Favorite_Link_Over"
|
||||
image_hover_unselected="Favorite_Link_Over"
|
||||
hover_glow_amount="0.15"
|
||||
label_shadow="false"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -1871,13 +1871,14 @@ Only large parcels can be listed in search.
|
|||
layout="topleft"
|
||||
left="110"
|
||||
name="parcel_enable_voice_channel_is_estate_disabled"
|
||||
top_delta="0"
|
||||
width="300" />
|
||||
<check_box
|
||||
height="16"
|
||||
label="Restrict Voice to this parcel"
|
||||
layout="topleft"
|
||||
left="110"
|
||||
name="parcel_enable_voice_channel_parcel"
|
||||
name="parcel_enable_voice_channel_local"
|
||||
width="300" />
|
||||
</panel>
|
||||
<panel
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ Re-enter amount to see the latest exchange rate.
|
|||
</text>
|
||||
<text
|
||||
type="string"
|
||||
width="175"
|
||||
width="176"
|
||||
height="125"
|
||||
top="60"
|
||||
left="165"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<multi_floater
|
||||
can_minimize="false"
|
||||
can_close="false"
|
||||
can_minimize="true"
|
||||
can_resize="true"
|
||||
height="390"
|
||||
layout="topleft"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue