Merge with Tip

master
callum 2009-12-14 14:10:16 -08:00
commit 180daf3ab8
212 changed files with 4531 additions and 2549 deletions

View File

@ -92,7 +92,7 @@ const U32 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23);
const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26);
const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27);
// const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27); // We no longer support ELAR
const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);

View File

@ -63,14 +63,15 @@ LLPluginClassMedia::~LLPluginClassMedia()
reset();
}
bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug)
bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path)
{
LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
LL_DEBUGS("Plugin") << "user_data_path: " << user_data_path << LL_ENDL;
mPlugin = new LLPluginProcessParent(this);
mPlugin->setSleepTime(mSleepTime);
mPlugin->init(launcher_filename, plugin_filename, debug);
mPlugin->init(launcher_filename, plugin_filename, debug, user_data_path);
return true;
}

View File

@ -49,7 +49,7 @@ public:
virtual ~LLPluginClassMedia();
// local initialization, called by the media manager when creating a source
virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug = false);
virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path);
// undoes everything init() didm called by the media manager when destroying a source
virtual void reset();

View File

@ -145,8 +145,12 @@ void LLPluginProcessChild::idle(void)
break;
case STATE_PLUGIN_LOADED:
setState(STATE_PLUGIN_INITIALIZING);
sendMessageToPlugin(LLPluginMessage("base", "init"));
{
setState(STATE_PLUGIN_INITIALIZING);
LLPluginMessage message("base", "init");
message.setValue("user_data_path", mUserDataPath);
sendMessageToPlugin(message);
}
break;
case STATE_PLUGIN_INITIALIZING:
@ -310,6 +314,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
if(message_name == "load_plugin")
{
mPluginFile = parsed.getValue("file");
mUserDataPath = parsed.getValue("user_data_path");
}
else if(message_name == "shm_add")
{

View File

@ -96,6 +96,8 @@ private:
LLSocket::ptr_t mSocket;
std::string mPluginFile;
std::string mUserDataPath;
LLPluginInstance *mInstance;

View File

@ -79,8 +79,10 @@ LLPluginProcessParent::~LLPluginProcessParent()
// and remove it from our map
mSharedMemoryRegions.erase(iter);
}
mProcess.kill();
// orphaning the process means it won't be killed when the LLProcessLauncher is destructed.
// This is what we want -- it should exit cleanly once it notices the sockets have been closed.
mProcess.orphan();
killSockets();
}
@ -99,12 +101,13 @@ void LLPluginProcessParent::errorState(void)
setState(STATE_ERROR);
}
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug)
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path)
{
mProcess.setExecutable(launcher_filename);
mPluginFile = plugin_filename;
mCPUUsage = 0.0f;
mDebug = debug;
mUserDataPath = user_data_path;
setState(STATE_INITIALIZED);
}
@ -362,6 +365,7 @@ void LLPluginProcessParent::idle(void)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin");
message.setValue("file", mPluginFile);
message.setValue("user_data_path", mUserDataPath);
sendMessage(message);
}
@ -412,7 +416,8 @@ void LLPluginProcessParent::idle(void)
break;
case STATE_CLEANUP:
mProcess.kill();
// Don't do a kill here anymore -- closing the sockets is the new 'kill'.
mProcess.orphan();
killSockets();
setState(STATE_DONE);
break;

View File

@ -58,7 +58,7 @@ public:
LLPluginProcessParent(LLPluginProcessParentOwner *owner);
~LLPluginProcessParent();
void init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug = false);
void init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path);
void idle(void);
// returns true if the plugin is on its way to steady state
@ -139,6 +139,8 @@ private:
std::string mPluginFile;
std::string mUserDataPath;
LLPluginProcessParentOwner *mOwner;
typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;

View File

@ -83,6 +83,8 @@ public:
virtual void onDockHidden();
virtual void onDockShown();
LLDockControl* getDockControl();
private:
/**
* Provides unique of dockable floater.
@ -92,7 +94,6 @@ private:
protected:
void setDockControl(LLDockControl* dockControl);
LLDockControl* getDockControl();
const LLUIImagePtr& getDockTongue();
private:

View File

@ -76,6 +76,9 @@ public:
// gets a rect that bounds possible positions for a dockable control (EXT-1111)
void getAllowedRect(LLRect& rect);
S32 getTongueWidth() { return mDockTongue->getWidth(); }
S32 getTongueHeight() { return mDockTongue->getHeight(); }
private:
virtual void moveDockable();
private:

View File

@ -891,7 +891,13 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const
// We have to update child rect here because of issues with rect after reshaping while creating LLTextbox
// It is possible to have invalid LLRect if Flat List is in LLAccordionTab
LLRect comment_rect = getLocalRect();
comment_rect.stretch(-getBorderWidth());
// To see comment correctly (EXT - 3244) in mNoItemsCommentTextbox we must get border width
// of LLFlatListView (@see getBorderWidth()) and stretch mNoItemsCommentTextbox to this width
// But getBorderWidth() returns 0 if LLFlatListView not visible. So we have to get border width
// from 'scroll_border'
LLViewBorder* scroll_border = getChild<LLViewBorder>("scroll border");
comment_rect.stretch(-scroll_border->getBorderWidth());
mNoItemsCommentTextbox->setRect(comment_rect);
}
mNoItemsCommentTextbox->setVisible(visible);

View File

@ -42,6 +42,8 @@ class LLHelp
virtual std::string defaultTopic() = 0;
// return topic to use before the user logs in
virtual std::string preLoginTopic() = 0;
// return topic to use for the top-level help, invoked by F1
virtual std::string f1HelpTopic() = 0;
};
#endif // headerguard

View File

@ -761,7 +761,7 @@ void LLMenuItemCallGL::initFromParams(const Params& p)
{
if (p.on_visible.isProvided())
{
mVisibleSignal.connect(initVisibleCallback(p.on_visible));
mVisibleSignal.connect(initEnableCallback(p.on_visible));
}
if (p.on_enable.isProvided())
{

View File

@ -175,9 +175,7 @@ protected:
// This function appends the character string representation of
// the current accelerator key and mask to the provided string.
void appendAcceleratorString( std::string& st ) const;
void initMenuEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig);
protected:
KEY mAcceleratorKey;
MASK mAcceleratorMask;
@ -249,7 +247,7 @@ public:
{
Optional<EnableCallbackParam > on_enable;
Optional<CommitCallbackParam > on_click;
Optional<VisibleCallbackParam > on_visible;
Optional<EnableCallbackParam > on_visible;
Params()
: on_enable("on_enable"),
on_click("on_click"),
@ -284,15 +282,10 @@ public:
{
return mEnableSignal.connect(cb);
}
boost::signals2::connection setVisibleCallback( const visible_signal_t::slot_type& cb )
{
return mVisibleSignal.connect(cb);
}
private:
enable_signal_t mEnableSignal;
visible_signal_t mVisibleSignal;
enable_signal_t mVisibleSignal;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -249,7 +249,6 @@ protected:
LLCallbackMap::map_t mFactoryMap;
CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar;
EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
VisibleCallbackRegistry::ScopedRegistrar mVisibleCallbackRegistrar;
commit_signal_t* mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()

View File

@ -2080,6 +2080,8 @@ void LLTextBase::updateRects()
}
mContentsRect.mTop += mVPad;
// subtract a pixel off the bottom to deal with rounding errors in measuring font height
mContentsRect.mBottom -= 1;
S32 delta_pos = -mContentsRect.mBottom;
// move line segments to fit new document rect

View File

@ -1887,9 +1887,10 @@ void LLTextEditor::doDelete()
removeChar();
}
onKeyStroke();
}
onKeyStroke();
needsReflow();
}

View File

@ -232,11 +232,6 @@ bool default_enable_handler(LLUICtrl* ctrl, const LLSD& param)
return true;
}
bool default_visible_handler(LLUICtrl* ctrl, const LLSD& param)
{
return true;
}
LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCallbackParam& cb)
{
@ -290,30 +285,6 @@ LLUICtrl::enable_signal_t::slot_type LLUICtrl::initEnableCallback(const EnableCa
return default_enable_handler;
}
LLUICtrl::visible_signal_t::slot_type LLUICtrl::initVisibleCallback(const VisibleCallbackParam& cb)
{
// Set the callback function
if (cb.function.isProvided())
{
if (cb.parameter.isProvided())
return boost::bind(cb.function(), this, cb.parameter);
else
return cb.function();
}
else
{
visible_callback_t* func = (VisibleCallbackRegistry::getValue(cb.function_name));
if (func)
{
if (cb.parameter.isProvided())
return boost::bind((*func), this, cb.parameter);
else
return visible_signal_t::slot_type(*func);
}
}
return default_visible_handler;
}
// virtual
void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask)
{

View File

@ -63,9 +63,6 @@ public:
typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> visible_callback_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> visible_signal_t;
struct CallbackParam : public LLInitParam::Block<CallbackParam>
{
Ignored name;
@ -83,16 +80,12 @@ public:
Optional<commit_callback_t> function;
};
// also used for visible callbacks
struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam >
{
Optional<enable_callback_t> function;
};
struct VisibleCallbackParam : public LLInitParam::Block<VisibleCallbackParam, CallbackParam >
{
Optional<visible_callback_t> function;
};
struct EnableControls : public LLInitParam::Choice<EnableControls>
{
Alternative<std::string> enabled;
@ -148,7 +141,6 @@ protected:
commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb);
enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb);
visible_signal_t::slot_type initVisibleCallback(const VisibleCallbackParam& cb);
// We need this virtual so we can override it with derived versions
virtual LLViewModel* getViewModel() const;
@ -269,10 +261,9 @@ public:
{};
class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{};
// the enable callback registry is also used for visiblity callbacks
class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{};
class VisibleCallbackRegistry : public CallbackRegistry<visible_callback_t, VisibleCallbackRegistry>{};
protected:
static bool controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type);

View File

@ -196,6 +196,31 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string)
return getUrlFromWikiLink(string);
}
//
// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
//
LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()
{
mPattern = boost::regex("(\\bwww\\.\\S+\\.\\S+|\\S+.com\\S*|\\S+.net\\S*|\\S+.edu\\S*|\\S+.org\\S*)",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_http.xml";
mTooltip = LLTrans::getString("TooltipHttpUrl");
}
std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
return unescapeUrl(url);
}
std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string)
{
if (string.find("://") == std::string::npos)
{
return "http://" + escapeUrl(string);
}
return escapeUrl(string);
}
//
// LLUrlEntrySLURL Describes generic http: and https: Urls
//

View File

@ -134,6 +134,17 @@ public:
/*virtual*/ std::string getUrl(const std::string &string);
};
///
/// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
///
class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase
{
public:
LLUrlEntryHTTPNoProtocol();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string);
};
///
/// LLUrlEntrySLURL Describes http://slurl.com/... Urls
///

View File

@ -58,6 +58,9 @@ LLUrlRegistry::LLUrlRegistry()
//so it should be registered in the end of list
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
// most common pattern is a URL without any protocol,
// e.g., "secondlife.com"
registerUrl(new LLUrlEntryHTTPNoProtocol());
}
LLUrlRegistry::~LLUrlRegistry()
@ -118,10 +121,23 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
return true;
}
static bool stringHasUrl(const std::string &text)
{
// fast heuristic test for a URL in a string. This is used
// to avoid lots of costly regex calls, BUT it needs to be
// kept in sync with the LLUrlEntry regexes we support.
return (text.find("://") != std::string::npos ||
text.find("www.") != std::string::npos ||
text.find(".com") != std::string::npos ||
text.find(".net") != std::string::npos ||
text.find(".edu") != std::string::npos ||
text.find(".org") != std::string::npos);
}
bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
{
// avoid costly regexes if there is clearly no URL in the text
if (text.find("://") == std::string::npos)
if (! stringHasUrl(text))
{
return false;
}

View File

@ -394,12 +394,6 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
prefix += "local_assets";
break;
case LL_PATH_MOZILLA_PROFILE:
prefix = getOSUserAppDir();
prefix += mDirDelimiter;
prefix += "browser_profile";
break;
case LL_PATH_EXECUTABLE:
prefix = getExecutableDir();
break;

View File

@ -38,7 +38,7 @@
#define MAX_PATH MAXPATHLEN
#endif
// these numbers *may* get serialized, so we need to be explicit
// these numbers *may* get serialized (really??), so we need to be explicit
typedef enum ELLPath
{
LL_PATH_NONE = 0,
@ -54,10 +54,8 @@ typedef enum ELLPath
LL_PATH_TOP_SKIN = 10,
LL_PATH_CHAT_LOGS = 11,
LL_PATH_PER_ACCOUNT_CHAT_LOGS = 12,
LL_PATH_MOZILLA_PROFILE = 13,
LL_PATH_USER_SKIN = 14,
LL_PATH_LOCAL_ASSETS = 15,
// LL_PATH_HTML = 16,
LL_PATH_EXECUTABLE = 16,
LL_PATH_DEFAULT_SKIN = 17,
LL_PATH_FONTS = 18,

View File

@ -225,15 +225,6 @@ void LLDir_Linux::initAppDirs(const std::string &app_name,
}
}
res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,""));
if (res == -1)
{
if (errno != EEXIST)
{
llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
}
}
mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
}

View File

@ -244,15 +244,6 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name,
}
}
res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,""));
if (res == -1)
{
if (errno != EEXIST)
{
llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
}
}
mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
}

View File

@ -212,14 +212,6 @@ void LLDir_Win32::initAppDirs(const std::string &app_name,
}
}
res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,""));
if (res == -1)
{
if (errno != EEXIST)
{
llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
}
}
res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SKIN,""));
if (res == -1)
{

View File

@ -35,6 +35,6 @@
#include "lscript_library.h"
extern LLScriptLibrary gScriptLibrary;
#endif

View File

@ -70,7 +70,7 @@ public:
std::vector<LLScriptLibraryFunction> mFunctions;
};
extern LLScriptLibrary gScriptLibrary;
class LLScriptLibData
{
@ -428,4 +428,6 @@ public:
};
extern LLScriptLibrary gScriptLibrary;
#endif

View File

