--HG--
branch : product-engine
master
Vadim Savchuk 2010-04-20 17:38:35 +03:00
commit 597485cceb
14 changed files with 510 additions and 99 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

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

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

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

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

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

@ -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 then [WIDTH]*[HEIGHT]</string>
</strings>