diff options
author | Eric M. Tulla (BigPapi) <tulla@lindenlab.com> | 2009-11-17 17:58:17 -0500 |
---|---|---|
committer | Eric M. Tulla (BigPapi) <tulla@lindenlab.com> | 2009-11-17 17:58:17 -0500 |
commit | 32178873564f86f0ab9ee06d485486fc9d609012 (patch) | |
tree | 4beae7908cbdd5e6af5241682110ac958b7c56ae | |
parent | 064fb26092ac9f73f9d0301f1e214e27e8418839 (diff) | |
parent | 2365dbcd459b37942ddacbcb7010232113a126c1 (diff) |
Merge of viewer2 into avp
--HG--
branch : avatar-pipeline
118 files changed, 2628 insertions, 2127 deletions
diff --git a/indra/develop.py b/indra/develop.py index 79baa613ad..05ad12f20e 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -578,12 +578,16 @@ class WindowsSetup(PlatformSetup): # devenv.com is CLI friendly, devenv.exe... not so much. return ('"%sdevenv.com" %s.sln /build %s' % (self.find_visual_studio(), self.project_name, self.build_type)) + #return ('devenv.com %s.sln /build %s' % + # (self.project_name, self.build_type)) def run(self, command, name=None, retry_on=None, retries=1): '''Run a program. If the program fails, raise an exception.''' while retries: retries = retries - 1 + print "develop.py tries to run:", command ret = os.system(command) + print "got ret", ret, "from", command if ret: if name is None: name = command.split(None, 1)[0] diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index e7ad571a90..eacbbb3ee0 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -96,6 +96,7 @@ void LLQueuedThread::shutdown() if (req->getStatus() == STATUS_QUEUED || req->getStatus() == STATUS_INPROGRESS) { ++active_count; + req->setStatus(STATUS_ABORTED); // avoid assert in deleteRequest } req->deleteRequest(); } diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 42d5ec49cd..c3d8a5aa23 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -593,10 +593,10 @@ void LLPluginClassMedia::setPriority(EPriority priority) mSleepTime = 1.0f; break; case PRIORITY_LOW: - mSleepTime = 1.0f / 50.0f; + mSleepTime = 1.0f / 25.0f; break; case PRIORITY_NORMAL: - mSleepTime = 1.0f / 100.0f; + mSleepTime = 1.0f / 50.0f; break; case PRIORITY_HIGH: mSleepTime = 1.0f / 100.0f; diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index 450dcb3c78..fc95136d9e 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -37,12 +37,13 @@ #include "llpluginmessageclasses.h" static const F32 HEARTBEAT_SECONDS = 1.0f; +static const F32 PLUGIN_IDLE_SECONDS = 1.0f / 100.0f; // Each call to idle will give the plugin this much time. LLPluginProcessChild::LLPluginProcessChild() { mInstance = NULL; mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); - mSleepTime = 1.0f / 100.0f; // default: send idle messages at 100Hz + mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz mCPUElapsed = 0.0f; } @@ -155,7 +156,7 @@ void LLPluginProcessChild::idle(void) { // Provide some time to the plugin LLPluginMessage message("base", "idle"); - message.setValueReal("time", mSleepTime); + message.setValueReal("time", PLUGIN_IDLE_SECONDS); sendMessageToPlugin(message); mInstance->idle(); diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 793a526c26..9ba0cfc6b8 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -754,6 +754,13 @@ std::string LLFontGL::nameFromFont(const LLFontGL* fontp) return fontp->mFontDescriptor.getName(); } + +// static +std::string LLFontGL::sizeFromFont(const LLFontGL* fontp) +{ + return fontp->mFontDescriptor.getSize(); +} + // static std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) { diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 5f2c86c6c1..bb7d8524e7 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -146,6 +146,7 @@ public: static U8 getStyleFromString(const std::string &style); static std::string nameFromFont(const LLFontGL* fontp); + static std::string sizeFromFont(const LLFontGL* fontp); static std::string nameFromHAlign(LLFontGL::HAlign align); static LLFontGL::HAlign hAlignFromName(const std::string& name); diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index bbaf908d2e..b65f248db2 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -146,7 +146,7 @@ LLButton::LLButton(const LLButton::Params& p) mHoverGlowStrength(p.hover_glow_amount), mCommitOnReturn(p.commit_on_return), mFadeWhenDisabled(FALSE), - mForcePressedState(FALSE), + mForcePressedState(false), mLastDrawCharsCount(0) { static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 08f289092f..3c1b57c4be 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -238,7 +238,7 @@ public: static void setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); static void showHelp(LLUICtrl* ctrl, const LLSD& sdname); - void setForcePressedState(BOOL b) { mForcePressedState = b; } + void setForcePressedState(bool b) { mForcePressedState = b; } protected: LLPointer<LLUIImage> getImageUnselected() const { return mImageUnselected; } @@ -315,7 +315,7 @@ private: BOOL mNeedsHighlight; BOOL mCommitOnReturn; BOOL mFadeWhenDisabled; - BOOL mForcePressedState; + bool mForcePressedState; LLFrameTimer mFlashingTimer; }; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 36e309d639..803978bfa2 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -109,7 +109,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) // Text label button LLButton::Params button_params = (mAllowTextEntry ? p.combo_button : p.drop_down_button); - button_params.mouse_down_callback.function(boost::bind(&LLComboBox::onButtonDown, this)); + button_params.mouse_down_callback.function( + boost::bind(&LLComboBox::onButtonMouseDown, this)); button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT); button_params.rect(p.rect); @@ -140,6 +141,10 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mList = LLUICtrlFactory::create<LLScrollListCtrl>(params); addChild(mList); + // Mouse-down on button will transfer mouse focus to the list + // Grab the mouse-up event and make sure the button state is correct + mList->setMouseUpCallback(boost::bind(&LLComboBox::onListMouseUp, this)); + for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin(); it != p.items().end(); ++it) @@ -644,7 +649,7 @@ void LLComboBox::hideList() } } -void LLComboBox::onButtonDown() +void LLComboBox::onButtonMouseDown() { if (!mList->getVisible()) { @@ -670,6 +675,10 @@ void LLComboBox::onButtonDown() if (mButton->hasMouseCapture()) { gFocusMgr.setMouseCapture(mList); + + // But keep the "pressed" look, which buttons normally lose when they + // lose focus + mButton->setForcePressedState(true); } } else @@ -679,6 +688,12 @@ void LLComboBox::onButtonDown() } +void LLComboBox::onListMouseUp() +{ + // In some cases this is the termination of a mouse click that started on + // the button, so clear its pressed state + mButton->setForcePressedState(false); +} //------------------------------------------------------------------ // static functions diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 6285ca5170..11acdb9b8f 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -204,7 +204,8 @@ public: void setButtonVisible(BOOL visible); - void onButtonDown(); + void onButtonMouseDown(); + void onListMouseUp(); void onItemSelected(const LLSD& data); void onTextCommit(const LLSD& data); diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index f56cb2eee7..c3dd4ae647 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -127,6 +127,10 @@ void LLDockableFloater::setVisible(BOOL visible) mDockControl.get()->repositionDockable(); } + if (visible) + { + LLFloater::setFrontmost(TRUE); + } LLFloater::setVisible(visible); } diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index a657ed039a..cdbd17e4dc 100644 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -133,11 +133,11 @@ void LLMenuButton::draw() if (mMenuVisibleLastFrame) { - setForcePressedState(TRUE); + setForcePressedState(true); } LLButton::draw(); - setForcePressedState(FALSE); + setForcePressedState(false); } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7b1aaac35c..caaf47240f 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1507,8 +1507,11 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c link_params.color = match.getColor(); // apply font name from requested style_params std::string font_name = LLFontGL::nameFromFont(style_params.font()); - link_params.font.name.setIfNotProvided(font_name); - link_params.font.style = "UNDERLINE"; + std::string font_size = LLFontGL::sizeFromFont(style_params.font()); + link_params.font.name(font_name); + link_params.font.size(font_size); + link_params.font.style("UNDERLINE"); + link_params.link_href = match.getUrl(); // output the text before the Url diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 70d78c77cd..c376a73615 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -139,6 +139,7 @@ public: // TODO: add optional style parameter virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style virtual std::string getText() const; + void setMaxTextLength(S32 length) { mMaxTextByteLength = length; } // wide-char versions void setWText(const LLWString& text); diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp index 717e135412..5df1d35383 100644 --- a/indra/llui/lltoggleablemenu.cpp +++ b/indra/llui/lltoggleablemenu.cpp @@ -40,6 +40,7 @@ static LLDefaultChildRegistry::Register<LLToggleableMenu> r("toggleable_menu"); LLToggleableMenu::LLToggleableMenu(const LLToggleableMenu::Params& p) : LLMenuGL(p), + mButtonRect(), mClosedByButtonClick(false) { } @@ -56,13 +57,19 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn) } } -void LLToggleableMenu::setButtonRect(const LLRect& rect, LLView* current_view) +void LLToggleableMenu::setButtonRect(const LLRect& rect, LLView* current_view) { LLRect screen; current_view->localRectToScreen(rect, &screen); mButtonRect = screen; } +void LLToggleableMenu::setButtonRect(LLView* current_view) +{ + LLRect rect = current_view->getLocalRect(); + setButtonRect(rect, current_view); +} + bool LLToggleableMenu::toggleVisibility() { if (mClosedByButtonClick) diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h index 3cd66e04a8..9d8c5261b9 100644 --- a/indra/llui/lltoggleablemenu.h +++ b/indra/llui/lltoggleablemenu.h @@ -49,8 +49,11 @@ protected: public: virtual void handleVisibilityChange (BOOL curVisibilityIn); + const LLRect& getButtonRect() const { return mButtonRect; } + // Converts the given local button rect to a screen rect void setButtonRect(const LLRect& rect, LLView* current_view); + void setButtonRect(LLView* current_view); // Returns "true" if menu was not closed by button click // and is not still visible. If menu is visible toggles diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index bb85177811..959313a5b6 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -163,6 +163,7 @@ LLToolTip::Params::Params() visible_time_far("visible_time_far", LLUI::sSettingGroups["config"]->getF32( "ToolTipVisibleTimeFar" )), sticky_rect("sticky_rect"), image("image"), + text_color("text_color"), time_based_media("time_based_media", false), web_based_media("web_based_media", false), media_playing("media_playing", false) @@ -186,7 +187,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p) params.h_pad = 0; params.v_pad = 0; params.mouse_opaque = false; - params.text_color = LLUIColorTable::instance().getColor( "ToolTipTextColor" ); + params.text_color = p.text_color; params.bg_visible = false; params.font = p.font; params.use_ellipses = true; diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index 8c8fdf0a4c..7978b6a583 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -88,6 +88,7 @@ public: Optional<LLRect> sticky_rect; Optional<const LLFontGL*> font; Optional<LLUIImage*> image; + Optional<LLUIColor> text_color; Optional<bool> time_based_media, web_based_media, media_playing; diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 26f38ca59b..20ba5768db 100644 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -1,536 +1,536 @@ -/**
- * @file media_plugin_quicktime.cpp
- * @brief QuickTime plugin for LLMedia API plugin system
- *
- * $LicenseInfo:firstyear=2008&license=viewergpl$
- *
- * Copyright (c) 2008, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llgl.h"
-
-#include "llplugininstance.h"
-#include "llpluginmessage.h"
-#include "llpluginmessageclasses.h"
-#include "media_plugin_base.h"
-
-#if LL_QUICKTIME_ENABLED
-
-#if defined(LL_DARWIN)
- #include <QuickTime/QuickTime.h>
-#elif defined(LL_WINDOWS)
- #include "MacTypes.h"
- #include "QTML.h"
- #include "Movies.h"
- #include "QDoffscreen.h"
- #include "FixMath.h"
- #include "QTLoadLibraryUtils.h"
-#endif
-
-// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint
-////////////////////////////////////////////////////////////////////////////////
-//
-class MediaPluginQuickTime : public MediaPluginBase
-{
-public:
- MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginQuickTime();
-
- /* virtual */ void receiveMessage(const char *message_string);
-
-private:
-
- int mNaturalWidth;
- int mNaturalHeight;
- Movie mMovieHandle;
- GWorldPtr mGWorldHandle;
- ComponentInstance mMovieController;
- int mCurVolume;
- bool mMediaSizeChanging;
- bool mIsLooping;
- std::string mMovieTitle;
- bool mReceivedTitle;
- const int mMinWidth;
- const int mMaxWidth;
- const int mMinHeight;
- const int mMaxHeight;
- F64 mPlayRate;
- std::string mNavigateURL;
-
- enum ECommand {
- COMMAND_NONE,
- COMMAND_STOP,
- COMMAND_PLAY,
- COMMAND_FAST_FORWARD,
- COMMAND_FAST_REWIND,
- COMMAND_PAUSE,
- COMMAND_SEEK,
- };
- ECommand mCommand;
-
- // Override this to add current time and duration to the message
- /*virtual*/ void setDirty(int left, int top, int right, int bottom)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
-
- message.setValueS32("left", left);
- message.setValueS32("top", top);
- message.setValueS32("right", right);
- message.setValueS32("bottom", bottom);
-
- if(mMovieHandle)
- {
- message.setValueReal("current_time", getCurrentTime());
- message.setValueReal("duration", getDuration());
- message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle)));
- }
-
- sendMessage(message);
- }
-
-
- static Rect rectFromSize(int width, int height)
- {
- Rect result;
-
-
- result.left = 0;
- result.top = 0;
- result.right = width;
- result.bottom = height;
-
- return result;
- }
-
- Fixed getPlayRate(void)
- {
- Fixed result;
- if(mPlayRate == 0.0f)
- {
- // Default to the movie's preferred rate
- result = GetMoviePreferredRate(mMovieHandle);
- if(result == 0)
- {
- // Don't return a 0 play rate, ever.
- std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl;
- result = X2Fix(1.0f);
- }
- }
- else
- {
- result = X2Fix(mPlayRate);
- }
-
- return result;
- }
-
- void load( const std::string url )
- {
-
- if ( url.empty() )
- return;
-
- // Stop and unload any existing movie before starting another one.
- unload();
-
- setStatus(STATUS_LOADING);
-
- //In case std::string::c_str() makes a copy of the url data,
- //make sure there is memory to hold it before allocating memory for handle.
- //if fails, NewHandleClear(...) should return NULL.
- const char* url_string = url.c_str() ;
- Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) );
-
- if ( NULL == handle || noErr != MemError() || NULL == *handle )
- {
- setStatus(STATUS_ERROR);
- return;
- }
-
- BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) );
-
- OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType );
- DisposeHandle( handle );
- if ( noErr != err )
- {
- setStatus(STATUS_ERROR);
- return;
- };
-
- mNavigateURL = url;
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
- message.setValue("uri", mNavigateURL);
- sendMessage(message);
-
- // do pre-roll actions (typically fired for streaming movies but not always)
- PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this );
-
- Rect movie_rect = rectFromSize(mWidth, mHeight);
-
- // make a new movie controller
- mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie );
-
- // movie controller
- MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this );
-
- SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize );
-
- // function that gets called when a frame is drawn
- SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this );
-
- setStatus(STATUS_LOADED);
-
- sizeChanged();
- };
-
- bool unload()
- {
- // new movie and have to get title again
- mReceivedTitle = false;
-
- if ( mMovieHandle )
- {
- StopMovie( mMovieHandle );
- if ( mMovieController )
- {
- MCMovieChanged( mMovieController, mMovieHandle );
- };
- };
-
- if ( mMovieController )
- {
- MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this );
- DisposeMovieController( mMovieController );
- mMovieController = NULL;
- };
-
- if ( mMovieHandle )
- {
- SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this );
- DisposeMovie( mMovieHandle );
- mMovieHandle = NULL;
- };
-
- if ( mGWorldHandle )
- {
- DisposeGWorld( mGWorldHandle );
- mGWorldHandle = NULL;
- };
-
- setStatus(STATUS_NONE);
-
- return true;
- }
-
- bool navigateTo( const std::string url )
- {
- unload();
- load( url );
-
- return true;
- };
-
- bool sizeChanged()
- {
- if ( ! mMovieHandle )
- return false;
-
- // Check to see whether the movie's natural size has updated
- {
- int width, height;
- getMovieNaturalSize(&width, &height);
- if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight)))
- {
- mNaturalWidth = width;
- mNaturalHeight = height;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
- message.setValue("name", mTextureSegmentName);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- sendMessage(message);
- //std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
- }
- }
-
- // sanitize destination size
- Rect dest_rect = rectFromSize(mWidth, mHeight);
-
- // media depth won't change
- int depth_bits = mDepth * 8;
- long rowbytes = mDepth * mTextureWidth;
-
- GWorldPtr old_gworld_handle = mGWorldHandle;
-
- if(mPixels != NULL)
- {
- // We have pixels. Set up a GWorld pointing at the texture.
- OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
- if ( noErr != result )
- {
- // TODO: unrecoverable?? throw exception? return something?
- return false;
- }
- }
- else
- {
- // We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
- Rect tempRect = rectFromSize(1, 1);
- OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
- if ( noErr != result )
- {
- // TODO: unrecoverable?? throw exception? return something?
- return false;
- }
- }
-
- SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
-
- // If the GWorld was already set up, delete it.
- if(old_gworld_handle != NULL)
- {
- DisposeGWorld( old_gworld_handle );
- }
-
- // Set up the movie display matrix
- {
- // scale movie to fit rect and invert vertically to match opengl image format
- MatrixRecord transform;
- SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix
- double scaleX = (double) mWidth / mNaturalWidth;
- double scaleY = -1.0 * (double) mHeight / mNaturalHeight;
- double centerX = mWidth / 2.0;
- double centerY = mHeight / 2.0;
- ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) );
- SetMovieMatrix( mMovieHandle, &transform );
- }
-
- // update movie controller
- if ( mMovieController )
- {
- MCSetControllerPort( mMovieController, mGWorldHandle );
- MCPositionController( mMovieController, &dest_rect, &dest_rect,
- mcTopLeftMovie | mcPositionDontInvalidate );
- MCMovieChanged( mMovieController, mMovieHandle );
- }
-
-
- // Emit event with size change so the calling app knows about it too
- // TODO:
- //LLMediaEvent event( this );
- //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event );
-
- return true;
- }
- static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref )
- {
- Boolean result = false;
-
- MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
-
- switch( action )
- {
- // handle window resizing
- case mcActionControllerSizeChanged:
- // Ensure that the movie draws correctly at the new size
- self->sizeChanged();
- break;
-
- // Block any movie controller actions that open URLs.
- case mcActionLinkToURL:
- case mcActionGetNextURL:
- case mcActionLinkToURLExtended:
- // Prevent the movie controller from handling the message
- result = true;
- break;
-
- default:
- break;
- };
-
- return result;
- };
-
- static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref )
- {
- MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
-
- // IMPORTANT: typically, a consumer who is observing this event will set a flag
- // when this event is fired then render later. Be aware that the media stream
- // can change during this period - dimensions, depth, format etc.
- //LLMediaEvent event( self );
-// self->updateQuickTime();
- // TODO ^^^
-
-
- if ( self->mWidth > 0 && self->mHeight > 0 )
- self->setDirty( 0, 0, self->mWidth, self->mHeight );
-
- return noErr;
- };
-
- static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref )
- {
- MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
-
- // TODO:
- //LLMediaEvent event( self );
- //self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event );
-
- // Send a "navigate complete" event.
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
- message.setValue("uri", self->mNavigateURL);
- message.setValueS32("result_code", 200);
- message.setValue("result_string", "OK");
- self->sendMessage(message);
- };
-
-
- void rewind()
- {
- GoToBeginningOfMovie( mMovieHandle );
- MCMovieChanged( mMovieController, mMovieHandle );
- };
-
- bool processState()
- {
- if ( mCommand == COMMAND_PLAY )
- {
- if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE )
- {
- long state = GetMovieLoadState( mMovieHandle );
-
- if ( state >= kMovieLoadStatePlaythroughOK )
- {
- // if the movie is at the end (generally because it reached it naturally)
- // and we play is requested, jump back to the start of the movie.
- // note: this is different from having loop flag set.
- if ( IsMovieDone( mMovieHandle ) )
- {
- Fixed rate = X2Fix( 0.0 );
- MCDoAction( mMovieController, mcActionPlay, (void*)rate );
- rewind();
- };
-
- MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() );
- MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
- setStatus(STATUS_PLAYING);
- mCommand = COMMAND_NONE;
- };
- };
- }
- else
- if ( mCommand == COMMAND_STOP )
- {
- if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE )
- {
- if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
- {
- Fixed rate = X2Fix( 0.0 );
- MCDoAction( mMovieController, mcActionPlay, (void*)rate );
- rewind();
-
- setStatus(STATUS_LOADED);
- mCommand = COMMAND_NONE;
- };
- };
- }
- else
- if ( mCommand == COMMAND_PAUSE )
- {
- if ( mStatus == STATUS_PLAYING )
- {
- if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
- {
- Fixed rate = X2Fix( 0.0 );
- MCDoAction( mMovieController, mcActionPlay, (void*)rate );
- setStatus(STATUS_PAUSED);
- mCommand = COMMAND_NONE;
- };
- };
- };
-
- return true;
- };
-
- void play(F64 rate)
- {
- mPlayRate = rate;
- mCommand = COMMAND_PLAY;
- };
-
- void stop()
- {
- mCommand = COMMAND_STOP;
- };
-
- void pause()
- {
- mCommand = COMMAND_PAUSE;
- };
-
- void getMovieNaturalSize(int *movie_width, int *movie_height)
- {
- Rect rect;
-
- GetMovieNaturalBoundsRect( mMovieHandle, &rect );
-
- int width = ( rect.right - rect.left );
- int height = ( rect.bottom - rect.top );
-
- // make sure width and height fall in valid range
- if ( width < mMinWidth )
- width = mMinWidth;
-
- if ( width > mMaxWidth )
- width = mMaxWidth;
-
- if ( height < mMinHeight )
- height = mMinHeight;
-
- if ( height > mMaxHeight )
- height = mMaxHeight;
-
- // return the new rect
- *movie_width = width;
- *movie_height = height;
- }
-
- void updateQuickTime(int milliseconds)
- {
- if ( ! mMovieHandle )
- return;
-
- if ( ! mMovieController )
- return;
-
- // this wasn't required in 1.xx viewer but we have to manually
- // work the Windows message pump now
- #if defined( LL_WINDOWS )
+/** + * @file media_plugin_quicktime.cpp + * @brief QuickTime plugin for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_QUICKTIME_ENABLED + +#if defined(LL_DARWIN) + #include <QuickTime/QuickTime.h> +#elif defined(LL_WINDOWS) + #include "MacTypes.h" + #include "QTML.h" + #include "Movies.h" + #include "QDoffscreen.h" + #include "FixMath.h" + #include "QTLoadLibraryUtils.h" +#endif + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginQuickTime : public MediaPluginBase +{ +public: + MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginQuickTime(); + + /* virtual */ void receiveMessage(const char *message_string); + +private: + + int mNaturalWidth; + int mNaturalHeight; + Movie mMovieHandle; + GWorldPtr mGWorldHandle; + ComponentInstance mMovieController; + int mCurVolume; + bool mMediaSizeChanging; + bool mIsLooping; + std::string mMovieTitle; + bool mReceivedTitle; + const int mMinWidth; + const int mMaxWidth; + const int mMinHeight; + const int mMaxHeight; + F64 mPlayRate; + std::string mNavigateURL; + + enum ECommand { + COMMAND_NONE, + COMMAND_STOP, + COMMAND_PLAY, + COMMAND_FAST_FORWARD, + COMMAND_FAST_REWIND, + COMMAND_PAUSE, + COMMAND_SEEK, + }; + ECommand mCommand; + + // Override this to add current time and duration to the message + /*virtual*/ void setDirty(int left, int top, int right, int bottom) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + if(mMovieHandle) + { + message.setValueReal("current_time", getCurrentTime()); + message.setValueReal("duration", getDuration()); + message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle))); + } + + sendMessage(message); + } + + + static Rect rectFromSize(int width, int height) + { + Rect result; + + + result.left = 0; + result.top = 0; + result.right = width; + result.bottom = height; + + return result; + } + + Fixed getPlayRate(void) + { + Fixed result; + if(mPlayRate == 0.0f) + { + // Default to the movie's preferred rate + result = GetMoviePreferredRate(mMovieHandle); + if(result == 0) + { + // Don't return a 0 play rate, ever. + std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl; + result = X2Fix(1.0f); + } + } + else + { + result = X2Fix(mPlayRate); + } + + return result; + } + + void load( const std::string url ) + { + + if ( url.empty() ) + return; + + // Stop and unload any existing movie before starting another one. + unload(); + + setStatus(STATUS_LOADING); + + //In case std::string::c_str() makes a copy of the url data, + //make sure there is memory to hold it before allocating memory for handle. + //if fails, NewHandleClear(...) should return NULL. + const char* url_string = url.c_str() ; + Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); + + if ( NULL == handle || noErr != MemError() || NULL == *handle ) + { + setStatus(STATUS_ERROR); + return; + } + + BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) ); + + OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); + DisposeHandle( handle ); + if ( noErr != err ) + { + setStatus(STATUS_ERROR); + return; + }; + + mNavigateURL = url; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + message.setValue("uri", mNavigateURL); + sendMessage(message); + + // do pre-roll actions (typically fired for streaming movies but not always) + PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this ); + + Rect movie_rect = rectFromSize(mWidth, mHeight); + + // make a new movie controller + mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); + + // movie controller + MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); + + SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); + + // function that gets called when a frame is drawn + SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); + + setStatus(STATUS_LOADED); + + sizeChanged(); + }; + + bool unload() + { + // new movie and have to get title again + mReceivedTitle = false; + + if ( mMovieHandle ) + { + StopMovie( mMovieHandle ); + if ( mMovieController ) + { + MCMovieChanged( mMovieController, mMovieHandle ); + }; + }; + + if ( mMovieController ) + { + MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); + DisposeMovieController( mMovieController ); + mMovieController = NULL; + }; + + if ( mMovieHandle ) + { + SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); + DisposeMovie( mMovieHandle ); + mMovieHandle = NULL; + }; + + if ( mGWorldHandle ) + { + DisposeGWorld( mGWorldHandle ); + mGWorldHandle = NULL; + }; + + setStatus(STATUS_NONE); + + return true; + } + + bool navigateTo( const std::string url ) + { + unload(); + load( url ); + + return true; + }; + + bool sizeChanged() + { + if ( ! mMovieHandle ) + return false; + + // Check to see whether the movie's natural size has updated + { + int width, height; + getMovieNaturalSize(&width, &height); + if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight))) + { + mNaturalWidth = width; + mNaturalHeight = height; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); + message.setValue("name", mTextureSegmentName); + message.setValueS32("width", width); + message.setValueS32("height", height); + sendMessage(message); + //std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl; + } + } + + // sanitize destination size + Rect dest_rect = rectFromSize(mWidth, mHeight); + + // media depth won't change + int depth_bits = mDepth * 8; + long rowbytes = mDepth * mTextureWidth; + + GWorldPtr old_gworld_handle = mGWorldHandle; + + if(mPixels != NULL) + { + // We have pixels. Set up a GWorld pointing at the texture. + OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes); + if ( noErr != result ) + { + // TODO: unrecoverable?? throw exception? return something? + return false; + } + } + else + { + // We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally. + Rect tempRect = rectFromSize(1, 1); + OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0); + if ( noErr != result ) + { + // TODO: unrecoverable?? throw exception? return something? + return false; + } + } + + SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) ); + + // If the GWorld was already set up, delete it. + if(old_gworld_handle != NULL) + { + DisposeGWorld( old_gworld_handle ); + } + + // Set up the movie display matrix + { + // scale movie to fit rect and invert vertically to match opengl image format + MatrixRecord transform; + SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix + double scaleX = (double) mWidth / mNaturalWidth; + double scaleY = -1.0 * (double) mHeight / mNaturalHeight; + double centerX = mWidth / 2.0; + double centerY = mHeight / 2.0; + ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) ); + SetMovieMatrix( mMovieHandle, &transform ); + } + + // update movie controller + if ( mMovieController ) + { + MCSetControllerPort( mMovieController, mGWorldHandle ); + MCPositionController( mMovieController, &dest_rect, &dest_rect, + mcTopLeftMovie | mcPositionDontInvalidate ); + MCMovieChanged( mMovieController, mMovieHandle ); + } + + + // Emit event with size change so the calling app knows about it too + // TODO: + //LLMediaEvent event( this ); + //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; + } + static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) + { + Boolean result = false; + + MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + + switch( action ) + { + // handle window resizing + case mcActionControllerSizeChanged: + // Ensure that the movie draws correctly at the new size + self->sizeChanged(); + break; + + // Block any movie controller actions that open URLs. + case mcActionLinkToURL: + case mcActionGetNextURL: + case mcActionLinkToURLExtended: + // Prevent the movie controller from handling the message + result = true; + break; + + default: + break; + }; + + return result; + }; + + static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref ) + { + MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + + // IMPORTANT: typically, a consumer who is observing this event will set a flag + // when this event is fired then render later. Be aware that the media stream + // can change during this period - dimensions, depth, format etc. + //LLMediaEvent event( self ); +// self->updateQuickTime(); + // TODO ^^^ + + + if ( self->mWidth > 0 && self->mHeight > 0 ) + self->setDirty( 0, 0, self->mWidth, self->mHeight ); + + return noErr; + }; + + static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) + { + MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + + // TODO: + //LLMediaEvent event( self ); + //self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); + + // Send a "navigate complete" event. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + message.setValue("uri", self->mNavigateURL); + message.setValueS32("result_code", 200); + message.setValue("result_string", "OK"); + self->sendMessage(message); + }; + + + void rewind() + { + GoToBeginningOfMovie( mMovieHandle ); + MCMovieChanged( mMovieController, mMovieHandle ); + }; + + bool processState() + { + if ( mCommand == COMMAND_PLAY ) + { + if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE ) + { + long state = GetMovieLoadState( mMovieHandle ); + + if ( state >= kMovieLoadStatePlaythroughOK ) + { + // if the movie is at the end (generally because it reached it naturally) + // and we play is requested, jump back to the start of the movie. + // note: this is different from having loop flag set. + if ( IsMovieDone( mMovieHandle ) ) + { + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); + rewind(); + }; + + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + setStatus(STATUS_PLAYING); + mCommand = COMMAND_NONE; + }; + }; + } + else + if ( mCommand == COMMAND_STOP ) + { + if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE ) + { + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) + { + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); + rewind(); + + setStatus(STATUS_LOADED); + mCommand = COMMAND_NONE; + }; + }; + } + else + if ( mCommand == COMMAND_PAUSE ) + { + if ( mStatus == STATUS_PLAYING ) + { + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) + { + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); + setStatus(STATUS_PAUSED); + mCommand = COMMAND_NONE; + }; + }; + }; + + return true; + }; + + void play(F64 rate) + { + mPlayRate = rate; + mCommand = COMMAND_PLAY; + }; + + void stop() + { + mCommand = COMMAND_STOP; + }; + + void pause() + { + mCommand = COMMAND_PAUSE; + }; + + void getMovieNaturalSize(int *movie_width, int *movie_height) + { + Rect rect; + + GetMovieNaturalBoundsRect( mMovieHandle, &rect ); + + int width = ( rect.right - rect.left ); + int height = ( rect.bottom - rect.top ); + + // make sure width and height fall in valid range + if ( width < mMinWidth ) + width = mMinWidth; + + if ( width > mMaxWidth ) + width = mMaxWidth; + + if ( height < mMinHeight ) + height = mMinHeight; + + if ( height > mMaxHeight ) + height = mMaxHeight; + + // return the new rect + *movie_width = width; + *movie_height = height; + } + + void updateQuickTime(int milliseconds) + { + if ( ! mMovieHandle ) + return; + + if ( ! mMovieController ) + return; + + // this wasn't required in 1.xx viewer but we have to manually + // work the Windows message pump now + #if defined( LL_WINDOWS ) MSG msg;
while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
@@ -538,567 +538,573 @@ private: TranslateMessage( &msg );
DispatchMessage( &msg );
};
- #endif
-
- MCIdle( mMovieController );
-
- if ( ! mGWorldHandle )
- return;
-
- if ( mMediaSizeChanging )
- return;
-
- // update state machine
- processState();
-
- // see if title arrived and if so, update member variable with contents
- checkTitle();
-
- // QT call to see if we are at the end - can't do with controller
- if ( IsMovieDone( mMovieHandle ) )
- {
- // special code for looping - need to rewind at the end of the movie
- if ( mIsLooping )
- {
- // go back to start
- rewind();
-
- if ( mMovieController )
- {
- // kick off new play
- MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() );
-
- // set the volume
- MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
- };
- }
- else
- {
- if(mStatus == STATUS_PLAYING)
- {
- setStatus(STATUS_DONE);
- }
- }
- }
-
- };
-
- int getDataWidth() const
- {
- if ( mGWorldHandle )
- {
- int depth = mDepth;
-
- if (depth < 1)
- depth = 1;
-
- // ALWAYS use the row bytes from the PixMap if we have a GWorld because
- // sometimes it's not the same as mMediaDepth * mMediaWidth !
- PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
- return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
- }
- else
- {
- // TODO : return LLMediaImplCommon::getaDataWidth();
- return 0;
- }
- };
-
- void seek( F64 time )
- {
- if ( mMovieController )
- {
- TimeRecord when;
- when.scale = GetMovieTimeScale( mMovieHandle );
- when.base = 0;
-
- // 'time' is in (floating point) seconds. The timebase time will be in 'units', where
- // there are 'scale' units per second.
- SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) );
-
- when.value.hi = ( SInt32 )( raw_time >> 32 );
- when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) );
-
- MCDoAction( mMovieController, mcActionGoToTime, &when );
- };
- };
-
- F64 getLoadedDuration()
- {
- TimeValue duration;
- if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr)
- {
- // If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie.
- duration = GetMovieDuration( mMovieHandle );
- }
- TimeValue scale = GetMovieTimeScale( mMovieHandle );
-
- return (F64)duration / (F64)scale;
- };
-
- F64 getDuration()
- {
- TimeValue duration = GetMovieDuration( mMovieHandle );
- TimeValue scale = GetMovieTimeScale( mMovieHandle );
-
- return (F64)duration / (F64)scale;
- };
-
- F64 getCurrentTime()
- {
- TimeValue curr_time = GetMovieTime( mMovieHandle, 0 );
- TimeValue scale = GetMovieTimeScale( mMovieHandle );
-
- return (F64)curr_time / (F64)scale;
- };
-
- void setVolume( F64 volume )
- {
- mCurVolume = (short)(volume * ( double ) 0x100 );
-
- if ( mMovieController )
- {
- MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void update(int milliseconds = 0)
- {
- updateQuickTime(milliseconds);
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void mouseDown( int x, int y )
- {
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void mouseUp( int x, int y )
- {
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void mouseMove( int x, int y )
- {
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void keyPress( unsigned char key )
- {
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // Grab movie title into mMovieTitle - should be called repeatedly
- // until it returns true since movie title takes a while to become
- // available.
- const bool getMovieTitle()
- {
- // grab meta data from movie
- QTMetaDataRef media_data_ref;
- OSErr result = QTCopyMovieMetaData( mMovieHandle, &media_data_ref );
- if ( noErr != result )
- return false;
-
- // look up "Display Name" in meta data
- OSType meta_data_key = kQTMetaDataCommonKeyDisplayName;
- QTMetaDataItem item = kQTMetaDataItemUninitialized;
- result = QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard,
- 0, kQTMetaDataKeyFormatCommon,
- (const UInt8 *)&meta_data_key,
- sizeof( meta_data_key ), &item );
- if ( noErr != result )
- return false;
-
- // find the size of the title
- ByteCount size;
- result = QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size );
- if ( noErr != result || size <= 0 )
- return false;
-
- // allocate some space and grab it
- UInt8* item_data = new UInt8( size );
- memset( item_data, 0, size * sizeof( UInt8* ) );
- result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL );
- if ( noErr != result )
- return false;
-
- // save it
- mMovieTitle = std::string( (char* )item_data );
-
- // clean up
- delete [] item_data;
-
- return true;
- };
-
- // called regularly to see if title changed
- void checkTitle()
- {
- // we did already receive title so keep checking
- if ( ! mReceivedTitle )
- {
- // grab title from movie meta data
- if ( getMovieTitle() )
- {
- // pass back to host application
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", mMovieTitle );
- sendMessage( message );
-
- // stop looking once we find a title for this movie.
- // TODO: this may to be reset if movie title changes
- // during playback but this is okay for now
- mReceivedTitle = true;
- };
- };
- };
-};
-
-MediaPluginQuickTime::MediaPluginQuickTime(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data ) :
- MediaPluginBase(host_send_func, host_user_data),
- mMinWidth( 0 ),
- mMaxWidth( 2048 ),
- mMinHeight( 0 ),
- mMaxHeight( 2048 )
-{
-// std::cerr << "MediaPluginQuickTime constructor" << std::endl;
-
- mNaturalWidth = -1;
- mNaturalHeight = -1;
- mMovieHandle = 0;
- mGWorldHandle = 0;
- mMovieController = 0;
- mCurVolume = 0x99;
- mMediaSizeChanging = false;
- mIsLooping = false;
- mMovieTitle = std::string();
- mReceivedTitle = false;
- mCommand = COMMAND_NONE;
- mPlayRate = 0.0f;
- mStatus = STATUS_NONE;
-}
-
-MediaPluginQuickTime::~MediaPluginQuickTime()
-{
-// std::cerr << "MediaPluginQuickTime destructor" << std::endl;
-
- ExitMovies();
-
-#ifdef LL_WINDOWS
- TerminateQTML();
-// std::cerr << "QuickTime closing down" << std::endl;
-#endif
-}
-
-
-void MediaPluginQuickTime::receiveMessage(const char *message_string)
-{
-// std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
- LLPluginMessage message_in;
-
- if(message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if(message_name == "init")
- {
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- // Normally a plugin would only specify one of these two subclasses, but this is a demo...
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
- message.setValueLLSD("versions", versions);
-
- #ifdef LL_WINDOWS
-
- // QuickTime 7.6.4 has an issue (that was not present in 7.6.2) with initializing QuickTime
- // according to this article: http://lists.apple.com/archives/QuickTime-API/2009/Sep/msg00097.html
- // The solution presented there appears to work.
- QTLoadLibrary("qtcf.dll");
-
- // main initialization for QuickTime - only required on Windows
- OSErr result = InitializeQTML( 0L );
- if ( result != noErr )
- {
- //TODO: If no QT on Windows, this fails - respond accordingly.
- }
- else
- {
- //std::cerr << "QuickTime initialized" << std::endl;
- };
- #endif
-
- // required for both Windows and Mac
- EnterMovies();
-
- std::string plugin_version = "QuickTime media plugin, QuickTime version ";
-
- long version = 0;
- Gestalt( gestaltQuickTimeVersion, &version );
- std::ostringstream codec( "" );
- codec << std::hex << version << std::dec;
- plugin_version += codec.str();
- message.setValue("plugin_version", plugin_version);
- sendMessage(message);
-
- // Plugin gets to decide the texture parameters to use.
- message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- #if defined(LL_WINDOWS)
- // Values for Windows
- mDepth = 3;
- message.setValueU32("format", GL_RGB);
- message.setValueU32("type", GL_UNSIGNED_BYTE);
-
- // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even.
- // Padding to a multiple of 3*32 guarantees it'll divide out properly.
- message.setValueU32("padding", 32 * 3);
- #else
- // Values for Mac
- mDepth = 4;
- message.setValueU32("format", GL_BGRA_EXT);
- #ifdef __BIG_ENDIAN__
- message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV );
- #else
- message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8);
- #endif
-
- // Pad texture width to a multiple of 32 bytes, to line up with cache lines.
- message.setValueU32("padding", 32);
- #endif
- message.setValueS32("depth", mDepth);
- message.setValueU32("internalformat", GL_RGB);
- message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left.
- message.setValueBoolean("allow_downsample", true);
- sendMessage(message);
- }
- else if(message_name == "idle")
- {
- // no response is necessary here.
- F64 time = message_in.getValueReal("time");
-
- // Convert time to milliseconds for update()
- update((int)(time * 1000.0f));
- }
- else if(message_name == "cleanup")
- {
- // TODO: clean up here
- }
- else if(message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name
-// << ", size: " << info.mSize
-// << ", address: " << info.mAddress
-// << std::endl;
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
- }
- else if(message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
-// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl;
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- if(mPixels == iter->second.mAddress)
- {
- // This is the currently active pixel buffer. Make sure we stop drawing to it.
- mPixels = NULL;
- mTextureSegmentName.clear();
-
- // Make sure the movie GWorld is no longer pointed at the shared segment.
- sizeChanged();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
-// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl;
- }
-
- // Send the response so it can be cleaned up.
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
-// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl;
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
- if(message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
-
- //std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
-
- if(!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
-// std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl;
-// std::cerr << "%%%% texture size is " << texture_width << " by " << texture_height << std::endl;
-
- mPixels = (unsigned char*)iter->second.mAddress;
- mTextureSegmentName = name;
- mWidth = width;
- mHeight = height;
-
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
-
- mMediaSizeChanging = false;
-
- sizeChanged();
-
- update();
- };
- };
- }
- else if(message_name == "load_uri")
- {
- std::string uri = message_in.getValue("uri");
- load( uri );
- sendStatus();
- }
- else if(message_name == "mouse_event")
- {
- std::string event = message_in.getValue("event");
- S32 x = message_in.getValueS32("x");
- S32 y = message_in.getValueS32("y");
-
- if(event == "down")
- {
- mouseDown(x, y);
- }
- else if(event == "up")
- {
- mouseUp(x, y);
- }
- else if(event == "move")
- {
- mouseMove(x, y);
- };
- };
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
- {
- if(message_name == "stop")
- {
- stop();
- }
- else if(message_name == "start")
- {
- F64 rate = 0.0;
- if(message_in.hasValue("rate"))
- {
- rate = message_in.getValueReal("rate");
- }
- play(rate);
- }
- else if(message_name == "pause")
- {
- pause();
- }
- else if(message_name == "seek")
- {
- F64 time = message_in.getValueReal("time");
- seek(time);
- }
- else if(message_name == "set_loop")
- {
- bool loop = message_in.getValueBoolean("loop");
- mIsLooping = loop;
- }
- else if(message_name == "set_volume")
- {
- F64 volume = message_in.getValueReal("volume");
- setVolume(volume);
- }
- }
- else
- {
-// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl;
- };
- };
-}
-
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data);
- *plugin_send_func = MediaPluginQuickTime::staticReceiveMessage;
- *plugin_user_data = (void*)self;
-
- return 0;
-}
-
-#else // LL_QUICKTIME_ENABLED
-
-// Stubbed-out class with constructor/destructor (necessary or windows linker
-// will just think its dead code and optimize it all out)
-class MediaPluginQuickTime : public MediaPluginBase
-{
-public:
- MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginQuickTime();
- /* virtual */ void receiveMessage(const char *message_string);
-};
-
-MediaPluginQuickTime::MediaPluginQuickTime(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data ) :
- MediaPluginBase(host_send_func, host_user_data)
-{
- // no-op
-}
-
-MediaPluginQuickTime::~MediaPluginQuickTime()
-{
- // no-op
-}
-
-void MediaPluginQuickTime::receiveMessage(const char *message_string)
-{
- // no-op
-}
-
-// We're building without quicktime enabled. Just refuse to initialize.
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- return -1;
-}
-
-#endif // LL_QUICKTIME_ENABLED
+ #endif + + MCIdle( mMovieController ); + + if ( ! mGWorldHandle ) + return; + + if ( mMediaSizeChanging ) + return; + + // update state machine + processState(); + + // see if title arrived and if so, update member variable with contents + checkTitle(); + + // QT call to see if we are at the end - can't do with controller + if ( IsMovieDone( mMovieHandle ) ) + { + // special code for looping - need to rewind at the end of the movie + if ( mIsLooping ) + { + // go back to start + rewind(); + + if ( mMovieController ) + { + // kick off new play + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); + + // set the volume + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + }; + } + else + { + if(mStatus == STATUS_PLAYING) + { + setStatus(STATUS_DONE); + } + } + } + + }; + + int getDataWidth() const + { + if ( mGWorldHandle ) + { + int depth = mDepth; + + if (depth < 1) + depth = 1; + + // ALWAYS use the row bytes from the PixMap if we have a GWorld because + // sometimes it's not the same as mMediaDepth * mMediaWidth ! + PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); + return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth; + } + else + { + // TODO : return LLMediaImplCommon::getaDataWidth(); + return 0; + } + }; + + void seek( F64 time ) + { + if ( mMovieController ) + { + TimeRecord when; + when.scale = GetMovieTimeScale( mMovieHandle ); + when.base = 0; + + // 'time' is in (floating point) seconds. The timebase time will be in 'units', where + // there are 'scale' units per second. + SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); + + when.value.hi = ( SInt32 )( raw_time >> 32 ); + when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); + + MCDoAction( mMovieController, mcActionGoToTime, &when ); + }; + }; + + F64 getLoadedDuration() + { + TimeValue duration; + if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr) + { + // If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie. + duration = GetMovieDuration( mMovieHandle ); + } + TimeValue scale = GetMovieTimeScale( mMovieHandle ); + + return (F64)duration / (F64)scale; + }; + + F64 getDuration() + { + TimeValue duration = GetMovieDuration( mMovieHandle ); + TimeValue scale = GetMovieTimeScale( mMovieHandle ); + + return (F64)duration / (F64)scale; + }; + + F64 getCurrentTime() + { + TimeValue curr_time = GetMovieTime( mMovieHandle, 0 ); + TimeValue scale = GetMovieTimeScale( mMovieHandle ); + + return (F64)curr_time / (F64)scale; + }; + + void setVolume( F64 volume ) + { + mCurVolume = (short)(volume * ( double ) 0x100 ); + + if ( mMovieController ) + { + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void update(int milliseconds = 0) + { + updateQuickTime(milliseconds); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseDown( int x, int y ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseUp( int x, int y ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x, int y ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyPress( unsigned char key ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // Grab movie title into mMovieTitle - should be called repeatedly + // until it returns true since movie title takes a while to become + // available. + const bool getMovieTitle() + { + // grab meta data from movie + QTMetaDataRef media_data_ref; + OSErr result = QTCopyMovieMetaData( mMovieHandle, &media_data_ref ); + if ( noErr != result ) + return false; + + // look up "Display Name" in meta data + OSType meta_data_key = kQTMetaDataCommonKeyDisplayName; + QTMetaDataItem item = kQTMetaDataItemUninitialized; + result = QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard, + 0, kQTMetaDataKeyFormatCommon, + (const UInt8 *)&meta_data_key, + sizeof( meta_data_key ), &item ); + if ( noErr != result ) + return false; + + // find the size of the title + ByteCount size; + result = QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size ); + if ( noErr != result || size <= 0 /*|| size > 1024 FIXME: arbitrary limit */ ) + return false; + + // allocate some space and grab it + UInt8* item_data = new UInt8( size + 1 ); + memset( item_data, 0, ( size + 1 ) * sizeof( UInt8* ) ); + result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); + if ( noErr != result ) + { + delete [] item_data; + return false; + }; + + // save it + if ( strlen( (char*)item_data ) ) + mMovieTitle = std::string( (char* )item_data ); + else + mMovieTitle = ""; + + // clean up + delete [] item_data; + + return true; + }; + + // called regularly to see if title changed + void checkTitle() + { + // we did already receive title so keep checking + if ( ! mReceivedTitle ) + { + // grab title from movie meta data + if ( getMovieTitle() ) + { + // pass back to host application + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", mMovieTitle ); + sendMessage( message ); + + // stop looking once we find a title for this movie. + // TODO: this may to be reset if movie title changes + // during playback but this is okay for now + mReceivedTitle = true; + }; + }; + }; +}; + +MediaPluginQuickTime::MediaPluginQuickTime( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data), + mMinWidth( 0 ), + mMaxWidth( 2048 ), + mMinHeight( 0 ), + mMaxHeight( 2048 ) +{ +// std::cerr << "MediaPluginQuickTime constructor" << std::endl; + + mNaturalWidth = -1; + mNaturalHeight = -1; + mMovieHandle = 0; + mGWorldHandle = 0; + mMovieController = 0; + mCurVolume = 0x99; + mMediaSizeChanging = false; + mIsLooping = false; + mMovieTitle = std::string(); + mReceivedTitle = false; + mCommand = COMMAND_NONE; + mPlayRate = 0.0f; + mStatus = STATUS_NONE; +} + +MediaPluginQuickTime::~MediaPluginQuickTime() +{ +// std::cerr << "MediaPluginQuickTime destructor" << std::endl; + + ExitMovies(); + +#ifdef LL_WINDOWS + TerminateQTML(); +// std::cerr << "QuickTime closing down" << std::endl; +#endif +} + + +void MediaPluginQuickTime::receiveMessage(const char *message_string) +{ +// std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + // Normally a plugin would only specify one of these two subclasses, but this is a demo... + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + #ifdef LL_WINDOWS + + // QuickTime 7.6.4 has an issue (that was not present in 7.6.2) with initializing QuickTime + // according to this article: http://lists.apple.com/archives/QuickTime-API/2009/Sep/msg00097.html + // The solution presented there appears to work. + QTLoadLibrary("qtcf.dll"); + + // main initialization for QuickTime - only required on Windows + OSErr result = InitializeQTML( 0L ); + if ( result != noErr ) + { + //TODO: If no QT on Windows, this fails - respond accordingly. + } + else + { + //std::cerr << "QuickTime initialized" << std::endl; + }; + #endif + + // required for both Windows and Mac + EnterMovies(); + + std::string plugin_version = "QuickTime media plugin, QuickTime version "; + + long version = 0; + Gestalt( gestaltQuickTimeVersion, &version ); + std::ostringstream codec( "" ); + codec << std::hex << version << std::dec; + plugin_version += codec.str(); + message.setValue("plugin_version", plugin_version); + sendMessage(message); + + // Plugin gets to decide the texture parameters to use. + message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + #if defined(LL_WINDOWS) + // Values for Windows + mDepth = 3; + message.setValueU32("format", GL_RGB); + message.setValueU32("type", GL_UNSIGNED_BYTE); + + // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even. + // Padding to a multiple of 3*32 guarantees it'll divide out properly. + message.setValueU32("padding", 32 * 3); + #else + // Values for Mac + mDepth = 4; + message.setValueU32("format", GL_BGRA_EXT); + #ifdef __BIG_ENDIAN__ + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); + #else + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8); + #endif + + // Pad texture width to a multiple of 32 bytes, to line up with cache lines. + message.setValueU32("padding", 32); + #endif + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + F64 time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + // TODO: clean up here + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); +// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name +// << ", size: " << info.mSize +// << ", address: " << info.mAddress +// << std::endl; + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + +// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl; + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + + // Make sure the movie GWorld is no longer pointed at the shared segment. + sizeChanged(); + } + mSharedSegments.erase(iter); + } + else + { +// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { +// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + //std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { +// std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl; +// std::cerr << "%%%% texture size is " << texture_width << " by " << texture_height << std::endl; + + mPixels = (unsigned char*)iter->second.mAddress; + mTextureSegmentName = name; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + mMediaSizeChanging = false; + + sizeChanged(); + + update(); + }; + }; + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + load( uri ); + sendStatus(); + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + }; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "stop") + { + stop(); + } + else if(message_name == "start") + { + F64 rate = 0.0; + if(message_in.hasValue("rate")) + { + rate = message_in.getValueReal("rate"); + } + play(rate); + } + else if(message_name == "pause") + { + pause(); + } + else if(message_name == "seek") + { + F64 time = message_in.getValueReal("time"); + seek(time); + } + else if(message_name == "set_loop") + { + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; + } + else if(message_name == "set_volume") + { + F64 volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + else + { +// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl; + }; + }; +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data); + *plugin_send_func = MediaPluginQuickTime::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + +#else // LL_QUICKTIME_ENABLED + +// Stubbed-out class with constructor/destructor (necessary or windows linker +// will just think its dead code and optimize it all out) +class MediaPluginQuickTime : public MediaPluginBase +{ +public: + MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginQuickTime(); + /* virtual */ void receiveMessage(const char *message_string); +}; + +MediaPluginQuickTime::MediaPluginQuickTime( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data) +{ + // no-op +} + +MediaPluginQuickTime::~MediaPluginQuickTime() +{ + // no-op +} + +void MediaPluginQuickTime::receiveMessage(const char *message_string) +{ + // no-op +} + +// We're building without quicktime enabled. Just refuse to initialize. +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return -1; +} + +#endif // LL_QUICKTIME_ENABLED diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 1e79720f43..09348782a4 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -296,7 +296,7 @@ private: // virtual void onNavigateBegin(const EventType& event) { - if(mInitState > INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); message.setValue("uri", event.getEventUri()); @@ -304,7 +304,8 @@ private: setStatus(STATUS_LOADING); } - else if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) + + if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) { mInitState = INIT_STATE_WAIT_REDRAW; } @@ -315,7 +316,7 @@ private: // virtual void onNavigateComplete(const EventType& event) { - if(mInitState > INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); message.setValue("uri", event.getEventUri()); @@ -338,7 +339,7 @@ private: // virtual void onUpdateProgress(const EventType& event) { - if(mInitState > INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress"); message.setValueS32("percent", event.getIntValue()); @@ -350,7 +351,7 @@ private: // virtual void onStatusTextChange(const EventType& event) { - if(mInitState > INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); message.setValue("status", event.getStringValue()); @@ -362,7 +363,7 @@ private: // virtual void onTitleChange(const EventType& event) { - if(mInitState > INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); message.setValue("name", event.getStringValue()); @@ -374,7 +375,7 @@ private: // virtual void onLocationChange(const EventType& event) { - if(mInitState > INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); message.setValue("uri", event.getEventUri()); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8ad52784d3..94a2ca16f4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1132,7 +1132,7 @@ <key>Type</key> <string>U32</string> <key>Value</key> - <integer>500</integer> + <integer>512</integer> </map> <key>CacheValidateCounter</key> <map> @@ -4545,6 +4545,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>MediaPerformanceManagerDebug</key> + <map> + <key>Comment</key> + <string>Whether to show debug data for the media performance manager in the nearby media list.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>MemoryLogFrequency</key> <map> <key>Comment</key> @@ -5369,7 +5380,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.0</real> + <real>1.0</real> </map> <key>PluginInstancesLow</key> <map> @@ -5385,24 +5396,24 @@ <key>PluginInstancesNormal</key> <map> <key>Comment</key> - <string>Limit on the number of inworld media plugins that will run at "normal" priority</string> + <string>Limit on the number of inworld media plugins that will run at "normal" or higher priority</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>U32</string> <key>Value</key> - <integer>4</integer> + <integer>2</integer> </map> <key>PluginInstancesTotal</key> <map> <key>Comment</key> - <string>Hard limit on the number of plugins that will be instantiated at once</string> + <string>Hard limit on the number of plugins that will be instantiated at once for inworld media</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>U32</string> <key>Value</key> - <integer>16</integer> + <integer>8</integer> </map> <key>PrecachingDelay</key> <map> @@ -6304,7 +6315,7 @@ <real>1.0</real> </map> - <key>RenderHighlightEnable</key> + <key>RenderHoverGlowEnable</key> <map> <key>Comment</key> <string>Show glow effect when hovering on interactive objects.</string> @@ -6313,7 +6324,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>RenderHighlightFadeTime</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index a093c1d434..7a540a45c4 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -42,6 +42,7 @@ #include "llanimationstates.h" #include "llbottomtray.h" #include "llcallingcard.h" +#include "llchannelmanager.h" #include "llconsole.h" #include "llfirstuse.h" #include "llfloatercamera.h" @@ -2136,6 +2137,7 @@ void LLAgent::setBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy")); } + LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true); } //----------------------------------------------------------------------------- @@ -2149,6 +2151,7 @@ void LLAgent::clearBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy")); } + LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false); } //----------------------------------------------------------------------------- diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index a171f75b17..6b2033fc6f 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -86,6 +86,26 @@ protected: void processContents(); }; +class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver +{ +public: + enum ELibraryOutfitFetchStep { + LOFS_FOLDER = 0, + LOFS_OUTFITS, + LOFS_CONTENTS + }; + LLLibraryOutfitsFetch() : mCurrFetchStep(LOFS_FOLDER), mOutfitsPopulated(false) {} + ~LLLibraryOutfitsFetch() {} + virtual void done(); +protected: + void folderDone(void); + void outfitsDone(void); + void contentsDone(void); + enum ELibraryOutfitFetchStep mCurrFetchStep; + std::vector< std::pair< LLUUID, std::string > > mOutfits; + bool mOutfitsPopulated; +}; + LLAgentWearables gAgentWearables; BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; @@ -905,6 +925,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // will call done for us when everything is here. gInventory.addObserver(outfit); } + + gAgentWearables.populateMyOutfitsFolder(); } } @@ -2004,6 +2026,130 @@ void LLAgentWearables::updateServer() gAgent.sendAgentSetAppearance(); } +void LLAgentWearables::populateMyOutfitsFolder(void) +{ + LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(); + + // What we do here is get the complete information on the items in + // the inventory, and set up an observer that will wait for that to + // happen. + LLInventoryFetchDescendentsObserver::folder_ref_t folders; + const LLUUID my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + + folders.push_back(my_outfits_id); + outfits->fetchDescendents(folders); + if(outfits->isEverythingComplete()) + { + // everything is already here - call done. + outfits->done(); + } + else + { + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(outfits); + } +} + +void LLLibraryOutfitsFetch::done() +{ + switch (mCurrFetchStep){ + case LOFS_FOLDER: + mCurrFetchStep = LOFS_OUTFITS; + folderDone(); + break; + case LOFS_OUTFITS: + mCurrFetchStep = LOFS_CONTENTS; + outfitsDone(); + break; + case LOFS_CONTENTS: + // No longer need this observer hanging around. + gInventory.removeObserver(this); + contentsDone(); + break; + default: + gInventory.removeObserver(this); + delete this; + return; + } + if (mOutfitsPopulated) + { + delete this; + } +} + +void LLLibraryOutfitsFetch::folderDone(void) +{ + // Early out if we already have items in My Outfits. + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t wearable_array; + gInventory.collectDescendents(mCompleteFolders.front(), cat_array, wearable_array, + LLInventoryModel::EXCLUDE_TRASH); + if (cat_array.count() > 0 || wearable_array.count() > 0) + { + mOutfitsPopulated = true; + gInventory.removeObserver(this); + return; + } + + // Get the UUID of the library's clothing folder + const LLUUID library_clothing_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true); + + mCompleteFolders.clear(); + + // What we do here is get the complete information on the items in + // the inventory, and set up an observer that will wait for that to + // happen. + LLInventoryFetchDescendentsObserver::folder_ref_t folders; + folders.push_back(library_clothing_id); + fetchDescendents(folders); + if(isEverythingComplete()) + { + // everything is already here - call done. + outfitsDone(); + } +} + +void LLLibraryOutfitsFetch::outfitsDone(void) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t wearable_array; + gInventory.collectDescendents(mCompleteFolders.front(), cat_array, wearable_array, + LLInventoryModel::EXCLUDE_TRASH); + + LLInventoryFetchDescendentsObserver::folder_ref_t folders; + for(S32 i = 0; i < cat_array.count(); ++i) + { + if (cat_array.get(i)->getName() != "More Outfits" && cat_array.get(i)->getName() != "Ruth"){ + folders.push_back(cat_array.get(i)->getUUID()); + mOutfits.push_back( std::make_pair(cat_array.get(i)->getUUID(), cat_array.get(i)->getName() )); + } + } + mCompleteFolders.clear(); + fetchDescendents(folders); + if(isEverythingComplete()) + { + // everything is already here - call done. + contentsDone(); + } +} + +void LLLibraryOutfitsFetch::contentsDone(void) +{ + for(S32 i = 0; i < (S32)mOutfits.size(); ++i) + { + // First, make a folder in the My Outfits directory. + const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + LLUUID folder_id = gInventory.createNewCategory(parent_id, + LLFolderType::FT_OUTFIT, + mOutfits[i].second); + + LLAppearanceManager::getInstance()->shallowCopyCategory(mOutfits[i].first, folder_id, NULL); + gInventory.notifyObservers(); + } + mOutfitsPopulated = true; +} + //-------------------------------------------------------------------- // InitialWearablesFetch // diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 9017c25fc6..8f3a16501e 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -169,9 +169,11 @@ public: const LLDynamicArray<S32>& attachments_to_include, BOOL rename_clothing); - // Note: wearables_to_include should be a list of EWearableType types - // attachments_to_include should be a list of attachment points LLUUID makeNewOutfitLinks(const std::string& new_folder_name); + + // Should only be called if we *know* we've never done so before, since users may + // not want the Library outfits to stay in their quick outfit selector and can delete them. + void populateMyOutfitsFolder(void); private: void makeNewOutfitDone(S32 type, U32 index); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 845a264327..f82d178089 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -89,6 +89,8 @@ #include "llvfsthread.h" #include "llvolumemgr.h" +#include "llnotificationmanager.h" + // Third party library includes #include <boost/bind.hpp> @@ -2340,6 +2342,8 @@ bool LLAppViewer::initWindow() gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"), gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"), FALSE, ignorePixelDepth); + + LLNotificationsUI::LLNotificationManager::getInstance(); if (gSavedSettings.getBOOL("WindowFullScreen")) { diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index fd711b72b0..958dbf226a 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -317,11 +317,6 @@ BOOL LLBottomTray::postBuild() // Registering Chat Bar to receive Voice client status change notifications. gVoiceClient->addObserver(this); - if (mChicletPanel && mToolbarStack && mNearbyChatBar) - { - verifyChildControlsSizes(); - } - return TRUE; } @@ -340,35 +335,6 @@ void LLBottomTray::log(LLView* panel, const std::string& descr) ; } -void LLBottomTray::verifyChildControlsSizes() -{ - LLRect rect = mChicletPanel->getRect(); - /* - if (rect.getWidth() < mChicletPanel->getMinWidth()) - { - llwarns << "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ: chiclet panel less then min" << llendl; - mChicletPanel->reshape(mChicletPanel->getMinWidth(), rect.getHeight()); - } -*/ - rect = mNearbyChatBar->getRect(); -/* - if (rect.getWidth() < mNearbyChatBar->getMinWidth()) - { - llwarns << "WWWWWWWWWWWWWWWWWWWWWWWWWWWWW: near chat panel less then min" << llendl; - mNearbyChatBar->reshape(mNearbyChatBar->getMinWidth(), rect.getHeight()); - } - else -*/ - if (rect.getWidth() > mNearbyChatBar->getMaxWidth()) - { - llerrs << "WWWWWWWWWWWWWWWWWWWWWWWWWWWWW: near chat panel more then max width" << llendl; - - rect.setLeftTopAndSize(rect.mLeft, rect.mTop, mNearbyChatBar->getMaxWidth(), rect.getHeight()); - mNearbyChatBar->reshape(mNearbyChatBar->getMaxWidth(), rect.getHeight()); - mNearbyChatBar->setRect(rect); - } -} - void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent) { static S32 debug_calling_number = 0; @@ -393,7 +359,6 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent) if (mChicletPanel && mToolbarStack && mNearbyChatBar) { mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE); - verifyChildControlsSizes(); // bottom tray is narrowed if (delta_width < 0) diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 974289d5e0..8989816bfe 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -101,8 +101,6 @@ private: , RS_RESIZABLE_BUTTONS = /*RS_BUTTON_SNAPSHOT | */RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES }EResizeState; - void updateResizeState(S32 new_width, S32 cur_width); - void verifyChildControlsSizes(); S32 processWidthDecreased(S32 delta_width); void processWidthIncreased(S32 delta_width); void log(LLView* panel, const std::string& descr); diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 914435b640..3443d8b593 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -220,5 +220,12 @@ void LLChannelManager::removeChannelByID(const LLUUID id) } //-------------------------------------------------------------------------- - +void LLChannelManager::muteAllChannels(bool mute) +{ + for (std::vector<ChannelElem>::iterator it = mChannelList.begin(); + it != mChannelList.end(); it++) + { + it->channel->setShowToasts(!mute); + } +} diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index b927d369cd..4b66a1ef89 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -102,6 +102,13 @@ public: // remove channel methods void removeChannelByID(const LLUUID id); + /** + * Manages toasts showing for all channels. + * + * @param mute Flag to disable/enable toasts showing. + */ + void muteAllChannels(bool mute); + private: LLScreenChannel* createChannel(LLChannelManager::Params& p); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 028bb7a384..f9c4a23f12 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -345,7 +345,7 @@ LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style return header; } -void LLChatHistory::appendWidgetMessage(const LLChat& chat) +void LLChatHistory::appendWidgetMessage(const LLChat& chat, const LLStyle::Params& input_append_params) { LLView* view = NULL; std::string view_text = "\n[" + formatCurrentTime() + "] "; @@ -361,12 +361,16 @@ void LLChatHistory::appendWidgetMessage(const LLChat& chat) LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); LLViewerChat::getChatColor(chat,txt_color); - LLFontGL* fontp = LLViewerChat::getChatFont(); - + LLFontGL* fontp = LLViewerChat::getChatFont(); + std::string font_name = LLFontGL::nameFromFont(fontp); + std::string font_size = LLFontGL::sizeFromFont(fontp); LLStyle::Params style_params; style_params.color(txt_color); style_params.readonly_color(txt_color); - style_params.font(fontp); + style_params.font.name(font_name); + style_params.font.size(font_size); + style_params.font.style(input_append_params.font.style); + if (mLastFromName == chat.mFromName) diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index f689a225fe..c89d4b4ec6 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -109,7 +109,7 @@ class LLChatHistory : public LLTextEditor * @param time time of a message. * @param message message itself. */ - void appendWidgetMessage(const LLChat& chat); + void appendWidgetMessage(const LLChat& chat, const LLStyle::Params& input_append_params = LLStyle::Params()); private: std::string mLastFromName; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index d2e3247250..b1dee46d2e 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -160,10 +160,14 @@ void LLNearbyChatToastPanel::init(LLSD& notification) LLStyle::Params style_params; style_params.color(mTextColor); - style_params.font(mFont); - - std::string str_sender; +// style_params.font(mFont); + std::string font_name = LLFontGL::nameFromFont(mFont); + std::string font_style_size = LLFontGL::sizeFromFont(mFont); + style_params.font.name(font_name); + style_params.font.size(font_style_size); + std::string str_sender; + if(gAgentID != mFromID) str_sender = mFromName; else @@ -173,10 +177,28 @@ void LLNearbyChatToastPanel::init(LLSD& notification) caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime() , style_params ); - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); - msg_text->setText(mText, style_params); + + if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC) + { + if (mFromName.size() > 0) + { + style_params.font.style = "ITALIC"; + + msg_text->setText(mFromName, style_params); + } + mText = mText.substr(3); + style_params.font.style = "UNDERLINE"; + msg_text->addText(mText,style_params); + } + else + { + msg_text->setText(mText, style_params); + } + + + LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); if(mSourceType != CHAT_SOURCE_AGENT) msg_inspector->setVisible(false); @@ -196,6 +218,8 @@ void LLNearbyChatToastPanel::setMessage (const LLChat& chat_msg) notification["from_id"] = chat_msg.mFromID; notification["time"] = chat_msg.mTime; notification["source"] = (S32)chat_msg.mSourceType; + notification["chat_type"] = (S32)chat_msg.mChatType; + notification["chat_style"] = (S32)chat_msg.mChatStyle; std::string r_color_name="White"; F32 r_color_alpha = 1.0f; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 9e290c8c04..4078fac4ec 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -797,13 +797,11 @@ LLChicletPanel::Params::Params() chiclet_padding = 3; scrolling_offset = 40; -/* if (!min_width.isProvided()) { // min_width = 4 chiclets + 3 paddings min_width = 180 + 3*chiclet_padding; } -*/ }; LLChicletPanel::LLChicletPanel(const Params&p) diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 20dc4440c2..169a963d0d 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -79,7 +79,7 @@ void LLDebugView::init() r.set(150 - 25, rect.getHeight() - 50, rect.getWidth()/2 - 25, rect.getHeight() - 450); - r.set(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), + r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); mFastTimerView = new LLFastTimerView(r); mFastTimerView->setFollowsTop(); @@ -87,7 +87,7 @@ void LLDebugView::init() mFastTimerView->setVisible(FALSE); // start invisible addChild(mFastTimerView); - r.set(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), + r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); LLMemoryView::Params mp; mp.name("memory"); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 6d7da107ac..bd6936f05c 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -164,7 +164,7 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText() S32 last_line = visible_lines.second - 1; LLStyle::Params expander_style = getDefaultStyle(); - expander_style.font.name.setIfNotProvided(LLFontGL::nameFromFont(expander_style.font)); + expander_style.font.name(LLFontGL::nameFromFont(expander_style.font)); expander_style.font.style = "UNDERLINE"; expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 18135fc558..ae5be8cc7c 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -74,6 +74,7 @@ public: mName("(Loading...)"), mPosX(0), mPosY(0), + mPosZ(0), mLoaded(false) {} @@ -101,6 +102,14 @@ public: requestNameAndPos(); return mPosY; } + + S32 getPosZ() + { + if (!mLoaded) + requestNameAndPos(); + return mPosZ; + } + private: /** * Requests landmark data from server. @@ -114,14 +123,15 @@ private: if(LLLandmarkActions::getLandmarkGlobalPos(mLandmarkID, g_pos)) { LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(g_pos, - boost::bind(&LLLandmarkInfoGetter::landmarkNameCallback, this, _1, _2, _3)); + boost::bind(&LLLandmarkInfoGetter::landmarkNameCallback, this, _1, _2, _3, _4)); } } - void landmarkNameCallback(const std::string& name, S32 x, S32 y) + void landmarkNameCallback(const std::string& name, S32 x, S32 y, S32 z) { mPosX = x; mPosY = y; + mPosZ = z; mName = name; mLoaded = true; } @@ -130,6 +140,7 @@ private: std::string mName; S32 mPosX; S32 mPosY; + S32 mPosZ; bool mLoaded; }; @@ -151,7 +162,8 @@ public: if (!region_name.empty()) { LLToolTip::Params params; - params.message = llformat("%s\n%s (%d, %d)", getLabelSelected().c_str(), region_name.c_str(), mLandmarkInfoGetter.getPosX(), mLandmarkInfoGetter.getPosY()); + params.message = llformat("%s\n%s (%d, %d, %d)", getLabelSelected().c_str(), region_name.c_str(), + mLandmarkInfoGetter.getPosX(), mLandmarkInfoGetter.getPosY(), mLandmarkInfoGetter.getPosZ()); params.sticky_rect = calcScreenRect(); LLToolTipMgr::instance().show(params); } @@ -901,7 +913,10 @@ void LLFavoritesBarCtrl::showDropDownMenu() menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - menu->setButtonRect(mChevronRect, this); + if (menu->getButtonRect().isEmpty()) + { + menu->setButtonRect(mChevronRect, this); + } LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0); return; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 21458f83cd..4192c6a586 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -909,11 +909,7 @@ void LLFolderView::finishRenamingItem( void ) mRenameItem->rename( mRenamer->getText() ); } - mRenamer->setCommitOnFocusLost( FALSE ); - mRenamer->setFocus( FALSE ); - mRenamer->setVisible( FALSE ); - mRenamer->setCommitOnFocusLost( TRUE ); - gFocusMgr.setTopCtrl( NULL ); + gFocusMgr.setTopCtrl( NULL ); if( mRenameItem ) { diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 23d9436fa6..ac060cef15 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -44,27 +44,24 @@ // Constants; -static const std::string INVENTORY_STRING_FRIENDS_SUBFOLDER = "Friends"; -static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All"; +static const std::string INVENTORY_STRING_FRIENDS_SUBFOLDER = "InvFolder Friends"; +static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "InvFolder All"; // helper functions -/* -mantipov *NOTE: unable to use -LLTrans::getString("InvFolder Friends"); or -LLTrans::getString("InvFolder FriendsAll"); -in next two functions to set localized folders' names because of there is a hack in the -LLFolderViewItem::refreshFromListener() method for protected asset types. -So, localized names will be got from the strings with "InvFolder LABEL_NAME" in the strings.xml -*/ -inline const std::string& get_friend_folder_name() +// NOTE: Usage of LLTrans::getString(); in next two functions to set localized +// folders' names is caused by a hack in the LLFolderViewItem::refreshFromListener() +// method for protected asset types. +// So, localized names will be got from the strings with "InvFolder LABEL_NAME" +// in the strings.xml +inline const std::string get_friend_folder_name() { - return INVENTORY_STRING_FRIENDS_SUBFOLDER; + return LLTrans::getString(INVENTORY_STRING_FRIENDS_SUBFOLDER); } -inline const std::string& get_friend_all_subfolder_name() +inline const std::string get_friend_all_subfolder_name() { - return INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER; + return LLTrans::getString(INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER); } void move_from_to_arrays(LLInventoryModel::cat_array_t& from, LLInventoryModel::cat_array_t& to) @@ -81,15 +78,20 @@ const LLUUID& get_folder_uuid(const LLUUID& parentFolderUUID, LLInventoryCollect LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - gInventory.collectDescendentsIf(parentFolderUUID, cats, items, + gInventory.collectDescendentsIf(parentFolderUUID, cats, items, LLInventoryModel::EXCLUDE_TRASH, matchFunctor); - if (cats.count() == 1) + S32 cats_count = cats.count(); + + if (cats_count > 1) { - return cats.get(0)->getUUID(); + LL_WARNS("LLFriendCardsManager") + << "There is more than one Friend card folder." + << "The first folder will be used." + << LL_ENDL; } - return LLUUID::null; + return (cats_count >= 1) ? cats.get(0)->getUUID() : LLUUID::null; } /** @@ -348,13 +350,8 @@ const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName); } -const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& folderLabel) const +const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& localizedName) const { - // mantipov *HACK: get localaized name in the same way like in the LLFolderViewItem::refreshFromListener() method. - // be sure these both methods are synchronized. - // see also get_friend_folder_name() and get_friend_all_subfolder_name() functions - std::string localizedName = LLTrans::getString("InvFolder " + folderLabel); - LLNameCategoryCollector matchFolderFunctor(localizedName); return get_folder_uuid(parentFolderUUID, matchFolderFunctor); diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index 98dc3153d0..b94d5ec2c0 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -120,7 +120,7 @@ private: return (mBuddyIDSet.end() != mBuddyIDSet.find(avatarID)); } - const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& folderLabel) const; + const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& localizedName) const; const LLUUID& findFriendFolderUUIDImpl() const; const LLUUID& findFriendAllSubfolderUUIDImpl() const; const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID); diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index e3121fbc7a..2c6543d6ca 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -476,8 +476,39 @@ void LLIMFloater::updateMessages() chat.mFromID = from_id; chat.mFromName = from; chat.mText = message; - - mChatHistory->appendWidgetMessage(chat); + + //Handle IRC styled /me messages. + std::string prefix = message.substr(0, 4); + if (prefix == "/me " || prefix == "/me'") + { + + LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); + LLViewerChat::getChatColor(chat,txt_color); + LLFontGL* fontp = LLViewerChat::getChatFont(); + std::string font_name = LLFontGL::nameFromFont(fontp); + std::string font_size = LLFontGL::sizeFromFont(fontp); + LLStyle::Params append_style_params; + append_style_params.color(txt_color); + append_style_params.readonly_color(txt_color); + append_style_params.font.name(font_name); + append_style_params.font.size(font_size); + + if (from.size() > 0) + { + append_style_params.font.style = "ITALIC"; + chat.mText = from + " "; + mChatHistory->appendWidgetMessage(chat, append_style_params); + } + + message = message.substr(3); + append_style_params.font.style = "UNDERLINE"; + mChatHistory->appendText(message, FALSE, append_style_params); + } + else + { + chat.mText = message; + mChatHistory->appendWidgetMessage(chat); + } mLastMessageIndex = msg["index"].asInteger(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 8b7a84a3d3..2d8b058ed8 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3947,7 +3947,6 @@ std::string LLObjectBridge::getLabelSuffix() const if( avatar && avatar->isWearingAttachment( mUUID ) )
{
std::string attachment_point_name = avatar->getAttachedPointName(mUUID);
- LLStringUtil::toLower(attachment_point_name);
LLStringUtil::format_map_t args;
args["[ATTACHMENT_POINT]"] = attachment_point_name.c_str();
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index a8e5c4c216..38a417f1a2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -307,10 +307,10 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id) // specifies 'type' as what it defaults to containing. The category is // not necessarily only for that type. *NOTE: This will create a new // inventory category on the fly if one does not exist. -const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bool create_folder) +const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bool create_folder, bool find_in_library) { - const LLUUID &rv = findCatUUID(t); - if(rv.isNull() && isInventoryUsable() && create_folder) + const LLUUID &rv = findCatUUID(t, find_in_library); + if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library)) { const LLUUID &root_id = gInventory.getRootFolderID(); if(root_id.notNull()) @@ -323,9 +323,9 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bo // Internal method which looks for a category with the specified // preferred type. Returns LLUUID::null if not found. -const LLUUID &LLInventoryModel::findCatUUID(LLFolderType::EType preferred_type) const +const LLUUID &LLInventoryModel::findCatUUID(LLFolderType::EType preferred_type, bool find_in_library) const { - const LLUUID &root_id = gInventory.getRootFolderID(); + const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID(); if(LLFolderType::FT_ROOT_INVENTORY == preferred_type) { return root_id; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 3c1f606d5c..aa4ffb392f 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -247,13 +247,12 @@ public: // findCategoryUUIDForType() returns the uuid of the category that // specifies 'type' as what it defaults to containing. The - // category is not necessarily only for that type. *NOTE: This - // will create a new inventory category on the fly if one does not - // exist. - + // category is not necessarily only for that type. *NOTE: If create_folder is true, this + // will create a new inventory category on the fly if one does not exist. *NOTE: if find_in_library is + // true it will search in the user's library folder instead of "My Inventory" // SDK: Added flag to specify whether the folder should be created if not found. This fixes the horrible // multiple trash can bug. - const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder = true); + const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder = true, bool find_in_library = false); // Call this method when it's time to update everyone on a new // state, by default, the inventory model will not update @@ -404,7 +403,7 @@ protected: // // Internal method which looks for a category with the specified // preferred type. Returns LLUUID::null if not found - const LLUUID &findCatUUID(LLFolderType::EType preferred_type) const; + const LLUUID &findCatUUID(LLFolderType::EType preferred_type, bool find_in_library = false) const; // Empty the entire contents void empty(); diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index d7eaad94f0..0acc67ff5a 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -134,15 +134,17 @@ void LLJoystick::updateSlop() return; } -BOOL LLJoystick::pointInCircle(S32 x, S32 y) const +bool LLJoystick::pointInCircle(S32 x, S32 y) const { - //cnt is x and y coordinates of center of joystick circle, and also its radius, - //because area is not just rectangular, it's a square! - //Make sure to change method if this changes. - int cnt = this->getLocalRect().mTop/2; - if((x-cnt)*(x-cnt)+(y-cnt)*(y-cnt)<=cnt*cnt) + if(this->getLocalRect().mTop!=this->getLocalRect().mRight) + { + llwarns << "Joystick shape is not square"<<llendl; return TRUE; - return FALSE; + } + //center is x and y coordinates of center of joystick circle, and also its radius + int center = this->getLocalRect().mTop/2; + bool in_circle = (x - center) * (x - center) + (y - center) * (y - center) <= center * center; + return in_circle; } BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask) @@ -150,7 +152,7 @@ BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask) //llinfos << "joystick mouse down " << x << ", " << y << llendl; bool handles = false; - if(handles = pointInCircle(x, y)) + if(pointInCircle(x, y)) { mLastMouse.set(x, y); mFirstMouse.set(x, y); diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 0465f78031..2b071a8999 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -79,7 +79,13 @@ public: static void onBtnHeldDown(void *userdata); // called by llbutton callback handler void setInitialQuadrant(EJoystickQuadrant initial) { mInitialQuadrant = initial; }; - BOOL pointInCircle(S32 x, S32 y) const; + /** + * Checks if click location is inside joystick circle. + * + * Image containing circle is square and this square has adherent points with joystick + * circle. Make sure to change method according to shape other than square. + */ + bool pointInCircle(S32 x, S32 y) const; static std::string nameFromQuadrant(const EJoystickQuadrant quadrant); static EJoystickQuadrant quadrantFromName(const std::string& name); diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index e0dc1b6f0f..003afafa87 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -324,7 +324,7 @@ void LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(const LLVector3d& gl { LLVector3 pos = sim_infop->getLocalPos(global_pos); std::string name = sim_infop->getName() ; - cb(name, llround(pos.mV[VX]), llround(pos.mV[VY])); + cb(name, llround(pos.mV[VX]), llround(pos.mV[VY]),llround(pos.mV[VZ])); } else { @@ -368,7 +368,7 @@ void LLLandmarkActions::onRegionResponseNameAndCoords(region_name_and_coords_cal { LLVector3 local_pos = sim_infop->getLocalPos(global_pos); std::string name = sim_infop->getName() ; - cb(name, llround(local_pos.mV[VX]), llround(local_pos.mV[VY])); + cb(name, llround(local_pos.mV[VX]), llround(local_pos.mV[VY]), llround(local_pos.mV[VZ])); } } diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h index 1c524c820c..c65b831f3e 100644 --- a/indra/newview/lllandmarkactions.h +++ b/indra/newview/lllandmarkactions.h @@ -43,7 +43,7 @@ class LLLandmarkActions { public: typedef boost::function<void(std::string& slurl)> slurl_callback_t; - typedef boost::function<void(std::string& slurl, S32 x, S32 y)> region_name_and_coords_callback_t; + typedef boost::function<void(std::string& slurl, S32 x, S32 y, S32 z)> region_name_and_coords_callback_t; /** * @brief Fetches landmark LLViewerInventoryItems for the given landmark name. diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index fa1dbe0603..9ca207a579 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -429,9 +429,10 @@ void LLManip::renderXYZ(const LLVector3 &vec) const S32 PAD = 10; std::string feedback_string; LLVector3 camera_pos = LLViewerCamera::getInstance()->getOrigin() + LLViewerCamera::getInstance()->getAtAxis(); - S32 vertical_offset = gViewerWindow->getWindowHeightScaled() / 2 - VERTICAL_OFFSET; - S32 window_center_x = gViewerWindow->getWindowWidthScaled() / 2; - S32 window_center_y = gViewerWindow->getWindowHeightScaled() / 2; + S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2; + S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2; + S32 vertical_offset = window_center_y - VERTICAL_OFFSET; + glPushMatrix(); { diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 8f29f908e5..90c009887d 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -92,6 +92,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mStretchToFill( true ), mMaintainAspectRatio ( true ), mHideLoading (false), + mHidingInitialLoad (false), mDecoupleTextureSize ( false ), mTextureWidth ( 1024 ), mTextureHeight ( 1024 ) @@ -616,6 +617,11 @@ bool LLMediaCtrl::ensureMediaSourceExists() mMediaSource->setHomeURL(mHomePageUrl); mMediaSource->setVisible( getVisible() ); mMediaSource->addObserver( this ); + + if(mHideLoading) + { + mHidingInitialLoad = true; + } } else { @@ -685,7 +691,13 @@ void LLMediaCtrl::draw() { setFrequentUpdates( false ); }; - + + if(mHidingInitialLoad) + { + // If we're hiding loading, don't draw at all. + return; + } + // alpha off for this LLGLSUIDefault gls_ui; LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); @@ -865,19 +877,15 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) case MEDIA_EVENT_NAVIGATE_BEGIN: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL; - if(mMediaSource && mHideLoading) - { - mMediaSource->suspendUpdates(true); - } }; break; case MEDIA_EVENT_NAVIGATE_COMPLETE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; - if(mMediaSource && mHideLoading) + if(mHidingInitialLoad) { - mMediaSource->suspendUpdates(false); + mHidingInitialLoad = false; } }; break; diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 76ddc61ebf..f07513a3fd 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -188,6 +188,7 @@ public: bool mStretchToFill; bool mMaintainAspectRatio; bool mHideLoading; + bool mHidingInitialLoad; bool mDecoupleTextureSize; S32 mTextureWidth; S32 mTextureHeight; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 9439717fb8..7e6145f578 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -143,11 +143,14 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) BOOL handled = FALSE; S32 column_index = getColumnIndexFromOffset(x); LLScrollListItem* hit_item = hitItem(x, y); - if (hit_item) + if (hit_item + && column_index == mNameColumnIndex) { - if (column_index == mNameColumnIndex) + // ...this is the column with the avatar name + LLUUID avatar_id = hit_item->getValue().asUUID(); + if (avatar_id.notNull()) { - // ...this is the column with the avatar name + // ...valid avatar id LLScrollListCell* hit_cell = hit_item->getColumn(column_index); if (hit_cell) { @@ -160,7 +163,6 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) // Spawn at right side of cell LLCoordGL pos( sticky_rect.mRight - 16, sticky_rect.mTop ); LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small"); - LLUUID avatar_id = hit_item->getValue().asUUID(); LLToolTip::Params params; params.background_visible( false ); diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 85db69174d..cae5c52378 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -155,7 +155,37 @@ void LLNearbyChat::addMessage(const LLChat& chat) if (!chat.mMuted) { - mChatHistory->appendWidgetMessage(chat); + std::string message = chat.mText; + std::string prefix = message.substr(0, 4); + + if (chat.mChatStyle == CHAT_STYLE_IRC) + { + LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); + LLViewerChat::getChatColor(chat,txt_color); + LLFontGL* fontp = LLViewerChat::getChatFont(); + std::string font_name = LLFontGL::nameFromFont(fontp); + std::string font_size = LLFontGL::sizeFromFont(fontp); + LLStyle::Params append_style_params; + append_style_params.color(txt_color); + append_style_params.readonly_color(txt_color); + append_style_params.font.name(font_name); + append_style_params.font.size(font_size); + if (chat.mFromName.size() > 0) + { + append_style_params.font.style = "ITALIC"; + LLChat add_chat=chat; + add_chat.mText = chat.mFromName + " "; + mChatHistory->appendWidgetMessage(add_chat, append_style_params); + } + + message = message.substr(3); + append_style_params.font.style = "UNDERLINE"; + mChatHistory->appendText(message, FALSE, append_style_params); + } + else + { + mChatHistory->appendWidgetMessage(chat); + } } } @@ -203,5 +233,12 @@ void LLNearbyChat::getAllowedRect(LLRect& rect) { rect = gViewerWindow->getWorldViewRectRaw(); } - +void LLNearbyChat::setMinimized (BOOL minimize) +{ + if(minimize && !isDocked()) + { + setVisible(FALSE); + } + LLDockableFloater::setMinimized(minimize); +} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 3303c388af..1f4e57cf89 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -56,6 +56,7 @@ public: /*virtual*/ void onOpen (const LLSD& key); virtual void setRect (const LLRect &rect); + virtual void setMinimized (BOOL minimize); private: virtual void applySavedVariables(); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 333646d2c5..8fb4ea4211 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -252,19 +252,6 @@ bool LLNearbyChatBar::instanceExists() void LLNearbyChatBar::draw() { -// TODO: mantipov: remove -/* - LLRect rect = getRect(); - S32 max_width = getMaxWidth(); - - if (rect.getWidth() > max_width) - { - rect.setLeftTopAndSize(rect.mLeft, rect.mTop, max_width, rect.getHeight()); - reshape(rect.getWidth(), rect.getHeight(), FALSE); - setRect(rect); - } -*/ - displaySpeakingIndicator(); LLPanel::draw(); } diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 458845fff3..74a75d0369 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -341,6 +341,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg) notification["time"] = chat_msg.mTime; notification["source"] = (S32)chat_msg.mSourceType; notification["chat_type"] = (S32)chat_msg.mChatType; + notification["chat_style"] = (S32)chat_msg.mChatStyle; std::string r_color_name = "White"; F32 r_color_alpha = 1.0f; diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index fc6fb25644..26730e1f10 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -37,6 +37,7 @@ #include "llgroupactions.h" #include "llviewercontrol.h" #include "llviewerwindow.h" +#include "llnotificationmanager.h" using namespace LLNotificationsUI; @@ -47,6 +48,9 @@ LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id) // Getting a Channel for our notifications mChannel = LLChannelManager::getInstance()->createNotificationChannel(); + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); + if(channel) + channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1)); } //-------------------------------------------------------------------------- @@ -118,5 +122,15 @@ void LLGroupHandler::onDeleteToast(LLToast* toast) } //-------------------------------------------------------------------------- +void LLGroupHandler::onRejectToast(LLUUID& id) +{ + LLNotificationPtr notification = LLNotifications::instance().find(id); + + if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this) + { + LLNotifications::instance().cancel(notification); + } +} +//-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 23998a0e5d..42cc7cacc2 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -209,6 +209,9 @@ public: protected: virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); + + // own handlers + void onRejectToast(LLUUID& id); }; /** diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h index 8a9ba66ec0..c2f8dbd074 100644 --- a/indra/newview/llpanelappearancetab.h +++ b/indra/newview/llpanelappearancetab.h @@ -53,12 +53,8 @@ public: bool isTabVisible(); // Check if parent TabContainer is visible. - void setPanelAppearanceButtons(LLPanelAppearance* panel); - protected: - LLButton* mWearBtn; - LLButton* mEditBtn; LLPanelAppearance* mParent; }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 3b54f1546e..2254684f21 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -41,6 +41,7 @@ #include "llimview.h" #include "lltexteditor.h" #include "lltexturectrl.h" +#include "lltoggleablemenu.h" #include "lltooldraganddrop.h" #include "llscrollcontainer.h" #include "llavatariconctrl.h" @@ -333,8 +334,14 @@ BOOL LLPanelAvatarProfile::postBuild() childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL); + childSetCommitCallback("overflow_btn", boost::bind(&LLPanelAvatarProfile::onOverflowButtonClicked, this), NULL); childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL); + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("Profile.Pay", boost::bind(&LLPanelAvatarProfile::pay, this)); + + mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic"); pic->setFallbackImageName("default_profile_picture.j2c"); @@ -513,6 +520,11 @@ void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data) childSetValue("acc_status_text", caption_text); } +void LLPanelAvatarProfile::pay() +{ + LLAvatarActions::pay(getAvatarId()); +} + void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url) { LLWeb::loadURL(url); @@ -552,6 +564,23 @@ void LLPanelAvatarProfile::onShareButtonClick() //*TODO not implemented } +void LLPanelAvatarProfile::onOverflowButtonClicked() +{ + if (!mProfileMenu->toggleVisibility()) + return; + + LLView* btn = getChild<LLView>("overflow_btn"); + + if (mProfileMenu->getButtonRect().isEmpty()) + { + mProfileMenu->setButtonRect(btn); + } + mProfileMenu->updateParent(LLMenuGL::sMenuContainer); + + LLRect rect = btn->getRect(); + LLMenuGL::showPopup(this, mProfileMenu, rect.mRight, rect.mTop); +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index ae0b8e9844..a0caf0c915 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -38,6 +38,7 @@ class LLComboBox; class LLLineEditor; +class LLToggleableMenu; enum EOnlineStatus { @@ -160,12 +161,17 @@ protected: * Fills Avatar's online status. */ virtual void fillOnlineStatus(const LLAvatarData* avatar_data); - + /** * Fills account status. */ virtual void fillAccountStatus(const LLAvatarData* avatar_data); + /** + * Opens "Pay Resident" dialog. + */ + void pay(); + void onUrlTextboxClicked(const std::string& url); void onHomepageTextboxClicked(); void onAddFriendButtonClick(); @@ -173,10 +179,12 @@ protected: void onCallButtonClick(); void onTeleportButtonClick(); void onShareButtonClick(); + void onOverflowButtonClicked(); private: - std::string mGroups; + std::string mGroups; + LLToggleableMenu* mProfileMenu; }; /** diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 1f5ffb7335..709525d4e2 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -448,6 +448,7 @@ LLPanelPeople::LLPanelPeople() mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this)); mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this)); mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this)); + mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); } LLPanelPeople::~LLPanelPeople() @@ -547,7 +548,6 @@ BOOL LLPanelPeople::postBuild() boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mOnlineFriendList)); buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this)); - buttonSetAction("add_friend_btn", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this)); buttonSetAction("chat_btn", boost::bind(&LLPanelPeople::onChatButtonClicked, this)); buttonSetAction("im_btn", boost::bind(&LLPanelPeople::onImButtonClicked, this)); @@ -707,7 +707,7 @@ void LLPanelPeople::updateButtons() bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME); bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME); bool group_tab_active = (cur_tab == GROUP_TAB_NAME); - bool recent_tab_active = (cur_tab == RECENT_TAB_NAME); + //bool recent_tab_active = (cur_tab == RECENT_TAB_NAME); LLUUID selected_id; std::vector<LLUUID> selected_uuids; @@ -717,7 +717,6 @@ void LLPanelPeople::updateButtons() buttonSetVisible("group_info_btn", group_tab_active); buttonSetVisible("chat_btn", group_tab_active); - buttonSetVisible("add_friend_btn", nearby_tab_active || recent_tab_active); buttonSetVisible("view_profile_btn", !group_tab_active); buttonSetVisible("im_btn", !group_tab_active); buttonSetVisible("call_btn", !group_tab_active); @@ -750,7 +749,9 @@ void LLPanelPeople::updateButtons() is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL; } - childSetEnabled("add_friend_btn", !is_friend); + LLPanel* cur_panel = mTabContainer->getCurrentPanel(); + if (cur_panel) + cur_panel->childSetEnabled("add_friend_btn", !is_friend); } buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front())); diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 2d3f901370..1051326e72 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -970,19 +970,32 @@ void LLPanelPermissions::setAllSaleInfo() if (price < 0) sale_type = LLSaleInfo::FS_NOT; - LLSaleInfo sale_info(sale_type, price); - LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(sale_info); + LLSaleInfo old_sale_info; + LLSelectMgr::getInstance()->selectGetSaleInfo(old_sale_info); + + LLSaleInfo new_sale_info(sale_type, price); + LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info); - // If turned off for-sale, make sure click-action buy is turned - // off as well - if (sale_type == LLSaleInfo::FS_NOT) + U8 old_click_action = 0; + LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action); + + if (old_sale_info.isForSale() + && !new_sale_info.isForSale() + && old_click_action == CLICK_ACTION_BUY) { - U8 click_action = 0; - LLSelectMgr::getInstance()->selectionGetClickAction(&click_action); - if (click_action == CLICK_ACTION_BUY) - { - LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_TOUCH); - } + // If turned off for-sale, make sure click-action buy is turned + // off as well + LLSelectMgr::getInstance()-> + selectionSetClickAction(CLICK_ACTION_TOUCH); + } + else if (new_sale_info.isForSale() + && !old_sale_info.isForSale() + && old_click_action == CLICK_ACTION_TOUCH) + { + // If just turning on for-sale, preemptively turn on one-click buy + // unless user have a different click action set + LLSelectMgr::getInstance()-> + selectionSetClickAction(CLICK_ACTION_BUY); } } diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 6905c7e546..04b4226f82 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -346,11 +346,18 @@ void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab) void LLPanelPicks::onOverflowButtonClicked() { - LLRect rect; - childGetRect(XML_BTN_OVERFLOW, rect); + if (!mOverflowMenu->toggleVisibility()) + return; + + LLView* btn = getChild<LLView>(XML_BTN_OVERFLOW); + if (mOverflowMenu->getButtonRect().isEmpty()) + { + mOverflowMenu->setButtonRect(btn); + } mOverflowMenu->updateParent(LLMenuGL::sMenuContainer); - mOverflowMenu->setButtonRect(rect, this); + + LLRect rect = btn->getRect(); LLMenuGL::showPopup(this, mOverflowMenu, rect.mRight, rect.mTop); } diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 61501cc1b1..0c7cc9af38 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -542,16 +542,16 @@ void LLPanelPlaceProfile::updateCovenantText(const std::string &text) void LLPanelPlaceProfile::onForSaleBannerClick() { LLViewerParcelMgr* mgr = LLViewerParcelMgr::getInstance(); - LLParcelSelectionHandle hParcel = mgr->getFloatingParcelSelection(); + LLParcel* parcel = mgr->getFloatingParcelSelection()->getParcel(); LLViewerRegion* selected_region = mgr->getSelectionRegion(); - if(!hParcel.isNull() && selected_region) + if(parcel && selected_region) { - if(hParcel->getParcel()->getLocalID() == mSelectedParcelID && + if(parcel->getLocalID() == mSelectedParcelID && mLastSelectedRegionID ==selected_region->getRegionID()) { - if(hParcel->getParcel()->getSalePrice() - gStatusBar->getBalance() > 0) + if(parcel->getSalePrice() - gStatusBar->getBalance() > 0) { - LLFloaterBuyCurrency::buyCurrency("Buying selected land ", hParcel->getParcel()->getSalePrice()); + LLFloaterBuyCurrency::buyCurrency("Buying selected land ", parcel->getSalePrice()); } else { diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 3d0fba9426..eb10d97b37 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -601,9 +601,12 @@ void LLPanelPlaces::onOverflowButtonClicked() if (!menu->toggleVisibility()) return; + if (menu->getButtonRect().isEmpty()) + { + menu->setButtonRect(mOverflowBtn); + } menu->updateParent(LLMenuGL::sMenuContainer); LLRect rect = mOverflowBtn->getRect(); - menu->setButtonRect(rect, this); LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop); } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index aeab3e2876..c30997fbdc 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -234,9 +234,16 @@ void LLSidepanelAppearance::toggleLookInfoPanel(BOOL visible) mNewLookBtn->setVisible(!visible); mOverflowBtn->setVisible(!visible); mCurrLookPanel->setVisible(!visible); + + if (visible) + { + LLRect rect = getRect(); + LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); + mLookInfo->reshape(new_rect.getWidth(),new_rect.getHeight()); + } } -void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) +void LLPanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) { if (!wearable) { diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 2fb6550107..eada387945 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -90,9 +90,9 @@ BOOL LLSysWellWindow::postBuild() void LLSysWellWindow::setMinimized(BOOL minimize) { // we don't show empty Message Well window - if (!minimize) + if (!minimize && isWindowEmpty()) { - setVisible(!isWindowEmpty()); + return; } LLDockableFloater::setMinimized(minimize); @@ -268,8 +268,11 @@ void LLSysWellWindow::toggleWindow() { setVisible(FALSE); } - //set window in foreground - setFocus(getVisible()); + else if(!isDocked()) + { + // bring to front undocked floater + setVisible(TRUE); + } } //--------------------------------------------------------------------------------- diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 9be342c424..c33c652935 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -834,9 +834,9 @@ bool LLTextureCache::updateTextureEntryList(const LLUUID& id, S32 bodysize) S32 idx = openAndReadEntry(id, entry, false); if (idx < 0) { - // TODO: change to llwarns - llerrs << "Failed to open entry: " << id << llendl; - removeFromCache(id); + llwarns << "Failed to open entry: " << id << llendl; + removeHeaderCacheEntry(id); + LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); return false; } else if (oldbodysize != entry.mBodySize) @@ -1002,7 +1002,7 @@ void LLTextureCache::closeHeaderEntriesFile() void LLTextureCache::readEntriesHeader() { // mHeaderEntriesInfo initializes to default values so safe not to read it - llassert_always(mHeaderAPRFile == NULL); + llassert_always(mHeaderAPRFile == NULL); if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool())) { LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo), @@ -1192,7 +1192,7 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries) // Called from either the main thread or the worker thread void LLTextureCache::readHeaderCache() { - LLMutexLock lock(&mHeaderMutex); + mHeaderMutex.lock(); mLRU.clear(); // always clear the LRU @@ -1212,28 +1212,29 @@ void LLTextureCache::readHeaderCache() if (num_entries) { U32 empty_entries = 0; - typedef std::pair<U32, LLUUID> lru_data_t; + typedef std::pair<U32, S32> lru_data_t; std::set<lru_data_t> lru; - std::vector<LLUUID> purge_list; + std::set<LLUUID> purge_list; for (U32 i=0; i<num_entries; i++) { Entry& entry = entries[i]; const LLUUID& id = entry.mID; if (entry.mImageSize < 0) { - // This will be in the Free List, don't put it in the LRY + // This will be in the Free List, don't put it in the LRU ++empty_entries; } else { - lru.insert(std::make_pair(entry.mTime, id)); + lru.insert(std::make_pair(entry.mTime, i)); if (entry.mBodySize > 0) { if (entry.mBodySize > entry.mImageSize) { // Shouldn't happen, failsafe only llwarns << "Bad entry: " << i << ": " << id << ": BodySize: " << entry.mBodySize << llendl; - purge_list.push_back(id); + purge_list.insert(entry.mID); + entry.mImageSize = -1; // empty/available } } } @@ -1243,22 +1244,31 @@ void LLTextureCache::readHeaderCache() // Special case: cache size was reduced, need to remove entries // Note: After we prune entries, we will call this again and create the LRU U32 entries_to_purge = (num_entries-empty_entries) - sCacheMaxEntries; + llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl; if (entries_to_purge > 0) { for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) { - purge_list.push_back(iter->second); - if (--entries_to_purge <= 0) - break; + S32 idx = iter->second; + if (entries[idx].mImageSize >= 0) + { + purge_list.insert(entries[idx].mID); + entries[idx].mImageSize = -1; + if (purge_list.size() >= entries_to_purge) + break; + } } } + llassert_always(purge_list.size() >= entries_to_purge); } else { S32 lru_entries = (S32)((F32)sCacheMaxEntries * TEXTURE_CACHE_LRU_SIZE); for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) { - mLRU.insert(iter->second); + S32 idx = iter->second; + const LLUUID& id = entries[idx].mID; + mLRU.insert(id); // llinfos << "LRU: " << iter->first << " : " << iter->second << llendl; if (--lru_entries <= 0) break; @@ -1267,9 +1277,12 @@ void LLTextureCache::readHeaderCache() if (purge_list.size() > 0) { - for (std::vector<LLUUID>::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) + for (std::set<LLUUID>::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { - removeFromCache(*iter); + const LLUUID& id = *iter; + bool res = removeHeaderCacheEntry(id); // sets entry size on disk to -1 + llassert_always(res); + LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); } // If we removed any entries, we need to rebuild the entries list, // write the header, and call this again @@ -1285,7 +1298,9 @@ void LLTextureCache::readHeaderCache() llassert_always(new_entries.size() <= sCacheMaxEntries); mHeaderEntriesInfo.mEntries = new_entries.size(); writeEntriesAndClose(new_entries); + mHeaderMutex.unlock(); // unlock the mutex before calling again readHeaderCache(); // repeat with new entries file + mHeaderMutex.lock(); } else { @@ -1293,6 +1308,7 @@ void LLTextureCache::readHeaderCache() } } } + mHeaderMutex.unlock(); } ////////////////////////////////////////////////////////////////////////////// @@ -1307,6 +1323,7 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) for (S32 i=0; i<16; i++) { std::string dirname = mTexturesDirName + delem + subdirs[i]; + llinfos << "Deleting files in directory: " << dirname << llendl; gDirUtilp->deleteFilesInDir(dirname,mask); if (purge_directories) { @@ -1337,9 +1354,12 @@ void LLTextureCache::purgeTextures(bool validate) return; } - // *FIX:Mani - watchdog off. - LLAppViewer::instance()->pauseMainloopTimeout(); - + if (!mThreaded) + { + // *FIX:Mani - watchdog off. + LLAppViewer::instance()->pauseMainloopTimeout(); + } + LLMutexLock lock(&mHeaderMutex); llinfos << "TEXTURE CACHE: Purging." << llendl; @@ -1486,7 +1506,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, S32& imagesize) // Writes imagesize to the header, updates timestamp S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, S32 imagesize) { - LLMutexLock lock(&mHeaderMutex); + mHeaderMutex.lock(); llassert_always(imagesize >= 0); Entry entry; S32 idx = openAndReadEntry(id, entry, true); @@ -1494,11 +1514,15 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, S32 imagesize) { entry.mImageSize = imagesize; writeEntryAndClose(idx, entry); + mHeaderMutex.unlock(); } else // retry { + mHeaderMutex.unlock(); readHeaderCache(); // We couldn't write an entry, so refresh the LRU + mHeaderMutex.lock(); llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries); + mHeaderMutex.unlock(); idx = setHeaderCacheEntry(id, imagesize); // assert above ensures no inf. recursion } return idx; @@ -1624,24 +1648,20 @@ void LLTextureCache::addCompleted(Responder* responder, bool success) ////////////////////////////////////////////////////////////////////////////// // Called from MAIN thread (endWork()) - +// Ensure that mHeaderMutex is locked first! bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) { - if (!mReadOnly) + Entry entry; + S32 idx = openAndReadEntry(id, entry, false); + if (idx >= 0) { - LLMutexLock lock(&mHeaderMutex); - Entry entry; - S32 idx = openAndReadEntry(id, entry, false); - if (idx >= 0) - { - entry.mImageSize = -1; - entry.mBodySize = 0; - writeEntryAndClose(idx, entry); - mFreeList.insert(idx); - mHeaderIDMap.erase(id); - mTexturesSizeMap.erase(id); - return true; - } + entry.mImageSize = -1; + entry.mBodySize = 0; + writeEntryAndClose(idx, entry); + mFreeList.insert(idx); + mHeaderIDMap.erase(id); + mTexturesSizeMap.erase(id); + return true; } return false; } @@ -1651,6 +1671,7 @@ void LLTextureCache::removeFromCache(const LLUUID& id) //llwarns << "Removing texture from cache: " << id << llendl; if (!mReadOnly) { + LLMutexLock lock(&mHeaderMutex); removeHeaderCacheEntry(id); LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index c918f98895..6f3dabe5a7 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -524,6 +524,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) mDesiredSize = size; prioritize = true; } + mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); if ((prioritize && mState == INIT) || mState == DONE) { mState = INIT; @@ -613,6 +614,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mCacheReadHandle = LLTextureCache::nullHandle(); mCacheWriteHandle = LLTextureCache::nullHandle(); mState = LOAD_FROM_TEXTURE_CACHE; + mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; // fall through @@ -681,7 +683,6 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == CACHE_POST) { - mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); mCachedSize = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; // Successfully loaded if ((mCachedSize >= mDesiredSize) || mHaveAllData) diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 903df21e78..ed2cedbd10 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -225,6 +225,7 @@ void LLToast::setVisible(BOOL show) { mTimer.start(); } + LLModalDialog::setFrontmost(FALSE); } LLPanel::setVisible(show); if(mPanel) diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index 1ea5f515b7..d2cc6d0726 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -51,14 +51,20 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mReplyBtn = getChild<LLButton>("reply"); LLStyle::Params style_params; + style_params.font.name(LLFontGL::nameFromFont(style_params.font)); + style_params.font.size(LLFontGL::sizeFromFont(style_params.font)); + style_params.font.style = "UNDERLINE"; + //Handle IRC styled /me messages. std::string prefix = p.message.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { mMessage->clear(); - style_params.font.style= "ITALIC"; + + style_params.font.style ="ITALIC"; mMessage->appendText(p.from + " ", FALSE, style_params); - style_params.font.style= "UNDERLINE"; + + style_params.font.style = "UNDERLINE"; mMessage->appendText(p.message.substr(3), FALSE, style_params); } else diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 0c23947a8c..48b68e4292 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -128,6 +128,7 @@ mAddedDefaultBtn(false) // *TODO: magic numbers(???) - copied from llnotify.cpp(250) const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; + mTextBox->setMaxTextLength(MAX_LENGTH); mTextBox->setVisible(TRUE); mTextBox->setValue(notification->getMessage()); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index d49ea5109d..9c8fca3552 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -526,7 +526,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) } static LLCachedControl<bool> enable_highlight( - gSavedSettings, "RenderHighlightEnable", false); + gSavedSettings, "RenderHoverGlowEnable", false); LLDrawable* drawable = NULL; if (enable_highlight && show_highlight && object) { diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index d65a060bbc..8de87eb602 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -201,3 +201,21 @@ S32 LLViewerChat::getChatFontSize() { return gSavedSettings.getS32("ChatFontSize"); } + + +//static +void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg) +{ + std::string tmpmsg = chat.mText; + + if(chat.mChatStyle == CHAT_STYLE_IRC) + { + formated_msg = chat.mFromName + tmpmsg.substr(3); + } + else + { + formated_msg = tmpmsg; + } + +} + diff --git a/indra/newview/llviewerchat.h b/indra/newview/llviewerchat.h index d8840d5dd2..502d6ea7e5 100644 --- a/indra/newview/llviewerchat.h +++ b/indra/newview/llviewerchat.h @@ -45,8 +45,7 @@ public: static void getChatColor(const LLChat& chat, std::string& r_color_name, F32& r_color_alpha); static LLFontGL* getChatFont(); static S32 getChatFontSize(); - - + static void formatChatMsg(const LLChat& chat, std::string& formated_msg); }; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 251d7d4a13..3a7c54479b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -32,6 +32,7 @@ #include "llviewerprecompiledheaders.h" +#include "llagent.h" #include "llviewermedia.h" #include "llviewermediafocus.h" #include "llmimetypes.h" @@ -541,6 +542,16 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView // The item with user focus always comes to the front of the list, period. return false; } + else if(i1->isParcelMedia()) + { + // The parcel media impl sorts above all other inworld media, unless one has focus. + return true; + } + else if(i2->isParcelMedia()) + { + // The parcel media impl sorts above all other inworld media, unless one has focus. + return false; + } else if(i1->getUsedInUI() && !i2->getUsedInUI()) { // i1 is a UI element, i2 is not. This makes i1 "less than" i2, so it sorts earlier in our list. @@ -551,16 +562,21 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView // i2 is a UI element, i1 is not. This makes i2 "less than" i1, so it sorts earlier in our list. return false; } - else if(i1->isParcelMedia()) + else if(i1->isPlayable() && !i2->isPlayable()) { - // The parcel media impl sorts above all other inworld media, unless one has focus. + // Playable items sort above ones that wouldn't play even if they got high enough priority return true; } - else if(i2->isParcelMedia()) + else if(!i1->isPlayable() && i2->isPlayable()) { - // The parcel media impl sorts above all other inworld media, unless one has focus. + // Playable items sort above ones that wouldn't play even if they got high enough priority return false; } + else if(i1->getInterest() == i2->getInterest()) + { + // Generally this will mean both objects have zero interest. In this case, sort on distance. + return (i1->getProximityDistance() < i2->getProximityDistance()); + } else { // The object with the larger interest value should be earlier in the list, so we reverse the sense of the comparison here. @@ -568,6 +584,11 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView } } +static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2) +{ + return (i1->getProximityDistance() < i2->getProximityDistance()); +} + ////////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerMedia::updateMedia() @@ -593,12 +614,9 @@ void LLViewerMedia::updateMedia() int impl_count_total = 0; int impl_count_interest_low = 0; int impl_count_interest_normal = 0; - int i = 0; - -#if 0 - LL_DEBUGS("PluginPriority") << "Sorted impls:" << llendl; -#endif - + + std::vector<LLViewerMediaImpl*> proximity_order; + U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal"); U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal"); U32 max_low = gSavedSettings.getU32("PluginInstancesLow"); @@ -629,10 +647,12 @@ void LLViewerMedia::updateMedia() else if(pimpl->hasFocus()) { new_priority = LLPluginClassMedia::PRIORITY_HIGH; + impl_count_interest_normal++; // count this against the count of "normal" instances for priority purposes } else if(pimpl->getUsedInUI()) { new_priority = LLPluginClassMedia::PRIORITY_NORMAL; + impl_count_interest_normal++; } else { @@ -640,7 +660,17 @@ void LLViewerMedia::updateMedia() // Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture, // turn it down to low instead of normal. This may downsample for plugins that support it. - bool media_is_small = pimpl->getInterest() < (pimpl->getApproximateTextureInterest() / 4); + bool media_is_small = false; + F64 approximate_interest = pimpl->getApproximateTextureInterest(); + if(approximate_interest == 0.0f) + { + // this media has no current size, which probably means it's not loaded. + media_is_small = true; + } + else if(pimpl->getInterest() < (approximate_interest / 4)) + { + media_is_small = true; + } if(pimpl->getInterest() == 0.0f) { @@ -678,7 +708,7 @@ void LLViewerMedia::updateMedia() } } - if(new_priority != LLPluginClassMedia::PRIORITY_UNLOADED) + if(!pimpl->getUsedInUI() && (new_priority != LLPluginClassMedia::PRIORITY_UNLOADED)) { impl_count_total++; } @@ -692,23 +722,27 @@ void LLViewerMedia::updateMedia() } else { - // Other impls just get the same ordering as the priority list (for now). - pimpl->mProximity = i; + proximity_order.push_back(pimpl); } -#if 0 - LL_DEBUGS("PluginPriority") << " " << pimpl - << ", setting priority to " << new_priority - << (pimpl->hasFocus()?", HAS FOCUS":"") - << (pimpl->getUsedInUI()?", is UI":"") - << ", cpu " << pimpl->getCPUUsage() - << ", interest " << pimpl->getInterest() - << ", media url " << pimpl->getMediaURL() << llendl; -#endif - total_cpu += pimpl->getCPUUsage(); - - i++; + } + + if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug")) + { + // Give impls the same ordering as the priority list + // they're already in the right order for this. + } + else + { + // Use a distance-based sort for proximity values. + std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor); + } + + // Transfer the proximity order to the proximity fields in the objects. + for(int i = 0; i < (int)proximity_order.size(); i++) + { + proximity_order[i]->mProximity = i; } LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << llendl; @@ -760,6 +794,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mIsDisabled(false), mIsParcelMedia(false), mProximity(-1), + mProximityDistance(0.0f), mMimeTypeProbe(NULL), mIsUpdated(false) { @@ -1588,6 +1623,10 @@ void LLViewerMediaImpl::update() { // This media source should not be loaded. } + else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW) + { + // Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state. + } else if(mMimeTypeProbe != NULL) { // this media source is doing a MIME type probe -- don't try loading it again. @@ -1816,7 +1855,7 @@ bool LLViewerMediaImpl::isMediaPaused() ////////////////////////////////////////////////////////////////////////////////////////// // -bool LLViewerMediaImpl::hasMedia() +bool LLViewerMediaImpl::hasMedia() const { return mMediaSource != NULL; } @@ -1851,6 +1890,31 @@ bool LLViewerMediaImpl::isForcedUnloaded() const } ////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isPlayable() const +{ + if(isForcedUnloaded()) + { + // All of the forced-unloaded criteria also imply not playable. + return false; + } + + if(hasMedia()) + { + // Anything that's already playing is, by definition, playable. + return true; + } + + if(!mMediaURL.empty()) + { + // If something has navigated the instance, it's ready to be played. + return true; + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event) { switch(event) @@ -2058,6 +2122,15 @@ void LLViewerMediaImpl::calculateInterest() mInterest = 0.0f; } + // Calculate distance from the avatar, for use in the proximity calculation. + mProximityDistance = 0.0f; + if(!mObjectList.empty()) + { + // Just use the first object in the list. We could go through the list and find the closest object, but this should work well enough. + LLVector3d global_delta = gAgent.getPositionGlobal() - (*mObjectList.begin())->getPositionGlobal(); + mProximityDistance = global_delta.magVecSquared(); // use distance-squared because it's cheaper and sorts the same. + } + if(mNeedsMuteCheck) { // Check all objects this instance is associated with, and those objects' owners, against the mute list @@ -2094,7 +2167,13 @@ F64 LLViewerMediaImpl::getApproximateTextureInterest() result = mMediaSource->getFullWidth(); result *= mMediaSource->getFullHeight(); } - + else + { + // No media source is loaded -- all we have to go on is the texture size that has been set on the impl, if any. + result = mMediaWidth; + result *= mMediaHeight; + } + return result; } @@ -2135,7 +2214,7 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority) { if(mPriority != priority) { - LL_INFOS("PluginPriority") + LL_DEBUGS("PluginPriority") << "changing priority of media id " << mTextureId << " from " << LLPluginClassMedia::priorityToString(mPriority) << " to " << LLPluginClassMedia::priorityToString(priority) diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 639aed4b8a..f4afce6c4c 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -194,7 +194,7 @@ public: bool isMediaPlaying(); bool isMediaPaused(); - bool hasMedia(); + bool hasMedia() const; bool isMediaFailed() const { return mMediaSourceFailed; }; void resetPreviousMediaState(); @@ -204,6 +204,9 @@ public: // returns true if this instance should not be loaded (disabled, muted object, crashed, etc.) bool isForcedUnloaded() const; + // returns true if this instance could be playable based on autoplay setting, current load state, etc. + bool isPlayable() const; + void setIsParcelMedia(bool is_parcel_media) { mIsParcelMedia = is_parcel_media; }; bool isParcelMedia() const { return mIsParcelMedia; }; @@ -267,6 +270,7 @@ public: F64 getInterest() const { return mInterest; }; F64 getApproximateTextureInterest(); S32 getProximity() const { return mProximity; }; + F64 getProximityDistance() const { return mProximityDistance; }; // Mark this object as being used in a UI panel instead of on a prim // This will be used as part of the interest sorting algorithm. @@ -336,6 +340,7 @@ public: bool mIsDisabled; bool mIsParcelMedia; S32 mProximity; + F64 mProximityDistance; LLMimeDiscoveryResponder *mMimeTypeProbe; private: diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0153116887..ef6a621323 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2343,14 +2343,14 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) std::string prefix = mesg.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { - chat.mText = from_name; - chat.mText += mesg.substr(3); +// chat.mText = from_name; +// chat.mText += mesg.substr(3); ircstyle = TRUE; } - else - { +// else +// { chat.mText = mesg; - } +// } // Look for the start of typing so we can put "..." in the bubbles. if (CHAT_TYPE_START == chat.mChatType) @@ -2376,19 +2376,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) return; } - // We have a real utterance now, so can stop showing "..." and proceed. - if (chatter && chatter->isAvatar()) - { - LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE); - ((LLVOAvatar*)chatter)->stopTyping(); - - if (!is_muted && !is_busy) - { - visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles"); - ((LLVOAvatar*)chatter)->addChat(chat); - } - } - // Look for IRC-style emotes if (ircstyle) { @@ -2428,6 +2415,23 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mText += mesg; } + // We have a real utterance now, so can stop showing "..." and proceed. + if (chatter && chatter->isAvatar()) + { + LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE); + ((LLVOAvatar*)chatter)->stopTyping(); + + if (!is_muted && !is_busy) + { + visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles"); + std::string formated_msg = ""; + LLViewerChat::formatChatMsg(chat, formated_msg); + LLChat chat_bubble = chat; + chat_bubble.mText = formated_msg; + ((LLVOAvatar*)chatter)->addChat(chat_bubble); + } + } + if (chatter) { chat.mPosAgent = chatter->getPositionAgent(); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 85bc26c9c0..0d29efaedf 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -2121,10 +2121,11 @@ LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level) llassert_always(mGLTexturep.notNull()) ; llassert_always(discard_level >= 0); llassert_always(mComponents > 0); + if (mRawImage.notNull()) { - llerrs << "called with existing mRawImage" << llendl; - mRawImage = NULL; + //mRawImage is in use by somebody else, do not delete it. + return NULL ; } if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 90a79698f6..7b35125b5b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4132,7 +4132,7 @@ void LLViewerWindow::drawMouselookInstructions() { // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.) const std::string instructions = LLTrans::getString("LeaveMouselook"); - const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Huge", LLFontGL::BOLD)); + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Large", LLFontGL::BOLD)); //to be on top of Bottom bar when it is opened const S32 INSTRUCTIONS_PAD = 50; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 999701ece1..6340189c93 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -287,17 +287,22 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, min_dim /= 2; } - mDetailTextures[i]->reloadRawImage(ddiscard) ; + BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ; if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. { - mDetailTextures[i]->destroyRawImage() ; + if(delete_raw) + { + mDetailTextures[i]->destroyRawImage() ; + } lldebugs << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << llendl; return FALSE; } mRawImages[i] = mDetailTextures[i]->getRawImage() ; - mDetailTextures[i]->destroyRawImage() ; - + if(delete_raw) + { + mDetailTextures[i]->destroyRawImage() ; + } if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE || mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE || mDetailTextures[i]->getComponents() != 3) diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 028a5844c6..eb8ec00bb9 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -663,7 +663,10 @@ value="0.812 0.753 0.451 1" /> <color name="ToolTipTextColor" - value="0.749 0.749 0.749 1" /> + reference="DkGray2" /> + <color + name="InspectorTipTextColor" + reference="LtGray" /> <color name="UserChatColor" reference="LtGray" /> diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index d5293bdbb5..8af65b25e9 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -106,6 +106,7 @@ <texture name="DropDown_Press" file_name="widgets/DropDown_Press.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="DropDown_Selected" file_name="widgets/DropDown_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="DropDown_Off" file_name="widgets/DropDown_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="DropDown_On" file_name="widgets/DropDown_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="DropTarget" file_name="widgets/DropTarget.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml index d0d0cc64c5..e4ab533bc5 100644 --- a/indra/newview/skins/default/xui/en/floater_aaa.xml +++ b/indra/newview/skins/default/xui/en/floater_aaa.xml @@ -5,5 +5,6 @@ name="floater_aaa" can_resize="true" width="1024"> + <string name="Nudge Parabuild">1</string> <panel filename="main_view.xml" follows="all" width="1024" height="768" top="0"/> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml index 6c4f10e61e..9d2a811d9f 100644 --- a/indra/newview/skins/default/xui/en/floater_customize.xml +++ b/indra/newview/skins/default/xui/en/floater_customize.xml @@ -3383,6 +3383,16 @@ scratch and wear it. bottom="536" follows="right|bottom" height="20" + label="Make Outfit" + label_selected="Make Outfit" + layout="topleft" + name="make_outfit_btn" + right="-216" + width="100" /> + <button + bottom="536" + follows="right|bottom" + height="20" label="Cancel" label_selected="Cancel" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 452d28d4ea..9e2dbc881f 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -2,66 +2,63 @@ <floater legacy_header_height="18" background_visible="true" - follows="left|top|right|bottom" - height="369" + follows="all" + height="350" layout="topleft" left="0" name="panel_im" - help_topic="panel_im" top="0" can_dock="true" - can_minimize="true" - visible="true" - width="520" + can_minimize="false" + visible="true" + width="320" can_resize="true" - min_width="350" - min_height="369"> - <layout_stack follows="left|top|right|bottom" - height="354" - width="520" + min_width="300" + min_height="350"> + <layout_stack follows="all" + height="350" + width="300" layout="topleft" orientation="horizontal" name="im_panels" - top="16" - left="2"> + top="20" + left="0"> <layout_panel name="panel_im_control_panel" layout="topleft" top_delta="-3" - height="354" + height="350" follows="left" label="IM Control Panel" auto_resize="false" user_resize="false" /> - <layout_panel height="354" - width="355" - left_delta="146" + <layout_panel height="350" + width="" + left_delta="110" top="0" user_resize="false"> - <button height="12" - follows="left|top" - top="8" - label="<<" + <button height="20" + follows="left|top" + top="0" + image_overlay="TabIcon_Open_Off" layout="topleft" - width="35" + width="25" name="slide_left_btn" /> - <button height="12" - follows="left|top" - top="8" - label=">>" - layout="topleft" - width="35" + <button height="20" + follows="left|top" + top="0" + image_overlay="TabIcon_Close_Off" + width="25" name="slide_right_btn" /> <chat_history length="1" - follows="left|top|right|bottom" - font="SansSerif" - height="300" + follows="all" + height="275" layout="topleft" name="chat_history" parse_highlights="true" - allow_html="true" - width="350"> + allow_html="true" + width="160"> </chat_history> <line_editor follows="left|right" @@ -69,7 +66,7 @@ label="To" layout="topleft" name="chat_editor" - width="345"> + width="160"> </line_editor> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 7f58ea132e..4f2d74b417 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater legacy_header_height="18" - can_minimize="true" + can_minimize="false" can_tear_off="false" can_resize="false" can_drag_on_left="false" @@ -11,7 +11,6 @@ height="300" layout="topleft" name="nearby_chat" - help_topic="nearby_chat" save_rect="true" title="NEARBY CHAT" save_dock_state="true" @@ -19,19 +18,17 @@ single_instance="true" width="320"> <chat_history - allow_html="true" + allow_html="true" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" follows="all" - left="1" + left="1" top="20" - font="SansSerif" layout="topleft" - height="280" + height="280" name="chat_history" - parse_highlights="true" + parse_highlights="true" text_color="ChatHistoryTextColor" text_readonly_color="ChatHistoryTextColor" - width="320"/> - + width="320" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index b2f46bc433..bfbfe7de7c 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -269,6 +269,7 @@ halign="left" left="13" name="RenderingCost" + tool_tip="Shows the rendering cost calculated for this object" top_pad="9" type="string" width="100"> @@ -306,6 +307,7 @@ layout="topleft" follows="left|top" name="combobox grid mode" + tool_tip="Choose the type of grid ruler for positioning the object" width="108"> <combo_box.item label="World grid" @@ -329,7 +331,7 @@ image_unselected="ForwardArrow_Off" layout="topleft" name="Options..." - tool_tip="Grid options" + tool_tip="See more grid options" top_delta="0" right="-10" width="18" @@ -786,7 +788,7 @@ </panel.string> <panel.string name="text modify warning"> - This object has linked parts + You must select entire object to set permissions </panel.string> <panel.string name="Cost Default"> @@ -1074,7 +1076,7 @@ even though the user gets a free copy. follows="left|top|right" layout="topleft" name="perm_modify" - width="250"> + width="264"> You can modify this object </text> <text diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index 2c1e2b6dc0..dd3cf079db 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -4,18 +4,18 @@ Single instance - only have one at a time, recycle it each spawn --> <floater - legacy_header_height="18" + legacy_header_height="25" bevel_style="in" - bg_opaque_image="Inspector_Background" + bg_opaque_image="Inspector_Background" can_close="false" can_minimize="false" - height="138" + height="148" layout="topleft" name="inspect_avatar" single_instance="true" sound_flags="0" visible="true" - width="245"> + width="228"> <!-- Allowed fields include: [BORN_ON] ("12/3/2008") [SL_PROFILE] (Second Life profile), @@ -30,7 +30,7 @@ </string> <string name="Details"> -[ACCTTYPE][COMMA] [PAYMENTINFO] +[SL_PROFILE] </string> <string name="Partner"> @@ -38,45 +38,45 @@ </string> <text follows="all" - font="SansSerifLargeBold" - height="18" + font="SansSerifLarge" + height="16" left="8" name="user_name" - top="5" - text_color="white" + top="10" + text_color="White" use_ellipses="true" value="Grumpity ProductEngine" - width="240" - word_wrap="false" /> + width="175" /> <text follows="all" height="16" left="8" - value="Grumpity ProductEngine moose moose" - name="user_details" - top_pad="0" - width="170" - use_ellipses="true" - word_wrap="false" /> - <text - follows="all" - font="SansSerifSmallBold" + name="user_subtitle" + font="SansSerifSmall" text_color="White" - height="18" + value="11 Months, 3 days old" + width="175" + use_ellipses="true" /> + <text + follows="all" + height="25" left="8" - name="user_subtitle" - use_ellipses="true" - top_pad="0" - width="170" /> + name="user_details" + word_wrap="true" + top_pad="6" + width="220">This is my second life description and I really think it is great. + </text> <text follows="all" - height="16" + height="13" left="8" name="user_partner" - top_pad="8" - width="240" + top_pad="3" + width="220" use_ellipses="true" - word_wrap="false" /> + word_wrap="false"> + Erica Linden + </text> <slider follows="top|left" height="23" @@ -89,15 +89,15 @@ tool_tip="Voice volume" top_pad="0" value="0.5" - width="150" /> + width="195" /> <button follows="all" height="16" - image_disabled="Inv_Sound" - image_disabled_selected="Inv_Sound" - image_hover_selected="Inv_Sound" - image_selected="Inv_Sound" - image_unselected="Inv_Sound" + image_disabled="Audio_Off" + image_disabled_selected="AudioMute_Off" + image_hover_selected="AudioMute_Over" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" is_toggle="true" left_pad="0" top_delta="4" @@ -106,67 +106,60 @@ <avatar_icon follows="all" height="38" - right="-25" + right="-10" bevel_style="in" border_style="line" mouse_opaque="true" name="avatar_icon" - top="24" + top="10" width="38" /> - <button - follows="top|left" - height="18" - image_disabled="ForwardArrow_Disabled" - image_selected="ForwardArrow_Press" - image_unselected="ForwardArrow_Off" - layout="topleft" - name="view_profile_btn" - right="-8" - top="35" - left_delta="110" - tab_stop="false" - width="18" /> <!-- Overlapping buttons for default actions llinspectavatar.cpp makes visible the most likely default action --> <button follows="bottom|left" - height="23" + height="20" label="Add Friend" left="8" - top="246" + top="119" name="add_friend_btn" - width="100" /> + width="90" /> <button follows="bottom|left" - height="23" + height="20" label="IM" left_delta="0" top_delta="0" name="im_btn" - width="100" + width="80" commit_callback.function="InspectAvatar.IM" /> - <menu_button + <button follows="top|left" - height="18" - image_disabled="OptionsMenu_Disabled" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" + height="20" + label="More" + layout="topleft" + name="view_profile_btn" + left_delta="96" + top_delta="0" + tab_stop="false" + width="80" /> + <!-- gear buttons here --> + <menu_button + height="20" + layout="topleft" + image_overlay="OptionsMenu_Off" menu_filename="menu_inspect_avatar_gear.xml" name="gear_btn" - right="-10" - top="249" - width="18" /> - <menu_button - visible="false" + right="-5" + top_delta="0" + width="35" /> + <menu_button follows="top|left" - height="18" - image_disabled="OptionsMenu_Disabled" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" + height="20" + image_overlay="OptionsMenu_Off" menu_filename="menu_inspect_self_gear.xml" name="gear_self_btn" - right="-10" - top="249" - width="18" /> + right="-5" + top_delta="0" + width="35" /> </floater> diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml index 1365a0483f..83570e2528 100644 --- a/indra/newview/skins/default/xui/en/inspect_object.xml +++ b/indra/newview/skins/default/xui/en/inspect_object.xml @@ -4,48 +4,46 @@ Single instance - only have one at a time, recycle it each spawn --> <floater - legacy_header_height="18" + legacy_header_height="25" bevel_style="in" - bg_opaque_image="Inspector_Background" + bg_opaque_image="Inspector_Background" can_close="false" can_minimize="false" - height="145" + height="148" layout="topleft" name="inspect_object" single_instance="true" sound_flags="0" visible="true" - width="300"> + width="228"> <string name="Creator">By [CREATOR]</string> <string name="CreatorAndOwner"> by [CREATOR] owner [OWNER] </string> - <!-- *TODO: Might need to change to [AMOUNT] if icon contains "L$" --> <string name="Price">L$[AMOUNT]</string> <string name="PriceFree">Free!</string> <string name="Touch">Touch</string> <string name="Sit">Sit</string> <text follows="all" - font="SansSerifLargeBold" + font="SansSerifLarge" height="16" left="8" name="object_name" text_color="White" - top="5" + top="10" use_ellipses="true" value="Test Object Name That Is Really Long" - width="291" /> + width="220" /> <text follows="all" - font="SansSerif" height="30" left="8" name="object_creator" top_pad="0" use_ellipses="true" - width="275"> + width="220"> by Longavatarname Johnsonlongstonnammer owner James Linden </text> @@ -53,32 +51,34 @@ owner James Linden <icon name="price_icon" image_name="Icon_For_Sale" - left="7" + right="-5" width="16" height="16" - top="52" + top="50" follows="left|top" /> <text follows="all" - font="SansSerifSmallBold" + font="SansSerifSmall" + font.style="BOLD" height="16" - left_pad="5" + halign="right" + left="5" name="price_text" text_color="white" - top="54" + top="53" font_shadow="none" - width="150"> + width="196"> L$300,000 </text> <text follows="all" - height="30" + font="SansSerifSmall" + height="36" left="8" name="object_description" top_pad="0" - width="291" - use_ellipses="true" + width="220" word_wrap="true"> This is a really long description for an object being as how it is at least 80 characters in length and maybe more like 120 at this point. Who knows, really? </text> @@ -86,69 +86,64 @@ This is a really long description for an object being as how it is at least 80 c for sale, "Sit" if can sit, etc. --> <text follows="all" - height="15" + font="SansSerifSmall" + height="13" left_delta="0" name="object_media_url" - top_pad="-5" + top_pad="0" width="291" - max_length = "50" - use_ellipses="true" - word_wrap="true"/> - + max_length = "50" + use_ellipses="true"> + http://www.superdupertest.com +</text> <button follows="top|left" - font="SansSerif" height="20" label="Buy" - left="10" + left="8" name="buy_btn" - top="114" - width="75" /> + top="119" + width="80" /> <button follows="top|left" - font="SansSerif" height="20" label="Pay" left_delta="0" name="pay_btn" top_delta="0" - width="75" /> + width="80" /> <button follows="top|left" - font="SansSerif" - height="23" + height="20" label="Take Copy" left_delta="0" name="take_free_copy_btn" top_delta="0" - width="75" /> + width="80" /> <button follows="top|left" - font="SansSerifSmall" height="20" label="Touch" left_delta="0" name="touch_btn" top_delta="0" - width="75" /> + width="80" /> <button follows="top|left" - font="SansSerif" - height="23" + height="20" label="Sit" left_delta="0" name="sit_btn" top_delta="0" - width="75" /> + width="80" /> <button follows="top|left" - font="SansSerifSmall" height="20" label="Open" left_delta="0" name="open_btn" top_delta="0" - width="75" /> + width="80" /> <icon name="secure_browsing" image_name="Lock" @@ -156,33 +151,28 @@ This is a really long description for an object being as how it is at least 80 c visible="false" width="18" height="18" - top_delta="2" + top_delta="0" tool_tip="Secure Browsing" - follows="left|top"/> - + follows="left|top" /> + <!-- non-overlapping buttons here --> - <menu_button - follows="top|left" - height="18" - image_disabled="OptionsMenu_Disabled" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" - menu_filename="menu_inspect_object_gear.xml" - name="gear_btn" - right="-10" - top_delta="5" - width="18" /> - <button + <button follows="top|left" - height="18" - image_disabled="ForwardArrow_Disabled" - image_selected="ForwardArrow_Press" - image_unselected="ForwardArrow_Off" + height="20" + label="More" layout="topleft" name="more_info_btn" - right="-5" - top="20" - left_delta="110" + left_delta="10" + top_delta="0" tab_stop="false" - width="18" /> + width="80" /> + <menu_button + follows="top|left" + height="20" + image_overlay="OptionsMenu_Off" + menu_filename="menu_inspect_object_gear.xml" + name="gear_btn" + right="-5" + top_delta="0" + width="35" /> </floater> diff --git a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml new file mode 100644 index 0000000000..7b52fecef7 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + height="50" + layout="topleft" + mouse_opaque="false" + name="profile_overflow_menu" + width="120"> + <menu_item_call + label="Pay" + layout="topleft" + name="pay"> + <menu_item_call.on_click + function="Profile.Pay" /> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index e98a6d57bb..181994a1bd 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2572,10 +2572,10 @@ name="Hover Glow Objects">
<menu_item_check.on_check
function="CheckControl"
- parameter="RenderHighlightEnable" />
+ parameter="RenderHoverGlowEnable" />
<menu_item_check.on_click
function="ToggleControl"
- parameter="RenderHighlightEnable" />
+ parameter="RenderHoverGlowEnable" />
</menu_item_check>
</menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 9fe03859bb..56cb54c975 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -581,9 +581,10 @@ Multiple faces are currently selected. If you continue this action, separate instances of media will be set on multiple faces of the object. To place the media on only one face, choose Select Texture and click on the desired face of that object then click Add. <usetemplate - name="okcancelignore" - notext="Cancel" - yestext="OK"/> + ignoretext="Media will be set on multiple selected faces" + name="okcancelignore" + notext="Cancel" + yestext="OK"/> </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml index 0246e21d25..a283cff5b3 100644 --- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml @@ -4,10 +4,9 @@ height="215" name="panel_im_control_panel" width="180"> - <avatar_list color="DkGray2" - follows="left|top|right|bottom" + follows="all" height="130" ignore_online_status="true" layout="topleft" @@ -18,11 +17,10 @@ show_profile_btn="false" show_speaking_indicator="false" top="10" - width="180"/> - + width="180" /> <panel background_visible="true" - bg_alpha_color="0.2 0.2 0.2 1" + bg_alpha_color="DkGray2" border="false" bottom="1" follows="left|bottom" @@ -32,32 +30,27 @@ name="panel_call_buttons" top_pad="0" width="180"> - <button bottom="10" height="20" label="Call" - left_delta="28" + left_delta="40" name="call_btn" - width="125"/> - + width="100" /> <button bottom="40" height="20" label="Leave Call" name="end_call_btn" visible="false" - width="125"/> - + width="100" /> <button enabled="false" bottom="10" height="20" - label="Open Voice Controls" + label="Voice Controls" name="voice_ctrls_btn" visible="false" - width="125"/> - + width="100" /> </panel> - </panel> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml index 16c8660781..b779b08a63 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml @@ -4,66 +4,63 @@ top="10" width="250" height="100" - background_opaque="false" - background_visible="true" - follows="left|top|bottom|right" - bg_alpha_color="0.3 0.3 0.3 1.0"> - <panel - width="250" - height="30" - background_visible="true" - background_opaque="false" + follows="all"> + <panel + width="240" + height="24" + left="5" + background_visible="true" + background_opaque="false" follows="left|top|right" - bg_alpha_color="0.0 0.0 0.0 1.0" + top="-5" + bg_alpha_color="black" name="msg_caption"> - <avatar_icon - top="-7" - left="10" - width="20" - height="20" + <avatar_icon + top="-3" + left="3" + width="18" + image_name="Generic_Person" + height="18" follows="left|top" - color="1 1 1 1" - enabled="true" - name="avatar_tag_icon"/> + enabled="true" + name="avatar_tag_icon" /> <text - width="160" - top="-10" - left="40" - height="20" + width="160" + top="-8" + left="30" + height="20" follows="left|right|top" - font="SansSerifBigBold" - text_color="white" + font.style="BOLD" + text_color="white" word_wrap="true" - mouse_opaque="true" - name="sender_tag_name" > + mouse_opaque="true" + name="sender_tag_name"> Angela Tester </text> - <text - width="30" - top="-12" - left="210" - height="20" - follows="right|top" - text_color="white" - word_wrap="true" - mouse_opaque="true" - name="tag_time" > - 07:52 - </text> + <text + font="SansSerifSmall" + follows="right" + height="13" + layout="topleft" + halign="right" + right="-5" + name="tag_time" + top="8" + value="23:30" + width="50" /> </panel> - <text_editor - top="65" - left="10" - right="-10" - height="100" - follows="left|top|bottom|right" - font="SansSerifSmall" + <text_editor + bg_readonly_color="DkGray" + font="SansSerifSmall" + top="65" + left="5" + right="-5" + height="100" + follows="all" read_only="true" - bg_readonly_color="0 0 0 0" word_wrap="true" - mouse_opaque="true" - name="msg_text" > + mouse_opaque="true" + name="msg_text"> The quick brown fox jumps over the lazy dog. </text_editor> </panel> - diff --git a/indra/newview/skins/default/xui/en/panel_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml index 64519b2571..323ee957e7 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_header.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml @@ -1,44 +1,46 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - background_visible="true" - bevel_style="in" - bg_alpha_color="black" - follows="left|top|right" - height="20" + background_visible="true" + bevel_style="in" + bg_alpha_color="black" + follows="top" + height="24" label="im_header" layout="topleft" - name="im_header" > - <avatar_icon - follows="left" - height="16" - image_name="icon_avatar_online.tga" - layout="topleft" - left="2" - mouse_opaque="true" - name="avatar_icon" - top="2" - width="16" /> + name="im_header" + width="300"> + <avatar_icon + follows="left" + height="18" + image_name="Generic_Person" + layout="topleft" + left="3" + mouse_opaque="true" + name="avatar_icon" + top="3" + width="18" /> <text follows="left|right" - font="SansSerifBigBold" - height="20" - layout="topleft" - left_pad="6" + font.style="BOLD" + height="12" + layout="topleft" + left_pad="5" right="-50" name="user_name" text_color="white" - top="3" - value="Darth Vader" - use_ellipses="true" /> + top="8" + use_ellipses="true" + value="Erica Vader" /> <text - follows="right" - font="SansSerifBig" - height="20" - layout="topleft" + font="SansSerifSmall" + follows="right" + halign="right" + height="13" + layout="topleft" + left_pad="5" name="time_box" - right="0" - text_color="white" - top="3" - value="23:30" - width="50" /> + right="-10" + top="8" + value="23:30" + width="50" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml index 05b04bbf8e..01917052d1 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_item.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml @@ -1,38 +1,71 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- All our XML is utf-8 encoded. --> - <panel name="instant_message" width="300" height="180" - background_opaque="true" - background_visible="false" - follows="left|top|right|bottom" - bg_alpha_color="0.3 0.3 0.3 0"> - <panel width="250" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="msg_caption"> - <avatar_icon - top="25" left="10" width="20" height="20" follows="left|top" - color="1 1 1 1" enabled="true" name="avatar_icon" - /> + follows="all"> + <panel + width="290" + height="24" + background_visible="true" + background_opaque="false" + bg_alpha_color="Black" + left="5" + name="msg_caption"> + <avatar_icon + follows="left" + height="18" + image_name="Generic_Person" + layout="topleft" + left="3" + mouse_opaque="true" + name="avatar_icon" + top="3" + width="18" /> <text - width="130" top="25" left="40" height="20" follows="left|right|top" - font="SansSerifBigBold" text_color="white" word_wrap="false" use_ellipses="true" - mouse_opaque="true" name="sender_name" > + font.style="BOLD" + height="12" + layout="topleft" + left_pad="5" + top="7" + text_color="white" + word_wrap="false" + use_ellipses="true" + mouse_opaque="true" + name="sender_name" + width="175"> Jerry Knight </text> - <icon top="22" left="170" width="15" height="15" follows="top|right" - image_name="icn_voice-pvtfocus.tga" visible="false" name="msg_inspector"/> - <icon top="22" left="190" width="10" height="10" follows="top|right" - image_name="speaking_indicator.tga" name="msg_icon"/> - <text width="35" top="22" left="205" height="20" follows="right|top" - text_color="white" word_wrap="true" mouse_opaque="true" name="msg_time" > - 10:32 - </text> + <!-- <icon top="22" left="170" width="15" height="15" follows="top|right" + image_name="icn_voice-pvtfocus.tga" visible="false" name="msg_inspector" />--> + <!--<icon top="22" left="190" width="10" height="10" follows="top|right" + image_name="speaking_indicator.tga" name="msg_icon"/>--> + <text + font="SansSerifSmall" + follows="right|top" + halign="right" + height="13" + layout="topleft" + right="-10" + left="205" + mouse_opaque="true" + name="msg_time" + top="8" + value="23:30" + width="50" + word_wrap="true" /> </panel> <text_chat - top="-35" left="10" right="-10" height="120" follows="left|right|bottom" - font="SansSerifSmall" text_color="white" word_wrap="true" - mouse_opaque="true" name="msg_text" > + top="-35" + left="10" + right="-10" + height="120" + follows="left|right|bottom" + text_color="white" + word_wrap="true" + mouse_opaque="true" + name="msg_text"> + To be or not to be, that is the question. Tis a far far better thing I do than I have ever done. Tis a far far better place I go, than I have ever been. </text_chat> </panel> - diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml index e81532ec3e..9573904c93 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -1,101 +1,86 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="false" - height="350" + height="300" name="panel_im_control_panel" - width="131"> - + width="110"> <avatar_icon follows="left|top" - height="125" - left_delta="3" + height="100" + left_delta="5" name="avatar_icon" - top="-10" - width="125"/> - + top="-5" + width="100"/> <text follows="top|left|right" - font="SansSerifBig" - height="16" + font="SansSerifLarge" + height="22" layout="topleft" name="avatar_name" use_ellipses="true" value="Unknown" - width="125" /> - + width="100" /> <button - follows="left|bottom" + follows="left|top" height="20" - label="View Profile" + label="Profile" name="view_profile_btn" - width="125"/> - + width="100" /> <button - follows="left|bottom" + follows="left|top" height="20" label="Add Friend" name="add_friend_btn" - width="125"/> - + width="100" /> <button - follows="left|bottom" + follows="left|top" height="20" label="Teleport" name="teleport_btn" - width="125"/> - + width="100" /> <button - follows="left|bottom" + follows="left|top" height="20" label="Share" name="share_btn" - width="125"/> - + width="100" /> <button - follows="left|bottom" + follows="left|top" height="20" label="Pay" name="pay_btn" - width="125"/> - + width="100" /> <panel background_visible="true" - bg_alpha_color="0.2 0.2 0.2 1" + bg_alpha_color="DkGray2" border="false" - bottom="1" - follows="left|bottom" + follows="left|top" height="70" left="0" left_pad="0" name="panel_call_buttons" - top_pad="0" - width="131"> - + width="110"> <button bottom="10" height="20" label="Call" - left_delta="3" + left_delta="5" name="call_btn" - width="125"/> - + width="100" /> <button - bottom="40" + bottom="35" height="20" label="Leave Call" name="end_call_btn" visible="false" - width="125"/> - + width="100" /> <button enabled="false" bottom="10" height="20" - label="Open Voice Controls" + label="Voice Controls" name="voice_ctrls_btn" visible="false" - width="125"/> - + width="100" /> </panel> - </panel> diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml index be56866119..1e570bf207 100644 --- a/indra/newview/skins/default/xui/en/panel_instant_message.xml +++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel background_visible="true" - bg_alpha_color="0.3 0.3 0.3 0" height="175" label="im_panel" layout="topleft" @@ -18,7 +17,7 @@ bevel_style="in" bg_alpha_color="black" follows="top" - height="20" + height="24" label="im_header" layout="topleft" left="5" @@ -27,52 +26,53 @@ width="295"> <avatar_icon follows="right" - height="20" - image_name="icon_avatar_online.tga" + height="18" + image_name="Generic_Person" layout="topleft" - left="0" + left="3" mouse_opaque="true" name="avatar_icon" - top="0" - width="20" /> - <icon + top="3" + width="18" /> + <!--<icon follows="right" height="20" - image_name="icon_top_pick.tga" + image_name="" layout="topleft" - left="0" + left="3" mouse_opaque="true" name="sys_msg_icon" top="0" - width="20" /> + width="20" />--> <text follows="left|right" - font="SansSerifBold" - height="20" + font.style="BOLD" + height="12" layout="topleft" left_pad="5" name="user_name" text_color="white" - top="5" - value="Darth Vader" - width="295" /> + top="8" + use_ellipses="true" + value="Erica Vader" + width="212" /> <!-- TIME STAMP --> <text + font="SansSerifSmall" follows="right" - font="SansSerif" - height="20" + height="13" layout="topleft" halign="right" - left="245" + right="-5" name="time_box" - text_color="white" - top="5" + top="8" value="23:30" width="50" /> </panel> <text - follows="left|top|bottom|right" - height="86" + font="SansSerifSmall" + follows="all" + height="97" layout="topleft" left="10" name="message" @@ -85,12 +85,11 @@ max_length="350" /> <button follows="bottom" - font="SansSerifBold" - height="25" + height="23" label="Reply" layout="topleft" - left="97" + left="100" name="reply" - top="137" - width="110" /> + top="144" + width="100" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index cb5ec15387..a9a02e8fc7 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -27,6 +27,7 @@ border_visible="false" bottom="600" follows="all" + hide_loading="true" left="0" name="login_html" start_url="" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 9fac7d34f7..a370b450e9 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -107,7 +107,10 @@ background_visible="true" name="add_friend_btn" top_delta="0" tool_tip="Add selected resident to your friends List" - width="18" /> + width="18"> + <commit_callback + function="People.addFriend" /> + </button> </panel> </panel> <panel @@ -325,7 +328,10 @@ background_visible="true" name="add_friend_btn" top_delta="0" tool_tip="Add selected resident to your friends List" - width="18" /> + width="18"> + <commit_callback + function="People.addFriend" /> + </button> </panel> </panel> </tab_container> diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 7ff227ecb6..023b1fc81d 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -12,24 +12,24 @@ follows="all" height="85" image_name="ListItem_Over" - right="-3" + right="-2" mouse_opaque="false" name="hovered_icon" top="1" scale_image="true" visible="false" - width="307"/> + width="308" /> <icon follows="all" height="85" image_name="ListItem_Select" - right="-3" + right="-2" mouse_opaque="false" name="selected_icon" top="1" scale_image="true" visible="false" - width="307"/> + width="308" /> <texture_picker allow_no_texture="true" border_enabled="true" @@ -47,36 +47,34 @@ width="90" /> <text follows="top|left|right" - font="SansSerifSmallBold" - height="16" + font="SansSerifSmall" + height="15" layout="topleft" left="110" name="picture_name" text_color="white" top="9" - use_ellipses="false" - width="197" + use_ellipses="true" + width="193" word_wrap="false" /> <expandable_text follows="top|left|right" font="SansSerifSmall" - height="40" + height="55" layout="topleft" - left="110" + left="103" name="picture_descr" - top_pad="3" + top_pad="0" width="178" word_wrap="true" /> - <button - follows="top|right" - height="16" - image_selected="BuyArrow_Press" - image_pressed="BuyArrow_Press" - image_unselected="BuyArrow_Press" + <button + follows="right" + height="20" + image_overlay="ForwardArrow_Off" layout="topleft" + left_pad="5" + right="-8" name="info_chevron" - right="-7" - tab_stop="false" - top="27" - width="16" /> + top_delta="15" + width="20" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index a6ca73d4b7..6bb937e3c6 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -66,11 +66,7 @@ label="Italiano (Italian) - Beta" name="Italian" value="it" /> - <combo_box.item - enabled="true" - label="Magyar (Hungarian) - Beta" - name="Hungarian" - value="hu" /> + <combo_box.item enabled="true" label="Nederlands (Dutch) - Beta" @@ -86,36 +82,16 @@ label="Portugués (Portuguese) - Beta" name="Portugese" value="pt" /> - <combo_box.item - enabled="true" - label="Русский (Russian) - Beta" - name="Russian" - value="ru" /> - <combo_box.item - enabled="true" - label="Türkçe (Turkish) - Beta" - name="Turkish" - value="tr" /> - <combo_box.item - enabled="true" - label="Українська (Ukrainian) - Beta" - name="Ukrainian" - value="uk" /> - <combo_box.item - enabled="true" - label="中文 (简体) (Chinese) - Beta" - name="Chinese" - value="zh" /> + + + + <combo_box.item enabled="true" label="日本語 (Japanese) - Beta" name="(Japanese)" value="ja" /> - <combo_box.item - enabled="true" - label="한국어 (Korean) - Beta" - name="(Korean)" - value="ko" /> + <combo_box.item enabled="true" label="Test Language" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 9b10edde33..eb00b9b79a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -16,81 +16,8 @@ height="12" layout="topleft" left="30" - name="WindowSizeLabel" - top="10" - width="300"> - Window size: - </text> - <check_box - control_name="WindowFullScreen" - height="16" - label="Use fullscreen" - layout="topleft" - left_delta="50" - name="windowed mode" - top_pad="4" - width="175"> - </check_box> - <combo_box - visiblity_control="WindowFullScreen" - allow_text_entry="false" - enabled="true" - layout="topleft" - height="18" - left_delta="220" - max_chars="20" - mouse_opaque="true" - name="windowsize combo" - top_delta="-1" - width="150"> - <combo_box.item - type="string" - length="1" - enabled="true" - name="640x480" - value="640 x 480" - label="640x480"/> - <combo_box.item - type="string" - length="1" - enabled="true" - name="800x600" - value="800 x 600" - label="800x600"/> - <combo_box.item - type="string" - length="1" - enabled="true" - name="720x480" - value="720 x 480" - label="720x480 (NTSC)"/> - <combo_box.item - type="string" - length="1" - enabled="true" - name="768x576" - value="768 x 576" - label="768x576 (PAL)"/> - <combo_box.item - type="string" - length="1" - enabled="true" - name="1024x768" - value="1024 x 768" - label="1024x768"/> - <combo_box.commit_callback - function="Pref.setControlFalse" - parameter="FullScreenAutoDetectAspectRatio" /> - </combo_box> - <text - type="string" - length="1" - follows="left|top" - height="12" - layout="topleft" - left="30" name="UI Size:" - top_pad="4" + top="10" width="300"> UI size: </text> @@ -101,7 +28,7 @@ follows="left|top" height="15" increment="0.025" - initial_value="1" + initial_valu="1" layout="topleft" left_delta="52" max_val="1.4" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 9cf0bd26d8..5cabae5fa0 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -169,12 +169,12 @@ decimal_digits="0" follows="left|top" height="15" - increment="10" - initial_value="50" + increment="16" + initial_value="512" layout="topleft" left_delta="150" - max_val="1000" - min_val="10" + max_val="1024" + min_val="32" name="cache_size" top_delta="-1" width="180" /> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index d454b9e5c8..8ef2cdfc37 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -350,7 +350,7 @@ border="false" follows="top|left" height="145" - label="DeviceSettings" + label="Device Settings" layout="topleft" left="0" name="device_settings_panel" diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index 70c5d7b823..98025e28db 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -77,10 +77,14 @@ width="22" top="4"> <button + image_overlay="Arrow_Left_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" auto_resize="false" height="22" - image_selected="media_btn_back.png" - image_unselected="media_btn_back.png" layout="topleft" tool_tip="Step back" width="22" @@ -96,37 +100,25 @@ user_resize="false" layout="topleft" top="10" - min_width="17" - width="17"> + min_width="22" + width="22"> <button + image_overlay="Arrow_Right_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" height="22" - image_selected="media_btn_forward.png" - image_unselected="media_btn_forward.png" layout="topleft" tool_tip="Step forward" top_delta="0" - min_width="17" - width="17"> + min_width="22" + width="22"> <button.commit_callback function="MediaCtrl.Forward" /> </button> </layout_panel> - <!-- - <panel - height="22" - layout="topleft" - auto_resize="false" - min_width="3" - width="3"> - <icon - height="22" - image_name="media_panel_divider.png" - layout="topleft" - top="0" - min_width="3" - width="3" /> - </panel> - --> <layout_panel name="home" auto_resize="false" @@ -136,11 +128,15 @@ min_width="22" width="22"> <button - height="22" - image_selected="media_btn_home.png" - image_unselected="media_btn_home.png" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_overlay="Home_Off" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" layout="topleft" tool_tip="Home page" + height="22" min_width="22" width="22"> <button.commit_callback @@ -155,10 +151,15 @@ top="2" min_width="22" width="22"> + <!-- The stop button here is temporary artwork --> <button + image_overlay="media_btn_stoploading.png" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" height="22" - image_selected="button_anim_stop.tga" - image_unselected="button_anim_stop.tga" layout="topleft" tool_tip="Stop media" min_width="22" @@ -167,22 +168,6 @@ function="MediaCtrl.Stop" /> </button> </layout_panel> - <!-- - <panel - height="22" - layout="topleft" - auto_resize="false" - min_width="3" - width="3"> - <icon - height="22" - image_name="media_panel_divider.png" - layout="topleft" - top="0" - min_width="3" - width="3" /> - </panel> - --> <layout_panel name="reload" auto_resize="false" @@ -193,8 +178,12 @@ width="22"> <button height="22" - image_selected="media_btn_reload.png" - image_unselected="media_btn_reload.png" + image_overlay="Refresh_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" layout="topleft" tool_tip="Reload" min_width="22" @@ -213,8 +202,12 @@ width="22"> <button height="22" - image_selected="media_btn_stoploading.png" - image_unselected="media_btn_stoploading.png" + image_overlay="StopReload_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" layout="topleft" tool_tip = "Stop loading" min_width="22" @@ -232,11 +225,15 @@ min_width="22" width="22"> <button - height="22" - image_selected="button_anim_play.tga" - image_unselected="button_anim_play.tga" + image_overlay="Play_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" layout="topleft" tool_tip = "Play media" + height="22" min_width="22" width="22"> <button.commit_callback @@ -252,10 +249,14 @@ min_width="22" width="22"> <button - height="22" - image_selected="button_anim_pause.tga" - image_unselected="button_anim_pause.tga" + image_overlay="Pause_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" layout="topleft" + height="22" tool_tip = "Pause media"> <button.commit_callback function="MediaCtrl.Pause" /> @@ -266,7 +267,7 @@ name="media_address" auto_resize="true" user_resize="false" - height="22" + height="24" follows="left|right|bottom" layout="topleft" width="190" @@ -313,7 +314,7 @@ function="MediaCtrl.CommitURL" /> name="media_whitelist_flag" follows="top|right" height="16" - image_name="smicon_warn.tga" + image_name="Flag" layout="topleft" tool_tip="White List enabled" min_width="16" @@ -327,7 +328,7 @@ function="MediaCtrl.CommitURL" /> <icon name="media_secure_lock_flag" height="16" - image_name="icon_lock.tga" + image_name="Lock2" layout="topleft" tool_tip="Secured Browsing" min_width="16" @@ -351,6 +352,7 @@ function="MediaCtrl.CommitURL" /> initial_value="0.5" layout="topleft" tool_tip="Movie play progress" + top="8" min_width="100" width="200"> <slider_bar.commit_callback @@ -362,43 +364,55 @@ function="MediaCtrl.CommitURL" /> auto_resize="false" user_resize="false" layout="topleft" - height="24" - min_width="24" - width="24"> + height="22" + min_width="22" + width="22"> + <!-- Note: this isn't quite right either...the mute button is not the --> + <!-- same as the others because it can't have the "image_overlay" be --> + <!-- two different images. --> <button + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + hover_glow_amount="0.15" name="media_volume_button" height="22" - image_selected="icn_speaker-muted_dark.tga" - image_unselected="icn_speaker_dark.tga" is_toggle="true" layout="topleft" scale_image="false" tool_tip="Mute This Media" - top_delta="22" - min_width="24" - width="24" > + top_delta="18" + min_width="22" + width="22" > <button.commit_callback function="MediaCtrl.ToggleMute" /> </button> </layout_panel> + <!-- We don't have a design yet for "volume", so this is a temporary --> + <!-- solution. See DEV-42827. --> <layout_panel name="volume_up" auto_resize="false" user_resize="false" layout="topleft" - min_width="20" + min_width="14" height="14" - width="20"> + width="14"> <button - top="-3" + image_overlay="media_btn_scrollup.png" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + top="-5" height="14" - image_selected="media_btn_scrollup.png" - image_unselected="media_btn_scrollup.png" layout="topleft" tool_tip="Volume up" scale_image="true" - min_width="20" - width="20" > + min_width="14" + width="14" > <button.commit_callback function="MediaCtrl.CommitVolumeUp" /> </button> @@ -408,27 +422,33 @@ function="MediaCtrl.CommitURL" /> auto_resize="false" user_resize="false" layout="topleft" - min_width="20" + min_width="14" height="14" - width="20"> + width="14"> <button - top="-5" - height="14" - image_selected="media_btn_scrolldown.png" - image_unselected="media_btn_scrolldown.png" + image_overlay="media_btn_scrolldown.png" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" layout="topleft" tool_tip="Volume down" scale_image="true" - min_width="20" - width="20"> + top="-5" + height="14" + min_width="14" + width="14"> <button.commit_callback function="MediaCtrl.CommitVolumeDown" /> </button> </layout_panel> <!-- Scroll pad --> + <!-- This was removed from the design, but is still here because it is --> + <!-- complex, and recreating it would be hard. In case the design --> + <!-- changes, here it lies: --> <!-- - disabled - <layout_panel + <layout_panel name="media_panel_scroll" auto_resize="false" user_resize="false" @@ -437,64 +457,77 @@ function="MediaCtrl.CommitURL" /> layout="topleft" min_width="32" width="32"> - <icon - height="32" - image_name="media_panel_scrollbg.png" - layout="topleft" - top="0" - min_width="32" - width="32" /> - <button - name="scrollup" - height="8" - image_selected="media_btn_scrollup.png" - image_unselected="media_btn_scrollup.png" - layout="topleft" - tool_tip="Scroll up" - scale_image="false" - left="12" - top_delta="4" - min_width="8" - width="8" /> - <button - name="scrollleft" - height="8" - image_selected="media_btn_scrollleft.png" - image_unselected="media_btn_scrollleft.png" - layout="topleft" - left="3" - tool_tip="Scroll left" - scale_image="false" - top="12" - min_width="8" - width="8" /> - <button - name="scrollright" - height="8" - image_selected="media_btn_scrollright.png" - image_unselected="media_btn_scrollright.png" - layout="topleft" - left_pad="9" - tool_tip="Scroll right" - scale_image="false" - top_delta="0" - min_width="8" - width="8" /> - <button - name="scrolldown" - height="8" - image_selected="media_btn_scrolldown.png" - image_unselected="media_btn_scrolldown.png" - layout="topleft" - left="12" - tool_tip="Scroll down" - scale_image="false" - top="20" - min_width="8" - width="8" /> - </layout_panel> - disabled + <icon + height="32" + image_name="media_panel_scrollbg.png" + layout="topleft" + top="0" + min_width="32" + width="32" /> + <button + name="scrollup" + height="8" + image_selected="media_btn_scrollup.png" + image_unselected="media_btn_scrollup.png" + layout="topleft" + tool_tip="Scroll up" + scale_image="false" + left="12" + top_delta="4" + min_width="8" + width="8" /> + <button + name="scrollleft" + height="8" + image_selected="media_btn_scrollleft.png" + image_unselected="media_btn_scrollleft.png" + layout="topleft" + left="3" + tool_tip="Scroll left" + scale_image="false" + top="12" + min_width="8" + width="8" /> + <button + name="scrollright" + height="8" + image_selected="media_btn_scrollright.png" + image_unselected="media_btn_scrollright.png" + layout="topleft" + left_pad="9" + tool_tip="Scroll right" + scale_image="false" + top_delta="0" + min_width="8" + width="8" /> + <button + name="scrolldown" + height="8" + image_selected="media_btn_scrolldown.png" + image_unselected="media_btn_scrolldown.png" + layout="topleft" + left="12" + tool_tip="Scroll down" + scale_image="false" + top="20" + min_width="8" + width="8" /> + </layout_panel> --> + <panel + height="28" + layout="topleft" + auto_resize="false" + min_width="3" + width="3"> + <icon + height="26" + image_name="media_panel_divider.png" + layout="topleft" + top="0" + min_width="3" + width="3" /> + </panel> <layout_panel name="zoom_frame" auto_resize="false" @@ -504,9 +537,13 @@ function="MediaCtrl.CommitURL" /> min_width="22" width="22"> <button + image_overlay="Zoom_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" height="22" - image_selected="media_btn_optimalzoom.png" - image_unselected="media_btn_optimalzoom.png" layout="topleft" tool_tip="Zoom into media" min_width="22" @@ -522,10 +559,15 @@ function="MediaCtrl.CommitURL" /> layout="topleft" min_width="21" width="21" > + <!-- There is no "Zoom out" icon, so we use this temporarily --> <button + image_overlay="ForwardArrow_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" height="22" - image_selected="media_btn_done.png" - image_unselected="media_btn_done.png" layout="topleft" tool_tip ="Zoom Back" top_delta="-4" @@ -534,22 +576,6 @@ function="MediaCtrl.CommitURL" /> function="MediaCtrl.Close" /> </button> </layout_panel> - <!-- - <panel - height="22" - layout="topleft" - auto_resize="false" - min_width="3" - width="3"> - <icon - height="22" - image_name="media_panel_divider.png" - layout="topleft" - top="0" - min_width="3" - width="3" /> - </panel> - --> <layout_panel name="new_window" auto_resize="false" @@ -558,34 +584,22 @@ function="MediaCtrl.CommitURL" /> min_width="22" width="22"> <button + image_overlay="ExternalBrowser_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" height="22" - image_selected="media_btn_newwindow.png" - image_unselected="media_btn_newwindow.png" layout="topleft" tool_tip = "Open URL in browser" - top_delta="-3" + top_delta="-4" min_width="24" width="24" > <button.commit_callback function="MediaCtrl.Open" /> </button> </layout_panel> - <!-- - <panel - height="22" - layout="topleft" - auto_resize="false" - min_width="3" - width="3"> - <icon - height="22" - image_name="media_panel_divider.png" - layout="topleft" - top="0" - min_width="3" - width="3" /> - </panel> - --> <!-- bookend panel --> <layout_panel name="right_bookend" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 0f5e96416d..5110b6b2ef 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -283,7 +283,7 @@ mouse_opaque="false" name="add_friend" top="5" - width="75" /> + width="76" /> <button follows="bottom|left" height="19" @@ -292,7 +292,7 @@ name="im" top="5" left_pad="5" - width="45" /> + width="31" /> <button follows="bottom|left" height="19" @@ -301,7 +301,7 @@ name="call" left_pad="5" top="5" - width="45" /> + width="40" /> <button enabled="false" follows="bottom|left" @@ -311,7 +311,7 @@ name="show_on_map_btn" top="5" left_pad="5" - width="45" /> + width="42" /> <button follows="bottom|left" height="19" @@ -320,7 +320,17 @@ name="teleport" left_pad="5" top="5" - width="80" /> + width="64" /> + <button + follows="bottom|right" + font="SansSerifSmall" + height="19" + label="▼" + layout="topleft" + name="overflow_btn" + right="-1" + top="5" + width="21" /> </panel> <panel follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index d87211d432..2ce156cfda 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -11,7 +11,7 @@ width="333"> <string name="looks_tab_title" - value="Looks" /> + value="Outfits" /> <panel left="5" width="320" height="55" background_visible="true" @@ -23,13 +23,13 @@ top="-5" width="200" left="5" height="10" follows="left|right|top" font="SansSerif" text_color="LtGray" word_wrap="true" mouse_opaque="false" name="currentlook_title"> - Current Look + Current Outfit </text> <text top="-30" left="8" height="10" follows="left|right|top" font="SansSerifBold" text_color="white" word_wrap="true" mouse_opaque="false" name="currentlook_name" > - MyLook + MyOutfit </text> <button follows="left|right|top" @@ -74,7 +74,7 @@ follows="bottom|left" font="SansSerifSmallBold" height="25" - label="New Look" + label="New Outfit" layout="topleft" left_pad="0" name="newlook_btn" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 761c17cfd2..a5272d1883 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1747,10 +1747,10 @@ Clears (deletes) the media and all params from the given face. </string> <!-- Avatar busy/away mode --> - <string name="AvatarSetNotAway">Set Not Away</string> - <string name="AvatarSetAway">Set Away</string> - <string name="AvatarSetNotBusy">Set Not Busy</string> - <string name="AvatarSetBusy">Set Busy</string> + <string name="AvatarSetNotAway">Not Away</string> + <string name="AvatarSetAway">Away</string> + <string name="AvatarSetNotBusy">Not Busy</string> + <string name="AvatarSetBusy">Busy</string> <!-- Wearable Types --> <string name="shape">Shape</string> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index 5bb48ef5aa..6b11e72247 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- Additional attributes: + image_pressed + image_pressed_selected + --> <button image_unselected="PushButton_Off" image_selected="PushButton_Selected" image_disabled_selected="PushButton_Selected_Disabled" diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml index fa3cb9275e..132bd24bca 100644 --- a/indra/newview/skins/default/xui/en/widgets/combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml @@ -16,7 +16,9 @@ scale_image="true" pad_right="24" image_unselected="DropDown_Off" - image_selected="DropDown_Selected" + image_selected="DropDown_On" + image_pressed="DropDown_Press" + image_pressed_selected="DropDown_Press" image_disabled="DropDown_Disabled" /> <combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" background_visible="true" diff --git a/indra/newview/skins/default/xui/en/widgets/inspector.xml b/indra/newview/skins/default/xui/en/widgets/inspector.xml index 61950d7554..8ec206023e 100644 --- a/indra/newview/skins/default/xui/en/widgets/inspector.xml +++ b/indra/newview/skins/default/xui/en/widgets/inspector.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <!-- See also settings.xml UIFloater* settings for configuration --> <inspector name="inspector" - bg_opaque_color="ToolTipBgColor" + bg_opaque_color="DkGray_66" background_visible="true" bg_opaque_image="none" + background_opaque="true" bg_alpha_image="none" + text_color="InspectorTipTextColor" /> diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml b/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml index 0794b49a0c..f936a1e208 100644 --- a/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml +++ b/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml @@ -1,9 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<scroll_column_header image_unselected="square_btn_32x128.tga" - image_selected="square_btn_selected_32x128.tga" - image_disabled="square_btn_32x128.tga" - image_disabled_selected="square_btn_selected_32x128.tga" - image_overlay="combobox_arrow.tga" +<scroll_column_header + image_unselected="SegmentedBtn_Middle_Selected" + image_selected="SegmentedBtn_Middle_Selected" + image_pressed="SegmentedBtn_Middle_Selected_Press" + image_disabled="SegmentedBtn_Middle_Disabled" + image_disabled_selected="SegmentedBtn_Middle_Selected_Disabled" + image_overlay="DisclosureArrow_Opened_Off" image_overlay_alignment="right" halign="left" - scale_image="true"/> + scale_image="true" /> diff --git a/indra/newview/skins/default/xui/en/widgets/tool_tip.xml b/indra/newview/skins/default/xui/en/widgets/tool_tip.xml index 6b49f832fd..a19201f7c3 100644 --- a/indra/newview/skins/default/xui/en/widgets/tool_tip.xml +++ b/indra/newview/skins/default/xui/en/widgets/tool_tip.xml @@ -5,6 +5,8 @@ padding="4" wrap="true" font="SansSerif" - bg_opaque_color="ToolTipBgColor" + bg_opaque_image="Tooltip" + background_opaque="true" background_visible="true" + text_color="ToolTipTextColor" /> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 7e5c30a978..64cfdf2704 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -221,10 +221,12 @@ class WindowsManifest(ViewerManifest): def construct(self): super(WindowsManifest, self).construct() + + self.enable_crt_manifest_check() + # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) - self.enable_crt_manifest_check() # Plugin host application self.path(os.path.join(os.pardir, diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index d987915bb8..27cb52a507 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -197,7 +197,7 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind { LLError::initForApplication("."); LLError::setDefaultLevel(LLError::LEVEL_INFO); -// LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); + //LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); } // lots of randomness in this app @@ -223,7 +223,6 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind resetView(); // initial media panel - const int num_initial_panels = 1; for( int i = 0; i < num_initial_panels; ++i ) { @@ -1460,6 +1459,9 @@ std::string LLMediaPluginTest::mimeTypeFromUrl( std::string& url ) if ( url.find( ".txt" ) != std::string::npos ) // Apple Text descriptors mime_type = "video/quicktime"; else + if ( url.find( ".mp3" ) != std::string::npos ) // Apple Text descriptors + mime_type = "video/quicktime"; + else if ( url.find( "example://" ) != std::string::npos ) // Example plugin mime_type = "example/example"; diff --git a/install.xml b/install.xml index ff9fa80500..1df8fd09f4 100644 --- a/install.xml +++ b/install.xml @@ -132,9 +132,9 @@ <key>windows</key> <map> <key>md5sum</key> - <string>70b51d0cc93c305026e4e2778cde6d19</string> + <string>f5cf8d121b26f2e7944f7e63cdbff04d</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ares-1.6.0-windows-20090722.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ares-1.6.0-windows-20091105.tar.bz2</uri> </map> </map> </map> @@ -254,9 +254,9 @@ <key>windows</key> <map> <key>md5sum</key> - <string>8dc4e818c2d6fbde76e9a5e34f4ffa72</string> + <string>53e5ab7affff7121a5af2f82b4d58b54</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/curl-7.19.6-windows-20090917b.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/curl-7.19.6-windows-20091016.tar.bz2</uri> </map> </map> </map> @@ -955,9 +955,9 @@ anguage Infrstructure (CLI) international standard</string> <key>linux</key> <map> <key>md5sum</key> - <string>0d8aab394b4dc00aae44b4ada50c2d9f</string> + <string>ffede2775355676096b1085cbb9d0da7</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20091027.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20091117.tar.bz2</uri> </map> <key>windows</key> <map> |