@ -76,6 +76,8 @@ public:
private:
std::string mProfileDir;
enum
{
INIT_STATE_UNINITIALIZED, // Browser instance hasn't been set up yet
@ -187,7 +189,6 @@ private:
#else
std::string component_dir = application_dir;
#endif
std::string profileDir = application_dir + "/" + "browser_profile"; // cross platform?
// window handle - needed on Windows and must be app window.
#if LL_WINDOWS
@ -199,7 +200,7 @@ private:
#endif
// main browser initialization
bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, profileDir, native_window_handle );
bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle );
if ( result )
{
// create single browser window
@ -587,6 +588,9 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
{
if(message_name == "init")
{
std::string user_data_path = message_in.getValue("user_data_path"); // n.b. always has trailing platform-specific dir-delimiter
mProfileDir = user_data_path + "browser_profile";
LLPluginMessage message("base", "init_response");
LLSD versions = LLSD::emptyMap();
versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;

View File

@ -104,6 +104,7 @@ set(viewer_SOURCE_FILES
llclassifiedstatsresponder.cpp
llcloud.cpp
llcolorswatch.cpp
llcommanddispatcherlistener.cpp
llcommandhandler.cpp
llcommandlineparser.cpp
llcompilequeue.cpp
@ -324,6 +325,7 @@ set(viewer_SOURCE_FILES
llpanellandmarks.cpp
llpanellandmedia.cpp
llpanellogin.cpp
llpanelloginlistener.cpp
llpanellookinfo.cpp
llpanelmaininventory.cpp
llpanelmediasettingsgeneral.cpp
@ -444,6 +446,7 @@ set(viewer_SOURCE_FILES
lluploaddialog.cpp
llurl.cpp
llurldispatcher.cpp
llurldispatcherlistener.cpp
llurlhistory.cpp
llurllineeditorctrl.cpp
llurlsimstring.cpp
@ -611,6 +614,7 @@ set(viewer_HEADER_FILES
llclassifiedstatsresponder.h
llcloud.h
llcolorswatch.h
llcommanddispatcherlistener.h
llcommandhandler.h
llcommandlineparser.h
llcompilequeue.h
@ -826,6 +830,7 @@ set(viewer_HEADER_FILES
llpanellandmarks.h
llpanellandmedia.h
llpanellogin.h
llpanelloginlistener.h
llpanellookinfo.h
llpanelmaininventory.h
llpanelmediasettingsgeneral.h
@ -950,6 +955,7 @@ set(viewer_HEADER_FILES
lluploaddialog.h
llurl.h
llurldispatcher.h
llurldispatcherlistener.h
llurlhistory.h
llurllineeditorctrl.h
llurlsimstring.h

View File

@ -4974,7 +4974,6 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>StartUpToastLifeTime</key>
<key>NearbyToastFadingTime</key>
<map>
<key>Comment</key>
@ -5039,7 +5038,18 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>35</integer>
<integer>5</integer>
</map>
<key>NotificationChannelHeightRatio</key>
<map>
<key>Comment</key>
<string>Notification channel and World View ratio(0.0 - always show 1 notification, 1.0 - max ratio).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.5</real>
</map>
<key>OverflowToastHeight</key>
<map>
@ -9933,6 +9943,28 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>UseCircuitCodeMaxRetries</key>
<map>
<key>Comment</key>
<string>Max timeout count for the initial UseCircuitCode message</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>3</real>
</map>
<key>UseCircuitCodeTimeout</key>
<map>
<key>Comment</key>
<string>Timeout duration in seconds for the initial UseCircuitCode message</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5.0</real>
</map>
<key>UseDebugLogin</key>
<map>
<key>Comment</key>

View File

@ -9283,7 +9283,7 @@ render_pass="bump">
wearable="skin"
edit_group="skin_facedetail"
edit_group_order="3"
name="wrinkles"
name="Wrinkles"
label_min="Less"
label_max="More"
value_min="0"

View File

@ -574,29 +574,32 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
linkAll(cof, obj_items, link_waiter);
linkAll(cof, gest_items, link_waiter);
LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
// Add link to outfit if category is an outfit.
LLViewerInventoryCategory* catp = gInventory.getCategory(category);
if (!append && catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
if (!append)
{
link_inventory_item(gAgent.getID(), category, cof, catp->getName(),
LLAssetType::AT_LINK_FOLDER, link_waiter);
// Update the current outfit name of the appearance sidepanel.
if (panel_appearance)
std::string new_outfit_name = "";
if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
{
panel_appearance->refreshCurrentOutfitName(catp->getName());
}
}
else
{
if (panel_appearance)
{
panel_appearance->refreshCurrentOutfitName("");
link_inventory_item(gAgent.getID(), category, cof, catp->getName(),
LLAssetType::AT_LINK_FOLDER, link_waiter);
new_outfit_name = catp->getName();
}
updatePanelOutfitName(new_outfit_name);
}
}
void LLAppearanceManager::updatePanelOutfitName(const std::string& name)
{
LLSidepanelAppearance* panel_appearance =
dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
if (panel_appearance)
{
panel_appearance->refreshCurrentOutfitName(name);
}
}
void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, bool append)
{
lldebugs << "updateAgentWearables()" << llendl;

View File

@ -64,6 +64,9 @@ public:
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getCurrentOutfitLink();
// Update the displayed outfit name in UI.
void updatePanelOutfitName(const std::string& name);
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
// For debugging - could be moved elsewhere.

View File

@ -78,6 +78,8 @@
#include "lllocationhistory.h"
#include "llfasttimerview.h"
#include "llvoicechannel.h"
#include "llsidetray.h"
#include "llweb.h"
#include "llsecondlifeurls.h"
@ -2862,6 +2864,8 @@ void LLAppViewer::requestQuit()
gFloaterView->closeAllChildren(true);
}
LLSideTray::getInstance()->notifyChildren(LLSD().with("request","quit"));
send_stats();
gLogoutTimer.reset();
@ -3766,6 +3770,13 @@ void LLAppViewer::idleShutdown()
{
return;
}
if (LLSideTray::getInstance()->notifyChildren(LLSD().with("request","wait_quit")))
{
return;
}
// ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup()
// *TODO: ugly

View File

@ -62,9 +62,6 @@
#include "llimfloater.h"
#include "lltrans.h"
// callback connection to auto-call when the IM floater initializes
boost::signals2::connection gAdhocAutoCall;
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@ -250,8 +247,8 @@ void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids)
// always open IM window when connecting to voice
LLIMFloater::show(session_id);
// start the call once the floater has fully initialized
gAdhocAutoCall = LLIMModel::getInstance()->addSessionInitializedCallback(callbackAutoStartCall);
// start the call once the session has fully initialized
gIMMgr->autoStartCallOnStartup(session_id);
make_ui_sound("UISndStartIM");
}
@ -466,17 +463,6 @@ bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& re
return false;
}
// static
void LLAvatarActions::callbackAutoStartCall(const LLSD& data)
{
// start the adhoc voice call now the IM panel has initialized
LLUUID session_id = data["session_id"].asUUID();
gIMMgr->startCall(session_id);
// and deschedule this callback as its work is done now
gAdhocAutoCall.disconnect();
}
// static
void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
{

View File

@ -139,7 +139,6 @@ private:
static bool handleRemove(const LLSD& notification, const LLSD& response);
static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
static void callback_invite_to_group(LLUUID group_id, LLUUID id);
static void callbackAutoStartCall(const LLSD& data);
// Just request friendship, no dialog.
static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);

View File

@ -440,11 +440,17 @@ void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, E
// Copy the map (because observers may delete themselves when updated?)
LLAvatarPropertiesProcessor::observer_multimap_t observers = mObservers;
observer_multimap_t::iterator oi = observers.lower_bound(id);
observer_multimap_t::iterator end = observers.upper_bound(id);
observer_multimap_t::iterator oi = observers.begin();
observer_multimap_t::iterator end = observers.end();
for (; oi != end; ++oi)
{
oi->second->processProperties(data,type);
// only notify observers for the same agent, or if the observer
// didn't know the agent ID and passed a NULL id.
const LLUUID &agent_id = oi->first;
if (agent_id == id || agent_id.isNull())
{
oi->second->processProperties(data,type);
}
}
}

View File

@ -61,6 +61,7 @@ static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc");
static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
static const LLRect CHICLET_RECT(0, 25, 25, 0);
static const LLRect CHICLET_ICON_RECT(0, 22, 22, 0);
@ -78,29 +79,73 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/**
* Updates the Well's 'Lit' state to flash it when "new messages" are come.
*
* It gets callback which will be called 2*N times with passed period. See EXT-3147
*/
class LLSysWellChiclet::FlashToLitTimer : public LLEventTimer
{
public:
typedef boost::function<void()> callback_t;
FlashToLitTimer(S32 count, F32 period, callback_t cb)
: LLEventTimer(period)
, mCallback(cb)
, mFlashCount(2 * count)
, mCurrentFlashCount(0)
{
mEventTimer.stop();
}
BOOL tick()
{
mCallback();
if (++mCurrentFlashCount == mFlashCount) mEventTimer.stop();
return FALSE;
}
void flash()
{
mCurrentFlashCount = 0;
mEventTimer.start();
}
private:
callback_t mCallback;
S32 mFlashCount;
S32 mCurrentFlashCount;
};
LLSysWellChiclet::Params::Params()
: button("button")
, unread_notifications("unread_notifications")
, max_displayed_count("max_displayed_count", 9)
, flash_to_lit_count("flash_to_lit_count", 3)
, flash_period("flash_period", 0.5F)
{
button.name("button");
button.tab_stop(FALSE);
button.label(LLStringUtil::null);
}
LLSysWellChiclet::LLSysWellChiclet(const Params& p)
: LLChiclet(p)
, mButton(NULL)
, mCounter(0)
, mMaxDisplayedCount(p.max_displayed_count)
, mFlashToLitTimer(NULL)
{
LLButton::Params button_params = p.button;
mButton = LLUICtrlFactory::create<LLButton>(button_params);
addChild(mButton);
mFlashToLitTimer = new FlashToLitTimer(p.flash_to_lit_count, p.flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this));
}
LLSysWellChiclet::~LLSysWellChiclet()
{
delete mFlashToLitTimer;
}
void LLSysWellChiclet::setCounter(S32 counter)
@ -108,11 +153,30 @@ void LLSysWellChiclet::setCounter(S32 counter)
std::string s_count;
if(counter != 0)
{
s_count = llformat("%d", counter);
static std::string more_messages_exist("+");
std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
s_count = llformat("%d%s"
, llmin(counter, mMaxDisplayedCount)
, more_messages.c_str()
);
}
mButton->setLabel(s_count);
/*
Emulate 4 states of button by background images, see detains in EXT-3147
xml attribute Description
image_unselected "Unlit" - there are no new messages
image_selected "Unlit" + "Selected" - there are no new messages and the Well is open
image_pressed "Lit" - there are new messages
image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open
*/
mButton->setForcePressedState(counter > 0);
if (mCounter == 0 && counter > 0)
{
mFlashToLitTimer->flash();
}
mCounter = counter;
}
@ -126,6 +190,14 @@ void LLSysWellChiclet::setToggleState(BOOL toggled) {
mButton->setToggleState(toggled);
}
void LLSysWellChiclet::changeLitState()
{
static bool set_lit = false;
mButton->setForcePressedState(set_lit);
set_lit ^= true;
}
/************************************************************************/
/* LLIMWellChiclet implementation */
@ -939,12 +1011,34 @@ void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
}
}
void object_chiclet_callback(const LLSD& data)
{
LLUUID object_id = data["object_id"];
bool new_message = data["new_message"];
std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(object_id);
std::list<LLChiclet *>::iterator iter;
for (iter = chiclets.begin(); iter != chiclets.end(); iter++)
{
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*iter);
if (chiclet != NULL)
{
if(data.has("unread"))
{
chiclet->setCounter(data["unread"]);
}
chiclet->setShowNewMessagesIcon(new_message);
}
}
}
BOOL LLChicletPanel::postBuild()
{
LLPanel::postBuild();
LLIMModel::instance().addNewMsgCallback(boost::bind(im_chiclet_callback, this, _1));
LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(im_chiclet_callback, this, _1));
LLScriptFloaterManager::getInstance()->addNewObjectCallback(boost::bind(object_chiclet_callback, _1));
LLScriptFloaterManager::getInstance()->addToggleObjectFloaterCallback(boost::bind(object_chiclet_callback, _1));
LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet<LLChiclet>, this, _1));
LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLChicletPanel::onCurrentVoiceChannelChanged, this, _1));
@ -1545,6 +1639,11 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id)
}
}
void LLScriptChiclet::setCounter(S32 counter)
{
setShowNewMessagesIcon( counter > 0 );
}
void LLScriptChiclet::onMouseDown()
{
LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
@ -1601,6 +1700,11 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id)
}
}
void LLInvOfferChiclet::setCounter(S32 counter)
{
setShowNewMessagesIcon( counter > 0 );
}
void LLInvOfferChiclet::onMouseDown()
{
LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId());

View File

@ -315,7 +315,7 @@ public:
{
Optional<std::string> new_messages_icon_name;
Params() : new_messages_icon_name("new_messages_icon_name", "icn_voice-localchat.tga")
Params() : new_messages_icon_name("new_messages_icon_name", "Unread_IM")
{}
};
@ -389,7 +389,7 @@ public:
* Made public so that it can be triggered from outside
* (more specifically, from the Active IM window).
*/
void onMouseDown();
virtual void onMouseDown();
protected:
@ -594,7 +594,7 @@ public:
/*virtual*/ void setSessionId(const LLUUID& session_id);
/*virtual*/ void setCounter(S32 counter){}
/*virtual*/ void setCounter(S32 counter);
/*virtual*/ S32 getCounter() { return 0; }
@ -634,7 +634,7 @@ public:
/*virtual*/ void setSessionId(const LLUUID& session_id);
/*virtual*/ void setCounter(S32 counter){}
/*virtual*/ void setCounter(S32 counter);
/*virtual*/ S32 getCounter() { return 0; }
@ -745,7 +745,7 @@ private:
/**
* Implements notification chiclet. Used to display total amount of unread messages
* across all IM sessions, total amount of system notifications.
* across all IM sessions, total amount of system notifications. See EXT-3147 for details
*/
class LLSysWellChiclet : public LLChiclet
{
@ -757,6 +757,24 @@ public:
Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
/**
* Contains maximum displayed count of unread messages. Default value is 9.
*
* If count is less than "max_unread_count" will be displayed as is.
* Otherwise 9+ will be shown (for default value).
*/
Optional<S32> max_displayed_count;
/**
* How many time chiclet should flash before set "Lit" state. Default value is 3.
*/
Optional<S32> flash_to_lit_count;
/**
* Period of flashing while setting "Lit" state, in seconds. Default value is 0.5.
*/
Optional<F32> flash_period;
Params();
};
@ -778,9 +796,26 @@ protected:
LLSysWellChiclet(const Params& p);
friend class LLUICtrlFactory;
/**
* Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
*
* There is an assumption that it will be called 2*N times to do not change its start state.
* @see FlashToLitTimer
*/
void changeLitState();
protected:
class FlashToLitTimer;
LLButton* mButton;
S32 mCounter;
S32 mMaxDisplayedCount;
/**
* How many times Well will blink.
*/
S32 mFlashToLitCount;
FlashToLitTimer* mFlashToLitTimer;
};
/**

View File

@ -306,6 +306,21 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
}
}
// This is called when the main floatercustomize panel is closed.
// Since this class has pointers up to its parents, we need to cleanup
// this class first in order to avoid a crash.
void LLColorSwatchCtrl::onParentFloaterClosed()
{
LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
if (pickerp)
{
pickerp->setSwatch(NULL);
pickerp->closeFloater();
}
mPickerHandle.markDead();
}
void LLColorSwatchCtrl::setValid(BOOL valid )
{
mValid = valid;
@ -323,7 +338,7 @@ void LLColorSwatchCtrl::showPicker(BOOL take_focus)
if (!pickerp)
{
pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately);
gFloaterView->getParentFloater(this)->addDependentFloater(pickerp);
//gFloaterView->getParentFloater(this)->addDependentFloater(pickerp);
mPickerHandle = pickerp->getHandle();
}

View File

@ -105,6 +105,7 @@ public:
/*virtual*/ void setEnabled( BOOL enabled );
static void onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE );
void onParentFloaterClosed();
protected:
BOOL mValid;

View File

@ -0,0 +1,47 @@
/**
* @file llcommanddispatcherlistener.cpp
* @author Nat Goodspeed
* @date 2009-12-10
* @brief Implementation for llcommanddispatcherlistener.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
* Copyright (c) 2009, Linden Research, Inc.
* $/LicenseInfo$
*/
// Precompiled header
#include "llviewerprecompiledheaders.h"
// associated header
#include "llcommanddispatcherlistener.h"
// STL headers
// std headers
// external library headers
// other Linden headers
#include "llcommandhandler.h"
LLCommandDispatcherListener::LLCommandDispatcherListener(/* LLCommandDispatcher* instance */):
LLEventAPI("LLCommandDispatcher", "Access to LLCommandHandler commands") /* ,
mDispatcher(instance) */
{
add("dispatch",
"Execute a command registered as an LLCommandHandler,\n"
"passing any required parameters:\n"
"[\"cmd\"] string command name\n"
"[\"params\"] array of parameters, as if from components of URL path\n"
"[\"query\"] map of parameters, as if from ?key1=val&key2=val\n"
"[\"trusted\"] boolean indicating trusted browser [default true]",
&LLCommandDispatcherListener::dispatch);
}
void LLCommandDispatcherListener::dispatch(const LLSD& params) const
{
// For most purposes, we expect callers to want to be trusted.
bool trusted_browser = true;
if (params.has("trusted"))
{
// But for testing, allow a caller to specify untrusted.
trusted_browser = params["trusted"].asBoolean();
}
LLCommandDispatcher::dispatch(params["cmd"], params["params"], params["query"], NULL,
trusted_browser);
}

View File

@ -0,0 +1,30 @@
/**
* @file llcommanddispatcherlistener.h
* @author Nat Goodspeed
* @date 2009-12-10
* @brief LLEventAPI for LLCommandDispatcher
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
* Copyright (c) 2009, Linden Research, Inc.
* $/LicenseInfo$
*/
#if ! defined(LL_LLCOMMANDDISPATCHERLISTENER_H)
#define LL_LLCOMMANDDISPATCHERLISTENER_H
#include "lleventapi.h"
class LLCommandDispatcher;
class LLSD;
class LLCommandDispatcherListener: public LLEventAPI
{
public:
LLCommandDispatcherListener(/* LLCommandDispatcher* instance */); // all static members
private:
void dispatch(const LLSD& params) const;
//LLCommandDispatcher* mDispatcher;
};
#endif /* ! defined(LL_LLCOMMANDDISPATCHERLISTENER_H) */

View File

@ -34,12 +34,16 @@
#include "llviewerprecompiledheaders.h"
#include "llcommandhandler.h"
#include "llnotificationsutil.h"
#include "llcommanddispatcherlistener.h"
// system includes
#include <boost/tokenizer.hpp>
#define THROTTLE_PERIOD 15 // required secs between throttled commands
static LLCommandDispatcherListener sCommandDispatcherListener;
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
//---------------------------------------------------------------------------
@ -93,6 +97,8 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
LLMediaCtrl* web,
bool trusted_browser)
{
static bool slurl_blocked = false;
static bool slurl_throttled = false;
static F64 last_throttle_time = 0.0;
F64 cur_time = 0.0;
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
@ -110,6 +116,11 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
// block request from external browser, but report as
// "handled" because it was well formatted.
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_blocked)
{
LLNotificationsUtil::add("BlockedSLURL");
slurl_blocked = true;
}
return true;
case LLCommandHandler::UNTRUSTED_THROTTLE:
@ -119,6 +130,11 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
// block request from external browser if it happened
// within THROTTLE_PERIOD secs of the last command
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_throttled)
{
LLNotificationsUtil::add("ThrottledSLURL");
slurl_throttled = true;
}
return true;
}
last_throttle_time = cur_time;

View File

@ -41,6 +41,7 @@
// project include
#include "llagent.h"
#include "llappviewer.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@ -142,6 +143,10 @@ BOOL LLFloaterChat::postBuild()
void LLFloaterChat::updateConsoleVisibility()
{
if(gDisconnected)
{
return;
}
// determine whether we should show console due to not being visible
gConsole->setVisible( !isInVisibleChain() // are we not in part of UI being drawn?
|| isMinimized() // are we minimized?

View File

@ -69,6 +69,7 @@ class LLFloaterColorPicker
void destroyUI ();
void cancelSelection ();
LLColorSwatchCtrl* getSwatch () { return mSwatch; };
void setSwatch( LLColorSwatchCtrl* swatch) { mSwatch = swatch; }
// mutator / accessor for original RGB value
void setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn );

View File

@ -2300,7 +2300,7 @@ void LLPanelLandAccess::refresh()
mListBanned->deleteAllItems();
LLParcel *parcel = mParcel->getParcel();
// Display options
if (parcel)
{
@ -2396,22 +2396,40 @@ void LLPanelLandAccess::refresh()
mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix);
}
}
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
if(region)
{
std::string region_access = "(";
region_access += region->getSimAccessString();
region_access += ")";
childSetLabelArg( "public_access", "[MATURITY]", region_access );
}
else
{
childSetLabelArg( "public_access", "[MATURITY]", std::string() );
}
if(parcel->getRegionDenyAnonymousOverride())
{
childSetValue("limit_payment", TRUE);
childSetLabelArg( "limit_payment", "[ESTATE_PAYMENT_LIMIT]", getString("access_estate_defined") );
}
else
{
childSetValue("limit_payment", (parcel->getParcelFlag(PF_DENY_ANONYMOUS)));
childSetLabelArg( "limit_payment", "[ESTATE_PAYMENT_LIMIT]", std::string() );
}
if(parcel->getRegionDenyAgeUnverifiedOverride())
{
childSetValue("limit_age_verified", TRUE);
childSetLabelArg( "limit_age_verified", "[ESTATE_AGE_LIMIT]", getString("access_estate_defined") );
}
else
{
childSetValue("limit_age_verified", (parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED)));
childSetLabelArg( "limit_age_verified", "[ESTATE_AGE_LIMIT]", std::string() );
}
BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST);

View File

@ -72,11 +72,14 @@ LLFloaterOpenObject::~LLFloaterOpenObject()
{
// sInstance = NULL;
}
// virtual
BOOL LLFloaterOpenObject::postBuild()
{
childSetTextArg("object_name", "[DESC]", std::string("Object") ); // *Note: probably do not want to translate this
mPanelInventoryObject = getChild<LLPanelObjectInventory>("object_contents");
refresh();
return TRUE;
}
@ -95,29 +98,57 @@ void LLFloaterOpenObject::onOpen(const LLSD& key)
return;
}
mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
refresh();
}
void LLFloaterOpenObject::refresh()
{
mPanelInventoryObject->refresh();
std::string name;
BOOL enabled;
std::string name = "";
// Enable the copy || copy & wear buttons only if we have something we can copy or copy & wear (respectively).
bool copy_enabled = false;
bool wear_enabled = false;
LLSelectNode* node = mObjectSelection->getFirstRootNode();
if (node)
if (node)
{
name = node->mName;
enabled = TRUE;
}
else
{
name = "";
enabled = FALSE;
copy_enabled = true;
LLViewerObject* object = node->getObject();
if (object)
{
// this folder is coming from an object, as there is only one folder in an object, the root,
// we need to collect the entire contents and handle them as a group
InventoryObjectList inventory_objects;
object->getInventoryContents(inventory_objects);
if (!inventory_objects.empty())
{
for (InventoryObjectList::iterator it = inventory_objects.begin();
it != inventory_objects.end();
++it)
{
LLInventoryItem* item = static_cast<LLInventoryItem*> ((LLInventoryObject*)(*it));
LLInventoryType::EType type = item->getInventoryType();
if (type == LLInventoryType::IT_OBJECT
|| type == LLInventoryType::IT_ATTACHMENT
|| type == LLInventoryType::IT_WEARABLE
|| type == LLInventoryType::IT_GESTURE)
{
wear_enabled = true;
break;
}
}
}
}
}
childSetTextArg("object_name", "[DESC]", name);
childSetEnabled("copy_to_inventory_button", enabled);
childSetEnabled("copy_and_wear_button", enabled);
childSetEnabled("copy_to_inventory_button", copy_enabled);
childSetEnabled("copy_and_wear_button", wear_enabled);
}

View File

@ -40,6 +40,7 @@
// viewer project includes
#include "llcommandhandler.h"
#include "llpanelplace.h"
#include "llsidetray.h"
// linden library includes
#include "lluuid.h"
@ -70,7 +71,10 @@ public:
{
if (parcel_id.notNull())
{
LLFloaterReg::showInstance("parcel_info", LLSD(parcel_id));
LLSD key;
key["type"] = "remote_place";
key["id"] = parcel_id;
LLSideTray::getInstance()->showPanel("panel_places", key);
return true;
}
}

