Ansariel 2024-06-05 11:24:35 +02:00
commit 332f7e1790
27 changed files with 296 additions and 1219 deletions

View File

@ -1014,6 +1014,7 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe
LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot)
{
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against against unlocked access to mItems
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
{
slot(LLSD().with("sigtype", "load").with("id", (*it)->id()));
@ -1052,10 +1053,17 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload)
bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPtr pNotification)
{
std::string cmd = payload["sigtype"];
LLNotificationSet::iterator foundItem = mItems.find(pNotification);
bool wasFound = (foundItem != mItems.end());
// <FS:Beq> Guard against unlocked access to mItems
// LLNotificationSet::iterator foundItem = mItems.find(pNotification);
// bool wasFound = (foundItem != mItems.end());
bool wasFound = false;
{
LLMutexLock lock(&mItemsMutex);
LLNotificationSet::iterator foundItem = mItems.find(pNotification);
wasFound = (foundItem != mItems.end());
}
// </FS:Beq>
bool passesFilter = mFilter ? mFilter(pNotification) : true;
// first, we offer the result of the filter test to the simple
// signals for pass/fail. One of these is guaranteed to be called.
// If either signal returns true, the change processing is NOT performed
@ -1084,6 +1092,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
assert(!wasFound);
if (passesFilter)
{
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against unlocked access to mItems
// not in our list, add it and say so
mItems.insert(pNotification);
onLoad(pNotification);
@ -1107,6 +1116,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
}
else
{
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against unlocked access to mItems
// not in our list, add it and say so
mItems.insert(pNotification);
onChange(pNotification);
@ -1120,6 +1130,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
{
if (wasFound)
{
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against unlocked access to mItems
// it already existed, so this is a delete
mItems.erase(pNotification);
onChange(pNotification);
@ -1138,6 +1149,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
assert(!wasFound);
if (passesFilter)
{
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against unlocked access to mItems
// not in our list, add it and say so
mItems.insert(pNotification);
onAdd(pNotification);
@ -1149,6 +1161,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
// if we have it in our list, pass on the delete, then delete it, else do nothing
if (wasFound)
{
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against unlocked access to mItems
onDelete(pNotification);
abortProcessing = mChanged(payload);
mItems.erase(pNotification);
@ -1714,6 +1727,7 @@ void LLNotifications::add(const LLNotificationPtr pNotif)
if (pNotif == NULL) return;
// first see if we already have it -- if so, that's a problem
LLMutexLock lock(&mItemsMutex); // <FS:Beq/> Guard against unlocked acceess to mItems
LLNotificationSet::iterator it=mItems.find(pNotif);
if (it != mItems.end())
{

File diff suppressed because it is too large Load Diff

View File

@ -153,6 +153,17 @@
<key>Value</key>
<string>http://phoenixviewer.com/app/fsdata/grids.xml</string>
</map>
<key>FSGridBuilderURL</key>
<map>
<key>Comment</key>
<string>Fetch an html page of grids from this URL.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://phoenixviewer.com/app/fsdata/fs_grid_builder.html</string>
</map>
<key>LastConnectedGrid</key>
<map>
<key>Comment</key>
@ -13959,6 +13970,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>FSUseLegacyUnsupportedHardwareChecks</key>
<map>
<key>Comment</key>
<string>If enabled, Firestorm will perform utterly pointless checks that probably made sense in 2004.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSUseStandaloneGroupFloater</key>
<map>
<key>Comment</key>

View File

@ -313,6 +313,7 @@ void FSFloaterWearableFavorites::onFilterEdit(const std::string& search_string)
{
mItemsList->setFilterSubString(search_string, true);
mItemsList->setNoItemsCommentText(getString("empty_list"));
mItemsList->rearrange();
}
void FSFloaterWearableFavorites::onOptionsMenuItemClicked(const LLSD& userdata)

View File

@ -61,6 +61,11 @@ public:
return mDADSignal.connect(cb);
}
void rearrange()
{
rearrangeItems();
}
protected:
friend class LLUICtrlFactory;
FSWearableFavoritesItemsList(const Params&);

View File

@ -250,6 +250,9 @@ FSPanelLogin::FSPanelLogin(const LLRect &rect,
LLTextBox* grid_mgr_help_text = getChild<LLTextBox>("grid_login_text");
grid_mgr_help_text->setClickedCallback(onClickGridMgrHelp, NULL);
LLTextBox* grid_builder_text = getChild<LLTextBox>("grid_builder_text");
grid_builder_text->setClickedCallback(onClickGridBuilder, NULL);
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
// argument (CmdLineLoginLocation) or by default.
@ -1356,6 +1359,12 @@ void FSPanelLogin::onClickGridMgrHelp(void*)
}
}
//static
void FSPanelLogin::onClickGridBuilder(void*)
{
LLWeb::loadURLInternal(gSavedSettings.getString("FSGridBuilderURL"));
}
void FSPanelLogin::onSelectUser()
{
LL_INFOS("AppInit") << "onSelectUser()" << LL_ENDL;

View File

@ -111,6 +111,7 @@ private:
static void onClickRemove(void*);
static void onRemoveCallback(const LLSD& notification, const LLSD& response);
static void onClickGridMgrHelp(void*);
static void onClickGridBuilder(void*);
static std::string credentialName();
private:

View File

@ -48,98 +48,101 @@
#define htxhop_log(format, ...) LL_DEBUGS("GridManager") << llformat(format, __VA_ARGS__) << LL_ENDL;
static inline std::string extract_region(const std::string& s)
namespace hypergrid
{
static auto const& patterns = {
std::regex { R"(/ ([^/:=]+)$)" }, // TODO: figure out where the spec lives for hop "slash space" embedding...
std::regex { R"(([^/:=]+)$)" }, // TODO: figure out where the spec lives for hop "grid:port:region" embedding...
static inline std::string extract_region(const std::string& s)
{
static auto const& patterns = {
std::regex { R"(/ ([^/:=]+)$)" }, // TODO: figure out where the spec lives for hop "slash space" embedding...
std::regex { R"(([^/:=]+)$)" }, // TODO: figure out where the spec lives for hop "grid:port:region" embedding...
};
std::smatch match_results;
std::string ls{ s };
LLStringUtil::toLower(ls);
for (const auto& pattern : patterns)
{
if (std::regex_search(ls, match_results, pattern))
{
return match_results[1].str();
}
}
return {};
}
// helper to encapsulate Region Map Block responses
struct MapBlock
{
S32 index{};
U16 x_regions{}, y_regions{}, x_size{ REGION_WIDTH_UNITS }, y_size{ REGION_WIDTH_UNITS };
std::string name{};
U8 accesscode{};
U32 region_flags{};
LLUUID image_id{};
inline U32 x_world() const { return (U32)(x_regions)*REGION_WIDTH_UNITS; }
inline U32 y_world() const { return (U32)(y_regions)*REGION_WIDTH_UNITS; }
inline U64 region_handle() const { return grid_to_region_handle(x_regions, y_regions); }
// see: LLWorldMapMessage::processMapBlockReply
MapBlock(LLMessageSystem* msg, S32 block)
: index(block)
{
msg->getU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block);
msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block);
msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block);
msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block);
msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block);
// msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block);
// msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block);
msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block);
// <FS:CR> Aurora Sim
if (msg->getNumberOfBlocksFast(_PREHASH_Size) > 0)
{
msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block);
msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block);
}
if (x_size == 0 || (x_size % 16) != 0 || (y_size % 16) != 0)
{
x_size = 256;
y_size = 256;
}
// </FS:CR> Aurora Sim
}
};
std::smatch match_results;
std::string ls { s };
LLStringUtil::toLower(ls);
for (const auto& pattern : patterns)
constexpr U32 EXACT_FLAG = 0x00000000;
constexpr U32 LAYER_FLAG = 0x00000002;
// see: LLWorldMapMessage::sendNamedRegionRequest
static void sendMapNameRequest(const std::string& region_name, U32 flags)
{
if (std::regex_search(ls, match_results, pattern))
{
return match_results[1].str();
}
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_MapNameRequest);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
msg->addU32Fast(_PREHASH_Flags, flags);
msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim
msg->addBOOLFast(_PREHASH_Godlike, false); // Filled in on sim
msg->nextBlockFast(_PREHASH_NameData);
msg->addStringFast(_PREHASH_Name, region_name);
gAgent.sendReliableMessage();
}
return {};
struct AdoptedRegionNameQuery
{
std::string key{};
std::string region_name{};
hypergrid::url_callback_t arbitrary_callback;
std::string arbitrary_slurl{};
bool arbitrary_teleport{ false };
};
// map extracted region names => pending query entries
static std::map<std::string, AdoptedRegionNameQuery> region_name_queries;
}
// helper to encapsulate Region Map Block responses
struct _MapBlock
{
S32 index {};
U16 x_regions {}, y_regions {}, x_size { REGION_WIDTH_UNITS }, y_size { REGION_WIDTH_UNITS };
std::string name {};
U8 accesscode {};
U32 region_flags {};
LLUUID image_id {};
inline U32 x_world() const { return (U32)(x_regions)*REGION_WIDTH_UNITS; }
inline U32 y_world() const { return (U32)(y_regions)*REGION_WIDTH_UNITS; }
inline U64 region_handle() const { return grid_to_region_handle(x_regions, y_regions); }
// see: LLWorldMapMessage::processMapBlockReply
_MapBlock(LLMessageSystem* msg, S32 block)
: index(block)
{
msg->getU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block);
msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block);
msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block);
msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block);
msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block);
// msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block);
// msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block);
msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block);
// <FS:CR> Aurora Sim
if (msg->getNumberOfBlocksFast(_PREHASH_Size) > 0)
{
msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block);
msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block);
}
if (x_size == 0 || (x_size % 16) != 0 || (y_size % 16) != 0)
{
x_size = 256;
y_size = 256;
}
// </FS:CR> Aurora Sim
}
};
constexpr U32 EXACT_FLAG = 0x00000000;
constexpr U32 LAYER_FLAG = 0x00000002;
// see: LLWorldMapMessage::sendNamedRegionRequest
static void _hypergrid_sendMapNameRequest(const std::string& region_name, U32 flags)
{
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_MapNameRequest);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
msg->addU32Fast(_PREHASH_Flags, flags);
msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim
msg->addBOOLFast(_PREHASH_Godlike, false); // Filled in on sim
msg->nextBlockFast(_PREHASH_NameData);
msg->addStringFast(_PREHASH_Name, region_name);
gAgent.sendReliableMessage();
}
struct _AdoptedRegionNameQuery
{
std::string key{};
std::string region_name{};
url_callback_t arbitrary_callback;
std::string arbitrary_slurl{};
bool arbitrary_teleport{ false };
};
// map extracted region names => pending query entries
static std::map<std::string, _AdoptedRegionNameQuery> _region_name_queries;
bool hypergrid_sendExactNamedRegionRequest(const std::string& region_name, const url_callback_t& callback, const std::string& callback_url, bool teleport)
bool hypergrid::sendExactNamedRegionRequest(const std::string& region_name, const url_callback_t& callback, const std::string& callback_url, bool teleport)
{
if (!LLGridManager::instance().isInOpenSim() || !callback)
{
@ -151,13 +154,13 @@ bool hypergrid_sendExactNamedRegionRequest(const std::string& region_name, const
{
return false;
}
_region_name_queries[key] = { key, region_name, callback, callback_url, teleport };
region_name_queries.try_emplace(key, AdoptedRegionNameQuery{ key, region_name, callback, callback_url, teleport });
htxhop_log("Send Region Name '%s' (key: %s)", region_name.c_str(), key.c_str());
_hypergrid_sendMapNameRequest(region_name, EXACT_FLAG);
sendMapNameRequest(region_name, EXACT_FLAG);
return true;
}
bool hypergrid_processExactNamedRegionResponse(LLMessageSystem* msg, U32 agent_flags)
bool hypergrid::processExactNamedRegionResponse(LLMessageSystem* msg, U32 agent_flags)
{
if (!LLGridManager::instance().isInOpenSim() || !msg || agent_flags & LAYER_FLAG)
{
@ -166,44 +169,44 @@ bool hypergrid_processExactNamedRegionResponse(LLMessageSystem* msg, U32 agent_f
// NOTE: we assume only agent_flags have been read from msg so far
S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data);
std::vector<_MapBlock> blocks;
std::vector<MapBlock> blocks;
blocks.reserve(num_blocks);
for (S32 b = 0; b < num_blocks; b++)
{
blocks.emplace_back(msg, b);
}
for (const auto& _block : blocks)
for (const auto& block : blocks)
{
htxhop_log("#%02d key='%s' block.name='%s' block.region_handle=%llu", _block.index, extract_region(_block.name).c_str(), _block.name.c_str(), _block.region_handle());
htxhop_log("#%02d key='%s' block.name='%s' block.region_handle=%llu", block.index, extract_region(block.name).c_str(), block.name.c_str(), block.region_handle());
}
// special case: handle singular result w/empty name tho valid region handle AND singular pending query as a match
// (might be that a landing area / redirect hop URL is coming back: "^hop://grid:port/$", which extract_region's into "")
bool solo_result = blocks.size() == 2 && blocks[0].region_handle() && extract_region(blocks[0].name).empty() && !blocks[1].region_handle();
if (solo_result && _region_name_queries.size() == 1)
if (solo_result && region_name_queries.size() == 1)
{
htxhop_log("applying first block as redirect; region_handle: %llu", blocks[0].region_handle());
blocks[0].name = _region_name_queries.begin()->second.region_name;
blocks[0].name = region_name_queries.begin()->second.region_name;
}
for (const auto& _block : blocks)
for (const auto& block : blocks)
{
auto key = extract_region(_block.name);
auto key = extract_region(block.name);
if (key.empty())
{
continue;
}
auto idx = _region_name_queries.find(key);
if (idx == _region_name_queries.end())
auto idx = region_name_queries.find(key);
if (idx == region_name_queries.end())
{
continue;
}
const auto& pending = idx->second;
auto pending{ idx->second };
htxhop_log("Recv Region Name '%s' (key: %s) block.name='%s' block.region_handle=%llu)", pending.region_name.c_str(),
pending.key.c_str(), _block.name.c_str(), _block.region_handle());
_region_name_queries.erase(idx);
pending.arbitrary_callback(_block.region_handle(), pending.arbitrary_slurl, _block.image_id, pending.arbitrary_teleport);
pending.key.c_str(), block.name.c_str(), block.region_handle());
region_name_queries.erase(idx);
pending.arbitrary_callback(block.region_handle(), pending.arbitrary_slurl, block.image_id, pending.arbitrary_teleport);
return true;
}
return false;

View File

@ -37,10 +37,13 @@
class LLMessageSystem;
class LLUUID;
using url_callback_t = std::function<void(uint64_t region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)>;
bool hypergrid_sendExactNamedRegionRequest(const std::string& region_name, const url_callback_t& callback, const std::string& callback_url, bool teleport);
bool hypergrid_processExactNamedRegionResponse(LLMessageSystem* msg, U32 agent_flags);
namespace hypergrid
{
// Needs to be identical to url_callback_t defined in llworldmapmessage.h
using url_callback_t = std::function<void(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)>;
bool sendExactNamedRegionRequest(const std::string& region_name, const url_callback_t& callback, const std::string& callback_url, bool teleport);
bool processExactNamedRegionResponse(LLMessageSystem* msg, U32 agent_flags);
}
#endif
#endif // FS_WORLDMAPMESSAGE_H

View File

@ -1166,7 +1166,7 @@ bool LLAppViewer::init()
}
// alert the user if they are using unsupported hardware
if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
if(gSavedSettings.getBOOL("FSUseLegacyUnsupportedHardwareChecks") && !gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
{
bool unsupported = false;
LLSD args;

View File

@ -3375,7 +3375,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
for (LLInventoryModel::item_array_t::value_type& item : items)
{
if (get_is_item_worn(item))
if (!item->getIsLinkType() && get_is_item_worn(item))
{
has_worn = true;
LLWearableType::EType type = item->getWearableType();
@ -3395,7 +3395,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
}
}
LLViewerInventoryItem* item = gInventory.getItem(obj_id);
if (item && get_is_item_worn(item))
if (item && !item->getIsLinkType() && get_is_item_worn(item))
{
has_worn = true;
LLWearableType::EType type = item->getWearableType();

View File

@ -1988,7 +1988,7 @@ void LLInventoryGallery::deleteSelection()
for (LLInventoryModel::item_array_t::value_type& item : items)
{
if (get_is_item_worn(item))
if (!item->getIsLinkType() && get_is_item_worn(item))
{
has_worn = true;
LLWearableType::EType type = item->getWearableType();
@ -2009,7 +2009,7 @@ void LLInventoryGallery::deleteSelection()
}
LLViewerInventoryItem* item = gInventory.getItem(id);
if (item && get_is_item_worn(item))
if (item && !item->getIsLinkType() && get_is_item_worn(item))
{
has_worn = true;
LLWearableType::EType type = item->getWearableType();

View File

@ -627,13 +627,12 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// [/RLVa:KB]
}
items.push_back(std::string("Task Properties"));
// <FS:Ansariel> Legacy object properties
// <FS:Ansariel> Improved object properties
//if ((flags & FIRST_SELECTED_ITEM) == 0)
if (!gSavedSettings.getBOOL("FSUseLegacyObjectProperties") && (flags & FIRST_SELECTED_ITEM) == 0)
//{
// disabled_items.push_back(std::string("Task Properties"));
//}
// </FS:Ansariel>
{
disabled_items.push_back(std::string("Task Properties"));
}
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Added: RLVa-1.2.1f
items.push_back(std::string("Task Rename"));
if ( (!isItemRenameable()) || ((flags & FIRST_SELECTED_ITEM) == 0) )
@ -1007,13 +1006,12 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
}
items.push_back(std::string("Task Properties"));
// <FS:Ansariel> Legacy object properties
// <FS:Ansariel> Improved object properties
//if ((flags & FIRST_SELECTED_ITEM) == 0)
if (!gSavedSettings.getBOOL("FSUseLegacyObjectProperties") && (flags & FIRST_SELECTED_ITEM) == 0)
//{
// disabled_items.push_back(std::string("Task Properties"));
//}
// </FS:Ansariel>
{
disabled_items.push_back(std::string("Task Properties"));
}
if(isItemRenameable())
{
items.push_back(std::string("Task Rename"));

View File

@ -102,7 +102,7 @@ void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name,
{
// <FS:humbletim> FIRE-31368: [OPENSIM] ... Search returns more than one result
#ifdef OPENSIM
if (hypergrid_sendExactNamedRegionRequest(region_name, callback, callback_url, teleport))
if (hypergrid::sendExactNamedRegionRequest(region_name, callback, callback_url, teleport))
{
return;
}
@ -171,7 +171,7 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags);
// <FS:humbletim> FIRE-31368: [OPENSIM] ... Search returns more than one result
#ifdef OPENSIM
if (hypergrid_processExactNamedRegionResponse(msg, agent_flags))
if (hypergrid::processExactNamedRegionResponse(msg, agent_flags))
{
return;
}

View File

@ -34,6 +34,9 @@
</combo_box>
</layout_panel>
<layout_panel name="grid_panel">
<text name="grid_builder_text">
+ Klicken um Grids hinzuzufügen
</text>
<text name="grid_login_text">
Gridauswahl:
</text>

View File

@ -37,6 +37,9 @@
<text name="grid_login_text">
Grid:
</text>
<text name="grid_builder_text">
+ Klicken um Grids hinzuzufügen
</text>
</layout_panel>
<layout_panel name="mode_selection">
<text name="mode_selection_text">

View File

@ -150,25 +150,25 @@
Start at:
</text>
<combo_box
allow_text_entry="true"
control_name="NextLoginLocation"
follows="left|bottom"
height="22"
max_chars="128"
top_pad="0"
name="start_location_combo"
width="165">
allow_text_entry="true"
control_name="NextLoginLocation"
follows="left|bottom"
height="22"
max_chars="128"
top_pad="0"
name="start_location_combo"
width="165">
<combo_box.item
label="Last location"
name="MyLastLocation"
value="last" />
label="Last location"
name="MyLastLocation"
value="last" />
<combo_box.item
label="Home"
name="MyHome"
value="home" />
label="Home"
name="MyHome"
value="home" />
<combo_box.item
label="&lt;Type region name&gt;"
name="Typeregionname" value="" />
label="&lt;Type region name&gt;"
name="Typeregionname" value="" />
</combo_box>
</layout_panel>
<layout_panel
@ -179,6 +179,17 @@
width="145"
height="80"
visible="false">
<text
follows="left|top|right"
font="SansSerifMedium"
text_color="EmphasisColor"
top="10"
height="16"
name="grid_builder_text"
left="5"
width="190">
+ Click to add more grids
</text>
<text
follows="left|bottom"
font="SansSerifSmall"
@ -193,6 +204,7 @@
allow_text_entry="true"
follows="left|bottom"
height="22"
top_pad="0"
max_chars="256"
force_disable_fulltext_search="true"
combo_editor.commit_on_focus_lost="false"

View File

@ -282,6 +282,18 @@
<combo_box.drop_down_button
font="SansSerifLarge"/>
</combo_box>
<text
follows="left|top|right"
font="SansSerifMedium"
text_color="EmphasisColor"
top_pad="5"
height="16"
name="grid_builder_text"
valign="center"
left="45"
width="250">
+ Click to add more grids
</text>
</layout_panel>
<layout_panel
follows="left|top|right"

View File

@ -0,0 +1,17 @@
<floater name="whitelist_floater" title="Liste blanche de dossiers et programmes">
<text name="whitelist_intro">
Les antivirus et les anti-logiciels malveillants sont un élément essentiel d'une utilisation sûre de l'internet, mais ils peuvent causer toute une série de problèmes à la visionneuse.
Pour réduire les interférences et améliorer la stabilité et les performances, nous conseillons vivement à tous les utilisateurs de veiller à ce qu'il y ait des exclusions (connues sous le nom de liste blanche) pour les dossiers et les programmes importants que la visionneuse utilise.
Pour plus d'informations, visitez le site
https://wiki.firestormviewer.org/antivirus_whitelisting
</text>
<text name="whitelist_folder_instruction">
Pour vous simplifier la tâche, l'encadré ci-dessous indique les dossiers utilisés par la visionneuse.
Veuillez les ajouter à vos exclusions de dossiers AV, comme indiqué sur la page wiki ci-dessus.
</text>
<text name="whitelist_exe_instruction">
La case suivante indique le nom et le chemin d'accès complet des exécutables de la visionneuse.
Ajoutez-les à vos exclusions d'exécutables AV comme indiqué dans le wiki ci-dessus.
</text>
</floater>

View File

@ -267,8 +267,17 @@
<menu_item_call label="Horaires des classes Firestorm" name="Firestorm Classes Schedule"/>
<menu_item_call label="Calendrier des évènements Firestorm" name="Firestorm Events Calendar"/>
<menu_item_check label="Guide" name="How To"/>
<!-- <menu_item_call label="Aide Second Life" name="Second Life Help"/>-->
<menu_item_call label="Aide [CURRENT_GRID]" name="current_grid_help"/>
<menu_item_call label="À propos de [CURRENT_GRID]" name="current_grid_about"/>
<!-- <menu_item_call label="Tutoriels" name="Tutorial"/>
<menu_item_call label="Base de connaissance" name="Knowledge Base"/>
<menu_item_call label="Wiki" name="Wiki"/>
<menu_item_call label="Forums communautaires" name="Community Forums"/>
<menu_item_call label="Portail d'assistance" name="Support portal"/>
<menu_item_call label="Nouvelles de [SECOND_LIFE]" name="Second Life News"/>
<menu_item_call label="Blogs de [SECOND_LIFE]" name="Second Life Blogs"/>-->
<menu_item_call name="whitelist_folders" label="Conseils de liste blanche"/>
<menu_item_check label="Consulter l'état de la grille" name="Grid Status"/>
<menu_item_call label="Signaler une infraction" name="Report Abuse"/>
<menu_item_call label="Signaler un problème" name="Report Bug"/>

View File

@ -17,6 +17,9 @@
</combo_box>
</layout_panel>
<layout_panel name="grid_panel">
<text name="grid_builder_text">
+ Ajouter des grilles
</text>
<text name="grid_login_text">Connexion à la Grille :</text>
</layout_panel>
<layout_panel name="links_login_panel">

View File

@ -37,6 +37,9 @@
<text name="grid_login_text" width="55">
Grille :
</text>
<text name="grid_builder_text">
+ Ajouter des grilles
</text>
</layout_panel>
<layout_panel name="mode_selection">
<text name="mode_selection_text">

View File

@ -9,7 +9,10 @@
<panel.string name="leave_txt">Quitter</panel.string>
<layout_stack name="group_info_sidetray_main">
<layout_panel name="header_container">
<panel name="group_info_top"><line_editor label="Saisissez le nom de votre nouveau groupe ici" name="group_name_editor"/></panel>
<panel name="group_info_top">
<text_editor name="group_name" value="(Chargement ...)"/>
<line_editor label="Saisissez le nom de votre nouveau groupe ici" name="group_name_editor"/>
</panel>
</layout_panel>
<layout_panel name="group_info_content">
<layout_stack name="layout">
@ -24,11 +27,17 @@
</layout_panel>
</layout_stack>
<layout_stack name="button_row_ls">
<layout_panel name="btn_chat_lp"><button label="Chat" name="btn_chat"/></layout_panel>
<layout_panel name="call_btn_lp"><button name="btn_call" label="Appel de groupe" tool_tip="Appeler ce groupe"/></layout_panel>
<layout_panel name="btn_activate_lp">
<button label="Activer" name="btn_activate" />
</layout_panel>
<layout_panel name="btn_chat_lp">
<button label="Chat" name="btn_chat"/>
</layout_panel>
<layout_panel name="call_btn_lp">
<button name="btn_call" label="Appel de groupe" tool_tip="Appeler ce groupe"/>
</layout_panel>
<layout_panel name="btn_apply_lp">
<button label="Enregistrer" label_selected="Enregistrer" name="btn_apply"/>
<button label="Créer un groupe" name="btn_create" tool_tip="Créer un nouveau groupe"/>
</layout_panel>
</layout_stack>
</layout_panel>

View File

@ -28,6 +28,9 @@
</combo_box>
</layout_panel>
<layout_panel name="grid_panel">
<text name="grid_builder_text">
+ Kliknij, by dodać światy
</text>
<text name="grid_login_text">
Loguj do świata:
</text>

View File

@ -34,6 +34,9 @@
<text name="grid_login_text" width="55">
Świat:
</text>
<text name="grid_builder_text">
+ Kliknij, by dodać światy
</text>
</layout_panel>
<layout_panel name="mode_selection">
<text name="mode_selection_text">

View File

@ -28,6 +28,9 @@
</combo_box>
</layout_panel>
<layout_panel name="grid_panel">
<text name="grid_builder_text" width="300">
+ Нажмите чтобы добавить больше сеток
</text>
<text name="grid_login_text">
Подключиться к сетке:
</text>

View File

@ -33,6 +33,7 @@
<layout_stack name="2nd_row_stack">
<layout_panel name="grid_panel">
<text name="grid_login_text" width="45">Сеть:</text>
<text name="grid_builder_text" width="300">+ Нажмите чтобы добавить больше сеток</text>
</layout_panel>
<layout_panel name="mode_selection">
<text name="mode_selection_text">Режим:</text>