diff options
author | Tofu Linden <tofu.linden@lindenlab.com> | 2010-04-21 10:29:03 +0100 |
---|---|---|
committer | Tofu Linden <tofu.linden@lindenlab.com> | 2010-04-21 10:29:03 +0100 |
commit | f464c663c6a2dfb602bc75ce329313c3539c75d6 (patch) | |
tree | f031169999bdba72e442faea7a6179fe58efed8d /indra | |
parent | c34bb6f62b0ce623074378173fa9693d938eeb89 (diff) | |
parent | ea64706e796e90d0cd775c2113c949c2b56c898c (diff) |
merge from PE's viewer-trunk
Diffstat (limited to 'indra')
30 files changed, 658 insertions, 171 deletions
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 22be4078a1..a69621a57b 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -21,6 +21,7 @@ include_directories( set(llimage_SOURCE_FILES llimagebmp.cpp llimage.cpp + llimagedimensionsinfo.cpp llimagedxt.cpp llimagej2c.cpp llimagejpeg.cpp @@ -35,6 +36,7 @@ set(llimage_HEADER_FILES llimage.h llimagebmp.h + llimagedimensionsinfo.h llimagedxt.h llimagej2c.h llimagejpeg.h diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp new file mode 100644 index 0000000000..890b49b50a --- /dev/null +++ b/indra/llimage/llimagedimensionsinfo.cpp @@ -0,0 +1,139 @@ +/** + * @file llimagedimensionsinfo.cpp + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "stdtypes.h" + +#include "llimagejpeg.h" + +#include "llimagedimensionsinfo.h" + +bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec) +{ + clean(); + + mSrcFilename = src_filename; + + S32 file_size = 0; + apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size); + + if (s != APR_SUCCESS) + { + setLastError("Unable to open file for reading", src_filename); + return false; + } + + if (file_size == 0) + { + setLastError("File is empty",src_filename); + return false; + } + + switch (codec) + { + case IMG_CODEC_BMP: + return getImageDimensionsBmp(); + case IMG_CODEC_TGA: + return getImageDimensionsTga(); + case IMG_CODEC_JPEG: + return getImageDimensionsJpeg(); + case IMG_CODEC_PNG: + return getImageDimensionsPng(); + default: + return false; + + } +} + + +bool LLImageDimensionsInfo::getImageDimensionsBmp() +{ + const S32 BMP_FILE_HEADER_SIZE = 14; + + mInfile.seek(APR_CUR,BMP_FILE_HEADER_SIZE+4); + mWidth = read_reverse_s32(); + mHeight = read_reverse_s32(); + + return true; +} + +bool LLImageDimensionsInfo::getImageDimensionsTga() +{ + const S32 TGA_FILE_HEADER_SIZE = 12; + + mInfile.seek(APR_CUR,TGA_FILE_HEADER_SIZE); + mWidth = read_byte() | read_byte() << 8; + mHeight = read_byte() | read_byte() << 8; + + return true; +} + +bool LLImageDimensionsInfo::getImageDimensionsPng() +{ + const S32 PNG_FILE_MARKER_SIZE = 8; + + mInfile.seek(APR_CUR,PNG_FILE_MARKER_SIZE + 8/*header offset+chunk length+chunk type*/); + mWidth = read_s32(); + mHeight = read_s32(); + + return true; +} + + +bool LLImageDimensionsInfo::getImageDimensionsJpeg() +{ + clean(); + FILE *fp = fopen (mSrcFilename.c_str(), "rb"); + if (fp == NULL) + { + setLastError("Unable to open file for reading", mSrcFilename); + return false; + } + /* Init jpeg */ + jpeg_error_mgr jerr; + jpeg_decompress_struct cinfo; + cinfo.err = jpeg_std_error(&jerr); + + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, fp); + jpeg_read_header (&cinfo, TRUE); + cinfo.out_color_space = JCS_RGB; + jpeg_start_decompress (&cinfo); + + mHeight = cinfo.output_width; + mHeight = cinfo.output_height; + + jpeg_destroy_decompress(&cinfo); + fclose(fp); + + return true; +} + diff --git a/indra/llimage/llimagedimensionsinfo.h b/indra/llimage/llimagedimensionsinfo.h new file mode 100644 index 0000000000..9e69635c1e --- /dev/null +++ b/indra/llimage/llimagedimensionsinfo.h @@ -0,0 +1,139 @@ +/**
+ * @file llimagedimentionsinfo.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLIMAGEDIMENSIONSINFO_H
+#define LL_LLIMAGEDIMENSIONSINFO_H
+
+//----------------------------------------------------------------------------- +// LLImageDimensionsInfo +// helper class to get image dimensions WITHOUT loading image to memore +// usefull when image may be too large... +//----------------------------------------------------------------------------- +class LLImageDimensionsInfo +{ +public: + LLImageDimensionsInfo(): + mData(NULL) + ,mHeight(0) + ,mWidth(0) + {} + ~LLImageDimensionsInfo() + { + clean(); + } + + bool load(const std::string& src_filename,U32 codec); + S32 getWidth() const { return mWidth;} + S32 getHeight() const { return mHeight;} + + const std::string& getLastError() + { + return mLastError; + } +protected: + + void clean() + { + mInfile.close(); + delete[] mData; + mData = NULL; + mWidth = 0; + mHeight = 0; + } + + U8* getData() + { + return mData; + } + + + void setLastError(const std::string& message, const std::string& filename) + { + std::string error = message; + if (!filename.empty()) + error += std::string(" FILE: ") + filename; + mLastError = error; + } + + + bool getImageDimensionsBmp(); + bool getImageDimensionsTga(); + bool getImageDimensionsPng(); + bool getImageDimensionsJpeg(); + + S32 read_s32() + { + char p[4]; + mInfile.read(&p[0],4); + S32 temp = (((S32)p[3]) & 0x000000FF) | + (((S32)p[2] << 8 ) & 0x0000FF00) | + (((S32)p[1] << 16) & 0x00FF0000) | + (((S32)p[0] << 24) & 0xFF000000); + + return temp; + } + S32 read_reverse_s32() + { + char p[4]; + mInfile.read(&p[0],4); + S32 temp = (((S32)p[0]) & 0x000000FF) | + (((S32)p[1] << 8 ) & 0x0000FF00) | + (((S32)p[2] << 16) & 0x00FF0000) | + (((S32)p[3] << 24) & 0xFF000000); + + return temp; + } + + U8 read_byte() + { + U8 bt; + mInfile.read(&bt,1); + return bt; + } + + U16 read_short() + { + return read_byte() << 8 | read_byte(); + } + +protected: + LLAPRFile mInfile ; + std::string mSrcFilename; + + std::string mLastError; + + U8* mData; + + S32 mWidth; + S32 mHeight; +}; +#endif diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 82f054c4b7..990bf5cd22 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -1,10 +1,10 @@ /** * @file llflatlistview.cpp - * @brief LLFlatListView base class + * @brief LLFlatListView base class and extension to support messages for several cases of an empty list. * * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2009, Linden Research, Inc. + * Copyright (c) 2009-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -1122,4 +1122,38 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items) } } + +/************************************************************************/ +/* LLFlatListViewEx implementation */ +/************************************************************************/ +LLFlatListViewEx::Params::Params() +: no_items_msg("no_items_msg") +, no_filtered_items_msg("no_filtered_items_msg") +{ + +} + +LLFlatListViewEx::LLFlatListViewEx(const Params& p) +: LLFlatListView(p) +, mNoFilteredItemsMsg(p.no_filtered_items_msg) +, mNoItemsMsg(p.no_items_msg) +{ + +} + +void LLFlatListViewEx::updateNoItemsMessage(bool items_filtered) +{ + if (items_filtered) + { + // items were filtered + setNoItemsCommentText(mNoFilteredItemsMsg); + } + else + { + // list does not contain any items at all + setNoItemsCommentText(mNoItemsMsg); + } + +} + //EOF diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index e3c07e811f..f7d094f7e7 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -1,10 +1,10 @@ /** * @file llflatlistview.h - * @brief LLFlatListView base class + * @brief LLFlatListView base class and extension to support messages for several cases of an empty list. * * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2009, Linden Research, Inc. + * Copyright (c) 2009-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -430,4 +430,54 @@ private: commit_signal_t mOnReturnSignal; }; +/** + * Extends LLFlatListView functionality to show different messages when there are no items in the + * list depend on whether they are filtered or not. + * + * Class provides one message per case of empty list. + * It also provides protected updateNoItemsMessage() method to be called each time when derived list + * is changed to update base mNoItemsCommentTextbox value. + * + * It is implemented to avoid duplication of this functionality in concrete implementations of the + * lists. It is intended to be used as a base class for lists which should support two different + * messages for empty state. Can be improved to support more than two messages via state-to-message map. + */ +class LLFlatListViewEx : public LLFlatListView +{ +public: + struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> + { + /** + * Contains a message for empty list when it does not contain any items at all. + */ + Optional<std::string> no_items_msg; + + /** + * Contains a message for empty list when its items are removed by filtering. + */ + Optional<std::string> no_filtered_items_msg; + Params(); + }; + + // *WORKAROUND: two methods to overload appropriate Params due to localization issue: + // no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931 + void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; } + void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; } + +protected: + LLFlatListViewEx(const Params& p); + + /** + * Applies a message for empty list depend on passed argument. + * + * @param items_filtered - if true message for filtered items will be set, otherwise for + * completely empty list. + */ + void updateNoItemsMessage(bool items_filtered); + +private: + std::string mNoFilteredItemsMsg; + std::string mNoItemsMsg; +}; + #endif diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c9b5631d54..6b9d30423d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10972,7 +10972,27 @@ <key>Value</key> <integer>0</integer> </map> - + <key>max_texture_dimension_X</key> + <map> + <key>Comment</key> + <string>Maximum texture width for user uploaded textures</string> + <key>Persist</key> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>2048</integer> + </map> + <key>max_texture_dimension_Y</key> + <map> + <key>Comment</key> + <string>Maximum texture height for user uploaded textures</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>2048</integer> + </map> <!-- End of back compatibility settings --> </map> </llsd> diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index c7a5691d70..8ba47b5198 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -113,7 +113,7 @@ LLAvatarList::Params::Params() } LLAvatarList::LLAvatarList(const Params& p) -: LLFlatListView(p) +: LLFlatListViewEx(p) , mIgnoreOnlineStatus(p.ignore_online_status) , mShowLastInteractionTime(p.show_last_interaction_time) , mContextMenu(NULL) @@ -154,7 +154,7 @@ void LLAvatarList::draw() // *NOTE dzaporozhan // Call refresh() after draw() to avoid flickering of avatar list items. - LLFlatListView::draw(); + LLFlatListViewEx::draw(); if (mDirty) refresh(); @@ -171,7 +171,7 @@ void LLAvatarList::clear() { getIDs().clear(); setDirty(true); - LLFlatListView::clear(); + LLFlatListViewEx::clear(); } void LLAvatarList::setNameFilter(const std::string& filter) @@ -179,6 +179,10 @@ void LLAvatarList::setNameFilter(const std::string& filter) if (mNameFilter != filter) { mNameFilter = filter; + + // update message for empty state here instead of refresh() to avoid blinking when switch + // between tabs. + updateNoItemsMessage(!mNameFilter.empty()); setDirty(); } } @@ -360,7 +364,7 @@ S32 LLAvatarList::notifyParent(const LLSD& info) sort(); return 1; } - return LLFlatListView::notifyParent(info); + return LLFlatListViewEx::notifyParent(info); } void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos) diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 528f796b8b..ff090f3a34 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -49,11 +49,11 @@ class LLTimer; * @see setDirty() * @see setNameFilter() */ -class LLAvatarList : public LLFlatListView +class LLAvatarList : public LLFlatListViewEx { LOG_CLASS(LLAvatarList); public: - struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> + struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> { Optional<bool> ignore_online_status, // show all items as online show_last_interaction_time, // show most recent interaction time. *HACK: move this to a derived class diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index d15c5f9bf4..5a96613870 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -228,7 +228,7 @@ void LLCallFloater::leaveCall() LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); if (voice_channel) { - voice_channel->deactivate(); + gIMMgr->endCall(voice_channel->getSessionID()); } } diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 05d3d70c74..9c4aa7b964 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -465,6 +465,7 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p) , mSpeakerCtrl(NULL) , mCounterCtrl(NULL) , mChicletButton(NULL) +, mPopupMenu(NULL) { enableCounterControl(p.enable_counter); } @@ -648,6 +649,37 @@ LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id) return type; } +BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if(!mPopupMenu) + { + createPopupMenu(); + } + + if (mPopupMenu) + { + updateMenuItems(); + mPopupMenu->arrangeAndClear(); + LLMenuGL::showPopup(this, mPopupMenu, x, y); + } + + return TRUE; +} + +bool LLIMChiclet::canCreateMenu() +{ + if(mPopupMenu) + { + llwarns << "Menu already exists" << llendl; + return false; + } + if(getSessionId().isNull()) + { + return false; + } + return true; +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -665,7 +697,6 @@ LLIMP2PChiclet::Params::Params() LLIMP2PChiclet::LLIMP2PChiclet(const Params& p) : LLIMChiclet(p) , mChicletIconCtrl(NULL) -, mPopupMenu(NULL) { LLButton::Params button_params = p.chiclet_button; mChicletButton = LLUICtrlFactory::create<LLButton>(button_params); @@ -720,34 +751,10 @@ void LLIMP2PChiclet::updateMenuItems() mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); } -BOOL LLIMP2PChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if(!mPopupMenu) - { - createPopupMenu(); - } - - if (mPopupMenu) - { - updateMenuItems(); - mPopupMenu->arrangeAndClear(); - LLMenuGL::showPopup(this, mPopupMenu, x, y); - } - - return TRUE; -} - void LLIMP2PChiclet::createPopupMenu() { - if(mPopupMenu) - { - llwarns << "Menu already exists" << llendl; + if(!canCreateMenu()) return; - } - if(getSessionId().isNull()) - { - return; - } LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); @@ -797,7 +804,6 @@ LLAdHocChiclet::Params::Params() LLAdHocChiclet::LLAdHocChiclet(const Params& p) : LLIMChiclet(p) , mChicletIconCtrl(NULL) -, mPopupMenu(NULL) { LLButton::Params button_params = p.chiclet_button; mChicletButton = LLUICtrlFactory::create<LLButton>(button_params); @@ -867,15 +873,8 @@ void LLAdHocChiclet::switchToCurrentSpeaker() void LLAdHocChiclet::createPopupMenu() { - if(mPopupMenu) - { - llwarns << "Menu already exists" << llendl; + if(!canCreateMenu()) return; - } - if(getSessionId().isNull()) - { - return; - } LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2)); @@ -895,22 +894,6 @@ void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data) } } -BOOL LLAdHocChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if(!mPopupMenu) - { - createPopupMenu(); - } - - if (mPopupMenu) - { - mPopupMenu->arrangeAndClear(); - LLMenuGL::showPopup(this, mPopupMenu, x, y); - } - - return TRUE; -} - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -929,7 +912,6 @@ LLIMGroupChiclet::LLIMGroupChiclet(const Params& p) : LLIMChiclet(p) , LLGroupMgrObserver(LLUUID::null) , mChicletIconCtrl(NULL) -, mPopupMenu(NULL) { LLButton::Params button_params = p.chiclet_button; mChicletButton = LLUICtrlFactory::create<LLButton>(button_params); @@ -1042,34 +1024,10 @@ void LLIMGroupChiclet::updateMenuItems() mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists); } -BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if(!mPopupMenu) - { - createPopupMenu(); - } - - if (mPopupMenu) - { - updateMenuItems(); - mPopupMenu->arrangeAndClear(); - LLMenuGL::showPopup(this, mPopupMenu, x, y); - } - - return TRUE; -} - void LLIMGroupChiclet::createPopupMenu() { - if(mPopupMenu) - { - llwarns << "Menu already exists" << llendl; + if(!canCreateMenu()) return; - } - if(getSessionId().isNull()) - { - return; - } LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); @@ -1917,6 +1875,28 @@ void LLScriptChiclet::onMouseDown() LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId()); } +void LLScriptChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string action = user_data.asString(); + + if("end" == action) + { + LLScriptFloaterManager::instance().onRemoveNotification(getSessionId()); + } +} + +void LLScriptChiclet::createPopupMenu() +{ + if(!canCreateMenu()) + return; + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2)); + + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> + ("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1978,4 +1958,26 @@ void LLInvOfferChiclet::onMouseDown() LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId()); } +void LLInvOfferChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string action = user_data.asString(); + + if("end" == action) + { + LLScriptFloaterManager::instance().onRemoveNotification(getSessionId()); + } +} + +void LLInvOfferChiclet::createPopupMenu() +{ + if(!canCreateMenu()) + return; + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2)); + + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> + ("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +} + // EOF diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 97f494b817..489c66be71 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -428,12 +428,31 @@ public: virtual void setToggleState(bool toggle); + /** + * Displays popup menu. + */ + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + protected: LLIMChiclet(const LLIMChiclet::Params& p); protected: + /** + * Creates chiclet popup menu. + */ + virtual void createPopupMenu() = 0; + + /** + * Enables/disables menus. + */ + virtual void updateMenuItems() {}; + + bool canCreateMenu(); + + LLMenuGL* mPopupMenu; + bool mShowSpeaker; bool mCounterEnabled; /* initial width of chiclet, should not include counter or speaker width */ @@ -519,11 +538,6 @@ protected: */ virtual void onMenuItemClicked(const LLSD& user_data); - /** - * Displays popup menu. - */ - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /** * Enables/disables menus based on relationship with other participant. * Enables/disables "show session" menu item depending on visible IM floater existence. @@ -533,7 +547,6 @@ protected: private: LLChicletAvatarIconCtrl* mChicletIconCtrl; - LLMenuGL* mPopupMenu; }; /** @@ -598,11 +611,6 @@ protected: virtual void onMenuItemClicked(const LLSD& user_data); /** - * Displays popup menu. - */ - virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - - /** * Finds a current speaker and resets the SpeakerControl with speaker's ID */ /*virtual*/ void switchToCurrentSpeaker(); @@ -610,7 +618,6 @@ protected: private: LLChicletAvatarIconCtrl* mChicletIconCtrl; - LLMenuGL* mPopupMenu; }; /** @@ -647,6 +654,16 @@ protected: LLScriptChiclet(const Params&); friend class LLUICtrlFactory; + /** + * Creates chiclet popup menu. + */ + virtual void createPopupMenu(); + + /** + * Processes clicks on chiclet popup menu. + */ + virtual void onMenuItemClicked(const LLSD& user_data); + private: LLIconCtrl* mChicletIconCtrl; @@ -685,6 +702,16 @@ protected: LLInvOfferChiclet(const Params&); friend class LLUICtrlFactory; + /** + * Creates chiclet popup menu. + */ + virtual void createPopupMenu(); + + /** + * Processes clicks on chiclet popup menu. + */ + virtual void onMenuItemClicked(const LLSD& user_data); + private: LLChicletInvOfferIconCtrl* mChicletIconCtrl; }; @@ -767,15 +794,9 @@ protected: */ virtual void updateMenuItems(); - /** - * Displays popup menu. - */ - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - private: LLChicletGroupIconCtrl* mChicletIconCtrl; - LLMenuGL* mPopupMenu; }; /** diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index ef9da30552..8a20712ea8 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -59,13 +59,18 @@ #include "llviewertexturelist.h" #include "llstring.h" +#include "llendianswizzle.h" + +#include "llviewercontrol.h" +#include "lltrans.h" +#include "llimagedimensionsinfo.h" + const S32 PREVIEW_BORDER_WIDTH = 2; const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16; const S32 PREVIEW_TEXTURE_HEIGHT = 300; - //----------------------------------------------------------------------------- // LLFloaterImagePreview() //----------------------------------------------------------------------------- @@ -124,6 +129,11 @@ BOOL LLFloaterImagePreview::postBuild() childShow("bad_image_text"); childDisable("clothing_type_combo"); childDisable("ok_btn"); + + if(!mImageLoadError.empty()) + { + childSetValue("bad_image_text",mImageLoadError.c_str()); + } } getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); @@ -341,6 +351,27 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) codec = IMG_CODEC_PNG; } + LLImageDimensionsInfo image_info; + if(!image_info.load(src_filename,codec)) + { + mImageLoadError = image_info.getLastError(); + return false; + } + + S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); + S32 max_heigh = gSavedSettings.getS32("max_texture_dimension_Y"); + + if(image_info.getWidth() > max_width|| image_info.getHeight() > max_heigh) + { + LLStringUtil::format_map_t args; + args["WIDTH"] = llformat("%d", max_width); + args["HEIGHT"] = llformat("%d", max_heigh); + + mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); + return false; + } + + LLPointer<LLImageRaw> raw_image = new LLImageRaw; switch (codec) diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index 466bd1d0ec..3a7e1ff7d8 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -143,7 +143,8 @@ protected: LLRect mPreviewRect; LLRectf mPreviewImageRect; LLPointer<LLViewerTexture> mImagep ; - + + std::string mImageLoadError; }; #endif // LL_LLFLOATERIMAGEPREVIEW_H diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 8a056f836f..f21b6e1085 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -71,18 +71,10 @@ public: static const LLGroupComparator GROUP_COMPARATOR; -LLGroupList::Params::Params() -: no_groups_msg("no_groups_msg") -, no_filtered_groups_msg("no_filtered_groups_msg") -{ - -} LLGroupList::LLGroupList(const Params& p) -: LLFlatListView(p) +: LLFlatListViewEx(p) , mDirty(true) // to force initial update - , mNoFilteredGroupsMsg(p.no_filtered_groups_msg) - , mNoGroupsMsg(p.no_groups_msg) { // Listen for agent group changes. gAgent.addListener(this, "new group"); @@ -160,16 +152,7 @@ void LLGroupList::refresh() bool have_filter = !mNameFilter.empty(); // set no items message depend on filter state & total count of groups - if (have_filter) - { - // groups were filtered - setNoItemsCommentText(mNoFilteredGroupsMsg); - } - else if (0 == count) - { - // user is not a member of any group - setNoItemsCommentText(mNoGroupsMsg); - } + updateNoItemsMessage(have_filter); clear(); diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index 0e9da25c58..16f3fc05a3 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -47,23 +47,10 @@ * * @see setNameFilter() */ -class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener +class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener { LOG_CLASS(LLGroupList); public: - struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> - { - /** - * Contains a message for empty list when user is not a member of any group - */ - Optional<std::string> no_groups_msg; - - /** - * Contains a message for empty list when all groups don't match passed filter - */ - Optional<std::string> no_filtered_groups_msg; - Params(); - }; LLGroupList(const Params& p); virtual ~LLGroupList(); @@ -75,11 +62,6 @@ public: void toggleIcons(); bool getIconsVisible() const { return mShowIcons; } - // *WORKAROUND: two methods to overload appropriate Params due to localization issue: - // no_groups_msg & no_filtered_groups_msg attributes are not defined as translatable in VLT. See EXT-5931 - void setNoGroupsMsg(const std::string& msg) { mNoGroupsMsg = msg; } - void setNoFilteredGroupsMsg(const std::string& msg) { mNoFilteredGroupsMsg = msg; } - private: void setDirty(bool val = true) { mDirty = val; } void refresh(); @@ -94,8 +76,6 @@ private: bool mShowIcons; bool mDirty; std::string mNameFilter; - std::string mNoFilteredGroupsMsg; - std::string mNoGroupsMsg; }; class LLButton; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4357c7d426..909878207c 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2744,6 +2744,12 @@ bool LLIMMgr::endCall(const LLUUID& session_id) if (!voice_channel) return false; voice_channel->deactivate(); + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); + if (im_session) + { + // need to update speakers' state + im_session->mSpeakers->update(FALSE); + } return true; } diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 5d72827a7a..f1c13de8bb 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -107,7 +107,9 @@ BOOL LLNearbyChat::postBuild() getDockTongue(), LLDockControl::TOP, boost::bind(&LLNearbyChat::getAllowedRect, this, _1))); } - setIsChrome(true); + //fix for EXT-4621 + //chrome="true" prevents floater from stilling capture + setIsChrome(true); //chrome="true" hides floater caption if (mDragHandle) mDragHandle->setTitleVisible(TRUE); @@ -351,3 +353,14 @@ void LLNearbyChat::onFocusLost() LLPanel::onFocusLost(); } +BOOL LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask) +{ + //fix for EXT-6625 + //highlight NearbyChat history whenever mouseclick happen in NearbyChat + //setting focus to eidtor will force onFocusLost() call that in its turn will change + //background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change. + + if(mChatHistory) + mChatHistory->setFocus(TRUE); + return LLDockableFloater::handleMouseDown(x, y, mask); +} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 6ef2a1fee3..3c116dbe83 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -53,6 +53,8 @@ public: void onNearbyChatContextMenuItemClicked(const LLSD& userdata); bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + // focus overrides /*virtual*/ void onFocusLost(); /*virtual*/ void onFocusReceived(); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index ba6473839a..ce17e1d624 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -468,13 +468,14 @@ void LLPanelOutfitEdit::onOutfitItemSelectionChange(void) return; LLRect item_rect; - mLookContents->localRectToOtherView(item->getRect(), &item_rect, getChild<LLUICtrl>("outfit_wearables_panel")); + mLookContents->localRectToOtherView(item->getRect(), &item_rect, this); // TODO button(and item list) should be removed (when new widget is ready) LLRect btn_rect = mEditWearableBtn->getRect(); btn_rect.set(item_rect.mRight - btn_rect.getWidth(), item_rect.mTop, item_rect.mRight, item_rect.mBottom); mEditWearableBtn->setShape(btn_rect); + sendChildToFront(mEditWearableBtn); mEditWearableBtn->setEnabled(TRUE); if (!mEditWearableBtn->getVisible()) diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 5802d53cd1..daa2a04f65 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -512,15 +512,19 @@ BOOL LLPanelPeople::postBuild() mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); mNearbyList->setNoItemsCommentText(getString("no_one_near")); + mNearbyList->setNoItemsMsg(getString("no_one_near")); + mNearbyList->setNoFilteredItemsMsg(getString("no_one_filtered_near")); mNearbyList->setShowIcons("NearbyListShowIcons"); mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); - mRecentList->setNoItemsCommentText(getString("no_people")); + mRecentList->setNoItemsCommentText(getString("no_recent_people")); + mRecentList->setNoItemsMsg(getString("no_recent_people")); + mRecentList->setNoFilteredItemsMsg(getString("no_filtered_recent_people")); mRecentList->setShowIcons("RecentListShowIcons"); mGroupList = getChild<LLGroupList>("group_list"); - mGroupList->setNoGroupsMsg(getString("no_groups_msg")); - mGroupList->setNoFilteredGroupsMsg(getString("no_filtered_groups_msg")); + mGroupList->setNoItemsMsg(getString("no_groups_msg")); + mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg")); mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu); mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 06f24d92d6..0d02aa56b8 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1802,7 +1802,7 @@ void inventory_offer_handler(LLOfferInfo* info) payload["give_inventory_notification"] = TRUE; LLNotification::Params params(p.name); params.substitutions = p.substitutions; - params.payload = p.payload; + params.payload = payload; LLPostponedNotification::add<LLPostponedOfferNotification>( params, info->mFromID, false); } } diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index 114b9a84e3..5b77f11d71 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -10,7 +10,9 @@ name="floater_voice_controls" help_topic="floater_voice_controls" title="Voice Controls" + save_dock_state="true" save_visibility="true" + save_rect="true" single_instance="true" width="282"> <string diff --git a/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml new file mode 100644 index 0000000000..45a0a6635b --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + height="101" + layout="topleft" + left="100" + mouse_opaque="false" + name="InvOfferChiclet Menu" + top="724" + visible="false" + width="128"> + <menu_item_call + label="Close" + layout="topleft" + name="Close"> + <menu_item_call.on_click + function="InvOfferChiclet.Action" + parameter="end" /> + </menu_item_call> +</menu> diff --git a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml new file mode 100644 index 0000000000..db29d9cebc --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + height="101" + layout="topleft" + left="100" + mouse_opaque="false" + name="ScriptChiclet Menu" + top="724" + visible="false" + width="128"> + <menu_item_call + label="Close" + layout="topleft" + name="Close"> + <menu_item_call.on_click + function="ScriptChiclet.Action" + parameter="end" /> + </menu_item_call> +</menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index ca922bf724..07304eb14e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -800,7 +800,7 @@ Insufficient funds to create classified. icon="alertmodal.tga" name="DeleteAvatarPick" type="alertmodal"> -Delete pick [PICK]? +Delete pick <nolink>[PICK]</nolink>? <usetemplate name="okcancelbuttons" notext="Cancel" diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 7996a89e72..9e99a8ceaf 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -262,6 +262,7 @@ top="0" width="313"> <text_editor + enabled="false" type="string" follows="all" height="200" @@ -286,6 +287,7 @@ top="0" width="313"> <text_editor + enabled="false" type="string" follows="all" height="185" @@ -329,6 +331,7 @@ top="0" width="313"> <text_editor + enabled="false" type="string" follows="all" height="185" diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 1d99de1fa7..184ea54fcb 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -16,10 +16,11 @@ label="Click here to chat." layout="topleft" left_delta="3" - text_pad_right="25" left="0" max_length="512" name="chat_box" + text_pad_left="5" + text_pad_right="25" tool_tip="Press Enter to say, Ctrl+Enter to shout" top="2" width="283" /> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index bc37af0319..c77e4e8d5e 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -30,6 +30,20 @@ <string name="Filter.Clothes/Body" value="Clothes/Body"/> <string name="Filter.Objects" value="Objects"/> + <!-- + TODO remove this button. Added it temporary for QA to be able to test new edit wearable + panel (see EXT-6564) + --> + <button + follows="left|top|right" + height="20" + label="edit" + left="0" + top="0" + layout="topleft" + name="edit_wearable_btn" + width="40" /> + <button follows="top|left" height="23" @@ -158,18 +172,8 @@ sort_column="look_item_sort" name="look_item_sort" /> </scroll_list> - <!-- TODO remove this button. Added it temporary for QA to be able to test new edit wearable panel (see EXT-6564)--> - <button - follows="left|top|right" - height="20" - label="edit" - left="0" - top="0" - layout="topleft" - name="edit_wearable_btn" - width="40" /> - <panel + <panel background_visible="true" bevel_style="none" follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 8a4a28e188..61784fede4 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -12,12 +12,18 @@ top="0" width="333"> <string - name="no_people" + name="no_recent_people" value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." /> <string + name="no_filtered_recent_people" + value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." /> + <string name="no_one_near" value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." /> <string + name="no_one_filtered_near" + value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." /> + <string name="no_friends_online" value="No friends online" /> <string @@ -30,7 +36,7 @@ name="groups_filter_label" value="Filter Groups" /> <!-- - *WORKAROUND: for group_list.no_groups_msg & group_list.no_filtered_groups_msg attributes. + *WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes. They are not defined as translatable in VLT. See EXT-5931 --> <string diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index a480266b5a..80fddcba43 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2156,7 +2156,7 @@ Clears (deletes) the media and all params from the given face. <!-- Region/Estate Covenant --> <string name="RegionNoCovenant">There is no Covenant provided for this Estate.</string> <string name="RegionNoCovenantOtherOwner">There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details.</string> - <string name="covenant_last_modified">Last Modified:</string> + <string name="covenant_last_modified" value="Last Modified: " /> <!-- use value="" to keep the trailing space --> <string name="none_text" value=" (none) " /> <string name="never_text" value=" (never) " /> @@ -3108,5 +3108,6 @@ Abuse Report</string> <string name="AvatarBirthDateFormat">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string> <string name="DefaultMimeType">none/none</string> + <string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string> </strings> |