View File

@ -88,8 +88,6 @@
#include "lltrans.h"
#include "llagentui.h"
#define ELAR_ENABLED 0 // Enable when server support is implemented
const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
@ -1995,11 +1993,6 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
childSetEnabled("remove_banned_avatar_btn", god || owner || manager);
childSetEnabled("message_estate_btn", god || owner || manager);
childSetEnabled("kick_user_from_estate_btn", god || owner || manager);
#if ELAR_ENABLED
childSetEnabled("abuse_email_address", god || owner || manager);
#else
childSetEnabled("abuse_email_address", false);
#endif
// estate managers can't add estate managers
childSetEnabled("add_estate_manager_btn", god || owner);
@ -2065,8 +2058,6 @@ BOOL LLPanelEstateInfo::postBuild()
initCtrl("limit_payment");
initCtrl("limit_age_verified");
initCtrl("voice_chat_check");
getChild<LLUICtrl>("abuse_email_address")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAnything, this));
getChild<LLLineEditor>("abuse_email_address")->setKeystrokeCallback(onChangeText, this);
// set up the use global time checkbox
getChild<LLUICtrl>("use_global_time_check")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeUseGlobalTime, this));
@ -2276,8 +2267,6 @@ bool LLPanelEstateInfo::commitEstateInfoCaps()
}
body["sun_hour"] = sun_hour;
body["owner_abuse_email"] = childGetValue("abuse_email_address").asString();
// we use a responder so that we can re-get the data after committing to the database
LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder(this));
return true;
@ -2436,16 +2425,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name)
childSetValue("estate_owner", LLSD(name));
}
const std::string LLPanelEstateInfo::getAbuseEmailAddress() const
{
return childGetValue("abuse_email_address").asString();
}
void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address)
{
childSetValue("abuse_email_address", LLSD(address));
}
void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent,
bool enable_group,
bool enable_ban)
@ -2954,18 +2933,6 @@ bool LLDispatchEstateUpdateInfo::operator()(
std::string estate_name = strings[0].c_str(); // preserve c_str() call!
panel->setEstateName(estate_name);
#if ELAR_ENABLED
if (strings.size() > 9)
{
std::string abuse_email = strings[9].c_str(); // preserve c_str() call!
panel->setAbuseEmailAddress(abuse_email);
}
else
#endif
{
panel->setAbuseEmailAddress(panel->getString("email_unsupported"));
}
LLViewerRegion* regionp = gAgent.getRegion();
LLUUID owner_id(strings[1]);

View File

@ -330,9 +330,6 @@ public:
const std::string getOwnerName() const;
void setOwnerName(const std::string& name);
const std::string getAbuseEmailAddress() const;
void setAbuseEmailAddress(const std::string& address);
// If visible from mainland, allowed agent and allowed groups
// are ignored, so must disable UI.
void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban);

View File

@ -95,7 +95,6 @@ const U32 INCLUDE_SCREENSHOT = 0x01 << 0;
LLFloaterReporter::LLFloaterReporter(const LLSD& key)
: LLFloater(key),
mReportType(COMPLAINT_REPORT),
mEmailToEstateOwner(FALSE),
mObjectID(),
mScreenID(),
mAbuserID(),
@ -117,18 +116,7 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
if ( LLFloaterReg::instanceVisible("reporter") )
{
LLFloaterReporter *f = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
BOOL email_to_estate_owner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER );
f->mEmailToEstateOwner = email_to_estate_owner;
if ( email_to_estate_owner )
{
LLNotificationsUtil::add("HelpReportAbuseEmailEO");
}
else
{
LLNotificationsUtil::add("HelpReportAbuseEmailLL");
}
LLNotificationsUtil::add("HelpReportAbuseEmailLL");
};
}
// virtual
@ -218,17 +206,7 @@ LLFloaterReporter::~LLFloaterReporter()
// virtual
void LLFloaterReporter::draw()
{
// this is set by a static callback sometime after the dialog is created.
// Only disable screenshot for abuse reports to estate owners
if ( mEmailToEstateOwner )
{
childSetValue("screen_check", FALSE );
childSetEnabled("screen_check", FALSE );
}
else
{
childSetEnabled("screen_check", TRUE );
}
childSetEnabled("screen_check", TRUE );
LLFloater::draw();
}
@ -637,11 +615,7 @@ LLSD LLFloaterReporter::gatherReport()
LLUUID screenshot_id = LLUUID::null;
if (childGetValue("screen_check"))
{
if ( mEmailToEstateOwner == FALSE )
{
screenshot_id = childGetValue("screenshot");
}
screenshot_id = childGetValue("screenshot");
};
LLSD report = LLSD::emptyMap();

View File

@ -124,7 +124,6 @@ private:
private:
EReportType mReportType;
BOOL mEmailToEstateOwner;
LLUUID mObjectID;
LLUUID mScreenID;
LLUUID mAbuserID;

View File

@ -42,7 +42,8 @@
LLFloaterSearch::LLFloaterSearch(const LLSD& key) :
LLFloater(key),
LLViewerMediaObserver(),
mBrowser(NULL)
mBrowser(NULL),
mSearchGodLevel(0)
{
// declare a map that transforms a category name into
// the URL suffix that is used to search that category
@ -86,12 +87,21 @@ void LLFloaterSearch::handleMediaEvent(LLPluginClassMedia *self, EMediaEvent eve
case MEDIA_EVENT_NAVIGATE_COMPLETE:
childSetText("status_text", getString("done_text"));
break;
default:
break;
}
}
void LLFloaterSearch::godLevelChanged(U8 godlevel)
{
// search results can change based upon god level - if the user
// changes god level, then give them a warning (we don't refresh
// the search as this might undo any page navigation or
// AJAX-driven changes since the last search).
childSetVisible("refresh_search", (godlevel != mSearchGodLevel));
}
void LLFloaterSearch::search(const LLSD &key)
{
if (! mBrowser)
@ -99,6 +109,10 @@ void LLFloaterSearch::search(const LLSD &key)
return;
}
// reset the god level warning as we're sending the latest state
childHide("refresh_search");
mSearchGodLevel = gAgent.getGodLevel();
// get the URL for the search page
std::string url = getString("search_url");
if (! LLStringUtil::endsWith(url, "/"))

View File

@ -66,14 +66,20 @@ public:
/// "events", "groups", "wiki", "destinations", "classifieds"
void search(const LLSD &key);
/// changing godmode can affect the search results that are
/// returned by the search website - use this method to tell the
/// search floater that the user has changed god level.
void godLevelChanged(U8 godlevel);
private:
/*virtual*/ BOOL postBuild();
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event);
LLMediaCtrl *mBrowser;
LLSD mCategoryPaths;
U8 mSearchGodLevel;
};
#endif // LL_LLFLOATERSEARCH_H

View File

@ -991,7 +991,7 @@ S32 LLFloaterTools::calcRenderCost()
if (viewer_volume)
{
cost += viewer_volume->getRenderCost(textures);
cost += textures.size() * 5;
cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
textures.clear();
}
}

View File

@ -40,7 +40,6 @@
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "lliconctrl.h"
#include "llsliderctrl.h"
#include "llviewercontrol.h"
#include "llvoiceclient.h"
#include "llvoicechannel.h"
@ -61,9 +60,6 @@ LLPanelVoiceDeviceSettings::LLPanelVoiceDeviceSettings()
mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
mDevicesUpdated = FALSE;
// grab "live" mic volume level
mMicVolume = gSavedSettings.getF32("AudioLevelMic");
// ask for new device enumeration
// now do this in onOpen() instead...
//gVoiceClient->refreshDeviceLists();
@ -75,10 +71,6 @@ LLPanelVoiceDeviceSettings::~LLPanelVoiceDeviceSettings()
BOOL LLPanelVoiceDeviceSettings::postBuild()
{
LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
// set mic volume tuning slider based on last mic volume setting
volume_slider->setValue(mMicVolume);
childSetCommitCallback("voice_input_device", onCommitInputDevice, this);
childSetCommitCallback("voice_output_device", onCommitOutputDevice, this);
@ -157,15 +149,6 @@ void LLPanelVoiceDeviceSettings::apply()
gSavedSettings.setString("VoiceOutputAudioDevice", s);
mOutputDevice = s;
}
// assume we are being destroyed by closing our embedding window
LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
if(volume_slider)
{
F32 slider_value = (F32)volume_slider->getValue().asReal();
gSavedSettings.setF32("AudioLevelMic", slider_value);
mMicVolume = slider_value;
}
}
void LLPanelVoiceDeviceSettings::cancel()
@ -178,22 +161,12 @@ void LLPanelVoiceDeviceSettings::cancel()
if(mCtrlOutputDevices)
mCtrlOutputDevices->setSimple(mOutputDevice);
gSavedSettings.setF32("AudioLevelMic", mMicVolume);
LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
if(volume_slider)
{
volume_slider->setValue(mMicVolume);
}
}
void LLPanelVoiceDeviceSettings::refresh()
{
//grab current volume
LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
// set mic volume tuning slider based on last mic volume setting
F32 current_volume = (F32)volume_slider->getValue().asReal();
gVoiceClient->tuningSetMicVolume(current_volume);
// update the live input level display
gVoiceClient->tuningSetMicVolume();
// Fill in popup menus
mCtrlInputDevices = getChild<LLComboBox>("voice_input_device");
@ -263,7 +236,6 @@ void LLPanelVoiceDeviceSettings::initialize()
{
mInputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
mMicVolume = gSavedSettings.getF32("AudioLevelMic");
mDevicesUpdated = FALSE;
// ask for new device enumeration

View File

@ -56,7 +56,6 @@ protected:
static void onCommitInputDevice(LLUICtrl* ctrl, void* user_data);
static void onCommitOutputDevice(LLUICtrl* ctrl, void* user_data);
F32 mMicVolume;
std::string mInputDevice;
std::string mOutputDevice;
class LLComboBox *mCtrlInputDevices;

View File

@ -357,6 +357,16 @@ void LLFolderView::openFolder(const std::string& foldername)
}
}
void LLFolderView::openTopLevelFolders()
{
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
folders_t::iterator fit = iter++;
(*fit)->setOpen(TRUE);
}
}
void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
{
// call base class to do proper recursion
@ -401,7 +411,12 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
}
if (folderp->getVisible())
// Need to call arrange regardless of visibility, since children's visibility
// might need to be changed too (e.g. even though a folder is invisible, its
// children also need to be set invisible for state-tracking purposes, e.g.
// llfolderviewitem::filter).
// if (folderp->getVisible())
{
S32 child_height = 0;
S32 child_width = 0;
@ -469,13 +484,13 @@ void LLFolderView::filter( LLInventoryFilter& filter )
if (getCompletedFilterGeneration() < filter.getCurrentGeneration())
{
mFiltered = FALSE;
mPassedFilter = FALSE;
mMinWidth = 0;
LLFolderViewFolder::filter(filter);
}
else
{
mFiltered = TRUE;
mPassedFilter = TRUE;
}
}
@ -890,7 +905,7 @@ void LLFolderView::draw()
}
else
{
mStatusText = LLTrans::getString("InventoryNoMatchingItems");
mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage());
font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
}

View File

@ -127,6 +127,7 @@ public:
// Close all folders in the view
void closeAllFolders();
void openFolder(const std::string& foldername);
void openTopLevelFolders();
virtual void toggleOpen() {};
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);

View File

@ -40,6 +40,7 @@
#include "llinventoryfilter.h"
#include "llpanel.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewerinventory.h"
#include "llviewerwindow.h" // Argh, only for setCursor()
// linden library includes
@ -121,7 +122,7 @@ LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p)
mHasVisibleChildren(FALSE),
mIndentation(0),
mNumDescendantsSelected(0),
mFiltered(FALSE),
mPassedFilter(FALSE),
mLastFilterGeneration(-1),
mStringMatchOffset(std::string::npos),
mControlLabelRotation(0.f),
@ -223,17 +224,17 @@ BOOL LLFolderViewItem::potentiallyVisible()
BOOL LLFolderViewItem::getFiltered()
{
return mFiltered && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
}
BOOL LLFolderViewItem::getFiltered(S32 filter_generation)
{
return mFiltered && mLastFilterGeneration >= filter_generation;
return mPassedFilter && mLastFilterGeneration >= filter_generation;
}
void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
{
mFiltered = filtered;
mPassedFilter = filtered;
mLastFilterGeneration = filter_generation;
}
@ -423,19 +424,20 @@ S32 LLFolderViewItem::getItemHeight()
void LLFolderViewItem::filter( LLInventoryFilter& filter)
{
BOOL filtered = mListener && filter.check(this);
const BOOL previous_passed_filter = mPassedFilter;
const BOOL passed_filter = mListener && filter.check(this);
// if our visibility will change as a result of this filter, then
// If our visibility will change as a result of this filter, then
// we need to be rearranged in our parent folder
if (getVisible() != filtered)
if (mParentFolder)
{
if (mParentFolder)
{
if (getVisible() != passed_filter)
mParentFolder->requestArrange();
if (passed_filter != previous_passed_filter)
mParentFolder->requestArrange();
}
}
setFiltered(filtered, filter.getCurrentGeneration());
setFiltered(passed_filter, filter.getCurrentGeneration());
mStringMatchOffset = filter.getStringMatchOffset();
filter.decrementFilterCount();
@ -603,6 +605,11 @@ const std::string& LLFolderViewItem::getSearchableLabel() const
return mSearchableLabel;
}
LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
{
return gInventory.getItem(getListener()->getUUID());
}
std::string LLFolderViewItem::getName( void ) const
{
if(mListener)
@ -1237,7 +1244,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
if (getLastFilterGeneration() < filter_generation)
{
if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter
!mFiltered) // and did not pass the filter
!mPassedFilter) // and did not pass the filter
{
// go ahead and flag this folder as done
mLastFilterGeneration = filter_generation;
@ -1375,7 +1382,7 @@ void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
{
// if this folder is now filtered, but wasn't before
// (it just passed)
if (filtered && !mFiltered)
if (filtered && !mPassedFilter)
{
// reset current height, because last time we drew it
// it might have had more visible items than now

View File

@ -45,6 +45,7 @@ class LLFolderViewListenerFunctor;
class LLInventoryFilter;
class LLMenuGL;
class LLUIImage;
class LLViewerInventoryItem;
// These are grouping of inventory types.
// Order matters when sorting system folders to the top.
@ -120,6 +121,9 @@ public:
static const F32 FOLDER_CLOSE_TIME_CONSTANT;
static const F32 FOLDER_OPEN_TIME_CONSTANT;
// Mostly for debugging printout purposes.
const std::string& getSearchableLabel() { return mSearchableLabel; }
protected:
friend class LLUICtrlFactory;
friend class LLFolderViewEventListener;
@ -148,7 +152,7 @@ protected:
BOOL mHasVisibleChildren;
S32 mIndentation;
S32 mNumDescendantsSelected;
BOOL mFiltered;
BOOL mPassedFilter;
S32 mLastFilterGeneration;
std::string::size_type mStringMatchOffset;
F32 mControlLabelRotation;
@ -156,8 +160,8 @@ protected:
BOOL mDragAndDropTarget;
LLUIImagePtr mArrowImage;
LLUIImagePtr mBoxImage;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
bool mDontShowInHierarchy;
// helper function to change the selection from the root.
@ -202,7 +206,7 @@ public:
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
virtual S32 getItemHeight();
void setDontShowInHierarchy(bool dont_show) { mDontShowInHierarchy = dont_show; }
bool getDontShowInHierarchy() { return mDontShowInHierarchy; }
bool getDontShowInHierarchy() const { return mDontShowInHierarchy; }
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
@ -281,6 +285,9 @@ public:
const LLFolderViewEventListener* getListener( void ) const { return mListener; }
LLFolderViewEventListener* getListener( void ) { return mListener; }
// Gets the inventory item if it exists (null otherwise)
LLViewerInventoryItem * getInventoryItem(void);
// just rename the object.
void rename(const std::string& new_name);
@ -328,7 +335,7 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
private:
private:
static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
};

View File

@ -90,8 +90,20 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
case IM_SESSION_CONFERENCE_START:
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
break;
default:
case IM_SESSION_GROUP_START:
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
break;
case IM_SESSION_INVITE:
if (gAgent.isInGroup(mSessionID))
{
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
}
else
{
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
}
break;
default: break;
}
}
}
@ -415,6 +427,7 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
if(channel)
{
channel->updateShowToastsState();
channel->redrawToasts();
}
}
@ -439,6 +452,7 @@ void LLIMFloater::setVisible(BOOL visible)
if(channel)
{
channel->updateShowToastsState();
channel->redrawToasts();
}
if (visible && mChatHistory && mInputEditor)

View File

