Automated merge

master
Roxie Linden 2010-04-21 18:17:11 -07:00
commit 5b9da4e8d9
36 changed files with 781 additions and 189 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -27,9 +27,15 @@ set(SLPlugin_SOURCE_FILES
add_executable(SLPlugin
WIN32
MACOSX_BUNDLE
${SLPlugin_SOURCE_FILES}
)
set_target_properties(SLPlugin
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
)
target_link_libraries(SLPlugin
${LLPLUGIN_LIBRARIES}
${LLMESSAGE_LIBRARIES}
@ -44,12 +50,16 @@ add_dependencies(SLPlugin
)
if (DARWIN)
# Mac version needs to link against carbon, and also needs an embedded plist (to set LSBackgroundOnly)
# Mac version needs to link against Carbon
target_link_libraries(SLPlugin ${CARBON_LIBRARY})
set_target_properties(
SLPlugin
PROPERTIES
LINK_FLAGS "-Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist"
# Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later)
add_custom_command(
TARGET SLPlugin POST_BUILD
COMMAND mkdir
ARGS
-p
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SLPlugin.app/Contents/Resources
)
endif (DARWIN)
ll_deploy_sharedlibs_command(SLPlugin)

View File

@ -51,7 +51,7 @@
#endif
/*
On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist.
On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly or LSUIElement flag in the Info.plist.
Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags:
@ -60,7 +60,8 @@
which means adding this to the gcc flags:
-Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist
Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity.
*/
#if LL_DARWIN || LL_LINUX
@ -239,6 +240,21 @@ int main(int argc, char **argv)
checkExceptionHandler();
#endif
#if LL_DARWIN
// If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground.
// Use this to track the current frontmost window and bring this process to the front if it changes.
WindowRef front_window = NULL;
WindowGroupRef layer_group = NULL;
int window_hack_state = 0;
CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group);
if(layer_group)
{
// Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube)
SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer"));
SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
}
#endif
while(!plugin->isDone())
{
timer.reset();
@ -248,6 +264,80 @@ int main(int argc, char **argv)
// Some plugins (webkit at least) will want an event loop. This qualifies.
EventRecord evt;
WaitNextEvent(0, &evt, 0, NULL);
// Check for a change in this process's frontmost window.
if(FrontWindow() != front_window)
{
ProcessSerialNumber self = { 0, kCurrentProcess };
ProcessSerialNumber parent = { 0, kNoProcess };
ProcessSerialNumber front = { 0, kNoProcess };
Boolean this_is_front_process = false;
Boolean parent_is_front_process = false;
{
// Get this process's parent
ProcessInfoRec info;
info.processInfoLength = sizeof(ProcessInfoRec);
info.processName = NULL;
info.processAppSpec = NULL;
if(GetProcessInformation( &self, &info ) == noErr)
{
parent = info.processLauncher;
}
// and figure out whether this process or its parent are currently frontmost
if(GetFrontProcess(&front) == noErr)
{
(void) SameProcess(&self, &front, &this_is_front_process);
(void) SameProcess(&parent, &front, &parent_is_front_process);
}
}
if((FrontWindow() != NULL) && (front_window == NULL))
{
// Opening the first window
if(window_hack_state == 0)
{
// Next time through the event loop, lower the window group layer
window_hack_state = 1;
}
if(layer_group)
{
SetWindowGroup(FrontWindow(), layer_group);
}
if(parent_is_front_process)
{
// Bring this process's windows to the front.
(void) SetFrontProcess( &self );
}
ActivateWindow(FrontWindow(), true);
}
else if((FrontWindow() == NULL) && (front_window != NULL))
{
// Closing the last window
if(this_is_front_process)
{
// Try to bring this process's parent to the front
(void) SetFrontProcess(&parent);
}
}
else if(window_hack_state == 1)
{
if(layer_group)
{
// Set the window group level back to something less extreme
SetWindowGroupLevel(layer_group, kCGNormalWindowLevel);
}
window_hack_state = 2;
}
front_window = FrontWindow();
}
}
#endif
F64 elapsed = timer.getElapsedTimeF64();

View File

@ -6,7 +6,7 @@
<string>English</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>LSBackgroundOnly</key>
<true/>
<key>LSUIElement</key>
<string>1</string>
</dict>
</plist>

View File

@ -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

View File

@ -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

View File

@ -426,7 +426,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
{
return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
"SLPlugin.app/Contents/MacOS/SLPlugin";
}
/*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name)

View File

@ -10712,7 +10712,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>WaterEditPresets</key>
<map>
@ -11094,7 +11094,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>

View File

@ -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)

View File

@ -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

View File

@ -227,7 +227,7 @@ void LLCallFloater::leaveCall()
LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
if (voice_channel)
{
voice_channel->deactivate();
gIMMgr->endCall(voice_channel->getSessionID());
}
}

View File

@ -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

View File

@ -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;
};
/**
@ -597,11 +610,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
*/
@ -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;
};
/**

View File

@ -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)

View File

@ -143,7 +143,8 @@ protected:
LLRect mPreviewRect;
LLRectf mPreviewImageRect;
LLPointer<LLViewerTexture> mImagep ;
std::string mImageLoadError;
};
#endif // LL_LLFLOATERIMAGEPREVIEW_H

View File

@ -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();

View File

@ -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;

View File

@ -2741,6 +2741,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;
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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())

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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>

View File

@ -18,16 +18,16 @@
name="Edit...">
<menu_item_call.on_click
function="Object.Edit" />
<menu_item_call.on_visible
<menu_item_call.on_visible
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
label="Build"
name="Build">
<menu_item_call.on_click
function="Object.Edit" />
<menu_item_call.on_visible
function="VisibleBuild"/>
function="Object.Build" />
<menu_item_call.on_visible
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
enabled="false"

View File

@ -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>

View File

@ -800,7 +800,7 @@ Insufficient funds to create classified.
icon="alertmodal.tga"
name="DeleteAvatarPick"
type="alertmodal">
Delete pick [PICK]?
Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<usetemplate
name="okcancelbuttons"
notext="Cancel"

View File

@ -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"

View File

@ -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" />

View File

@ -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"

View File

@ -12,11 +12,17 @@
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" />
@ -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

View File

@ -2165,7 +2165,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) " />
@ -3117,5 +3117,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>

View File

@ -639,10 +639,14 @@ class DarwinManifest(ViewerManifest):
self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
# plugin launcher
self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app")
# our apps dependencies on shared libs
if dylibs["llcommon"]:
mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources")
mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources")
slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources")
for libfile in ("libllcommon.dylib",
"libapr-1.0.3.7.dylib",
"libaprutil-1.0.3.8.dylib",
@ -656,9 +660,10 @@ class DarwinManifest(ViewerManifest):
{'target': target_lib,
'link' : os.path.join(mac_updater_res_path, libfile)}
)
# plugin launcher
self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
self.run_command("ln -sf %(target)r %(link)r" %
{'target': target_lib,
'link' : os.path.join(slplugin_res_path, libfile)}
)
# plugins
if self.prefix(src="", dst="llplugin"):