Merge branch 'DRTVWR-594-maint-Y' into marchcat/594-y-pbr-merge
# Conflicts: # indra/newview/llinventorygallery.cpp # indra/newview/skins/default/xui/en/notifications.xmlmaster
commit
c409236dac
|
|
@ -408,11 +408,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>f6835c4d7745cd1cadfbce47b40331d08affb532</string>
|
||||
<string>e03eb77224290c875ff84f75b7fe3d0e7c162c94</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-dictionaries/releases/download/v1.0.1-dev2.gf887629-f887629/dictionaries-common-None.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-dictionaries/releases/download/v1-a01bb6c/dictionaries-1.a01bb6c-common-a01bb6c.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
|
|
@ -425,7 +425,7 @@
|
|||
<key>copyright</key>
|
||||
<string>Copyright 2014 Apache OpenOffice software</string>
|
||||
<key>version</key>
|
||||
<string>None</string>
|
||||
<string>1.a01bb6c</string>
|
||||
<key>name</key>
|
||||
<string>dictionaries</string>
|
||||
<key>description</key>
|
||||
|
|
@ -734,11 +734,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>6604c1cca515d287e697997a8d5593d1cae172a9</string>
|
||||
<string>066625e7aa7f697a4b6cd461aad960c57181011f</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-glh_linear/releases/download/v1.0.1-dev2.g3253ed7-3253ed7/glh_linear-common-None.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-glh_linear/releases/download/v1.0.1-dev4-984c397/glh_linear-1.0.1-dev4-common-984c397.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
|
|
@ -751,7 +751,7 @@
|
|||
<key>copyright</key>
|
||||
<string>Copyright (c) 2000 Cass Everitt</string>
|
||||
<key>version</key>
|
||||
<string>None</string>
|
||||
<string>1.0.1-dev4</string>
|
||||
<key>name</key>
|
||||
<string>glh_linear</string>
|
||||
<key>description</key>
|
||||
|
|
@ -882,11 +882,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>a193ff65d6db48626d65d96c6124c6efca85e8ec</string>
|
||||
<string>ae2c2a215b1bc2e3f37a67e301926dc405902d1a</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912596</string>
|
||||
<string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778143</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -910,11 +910,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>ebfb82b6143874e7938b9d1e8a70d0a2e28aa818</string>
|
||||
<string>0393dd75c58f7046bed47e62a8884a78cb02a5c3</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912599</string>
|
||||
<string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778145</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
@ -1120,11 +1120,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>bcc7e2c34896fc9cbc41828dee8a4ddf54f10453</string>
|
||||
<string>ad72fa1d103df777906f0d98f3e882b9916aeada</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298968</string>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774118</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -1136,11 +1136,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>9de772df2ed12e9c742df6c90670c7cbbb9c93a6</string>
|
||||
<string>e46e4ac93a237b5c4a14183766f76ba5d58935a2</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298969</string>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774125</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1152,15 +1152,31 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>92533ff0f8c1881ad85e75800f9072c413ccf7b7</string>
|
||||
<string>bb37557f78c72b26580a521f8b8dabfa1b34e6e6</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298970</string>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774126</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>linux</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>711b82f9f588d3a125af7dcd8c81f93d9c343a7d</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774121</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>Kakadu</string>
|
||||
|
|
@ -1169,7 +1185,7 @@
|
|||
<key>copyright</key>
|
||||
<string>Kakadu software</string>
|
||||
<key>version</key>
|
||||
<string>7.10.4.539108</string>
|
||||
<string>7.10.4.4b9ec5f</string>
|
||||
<key>name</key>
|
||||
<string>kdu</string>
|
||||
<key>description</key>
|
||||
|
|
@ -1468,11 +1484,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e50ea94bbaa4ff41bf53b84b7192df1a694c5337</string>
|
||||
<string>d3c1f7f947a2d8e89a98af816be2492afb42dfbc</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/llca/releases/download/v202310121525.0-d22bd98/llca-202310121530.0-common-d22bd98.tar.zst</string>
|
||||
<string>https://github.com/secondlife/llca/releases/download/v202311020117.0-0f5d9c3/llca-202311012318.0-common-0f5d9c3.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
|
|
|
|||
|
|
@ -842,6 +842,7 @@ Kadah Coba
|
|||
Jondan Lundquist
|
||||
Joosten Briebers
|
||||
MAINT-7074
|
||||
BUG-225288
|
||||
Josef Munster
|
||||
Josette Windlow
|
||||
Juilan Tripsa
|
||||
|
|
|
|||
|
|
@ -152,12 +152,21 @@ void LLEventPumps::clear()
|
|||
}
|
||||
}
|
||||
|
||||
void LLEventPumps::reset()
|
||||
void LLEventPumps::reset(bool log_pumps)
|
||||
{
|
||||
// Reset every known LLEventPump instance. Leave it up to each instance to
|
||||
// decide what to do with the reset() call.
|
||||
if (log_pumps)
|
||||
{
|
||||
LL_INFOS() << "Resetting " << (S32)mPumpMap.size() << " pumps" << LL_ENDL;
|
||||
}
|
||||
|
||||
for (PumpMap::value_type& pair : mPumpMap)
|
||||
{
|
||||
if (log_pumps)
|
||||
{
|
||||
LL_INFOS() << "Resetting pump " << pair.first << LL_ENDL;
|
||||
}
|
||||
pair.second->reset();
|
||||
}
|
||||
}
|
||||
|
|
@ -314,9 +323,11 @@ std::string LLEventPump::inventName(const std::string& pfx)
|
|||
|
||||
void LLEventPump::clear()
|
||||
{
|
||||
LLMutexLock lock(&mConnectionListMutex);
|
||||
// Destroy the original LLStandardSignal instance, replacing it with a
|
||||
// whole new one.
|
||||
mSignal = std::make_shared<LLStandardSignal>();
|
||||
|
||||
mConnections.clear();
|
||||
}
|
||||
|
||||
|
|
@ -324,6 +335,7 @@ void LLEventPump::reset()
|
|||
{
|
||||
// Resetting mSignal is supposed to disconnect everything on its own
|
||||
// But due to crash on 'reset' added explicit cleanup to get more data
|
||||
LLMutexLock lock(&mConnectionListMutex);
|
||||
ConnectionMap::const_iterator iter = mConnections.begin();
|
||||
ConnectionMap::const_iterator end = mConnections.end();
|
||||
while (iter!=end)
|
||||
|
|
@ -348,6 +360,8 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
|
|||
return LLBoundListener();
|
||||
}
|
||||
|
||||
LLMutexLock lock(&mConnectionListMutex);
|
||||
|
||||
float nodePosition = 1.0;
|
||||
|
||||
// if the supplied name is empty we are not interested in the ordering mechanism
|
||||
|
|
@ -507,8 +521,9 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
|
|||
return bound;
|
||||
}
|
||||
|
||||
LLBoundListener LLEventPump::getListener(const std::string& name) const
|
||||
LLBoundListener LLEventPump::getListener(const std::string& name)
|
||||
{
|
||||
LLMutexLock lock(&mConnectionListMutex);
|
||||
ConnectionMap::const_iterator found = mConnections.find(name);
|
||||
if (found != mConnections.end())
|
||||
{
|
||||
|
|
@ -520,6 +535,7 @@ LLBoundListener LLEventPump::getListener(const std::string& name) const
|
|||
|
||||
void LLEventPump::stopListening(const std::string& name)
|
||||
{
|
||||
LLMutexLock lock(&mConnectionListMutex);
|
||||
ConnectionMap::iterator found = mConnections.find(name);
|
||||
if (found != mConnections.end())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ public:
|
|||
* Reset all known LLEventPump instances
|
||||
* workaround for DEV-35406 crash on shutdown
|
||||
*/
|
||||
void reset();
|
||||
void reset(bool log_pumps = false);
|
||||
|
||||
private:
|
||||
friend class LLEventPump;
|
||||
|
|
@ -519,7 +519,7 @@ public:
|
|||
|
||||
/// Get the LLBoundListener associated with the passed name (dummy
|
||||
/// LLBoundListener if not found)
|
||||
virtual LLBoundListener getListener(const std::string& name) const;
|
||||
virtual LLBoundListener getListener(const std::string& name);
|
||||
/**
|
||||
* Instantiate one of these to block an existing connection:
|
||||
* @code
|
||||
|
|
@ -562,6 +562,7 @@ private:
|
|||
LLHandle<LLEventPumps> mRegistry;
|
||||
|
||||
std::string mName;
|
||||
LLMutex mConnectionListMutex;
|
||||
|
||||
protected:
|
||||
virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <mach/mach_host.h>
|
||||
#elif LL_LINUX
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "llmemory.h"
|
||||
|
|
@ -273,33 +274,16 @@ U64 LLMemory::getCurrentRSS()
|
|||
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
{
|
||||
static const char statPath[] = "/proc/self/stat";
|
||||
LLFILE *fp = LLFile::fopen(statPath, "r");
|
||||
U64 rss = 0;
|
||||
struct rusage usage;
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
LL_WARNS() << "couldn't open " << statPath << LL_ENDL;
|
||||
if (getrusage(RUSAGE_SELF, &usage) != 0) {
|
||||
// Error handling code could be here
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Eee-yew! See Documentation/filesystems/proc.txt in your
|
||||
// nearest friendly kernel tree for details.
|
||||
|
||||
{
|
||||
int ret = fscanf(fp, "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*d %*d "
|
||||
"%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %Lu",
|
||||
&rss);
|
||||
if (ret != 1)
|
||||
{
|
||||
LL_WARNS() << "couldn't parse contents of " << statPath << LL_ENDL;
|
||||
rss = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return rss;
|
||||
// ru_maxrss (since Linux 2.6.32)
|
||||
// This is the maximum resident set size used (in kilobytes).
|
||||
return usage.ru_maxrss * 1024;
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -298,6 +298,13 @@ BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char
|
|||
}
|
||||
|
||||
htolememcpy(&size, mCurBufferp, MVT_S32, 4);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData unpacked invalid size, aborting!" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mCurBufferp += 4;
|
||||
|
||||
if (!verifyLength(size, name))
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class LLFilterEditor : public LLSearchEditor
|
|||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLSearchEditor::Params>
|
||||
{};
|
||||
virtual ~LLFilterEditor() {}
|
||||
|
||||
protected:
|
||||
LLFilterEditor(const Params&);
|
||||
|
|
|
|||
|
|
@ -1772,6 +1772,8 @@ void LLFloater::onClickTearOff(LLFloater* self)
|
|||
{
|
||||
if (self->mSaveRect)
|
||||
{
|
||||
LLRect screen_rect = self->calcScreenRect();
|
||||
self->mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
|
||||
self->storeRectControl();
|
||||
}
|
||||
self->setMinimized(FALSE); // to reenable minimize button if it was minimized
|
||||
|
|
|
|||
|
|
@ -994,6 +994,7 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe
|
|||
// all of the notifications that are already in the channel
|
||||
// we use a special signal called "load" in case the channel wants to care
|
||||
// only about new notifications
|
||||
LLMutexLock lock(&mItemsMutex);
|
||||
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
|
||||
{
|
||||
slot(LLSD().with("sigtype", "load").with("id", (*it)->id()));
|
||||
|
|
@ -1171,6 +1172,14 @@ LLNotificationChannel::LLNotificationChannel(const std::string& name,
|
|||
connectToChannel(parent);
|
||||
}
|
||||
|
||||
LLNotificationChannel::~LLNotificationChannel()
|
||||
{
|
||||
for (LLBoundListener &listener : mListeners)
|
||||
{
|
||||
listener.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLNotificationChannel::isEmpty() const
|
||||
{
|
||||
return mItems.empty();
|
||||
|
|
@ -1178,17 +1187,7 @@ bool LLNotificationChannel::isEmpty() const
|
|||
|
||||
S32 LLNotificationChannel::size() const
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
LLNotificationChannel::Iterator LLNotificationChannel::begin()
|
||||
{
|
||||
return mItems.begin();
|
||||
}
|
||||
|
||||
LLNotificationChannel::Iterator LLNotificationChannel::end()
|
||||
{
|
||||
return mItems.end();
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
size_t LLNotificationChannel::size()
|
||||
|
|
@ -1196,12 +1195,19 @@ size_t LLNotificationChannel::size()
|
|||
return mItems.size();
|
||||
}
|
||||
|
||||
void LLNotificationChannel::forEachNotification(NotificationProcess process)
|
||||
{
|
||||
LLMutexLock lock(&mItemsMutex);
|
||||
std::for_each(mItems.begin(), mItems.end(), process);
|
||||
}
|
||||
|
||||
std::string LLNotificationChannel::summarize()
|
||||
{
|
||||
std::string s("Channel '");
|
||||
s += mName;
|
||||
s += "'\n ";
|
||||
for (LLNotificationChannel::Iterator it = begin(); it != end(); ++it)
|
||||
LLMutexLock lock(&mItemsMutex);
|
||||
for (LLNotificationChannel::Iterator it = mItems.begin(); it != mItems.end(); ++it)
|
||||
{
|
||||
s += (*it)->summarize();
|
||||
s += "\n ";
|
||||
|
|
@ -1213,14 +1219,14 @@ void LLNotificationChannel::connectToChannel( const std::string& channel_name )
|
|||
{
|
||||
if (channel_name.empty())
|
||||
{
|
||||
LLNotifications::instance().connectChanged(
|
||||
boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
|
||||
mListeners.push_back(LLNotifications::instance().connectChanged(
|
||||
boost::bind(&LLNotificationChannelBase::updateItem, this, _1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
mParents.push_back(channel_name);
|
||||
LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name);
|
||||
p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
|
||||
mListeners.push_back(p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1728,6 +1734,7 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
|
|||
|
||||
void LLNotifications::cancelByName(const std::string& name)
|
||||
{
|
||||
LLMutexLock lock(&mItemsMutex);
|
||||
std::vector<LLNotificationPtr> notifs_to_cancel;
|
||||
for (LLNotificationSet::iterator it=mItems.begin(), end_it = mItems.end();
|
||||
it != end_it;
|
||||
|
|
@ -1752,6 +1759,7 @@ void LLNotifications::cancelByName(const std::string& name)
|
|||
|
||||
void LLNotifications::cancelByOwner(const LLUUID ownerId)
|
||||
{
|
||||
LLMutexLock lock(&mItemsMutex);
|
||||
std::vector<LLNotificationPtr> notifs_to_cancel;
|
||||
for (LLNotificationSet::iterator it = mItems.begin(), end_it = mItems.end();
|
||||
it != end_it;
|
||||
|
|
@ -1799,11 +1807,6 @@ LLNotificationPtr LLNotifications::find(LLUUID uuid)
|
|||
}
|
||||
}
|
||||
|
||||
void LLNotifications::forEachNotification(NotificationProcess process)
|
||||
{
|
||||
std::for_each(mItems.begin(), mItems.end(), process);
|
||||
}
|
||||
|
||||
std::string LLNotifications::getGlobalString(const std::string& key) const
|
||||
{
|
||||
GlobalStringMap::const_iterator it = mGlobalStrings.find(key);
|
||||
|
|
|
|||
|
|
@ -738,16 +738,19 @@ class LLNotificationChannelBase :
|
|||
{
|
||||
LOG_CLASS(LLNotificationChannelBase);
|
||||
public:
|
||||
LLNotificationChannelBase(LLNotificationFilter filter)
|
||||
: mFilter(filter),
|
||||
mItems()
|
||||
{}
|
||||
LLNotificationChannelBase(LLNotificationFilter filter)
|
||||
: mFilter(filter)
|
||||
, mItems()
|
||||
, mItemsMutex()
|
||||
{}
|
||||
|
||||
virtual ~LLNotificationChannelBase()
|
||||
{
|
||||
// explicit cleanup for easier issue detection
|
||||
mChanged.disconnect_all_slots();
|
||||
mPassedFilter.disconnect_all_slots();
|
||||
mFailedFilter.disconnect_all_slots();
|
||||
LLMutexLock lock(&mItemsMutex);
|
||||
mItems.clear();
|
||||
}
|
||||
// you can also connect to a Channel, so you can be notified of
|
||||
|
|
@ -786,6 +789,7 @@ protected:
|
|||
LLStandardSignal mChanged;
|
||||
LLStandardSignal mPassedFilter;
|
||||
LLStandardSignal mFailedFilter;
|
||||
LLMutex mItemsMutex;
|
||||
|
||||
// these are action methods that subclasses can override to take action
|
||||
// on specific types of changes; the management of the mItems list is
|
||||
|
|
@ -835,7 +839,7 @@ public:
|
|||
LLNotificationChannel(const Params& p = Params());
|
||||
LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter);
|
||||
|
||||
virtual ~LLNotificationChannel() {}
|
||||
virtual ~LLNotificationChannel();
|
||||
typedef LLNotificationSet::iterator Iterator;
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
|
|
@ -844,21 +848,23 @@ public:
|
|||
{
|
||||
return boost::iterator_range<parents_iter>(mParents);
|
||||
}
|
||||
|
||||
void connectToChannel(const std::string& channel_name);
|
||||
|
||||
|
||||
bool isEmpty() const;
|
||||
S32 size() const;
|
||||
|
||||
Iterator begin();
|
||||
Iterator end();
|
||||
size_t size();
|
||||
|
||||
size_t size();
|
||||
|
||||
typedef boost::function<void(LLNotificationPtr)> NotificationProcess;
|
||||
void forEachNotification(NotificationProcess process);
|
||||
|
||||
std::string summarize();
|
||||
|
||||
protected:
|
||||
void connectToChannel(const std::string& channel_name);
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::vector<std::string> mParents;
|
||||
std::vector<LLBoundListener> mListeners;
|
||||
};
|
||||
|
||||
// An interface class to provide a clean linker seam to the LLNotifications class.
|
||||
|
|
@ -924,10 +930,6 @@ public:
|
|||
void update(const LLNotificationPtr pNotif);
|
||||
|
||||
LLNotificationPtr find(LLUUID uuid);
|
||||
|
||||
typedef boost::function<void (LLNotificationPtr)> NotificationProcess;
|
||||
|
||||
void forEachNotification(NotificationProcess process);
|
||||
|
||||
// This is all stuff for managing the templates
|
||||
// take your template out
|
||||
|
|
|
|||
|
|
@ -149,11 +149,11 @@ void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
|
|||
if (channel)
|
||||
{
|
||||
LLSD notifications(LLSD::emptyArray());
|
||||
for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
|
||||
ni != nend; ++ni)
|
||||
{
|
||||
notifications.append(asLLSD(*ni));
|
||||
}
|
||||
std::function<void(LLNotificationPtr)> func = [notifications](LLNotificationPtr ni) mutable
|
||||
{
|
||||
notifications.append(asLLSD(ni));
|
||||
};
|
||||
channel->forEachNotification(func);
|
||||
response["notifications"] = notifications;
|
||||
}
|
||||
LLEventPumps::instance().obtain(params["reply"]).post(response);
|
||||
|
|
|
|||
|
|
@ -104,6 +104,14 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
|
|||
}
|
||||
}
|
||||
|
||||
LLSearchEditor::~LLSearchEditor()
|
||||
{
|
||||
mSearchButton = NULL;
|
||||
mClearButton = NULL;
|
||||
mSearchEditor->deleteAllChildren();
|
||||
deleteAllChildren();
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::draw()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ protected:
|
|||
friend class LLUICtrlFactory;
|
||||
|
||||
public:
|
||||
virtual ~LLSearchEditor() {}
|
||||
virtual ~LLSearchEditor();
|
||||
|
||||
/*virtual*/ void draw();
|
||||
|
||||
|
|
|
|||
|
|
@ -440,7 +440,13 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
|
|||
tooltip_params.rect = LLRect (0, 1, 1, 0);
|
||||
|
||||
if (tooltip_params.create_callback.isProvided())
|
||||
mToolTip = tooltip_params.create_callback()(tooltip_params);
|
||||
{
|
||||
mToolTip = tooltip_params.create_callback()(tooltip_params);
|
||||
if (mToolTip == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
|
||||
|
||||
|
|
@ -492,7 +498,7 @@ void LLToolTipMgr::show(const LLToolTip::Params& params)
|
|||
{
|
||||
if (!params.styled_message.isProvided()
|
||||
&& (!params.message.isProvided() || params.message().empty())
|
||||
&& !params.image.isProvided()) return;
|
||||
&& !params.image.isProvided() && !params.create_callback.isProvided()) return;
|
||||
|
||||
// fill in default tooltip params from tool_tip.xml
|
||||
LLToolTip::Params params_with_defaults(params);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam)
|
|||
BSTR pNamespace = nullptr;
|
||||
|
||||
*pdwAdapterRam = 0;
|
||||
hrCoInitialize = CoInitialize( 0 );
|
||||
hrCoInitialize = CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||
|
||||
hr = CoCreateInstance( CLSID_WbemLocator,
|
||||
nullptr,
|
||||
|
|
@ -234,7 +234,7 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
|||
std::string mDriverVersion;
|
||||
HRESULT hrCoInitialize = S_OK;
|
||||
HRESULT hres;
|
||||
hrCoInitialize = CoInitialize(0);
|
||||
hrCoInitialize = CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||
IWbemLocator *pLoc = NULL;
|
||||
|
||||
hres = CoCreateInstance(
|
||||
|
|
@ -687,7 +687,7 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
|
|||
BOOL ok = FALSE;
|
||||
HRESULT hr;
|
||||
|
||||
CoInitialize(NULL);
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
IDxDiagProvider *dx_diag_providerp = NULL;
|
||||
IDxDiagContainer *dx_diag_rootp = NULL;
|
||||
|
|
@ -976,7 +976,7 @@ LLSD LLDXHardware::getDisplayInfo()
|
|||
LLTimer hw_timer;
|
||||
HRESULT hr;
|
||||
LLSD ret;
|
||||
CoInitialize(NULL);
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
IDxDiagProvider *dx_diag_providerp = NULL;
|
||||
IDxDiagContainer *dx_diag_rootp = NULL;
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloaterimcontainer.cpp
|
||||
llfloaterinspect.cpp
|
||||
llfloaterinventorysettings.cpp
|
||||
llfloaterinventorythumbnailshelper.cpp
|
||||
llfloaterjoystick.cpp
|
||||
llfloaterlagmeter.cpp
|
||||
llfloaterland.cpp
|
||||
|
|
@ -887,6 +888,7 @@ set(viewer_HEADER_FILES
|
|||
llfloaterimcontainer.h
|
||||
llfloaterinspect.h
|
||||
llfloaterinventorysettings.h
|
||||
llfloaterinventorythumbnailshelper.h
|
||||
llfloaterjoystick.h
|
||||
llfloaterlagmeter.h
|
||||
llfloaterland.h
|
||||
|
|
|
|||
|
|
@ -4335,6 +4335,10 @@ void LLAgent::teleportRequest(
|
|||
// Landmark ID = LLUUID::null means teleport home
|
||||
void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
|
||||
{
|
||||
if (landmark_asset_id.isNull())
|
||||
{
|
||||
gAgentCamera.resetView();
|
||||
}
|
||||
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
|
||||
startTeleportRequest();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1711,7 +1711,7 @@ bool LLAppViewer::cleanup()
|
|||
LLNotifications::instance().clear();
|
||||
|
||||
// workaround for DEV-35406 crash on shutdown
|
||||
LLEventPumps::instance().reset();
|
||||
LLEventPumps::instance().reset(true);
|
||||
|
||||
//dump scene loading monitor results
|
||||
if (LLSceneMonitor::instanceExists())
|
||||
|
|
|
|||
|
|
@ -177,6 +177,11 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
|
|||
LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this);
|
||||
}
|
||||
|
||||
LLNotificationChiclet::~LLNotificationChiclet()
|
||||
{
|
||||
mNotificationChannel.reset();
|
||||
}
|
||||
|
||||
void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
|
||||
{
|
||||
std::string action = user_data.asString();
|
||||
|
|
|
|||
|
|
@ -531,8 +531,9 @@ public:
|
|||
struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
|
||||
|
||||
protected:
|
||||
struct ChicletNotificationChannel : public LLNotificationChannel
|
||||
class ChicletNotificationChannel : public LLNotificationChannel
|
||||
{
|
||||
public:
|
||||
ChicletNotificationChannel(LLNotificationChiclet* chiclet)
|
||||
: LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
|
||||
, mChiclet(chiclet)
|
||||
|
|
@ -542,6 +543,7 @@ protected:
|
|||
connectToChannel("Offer");
|
||||
connectToChannel("Notifications");
|
||||
}
|
||||
virtual ~ChicletNotificationChannel() {}
|
||||
|
||||
static bool filterNotification(LLNotificationPtr notify);
|
||||
// connect counter updaters to the corresponding signals
|
||||
|
|
@ -553,9 +555,10 @@ protected:
|
|||
};
|
||||
|
||||
boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
|
||||
|
||||
LLNotificationChiclet(const Params& p);
|
||||
|
||||
|
||||
LLNotificationChiclet(const Params& p);
|
||||
~LLNotificationChiclet();
|
||||
|
||||
/**
|
||||
* Processes clicks on chiclet menu.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,543 @@
|
|||
/**
|
||||
* @file llfloaterinventorythumbnailshelper.cpp
|
||||
* @author Callum Prentice
|
||||
* @brief LLFloaterInventoryThumbnailsHelper class implementation
|
||||
*
|
||||
* Usage instructions and some brief notes can be found in Confluence here:
|
||||
* https://lindenlab.atlassian.net/wiki/spaces/~174746736/pages/2928672843/Inventory+Thumbnail+Helper+Tool
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llaisapi.h"
|
||||
#include "llclipboard.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
#include "llfloaterinventorythumbnailshelper.h"
|
||||
|
||||
LLFloaterInventoryThumbnailsHelper::LLFloaterInventoryThumbnailsHelper(const LLSD& key)
|
||||
: LLFloater("floater_inventory_thumbnails_helper")
|
||||
{
|
||||
}
|
||||
|
||||
LLFloaterInventoryThumbnailsHelper::~LLFloaterInventoryThumbnailsHelper()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLFloaterInventoryThumbnailsHelper::postBuild()
|
||||
{
|
||||
mInventoryThumbnailsList = getChild<LLScrollListCtrl>("inventory_thumbnails_list");
|
||||
mInventoryThumbnailsList->setAllowMultipleSelection(true);
|
||||
|
||||
mOutputLog = getChild<LLTextEditor>("output_log");
|
||||
mOutputLog->setMaxTextLength(0xffff * 0x10);
|
||||
|
||||
mPasteItemsBtn = getChild<LLUICtrl>("paste_items_btn");
|
||||
mPasteItemsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteItems, this));
|
||||
mPasteItemsBtn->setEnabled(true);
|
||||
|
||||
mPasteTexturesBtn = getChild<LLUICtrl>("paste_textures_btn");
|
||||
mPasteTexturesBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteTextures, this));
|
||||
mPasteTexturesBtn->setEnabled(true);
|
||||
|
||||
mWriteThumbnailsBtn = getChild<LLUICtrl>("write_thumbnails_btn");
|
||||
mWriteThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onWriteThumbnails, this));
|
||||
mWriteThumbnailsBtn->setEnabled(false);
|
||||
|
||||
mLogMissingThumbnailsBtn = getChild<LLUICtrl>("log_missing_thumbnails_btn");
|
||||
mLogMissingThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onLogMissingThumbnails, this));
|
||||
mLogMissingThumbnailsBtn->setEnabled(false);
|
||||
|
||||
mClearThumbnailsBtn = getChild<LLUICtrl>("clear_thumbnails_btn");
|
||||
mClearThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onClearThumbnails, this));
|
||||
mClearThumbnailsBtn->setEnabled(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Records an entry in the pasted items - saves it to a map and writes it to the log
|
||||
// window for later confirmation/validation - since it uses a map, duplicates (based on
|
||||
// the name) are discarded
|
||||
void LLFloaterInventoryThumbnailsHelper::recordInventoryItemEntry(LLViewerInventoryItem* item)
|
||||
{
|
||||
const std::string name = item->getName();
|
||||
|
||||
std::map<std::string, LLViewerInventoryItem*>::iterator iter = mItemNamesItems.find(name);
|
||||
if (iter == mItemNamesItems.end())
|
||||
{
|
||||
mItemNamesItems.insert({name, item});
|
||||
|
||||
writeToLog(
|
||||
STRINGIZE(
|
||||
"ITEM " << mItemNamesItems.size() << "> " <<
|
||||
name <<
|
||||
std::endl
|
||||
), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dupe - do not save
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the user has copied items from their inventory and selects the Paste Items button
|
||||
// in the UI - iterates over items and folders and saves details of each one.
|
||||
// The first use of this tool is for updating NUX items and as such, only looks for OBJECTS,
|
||||
// CLOTHING and BODYPARTS - later versions of this tool should make that selection editable.
|
||||
void LLFloaterInventoryThumbnailsHelper::onPasteItems()
|
||||
{
|
||||
if (!LLClipboard::instance().hasContents())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writeToLog(
|
||||
STRINGIZE(
|
||||
"\n==== Pasting items from inventory ====" <<
|
||||
std::endl
|
||||
), false);
|
||||
|
||||
std::vector<LLUUID> objects;
|
||||
LLClipboard::instance().pasteFromClipboard(objects);
|
||||
size_t count = objects.size();
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
const LLUUID& entry = objects.at(i);
|
||||
|
||||
// Check for a folder
|
||||
const LLInventoryCategory* cat = gInventory.getCategory(entry);
|
||||
if (cat)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
LLIsType is_object(LLAssetType::AT_OBJECT);
|
||||
gInventory.collectDescendentsIf(cat->getUUID(),
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_object);
|
||||
|
||||
LLIsType is_bodypart(LLAssetType::AT_BODYPART);
|
||||
gInventory.collectDescendentsIf(cat->getUUID(),
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_bodypart);
|
||||
|
||||
LLIsType is_clothing(LLAssetType::AT_CLOTHING);
|
||||
gInventory.collectDescendentsIf(cat->getUUID(),
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_clothing);
|
||||
|
||||
for (size_t i = 0; i < item_array.size(); i++)
|
||||
{
|
||||
LLViewerInventoryItem* item = item_array.at(i);
|
||||
recordInventoryItemEntry(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an item
|
||||
LLViewerInventoryItem* item = gInventory.getItem(entry);
|
||||
if (item)
|
||||
{
|
||||
const LLAssetType::EType item_type = item->getType();
|
||||
if (item_type == LLAssetType::AT_OBJECT || item_type == LLAssetType::AT_BODYPART || item_type == LLAssetType::AT_CLOTHING)
|
||||
{
|
||||
recordInventoryItemEntry(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the main list view based on what we found
|
||||
updateDisplayList();
|
||||
|
||||
// update the buttons enabled state based on what we found/saved
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
// Records a entry in the pasted textures - saves it to a map and writes it to the log
|
||||
// window for later confirmation/validation - since it uses a map, duplicates (based on
|
||||
// the name) are discarded
|
||||
void LLFloaterInventoryThumbnailsHelper::recordTextureItemEntry(LLViewerInventoryItem* item)
|
||||
{
|
||||
const std::string name = item->getName();
|
||||
|
||||
std::map<std::string, LLUUID>::iterator iter = mTextureNamesIDs.find(name);
|
||||
if (iter == mTextureNamesIDs.end())
|
||||
{
|
||||
LLUUID id = item->getAssetUUID();
|
||||
mTextureNamesIDs.insert({name, id});
|
||||
|
||||
writeToLog(
|
||||
STRINGIZE(
|
||||
"TEXTURE " << mTextureNamesIDs.size() << "> " <<
|
||||
name <<
|
||||
//" | " <<
|
||||
//id.asString() <<
|
||||
std::endl
|
||||
), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dupe - do not save
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the user has copied textures from their inventory and selects the Paste Textures
|
||||
// button in the UI - iterates over textures and folders and saves details of each one.
|
||||
void LLFloaterInventoryThumbnailsHelper::onPasteTextures()
|
||||
{
|
||||
if (!LLClipboard::instance().hasContents())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writeToLog(
|
||||
STRINGIZE(
|
||||
"\n==== Pasting textures from inventory ====" <<
|
||||
std::endl
|
||||
), false);
|
||||
|
||||
std::vector<LLUUID> objects;
|
||||
LLClipboard::instance().pasteFromClipboard(objects);
|
||||
size_t count = objects.size();
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
const LLUUID& entry = objects.at(i);
|
||||
|
||||
const LLInventoryCategory* cat = gInventory.getCategory(entry);
|
||||
if (cat)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
LLIsType is_object(LLAssetType::AT_TEXTURE);
|
||||
gInventory.collectDescendentsIf(cat->getUUID(),
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_object);
|
||||
|
||||
for (size_t i = 0; i < item_array.size(); i++)
|
||||
{
|
||||
LLViewerInventoryItem* item = item_array.at(i);
|
||||
recordTextureItemEntry(item);
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* item = gInventory.getItem(entry);
|
||||
if (item)
|
||||
{
|
||||
const LLAssetType::EType item_type = item->getType();
|
||||
if (item_type == LLAssetType::AT_TEXTURE)
|
||||
{
|
||||
recordTextureItemEntry(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the main list view based on what we found
|
||||
updateDisplayList();
|
||||
|
||||
// update the buttons enabled state based on what we found/saved
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
// Updates the main list of entries in the UI based on what is in the maps/storage
|
||||
void LLFloaterInventoryThumbnailsHelper::updateDisplayList()
|
||||
{
|
||||
mInventoryThumbnailsList->deleteAllItems();
|
||||
|
||||
std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin();
|
||||
while (item_iter != mItemNamesItems.end())
|
||||
{
|
||||
std::string item_name = (*item_iter).first;
|
||||
|
||||
std::string existing_texture_name = std::string();
|
||||
LLUUID existing_thumbnail_id = (*item_iter).second->getThumbnailUUID();
|
||||
if (existing_thumbnail_id != LLUUID::null)
|
||||
{
|
||||
existing_texture_name = existing_thumbnail_id.asString();
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_texture_name = "none";
|
||||
}
|
||||
|
||||
std::string new_texture_name = std::string();
|
||||
std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name);
|
||||
if (texture_iter != mTextureNamesIDs.end())
|
||||
{
|
||||
new_texture_name = (*texture_iter).first;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_texture_name = "missing";
|
||||
}
|
||||
|
||||
LLSD row;
|
||||
row["columns"][EListColumnNum::NAME]["column"] = "item_name";
|
||||
row["columns"][EListColumnNum::NAME]["type"] = "text";
|
||||
row["columns"][EListColumnNum::NAME]["value"] = item_name;
|
||||
row["columns"][EListColumnNum::NAME]["font"]["name"] = "Monospace";
|
||||
|
||||
row["columns"][EListColumnNum::EXISTING_TEXTURE]["column"] = "existing_texture";
|
||||
row["columns"][EListColumnNum::EXISTING_TEXTURE]["type"] = "text";
|
||||
row["columns"][EListColumnNum::EXISTING_TEXTURE]["font"]["name"] = "Monospace";
|
||||
row["columns"][EListColumnNum::EXISTING_TEXTURE]["value"] = existing_texture_name;
|
||||
|
||||
row["columns"][EListColumnNum::NEW_TEXTURE]["column"] = "new_texture";
|
||||
row["columns"][EListColumnNum::NEW_TEXTURE]["type"] = "text";
|
||||
row["columns"][EListColumnNum::NEW_TEXTURE]["font"]["name"] = "Monospace";
|
||||
row["columns"][EListColumnNum::NEW_TEXTURE]["value"] = new_texture_name;
|
||||
|
||||
mInventoryThumbnailsList->addElement(row);
|
||||
|
||||
++item_iter;
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
// *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model.
|
||||
// temp code in transition
|
||||
void inventoryThumbnailsHelperCb(LLPointer<LLInventoryCallback> cb, LLUUID id)
|
||||
{
|
||||
if (cb.notNull())
|
||||
{
|
||||
cb->fire(id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Makes calls to the AIS v3 API to record the local changes made to the thumbnails.
|
||||
// If this is not called, the operations (e.g. set thumbnail or clear thumbnail)
|
||||
// appear to work but do not push the changes back to the inventory (local cache view only)
|
||||
bool writeInventoryThumbnailID(LLUUID item_id, LLUUID thumbnail_asset_id)
|
||||
{
|
||||
if (AISAPI::isAvailable())
|
||||
{
|
||||
|
||||
LLSD updates;
|
||||
updates["thumbnail"] = LLSD().with("asset_id", thumbnail_asset_id.asString());
|
||||
|
||||
LLPointer<LLInventoryCallback> cb;
|
||||
|
||||
AISAPI::completion_t cr = boost::bind(&inventoryThumbnailsHelperCb, cb, _1);
|
||||
AISAPI::UpdateItem(item_id, updates, cr);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Unable to write inventory thumbnail because the AIS API is not available" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the Write Thumbanils button is pushed. Iterates over the name/item and
|
||||
// name/.texture maps and where it finds a common name, extracts what is needed and
|
||||
// writes the thumbnail accordingly.
|
||||
void LLFloaterInventoryThumbnailsHelper::onWriteThumbnails()
|
||||
{
|
||||
// create and show confirmation (Yes/No) textbox since this is a destructive operation
|
||||
LLNotificationsUtil::add("WriteInventoryThumbnailsWarning", LLSD(), LLSD(),
|
||||
[&](const LLSD & notif, const LLSD & resp)
|
||||
{
|
||||
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
|
||||
if (opt == 0)
|
||||
{
|
||||
std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin();
|
||||
while (item_iter != mItemNamesItems.end())
|
||||
{
|
||||
std::string item_name = (*item_iter).first;
|
||||
|
||||
std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name);
|
||||
if (texture_iter != mTextureNamesIDs.end())
|
||||
{
|
||||
LLUUID item_id = (*item_iter).second->getUUID();
|
||||
|
||||
LLUUID thumbnail_asset_id = (*texture_iter).second;
|
||||
|
||||
writeToLog(
|
||||
STRINGIZE(
|
||||
"WRITING THUMB " <<
|
||||
(*item_iter).first <<
|
||||
"\n" <<
|
||||
"item ID: " <<
|
||||
item_id <<
|
||||
"\n" <<
|
||||
"thumbnail texture ID: " <<
|
||||
thumbnail_asset_id <<
|
||||
"\n"
|
||||
), true);
|
||||
|
||||
|
||||
(*item_iter).second->setThumbnailUUID(thumbnail_asset_id);
|
||||
|
||||
// This additional step (notifying AIS API) is required
|
||||
// to make the changes persist outside of the local cache
|
||||
writeInventoryThumbnailID(item_id, thumbnail_asset_id);
|
||||
}
|
||||
|
||||
++item_iter;
|
||||
}
|
||||
|
||||
updateDisplayList();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "Writing new thumbnails was canceled" << LL_ENDL;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Called when the Log Items with Missing Thumbnails is selected. This merely writes
|
||||
// a list of all the items for which the thumbnail ID is Null. Typical use case is to
|
||||
// copy from the log window, pasted to Slack to illustrate which items are missing
|
||||
// a thumbnail
|
||||
void LLFloaterInventoryThumbnailsHelper::onLogMissingThumbnails()
|
||||
{
|
||||
std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin();
|
||||
while (item_iter != mItemNamesItems.end())
|
||||
{
|
||||
LLUUID thumbnail_id = (*item_iter).second->getThumbnailUUID();
|
||||
|
||||
if (thumbnail_id == LLUUID::null)
|
||||
{
|
||||
writeToLog(
|
||||
STRINGIZE(
|
||||
"Missing thumbnail: " <<
|
||||
(*item_iter).first <<
|
||||
std::endl
|
||||
), true);
|
||||
}
|
||||
|
||||
++item_iter;
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the Clear Thumbnail button is selected. Code to perform the clear (really
|
||||
// just writing a NULL UUID into the thumbnail field) is behind an "Are you Sure?" dialog
|
||||
// since it cannot be undone and potentinally, you could remove the thumbnails from your
|
||||
// whole inventory this way.
|
||||
void LLFloaterInventoryThumbnailsHelper::onClearThumbnails()
|
||||
{
|
||||
// create and show confirmation (Yes/No) textbox since this is a destructive operation
|
||||
LLNotificationsUtil::add("ClearInventoryThumbnailsWarning", LLSD(), LLSD(),
|
||||
[&](const LLSD & notif, const LLSD & resp)
|
||||
{
|
||||
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
|
||||
if (opt == 0)
|
||||
{
|
||||
std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin();
|
||||
while (item_iter != mItemNamesItems.end())
|
||||
{
|
||||
(*item_iter).second->setThumbnailUUID(LLUUID::null);
|
||||
|
||||
// This additional step (notifying AIS API) is required
|
||||
// to make the changes persist outside of the local cache
|
||||
const LLUUID item_id = (*item_iter).second->getUUID();
|
||||
writeInventoryThumbnailID(item_id, LLUUID::null);
|
||||
|
||||
++item_iter;
|
||||
}
|
||||
|
||||
updateDisplayList();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "Clearing on thumbnails was canceled" << LL_ENDL;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update the endabled state of some of the UI buttons based on what has
|
||||
// been recorded so far. For example, if there are no valid item/texture pairs,
|
||||
// then the Write Thumbnails button is not enabled.
|
||||
void LLFloaterInventoryThumbnailsHelper::updateButtonStates()
|
||||
{
|
||||
size_t found_count = 0;
|
||||
|
||||
std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin();
|
||||
while (item_iter != mItemNamesItems.end())
|
||||
{
|
||||
std::string item_name = (*item_iter).first;
|
||||
|
||||
std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name);
|
||||
if (texture_iter != mTextureNamesIDs.end())
|
||||
{
|
||||
found_count++;
|
||||
}
|
||||
|
||||
++item_iter;
|
||||
}
|
||||
|
||||
// the "Write Thumbnails" button is only enabled when there is at least one
|
||||
// item with a matching texture ready to be written to the thumbnail field
|
||||
if (found_count > 0)
|
||||
{
|
||||
mWriteThumbnailsBtn->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mWriteThumbnailsBtn->setEnabled(false);
|
||||
}
|
||||
|
||||
// The "Log Missing Items" and "Clear Thumbnails" buttons are only enabled
|
||||
// when there is at least 1 item that was pasted from inventory (doesn't need
|
||||
// to have a matching texture for these operations)
|
||||
if (mItemNamesItems.size() > 0)
|
||||
{
|
||||
mLogMissingThumbnailsBtn->setEnabled(true);
|
||||
mClearThumbnailsBtn->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLogMissingThumbnailsBtn->setEnabled(false);
|
||||
mClearThumbnailsBtn->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for writing a line to the log window. Currently the only additional
|
||||
// feature is that it scrolls to the bottom each time a line is written but it
|
||||
// is envisaged that other common actions will be added here eventually - E.G. write eavh
|
||||
// line to the Second Life log too for example.
|
||||
void LLFloaterInventoryThumbnailsHelper::writeToLog(std::string logline, bool prepend_newline)
|
||||
{
|
||||
mOutputLog->appendText(logline, prepend_newline);
|
||||
|
||||
mOutputLog->setCursorAndScrollToEnd();
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file llfloaterinventorythumbnailshelper.h
|
||||
* @author Callum Prentice
|
||||
* @brief Helper floater for bulk processing of inventory thumbnails tool
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERINVENTORYTHUMBNAILSHELPER_H
|
||||
#define LL_LLFLOATERINVENTORYTHUMBNAILSHELPER_H
|
||||
|
||||
#include "llfloater.h"
|
||||
class LLTextEditor;
|
||||
class LLScrollListCtrl;
|
||||
class LLViewerInventoryItem;
|
||||
class LLUUID;
|
||||
|
||||
class LLFloaterInventoryThumbnailsHelper:
|
||||
public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
private:
|
||||
LLFloaterInventoryThumbnailsHelper(const LLSD& key);
|
||||
BOOL postBuild() override;
|
||||
~LLFloaterInventoryThumbnailsHelper();
|
||||
|
||||
LLScrollListCtrl* mInventoryThumbnailsList;
|
||||
|
||||
LLTextEditor* mOutputLog;
|
||||
|
||||
LLUICtrl* mPasteItemsBtn;
|
||||
void onPasteItems();
|
||||
|
||||
LLUICtrl* mPasteTexturesBtn;
|
||||
void onPasteTextures();
|
||||
|
||||
LLUICtrl* mWriteThumbnailsBtn;
|
||||
void onWriteThumbnails();
|
||||
|
||||
LLUICtrl* mLogMissingThumbnailsBtn;
|
||||
void onLogMissingThumbnails();
|
||||
|
||||
LLUICtrl* mClearThumbnailsBtn;
|
||||
void onClearThumbnails();
|
||||
|
||||
void recordInventoryItemEntry(LLViewerInventoryItem* item);
|
||||
void recordTextureItemEntry(LLViewerInventoryItem* item);
|
||||
void updateButtonStates();
|
||||
void updateDisplayList();
|
||||
void writeToLog(std::string logline, bool prepend_newline);
|
||||
|
||||
std::map<std::string, LLViewerInventoryItem*> mItemNamesItems;
|
||||
std::map<std::string, LLUUID> mTextureNamesIDs;
|
||||
|
||||
enum EListColumnNum
|
||||
{
|
||||
NAME = 0,
|
||||
EXISTING_TEXTURE = 1,
|
||||
NEW_TEXTURE = 2
|
||||
};
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERINVENTORYTHUMBNAILSHELPER_H
|
||||
|
|
@ -290,6 +290,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
|
|||
BOOL LLFloaterWorldMap::postBuild()
|
||||
{
|
||||
mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
|
||||
mMapView->setPan(0, 0, true);
|
||||
|
||||
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
|
||||
avatar_combo->selectFirstItem();
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!p.message.isProvided() || p.message().empty()))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// No or more than one texture found => show default tooltip
|
||||
return LLUICtrlFactory::create<LLToolTip>(p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2810,7 +2810,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
is_movable = can_move_folder_to_marketplace(master_folder, dest_folder, inv_cat, tooltip_msg, bundle_size);
|
||||
}
|
||||
|
||||
if (is_movable)
|
||||
if (is_movable && !move_is_into_landmarks)
|
||||
{
|
||||
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
|
||||
is_movable = active_panel != NULL;
|
||||
|
|
|
|||
|
|
@ -462,6 +462,13 @@ void copy_inventory_category(LLInventoryModel* model,
|
|||
gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func, cat->getThumbnailUUID());
|
||||
}
|
||||
|
||||
void copy_cb(const LLUUID& dest_folder, const LLUUID& root_id)
|
||||
{
|
||||
// Decrement the count in root_id since that one item won't be copied over
|
||||
LLMarketplaceData::instance().decrementValidationWaiting(root_id);
|
||||
update_folder_cb(dest_folder);
|
||||
};
|
||||
|
||||
void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& root_copy_id, bool move_no_copy_items)
|
||||
{
|
||||
model->notifyObservers();
|
||||
|
|
@ -480,12 +487,21 @@ void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryMode
|
|||
LLMarketplaceData::instance().setValidationWaiting(root_id, count_descendants_items(cat->getUUID()));
|
||||
}
|
||||
|
||||
LLPointer<LLInventoryCallback> cb;
|
||||
if (root_copy_id.isNull())
|
||||
{
|
||||
cb = new LLBoostFuncInventoryCallback(boost::bind(copy_cb, new_cat_uuid, root_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid));
|
||||
}
|
||||
|
||||
// Copy all the items
|
||||
LLInventoryModel::item_array_t item_array_copy = *item_array;
|
||||
for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
|
||||
{
|
||||
LLInventoryItem* item = *iter;
|
||||
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid));
|
||||
|
||||
if (item->getIsLinkType())
|
||||
{
|
||||
|
|
@ -500,8 +516,11 @@ void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryMode
|
|||
LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *)item;
|
||||
gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true);
|
||||
}
|
||||
// Decrement the count in root_id since that one item won't be copied over
|
||||
LLMarketplaceData::instance().decrementValidationWaiting(root_id);
|
||||
if (root_copy_id.isNull())
|
||||
{
|
||||
// Decrement the count in root_id since that one item won't be copied over
|
||||
LLMarketplaceData::instance().decrementValidationWaiting(root_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2386,30 +2386,46 @@ BOOL LLInventoryGallery::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||
return handled;
|
||||
}
|
||||
|
||||
void LLInventoryGallery::startDrag()
|
||||
void LLInventoryGallery::startDrag()
|
||||
{
|
||||
std::vector<EDragAndDropType> types;
|
||||
uuid_vec_t ids;
|
||||
LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_AGENT;
|
||||
for (LLUUID& selected_id : mSelectedItemIDs)
|
||||
{
|
||||
const LLInventoryItem* item = gInventory.getItem(selected_id);
|
||||
if (item)
|
||||
{
|
||||
if (item->getPermissions().getOwner() == ALEXANDRIA_LINDEN_ID)
|
||||
{
|
||||
src = LLToolDragAndDrop::SOURCE_LIBRARY;
|
||||
}
|
||||
|
||||
EDragAndDropType type = LLViewerAssetType::lookupDragAndDropType(item->getType());
|
||||
types.push_back(type);
|
||||
ids.push_back(selected_id);
|
||||
}
|
||||
|
||||
const LLViewerInventoryCategory* cat = gInventory.getCategory(selected_id);
|
||||
if (cat && gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID())
|
||||
&& !LLFolderType::lookupIsProtectedType((cat)->getPreferredType()))
|
||||
if (cat)
|
||||
{
|
||||
EDragAndDropType type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
|
||||
types.push_back(type);
|
||||
ids.push_back(selected_id);
|
||||
if (gInventory.isObjectDescendentOf(selected_id, gInventory.getLibraryRootFolderID()))
|
||||
{
|
||||
src = LLToolDragAndDrop::SOURCE_LIBRARY;
|
||||
EDragAndDropType type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
|
||||
types.push_back(type);
|
||||
ids.push_back(selected_id);
|
||||
}
|
||||
else if (gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID())
|
||||
&& !LLFolderType::lookupIsProtectedType((cat)->getPreferredType()))
|
||||
{
|
||||
EDragAndDropType type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
|
||||
types.push_back(type);
|
||||
ids.push_back(selected_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
LLToolDragAndDrop::getInstance()->beginMultiDrag(types, ids, LLToolDragAndDrop::SOURCE_AGENT);
|
||||
LLToolDragAndDrop::getInstance()->beginMultiDrag(types, ids, src);
|
||||
}
|
||||
|
||||
bool LLInventoryGallery::areViewsInitialized()
|
||||
|
|
|
|||
|
|
@ -358,7 +358,6 @@ void LLInventoryFetchItemsObserver::startFetch()
|
|||
{
|
||||
// Start fetching whole folder since we need all items
|
||||
LLInventoryModelBackgroundFetch::getInstance()->scheduleFolderFetch(folder.first, true);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ void LLWMIMethods::initCOMObjects()
|
|||
mHR = CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||
if (FAILED(mHR))
|
||||
{
|
||||
// if result S_FALSE, it's already initialized
|
||||
LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << std::hex << mHR << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -611,27 +611,17 @@ private:
|
|||
static void onIdleProcessQueue(void *userdata);
|
||||
|
||||
// doesn't hold just marketplace related ids
|
||||
static std::set<LLUUID> sAddQueue;
|
||||
static std::set<LLUUID> sStructureQueue;
|
||||
static bool sProcessingQueue;
|
||||
};
|
||||
|
||||
std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue;
|
||||
std::set<LLUUID> LLMarketplaceInventoryObserver::sStructureQueue;
|
||||
bool LLMarketplaceInventoryObserver::sProcessingQueue = false;
|
||||
|
||||
void LLMarketplaceInventoryObserver::changed(U32 mask)
|
||||
{
|
||||
if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting())
|
||||
{
|
||||
// When things are added to the marketplace, we might need to re-validate and fix the containing listings
|
||||
// just add whole list even if it contains items and non-marketplace folders
|
||||
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
|
||||
sAddQueue.insert(changed_items.begin(), changed_items.end());
|
||||
}
|
||||
|
||||
if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
|
||||
{
|
||||
if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
|
||||
{
|
||||
// When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
|
||||
// * stock counts changing : no copy items coming in and out will change the stock count on folders
|
||||
// * version and listing folders : moving those might invalidate the marketplace data itself
|
||||
|
|
@ -641,7 +631,7 @@ void LLMarketplaceInventoryObserver::changed(U32 mask)
|
|||
sStructureQueue.insert(changed_items.begin(), changed_items.end());
|
||||
}
|
||||
|
||||
if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty()))
|
||||
if (!sProcessingQueue && !sStructureQueue.empty())
|
||||
{
|
||||
gIdleCallbacks.addFunction(onIdleProcessQueue, NULL);
|
||||
// can do without sProcessingQueue, but it's usufull for simplicity and reliability
|
||||
|
|
@ -655,40 +645,6 @@ void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)
|
|||
const U64 MAX_PROCESSING_TIME = 1000;
|
||||
U64 stop_time = start_time + MAX_PROCESSING_TIME;
|
||||
|
||||
if (!sAddQueue.empty())
|
||||
{
|
||||
// Make a copy of sAddQueue since decrementValidationWaiting
|
||||
// can theoretically add more items
|
||||
std::set<LLUUID> add_queue(sAddQueue);
|
||||
sAddQueue.clear();
|
||||
|
||||
std::set<LLUUID>::const_iterator id_it = add_queue.begin();
|
||||
std::set<LLUUID>::const_iterator id_end = add_queue.end();
|
||||
// First, count the number of items in this list...
|
||||
S32 count = 0;
|
||||
for (; id_it != id_end; ++id_it)
|
||||
{
|
||||
LLInventoryObject* obj = gInventory.getObject(*id_it);
|
||||
if (obj && (LLAssetType::AT_CATEGORY != obj->getType()))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
// Then, decrement the folders of that amount
|
||||
// Note that of all of those, only one folder will be a listing folder (if at all).
|
||||
// The other will be ignored by the decrement method.
|
||||
id_it = add_queue.begin();
|
||||
for (; id_it != id_end; ++id_it)
|
||||
{
|
||||
LLInventoryObject* obj = gInventory.getObject(*id_it);
|
||||
if (obj && (LLAssetType::AT_CATEGORY == obj->getType()))
|
||||
{
|
||||
// can trigger notifyObservers
|
||||
LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time)
|
||||
{
|
||||
std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin();
|
||||
|
|
@ -722,7 +678,7 @@ void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)
|
|||
sStructureQueue.erase(id_it);
|
||||
}
|
||||
|
||||
if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty()))
|
||||
if (LLApp::isExiting() || sStructureQueue.empty())
|
||||
{
|
||||
// Nothing to do anymore
|
||||
gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL);
|
||||
|
|
|
|||
|
|
@ -1155,22 +1155,13 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu()
|
|||
registrar.add("Outfit.Delete", boost::bind(LLOutfitGallery::onRemoveOutfit, selected_id));
|
||||
registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2));
|
||||
registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitGalleryContextMenu::onThumbnail, this, selected_id));
|
||||
registrar.add("Outfit.Save", boost::bind(&LLOutfitGalleryContextMenu::onSave, this, selected_id));
|
||||
enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2));
|
||||
enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2));
|
||||
|
||||
return createFromFile("menu_gallery_outfit_tab.xml");
|
||||
}
|
||||
|
||||
void LLOutfitGalleryContextMenu::onThumbnail(const LLUUID& outfit_cat_id)
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && outfit_cat_id.notNull())
|
||||
{
|
||||
LLSD data(outfit_cat_id);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryContextMenu::onCreate(const LLSD& data)
|
||||
{
|
||||
LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(data.asString());
|
||||
|
|
@ -1205,7 +1196,6 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
|
|||
mMenu->setItemVisible("expand", FALSE);
|
||||
mMenu->setItemVisible("collapse", FALSE);
|
||||
mMenu->setItemVisible("thumbnail", have_selection);
|
||||
mMenu->setItemVisible("sepatator3", TRUE);
|
||||
mMenu->setItemVisible("sort_folders_by_name", TRUE);
|
||||
LLOutfitListGearMenuBase::onUpdateItemsVisibility();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,17 +195,13 @@ public:
|
|||
|
||||
friend class LLOutfitGallery;
|
||||
LLOutfitGalleryContextMenu(LLOutfitListBase* outfit_list)
|
||||
: LLOutfitContextMenu(outfit_list),
|
||||
mOutfitList(outfit_list){}
|
||||
: LLOutfitContextMenu(outfit_list){}
|
||||
|
||||
protected:
|
||||
/* virtual */ LLContextMenu* createMenu();
|
||||
bool onEnable(LLSD::String param);
|
||||
bool onVisible(LLSD::String param);
|
||||
void onThumbnail(const LLUUID& outfit_cat_id);
|
||||
void onCreate(const LLSD& data);
|
||||
private:
|
||||
LLOutfitListBase* mOutfitList;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llappearancemgr.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llinspecttexture.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llmenubutton.h"
|
||||
|
|
@ -62,7 +63,7 @@ bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LL
|
|||
return (LLStringUtil::compareDict(name1, name2) < 0);
|
||||
}
|
||||
|
||||
struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLAccordionCtrlTab::Params>
|
||||
struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLOutfitAccordionCtrlTab::Params>
|
||||
{
|
||||
Mandatory<LLWearableItemsList::Params> wearable_list;
|
||||
|
||||
|
|
@ -144,7 +145,8 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
|
|||
std::string name = cat->getName();
|
||||
|
||||
outfit_accordion_tab_params tab_params(get_accordion_tab_params());
|
||||
LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
|
||||
tab_params.cat_id = cat_id;
|
||||
LLOutfitAccordionCtrlTab *tab = LLUICtrlFactory::create<LLOutfitAccordionCtrlTab>(tab_params);
|
||||
if (!tab) return;
|
||||
LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
|
||||
wearable_list->setShape(tab->getLocalRect());
|
||||
|
|
@ -1028,6 +1030,8 @@ LLContextMenu* LLOutfitContextMenu::createMenu()
|
|||
registrar.add("Outfit.Edit", boost::bind(editOutfit));
|
||||
registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
|
||||
registrar.add("Outfit.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList));
|
||||
registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitContextMenu::onThumbnail, this, selected_id));
|
||||
registrar.add("Outfit.Save", boost::bind(&LLOutfitContextMenu::onSave, this, selected_id));
|
||||
|
||||
enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2));
|
||||
enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2));
|
||||
|
|
@ -1092,6 +1096,31 @@ void LLOutfitContextMenu::renameOutfit(const LLUUID& outfit_cat_id)
|
|||
LLAppearanceMgr::instance().renameOutfit(outfit_cat_id);
|
||||
}
|
||||
|
||||
void LLOutfitContextMenu::onThumbnail(const LLUUID &outfit_cat_id)
|
||||
{
|
||||
if (outfit_cat_id.notNull())
|
||||
{
|
||||
LLSD data(outfit_cat_id);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitContextMenu::onSave(const LLUUID &outfit_cat_id)
|
||||
{
|
||||
if (outfit_cat_id.notNull())
|
||||
{
|
||||
LLNotificationsUtil::add("ConfirmOverwriteOutfit", LLSD(), LLSD(),
|
||||
[outfit_cat_id](const LLSD ¬if, const LLSD &resp)
|
||||
{
|
||||
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
|
||||
if (opt == 0)
|
||||
{
|
||||
LLAppearanceMgr::getInstance()->onOutfitFolderCreated(outfit_cat_id, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
|
||||
: mOutfitList(olist),
|
||||
mMenu(NULL)
|
||||
|
|
@ -1110,6 +1139,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
|
|||
registrar.add("Gear.Expand", boost::bind(&LLOutfitListBase::onExpandAllFolders, mOutfitList));
|
||||
|
||||
registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
|
||||
registrar.add("Gear.Save", boost::bind(&LLOutfitListGearMenuBase::onSave, this));
|
||||
|
||||
registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this));
|
||||
registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this));
|
||||
|
|
@ -1135,8 +1165,7 @@ void LLOutfitListGearMenuBase::onUpdateItemsVisibility()
|
|||
if (!mMenu) return;
|
||||
|
||||
bool have_selection = getSelectedOutfitID().notNull();
|
||||
mMenu->setItemVisible("sepatator1", have_selection);
|
||||
mMenu->setItemVisible("sepatator2", have_selection);
|
||||
mMenu->setItemVisible("wear_separator", have_selection);
|
||||
mMenu->arrangeAndClear(); // update menu height
|
||||
}
|
||||
|
||||
|
|
@ -1181,6 +1210,20 @@ void LLOutfitListGearMenuBase::onAdd()
|
|||
}
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onSave()
|
||||
{
|
||||
const LLUUID &selected_id = getSelectedOutfitID();
|
||||
LLNotificationsUtil::add("ConfirmOverwriteOutfit", LLSD(), LLSD(),
|
||||
[selected_id](const LLSD ¬if, const LLSD &resp)
|
||||
{
|
||||
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
|
||||
if (opt == 0)
|
||||
{
|
||||
LLAppearanceMgr::getInstance()->onOutfitFolderCreated(selected_id, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onTakeOff()
|
||||
{
|
||||
// Take off selected outfit.
|
||||
|
|
@ -1234,15 +1277,6 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)
|
|||
return false;
|
||||
}
|
||||
|
||||
// *TODO This condition leads to menu item behavior inconsistent with
|
||||
// "Wear" button behavior and should be modified or removed.
|
||||
bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
|
||||
|
||||
if ("wear" == param)
|
||||
{
|
||||
return !is_worn;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1270,10 +1304,29 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
|
|||
if (!mMenu) return;
|
||||
mMenu->setItemVisible("expand", TRUE);
|
||||
mMenu->setItemVisible("collapse", TRUE);
|
||||
mMenu->setItemVisible("thumbnail", FALSE); // Never visible?
|
||||
mMenu->setItemVisible("sepatator3", FALSE);
|
||||
mMenu->setItemVisible("thumbnail", getSelectedOutfitID().notNull());
|
||||
mMenu->setItemVisible("sort_folders_by_name", FALSE);
|
||||
LLOutfitListGearMenuBase::onUpdateItemsVisibility();
|
||||
}
|
||||
|
||||
BOOL LLOutfitAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (y >= getLocalRect().getHeight() - getHeaderHeight())
|
||||
{
|
||||
LLSD params;
|
||||
params["inv_type"] = LLInventoryType::IT_CATEGORY;
|
||||
params["thumbnail_id"] = gInventory.getCategory(mFolderID)->getThumbnailUUID();
|
||||
params["item_id"] = mFolderID;
|
||||
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params()
|
||||
.message(getToolTip())
|
||||
.sticky_rect(calcScreenRect())
|
||||
.delay_time(LLView::getTooltipTimeout())
|
||||
.create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1))
|
||||
.create_params(params));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return LLAccordionCtrlTab::handleToolTip(x, y, mask);
|
||||
}
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llpanel.h"
|
||||
|
||||
// newview
|
||||
#include "llaccordionctrltab.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lllistcontextmenu.h"
|
||||
#include "llpanelappearancetab.h"
|
||||
|
|
@ -147,6 +148,9 @@ protected:
|
|||
|
||||
static void renameOutfit(const LLUUID& outfit_cat_id);
|
||||
|
||||
void onThumbnail(const LLUUID &outfit_cat_id);
|
||||
void onSave(const LLUUID &outfit_cat_id);
|
||||
|
||||
private:
|
||||
LLOutfitListBase* mOutfitList;
|
||||
};
|
||||
|
|
@ -178,6 +182,7 @@ private:
|
|||
void onAdd();
|
||||
void onTakeOff();
|
||||
void onRename();
|
||||
void onSave();
|
||||
void onCreate(const LLSD& data);
|
||||
bool onEnable(LLSD::String param);
|
||||
bool onVisible(LLSD::String param);
|
||||
|
|
@ -193,7 +198,27 @@ protected:
|
|||
/*virtual*/ void onUpdateItemsVisibility();
|
||||
};
|
||||
|
||||
/**
|
||||
class LLOutfitAccordionCtrlTab : public LLAccordionCtrlTab
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLAccordionCtrlTab::Params>
|
||||
{
|
||||
Optional<LLUUID> cat_id;
|
||||
Params() : cat_id("cat_id") {}
|
||||
};
|
||||
|
||||
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
|
||||
|
||||
protected:
|
||||
LLOutfitAccordionCtrlTab(const LLOutfitAccordionCtrlTab::Params &p)
|
||||
: LLAccordionCtrlTab(p),
|
||||
mFolderID(p.cat_id)
|
||||
{}
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
LLUUID mFolderID;
|
||||
};
|
||||
/**
|
||||
* @class LLOutfitsList
|
||||
*
|
||||
* A list of agents's outfits from "My Outfits" inventory category
|
||||
|
|
|
|||
|
|
@ -1067,6 +1067,12 @@ void LLTeleportHistoryPanel::onGearMenuAction(const LLSD& userdata)
|
|||
LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
|
||||
boost::bind(&LLTeleportHistoryPanel::gotSLURLCallback, _1));
|
||||
}
|
||||
else if ("remove" == command_name)
|
||||
{
|
||||
LLTeleportHistoryStorage::getInstance()->removeItem(index);
|
||||
LLTeleportHistoryStorage::getInstance()->save();
|
||||
showTeleportHistory();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const
|
||||
|
|
@ -1121,7 +1127,8 @@ bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const
|
|||
if ("teleport" == command_name
|
||||
|| "view" == command_name
|
||||
|| "show_on_map" == command_name
|
||||
|| "copy_slurl" == command_name)
|
||||
|| "copy_slurl" == command_name
|
||||
|| "remove" == command_name)
|
||||
{
|
||||
if (!mLastSelectedFlatlList)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ namespace LLPerfStats
|
|||
{
|
||||
assert_main_thread();
|
||||
// these following variables are proxies for pipeline statics we do not need a two way update (no llviewercontrol handler)
|
||||
if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImpostors); };
|
||||
if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("RenderAvatarMaxNonImpostors", nonImpostors); };
|
||||
if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); };
|
||||
if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); };
|
||||
if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipMin", userMinDrawDistance); };
|
||||
|
|
@ -378,7 +378,7 @@ namespace LLPerfStats
|
|||
auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance));
|
||||
if( count != tunables.nonImpostors )
|
||||
{
|
||||
tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER );
|
||||
tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : 0 );
|
||||
LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,3 +120,13 @@ S32 LLPlacesInventoryPanel::notify(const LLSD& info)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL LLPlacesInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
|
||||
EAcceptance *accept, std::string &tooltip_msg)
|
||||
{
|
||||
if (mAcceptsDragAndDrop)
|
||||
{
|
||||
return LLInventoryPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,14 @@ public:
|
|||
LLPlacesInventoryPanel(const Params& p);
|
||||
~LLPlacesInventoryPanel();
|
||||
|
||||
LLFolderView * createFolderRoot(LLUUID root_id );
|
||||
LLFolderView * createFolderRoot(LLUUID root_id ) override;
|
||||
void saveFolderState();
|
||||
void restoreFolderState();
|
||||
|
||||
virtual S32 notify(const LLSD& info) ;
|
||||
virtual S32 notify(const LLSD& info) override;
|
||||
|
||||
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
|
||||
EAcceptance *accept, std::string &tooltip_msg) override;
|
||||
|
||||
private:
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
#include "llfloaterimsession.h"
|
||||
#include "llfloaterinspect.h"
|
||||
#include "llfloaterinventorysettings.h"
|
||||
#include "llfloaterinventorythumbnailshelper.h"
|
||||
#include "llfloaterjoystick.h"
|
||||
#include "llfloaterlagmeter.h"
|
||||
#include "llfloaterland.h"
|
||||
|
|
@ -243,6 +244,7 @@ public:
|
|||
"group_picker",
|
||||
"hud",
|
||||
"incoming_call",
|
||||
"inventory_thumbnails_helper",
|
||||
"linkreplace",
|
||||
"mem_leaking",
|
||||
"marketplace_validation",
|
||||
|
|
@ -329,7 +331,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("build", "floater_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTools>);
|
||||
LLFloaterReg::add("build_options", "floater_build_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuildOptions>);
|
||||
LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
|
||||
|
||||
|
||||
LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
|
||||
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
|
||||
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
|
||||
|
|
@ -376,6 +378,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
|
||||
LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);
|
||||
LLFloaterReg::add("inventory_thumbnails_helper", "floater_inventory_thumbnails_helper.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<LLFloaterInventoryThumbnailsHelper>);
|
||||
LLFloaterReg::add("item_properties", "floater_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterItemProperties>);
|
||||
LLFloaterReg::add("task_properties", "floater_task_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterItemProperties>);
|
||||
LLFloaterReg::add("inventory_settings", "floater_inventory_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventorySettings>);
|
||||
|
|
|
|||
|
|
@ -4158,6 +4158,12 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
|
|||
LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
|
||||
for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
|
||||
{
|
||||
if (anim_it->first != object_id)
|
||||
{
|
||||
// elements with the same key are always contiguous, bail if we went past the
|
||||
// end of this object's animations
|
||||
break;
|
||||
}
|
||||
if (anim_it->second == animation_id)
|
||||
{
|
||||
anim_found = TRUE;
|
||||
|
|
|
|||
|
|
@ -2043,6 +2043,7 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
|
|||
{
|
||||
LL_WARNS() << objectp->mID << " has self as parent, skipping!"
|
||||
<< LL_ENDL;
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -834,7 +834,11 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
|
|||
for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
|
||||
{
|
||||
gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
|
||||
mAnimationSources.erase(motion_it++);
|
||||
mAnimationSources.erase(motion_it);
|
||||
// Must find() after each erase() to deal with potential iterator invalidation
|
||||
// This also ensures that we don't go past the end of this source's animations
|
||||
// into those of another source.
|
||||
motion_it = mAnimationSources.find(source_id);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
can_resize="false"
|
||||
height="600"
|
||||
layout="topleft"
|
||||
min_height="175"
|
||||
min_width="500"
|
||||
name="contents"
|
||||
help_topic="contents"
|
||||
title="Inventory Thumbnails Helper"
|
||||
width="800">
|
||||
<scroll_list
|
||||
top="20"
|
||||
height="350"
|
||||
draw_stripes="true"
|
||||
draw_heading="true"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="8"
|
||||
multi_select="true"
|
||||
name="inventory_thumbnails_list"
|
||||
right="-8"
|
||||
tool_tip="Paste items from your inventory">
|
||||
<scroll_list.columns
|
||||
dynamic_width="true"
|
||||
label="Inventory Item"
|
||||
name="item_name"
|
||||
relative_width="0.4" />
|
||||
<scroll_list.columns
|
||||
dynamic_width="true"
|
||||
label="Existing Texture"
|
||||
name="existing_texture"
|
||||
relative_width="0.3" />
|
||||
<scroll_list.columns
|
||||
dynamic_width="true"
|
||||
label="New Texture"
|
||||
name="new_texture"
|
||||
relative_width="0.3" />
|
||||
</scroll_list>
|
||||
<text_editor
|
||||
top="375"
|
||||
height="140"
|
||||
follows="all"
|
||||
left="8"
|
||||
right="-8"
|
||||
name="output_log"
|
||||
font="Monospace"
|
||||
text_color="0.1 0.5 0.1 1.0"
|
||||
width="480">
|
||||
</text_editor>
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Paste items from Inventory"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="paste_items_btn"
|
||||
bottom="-60"
|
||||
width="235" />
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Paste textures from Inventory"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="paste_textures_btn"
|
||||
top_delta="26 "
|
||||
width="235" />
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Write Thumbnails"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="write_thumbnails_btn"
|
||||
top_delta="26 "
|
||||
width="235" />
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Log items with no thumbnail"
|
||||
layout="bottomleft"
|
||||
right="-10"
|
||||
name="log_missing_thumbnails_btn"
|
||||
bottom="60"
|
||||
width="235" />
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Clear thumbnails from pasted items"
|
||||
layout="bottomleft"
|
||||
right="-10"
|
||||
name="clear_thumbnails_btn"
|
||||
top_delta="26"
|
||||
width="235" />
|
||||
|
||||
|
||||
</floater>
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
layout="topleft"
|
||||
name="Folder Wearables Separator" />
|
||||
<menu_item_call
|
||||
label="Replace Current Outfit"
|
||||
label="Replace current outfit"
|
||||
layout="topleft"
|
||||
name="Replace Outfit">
|
||||
<menu_item_call.on_click
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
parameter="replaceoutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Add To Current Outfit"
|
||||
label="Add folder items"
|
||||
layout="topleft"
|
||||
name="Add To Outfit">
|
||||
<menu_item_call.on_click
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
parameter="addtooutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Remove From Current Outfit"
|
||||
label="Take off folder items"
|
||||
layout="topleft"
|
||||
name="Remove From Outfit">
|
||||
<menu_item_call.on_click
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
layout="topleft"
|
||||
name="Outfit">
|
||||
<menu_item_call
|
||||
label="Wear - Replace Current Outfit"
|
||||
label="Replace current outfit"
|
||||
layout="topleft"
|
||||
name="wear_replace">
|
||||
<on_click
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
parameter="wear_replace" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Wear - Add to Current Outfit"
|
||||
label="Add outfit items"
|
||||
layout="topleft"
|
||||
name="wear_add">
|
||||
<on_click
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
parameter="wear_add" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Take Off - Remove from Current Outfit"
|
||||
label="Take off outfit items"
|
||||
layout="topleft"
|
||||
name="take_off">
|
||||
<on_click
|
||||
|
|
@ -41,17 +41,60 @@
|
|||
function="Outfit.OnVisible"
|
||||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator/>
|
||||
<menu_item_call
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
<on_click
|
||||
function="Outfit.Thumbnail" />
|
||||
function="Outfit.Thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="sepatator1" />
|
||||
<menu_item_call
|
||||
label="Edit outfit"
|
||||
layout="topleft"
|
||||
name="edit">
|
||||
<on_click
|
||||
function="Outfit.Edit" />
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="edit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Rename outfit"
|
||||
layout="topleft"
|
||||
name="rename">
|
||||
<on_click
|
||||
function="Outfit.Rename" />
|
||||
<on_enable
|
||||
function="Outfit.OnEnable"
|
||||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Save to this outfit"
|
||||
layout="topleft"
|
||||
name="save">
|
||||
<on_click
|
||||
function="Outfit.Save" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator>
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_separator>
|
||||
<menu_item_call
|
||||
label="Delete outfit"
|
||||
layout="topleft"
|
||||
name="delete">
|
||||
<on_click
|
||||
function="Outfit.Delete" />
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator/>
|
||||
<menu
|
||||
height="175"
|
||||
label="New Clothes"
|
||||
label="New clothes"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
mouse_opaque="false"
|
||||
|
|
@ -157,7 +200,7 @@
|
|||
</menu>
|
||||
<menu
|
||||
height="85"
|
||||
label="New Body Parts"
|
||||
label="New body parts"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
mouse_opaque="false"
|
||||
|
|
@ -197,35 +240,4 @@
|
|||
parameter="eyes" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu_item_separator name="sepatator2" />
|
||||
<menu_item_call
|
||||
label="Edit Outfit"
|
||||
layout="topleft"
|
||||
name="edit">
|
||||
<on_click
|
||||
function="Outfit.Edit" />
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="edit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Rename Outfit"
|
||||
layout="topleft"
|
||||
name="rename">
|
||||
<on_click
|
||||
function="Outfit.Rename" />
|
||||
<on_enable
|
||||
function="Outfit.OnEnable"
|
||||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Delete Outfit"
|
||||
layout="topleft"
|
||||
name="delete">
|
||||
<on_click
|
||||
function="Outfit.Delete" />
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_call>
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@
|
|||
layout="topleft"
|
||||
name="Folder Wearables Separator" />
|
||||
<menu_item_call
|
||||
label="Replace Current Outfit"
|
||||
label="Replace current outfit"
|
||||
layout="topleft"
|
||||
name="Replace Outfit">
|
||||
<menu_item_call.on_click
|
||||
|
|
@ -272,7 +272,7 @@
|
|||
parameter="replaceoutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Add To Current Outfit"
|
||||
label="Add folder items"
|
||||
layout="topleft"
|
||||
name="Add To Outfit">
|
||||
<menu_item_call.on_click
|
||||
|
|
@ -280,7 +280,7 @@
|
|||
parameter="addtooutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Remove From Current Outfit"
|
||||
label="Take off folder items"
|
||||
layout="topleft"
|
||||
name="Remove From Outfit">
|
||||
<menu_item_call.on_click
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
visible="false"
|
||||
name="Gear Outfit">
|
||||
<menu_item_call
|
||||
label="Wear - Replace Current Outfit"
|
||||
label="Replace current outfit"
|
||||
layout="topleft"
|
||||
name="wear">
|
||||
<on_click
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
parameter="wear" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Wear - Add to Current Outfit"
|
||||
label="Add outfit items"
|
||||
layout="topleft"
|
||||
name="wear_add">
|
||||
<on_click
|
||||
|
|
@ -25,9 +25,11 @@
|
|||
<on_enable
|
||||
function="Gear.OnEnable"
|
||||
parameter="wear_add" />
|
||||
<on_visible
|
||||
function="Gear.OnVisible"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Take Off - Remove from Current Outfit"
|
||||
label="Take off outfit items"
|
||||
layout="topleft"
|
||||
name="take_off">
|
||||
<on_click
|
||||
|
|
@ -39,19 +41,88 @@
|
|||
function="Gear.OnVisible"
|
||||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="wear_separator" />
|
||||
<menu_item_call
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
<on_click
|
||||
function="Gear.Thumbnail" />
|
||||
<on_click
|
||||
function="Gear.Thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="sepatator1" />
|
||||
<menu_item_call
|
||||
label="Rename outfit"
|
||||
layout="topleft"
|
||||
name="rename">
|
||||
<on_click
|
||||
function="Gear.Rename" />
|
||||
<on_enable
|
||||
function="Gear.OnEnable"
|
||||
parameter="rename" />
|
||||
<on_visible
|
||||
function="Gear.OnVisible"
|
||||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Save to this outfit"
|
||||
layout="topleft"
|
||||
name="save">
|
||||
<on_click
|
||||
function="Gear.Save" />
|
||||
<on_visible
|
||||
function="Gear.OnVisible"/>
|
||||
</menu_item_call>
|
||||
<menu_item_separator>
|
||||
<on_visible
|
||||
function="Gear.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_separator>
|
||||
<menu_item_call
|
||||
label="Delete outfit"
|
||||
layout="topleft"
|
||||
name="delete_outfit">
|
||||
<on_click
|
||||
function="Gear.Delete" />
|
||||
<on_enable
|
||||
function="Gear.OnEnable"
|
||||
parameter="delete" />
|
||||
<on_visible
|
||||
function="Gear.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator>
|
||||
<on_visible
|
||||
function="Gear.OnVisible"/>
|
||||
</menu_item_separator>
|
||||
<menu_item_check
|
||||
label="Sort folders always by name"
|
||||
layout="topleft"
|
||||
name="sort_folders_by_name">
|
||||
<on_click
|
||||
function="Gear.SortByName" />
|
||||
<on_check
|
||||
function="CheckControl"
|
||||
parameter="OutfitGallerySortByName" />
|
||||
</menu_item_check>
|
||||
<menu_item_call
|
||||
label="Expand all folders"
|
||||
layout="topleft"
|
||||
name="expand">
|
||||
<on_click
|
||||
function="Gear.Expand" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Collapse all folders"
|
||||
layout="topleft"
|
||||
name="collapse">
|
||||
<on_click
|
||||
function="Gear.Collapse" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator/>
|
||||
<!-- copied (with minor modifications) from menu_inventory_add.xml -->
|
||||
<!-- *TODO: generate dynamically? -->
|
||||
<menu
|
||||
height="175"
|
||||
label="New Clothes"
|
||||
label="New clothes"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
mouse_opaque="false"
|
||||
|
|
@ -165,7 +236,7 @@
|
|||
</menu>
|
||||
<menu
|
||||
height="85"
|
||||
label="New Body Parts"
|
||||
label="New body parts"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
mouse_opaque="false"
|
||||
|
|
@ -206,57 +277,4 @@
|
|||
</menu_item_call>
|
||||
</menu>
|
||||
<!-- copied from menu_inventory_add.xml -->
|
||||
|
||||
<menu_item_separator name="sepatator2" />
|
||||
<menu_item_call
|
||||
label="Expand all folders"
|
||||
layout="topleft"
|
||||
name="expand">
|
||||
<on_click
|
||||
function="Gear.Expand" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Collapse all folders"
|
||||
layout="topleft"
|
||||
name="collapse">
|
||||
<on_click
|
||||
function="Gear.Collapse" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Rename Outfit"
|
||||
layout="topleft"
|
||||
name="rename">
|
||||
<on_click
|
||||
function="Gear.Rename" />
|
||||
<on_enable
|
||||
function="Gear.OnEnable"
|
||||
parameter="rename" />
|
||||
<on_visible
|
||||
function="Gear.OnVisible"
|
||||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Delete Outfit"
|
||||
layout="topleft"
|
||||
name="delete_outfit">
|
||||
<on_click
|
||||
function="Gear.Delete" />
|
||||
<on_enable
|
||||
function="Gear.OnEnable"
|
||||
parameter="delete" />
|
||||
<on_visible
|
||||
function="Gear.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="sepatator3" />
|
||||
<menu_item_check
|
||||
label="Sort Folders Always by Name"
|
||||
layout="topleft"
|
||||
name="sort_folders_by_name">
|
||||
<on_click
|
||||
function="Gear.SortByName" />
|
||||
<on_check
|
||||
function="CheckControl"
|
||||
parameter="OutfitGallerySortByName" />
|
||||
</menu_item_check>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
layout="topleft"
|
||||
name="Outfit">
|
||||
<menu_item_call
|
||||
label="Wear - Replace Current Outfit"
|
||||
label="Replace current outfit"
|
||||
layout="topleft"
|
||||
name="wear_replace">
|
||||
<on_click
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
parameter="wear_replace" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Wear - Add to Current Outfit"
|
||||
label="Add outfit items"
|
||||
layout="topleft"
|
||||
name="wear_add">
|
||||
<on_click
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
parameter="wear_add" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Take Off - Remove from Current Outfit"
|
||||
label="Take off outfit items"
|
||||
layout="topleft"
|
||||
name="take_off">
|
||||
<on_click
|
||||
|
|
@ -41,19 +41,26 @@
|
|||
function="Outfit.OnVisible"
|
||||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<menu_item_call
|
||||
label="Edit Outfit"
|
||||
layout="topleft"
|
||||
name="edit">
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
<on_click
|
||||
function="Outfit.Thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Edit outfit"
|
||||
layout="topleft"
|
||||
name="edit">
|
||||
<on_click
|
||||
function="Outfit.Edit" />
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="edit" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<menu_item_call
|
||||
label="Rename Outfit"
|
||||
label="Rename outfit"
|
||||
layout="topleft"
|
||||
name="rename">
|
||||
<on_click
|
||||
|
|
@ -63,7 +70,19 @@
|
|||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Delete Outfit"
|
||||
label="Save to this outfit"
|
||||
layout="topleft"
|
||||
name="save">
|
||||
<on_click
|
||||
function="Outfit.Save" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator>
|
||||
<on_visible
|
||||
function="Outfit.OnVisible"
|
||||
parameter="delete" />
|
||||
</menu_item_separator>
|
||||
<menu_item_call
|
||||
label="Delete outfit"
|
||||
layout="topleft"
|
||||
name="delete">
|
||||
<on_click
|
||||
|
|
|
|||
|
|
@ -49,4 +49,17 @@
|
|||
function="TeleportHistory.GearMenu.Enable"
|
||||
parameter="copy_slurl" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
<menu_item_call
|
||||
label="Remove from history"
|
||||
layout="topleft"
|
||||
name="remove_from_history">
|
||||
<on_click
|
||||
function="TeleportHistory.GearMenu.Action"
|
||||
parameter="remove" />
|
||||
<on_enable
|
||||
function="TeleportHistory.GearMenu.Enable"
|
||||
parameter="remove" />
|
||||
</menu_item_call>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -3519,6 +3519,21 @@ function="World.EnvPreset"
|
|||
<menu_item_call.on_click
|
||||
function="Advanced.WebContentTest"
|
||||
parameter="http://duckduckgo.com"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Inventory Thumbnails Helper"
|
||||
name="Inventory Thumbnails Helper"
|
||||
shortcut="control|alt|shift|X">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Show"
|
||||
parameter="inventory_thumbnails_helper" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="FB Connect Test"
|
||||
name="FB Connect Test">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.WebContentTest"
|
||||
parameter="https://cryptic-ridge-1632.herokuapp.com/"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Dump SelectMgr"
|
||||
|
|
|
|||
|
|
@ -12248,6 +12248,50 @@ Would you like to save them first?
|
|||
notext="No"
|
||||
yestext="Yes"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ConfirmOverwriteOutfit"
|
||||
type="alertmodal">
|
||||
<unique/>
|
||||
This will replace the items in the
|
||||
selected outfit with the items you
|
||||
are wearing now.
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
ignoretext="Confirm before overwriting outfit"
|
||||
name="okcancelignore"
|
||||
notext="Cancel"
|
||||
yestext="Save"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ClearInventoryThumbnailsWarning"
|
||||
type="alertmodal">
|
||||
You are about to remove thumbnail images from the inventory items in the list. This change cannot be undone.
|
||||
|
||||
Would you like to proceed?
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
name="okcancelbuttons"
|
||||
notext="No"
|
||||
yestext="Yes"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="WriteInventoryThumbnailsWarning"
|
||||
type="alertmodal">
|
||||
You are about to overwrite thumbnail images for some or all of the inventory items in the list. This change cannot be undone.
|
||||
|
||||
Would you like to proceed?
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
name="okcancelbuttons"
|
||||
notext="No"
|
||||
yestext="Yes"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
Density Exponent:
|
||||
</text>
|
||||
<slider
|
||||
decimal_digits="1"
|
||||
decimal_digits="2"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="0.01"
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ def make_translation_table(mod_tree, base_tree, lang, args):
|
|||
filename = mod_blob.path
|
||||
if mod_blob.type == "tree": # directory, skip
|
||||
continue
|
||||
if args.files and os.path.basename(filename) not in args.files:
|
||||
continue # process only the specified files
|
||||
|
||||
if args.verbose:
|
||||
print(filename)
|
||||
|
|
@ -325,9 +327,11 @@ if __name__ == "__main__":
|
|||
parser.add_argument("--deleted", action="store_true", default = False, help="show all translated entities which don't exist in english")
|
||||
parser.add_argument("--skip_spreadsheet", action="store_true", default = False, help="skip creating the translation spreadsheet")
|
||||
parser.add_argument("--rev", help="revision with modified strings, default HEAD", default="HEAD")
|
||||
parser.add_argument("--rev_base", help="previous revision to compare against, default master", default="master")
|
||||
parser.add_argument("--rev_base", help="previous revision to compare against, default main", default="main")
|
||||
parser.add_argument("--base_lang", help="base language, default en (normally leave unchanged - other values are only useful for testing)", default="en")
|
||||
parser.add_argument("--lang", help="target languages, or 'all_valid' or 'supported'; default is 'supported'", nargs="+", default = ["supported"])
|
||||
parser.add_argument("--files", help='list of files to process', metavar='F', type=str, nargs='*')
|
||||
parser.add_argument("--outfile", help='name of the output file', type=str, nargs='?', default="SL_Translations.xlsx")
|
||||
args = parser.parse_args()
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
|
@ -370,7 +374,7 @@ if __name__ == "__main__":
|
|||
print("Target language(s) are", ",".join(sorted(langs)))
|
||||
sys.stdout.flush()
|
||||
|
||||
outfile = "SL_Translations.xlsx"
|
||||
outfile = args.outfile
|
||||
try:
|
||||
f = open(outfile,"a+")
|
||||
f.close()
|
||||
|
|
|
|||
Loading…
Reference in New Issue