@ -88,6 +88,9 @@ const static std::string IM_TEXT("message");
const static std::string IM_FROM("from");
const static std::string IM_FROM_ID("from_id");
const static std::string NO_SESSION("(IM Session Doesn't Exist)");
const static std::string ADHOC_NAME_SUFFIX(" Conference");
std::string LLCallDialogManager::sPreviousSessionlName = "";
std::string LLCallDialogManager::sCurrentSessionlName = "";
LLIMModel::LLIMSession* LLCallDialogManager::sSession = NULL;
@ -116,6 +119,13 @@ void toast_callback(const LLSD& msg){
return;
}
// Skip toasting if we have open window of IM with this session id
LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
if (open_im_floater && open_im_floater->getVisible())
{
return;
}
LLSD args;
args["MESSAGE"] = msg["message"];
args["TIME"] = msg["time"];
@ -154,11 +164,11 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mInitialTargetIDs(ids),
mVoiceChannel(NULL),
mSpeakers(NULL),
mCallDialogManager(NULL),
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
mOtherParticipantIsAvatar(true)
mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false)
{
if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
{
@ -287,9 +297,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
LLIMModel::LLIMSession::~LLIMSession()
{
delete mCallDialogManager;
mCallDialogManager = NULL;
delete mSpeakers;
mSpeakers = NULL;
@ -413,6 +420,12 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
{
im_floater->sessionInitReplyReceived(new_session_id);
}
// auto-start the call on session initialization?
if (session->mStartCallOnInitialize)
{
gIMMgr->startCall(new_session_id);
}
}
//*TODO remove this "floater" stuff when Communicate Floater is gone
@ -448,10 +461,16 @@ void LLIMModel::testMessages()
addMessage(bot2_session_id, from, bot2_id, "Test Message: OMGWTFBBQ.");
}
//session name should not be empty
bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
const LLUUID& other_participant_id, const std::vector<LLUUID>& ids)
{
if (name.empty())
{
llwarns << "Attempt to create a new session with empty name; id = " << session_id << llendl;
return false;
}
if (findIMSession(session_id))
{
llwarns << "IM Session " << session_id << " already exists" << llendl;
@ -608,7 +627,7 @@ const std::string& LLIMModel::getName(const LLUUID& session_id) const
if (!session)
{
llwarns << "session " << session_id << "does not exist " << llendl;
return LLStringUtil::null;
return NO_SESSION;
}
return session->mName;
@ -995,18 +1014,6 @@ bool LLIMModel::sendStartSession(
return false;
}
// static
void LLIMModel::sendSessionInitialized(const LLUUID &session_id)
{
LLIMSession* session = getInstance()->findIMSession(session_id);
if (session)
{
LLSD arg;
arg["session_id"] = session_id;
getInstance()->mSessionInitializedSignal(arg);
}
}
//
// Helper Functions
//
@ -1079,7 +1086,7 @@ public:
if ( 404 == statusNum )
{
std::string error_string;
error_string = "does not exist";
error_string = "session_does_not_exist_error";
gIMMgr->showSessionStartError(error_string, mSessionID);
}
}
@ -1268,6 +1275,7 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat
{
LLSD mCallDialogPayload;
LLOutgoingCallDialog* ocd;
bool is_incoming;
mCallDialogPayload["session_id"] = sSession->mSessionID;
mCallDialogPayload["session_name"] = sSession->mName;
@ -1277,8 +1285,10 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat
switch(new_state)
{
case LLVoiceChannel::STATE_CALL_STARTED :
// do not show "Calling to..." if it is incoming P2P call
if(sSession->mSessionType == LLIMModel::LLIMSession::P2P_SESSION && static_cast<LLVoiceChannelP2P*>(sSession->mVoiceChannel)->isIncomingCall())
// do not show "Calling to..." if it is incoming call
is_incoming = LLVoiceClient::getInstance()->isSessionIncoming(sSession->mSessionID);
// *TODO: implement for AdHoc and Group voice chats
if(is_incoming)
{
return;
}
@ -1290,6 +1300,7 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat
ocd->getChild<LLTextBox>("leaving")->setVisible(true);
ocd->getChild<LLTextBox>("connecting")->setVisible(false);
ocd->getChild<LLTextBox>("noanswer")->setVisible(false);
ocd->getChild<LLButton>("Cancel")->setVisible(true);
}
return;
@ -1301,10 +1312,12 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat
ocd->getChild<LLTextBox>("leaving")->setVisible(true);
ocd->getChild<LLTextBox>("connecting")->setVisible(true);
ocd->getChild<LLTextBox>("noanswer")->setVisible(false);
ocd->getChild<LLButton>("Cancel")->setVisible(true);
}
return;
case LLVoiceChannel::STATE_ERROR :
mCallDialogPayload["start_timer"] = true;
ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
if (ocd)
{
@ -1312,6 +1325,7 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat
ocd->getChild<LLTextBox>("leaving")->setVisible(false);
ocd->getChild<LLTextBox>("connecting")->setVisible(false);
ocd->getChild<LLTextBox>("noanswer")->setVisible(true);
ocd->getChild<LLButton>("Cancel")->setVisible(false);
}
return;
@ -1363,6 +1377,33 @@ LLCallDialog(payload)
instance->onCancel(instance);
}
}
void LLOutgoingCallDialog::draw()
{
if (lifetimeHasExpired())
{
onLifetimeExpired();
}
LLDockableFloater::draw();
}
bool LLOutgoingCallDialog::lifetimeHasExpired()
{
if (mLifetimeTimer.getStarted())
{
F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32();
if (elapsed_time > LIFETIME)
{
return true;
}
}
return false;
}
void LLOutgoingCallDialog::onLifetimeExpired()
{
mLifetimeTimer.stop();
closeFloater();
}
void LLOutgoingCallDialog::onOpen(const LLSD& key)
{
@ -1391,6 +1432,13 @@ void LLOutgoingCallDialog::onOpen(const LLSD& key)
childSetTextArg("connecting", "[CALLEE_NAME]", callee_name);
LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
icon->setValue(callee_id);
// stop timer by default
mLifetimeTimer.stop();
if(mPayload.has("start_timer"))
{
mLifetimeTimer.reset();
}
}
@ -1514,6 +1562,8 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
return;
LLUUID session_id = mPayload["session_id"].asUUID();
LLUUID caller_id = mPayload["caller_id"].asUUID();
std::string session_name = mPayload["session_name"].asString();
EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)mPayload["inv_type"].asInteger();
bool voice = true;
@ -1530,8 +1580,8 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
{
// create a normal IM session
session_id = gIMMgr->addP2PSession(
mPayload["session_name"].asString(),
mPayload["caller_id"].asUUID(),
session_name,
caller_id,
mPayload["session_handle"].asString(),
mPayload["session_uri"].asString());
@ -1549,10 +1599,38 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
}
else
{
LLUUID new_session_id = gIMMgr->addSession(
mPayload["session_name"].asString(),
type,
session_id);
//session name should not be empty, but it can contain spaces so we don't trim
std::string correct_session_name = session_name;
if (session_name.empty())
{
llwarns << "Received an empty session name from a server" << llendl;
switch(type){
case IM_SESSION_CONFERENCE_START:
case IM_SESSION_GROUP_START:
case IM_SESSION_INVITE:
if (gAgent.isInGroup(session_id))
{
LLGroupData data;
if (!gAgent.getGroupData(session_id, data)) break;
correct_session_name = data.mName;
}
else
{
if (gCacheName->getFullName(caller_id, correct_session_name))
{
correct_session_name.append(ADHOC_NAME_SUFFIX);
}
}
llinfos << "Corrected session name is " << correct_session_name << llendl;
break;
default:
llwarning("Received an empty session name from a server and failed to generate a new proper session name", 0);
break;
}
}
LLUUID new_session_id = gIMMgr->addSession(correct_session_name, type, session_id);
if (new_session_id != LLUUID::null)
{
LLIMFloater::show(new_session_id);
@ -1929,6 +2007,15 @@ BOOL LLIMMgr::getIMReceived() const
return mIMReceived;
}
void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id)
{
LLIMModel::LLIMSession *session = LLIMModel::getInstance()->findIMSession(session_id);
if (session)
{
session->mStartCallOnInitialize = true;
}
}
LLUUID LLIMMgr::addP2PSession(const std::string& name,
const LLUUID& other_participant_id,
const std::string& voice_session_handle,
@ -1979,6 +2066,12 @@ LLUUID LLIMMgr::addSession(
return LLUUID::null;
}
if (name.empty())
{
llwarning("Session name cannot be null!", 0);
return LLUUID::null;
}
LLUUID session_id = computeSessionID(dialog,other_participant_id);
bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);

View File

@ -81,7 +81,6 @@ public:
SType mSessionType;
LLUUID mOtherParticipantID;
std::vector<LLUUID> mInitialTargetIDs;
LLCallDialogManager* mCallDialogManager;
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;
@ -105,6 +104,7 @@ public:
bool mTextIMPossible;
bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
};
@ -124,7 +124,6 @@ public:
typedef boost::function<void(const LLSD&)> session_callback_t;
session_signal_t mNewMsgSignal;
session_signal_t mNoUnreadMsgsSignal;
session_signal_t mSessionInitializedSignal;
/**
* Find an IM Session corresponding to session_id
@ -139,10 +138,10 @@ public:
boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); }
boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); }
boost::signals2::connection addSessionInitializedCallback(session_callback_t cb ) { return mSessionInitializedSignal.connect(cb); }
/**
* Create new session object in a model
* @param name session name should not be empty, will return false if empty
*/
bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id,
const std::vector<LLUUID>& ids = std::vector<LLUUID>());
@ -213,7 +212,6 @@ public:
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
const std::vector<LLUUID>& ids, EInstantMessage dialog);
static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing);
static void sendSessionInitialized(const LLUUID &session_id);
static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,
const LLUUID& other_participant_id, EInstantMessage dialog);
@ -299,6 +297,7 @@ public:
/**
* Creates a P2P session with the requisite handle for responding to voice calls.
*
* @param name session name, cannot be null
* @param caller_uri - sip URI of caller. It should be always be passed into the method to avoid
* incorrect working of LLVoiceChannel instances. See EXT-2985.
*/
@ -330,6 +329,9 @@ public:
void notifyNewIM();
void clearNewIMNotification();
// automatically start a call once the session has initialized
void autoStartCallOnStartup(const LLUUID& session_id);
// IM received that you haven't seen yet
BOOL getIMReceived() const;
@ -493,7 +495,16 @@ public:
static void onCancel(void* user_data);
// check timer state
/*virtual*/ void draw();
private:
// lifetime timer for NO_ANSWER notification
LLTimer mLifetimeTimer;
// lifetime duration for NO_ANSWER notification
static const S32 LIFETIME = 5;
bool lifetimeHasExpired();
void onLifetimeExpired();
};
// Globals

View File

@ -42,10 +42,12 @@
#include "lldateutil.h"
#include "llfloaterreporter.h"
#include "llfloaterworldmap.h"
#include "llimview.h"
#include "llinspect.h"
#include "llmutelist.h"
#include "llpanelblockedlist.h"
#include "llstartup.h"
#include "llspeakers.h"
#include "llviewermenu.h"
#include "llvoiceclient.h"
#include "llviewerobjectlist.h"
@ -99,6 +101,12 @@ private:
// Set the volume slider to this user's current client-side volume setting,
// hiding/disabling if the user is not nearby.
void updateVolumeSlider();
// Shows/hides moderator panel depending on voice state
void updateModeratorPanel();
// Moderator ability to enable/disable voice chat for avatar
void toggleSelectedVoice(bool enabled);
// Button callbacks
void onClickAddFriend();
@ -205,10 +213,12 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
mCommitCallbackRegistrar.add("InspectAvatar.Report", boost::bind(&LLInspectAvatar::onClickReport, this));
mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onClickFindOnMap, this));
mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
mVisibleCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));
mVisibleCallbackRegistrar.add("InspectAvatar.VisibleFreezeEject",
mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false));
mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true));
mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));
mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreezeEject",
boost::bind(&LLInspectAvatar::onVisibleFreezeEject, this));
mVisibleCallbackRegistrar.add("InspectAvatar.VisibleZoomIn",
mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn",
boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
@ -277,6 +287,8 @@ void LLInspectAvatar::onOpen(const LLSD& data)
requestUpdate();
updateVolumeSlider();
updateModeratorPanel();
}
// virtual
@ -366,6 +378,119 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
mPropertiesRequest = NULL;
}
void LLInspectAvatar::updateModeratorPanel()
{
bool enable_moderator_panel = false;
if (LLVoiceChannel::getCurrentVoiceChannel())
{
LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
if (session_id != LLUUID::null)
{
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
if (speaker_mgr)
{
LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID());
LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID);
if(speaker_mgr->isVoiceActive() && selected_speakerp &&
((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike()))
{
getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice);
getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice);
enable_moderator_panel = true;
}
}
}
}
if (enable_moderator_panel)
{
if (!getChild<LLUICtrl>("moderator_panel")->getVisible())
{
getChild<LLUICtrl>("moderator_panel")->setVisible(true);
// stretch the floater so it can accommodate the moderator panel
reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
}
}
else if (getChild<LLUICtrl>("moderator_panel")->getVisible())
{
getChild<LLUICtrl>("moderator_panel")->setVisible(false);
// shrink the inspector floater back to original size
reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
}
}
void LLInspectAvatar::toggleSelectedVoice(bool enabled)
{
LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
if (speaker_mgr)
{
if (!gAgent.getRegion())
return;
std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
LLSD data;
data["method"] = "mute update";
data["session-id"] = session_id;
data["params"] = LLSD::emptyMap();
data["params"]["agent_id"] = mAvatarID;
data["params"]["mute_info"] = LLSD::emptyMap();
// ctrl value represents ability to type, so invert
data["params"]["mute_info"]["voice"] = !enabled;
class MuteVoiceResponder : public LLHTTPClient::Responder
{
public:
MuteVoiceResponder(const LLUUID& session_id)
{
mSessionID = session_id;
}
virtual void error(U32 status, const std::string& reason)
{
llwarns << status << ": " << reason << llendl;
if ( gIMMgr )
{
//403 == you're not a mod
//should be disabled if you're not a moderator
if ( 403 == status )
{
gIMMgr->showSessionEventError(
"mute",
"not_a_moderator",
mSessionID);
}
else
{
gIMMgr->showSessionEventError(
"mute",
"generic",
mSessionID);
}
}
}
private:
LLUUID mSessionID;
};
LLHTTPClient::post(
url,
data,
new MuteVoiceResponder(speaker_mgr->getSessionID()));
}
closeFloater();
}
void LLInspectAvatar::updateVolumeSlider()
{
// By convention, we only display and toggle voice mutes, not all mutes

View File

@ -506,12 +506,59 @@ void hide_context_entries(LLMenuGL& menu,
}
}
bool isWornLink(LLUUID link_id)
{
LLViewerInventoryItem *link = gInventory.getItem(link_id);
if (!link)
return false;
LLViewerInventoryItem *item = link->getLinkedItem();
if (!item)
return false;
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
{
LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
if(my_avatar && my_avatar->isWearingAttachment(item->getUUID()))
return true;
}
break;
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
if(gAgentWearables.isWearingItem(item->getUUID()))
return true;
break;
case LLAssetType::AT_GESTURE:
if (LLGestureManager::instance().isGestureActive(item->getUUID()))
return true;
break;
default:
break;
}
return false;
}
// Helper for commonly-used entries
void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
std::vector<std::string> &items,
std::vector<std::string> &disabled_items, U32 flags)
{
const LLInventoryObject *obj = getInventoryObject();
bool is_sidepanel = isInOutfitsSidePanel();
if (is_sidepanel)
{
// Sidepanel includes restricted menu.
if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
{
items.push_back(std::string("Remove Link"));
}
return;
}
if (obj)
{
if (obj->getIsLinkType())
@ -566,6 +613,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
items.push_back(std::string("Paste Separator"));
if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
{
items.push_back(std::string("Remove Link"));
}
items.push_back(std::string("Delete"));
if (!isItemRemovable())
{
@ -714,20 +767,20 @@ BOOL LLInvFVBridge::isItemPermissive() const
// static
void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
LLViewerInventoryItem* item,
const LLUUID& new_parent,
const LLUUID& new_parent_id,
BOOL restamp)
{
if(item->getParentUUID() != new_parent)
if(item->getParentUUID() != new_parent_id)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->setParent(new_parent);
new_item->setParent(new_parent_id);
new_item->updateParentOnServer(restamp);
model->updateItem(new_item);
model->notifyObservers();
@ -737,24 +790,27 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
// static
void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model,
LLViewerInventoryCategory* cat,
const LLUUID& new_parent,
const LLUUID& new_parent_id,
BOOL restamp)
{
if(cat->getParentUUID() != new_parent)
// Can't move a folder into a child of itself.
if (model->isObjectDescendentOf(new_parent_id, cat->getUUID()))
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
new_cat->setParent(new_parent);
new_cat->updateParentOnServer(restamp);
model->updateCategory(new_cat);
model->notifyObservers();
return;
}
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
update.push_back(new_folder);
model->accountForUpdate(update);
LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
new_cat->setParent(new_parent_id);
new_cat->updateParentOnServer(restamp);
model->updateCategory(new_cat);
model->notifyObservers();
}
@ -910,6 +966,16 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
}
}
bool LLInvFVBridge::isInOutfitsSidePanel() const
{
LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLPanelOutfitsInventory *outfit_panel =
dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
if (!outfit_panel)
return false;
return outfit_panel->isAccordionPanel(my_panel);
}
// +=================================================+
// | InventoryFVBridgeBuilder |
// +=================================================+
@ -1405,13 +1471,14 @@ BOOL LLFolderBridge::isItemRemovable()
{
return FALSE;
}
// Allow protected types to be removed, but issue a warning.
/*
if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
// Restrict to god mode so users don't inadvertently mess up their inventory.
if(LLFolderType::lookupIsProtectedType(category->getPreferredType()) &&
!gAgent.isGodlike())
{
return FALSE;
}
*/
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
@ -2243,11 +2310,6 @@ BOOL LLFolderBridge::removeItem()
LLNotification::Params params("ConfirmDeleteProtectedCategory");
params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
//params.functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
/*
LLNotification::Params params("ChangeLindenEstate");
params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
*/
if (LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
LLNotifications::instance().add(params);
@ -2278,14 +2340,16 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re
LLInventoryModel::item_array_t descendent_items;
gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
S32 i;
for (i = 0; i < descendent_items.count(); i++)
for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin();
iter != descendent_items.end();
++iter)
{
LLInventoryItem* item = descendent_items[i];
const LLViewerInventoryItem* item = (*iter);
const LLUUID& item_id = item->getUUID();
if (item->getType() == LLAssetType::AT_GESTURE
&& LLGestureManager::instance().isGestureActive(item->getUUID()))
&& LLGestureManager::instance().isGestureActive(item_id))
{
LLGestureManager::instance().deactivateGesture(item->getUUID());
LLGestureManager::instance().deactivateGesture(item_id);
}
}
@ -2306,14 +2370,16 @@ void LLFolderBridge::pasteFromClipboard()
LLInventoryModel* model = getInventoryModel();
if(model && isClipboardPasteable())
{
LLInventoryItem* item = NULL;
const LLUUID parent_id(mUUID);
LLDynamicArray<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
S32 count = objects.count();
const LLUUID parent_id(mUUID);
for(S32 i = 0; i < count; i++)
for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
iter != objects.end();
++iter)
{
item = model->getItem(objects.get(i));
const LLUUID& item_id = (*iter);
LLInventoryItem *item = model->getItem(item_id);
if (item)
{
if(LLInventoryClipboard::instance().isCutMode())
@ -2342,13 +2408,15 @@ void LLFolderBridge::pasteLinkFromClipboard()
const LLInventoryModel* model = getInventoryModel();
if(model)
{
const LLUUID parent_id(mUUID);
LLDynamicArray<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
S32 count = objects.count();
LLUUID parent_id(mUUID);
for(S32 i = 0; i < count; i++)
for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
iter != objects.end();
++iter)
{
const LLUUID &object_id = objects.get(i);
const LLUUID &object_id = (*iter);
#if SUPPORT_ENSEMBLES
if (LLInventoryCategory *cat = model->getCategory(object_id))
{
@ -2382,19 +2450,6 @@ void LLFolderBridge::staticFolderOptionsMenu()
sSelf->folderOptionsMenu();
}
bool isInOutfitsSidePanel(LLPanel *panel)
{
LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(panel);
LLPanelOutfitsInventory *outfit_panel =
dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
if (!outfit_panel)
return false;
return outfit_panel->isAccordionPanel(my_panel);
//LLInventoryPanel *outfit_inv_panel = outfit_panel ? outfit_panel->getActivePanel(): NULL;
//return (my_panel && (my_panel == outfit_inv_panel));
}
void LLFolderBridge::folderOptionsMenu()
{
std::vector<std::string> disabled_items;
@ -2408,13 +2463,12 @@ void LLFolderBridge::folderOptionsMenu()
// BAP change once we're no longer treating regular categories as ensembles.
const bool is_ensemble = category && (type == LLFolderType::FT_NONE ||
LLFolderType::lookupIsEnsembleType(type));
const bool is_sidepanel = isInOutfitsSidePanel(mInventoryPanel.get());
// calling card related functionality for folders.
const bool is_sidepanel = isInOutfitsSidePanel();
if (is_sidepanel)
{
mItems.clear();
mItems.push_back("Rename");
mItems.push_back("Delete");
}
@ -2455,6 +2509,8 @@ void LLFolderBridge::folderOptionsMenu()
mItems.push_back(std::string("Wear As Ensemble"));
}
mItems.push_back(std::string("Remove From Outfit"));
mItems.push_back(std::string("Outfit Separator"));
}
hide_context_entries(*mMenu, mItems, disabled_items);
@ -2482,14 +2538,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.clear();
lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
// std::vector<std::string> disabled_items;
LLInventoryModel* model = getInventoryModel();
if(!model) return;
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
mItems.clear(); //adding code to clear out member Items (which means Items should not have other data here at this point)
mDisabledItems.clear(); //adding code to clear out disabled members from previous
if (lost_and_found_id == mUUID)
{
// This is the lost+found folder.
@ -2518,7 +2573,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
LLViewerInventoryCategory *cat = getCategory();
// BAP removed protected check to re-enable standard ops in untyped folders.
// Not sure what the right thing is to do here.
if (!isCOFFolder() && cat /*&&
if (!isCOFFolder() && cat && cat->getPreferredType()!=LLFolderType::FT_OUTFIT /*&&
LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())*/)
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
@ -3144,6 +3199,22 @@ void LLTextureBridge::openItem()
}
}
bool LLTextureBridge::canSaveTexture(void)
{
const LLInventoryModel* model = getInventoryModel();
if(!model)
{
return false;
}
const LLViewerInventoryItem *item = model->getItem(mUUID);
if (item)
{
return item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
}
return false;
}
void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;
@ -3168,6 +3239,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Texture Separator"));
items.push_back(std::string("Save As"));
if (!canSaveTexture())
{
disabled_items.push_back(std::string("Save As"));
}
}
hide_context_entries(menu, items, disabled_items);
}
@ -3770,8 +3845,13 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
items.push_back(std::string("Open"));
items.push_back(std::string("Properties"));
bool is_sidepanel = isInOutfitsSidePanel();
if (!is_sidepanel)
{
items.push_back(std::string("Open"));
items.push_back(std::string("Properties"));
}
getClipboardEntries(true, items, disabled_items, flags);
@ -4095,13 +4175,18 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
items.push_back(std::string("Properties"));
bool is_sidepanel = isInOutfitsSidePanel();
if (!is_sidepanel)
{
items.push_back(std::string("Properties"));
}
LLInventoryItem *item = getItem();
getClipboardEntries(true, items, disabled_items, flags);
LLObjectBridge::sContextMenuItemID = mUUID;
LLInventoryItem *item = getItem();
if(item)
{
LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
@ -4527,19 +4612,23 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
can_open = FALSE;
}
if (can_open)
bool is_sidepanel = isInOutfitsSidePanel();
if (can_open && !is_sidepanel)
{
items.push_back(std::string("Open"));
}
items.push_back(std::string("Properties"));
if (!is_sidepanel)
{
items.push_back(std::string("Properties"));
}
getClipboardEntries(true, items, disabled_items, flags);
items.push_back(std::string("Wearable Separator"));
items.push_back(std::string("Wearable Wear"));
items.push_back(std::string("Wearable Add"));
items.push_back(std::string("Wearable Edit"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
@ -4569,6 +4658,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
items.push_back(std::string("Wearable Wear"));
items.push_back(std::string("Wearable Add"));
disabled_items.push_back(std::string("Take Off"));
}
break;
@ -4738,7 +4829,8 @@ void LLWearableBridge::onEditOnAvatar(void* user_data)
void LLWearableBridge::editOnAvatar()
{
const LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID);
LLUUID linked_id = gInventory.getLinkedItemID(mUUID);
const LLWearable* wearable = gAgentWearables.getWearableFromItemID(linked_id);
if( wearable )
{
// Set the tab to the right wearable.

View File

@ -182,6 +182,9 @@ public:
// LLInvFVBridge functionality
virtual void clearDisplayName() {}
// Allow context menus to be customized for side panel.
bool isInOutfitsSidePanel() const;
protected:
LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid);
@ -377,6 +380,7 @@ public:
protected:
LLTextureBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type) :
LLItemBridge(inventory, uuid), mInvType(type) {}
bool canSaveTexture(void);
LLInventoryType::EType mInvType;
};

View File

@ -40,6 +40,7 @@
#include "llinventorymodel.h" // gInventory.backgroundFetchActive()
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llfolderview.h"
// linden library includes
#include "lltrans.h"
@ -63,7 +64,8 @@ LLInventoryFilter::FilterOps::FilterOps() :
LLInventoryFilter::LLInventoryFilter(const std::string& name)
: mName(name),
mModified(FALSE),
mNeedTextRebuild(TRUE)
mNeedTextRebuild(TRUE),
mEmptyLookupMessage("InventoryNoMatchingItems")
{
mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
@ -95,26 +97,14 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
return TRUE;
}
const U16 HOURS_TO_SECONDS = 3600;
time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
{
earliest = mFilterOps.mMinDate;
}
else if (!mFilterOps.mHoursAgo)
{
earliest = 0;
}
const LLFolderViewEventListener* listener = item->getListener();
mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
const BOOL passed_filtertype = checkAgainstFilterType(item);
const BOOL passed = passed_filtertype &&
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) &&
((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) &&
(listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions);
return passed;
}
@ -127,27 +117,38 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item)
const LLUUID object_id = listener->getUUID();
const LLInventoryObject *object = gInventory.getObject(object_id);
if (!object) return FALSE;
const U32 filterTypes = mFilterOps.mFilterTypes;
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_OBJECT
// Pass if this item's type is of the correct filter type
if (filterTypes & FILTERTYPE_OBJECT)
{
// If it has no type, pass it, unless it's a link.
if (object_type == LLInventoryType::IT_NONE)
{
if (object->getIsLinkType())
if (object && object->getIsLinkType())
return FALSE;
}
if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
{
return FALSE;
}
}
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_CATEGORY
// Pass if this item is a category of the filter type, or
// if its parent is a category of the filter type.
if (filterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
if (!object) return FALSE;
LLUUID cat_id = object_id;
if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
{
@ -159,13 +160,45 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item)
if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
return FALSE;
}
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_UUID
// Pass if this item is the target UUID or if it links to the target UUID
if (filterTypes & FILTERTYPE_UUID)
{
if (!object) return FALSE;
if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
return FALSE;
}
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_DATE
// Pass if this item is within the date range.
if (filterTypes & FILTERTYPE_DATE)
{
const U16 HOURS_TO_SECONDS = 3600;
time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
{
earliest = mFilterOps.mMinDate;
}
else if (!mFilterOps.mHoursAgo)
{
earliest = 0;
}
if (listener->getCreationDate() < earliest ||
listener->getCreationDate() > mFilterOps.mMaxDate)
return FALSE;
}
//
////////////////////////////////////////////////////////////////////////////////
return TRUE;
}
@ -297,7 +330,6 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
mFilterSubString = string;
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
if (less_restrictive)
{
setModified(FILTER_LESS_RESTRICTIVE);
@ -359,6 +391,7 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
setModified();
}
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
}
void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
@ -373,12 +406,14 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
setDateRange(0, time_max());
setModified();
}
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
}
BOOL LLInventoryFilter::isSinceLogoff() const
{
return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
(mFilterOps.mMaxDate == time_max());
(mFilterOps.mMaxDate == time_max()) &&
(mFilterOps.mFilterTypes & FILTERTYPE_DATE);
}
void LLInventoryFilter::clearModified()
@ -410,7 +445,9 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
setModified(FILTER_RESTART);
}
}
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
}
void LLInventoryFilter::setShowFolderState(EFolderShow state)
{
if (mFilterOps.mShowFolderState != state)
@ -475,21 +512,21 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
// if not keeping current filter results, update last valid as well
switch(mFilterBehavior)
{
case FILTER_RESTART:
mMustPassGeneration = mFilterGeneration;
mMinRequiredGeneration = mFilterGeneration;
break;
case FILTER_LESS_RESTRICTIVE:
mMustPassGeneration = mFilterGeneration;
break;
case FILTER_MORE_RESTRICTIVE:
mMinRequiredGeneration = mFilterGeneration;
// must have passed either current filter generation (meaningless, as it hasn't been run yet)
// or some older generation, so keep the value
mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
break;
default:
llerrs << "Bad filter behavior specified" << llendl;
case FILTER_RESTART:
mMustPassGeneration = mFilterGeneration;
mMinRequiredGeneration = mFilterGeneration;
break;
case FILTER_LESS_RESTRICTIVE:
mMustPassGeneration = mFilterGeneration;
break;
case FILTER_MORE_RESTRICTIVE:
mMinRequiredGeneration = mFilterGeneration;
// must have passed either current filter generation (meaningless, as it hasn't been run yet)
// or some older generation, so keep the value
mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
break;
default:
llerrs << "Bad filter behavior specified" << llendl;
}
}
else
@ -825,3 +862,14 @@ S32 LLInventoryFilter::getMustPassGeneration() const
{
return mMustPassGeneration;
}
void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
{
mEmptyLookupMessage = message;
}
const std::string& LLInventoryFilter::getEmptyLookupMessage() const
{
return mEmptyLookupMessage;
}

View File

@ -61,7 +61,8 @@ public:
FILTERTYPE_NONE = 0,
FILTERTYPE_OBJECT = 1, // normal default search-by-object-type
FILTERTYPE_CATEGORY = 2, // search by folder type
FILTERTYPE_UUID = 4 // find the object with UUID and any links to it
FILTERTYPE_UUID = 4, // find the object with UUID and any links to it
FILTERTYPE_DATE = 8 // search by date range
};
// REFACTOR: Change this to an enum.
@ -72,13 +73,6 @@ public:
LLInventoryFilter(const std::string& name);
virtual ~LLInventoryFilter();
// +-------------------------------------------------------------------+
// + Execution And Results
// +-------------------------------------------------------------------+
BOOL check(const LLFolderViewItem* item);
BOOL checkAgainstFilterType(const LLFolderViewItem* item);
std::string::size_type getStringMatchOffset() const;
// +-------------------------------------------------------------------+
// + Parameters
// +-------------------------------------------------------------------+
@ -103,12 +97,25 @@ public:
void setHoursAgo(U32 hours);
U32 getHoursAgo() const;
// +-------------------------------------------------------------------+
// + Execution And Results
// +-------------------------------------------------------------------+
BOOL check(const LLFolderViewItem* item);
BOOL checkAgainstFilterType(const LLFolderViewItem* item);
std::string::size_type getStringMatchOffset() const;
// +-------------------------------------------------------------------+
// + Presentation
// +-------------------------------------------------------------------+
void setShowFolderState( EFolderShow state);
EFolderShow getShowFolderState() const;
void setSortOrder(U32 order);
U32 getSortOrder() const;
void setEmptyLookupMessage(const std::string& message);
const std::string& getEmptyLookupMessage() const;
// +-------------------------------------------------------------------+
// + Status
// +-------------------------------------------------------------------+
@ -187,6 +194,7 @@ private:
BOOL mModified;
BOOL mNeedTextRebuild;
std::string mFilterText;
std::string mEmptyLookupMessage;
};
#endif

View File

@ -59,7 +59,8 @@
BOOL LLInventoryModel::sBackgroundFetchActive = FALSE;
BOOL LLInventoryModel::sAllFoldersFetched = FALSE;
BOOL LLInventoryModel::sFullFetchStarted = FALSE;
BOOL LLInventoryModel::sMyInventoryFetchStarted = FALSE;
BOOL LLInventoryModel::sLibraryFetchStarted = FALSE;
S32 LLInventoryModel::sNumFetchRetries = 0;
F32 LLInventoryModel::sMinTimeBetweenFetches = 0.3f;
F32 LLInventoryModel::sMaxTimeBetweenFetches = 10.f;
@ -192,6 +193,8 @@ void LLInventoryModel::cleanupInventory()
BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id,
const LLUUID& cat_id) const
{
if (obj_id == cat_id) return TRUE;
const LLInventoryObject* obj = getObject(obj_id);
while(obj)
{
@ -1340,11 +1343,11 @@ bool LLInventoryModel::isBulkFetchProcessingComplete()
&& sBulkFetchCount<=0) ? TRUE : FALSE ) ;
}
class fetchDescendentsResponder: public LLHTTPClient::Responder
class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder
{
public:
fetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
//fetchDescendentsResponder() {};
LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
//LLInventoryModelFetchDescendentsResponder() {};
void result(const LLSD& content);
void error(U32 status, const std::string& reason);
public:
@ -1354,7 +1357,7 @@ class fetchDescendentsResponder: public LLHTTPClient::Responder
};
//If we get back a normal response, handle it here
void fetchDescendentsResponder::result(const LLSD& content)
void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
{
if (content.has("folders"))
{
@ -1421,7 +1424,8 @@ void fetchDescendentsResponder::result(const LLSD& content)
LLSD category = *category_it;
tcategory->fromLLSD(category);
if (LLInventoryModel::sFullFetchStarted)
if (LLInventoryModel::sMyInventoryFetchStarted ||
LLInventoryModel::sLibraryFetchStarted)
{
sFetchQueue.push_back(tcategory->getUUID());
}
@ -1473,20 +1477,16 @@ void fetchDescendentsResponder::result(const LLSD& content)
if (LLInventoryModel::isBulkFetchProcessingComplete())
{
llinfos << "Inventory fetch completed" << llendl;
if (LLInventoryModel::sFullFetchStarted)
{
LLInventoryModel::sAllFoldersFetched = TRUE;
}
LLInventoryModel::stopBackgroundFetch();
LLInventoryModel::setAllFoldersFetched();
}
gInventory.notifyObservers("fetchDescendents");
}
//If we get back an error (not found, etc...), handle it here
void fetchDescendentsResponder::error(U32 status, const std::string& reason)
void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)
{
llinfos << "fetchDescendentsResponder::error "
llinfos << "LLInventoryModelFetchDescendentsResponder::error "
<< status << ": " << reason << llendl;
LLInventoryModel::incrBulkFetch(-1);
@ -1506,11 +1506,7 @@ void fetchDescendentsResponder::error(U32 status, const std::string& reason)
{
if (LLInventoryModel::isBulkFetchProcessingComplete())
{
if (LLInventoryModel::sFullFetchStarted)
{
LLInventoryModel::sAllFoldersFetched = TRUE;
}
LLInventoryModel::stopBackgroundFetch();
LLInventoryModel::setAllFoldersFetched();
}
}
gInventory.notifyObservers("fetchDescendents");
@ -1578,7 +1574,8 @@ void LLInventoryModel::bulkFetch(std::string url)
body["folders"].append(folder_sd);
folder_count++;
}
if (sFullFetchStarted)
if (sMyInventoryFetchStarted ||
sLibraryFetchStarted)
{ //Already have this folder but append child folders to list.
// add all children to queue
parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID());
@ -1603,22 +1600,18 @@ void LLInventoryModel::bulkFetch(std::string url)
sBulkFetchCount++;
if (body["folders"].size())
{
LLHTTPClient::post(url, body, new fetchDescendentsResponder(body),300.0);
LLHTTPClient::post(url, body, new LLInventoryModelFetchDescendentsResponder(body),300.0);
}
if (body_lib["folders"].size())
{
std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents");
LLHTTPClient::post(url_lib, body_lib, new fetchDescendentsResponder(body_lib),300.0);
LLHTTPClient::post(url_lib, body_lib, new LLInventoryModelFetchDescendentsResponder(body_lib),300.0);
}
sFetchTimer.reset();
}
else if (isBulkFetchProcessingComplete())
{
if (sFullFetchStarted)
{
sAllFoldersFetched = TRUE;
}
stopBackgroundFetch();
setAllFoldersFetched();
}
}
@ -1634,7 +1627,6 @@ BOOL LLInventoryModel::backgroundFetchActive()
return sBackgroundFetchActive;
}
//static
void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id)
{
if (!sAllFoldersFetched)
@ -1642,9 +1634,16 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id)
sBackgroundFetchActive = TRUE;
if (cat_id.isNull())
{
if (!sFullFetchStarted)
if (!sMyInventoryFetchStarted)
{
sFullFetchStarted = TRUE;
sMyInventoryFetchStarted = TRUE;
sFetchQueue.push_back(gInventory.getLibraryRootFolderID());
sFetchQueue.push_back(gInventory.getRootFolderID());
gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL);
}
if (!sLibraryFetchStarted)
{
sLibraryFetchStarted = TRUE;
sFetchQueue.push_back(gInventory.getLibraryRootFolderID());
sFetchQueue.push_back(gInventory.getRootFolderID());
gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL);
@ -1658,6 +1657,14 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id)
sFetchQueue.push_front(cat_id);
gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL);
}
if (cat_id == gInventory.getLibraryRootFolderID())
{
sLibraryFetchStarted = TRUE;
}
if (cat_id == gInventory.getRootFolderID())
{
sMyInventoryFetchStarted = TRUE;
}
}
}
}
@ -1679,10 +1686,20 @@ void LLInventoryModel::stopBackgroundFetch()
gIdleCallbacks.deleteFunction(&LLInventoryModel::backgroundFetch, NULL);
sBulkFetchCount=0;
sMinTimeBetweenFetches=0.0f;
// sFullFetchStarted=FALSE;
}
}
// static
void LLInventoryModel::setAllFoldersFetched()
{
if (sMyInventoryFetchStarted &&
sLibraryFetchStarted)
{
sAllFoldersFetched = TRUE;
}
stopBackgroundFetch();
}
//static
void LLInventoryModel::backgroundFetch(void*)
{
@ -1701,11 +1718,8 @@ void LLInventoryModel::backgroundFetch(void*)
if (sFetchQueue.empty())
{
llinfos << "Inventory fetch completed" << llendl;
if (sFullFetchStarted)
{
sAllFoldersFetched = TRUE;
}
stopBackgroundFetch();
setAllFoldersFetched();
return;
}

View File

@ -72,6 +72,8 @@ class LLInventoryCollectFunctor;
class LLInventoryModel
{
public:
friend class LLInventoryModelFetchDescendentsResponder;
enum EHasChildren
{
CHILDREN_NO,
@ -282,9 +284,6 @@ public:
// Make sure we have the descendents in the structure. Returns true
// if a fetch was performed.
bool fetchDescendentsOf(const LLUUID& folder_id);
// Add categories to a list to be fetched in bulk.
static void bulkFetch(std::string url);
// call this method to request the inventory.
//void requestFromServer(const LLUUID& agent_id);
@ -369,15 +368,7 @@ public:
// Utility Functions
void removeItem(const LLUUID& item_id);
// start and stop background breadth-first fetching of inventory contents
// this gets triggered when performing a filter-search
static void startBackgroundFetch(const LLUUID& cat_id = LLUUID::null); // start fetch process
static void findLostItems();
static BOOL backgroundFetchActive();
static bool isEverythingFetched();
static void backgroundFetch(void*); // background fetch idle function
static void incrBulkFetch(S16 fetching) { sBulkFetchCount+=fetching; if (sBulkFetchCount<0) sBulkFetchCount=0; }
// Data about the agent's root folder and root library folder
// are stored here, rather than in LLAgent where it used to be, because
@ -477,14 +468,11 @@ private:
LLUUID mLibraryRootFolderID;
LLUUID mLibraryOwnerID;
// completing the fetch once per session should be sufficient
static BOOL sBackgroundFetchActive;
static BOOL sTimelyFetchPending;
static S32 sNumFetchRetries;
static LLFrameTimer sFetchTimer;
static F32 sMinTimeBetweenFetches;
static F32 sMaxTimeBetweenFetches;
static S16 sBulkFetchCount;
// Expected inventory cache version
const static S32 sCurrentInvCacheVersion;
@ -510,11 +498,33 @@ private:
public:
// *NOTE: DEBUG functionality
void dumpInventory() const;
static bool isBulkFetchProcessingComplete();
static void stopBackgroundFetch(); // stop fetch process
static BOOL sFullFetchStarted;
////////////////////////////////////////////////////////////////////////////////
// Bulk / Background Fetch
public:
// Start and stop background breadth-first fetching of inventory contents.
// This gets triggered when performing a filter-search
void startBackgroundFetch(const LLUUID& cat_id = LLUUID::null);
static BOOL backgroundFetchActive();
static bool isEverythingFetched();
static void backgroundFetch(void*); // background fetch idle function
static void incrBulkFetch(S16 fetching) { sBulkFetchCount+=fetching; if (sBulkFetchCount<0) sBulkFetchCount=0; }
static void stopBackgroundFetch(); // stop fetch process
static bool isBulkFetchProcessingComplete();
// Add categories to a list to be fetched in bulk.
static void bulkFetch(std::string url);
private:
static BOOL sMyInventoryFetchStarted;
static BOOL sLibraryFetchStarted;
static BOOL sAllFoldersFetched;
static void setAllFoldersFetched();
// completing the fetch once per session should be sufficient
static BOOL sBackgroundFetchActive;
static S16 sBulkFetchCount;
};
// a special inventory model for the agent

View File

@ -903,13 +903,10 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
if (!auto_open) return NULL;
// D. Open the inventory side panel and use that.
LLSideTray *side_tray = LLSideTray::getInstance();
LLSD key;
LLSidepanelInventory *sidepanel_inventory =
dynamic_cast<LLSidepanelInventory *>(side_tray->getPanel("sidepanel_inventory"));
// Use the inventory side panel only if it is already active.
// Activating it may unexpectedly switch off the currently active tab in some cases.
if (sidepanel_inventory && (LLPanel*)side_tray->getActiveTab() == (LLPanel*)sidepanel_inventory)
dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->showPanel("sidepanel_inventory", key));
if (sidepanel_inventory)
{
return sidepanel_inventory->getActivePanel();
}

View File

@ -192,6 +192,7 @@ protected:
public:
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
const LLUUID& getStartFolderID() const { return mStartFolderID; }
const std::string& getStartFolderString() { return mStartFolderString; }
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();

View File

@ -58,12 +58,19 @@
// - Any request that gets a 503 still goes through the retry logic
//
//
// Forward decls
//
const F32 LLMediaDataClient::QUEUE_TIMER_DELAY = 1.0; // seconds(s)
const F32 LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY = 5.0; // secs
const U32 LLMediaDataClient::MAX_RETRIES = 4;
const U32 LLMediaDataClient::MAX_SORTED_QUEUE_SIZE = 10000;
const U32 LLMediaDataClient::MAX_ROUND_ROBIN_QUEUE_SIZE = 10000;
// << operators
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q);
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &q);
//////////////////////////////////////////////////////////////////////////////////////
//
// LLMediaDataClient
@ -395,7 +402,7 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue
LLMediaDataClient::request_queue_t::const_iterator end = q.end();
while (iter != end)
{
s << "\t" << i << "]: " << (*iter)->getObject()->getID().asString();
s << "\t" << i << "]: " << (*iter)->getObject()->getID().asString() << "(" << (*iter)->getObject()->getMediaInterest() << ")";
iter++;
i++;
}

View File

@ -127,7 +127,6 @@ LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
if (p.item_type == TYPE_BACKWARD)
{
setFont( p.back_item_font );
setLabel(std::string(" ") + std::string(p.label));
}
else if (p.item_type == TYPE_CURRENT)
{
@ -136,7 +135,6 @@ LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
else
{
setFont( p.forward_item_font );
setLabel(std::string(" ") + std::string(p.label));
}
LLIconCtrl::Params icon_params;

View File

@ -265,6 +265,11 @@ public:
*/
static bool canLogToIM(const LLNotificationPtr& notification);
/**
* Checks sufficient conditions to log notification message to nearby chat session.
*/
static bool canLogToNearbyChat(const LLNotificationPtr& notification);
/**
* Checks sufficient conditions to spawn IM session.
*/
@ -287,6 +292,11 @@ public:
* Writes group notice notification message to IM group session.
*/
static void logGroupNoticeToIMGroup(const LLNotificationPtr& notification);
/**
* Writes notification message to nearby chat.
*/
static void logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type);
};
}

View File

@ -37,6 +37,8 @@
#include "llnotifications.h"
#include "llimview.h"
#include "llagent.h"
#include "llfloaterreg.h"
#include "llnearbychat.h"
using namespace LLNotificationsUI;
@ -47,7 +49,9 @@ const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
USER_GIVE_ITEM("UserGiveItem"), OFFER_FRIENDSHIP("OfferFriendship"),
FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
FRIENDSHIP_OFFERED("FriendshipOffered");
FRIENDSHIP_OFFERED("FriendshipOffered"),
FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
SERVER_OBJECT_MESSAGE("ServerObjectMessage");
// static
bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
@ -55,7 +59,16 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
return GRANTED_MODIFY_RIGHTS == notification->getName()
|| REVOKED_MODIFY_RIGHTS == notification->getName()
|| PAYMENT_RECIVED == notification->getName()
|| FRIENDSHIP_OFFERED == notification->getName();
|| FRIENDSHIP_OFFERED == notification->getName()
|| SERVER_OBJECT_MESSAGE == notification->getName();
}
// static
bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
{
return notification->getType() == "notifytip"
&& FRIEND_ONLINE != notification->getName()
&& FRIEND_OFFLINE != notification->getName();
}
// static
@ -144,3 +157,15 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
payload["group_id"], sender_id);
}
// static
void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
{
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
if(nearby_chat)
{
LLChat chat_msg(notification->getMessage());
chat_msg.mSourceType = type;
nearby_chat->addMessage(chat_msg);
}
}

View File

@ -88,18 +88,17 @@ bool LLTipHandler::processNotification(const LLSD& notify)
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
{
// archive message in nearby chat
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
if(nearby_chat)
if (LLHandlerUtil::canLogToNearbyChat(notification))
{
LLChat chat_msg(notification->getMessage());
chat_msg.mSourceType = CHAT_SOURCE_SYSTEM;
nearby_chat->addMessage(chat_msg);
LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
// don't show toast if Nearby Chat is opened
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<
LLNearbyChat>("nearby_chat", LLSD());
if (nearby_chat->getVisible())
{
return true;
}
}
}
LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);

View File

@ -51,6 +51,7 @@
#include "llfloaterworldmap.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llvoiceclient.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLDropTarget
@ -395,6 +396,7 @@ void LLPanelProfileTab::updateButtons()
&& gAgent.isGodlike() || is_agent_mappable(getAvatarId());
childSetEnabled("show_on_map_btn", enable_map_btn);
childSetEnabled("call", LLVoiceClient::voiceEnabled());
}
//////////////////////////////////////////////////////////////////////////

View File

@ -90,6 +90,7 @@ LLPanelGroup::LLPanelGroup()
: LLPanel(),
LLGroupMgrObserver( LLUUID() ),
mAllowEdit( TRUE )
,mShowingNotifyDialog(false)
{
// Set up the factory callbacks.
// Roles sub tabs
@ -538,3 +539,69 @@ void LLPanelGroup::showNotice(const std::string& subject,
}
bool LLPanelGroup::canClose()
{
if(getVisible() == false)
return true;
bool need_save = false;
std::string mesg;
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
if(need_save|=(*it)->needsApply(mesg))
break;
if(!need_save)
return false;
// If no message was provided, give a generic one.
if (mesg.empty())
{
mesg = mDefaultNeedsApplyMesg;
}
// Create a notify box, telling the user about the unapplied tab.
LLSD args;
args["NEEDS_APPLY_MESSAGE"] = mesg;
args["WANT_APPLY_MESSAGE"] = mWantApplyMesg;
LLNotificationsUtil::add("SaveChanges", args, LLSD(), boost::bind(&LLPanelGroup::handleNotifyCallback,this, _1, _2));
mShowingNotifyDialog = true;
return false;
}
bool LLPanelGroup::notifyChildren(const LLSD& info)
{
if(info.has("request") && mID.isNull() )
{
std::string str_action = info["request"];
if (str_action == "quit" )
{
canClose();
return true;
}
if(str_action == "wait_quit")
return mShowingNotifyDialog;
}
return false;
}
bool LLPanelGroup::handleNotifyCallback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
mShowingNotifyDialog = false;
switch (option)
{
case 0: // "Apply Changes"
apply();
break;
case 1: // "Ignore Changes"
break;
case 2: // "Cancel"
default:
// Do nothing. The user is canceling the action.
// If we were quitting, we didn't really mean it.
LLAppViewer::instance()->abortQuit();
break;
}
return false;
}

View File

@ -89,7 +89,10 @@ public:
const std::string& inventory_name,
LLOfferInfo* inventory_offer);
bool notifyChildren (const LLSD& info);
bool handleNotifyCallback(const LLSD&, const LLSD&);
protected:
virtual void update(LLGroupChange gc);
@ -107,6 +110,9 @@ protected:
protected:
bool apply(LLPanelGroupTab* tab);
bool canClose();
bool mShowingNotifyDialog;
LLTimer mRefreshTimer;

View File

@ -101,14 +101,6 @@ void LLPanelChatControlPanel::draw()
&& callback_enabled;
childSetEnabled("call_btn", enable_connect);
// send a signal when the floater is fully initialized
// this lets LLAvatarActions::startAdhocCall() start the call
if (enable_connect && !mInitialized)
{
LLIMModel::sendSessionInitialized(mSessionId);
mInitialized = true;
}
LLPanel::draw();
}

View File

@ -45,8 +45,7 @@ class LLPanelChatControlPanel : public LLPanel
{
public:
LLPanelChatControlPanel() :
mSessionId(LLUUID()),
mInitialized(false) {};
mSessionId(LLUUID()) {};
~LLPanelChatControlPanel();
virtual BOOL postBuild();
@ -63,7 +62,6 @@ public:
private:
LLUUID mSessionId;
bool mInitialized;
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;

View File

@ -66,6 +66,30 @@ static const std::string TRASH_BUTTON_NAME = "trash_btn";
// helper functions
static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string);
static void save_folder_state_if_no_filter(LLInventorySubTreePanel* inventory_list);
/**
* Bridge to support knowing when the inventory has changed to update folder (open/close) state
* for landmarks panels.
*
* Due to Inventory data are loaded in background we need to save folder state each time
* next level is loaded. See EXT-3094.
*/
class LLLandmarksPanelObserver : public LLInventoryObserver
{
public:
LLLandmarksPanelObserver(LLLandmarksPanel* lp) : mLP(lp) {}
virtual ~LLLandmarksPanelObserver() {}
/*virtual*/ void changed(U32 mask);
private:
LLLandmarksPanel* mLP;
};
void LLLandmarksPanelObserver::changed(U32 mask)
{
mLP->saveFolderStateIfNoFilter();
}
LLLandmarksPanel::LLLandmarksPanel()
: LLPanelPlacesTab()
@ -78,11 +102,18 @@ LLLandmarksPanel::LLLandmarksPanel()
, mGearFolderMenu(NULL)
, mGearLandmarkMenu(NULL)
{
mInventoryObserver = new LLLandmarksPanelObserver(this);
gInventory.addObserver(mInventoryObserver);
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_landmarks.xml");
}
LLLandmarksPanel::~LLLandmarksPanel()
{
if (gInventory.containsObserver(mInventoryObserver))
{
gInventory.removeObserver(mInventoryObserver);
}
}
BOOL LLLandmarksPanel::postBuild()
@ -226,6 +257,14 @@ void LLLandmarksPanel::onSelectorButtonClicked()
}
}
void LLLandmarksPanel::saveFolderStateIfNoFilter()
{
save_folder_state_if_no_filter(mFavoritesInventoryPanel);
save_folder_state_if_no_filter(mLandmarksInventoryPanel);
save_folder_state_if_no_filter(mMyInventoryPanel);
save_folder_state_if_no_filter(mLibraryInventoryPanel);
}
//////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////
@ -327,6 +366,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()
mFavoritesInventoryPanel = getChild<LLInventorySubTreePanel>("favorites_list");
initLandmarksPanel(mFavoritesInventoryPanel);
mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems");
initAccordion("tab_favorites", mFavoritesInventoryPanel);
}
@ -389,9 +429,6 @@ void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_lis
}
root_folder->setParentLandmarksPanel(this);
// save initial folder state to avoid incorrect work while switching between Landmarks & Teleport History tabs
// See EXT-1609.
inventory_list->saveFolderState();
}
@ -747,7 +784,7 @@ void LLLandmarksPanel::updateFilteredAccordions()
{
LLInventoryPanel* inventory_list = NULL;
LLAccordionCtrlTab* accordion_tab = NULL;
// bool needs_arrange = false;
bool needs_arrange = false;
for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
{
@ -759,7 +796,7 @@ void LLLandmarksPanel::updateFilteredAccordions()
if (NULL == inventory_list) continue;
// This doesn't seem to work correctly. Disabling for now. -Seraph
/*
// Enabled to show/hide accordions with/without landmarks. See EXT-2346. (Seth PE)
LLFolderView* fv = inventory_list->getRootFolder();
// arrange folder view contents to draw its descendants if it has any
@ -770,17 +807,17 @@ void LLLandmarksPanel::updateFilteredAccordions()
needs_arrange = true;
accordion_tab->setVisible(has_descendants);
*/
accordion_tab->setVisible(TRUE);
//accordion_tab->setVisible(TRUE);
}
// we have to arrange accordion tabs for cases when filter string is less restrictive but
// all items are still filtered.
// if (needs_arrange)
// {
if (needs_arrange)
{
static LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
accordion->arrange();
// }
}
}
/*
@ -995,15 +1032,17 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
//////////////////////////////////////////////////////////////////////////
static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string)
{
// When search is cleared, restore the old folder state.
if (string == "")
{
inventory_list->setFilterSubString(LLStringUtil::null);
// re-open folders that were initially open
// Re-open folders that were open before
inventory_list->restoreFolderState();
}
gInventory.startBackgroundFetch();
// Open the immediate children of the root folder, since those
// are invisible in the UI and thus must always be open.
inventory_list->getRootFolder()->openTopLevelFolders();
if (inventory_list->getFilterSubString().empty() && string.empty())
{
@ -1017,7 +1056,17 @@ static void filter_list(LLInventorySubTreePanel* inventory_list, const std::stri
inventory_list->saveFolderState();
}
// set new filter string
// Set new filter string
inventory_list->setFilterSubString(string);
}
static void save_folder_state_if_no_filter(LLInventorySubTreePanel* inventory_list)
{
// save current folder open state if no filter currently applied
if (inventory_list->getRootFolder() && inventory_list->getRootFolder()->getFilterSubString().empty())
{
// inventory_list->saveFolderState(); // *TODO: commented out to fix build
}
}
// EOF

View File

@ -67,6 +67,11 @@ public:
mCurrentSelectedList = inventory_list;
}
/**
* Saves folder state for all Inventory Panels if there are no applied filter.
*/
void saveFolderStateIfNoFilter();
protected:
/**
* @return true - if current selected panel is not null and selected item is a landmark
@ -151,6 +156,7 @@ private:
LLMenuGL* mGearFolderMenu;
LLMenuGL* mMenuAdd;
LLInventorySubTreePanel* mCurrentSelectedList;
LLInventoryObserver* mInventoryObserver;
LLPanel* mListCommands;
bool mSortByDate;

View File

@ -73,6 +73,11 @@
#include "llfloatertos.h"
#include "lltrans.h"
#include "llglheaders.h"
#include "llpanelloginlistener.h"
#if LL_WINDOWS
#pragma warning(disable: 4355) // 'this' used in initializer list
#endif // LL_WINDOWS
#define USE_VIEWER_AUTH 0
@ -166,7 +171,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mLogoImage(),
mCallback(callback),
mCallbackData(cb_data),
mHtmlAvailable( TRUE )
mHtmlAvailable( TRUE ),
mListener(new LLPanelLoginListener(this))
{
setFocusRoot(TRUE);
@ -452,7 +458,7 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
if ( KEY_F1 == key )
{
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
vhelp->showTopic(vhelp->getTopicFromFocus());
vhelp->showTopic(vhelp->f1HelpTopic());
return TRUE;
}
@ -972,7 +978,7 @@ void LLPanelLogin::onClickHelp(void*)
if (sInstance)
{
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
vhelp->showTopic(vhelp->getTopicFromFocus());
vhelp->showTopic(vhelp->preLoginTopic());
}
}

View File

@ -36,10 +36,11 @@
#include "llpanel.h"
#include "llpointer.h" // LLPointer<>
#include "llmediactrl.h" // LLMediaCtrlObserver
#include <boost/scoped_ptr.hpp>
class LLLineEditor;
class LLUIImage;
class LLPanelLoginListener;
class LLPanelLogin:
public LLPanel,
@ -90,6 +91,7 @@ public:
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
private:
friend class LLPanelLoginListener;
void reshapeBrowser();
static void onClickConnect(void*);
static void onClickNewAccount(void*);
@ -103,6 +105,7 @@ private:
private:
LLPointer<LLUIImage> mLogoImage;
boost::scoped_ptr<LLPanelLoginListener> mListener;
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;

View File

@ -0,0 +1,34 @@
/**
* @file llpanelloginlistener.cpp
* @author Nat Goodspeed
* @date 2009-12-10
* @brief Implementation for llpanelloginlistener.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
* Copyright (c) 2009, Linden Research, Inc.
* $/LicenseInfo$
*/
// Precompiled header
#include "llviewerprecompiledheaders.h"
// associated header
#include "llpanelloginlistener.h"
// STL headers
// std headers
// external library headers
// other Linden headers
#include "llpanellogin.h"
LLPanelLoginListener::LLPanelLoginListener(LLPanelLogin* instance):
LLEventAPI("LLPanelLogin", "Access to LLPanelLogin methods"),
mPanel(instance)
{
add("onClickConnect",
"Pretend user clicked the \"Log In\" button",
&LLPanelLoginListener::onClickConnect);
}
void LLPanelLoginListener::onClickConnect(const LLSD&) const
{
mPanel->onClickConnect(NULL);
}

View File

@ -0,0 +1,30 @@
/**
* @file llpanelloginlistener.h
* @author Nat Goodspeed
* @date 2009-12-10
* @brief LLEventAPI for LLPanelLogin
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
* Copyright (c) 2009, Linden Research, Inc.
* $/LicenseInfo$
*/
#if ! defined(LL_LLPANELLOGINLISTENER_H)
#define LL_LLPANELLOGINLISTENER_H
#include "lleventapi.h"
class LLPanelLogin;
class LLSD;
class LLPanelLoginListener: public LLEventAPI
{
public:
LLPanelLoginListener(LLPanelLogin* instance);
private:
void onClickConnect(const LLSD&) const;
LLPanelLogin* mPanel;
};
#endif /* ! defined(LL_LLPANELLOGINLISTENER_H) */

View File

@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelmaininventory.h"
#include "llagent.h"
#include "lldndbutton.h"
#include "llfilepicker.h"
#include "llfloaterinventory.h"
@ -863,7 +864,6 @@ void LLPanelMainInventory::initListCommandsHandlers()
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
}
void LLPanelMainInventory::updateListCommands()
@ -909,6 +909,22 @@ void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
}
void LLPanelMainInventory::saveTexture(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
return;
}
const LLUUID& item_id = current_item->getListener()->getUUID();
LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
if (preview_texture)
{
preview_texture->openToSave();
}
}
void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
if (!isActionEnabled(userdata))
@ -953,18 +969,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
if (command_name == "save_texture")
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
return;
}
const LLUUID& item_id = current_item->getListener()->getUUID();
LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
if (preview_texture)
{
preview_texture->openToSave();
}
saveTexture(userdata);
}
// This doesn't currently work, since the viewer can't change an assetID an item.
if (command_name == "regenerate_link")
@ -1008,6 +1013,22 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
}
bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (current_item)
{
LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
if(inv_item)
{
bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
}
}
return false;
}
BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
const std::string command_name = userdata.asString();
@ -1020,6 +1041,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
can_delete = TRUE;
std::set<LLUUID> selection_set;
folder->getSelectionList(selection_set);
if (selection_set.empty()) return FALSE;
for (std::set<LLUUID>::iterator iter = selection_set.begin();
iter != selection_set.end();
++iter)
@ -1034,12 +1056,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
}
if (command_name == "save_texture")
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (current_item)
{
return (current_item->getListener()->getInventoryType() == LLInventoryType::IT_TEXTURE);
}
return FALSE;
return isSaveTextureEnabled(userdata);
}
if (command_name == "find_original")
{

View File

@ -110,6 +110,8 @@ protected:
void doCreate(const LLSD& userdata);
void resetFilters();
void setSortBy(const LLSD& userdata);
void saveTexture(const LLSD& userdata);
bool isSaveTextureEnabled(const LLSD& userdata);
private:
LLFloaterInventoryFinder* getFinder();

View File

@ -264,4 +264,4 @@ void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in )
void LLPanelMediaSettingsPermissions::postApply()
{
// no-op
}
}

View File

@ -157,7 +157,7 @@ LLInventoryItem* LLTaskInvFVBridge::findItem() const
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
if(object)
{
return (LLInventoryItem*)(object->getInventoryObject(mUUID));
return dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID));
}
return NULL;
}
@ -712,6 +712,7 @@ public:
virtual LLUIImagePtr getIcon() const;
virtual const std::string& getDisplayName() const { return getName(); }
virtual BOOL isItemRenameable() const;
// virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemRemovable();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
@ -1697,7 +1698,7 @@ void LLPanelObjectInventory::updateInventory()
mFolders->requestArrange();
mInventoryNeedsUpdate = FALSE;
LLEditMenuHandler::gEditMenuHandler = mFolders;
// Edit menu handler is set in onFocusReceived
}
// *FIX: This is currently a very expensive operation, because we have

View File

@ -136,6 +136,24 @@ void LLPanelOutfitsInventory::onWear()
}
}
void LLPanelOutfitsInventory::onAdd()
{
LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
if (listenerp)
{
listenerp->performAction(NULL, NULL,"addtooutfit");
}
}
void LLPanelOutfitsInventory::onRemove()
{
LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
if (listenerp)
{
listenerp->performAction(NULL, NULL,"removefromoutfit");
}
}
void LLPanelOutfitsInventory::onEdit()
{
}
@ -224,8 +242,10 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
, _7 // EAcceptance* accept
));
mCommitCallbackRegistrar.add("panel_outfits_inventory_gear_default.Custom.Action", boost::bind(&LLPanelOutfitsInventory::onCustomAction, this, _2));
mEnableCallbackRegistrar.add("panel_outfits_inventory_gear_default.Enable", boost::bind(&LLPanelOutfitsInventory::isActionEnabled, this, _2));
mCommitCallbackRegistrar.add("panel_outfits_inventory_gear_default.Custom.Action",
boost::bind(&LLPanelOutfitsInventory::onCustomAction, this, _2));
mEnableCallbackRegistrar.add("panel_outfits_inventory_gear_default.Enable",
boost::bind(&LLPanelOutfitsInventory::isActionEnabled, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("panel_outfits_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
}
@ -290,6 +310,22 @@ void LLPanelOutfitsInventory::onCustomAction(const LLSD& userdata)
{
onWear();
}
if (command_name == "add")
{
onAdd();
}
if (command_name == "remove")
{
onRemove();
}
if (command_name == "rename")
{
onClipboardAction("rename");
}
if (command_name == "remove_link")
{
onClipboardAction("delete");
}
if (command_name == "delete")
{
onClipboardAction("delete");
@ -320,8 +356,33 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
}
return FALSE;
}
if (command_name == "remove_link")
{
BOOL can_delete = FALSE;
LLFolderView *folder = getActivePanel()->getRootFolder();
if (folder)
{
can_delete = TRUE;
std::set<LLUUID> selection_set;
folder->getSelectionList(selection_set);
for (std::set<LLUUID>::iterator iter = selection_set.begin();
iter != selection_set.end();
++iter)
{
const LLUUID &item_id = (*iter);
LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (!item || !item->getIsLinkType())
return FALSE;
}
return can_delete;
}
return FALSE;
}
if (command_name == "edit" ||
command_name == "wear")
command_name == "wear" ||
command_name == "add" ||
command_name == "remove"
)
{
return (getCorrectListenerForAction() != NULL);
}

View File

@ -55,6 +55,8 @@ public:
void onSearchEdit(const std::string& string);
void onWear();
void onAdd();
void onRemove();
void onEdit();
void onNew();

View File

@ -775,7 +775,7 @@ void LLPanelPeople::updateButtons()
buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
buttonSetEnabled("view_profile_btn", item_selected);
buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
buttonSetEnabled("call_btn", multiple_selected);
buttonSetEnabled("call_btn", multiple_selected && LLVoiceClient::voiceEnabled());
buttonSetEnabled("share_btn", item_selected); // not implemented yet
bool none_group_selected = item_selected && selected_id.isNull();

View File

@ -100,7 +100,7 @@ LLContextMenu* NearbyMenu::createMenu()
registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, id));
registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this));
registrar.add("Avatar.ShowOnMap", boost::bind(&LLAvatarActions::startIM, id)); // *TODO: unimplemented
registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, id)); // *TODO: unimplemented
registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, id));
registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id));
registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, id));

View File

@ -181,6 +181,85 @@ LLPanelPermissions::~LLPanelPermissions()
}
void LLPanelPermissions::disableAll()
{
childSetEnabled("perm_modify", FALSE);
childSetText("perm_modify", LLStringUtil::null);
childSetEnabled("Creator:", FALSE);
childSetText("Creator Name", LLStringUtil::null);
childSetEnabled("Creator Name", FALSE);
childSetEnabled("Owner:", FALSE);
childSetText("Owner Name", LLStringUtil::null);
childSetEnabled("Owner Name", FALSE);
childSetEnabled("Group:", FALSE);
childSetText("Group Name", LLStringUtil::null);
childSetEnabled("Group Name", FALSE);
childSetEnabled("button set group", FALSE);
childSetText("Object Name", LLStringUtil::null);
childSetEnabled("Object Name", FALSE);
childSetEnabled("Name:", FALSE);
childSetText("Group Name", LLStringUtil::null);
childSetEnabled("Group Name", FALSE);
childSetEnabled("Description:", FALSE);
childSetText("Object Description", LLStringUtil::null);
childSetEnabled("Object Description", FALSE);
childSetEnabled("Permissions:", FALSE);
childSetValue("checkbox share with group", FALSE);
childSetEnabled("checkbox share with group", FALSE);
childSetEnabled("button deed", FALSE);
childSetValue("checkbox allow everyone move", FALSE);
childSetEnabled("checkbox allow everyone move", FALSE);
childSetValue("checkbox allow everyone copy", FALSE);
childSetEnabled("checkbox allow everyone copy", FALSE);
//Next owner can:
childSetEnabled("Next owner can:", FALSE);
childSetValue("checkbox next owner can modify", FALSE);
childSetEnabled("checkbox next owner can modify", FALSE);
childSetValue("checkbox next owner can copy", FALSE);
childSetEnabled("checkbox next owner can copy", FALSE);
childSetValue("checkbox next owner can transfer", FALSE);
childSetEnabled("checkbox next owner can transfer", FALSE);
//checkbox for sale
childSetValue("checkbox for sale", FALSE);
childSetEnabled("checkbox for sale", FALSE);
//checkbox include in search
childSetValue("search_check", FALSE);
childSetEnabled("search_check", FALSE);
LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
combo_sale_type->setValue(LLSaleInfo::FS_COPY);
combo_sale_type->setEnabled(FALSE);
childSetEnabled("Cost", FALSE);
childSetText("Cost", getString("Cost Default"));
childSetText("Edit Cost", LLStringUtil::null);
childSetEnabled("Edit Cost", FALSE);
childSetEnabled("label click action", FALSE);
LLComboBox* combo_click_action = getChild<LLComboBox>("clickaction");
if (combo_click_action)
{
combo_click_action->setEnabled(FALSE);
combo_click_action->clear();
}
childSetVisible("B:", FALSE);
childSetVisible("O:", FALSE);
childSetVisible("G:", FALSE);
childSetVisible("E:", FALSE);
childSetVisible("N:", FALSE);
childSetVisible("F:", FALSE);
}
void LLPanelPermissions::refresh()
{
LLButton* BtnDeedToGroup = getChild<LLButton>("button deed");
@ -215,136 +294,58 @@ void LLPanelPermissions::refresh()
if(!nodep || !objectp)// || attachment_selected)
{
// ...nothing selected
childSetEnabled("perm_modify",false);
childSetText("perm_modify",LLStringUtil::null);
childSetEnabled("Creator:",false);
childSetText("Creator Name",LLStringUtil::null);
childSetEnabled("Creator Name",false);
childSetEnabled("Owner:",false);
childSetText("Owner Name",LLStringUtil::null);
childSetEnabled("Owner Name",false);
childSetEnabled("Group:",false);
childSetText("Group Name",LLStringUtil::null);
childSetEnabled("Group Name",false);
childSetEnabled("button set group",false);
childSetText("Object Name",LLStringUtil::null);
childSetEnabled("Object Name",false);
childSetEnabled("Name:",false);
childSetText("Group Name",LLStringUtil::null);
childSetEnabled("Group Name",false);
childSetEnabled("Description:",false);
childSetText("Object Description",LLStringUtil::null);
childSetEnabled("Object Description",false);
childSetEnabled("Permissions:",false);
childSetValue("checkbox share with group",FALSE);
childSetEnabled("checkbox share with group",false);
childSetEnabled("button deed",false);
childSetValue("checkbox allow everyone move",FALSE);
childSetEnabled("checkbox allow everyone move",false);
childSetValue("checkbox allow everyone copy",FALSE);
childSetEnabled("checkbox allow everyone copy",false);
//Next owner can:
childSetEnabled("Next owner can:",false);
childSetValue("checkbox next owner can modify",FALSE);
childSetEnabled("checkbox next owner can modify",false);
childSetValue("checkbox next owner can copy",FALSE);
childSetEnabled("checkbox next owner can copy",false);
childSetValue("checkbox next owner can transfer",FALSE);
childSetEnabled("checkbox next owner can transfer",false);
//checkbox for sale
childSetValue("checkbox for sale",FALSE);
childSetEnabled("checkbox for sale",false);
//checkbox include in search
childSetValue("search_check", FALSE);
childSetEnabled("search_check", false);
LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
combo_sale_type->setValue(LLSaleInfo::FS_COPY);
combo_sale_type->setEnabled(FALSE);
childSetEnabled("Cost",false);
childSetText("Cost",getString("Cost Default"));
childSetText("Edit Cost",LLStringUtil::null);
childSetEnabled("Edit Cost",false);
childSetEnabled("label click action",false);
LLComboBox* ComboClickAction = getChild<LLComboBox>("clickaction");
if(ComboClickAction)
{
ComboClickAction->setEnabled(FALSE);
ComboClickAction->clear();
}
childSetVisible("B:",false);
childSetVisible("O:",false);
childSetVisible("G:",false);
childSetVisible("E:",false);
childSetVisible("N:",false);
childSetVisible("F:",false);
disableAll();
return;
}
// figure out a few variables
BOOL is_one_object = (object_count == 1);
const BOOL is_one_object = (object_count == 1);
// BUG: fails if a root and non-root are both single-selected.
BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
&& LLSelectMgr::getInstance()->selectGetRootsModify())
|| LLSelectMgr::getInstance()->selectGetModify();
&& LLSelectMgr::getInstance()->selectGetRootsModify())
|| LLSelectMgr::getInstance()->selectGetModify();
const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus();
S32 string_index = 0;
std::string MODIFY_INFO_STRINGS[] =
{
getString("text modify info 1"),
getString("text modify info 2"),
getString("text modify info 3"),
getString("text modify info 4")
};
if(!is_perm_modify)
{
getString("text modify info 1"),
getString("text modify info 2"),
getString("text modify info 3"),
getString("text modify info 4")
};
if (!is_perm_modify)
{
string_index += 2;
}
if(!is_one_object)
if (!is_one_object)
{
++string_index;
}
childSetEnabled("perm_modify",true);
childSetText("perm_modify",MODIFY_INFO_STRINGS[string_index]);
childSetEnabled("perm_modify", TRUE);
childSetText("perm_modify", MODIFY_INFO_STRINGS[string_index]);
childSetEnabled("Permissions:",true);
childSetEnabled("Permissions:", TRUE);
// Update creator text field
childSetEnabled("Creator:",true);
childSetEnabled("Creator:", TRUE);
BOOL creators_identical;
std::string creator_name;
creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
creator_name);
creator_name);
childSetText("Creator Name",creator_name);
childSetEnabled("Creator Name",TRUE);
childSetText("Creator Name", creator_name);
childSetEnabled("Creator Name", TRUE);
// Update owner text field
childSetEnabled("Owner:",true);
childSetEnabled("Owner:", TRUE);
BOOL owners_identical;
std::string owner_name;
owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name);
// llinfos << "owners_identical " << (owners_identical ? "TRUE": "FALSE") << llendl;
const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name);
if (mOwnerID.isNull())
{
if(LLSelectMgr::getInstance()->selectIsGroupOwned())
if (LLSelectMgr::getInstance()->selectIsGroupOwned())
{
// Group owned already displayed by selectGetOwner
}
@ -359,61 +360,53 @@ void LLPanelPermissions::refresh()
if (!mLastOwnerID.isNull() && !last_owner_name.empty())
{
owner_name.append(", last ");
owner_name.append( last_owner_name );
owner_name.append(last_owner_name);
}
}
}
childSetText("Owner Name",owner_name);
childSetEnabled("Owner Name",TRUE);
childSetText("Owner Name", owner_name);
childSetEnabled("Owner Name", TRUE);
// update group text field
childSetEnabled("Group:",true);
childSetText("Group Name",LLStringUtil::null);
childSetEnabled("Group:", TRUE);
childSetText("Group Name", LLStringUtil::null);
LLUUID group_id;
BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
if (groups_identical)
{
if(mLabelGroupName)
if (mLabelGroupName)
{
mLabelGroupName->setNameID(group_id, TRUE);
mLabelGroupName->setNameID(group_id,TRUE);
mLabelGroupName->setEnabled(TRUE);
}
}
else
{
if(mLabelGroupName)
if (mLabelGroupName)
{
mLabelGroupName->setNameID(LLUUID::null, TRUE);
mLabelGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, TRUE);
mLabelGroupName->refresh(LLUUID::null,LLStringUtil::null, LLStringUtil::null, TRUE);
mLabelGroupName->setEnabled(FALSE);
}
}
childSetEnabled("button set group",owners_identical && (mOwnerID == gAgent.getID()));
childSetEnabled("button set group", owners_identical && (mOwnerID == gAgent.getID()));
// figure out the contents of the name, description, & category
BOOL edit_name_desc = FALSE;
if(is_one_object && objectp->permModify())
{
edit_name_desc = TRUE;
}
childSetEnabled("Name:",true);
childSetEnabled("Name:", TRUE);
LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name");
childSetEnabled("Description:",true);
LLLineEditor* LineEditorObjectDesc = getChild<LLLineEditor>("Object Description");
childSetEnabled("Description:", TRUE);
LLLineEditor* LineEditorObjectDesc = getChild<LLLineEditor>("Object Description");
if(is_one_object)
if (is_one_object)
{
if(keyboard_focus_view != LineEditorObjectName)
if (keyboard_focus_view != LineEditorObjectName)
{
childSetText("Object Name",nodep->mName);
}
if(LineEditorObjectDesc)
if (LineEditorObjectDesc)
{
if(keyboard_focus_view != LineEditorObjectDesc)
if (keyboard_focus_view != LineEditorObjectDesc)
{
LineEditorObjectDesc->setText(nodep->mDescription);
}
@ -421,19 +414,25 @@ void LLPanelPermissions::refresh()
}
else
{
childSetText("Object Name",LLStringUtil::null);
childSetText("Object Name", LLStringUtil::null);
LineEditorObjectDesc->setText(LLStringUtil::null);
}
if(edit_name_desc)
// figure out the contents of the name, description, & category
BOOL edit_name_desc = FALSE;
if (is_one_object && objectp->permModify())
{
childSetEnabled("Object Name",true);
childSetEnabled("Object Description",true);
edit_name_desc = TRUE;
}
if (edit_name_desc)
{
childSetEnabled("Object Name", TRUE);
childSetEnabled("Object Description", TRUE);
}
else
{
childSetEnabled("Object Name",false);
childSetEnabled("Object Description",false);
childSetEnabled("Object Name", FALSE);
childSetEnabled("Object Description", FALSE);
}
S32 total_sale_price = 0;
@ -442,10 +441,10 @@ void LLPanelPermissions::refresh()
BOOL is_sale_price_mixed = FALSE;
U32 num_for_sale = FALSE;
LLSelectMgr::getInstance()->selectGetAggregateSaleInfo(num_for_sale,
is_for_sale_mixed,
is_sale_price_mixed,
total_sale_price,
individual_sale_price);
is_for_sale_mixed,
is_sale_price_mixed,
total_sale_price,
individual_sale_price);
const BOOL self_owned = (gAgent.getID() == mOwnerID);
const BOOL group_owned = LLSelectMgr::getInstance()->selectIsGroupOwned() ;
@ -453,35 +452,35 @@ void LLPanelPermissions::refresh()
const BOOL can_transfer = LLSelectMgr::getInstance()->selectGetRootsTransfer();
const BOOL can_copy = LLSelectMgr::getInstance()->selectGetRootsCopy();
if(!owners_identical)
if (!owners_identical)
{
childSetEnabled("Cost",false);
childSetText("Edit Cost",LLStringUtil::null);
childSetEnabled("Edit Cost",false);
childSetEnabled("Cost", FALSE);
childSetText("Edit Cost", LLStringUtil::null);
childSetEnabled("Edit Cost", FALSE);
}
// You own these objects.
else if(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id,GP_OBJECT_SET_SALE)))
else if (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id,GP_OBJECT_SET_SALE)))
{
// If there are multiple items for sale then set text to PRICE PER UNIT.
if (num_for_sale > 1)
{
childSetText("Cost",getString("Cost Per Unit"));
childSetText("Cost", getString("Cost Per Unit"));
}
else
{
childSetText("Cost",getString("Cost Default"));
childSetText("Cost", getString("Cost Default"));
}
LLSpinCtrl *edit_price = getChild<LLSpinCtrl>("Edit Cost");
if(!edit_price->hasFocus())
if (!edit_price->hasFocus())
{
// If the sale price is mixed then set the cost to MIXED, otherwise
// set to the actual cost.
if (num_for_sale > 0 && is_for_sale_mixed)
if ((num_for_sale > 0) && is_for_sale_mixed)
{
edit_price->setTentative(TRUE);
}
else if (num_for_sale > 0 && is_sale_price_mixed)
else if ((num_for_sale > 0) && is_sale_price_mixed)
{
edit_price->setTentative(TRUE);
}
@ -492,303 +491,279 @@ void LLPanelPermissions::refresh()
}
// The edit fields are only enabled if you can sell this object
// and the sale price is not mixed.
bool enable_edit = (num_for_sale && can_transfer) ? !is_for_sale_mixed : false;
childSetEnabled("Cost",enable_edit);
childSetEnabled("Edit Cost",enable_edit);
BOOL enable_edit = (num_for_sale && can_transfer) ? !is_for_sale_mixed : FALSE;
childSetEnabled("Cost", enable_edit);
childSetEnabled("Edit Cost", enable_edit);
}
// Someone, not you, owns these objects.
else if(!public_owned)
else if (!public_owned)
{
childSetEnabled("Cost",false);
childSetEnabled("Edit Cost",false);
childSetEnabled("Cost", FALSE);
childSetEnabled("Edit Cost", FALSE);
// Don't show a price if none of the items are for sale.
if (num_for_sale)
childSetText("Edit Cost",llformat("%d",total_sale_price));
childSetText("Edit Cost", llformat("%d",total_sale_price));
else
childSetText("Edit Cost",LLStringUtil::null);
childSetText("Edit Cost", LLStringUtil::null);
// If multiple items are for sale, set text to TOTAL PRICE.
if (num_for_sale > 1)
childSetText("Cost",getString("Cost Total"));
childSetText("Cost", getString("Cost Total"));
else
childSetText("Cost",getString("Cost Default"));
childSetText("Cost", getString("Cost Default"));
}
// This is a public object.
else
{
childSetEnabled("Cost",false);
childSetText("Cost",getString("Cost Default"));
childSetEnabled("Cost", FALSE);
childSetText("Cost", getString("Cost Default"));
childSetText("Edit Cost",LLStringUtil::null);
childSetEnabled("Edit Cost",false);
childSetText("Edit Cost", LLStringUtil::null);
childSetEnabled("Edit Cost", FALSE);
}
// Enable and disable the permissions checkboxes
// based on who owns the object.
// TODO: Creator permissions
BOOL valid_base_perms = FALSE;
BOOL valid_owner_perms = FALSE;
BOOL valid_group_perms = FALSE;
BOOL valid_everyone_perms = FALSE;
BOOL valid_next_perms = FALSE;
U32 base_mask_on = 0;
U32 base_mask_off = 0;
U32 owner_mask_off = 0;
U32 owner_mask_on = 0;
U32 group_mask_on = 0;
U32 group_mask_off = 0;
U32 everyone_mask_on = 0;
U32 everyone_mask_off = 0;
U32 next_owner_mask_on = 0;
U32 next_owner_mask_off = 0;
U32 base_mask_on;
U32 base_mask_off;
U32 owner_mask_on;
U32 owner_mask_off;
U32 group_mask_on;
U32 group_mask_off;
U32 everyone_mask_on;
U32 everyone_mask_off;
U32 next_owner_mask_on = 0;
U32 next_owner_mask_off = 0;
valid_base_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_BASE,
&base_mask_on,
&base_mask_off);
valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
&owner_mask_on,
&owner_mask_off);
valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
&group_mask_on,
&group_mask_off);
BOOL valid_base_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_BASE,
&base_mask_on,
&base_mask_off);
//BOOL valid_owner_perms =//
LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
&owner_mask_on,
&owner_mask_off);
BOOL valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
&group_mask_on,
&group_mask_off);
valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
&everyone_mask_on,
&everyone_mask_off);
BOOL valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
&everyone_mask_on,
&everyone_mask_off);
valid_next_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_NEXT_OWNER,
&next_owner_mask_on,
&next_owner_mask_off);
BOOL valid_next_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_NEXT_OWNER,
&next_owner_mask_on,
&next_owner_mask_off);
if( gSavedSettings.getBOOL("DebugPermissions") )
if (gSavedSettings.getBOOL("DebugPermissions") )
{
std::string perm_string;
if (valid_base_perms)
{
perm_string = "B: ";
perm_string += mask_to_string(base_mask_on);
childSetText("B:",perm_string);
childSetVisible("B:",true);
childSetText("B:", "B: " + mask_to_string(base_mask_on));
childSetVisible("B:", TRUE);
perm_string = "O: ";
perm_string += mask_to_string(owner_mask_on);
childSetText("O:",perm_string);
childSetVisible("O:",true);
childSetText("O:", "O: " + mask_to_string(owner_mask_on));
childSetVisible("O:", TRUE);
perm_string = "G: ";
perm_string += mask_to_string(group_mask_on);
childSetText("G:",perm_string);
childSetVisible("G:",true);
childSetText("G:", "G: " + mask_to_string(group_mask_on));
childSetVisible("G:", TRUE);
perm_string = "E: ";
perm_string += mask_to_string(everyone_mask_on);
childSetText("E:",perm_string);
childSetVisible("E:",true);
childSetText("E:", "E: " + mask_to_string(everyone_mask_on));
childSetVisible("E:", TRUE);
perm_string = "N: ";
perm_string += mask_to_string(next_owner_mask_on);
childSetText("N:",perm_string);
childSetVisible("N:",true);
childSetText("N:", "N: " + mask_to_string(next_owner_mask_on));
childSetVisible("N:", TRUE);
}
perm_string = "F: ";
U32 flag_mask = 0x0;
if (objectp->permMove())
flag_mask |= PERM_MOVE;
if (objectp->permModify())
flag_mask |= PERM_MODIFY;
if (objectp->permCopy())
flag_mask |= PERM_COPY;
if (objectp->permTransfer())
flag_mask |= PERM_TRANSFER;
perm_string += mask_to_string(flag_mask);
childSetText("F:",perm_string);
childSetVisible("F:",true);
if (objectp->permMove()) flag_mask |= PERM_MOVE;
if (objectp->permModify()) flag_mask |= PERM_MODIFY;
if (objectp->permCopy()) flag_mask |= PERM_COPY;
if (objectp->permTransfer()) flag_mask |= PERM_TRANSFER;
childSetText("F:", "F:" + mask_to_string(flag_mask));
childSetVisible("F:", TRUE);
}
else
{
childSetVisible("B:",false);
childSetVisible("O:",false);
childSetVisible("G:",false);
childSetVisible("E:",false);
childSetVisible("N:",false);
childSetVisible("F:",false);
childSetVisible("B:", FALSE);
childSetVisible("O:", FALSE);
childSetVisible("G:", FALSE);
childSetVisible("E:", FALSE);
childSetVisible("N:", FALSE);
childSetVisible("F:", FALSE);
}
bool has_change_perm_ability = false;
bool has_change_sale_ability = false;
BOOL has_change_perm_ability = FALSE;
BOOL has_change_sale_ability = FALSE;
if(valid_base_perms
&& (self_owned
|| (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE))))
if (valid_base_perms &&
(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE))))
{
has_change_perm_ability = true;
has_change_perm_ability = TRUE;
}
if(valid_base_perms
&& (self_owned
|| (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE))))
if (valid_base_perms &&
(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE))))
{
has_change_sale_ability = true;
has_change_sale_ability = TRUE;
}
if (!has_change_perm_ability && !has_change_sale_ability && !root_selected)
{
// ...must select root to choose permissions
childSetValue("perm_modify", getString("text modify warning"));
childSetValue("perm_modify", getString("text modify warning"));
}
if (has_change_perm_ability)
{
childSetEnabled("checkbox share with group",true);
childSetEnabled("checkbox allow everyone move",owner_mask_on & PERM_MOVE);
childSetEnabled("checkbox allow everyone copy",owner_mask_on & PERM_COPY && owner_mask_on & PERM_TRANSFER);
childSetEnabled("checkbox share with group", TRUE);
childSetEnabled("checkbox allow everyone move", owner_mask_on & PERM_MOVE);
childSetEnabled("checkbox allow everyone copy", owner_mask_on & PERM_COPY && owner_mask_on & PERM_TRANSFER);
}
else
{
childSetEnabled("checkbox share with group", FALSE);
childSetEnabled("checkbox allow everyone move", FALSE);
childSetEnabled("checkbox allow everyone copy", FALSE);
childSetEnabled("checkbox share with group", FALSE);
childSetEnabled("checkbox allow everyone move", FALSE);
childSetEnabled("checkbox allow everyone copy", FALSE);
}
if (has_change_sale_ability && (owner_mask_on & PERM_TRANSFER))
{
childSetEnabled("checkbox for sale", can_transfer || (!can_transfer && num_for_sale));
childSetEnabled("checkbox for sale", can_transfer || (!can_transfer && num_for_sale));
// Set the checkbox to tentative if the prices of each object selected
// are not the same.
childSetTentative("checkbox for sale", is_for_sale_mixed);
childSetEnabled("sale type",num_for_sale && can_transfer && !is_sale_price_mixed);
childSetTentative("checkbox for sale", is_for_sale_mixed);
childSetEnabled("sale type", num_for_sale && can_transfer && !is_sale_price_mixed);
childSetEnabled("Next owner can:", TRUE);
childSetEnabled("checkbox next owner can modify",base_mask_on & PERM_MODIFY);
childSetEnabled("checkbox next owner can copy",base_mask_on & PERM_COPY);
childSetEnabled("checkbox next owner can transfer",next_owner_mask_on & PERM_COPY);
childSetEnabled("Next owner can:", TRUE);
childSetEnabled("checkbox next owner can modify", base_mask_on & PERM_MODIFY);
childSetEnabled("checkbox next owner can copy", base_mask_on & PERM_COPY);
childSetEnabled("checkbox next owner can transfer", next_owner_mask_on & PERM_COPY);
}
else
{
childSetEnabled("checkbox for sale",FALSE);
childSetEnabled("sale type",FALSE);
childSetEnabled("checkbox for sale", FALSE);
childSetEnabled("sale type", FALSE);
childSetEnabled("Next owner can:",FALSE);
childSetEnabled("checkbox next owner can modify",FALSE);
childSetEnabled("checkbox next owner can copy",FALSE);
childSetEnabled("checkbox next owner can transfer",FALSE);
childSetEnabled("Next owner can:", FALSE);
childSetEnabled("checkbox next owner can modify", FALSE);
childSetEnabled("checkbox next owner can copy", FALSE);
childSetEnabled("checkbox next owner can transfer", FALSE);
}
if(valid_group_perms)
if (valid_group_perms)
{
if((group_mask_on & PERM_COPY) && (group_mask_on & PERM_MODIFY) && (group_mask_on & PERM_MOVE))
if ((group_mask_on & PERM_COPY) && (group_mask_on & PERM_MODIFY) && (group_mask_on & PERM_MOVE))
{
childSetValue("checkbox share with group",TRUE);
childSetTentative("checkbox share with group",FALSE);
childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
childSetValue("checkbox share with group", TRUE);
childSetTentative("checkbox share with group", FALSE);
childSetEnabled("button deed", gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
}
else if((group_mask_off & PERM_COPY) && (group_mask_off & PERM_MODIFY) && (group_mask_off & PERM_MOVE))
else if ((group_mask_off & PERM_COPY) && (group_mask_off & PERM_MODIFY) && (group_mask_off & PERM_MOVE))
{
childSetValue("checkbox share with group",FALSE);
childSetTentative("checkbox share with group",false);
childSetEnabled("button deed",false);
childSetValue("checkbox share with group", FALSE);
childSetTentative("checkbox share with group", FALSE);
childSetEnabled("button deed", FALSE);
}
else
{
childSetValue("checkbox share with group",TRUE);
childSetTentative("checkbox share with group",true);
childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
childSetValue("checkbox share with group", TRUE);
childSetTentative("checkbox share with group", TRUE);
childSetEnabled("button deed", gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
}
}
if(valid_everyone_perms)
if (valid_everyone_perms)
{
// Move
if(everyone_mask_on & PERM_MOVE)
if (everyone_mask_on & PERM_MOVE)
{
childSetValue("checkbox allow everyone move",TRUE);
childSetTentative("checkbox allow everyone move",false);
childSetValue("checkbox allow everyone move", TRUE);
childSetTentative("checkbox allow everyone move", FALSE);
}
else if(everyone_mask_off & PERM_MOVE)
else if (everyone_mask_off & PERM_MOVE)
{
childSetValue("checkbox allow everyone move",FALSE);
childSetTentative("checkbox allow everyone move",false);
childSetValue("checkbox allow everyone move", FALSE);
childSetTentative("checkbox allow everyone move", FALSE);
}
else
{
childSetValue("checkbox allow everyone move",TRUE);
childSetTentative("checkbox allow everyone move",true);
childSetValue("checkbox allow everyone move", TRUE);
childSetTentative("checkbox allow everyone move", TRUE);
}
// Copy == everyone can't copy
if(everyone_mask_on & PERM_COPY)
if (everyone_mask_on & PERM_COPY)
{
childSetValue("checkbox allow everyone copy",TRUE);
childSetTentative("checkbox allow everyone copy",!can_copy || !can_transfer);
childSetValue("checkbox allow everyone copy", TRUE);
childSetTentative("checkbox allow everyone copy", !can_copy || !can_transfer);
}
else if(everyone_mask_off & PERM_COPY)
else if (everyone_mask_off & PERM_COPY)
{
childSetValue("checkbox allow everyone copy",FALSE);
childSetTentative("checkbox allow everyone copy",false);
childSetValue("checkbox allow everyone copy", FALSE);
childSetTentative("checkbox allow everyone copy", FALSE);
}
else
{
childSetValue("checkbox allow everyone copy",TRUE);
childSetTentative("checkbox allow everyone copy",true);
childSetValue("checkbox allow everyone copy", TRUE);
childSetTentative("checkbox allow everyone copy", TRUE);
}
}
if(valid_next_perms)
if (valid_next_perms)
{
// Modify == next owner canot modify
if(next_owner_mask_on & PERM_MODIFY)
if (next_owner_mask_on & PERM_MODIFY)
{
childSetValue("checkbox next owner can modify",TRUE);
childSetTentative("checkbox next owner can modify",false);
childSetValue("checkbox next owner can modify", TRUE);
childSetTentative("checkbox next owner can modify", FALSE);
}
else if(next_owner_mask_off & PERM_MODIFY)
else if (next_owner_mask_off & PERM_MODIFY)
{
childSetValue("checkbox next owner can modify",FALSE);
childSetTentative("checkbox next owner can modify",false);
childSetValue("checkbox next owner can modify", FALSE);
childSetTentative("checkbox next owner can modify", FALSE);
}
else
{
childSetValue("checkbox next owner can modify",TRUE);
childSetTentative("checkbox next owner can modify",true);
childSetValue("checkbox next owner can modify", TRUE);
childSetTentative("checkbox next owner can modify", TRUE);
}
// Copy == next owner cannot copy
if(next_owner_mask_on & PERM_COPY)
if (next_owner_mask_on & PERM_COPY)
{
childSetValue("checkbox next owner can copy",TRUE);
childSetTentative("checkbox next owner can copy",!can_copy);
childSetValue("checkbox next owner can copy", TRUE);
childSetTentative("checkbox next owner can copy", !can_copy);
}
else if(next_owner_mask_off & PERM_COPY)
else if (next_owner_mask_off & PERM_COPY)
{
childSetValue("checkbox next owner can copy",FALSE);
childSetTentative("checkbox next owner can copy",FALSE);
childSetValue("checkbox next owner can copy", FALSE);
childSetTentative("checkbox next owner can copy", FALSE);
}
else
{
childSetValue("checkbox next owner can copy",TRUE);
childSetTentative("checkbox next owner can copy",TRUE);
childSetValue("checkbox next owner can copy", TRUE);
childSetTentative("checkbox next owner can copy", TRUE);
}
// Transfer == next owner cannot transfer
if(next_owner_mask_on & PERM_TRANSFER)
if (next_owner_mask_on & PERM_TRANSFER)
{
childSetValue("checkbox next owner can transfer",TRUE);
childSetTentative("checkbox next owner can transfer",!can_transfer);
childSetValue("checkbox next owner can transfer", TRUE);
childSetTentative("checkbox next owner can transfer", !can_transfer);
}
else if(next_owner_mask_off & PERM_TRANSFER)
else if (next_owner_mask_off & PERM_TRANSFER)
{
childSetValue("checkbox next owner can transfer",FALSE);
childSetTentative("checkbox next owner can transfer",FALSE);
childSetValue("checkbox next owner can transfer", FALSE);
childSetTentative("checkbox next owner can transfer", FALSE);
}
else
{
childSetValue("checkbox next owner can transfer",TRUE);
childSetTentative("checkbox next owner can transfer",TRUE);
childSetValue("checkbox next owner can transfer", TRUE);
childSetTentative("checkbox next owner can transfer", TRUE);
}
}
@ -800,48 +775,51 @@ void LLPanelPermissions::refresh()
LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
if (valid_sale_info)
{
combo_sale_type->setValue(sale_type == LLSaleInfo::FS_NOT ? LLSaleInfo::FS_COPY : sale_type);
combo_sale_type->setTentative(FALSE); // unfortunately this doesn't do anything at the moment.
combo_sale_type->setValue( sale_type == LLSaleInfo::FS_NOT ? LLSaleInfo::FS_COPY : sale_type);
combo_sale_type->setTentative( FALSE); // unfortunately this doesn't do anything at the moment.
}
else
{
// default option is sell copy, determined to be safest
combo_sale_type->setValue(LLSaleInfo::FS_COPY);
combo_sale_type->setTentative(TRUE); // unfortunately this doesn't do anything at the moment.
combo_sale_type->setValue( LLSaleInfo::FS_COPY);
combo_sale_type->setTentative( TRUE); // unfortunately this doesn't do anything at the moment.
}
childSetValue("checkbox for sale", num_for_sale != 0);
childSetValue("checkbox for sale", (num_for_sale != 0));
// HACK: There are some old objects in world that are set for sale,
// but are no-transfer. We need to let users turn for-sale off, but only
// if for-sale is set.
bool cannot_actually_sell = !can_transfer || (!can_copy && sale_type == LLSaleInfo::FS_COPY);
if (num_for_sale && has_change_sale_ability && cannot_actually_sell)
if (cannot_actually_sell)
{
childSetEnabled("checkbox for sale", true);
if (num_for_sale && has_change_sale_ability)
{
childSetEnabled("checkbox for sale", true);
}
}
// Check search status of objects
BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
const BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
bool include_in_search;
bool all_include_in_search = LLSelectMgr::getInstance()->selectionGetIncludeInSearch(&include_in_search);
childSetEnabled("search_check", has_change_sale_ability && all_volume);
childSetValue("search_check", include_in_search);
childSetTentative("search_check", ! all_include_in_search);
const BOOL all_include_in_search = LLSelectMgr::getInstance()->selectionGetIncludeInSearch(&include_in_search);
childSetEnabled("search_check", has_change_sale_ability && all_volume);
childSetValue("search_check", include_in_search);
childSetTentative("search_check", !all_include_in_search);
// Click action (touch, sit, buy)
U8 click_action = 0;
if (LLSelectMgr::getInstance()->selectionGetClickAction(&click_action))
{
LLComboBox* ComboClickAction = getChild<LLComboBox>("clickaction");
if(ComboClickAction)
LLComboBox* combo_click_action = getChild<LLComboBox>("clickaction");
if(combo_click_action)
{
std::string combo_value = click_action_to_string_value(click_action);
ComboClickAction->setValue(LLSD(combo_value));
const std::string combo_value = click_action_to_string_value(click_action);
combo_click_action->setValue(LLSD(combo_value));
}
}
childSetEnabled("label click action",is_perm_modify && all_volume);
childSetEnabled("clickaction",is_perm_modify && all_volume);
childSetEnabled("label click action", is_perm_modify && all_volume);
childSetEnabled("clickaction", is_perm_modify && all_volume);
}

Some files were not shown because too many files have changed in this diff Show More