# Conflicts:
#	.github/workflows/build.yaml
#	indra/newview/app_settings/settings.xml
#	indra/newview/llinventorygallerymenu.cpp
#	indra/newview/skins/default/xui/en/notifications.xml
This commit is contained in:
Ansariel
2026-03-09 13:23:25 +01:00
51 changed files with 727 additions and 207 deletions
+9 -9
View File
@@ -265,7 +265,7 @@ jobs:
- name: Upload executable
if: steps.build.outputs.viewer_app
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: "${{ steps.build.outputs.artifact }}-app"
path: |
@@ -275,13 +275,13 @@ jobs:
# artifact for that too.
- name: Upload symbol file
if: steps.build.outputs.symbolfile
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: "${{ steps.build.outputs.artifact }}-symbols"
path: ${{ steps.build.outputs.symbolfile }}
- name: Upload metadata
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: "${{ steps.build.outputs.artifact }}-metadata"
# emitted by build.sh, possibly multiple lines
@@ -289,7 +289,7 @@ jobs:
${{ steps.build.outputs.metadata }}
- name: Upload physics package
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
# should only be set for viewer-private
if: matrix.configuration == 'Release' && steps.build.outputs.physicstpv
with:
@@ -370,13 +370,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download viewer exe
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
name: Windows-app
path: _artifacts
- name: Download Windows Symbols
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
name: Windows-symbols
- name: Extract viewer pdb
@@ -409,7 +409,7 @@ jobs:
steps:
- name: Download Mac Symbols
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
name: macOS-symbols
- name: Post Mac symbols
@@ -431,11 +431,11 @@ jobs:
runs-on: ubuntu-latest
if: needs.setup.outputs.release_run
steps:
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v8
with:
pattern: "*-installer"
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v8
with:
pattern: "*-metadata"
+5 -5
View File
@@ -486,7 +486,7 @@ jobs:
dumpSyms: false
- name: Publish artifacts
if: runner.os == 'Windows'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{ matrix.grid }}-artifacts.zip
path: |
@@ -495,7 +495,7 @@ jobs:
- name: publish Linux artifacts
if: runner.os == 'Linux'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{matrix.grid}}-artifacts.zip
path: |
@@ -504,7 +504,7 @@ jobs:
- name: publish MacOS artifacts
if: runner.os == 'macOS'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{matrix.grid}}-artifacts.zip
path: |
@@ -533,7 +533,7 @@ jobs:
run: pip install discord-webhook
- name: Download artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
id: download
with:
path: to_deploy
@@ -585,7 +585,7 @@ jobs:
# Upload Build Info Artifact (note that this file is expected to be identical for each matrix run, so items like OS and VARIANT cannot be in this file.)
- name: Upload Tag Info
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: build_info
path: build_info.json
+5 -5
View File
@@ -488,7 +488,7 @@ jobs:
dumpSyms: false
- name: Publish artifacts
if: runner.os == 'Windows'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{ matrix.grid }}-artifacts.zip
path: |
@@ -497,7 +497,7 @@ jobs:
- name: publish Linux artifacts
if: runner.os == 'Linux'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{matrix.grid}}-artifacts.zip
path: |
@@ -506,7 +506,7 @@ jobs:
- name: publish MacOS artifacts
if: runner.os == 'macOS'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{matrix.grid}}-artifacts.zip
path: |
@@ -535,7 +535,7 @@ jobs:
run: pip install discord-webhook
- name: Download artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
id: download
with:
path: to_deploy
@@ -587,7 +587,7 @@ jobs:
# Upload Build Info Artifact (note that this file is expected to be identical for each matrix run, so items like OS and VARIANT cannot be in this file.)
- name: Upload Tag Info
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: build_info
path: build_info.json
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
run: pip install discord-webhook
- name: Download Build Artifacts
uses: dawidd6/action-download-artifact@v13
uses: dawidd6/action-download-artifact@v16
id: download
with:
workflow: build_viewer.yml
+7 -7
View File
@@ -41,7 +41,7 @@ jobs:
setup_files: ${{ steps.get-files.outputs.setup_files }}
steps:
- name: Download Build Artifacts
uses: dawidd6/action-download-artifact@v13
uses: dawidd6/action-download-artifact@v16
id: download
with:
workflow: build_viewer.yml
@@ -62,7 +62,7 @@ jobs:
files_json=$(ls setup_exe_files | jq -R . | jq -s -c .)
echo "setup_files=$files_json" >> $GITHUB_OUTPUT
- name: Upload Setup.exe Files
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: setup-exe-files
path: setup_exe_files/
@@ -86,7 +86,7 @@ jobs:
shell: bash
- name: Download Setup.exe Files Artifact
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
name: setup-exe-files
path: setup_exe_files
@@ -97,7 +97,7 @@ jobs:
shell: bash
# - name: Upload unsigned artifact
# id: upload-unsigned-artifact
# uses: actions/upload-artifact@v6
# uses: actions/upload-artifact@v7
# with:
# name: unsigned-artifact-${{ matrix.file }}
# path: to_sign/${{ matrix.file }}
@@ -115,7 +115,7 @@ jobs:
# wait-for-completion: true
# output-artifact-directory: 'application-signed'
- name: Azure Trusted Signing
uses: azure/trusted-signing-action@v1.0.0
uses: azure/trusted-signing-action@v1.1.0
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
@@ -129,14 +129,14 @@ jobs:
files-folder-filter: exe
# - name: Upload signed artifact
# uses: actions/upload-artifact@v6
# uses: actions/upload-artifact@v7
# with:
# name: signed-artifact-${{ matrix.file }}
# path: ./application-signed
# - name: Upload unsigned artifact
- name: Upload signed artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: unsigned-artifact-${{ matrix.file }}
path: to_sign\${{ matrix.file }}
+1 -1
View File
@@ -72,7 +72,7 @@ jobs:
echo "build_run_number=${{ github.event.inputs.build_run_number }}" >> "$GITHUB_OUTPUT"
fi
- name: Download Build Artifacts
uses: dawidd6/action-download-artifact@v13
uses: dawidd6/action-download-artifact@v16
id: download_build_info
with:
workflow: build_viewer.yml
+6 -6
View File
@@ -874,11 +874,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>19e40aa358c1784b49eccd547e704647</string>
<string>e474e018a7922d771eee789acf8d7182</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///opt/firestorm/fmodstudio-2.03.07-darwin64-251121740.tar.bz2</string>
<string>file:///opt/firestorm/fmodstudio-2.03.12-darwin64-260671926.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -888,11 +888,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>a459e2967306ff56a835a321dc00718c</string>
<string>f9c203d45f22e3b448653d2f652806d8</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///opt/firestorm/fmodstudio-2.03.07-linux64-251121739.tar.bz2</string>
<string>file:///opt/firestorm/fmodstudio-2.03.12-linux64-260671925.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -902,9 +902,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>4a0da36b4a31332df62dadf6438f935e</string>
<string>2b9a4903cb4413a09a4c2101e834d0d3</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.03.07-windows64-251121127.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.03.12-windows64-260671934.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
+34
View File
@@ -128,6 +128,40 @@ std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
return v;
}
// <FS:TJ> For CEF cache purging in a background thread
std::vector<std::string> LLDir::getDirectoriesInDir(const std::string &dirname)
{
//Returns a vector of directory names.
#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
boost::filesystem::path p(ll_convert<std::wstring>(dirname));
#else
boost::filesystem::path p(dirname);
#endif
std::vector<std::string> v;
boost::system::error_code ec;
if (exists(p, ec) && !ec.failed())
{
if (is_directory(p, ec) && !ec.failed())
{
boost::filesystem::directory_iterator end_iter;
for (boost::filesystem::directory_iterator dir_itr(p);
dir_itr != end_iter;
++dir_itr)
{
if (boost::filesystem::is_directory(dir_itr->status()))
{
v.push_back(dir_itr->path().filename().string());
}
}
}
}
return v;
}
// </FS:TJ>
S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
{
if (!fileExists(dirname)) return 0;
+1
View File
@@ -78,6 +78,7 @@ class LLDir
virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
U32 deleteDirAndContents(const std::string& dir_name);
std::vector<std::string> getFilesInDir(const std::string &dirname);
std::vector<std::string> getDirectoriesInDir(const std::string &dirname); // <FS:TJ/> For CEF cache purging in a background thread
// pure virtual functions
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
+33
View File
@@ -27358,6 +27358,39 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>FSAutoOrderIMTabs</key>
<map>
<key>Comment</key>
<string>Use automatic tab ordering for IM tabs inside the conversations floater.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSAutoOrderIMTabsPriorities</key>
<map>
<key>Comment</key>
<string>Priority for automatic ordering IM tabs. Higher priority means the tab will be inserted before lower priority. Default is Groups[0]=2 Conferences[1]=1 IMs[2]=0</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>210</string>
</map>
<key>FSAutoOrderIMTabsAtTop</key>
<map>
<key>Comment</key>
<string>Add new IM tabs as first in their chat type group.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSUseFSLegacySearch</key>
<map>
<key>Comment</key>
+1 -1
View File
@@ -272,7 +272,7 @@ void FSFloaterContacts::onOpen(const LLSD& key)
}
else
{
floater_container->addFloater(this, true);
floater_container->addFloater(this, true, IM_NOTHING_SPECIAL);
}
openTab(key.asString());
+10 -3
View File
@@ -1320,11 +1320,10 @@ FSFloaterIM* FSFloaterIM::show(const LLUUID& session_id)
{
// LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
if (floater_container)
{
floater_container->addFloater(floater, true, i_pt);
floater_container->addFloater(floater, true, session->mType);
}
}
@@ -2289,7 +2288,15 @@ void FSFloaterIM::onNewIMReceived(const LLUUID& session_id)
}
FSFloaterIM* new_tab = FSFloaterIM::getInstance(session_id);
FSFloaterIMContainer::getInstance()->addNewSession(new_tab);
EInstantMessage type{ IM_NOTHING_SPECIAL };
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
if (session)
{
type = session->mType;
}
FSFloaterIMContainer::getInstance()->addNewSession(new_tab, type);
}
}
+95 -6
View File
@@ -123,7 +123,7 @@ void FSFloaterIMContainer::initTabs()
}
else
{
addFloater(floater_contacts, true);
addFloater(floater_contacts, true, IM_NOTHING_SPECIAL);
}
}
@@ -141,7 +141,7 @@ void FSFloaterIMContainer::initTabs()
}
else
{
addFloater(floater_chat, true);
addFloater(floater_chat, true, IM_NOTHING_SPECIAL);
}
}
}
@@ -193,6 +193,27 @@ void FSFloaterIMContainer::onClose(bool app_quitting)
void FSFloaterIMContainer::addFloater(LLFloater* floaterp,
bool select_added_floater,
LLTabContainer::eInsertionPoint insertion_point)
{
if (!floaterp)
{
return;
}
EInstantMessage type{ IM_NOTHING_SPECIAL };
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(floaterp->getKey());
if (session)
{
type = session->mType;
}
addFloater(floaterp, select_added_floater, type, insertion_point);
}
void FSFloaterIMContainer::addFloater(LLFloater* floaterp,
bool select_added_floater,
EInstantMessage type,
LLTabContainer::eInsertionPoint no_auto_insertion_point)
{
if (!floaterp)
return;
@@ -239,11 +260,79 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp,
floaterp->setCanClose(false);
return;
}
LLTabContainer::eInsertionPoint insertion_point = no_auto_insertion_point;
if (mIsAddingNewSession)
{
if (gSavedSettings.getBOOL("FSAutoOrderIMTabs"))
{
const std::string order_priorities = gSavedSettings.getString("FSAutoOrderIMTabsPriorities");
// sort order uses the ascii values for 0, 1 and 2, just to make it simpler to store as a string
// and the values can be easily compared via greater or less than
std::map<EInstantMessage, S32> sort_order;
sort_order[IM_SESSION_GROUP_START] = order_priorities[0];
sort_order[IM_SESSION_CONFERENCE_START] = order_priorities[1];
sort_order[IM_NOTHING_SPECIAL] = order_priorities[2];
bool insert_at_top = gSavedSettings.getBOOL("FSAutoOrderIMTabsAtTop");
if (type == IM_SESSION_INVITE)
{
// make sure group IMs are always the same value
type = IM_SESSION_GROUP_START;
}
bool type_found{ false };
S32 index;
for (index = mTabContainer->getNumLockedTabs(); index < mTabContainer->getTabCount(); index++)
{
FSFloaterIM* tab = dynamic_cast<FSFloaterIM*>(mTabContainer->getPanelByIndex(index));
if (!tab)
{
continue;
}
const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(tab->getKey());
if (!session)
{
continue;
}
EInstantMessage session_type = session->mType;
if (session_type == IM_SESSION_INVITE)
{
// make sure group IMs are always the same value
session_type = IM_SESSION_GROUP_START;
}
if (session_type == type)
{
if (insert_at_top)
{
break;
}
type_found = true;
}
else if (type_found)
{
break;
}
else if (sort_order[session_type] < sort_order[type])
{
break;
}
}
insertion_point = (LLTabContainer::eInsertionPoint)index;
}
}
else
{
// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-06-22 (Catznip-3.3.0)
// If we're redocking a torn off IM floater, return it back to its previous place
if (!mIsAddingNewSession && (floaterp->isTornOff()) && (LLTabContainer::END == insertion_point) )
if (floaterp->isTornOff())
{
LLChicletPanel* pChicletPanel = LLChicletBar::instance().getChicletPanel();
@@ -283,11 +372,11 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp,
floaterp->mCloseSignal.connect(boost::bind(&FSFloaterIMContainer::onCloseFloater, this, session_id));
}
void FSFloaterIMContainer::addNewSession(LLFloater* floaterp)
void FSFloaterIMContainer::addNewSession(LLFloater* floaterp, EInstantMessage type)
{
// Make sure we don't do some strange re-arranging if we add a new IM floater due to a new session
mIsAddingNewSession = true;
addFloater(floaterp, false, LLTabContainer::END);
addFloater(floaterp, false, type);
mIsAddingNewSession = false;
}
@@ -682,7 +771,7 @@ void FSFloaterIMContainer::restoreOpenIMs()
{
if (im_floater->getHost() != this)
{
addFloater(im_floater, false);
addFloater(im_floater, false, IM_NOTHING_SPECIAL);
}
}
}
+9 -2
View File
@@ -32,6 +32,7 @@
#include "llmultifloater.h"
#include "llimview.h"
#include "llinstantmessage.h"
class LLTabContainer;
@@ -48,13 +49,19 @@ public:
void draw() override;
void addFloater(LLFloater* floaterp,
bool select_added_floater,
LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END) override;
LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END) override;
void addFloater(LLFloater* floaterp,
bool select_added_floater,
EInstantMessage type,
LLTabContainer::eInsertionPoint no_auto_insertion_point = LLTabContainer::END);
// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-12-11 (Catznip-3.2.0d) | Added: Catznip-3.2.0d
void removeFloater(LLFloater* floaterp) override;
// [/SL:KB]
bool hasFloater(LLFloater* floaterp);
void addNewSession(LLFloater* floaterp);
void addNewSession(LLFloater* floaterp, EInstantMessage type);
static FSFloaterIMContainer* findInstance();
static FSFloaterIMContainer* getInstance();
+1 -1
View File
@@ -524,7 +524,7 @@ void FSFloaterNearbyChat::onOpen(const LLSD& key )
}
else
{
floater_container->addFloater(this, false);
floater_container->addFloater(this, false, IM_NOTHING_SPECIAL);
}
}
+1 -1
View File
@@ -828,7 +828,7 @@ void FSFloaterPlaceDetails::onSLURLBuilt(std::string& slurl)
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (slurl.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+54 -29
View File
@@ -27,27 +27,28 @@
#include "fsfloaterposer.h"
#include "fsposeranimator.h"
#include "fsvirtualtrackpad.h"
#include "v4color.h"
#include "llagent.h"
#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llcheckboxctrl.h"
#include "llcommonutils.h"
#include "llcontrolavatar.h"
#include "llnotificationsutil.h"
#include "lldiriterator.h"
#include "llsdserialize.h"
#include "llscrolllistctrl.h"
#include "llsliderctrl.h"
#include "lltabcontainer.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llwindow.h"
#include "llvoavatarself.h"
#include "llinventoryfunctions.h"
#include "lltoolcomp.h"
#include "llloadingindicator.h"
#include "llmutelist.h"
#include "llappviewer.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
#include "llsliderctrl.h"
#include "llstring.h"
#include "lltabcontainer.h"
#include "lltoolcomp.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwindow.h"
#include "v4color.h"
namespace
{
@@ -131,7 +132,7 @@ bool FSFloaterPoser::postBuild()
{
onJointTabSelect();
setRotationChangeButtons(false, false);
});
});
mAvatarSelectionScrollList = getChild<LLScrollListCtrl>("avatarSelection_scroll");
mAvatarSelectionScrollList->setCommitOnSelectionChange(true);
@@ -411,19 +412,35 @@ void FSFloaterPoser::refreshPoseScroll(LLScrollListCtrl* posesScrollList, std::o
if (subDirectory.has_value())
gDirUtilp->append(dir, std::string(subDirectory.value()));
std::string file;
static const std::string date_format_str = getString(gSavedSettings.getBOOL("Use24HourClock") ? "FiledateFormat" : "FiledateFormatAMPM");
std::string file;
llstat stat_data;
time_t last_modified = 0;
LLDirIterator dir_iter(dir, POSE_INTERNAL_FORMAT_FILE_MASK);
while (dir_iter.next(file))
{
std::string path = gDirUtilp->add(dir, file);
std::string name = gDirUtilp->getBaseFileName(LLURI::unescape(path), true);
LLSD row;
row["columns"][0]["column"] = "name";
row["columns"][0]["value"] = name;
if (LLFile::stat(path, &stat_data))
last_modified = 0;
else
last_modified = stat_data.st_mtime;
llifstream infile;
infile.open(path);
std::string date_str = date_format_str;
LLSD substitution;
substitution["datetime"] = (F64)last_modified;
LLStringUtil::format(date_str, substitution);
LLSD row;
row["columns"][0]["column"] = "load_file_name_column";
row["columns"][0]["value"] = name;
row["columns"][1]["column"] = "load_file_date_column";
row["columns"][1]["value"] = date_str;
row["columns"][2]["column"] = "load_file_date_sort_column";
row["columns"][2]["value"] = llformat("%u", (U64)last_modified);
llifstream infile(path.c_str());
if (!infile.is_open())
{
LL_WARNS("Posing") << "Skipping: Cannot read file in: " << path << LL_ENDL;
@@ -628,14 +645,14 @@ bool FSFloaterPoser::savePoseToXml(LLVOAvatar* avatar, const std::string& poseFi
{
bool savingDiff = !mPoserAnimator.allBaseRotationsAreZero(avatar);
LLSD record;
record["version"]["value"] = (S32)7;
record["version"]["value"] = (S32)8;
record["startFromTeePose"]["value"] = !savingDiff;
if (savingDiff)
mPoserAnimator.savePosingState(avatar, false, &record);
LLVector3 rotation, position, scale, zeroVector;
bool baseRotationIsZero;
bool baseRotationIsZero, userSetBaseRotationToZero;
for (const FSPoserAnimator::FSPoserJoint& pj : mPoserAnimator.PoserJoints)
{
@@ -651,7 +668,8 @@ bool FSFloaterPoser::savePoseToXml(LLVOAvatar* avatar, const std::string& poseFi
record[bone_name]["mirrored"] = jointRotMirrored;
if (!mPoserAnimator.tryGetJointSaveVectors(avatar, pj, &rotation, &position, &scale, &baseRotationIsZero))
if (!mPoserAnimator.tryGetJointSaveVectors(avatar, pj, &rotation, &position, &scale, &baseRotationIsZero,
&userSetBaseRotationToZero))
continue;
bool jointRotPosScaleAllZero = rotation == zeroVector && position == zeroVector && scale == zeroVector;
@@ -659,11 +677,12 @@ bool FSFloaterPoser::savePoseToXml(LLVOAvatar* avatar, const std::string& poseFi
if (savingDiff && jointRotPosScaleAllZero)
continue;
record[bone_name]["jointBaseRotationIsZero"] = baseRotationIsZero;
record[bone_name]["rotation"] = rotation.getValue();
record[bone_name]["position"] = position.getValue();
record[bone_name]["scale"] = scale.getValue();
record[bone_name]["worldLocked"] = jointRotLocked;
record[bone_name]["jointBaseRotationIsZero"] = baseRotationIsZero;
record[bone_name]["userSetBaseRotationToZero"] = userSetBaseRotationToZero;
record[bone_name]["rotation"] = rotation.getValue();
record[bone_name]["position"] = position.getValue();
record[bone_name]["scale"] = scale.getValue();
record[bone_name]["worldLocked"] = jointRotLocked;
}
std::string fullSavePath =
@@ -1191,7 +1210,7 @@ void FSFloaterPoser::onClickLoadHandPose(bool isRightHand)
continue;
vec3.setValue(control_map["rotation"]);
mPoserAnimator.loadJointRotation(avatar, poserJoint, true, vec3);
mPoserAnimator.loadJointRotation(avatar, poserJoint, true, true, vec3);
}
}
@@ -1274,6 +1293,7 @@ bool FSFloaterPoser::loadPoseFromXml(LLVOAvatar* avatar, const std::string& pose
LLQuaternion quat;
bool enabled;
bool setJointBaseRotationToZero;
bool userSetBaseRotationToZero;
bool worldLocked;
bool mirroredJoint;
S32 version = 0;
@@ -1335,6 +1355,11 @@ bool FSFloaterPoser::loadPoseFromXml(LLVOAvatar* avatar, const std::string& pose
else
setJointBaseRotationToZero = startFromZeroRot;
if (control_map.has("userSetBaseRotationToZero"))
userSetBaseRotationToZero = control_map["userSetBaseRotationToZero"].asBoolean();
else
userSetBaseRotationToZero = startFromZeroRot;
if (loadPositions && control_map.has("position"))
vec3.setValue(control_map["position"]);
else
@@ -1347,7 +1372,7 @@ bool FSFloaterPoser::loadPoseFromXml(LLVOAvatar* avatar, const std::string& pose
else
vec3.clear();
mPoserAnimator.loadJointRotation(avatar, poserJoint, setJointBaseRotationToZero, vec3);
mPoserAnimator.loadJointRotation(avatar, poserJoint, setJointBaseRotationToZero, userSetBaseRotationToZero, vec3);
if (loadScales && control_map.has("scale"))
vec3.setValue(control_map["scale"]);
+2 -2
View File
@@ -58,12 +58,12 @@ void FSJointPose::setPublicPosition(const LLVector3& pos)
mCurrentState.mPoserChangeType = POSER_CHANGE_DEFAULT;
}
void FSJointPose::setPublicRotation(bool zeroBase, E_PoserChangeType changeType, const LLQuaternion& rot)
void FSJointPose::setPublicRotation(bool zeroBase, bool zeroBaseAsUser, E_PoserChangeType changeType, const LLQuaternion& rot)
{
addStateToUndo(mCurrentState);
if (zeroBase)
zeroBaseRotation(true);
zeroBaseRotation(zeroBaseAsUser);
else
mCurrentState.mUserSpecifiedBaseZero = POSER_CHANGE_DEFAULT;
+3 -1
View File
@@ -104,6 +104,8 @@ class FSJointPose
/// Sets the 'public' rotation of the joint.
/// </summary>
/// <param name="zeroBase">Whether to zero the base rotation on setting the supplied rotation.</param>
/// <param name="zeroBaseAsUser">Whether to indicate base was zeroed by action of the user; used for BVH export.</param>
/// <param name="changeType">The type change, hinting at the kind of undo action expected.</param>
/// <param name="rot">The change in rotation to apply.</param>
/// <remarks>
/// 'Public rotation' is the amount of rotation the user has added to the initial state.
@@ -112,7 +114,7 @@ class FSJointPose
/// If zeroBase is true, we treat rotations as if in BVH mode: user work.
/// If zeroBase is false, we treat as NOT BVH: some existing pose and user work.
/// </remarks>
void setPublicRotation(bool zeroBase, E_PoserChangeType changeType, const LLQuaternion& rot);
void setPublicRotation(bool zeroBase, bool zeroBaseAsUser, E_PoserChangeType changeType, const LLQuaternion& rot);
/// <summary>
/// Reflects the base and delta rotation of the represented joint left-right.
+21 -19
View File
@@ -506,7 +506,7 @@ void FSPoserAnimator::updateJointRotationFromManip(LLVOAvatar* avatar, const FSP
return;
LLQuaternion framedRotation = changeToRotationFrame(avatar, rotation, frame, jointPose);
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_ROTATION, framedRotation * jointPose->getPublicRotation());
jointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_ROTATION, framedRotation * jointPose->getPublicRotation());
deRotateWorldLockedDescendants(joint, posingMotion, framedRotation);
@@ -523,7 +523,7 @@ void FSPoserAnimator::updateJointRotationFromManip(LLVOAvatar* avatar, const FSP
{
case SYMPATHETIC:
case SYMPATHETIC_DELTA:
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_ROTATION,
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_ROTATION,
framedRotation * oppositeJointPose->getPublicRotation());
if (oppositePoserJoint)
deRotateWorldLockedDescendants(oppositePoserJoint, posingMotion, framedRotation);
@@ -531,7 +531,7 @@ void FSPoserAnimator::updateJointRotationFromManip(LLVOAvatar* avatar, const FSP
case MIRROR:
case MIRROR_DELTA:
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_ROTATION,
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_ROTATION,
mirroredRotation * oppositeJointPose->getPublicRotation());
if (oppositePoserJoint)
deRotateWorldLockedDescendants(oppositePoserJoint, posingMotion, mirroredRotation);
@@ -617,12 +617,13 @@ void FSPoserAnimator::updateJointPositionFromManip(LLVOAvatar* avatar, const FSP
grandParentLengthRotChange = grandParentWorldRot * grandParentLengthRotChange * ~grandParentWorldRot;
parentLengthRotChange = parentWorldRot * parentLengthRotChange * ~parentWorldRot;
movedJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_CHILDMOVE, movedJointPose->getPublicRotation()); // set up undo
parentJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_ROTATION,
movedJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_CHILDMOVE,
movedJointPose->getPublicRotation()); // set up undo
parentJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_ROTATION,
parentLengthRotChange * parentJointPose->getPublicRotation());
grandParentJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_ROTATION,
grandParentJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_ROTATION,
grandParentLengthRotChange * grandParentJointPose->getPublicRotation());
grandParentJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_ROTATION,
grandParentJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_ROTATION,
grandParentFrameRotChange * grandParentJointPose->getPublicRotation());
auto grandParentPoserJoint = getPoserJointByName(grandParentJoint->getName());
@@ -867,28 +868,28 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
case SYMPATHETIC:
case MIRROR:
if (rotationStyle == DELTAIC_ROT || translationRequiresDelta)
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
jointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
else
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT, absRot);
jointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT, absRot);
break;
case SYMPATHETIC_DELTA:
case MIRROR_DELTA:
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
jointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
break;
case DELTAMODE:
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
jointPose->setPublicRotation(resetBaseRotationToZero,true, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
deRotateWorldLockedDescendants(joint, posingMotion, deltaRot);
return;
case NONE:
default:
if (rotationStyle == DELTAIC_ROT || translationRequiresDelta)
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
jointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT, deltaRot * jointPose->getPublicRotation());
else
jointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT, absRot);
jointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT, absRot);
deRotateWorldLockedDescendants(joint, posingMotion, deltaRot);
return;
@@ -911,7 +912,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
break;
case SYMPATHETIC_DELTA:
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT,
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT,
deltaRot * oppositeJointPose->getPublicRotation());
if (oppositePoserJoint)
deRotateWorldLockedDescendants(oppositePoserJoint, posingMotion, deltaRot);
@@ -924,7 +925,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
break;
case MIRROR_DELTA:
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, POSER_CHANGE_DEFAULT,
oppositeJointPose->setPublicRotation(resetBaseRotationToZero, true, POSER_CHANGE_DEFAULT,
mirroredRotation * oppositeJointPose->getPublicRotation());
if (oppositePoserJoint)
deRotateWorldLockedDescendants(oppositePoserJoint, posingMotion, mirroredRotation);
@@ -1266,7 +1267,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join
}
bool FSPoserAnimator::tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJoint& joint, LLVector3* rot, LLVector3* pos,
LLVector3* scale, bool* baseRotationIsZero)
LLVector3* scale, bool* baseRotationIsZero, bool* userSetBaseRotZero)
{
if (!rot || !pos || !scale)
return false;
@@ -1287,11 +1288,12 @@ bool FSPoserAnimator::tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJo
pos->set(jointPose->getPublicPosition());
scale->set(jointPose->getPublicScale());
*baseRotationIsZero = jointPose->isBaseRotationZero();
*userSetBaseRotZero = jointPose->userHasSetBaseRotationToZero();
return true;
}
void FSPoserAnimator::loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, bool setBaseToZero, LLVector3 rotation)
void FSPoserAnimator::loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, bool setBaseToZero, bool userSetBaseToZero, LLVector3 rotation)
{
if (!isAvatarSafeToUse(avatar) || !joint)
return;
@@ -1307,7 +1309,7 @@ void FSPoserAnimator::loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint*
jointPose->purgeUndoQueue();
LLQuaternion rot = translateRotationToQuaternion(avatar, jointPose, POSER_FRAME_BONE, SWAP_NOTHING, NEGATE_NOTHING, rotation);
jointPose->setPublicRotation(setBaseToZero, POSER_CHANGE_DEFAULT, rot);
jointPose->setPublicRotation(setBaseToZero, userSetBaseToZero, POSER_CHANGE_DEFAULT, rot);
}
void FSPoserAnimator::loadJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, bool loadPositionAsDelta, LLVector3 position)
@@ -1621,7 +1623,7 @@ void FSPoserAnimator::deRotateJointOrFirstLockedChild(const FSPoserJoint* joint,
LLQuaternion rotDiffInChildFrame = differenceInWorldRot * rotationChange * ~differenceInWorldRot;
rotDiffInChildFrame.conjugate();
jointPose->setPublicRotation(false, POSER_CHANGE_ROTATION, rotDiffInChildFrame * jointPose->getPublicRotation());
jointPose->setPublicRotation(false, false, POSER_CHANGE_ROTATION, rotDiffInChildFrame * jointPose->getPublicRotation());
return;
}
+5 -2
View File
@@ -693,13 +693,15 @@ public:
/// <param name="pos">The vector to store the position to save in.</param>
/// <param name="scale">The vector to store the scale to save in.</param>
/// <param name="baseRotationIsZero">The bool to store whether the base rotation is zero.</param>
/// <param name="userSetBaseRotZero">The bool indicating rotation was set to zero by user action.</param>
/// <returns>True if the joint should be saved, otherwise false.</returns>
/// <remarks>
/// Our objective is to protect peoples novel work: the poses created with this, and poses from other sources, such as in-world.
/// In all scenarios, this yeilds 'deltas' of rotation/position/scale.
/// The deltas represent the user's novel work, and may be relative to some initial values (as from a pose), or to 'nothing' (such as all rotations == 0, or, the 'T-Pose').
/// </remarks>
bool tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJoint& joint, LLVector3* rot, LLVector3* pos, LLVector3* scale, bool* baseRotationIsZero);
bool tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJoint& joint, LLVector3* rot, LLVector3* pos, LLVector3* scale,
bool* baseRotationIsZero, bool* userSetBaseRotZero);
/// <summary>
/// Loads a joint rotation for the supplied joint on the supplied avatar.
@@ -707,13 +709,14 @@ public:
/// <param name="avatar">The avatar to load the rotation for.</param>
/// <param name="joint">The joint to load the rotation for.</param>
/// <param name="setBaseToZero">Whether to start from a zero base rotation.</param>
/// <param name="userSetBaseToZero">Whether the user has set zero base rotation, such as by editing when BVH export enabled.</param>
/// <param name="rotation">The rotation to load.</param>
/// <remarks>
/// All rotations we load are deltas to the current rotation the supplied joint has.
/// Whether the joint already has a rotation because some animation is playing,
/// or whether its rotation is zero, the result is always the same: just 'add' the supplied rotation to the existing rotation.
/// </remarks>
void loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, bool setBaseToZero, LLVector3 rotation);
void loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, bool setBaseToZero, bool userSetBaseToZero, LLVector3 rotation);
/// <summary>
/// Loads a joint position for the supplied joint on the supplied avatar.
+1 -1
View File
@@ -279,7 +279,7 @@ void FSPosingMotion::setAllRotationsToZeroAndClearUndo()
for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter)
{
poserJoint_iter->purgeUndoQueue();
poserJoint_iter->setPublicRotation(true, POSER_CHANGE_ROTATION, LLQuaternion::DEFAULT);
poserJoint_iter->setPublicRotation(true, true, POSER_CHANGE_ROTATION, LLQuaternion::DEFAULT);
}
}
+74 -1
View File
@@ -685,6 +685,44 @@ public:
}
};
// <FS:TJ> Purge CEF cache in another thread to prevent very slow startup times
class FSCefCachePurgeThread : public LLThread
{
public:
std::string mCefCachePath;
FSCefCachePurgeThread(const std::string& cef_cache_path) : LLThread("cef cache purge")
{
mCefCachePath = cef_cache_path;
}
void run()
{
// Check if the entire cache path can be purged
std::string cef_cache_path_old = mCefCachePath + "_old";
if (LLFile::isdir(cef_cache_path_old))
{
gDirUtilp->deleteDirAndContents(cef_cache_path_old);
return;
}
// Otherwise, purge individual folders that aren't in use
std::vector<std::string> cef_caches = gDirUtilp->getDirectoriesInDir(mCefCachePath);
for (const auto& cache_dir : cef_caches)
{
if (!LLAppViewer::instance()->isQuitting())
{
if (cache_dir.ends_with("_old"))
{
std::string cef_cache_path = mCefCachePath + "\\" + cache_dir;
gDirUtilp->deleteDirAndContents(cef_cache_path);
}
}
}
}
};
// </FS:TJ>
//virtual
bool LLAppViewer::initSLURLHandler()
{
@@ -736,6 +774,7 @@ LLAppViewer::LLAppViewer()
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", false)),
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", false)),
mFastTimerLogThread(NULL),
mCefCachePurgeThread(NULL), // <FS:TJ/> For CEF cache purging in a background thread
mSettingsLocationList(NULL),
mIsFirstRun(false),
mSaveSettingsOnExit(true), // <FS:Zi> Backup Settings
@@ -2491,6 +2530,10 @@ bool LLAppViewer::cleanup()
sPurgeDiskCacheThread = NULL;
delete mGeneralThreadPool;
mGeneralThreadPool = NULL;
// <FS:TJ> For CEF cache purging in a background thread
delete mCefCachePurgeThread;
mCefCachePurgeThread = NULL;
// </FS:TJ>
if (LLFastTimerView::sAnalyzePerformance)
{
@@ -5369,7 +5412,10 @@ bool LLAppViewer::initCache()
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS, getObjectCacheVersion());
// Remove old, stale CEF cache folders
purgeCefStaleCaches();
// <FS:TJ> Purge CEF cache in another thread to prevent very slow startup times
//purgeCefStaleCaches();
startCefCachePurge();
// </FS:TJ>
return true;
}
@@ -5411,6 +5457,33 @@ void LLAppViewer::purgeCefStaleCaches()
}
}
// <FS:TJ> Purge CEF cache in another thread to prevent very slow startup times
void LLAppViewer::startCefCachePurge()
{
const std::string browser_parent_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");
if (LLFile::isdir(browser_parent_cache))
{
// Try rename the entire cef cache folder to be purged in the background thread
if (LLFile::rename(browser_parent_cache, browser_parent_cache + "_old", -1) == -1)
{
// Otherwise rename the individual cache folders to be purged in the background thread
std::vector<std::string> cef_caches = gDirUtilp->getDirectoriesInDir(browser_parent_cache);
for (const auto& cache_dir : cef_caches)
{
if (!cache_dir.ends_with("_old"))
{
std::string cef_cache_path = browser_parent_cache + "\\" + cache_dir;
LLFile::rename(cef_cache_path, cef_cache_path + "_old", -1);
}
}
}
mCefCachePurgeThread = new FSCefCachePurgeThread(browser_parent_cache);
mCefCachePurgeThread->start();
}
}
// </FS:TJ>
void LLAppViewer::purgeCache()
{
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
+2
View File
@@ -378,6 +378,7 @@ private:
// For performance and metric gathering
class LLThread* mFastTimerLogThread;
class LLThread* mCefCachePurgeThread; // <FS:TJ/> For CEF cache purging in a background thread
// for tracking viewer<->region circuit death
bool mAgentRegionLastAlive;
@@ -397,6 +398,7 @@ private:
// <FS:ND> For Windows, purging the cache can take an extraordinary amount of time. Rename the cache dir and purge it using another thread.
virtual void startCachePurge() {}
void startCefCachePurge(); // <FS:TJ/> Purge this in another thread to prevent very slow startup times
};
// Globals with external linkage. From viewer.h
+1 -1
View File
@@ -1545,7 +1545,7 @@ void copy_slurl_to_clipboard_cb(std::string& slurl)
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (slurl.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+74
View File
@@ -40,6 +40,7 @@
#endif
LLFloaterHoverHeight::LLFloaterHoverHeight(const LLSD& key) : LLFloater(key)
, mModifiers(MASK_NONE) // <FS:Zi> FIRE-33859 - Add +/- and reset buttons to hover height slider
{
}
@@ -71,6 +72,11 @@ bool LLFloaterHoverHeight::postBuild()
sldrCtrl->setSliderMouseUpCallback(boost::bind(&LLFloaterHoverHeight::onFinalCommit,this));
sldrCtrl->setSliderEditorCommitCallback(boost::bind(&LLFloaterHoverHeight::onFinalCommit,this));
childSetCommitCallback("HoverHeightSlider", &LLFloaterHoverHeight::onSliderMoved, NULL);
// <FS:Zi> FIRE-33859 - Add +/- and reset buttons to hover height slider
childSetCommitCallback("PlusButton", boost::bind(&LLFloaterHoverHeight::onPlusButtonClicked, this), nullptr);
childSetCommitCallback("MinusButton", boost::bind(&LLFloaterHoverHeight::onMinusButtonClicked, this), nullptr);
childSetCommitCallback("ResetButton", boost::bind(&LLFloaterHoverHeight::onResetButtonClicked, this), nullptr);
// </FS:Zi>
// Initialize slider from pref setting.
syncFromPreferenceSetting(this);
@@ -145,6 +151,66 @@ void LLFloaterHoverHeight::onFinalCommit()
gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ",value);
}
// <FS:Zi> FIRE-33859 - Add +/- and reset buttons to hover height slider
bool LLFloaterHoverHeight::handleKey(KEY key, MASK mask, bool called_from_parent)
{
mModifiers = mask;
return LLUICtrl::handleKey(key, mask, called_from_parent);
}
bool LLFloaterHoverHeight::handleKeyUp(KEY key, MASK mask, bool called_from_parent)
{
mModifiers = mask;
return LLUICtrl::handleKeyUp(key, mask, called_from_parent);
}
void LLFloaterHoverHeight::onResetButtonClicked()
{
onButtonClicked(0.0f);
}
void LLFloaterHoverHeight::onPlusButtonClicked()
{
onButtonClicked(0.01f);
}
void LLFloaterHoverHeight::onMinusButtonClicked()
{
onButtonClicked(-0.01f);
}
void LLFloaterHoverHeight::onButtonClicked(F32 value)
{
LLSliderCtrl* sldrCtrl = getChild<LLSliderCtrl>("HoverHeightSlider");
if (value == 0.0f)
{
sldrCtrl->setValue(0.0f);
}
else
{
switch (mModifiers)
{
case MASK_ALT:
{
value *= 10.0f;
break;
}
case MASK_CONTROL:
case MASK_SHIFT:
{
value *= 0.1f;
break;
}
}
sldrCtrl->setValue(sldrCtrl->getValueF32() + value);
}
onSliderMoved(sldrCtrl, nullptr);
onFinalCommit();
}
// </FS:Zi>
void LLFloaterHoverHeight::onRegionChanged()
{
LLViewerRegion *region = gAgent.getRegion();
@@ -178,6 +244,14 @@ void LLFloaterHoverHeight::updateEditEnabled()
// </FS:Ansariel>
LLSliderCtrl* sldrCtrl = getChild<LLSliderCtrl>("HoverHeightSlider");
sldrCtrl->setEnabled(enabled);
// <FS:Zi> FIRE-33859 - Add +/- and reset buttons to hover height slider
LLButton* button = getChild<LLButton>("PlusButton");
button->setEnabled(enabled);
button = getChild<LLButton>("MinusButton");
button->setEnabled(enabled);
button = getChild<LLButton>("ResetButton");
button->setEnabled(enabled);
// </FS:Zi>
if (enabled)
{
syncFromPreferenceSetting(this);
+12
View File
@@ -45,6 +45,18 @@ public:
void onSimulatorFeaturesReceived(const LLUUID &region_id);
void updateEditEnabled();
// <FS:Zi> FIRE-33859 - Add +/- and reset buttons to hover height slider
bool handleKey(KEY key, MASK mask, bool called_from_parent);
bool handleKeyUp(KEY key, MASK mask, bool called_from_parent);
void onResetButtonClicked();
void onPlusButtonClicked();
void onMinusButtonClicked();
void onButtonClicked(F32 value);
MASK mModifiers;
// </FS:Zi>
/*virtual*/ void onClose(bool app_quitting);
boost::signals2::connection mRegionChangedSlot;
};
+1 -1
View File
@@ -2070,7 +2070,7 @@ void copy_slurl_to_clipboard_callback_inv(const std::string& slurl)
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (slurl.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+1 -1
View File
@@ -345,7 +345,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (slurl.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+7 -2
View File
@@ -432,9 +432,8 @@ void NearbyVoiceMonitor::draw()
mSpeakerMgr->update(true);
mSpeakerMgr->getSpeakerList(&speaker_list, false);
for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin(); it != speaker_list.end(); ++it)
for (const auto& speaker : speaker_list)
{
LLPointer<LLSpeaker> speaker = *it;
if (speaker->mSpeechVolume > 0.f || speaker->mStatus == LLSpeaker::STATUS_SPEAKING)
{
draw = true;
@@ -450,6 +449,12 @@ void NearbyVoiceMonitor::draw()
LLOutputMonitorCtrl::draw();
}
}
bool NearbyVoiceMonitor::handleMouseUp(S32 x, S32 y, MASK mask)
{
return true;
}
// </FS:Zi> Add new control to have a nearby voice output monitor
//////////////////////////////////////////////////////////////////////////
+1
View File
@@ -188,6 +188,7 @@ public:
NearbyVoiceMonitor(const Params& p);
void draw();
bool handleMouseUp(S32 x, S32 y, MASK mask);
protected:
bool mAutoHide;
+1 -1
View File
@@ -1476,7 +1476,7 @@ static void onSLURLBuilt(std::string& slurl)
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (slurl.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+1 -1
View File
@@ -85,7 +85,7 @@ void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos,
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (sl_url.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+1 -1
View File
@@ -1202,7 +1202,7 @@ void LLTeleportHistoryPanel::gotSLURLCallback(const std::string& slurl)
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
if (slurl.empty())
{
LLNotificationsUtil::add("CopySLURLEmpty");
LLNotificationsUtil::add("LandmarkLocationUnknown");
return;
}
// </FS:Zi>
+48 -53
View File
@@ -38,7 +38,8 @@
// </FS:CR> Aurora Sim
#include "fsworldmapmessage.h" // <FS:humbletim/> FIRE-31368: [OPENSIM] ... Search returns more than one result
const U32 LAYER_FLAG = 2;
constexpr U32 LAYER_FLAG = 2;
constexpr S32 MAP_SIM_RETURN_NULL_SIMS = 0x00010000;
//---------------------------------------------------------------------------
// World Map Message Handling
@@ -147,12 +148,12 @@ void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
// - use 0x01 (prims) because LAYER_FLAG (terrain) does not come back on nonexistant
// U32 flags = LAYER_FLAG;
U32 flags = 0x01;
// </FS:Zi>
flags |= (return_nonexistent ? 0x10000 : 0);
U32 flags = LAYER_FLAG;
if (return_nonexistent)
{
// overwrite LAYER_FLAG, otherwise server won't respond to missing regions
flags = MAP_SIM_RETURN_NULL_SIMS;
}
msg->addU32Fast(_PREHASH_Flags, flags);
msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim
msg->addBOOLFast(_PREHASH_Godlike, false); // Filled in on sim
@@ -182,31 +183,17 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
#endif
// </FS:humbletim>
// There's only one flag that we ever use here
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
// - use 0x01 (prims) because LAYER_FLAG (terrain) does not come back on nonexistent
// if (agent_flags != LAYER_FLAG)
if (agent_flags != 0x01)
// <FS:Zi>
S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data);
// There's only one flag that we ever use here, unless we also want an existence check.
if (agent_flags != LAYER_FLAG
&& num_blocks != 1) // we check existence for a single region
{
LL_WARNS() << "Invalid map image type returned! layer = " << agent_flags << LL_ENDL;
// <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know
// Handle the SLURL callback if any
url_callback_t callback = LLWorldMapMessage::getInstance()->mSLURLCallback;
if(callback != NULL)
{
LLWorldMapMessage::getInstance()->mSLURLCallback = NULL;
LLWorldMapMessage::getInstance()->mSLURLRegionName.clear();
LLWorldMapMessage::getInstance()->mSLURLRegionHandle = 0;
callback(0, LLWorldMapMessage::getInstance()->mSLURL, LLUUID::null, false);
}
// </FS:Zi>
return;
}
S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data);
//LL_INFOS("WorldMap") << "num_blocks = " << num_blocks << LL_ENDL;
LL_DEBUGS("WorldMap") << "num_blocks = " << num_blocks << LL_ENDL;
bool found_null_sim = false;
@@ -248,36 +235,44 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
U32 x_world = (U32)(x_regions) * REGION_WIDTH_UNITS;
U32 y_world = (U32)(y_regions) * REGION_WIDTH_UNITS;
// name shouldn't be empty, see EXT-4568
// <AW: opensim>
// was: llassert(!name.empty())
// which made debug builds impossible to use on OpenSim
if (name.empty() && accesscode != 255)
// Name shouldn't be empty unless region doesn't exist
if (!name.empty())
{
LL_WARNS() << "MapBlockReply returned empty region name, not inserting in the world map" << LL_ENDL;
continue;
}
// </AW: opensim>
// Insert that region in the world map, if failure, flag it as a "null_sim"
// <FS:CR> Aurora Sim
//if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, name, image_id, (U32)accesscode, region_flags)))
if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, x_size, y_size, name, image_id, (U32)accesscode, region_flags)))
// </FS:CR> Aurora Sim
{
found_null_sim = true;
}
// Insert that region in the world map, if failure, flag it as a "null_sim"
// If we hit a valid tracking location, do what needs to be done app level wise
if (LLWorldMap::getInstance()->isTrackingValidLocation())
{
LLVector3d pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal();
if (LLWorldMap::getInstance()->isTrackingDoubleClick())
// <FS:CR> Aurora Sim
//if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, name, image_id, (U32)accesscode, region_flags)))
if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, x_size, y_size, name, image_id, (U32)accesscode, region_flags)))
// </FS:CR> Aurora Sim
{
// Teleport if the user double clicked
gAgent.teleportViaLocation(pos_global);
found_null_sim = true;
}
// Update the "real" tracker information
gFloaterWorldMap->trackLocation(pos_global);
// If we hit a valid tracking location, do what needs to be done app level wise
if (LLWorldMap::getInstance()->isTrackingValidLocation())
{
LLVector3d pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal();
if (LLWorldMap::getInstance()->isTrackingDoubleClick())
{
// Teleport if the user double clicked
gAgent.teleportViaLocation(pos_global);
}
// Update the "real" tracker information
gFloaterWorldMap->trackLocation(pos_global);
}
}
else
{
// <AW: opensim>
if (accesscode != 255)
{
LL_WARNS() << "MapBlockReply returned empty region name, not inserting in the world map" << LL_ENDL;
continue;
}
LLWorldMap::getInstance()->insertRegion(x_world, y_world, x_size, y_size, name, image_id, (U32)accesscode, region_flags);
// </AW: opensim>
found_null_sim = true;
}
// Handle the SLURL callback if any
@@ -180,6 +180,13 @@
<string name="SaveDiffLabel">Diff. speichern</string>
<string name="OverWriteLabel">Überschreiben?</string>
<floater.string name="FiledateFormat">
[day,datetime,local].[mthnum,datetime,local].[year,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]
</floater.string>
<floater.string name="FiledateFormatAMPM">
[day,datetime,local].[mthnum,datetime,local].[year,datetime,local] [hour12,datetime,local]:[min,datetime,local]:[second,datetime,local] [ampm,datetime,local]
</floater.string>
<!-- The layout is a vertical stack of 3 rows, and each row a horizontal stack of panels -->
<layout_stack name="poser_stack">
<layout_panel name="regular_controls_layout">
@@ -315,7 +322,8 @@
</panel>
<panel name="poses_loadSave">
<scroll_list tool_tip="Pose für ausgewählten Avatar laden." name="poses_scroll">
<scroll_list.columns label="Name Pose" name="name"/>
<scroll_list.columns label="Name" name="load_file_name_column"/>
<scroll_list.columns label="Datum" name="load_file_date_column"/>
</scroll_list>
<line_editor label="Name für Pose zum Speichern eingeben..." name="pose_save_name"/>
</panel>
@@ -329,7 +337,7 @@
<button label="Eigene Posen" name="toggleLoadSavePanel" tool_tip="Laden, speichern under verwalten der eigenen erstellten Posen"/>
<button tool_tip="Posen-Verzeichnis verwalten" name="open_poseDir_button"/>
<menu_button label="Pose laden" tool_tip="Lädt die aktuell ausgewählte Pose." name="load_poses_button"/>
<button label="Diff. speich." tool_tip="Speichert die Differenz zu einer bestehenden Pose. Aus einer T-Pose heraus starten, um ein neues Werk zu beginnen." name="save_poses_button"/>
<button label="Diff. speichern" tool_tip="Speichert die Differenz zu einer bestehenden Pose. Aus einer T-Pose heraus starten, um ein neues Werk zu beginnen." name="save_poses_button"/>
</panel>
</layout_panel>
</layout_stack>
@@ -977,6 +977,10 @@ Dem Viewer ist beim Öffnen der Datei der Speicher ausgegangen. Die Datei ist ve
Sie besitzen für diesen Standort bereits eine Landmarke.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandmarkLocationUnknown">
Die Position der Region konnte nicht ermittelt werden. Die Region ist möglicherweise temporär nicht verfügbar oder wurde entfernt.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CannotCreateLandmarkNotOwner">
Sie können hier keine Landmarke erstellen, da der Landeigentümer dies verboten hat.
</notification>
@@ -2783,12 +2787,6 @@ Von einer Webseite zu diesem Formular linken, um anderen leichten Zugang zu dies
<ignore name="ignore" text="Slurl wurde in meine Zwischenablage kopiert"/>
</form>
</notification>
<notification name="CopySLURLEmpty">
Es gab ein Problem beim Kopieren der SLurl. Die Zielregion existiert möglicherweise nicht mehr.
<form name="form">
<ignore name="ignore" text="Kopieren einer Slurl ist fehlgeschlagen"/>
</form>
</notification>
<notification name="WLSavePresetAlert">
Die gespeicherte Voreinstellung überschreiben?
<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
@@ -84,6 +84,16 @@
<text name="req_restart_chattabs" width="120">
(Erfordert Neustart)
</text>
<check_box name="FSAutoOrderIMTabs" label="IM-Tabs nach Typ sortieren:" tool_tip="Aktiviert automatische Sortierung für IM-Tabs innerhalb des „Gespräche“-Fensters." width="170"/>
<combo_box name="FSAutoOrderIMTabsPriorities">
<combo_box.item name="group_conf_im" label="Gruppen, Konferenzen, IMs"/>
<combo_box.item name="group_im_conf" label="Gruppen, IMs, Konferenzen"/>
<combo_box.item name="conf_group_im" label="Konferenzen, Gruppen, IMs"/>
<combo_box.item name="conf_im_group" label="Konferenzen, IMs, Gruppen"/>
<combo_box.item name="im_group_conf" label="IMs, Gruppen, Konferenzen"/>
<combo_box.item name="im_conf_group" label="IMs, Konferenzen, Gruppen"/>
</combo_box>
<check_box name="FSAutoOrderIMTabsAtTop" label="Neue Tabs als erste einfügen" tool_tip="Fügt neue IM-Tabs als erstes Tab in der jeweiligen Gruppe hinzu."/>
<text name="FSIMTabNameFormat_label">
Namensformat für IM-Tabs:
</text>
@@ -6,7 +6,7 @@
can_close="true"
can_resize="true"
min_height="75"
min_width="515"
min_width="280"
height="75"
layout="topleft"
name="HoverHeight"
@@ -19,7 +19,7 @@
<slider
enabled="false"
decimal_digits="3"
follows="top|left"
follows="top|left|right"
height="15"
increment="0.001"
initial_value="0.0"
@@ -42,4 +42,33 @@
name="BindCameraCheck"
top_pad="10"
width="237"/>
<button
layout="topleft"
enabled="false"
follows="top|right"
right="-60"
label="+"
name="PlusButton"
height="15"
top_delta="0"
width="24"/>
<button
layout="topleft"
enabled="false"
follows="top|right"
left_pad="4"
label="0"
name="ResetButton"
height="15"
width="24"/>
<button
layout="topleft"
enabled="false"
follows="top|right"
left_pad="4"
label="-"
name="MinusButton"
height="15"
width="24"/>
</floater>
@@ -453,6 +453,13 @@
<string name="SaveDiffLabel">Save Diff</string>
<string name="OverWriteLabel">Overwrite?</string>
<floater.string name="FiledateFormat">
[year,datetime,local]/[mthnum,datetime,local]/[day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]
</floater.string>
<floater.string name="FiledateFormatAMPM">
[year,datetime,local]/[mthnum,datetime,local]/[day,datetime,local] [hour12,datetime,local]:[min,datetime,local]:[second,datetime,local] [ampm,datetime,local]
</floater.string>
<!-- The layout is a vertical stack of 3 rows, and each row a horizontal stack of panels -->
<layout_stack
follows="top|left|right"
@@ -1842,20 +1849,32 @@
visible="false"
name="poses_loadSave"
top="0"
width="225">
width="275">
<scroll_list
column_padding="0"
height="280"
follows="left|top|right"
layout="topleft"
tool_tip="Load a pose for who you are animating."
width="225"
multi_select="true"
width="275"
multi_select="false"
draw_heading="true"
name="poses_scroll"
sort_column="load_file_name_column"
top="0">
<scroll_list.columns
label="Pose Name"
name="name"/>
label="Name"
name="load_file_name_column"
width="150"/>
<scroll_list.columns
label="Date"
name="load_file_date_column"
sort_column="load_file_date_sort_column"
width="125"/>
<scroll_list.columns
label="Date"
name="load_file_date_sort_column"
width="-1"/>
</scroll_list>
<line_editor
follows="top|left"
@@ -1865,7 +1884,7 @@
commit_on_focus_lost="false"
label="Enter Pose Name To Save..."
name="pose_save_name"
width="225"/>
width="275"/>
</panel>
</layout_panel>
<layout_panel
@@ -2038,9 +2057,9 @@
menu_filename="menu_fs_poser_poses_btn.xml"
menu_position="topright"
name="load_poses_button"
left_pad="1"
left_pad="5"
top_delta="0"
width="85"/>
width="105"/>
<button
height="21"
follows="top|left"
@@ -2055,7 +2074,7 @@
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
name="save_poses_button"
width="85"
width="105"
top_delta="0"
left_pad="1">
<button.commit_callback
@@ -2084,4 +2103,4 @@
</panel>
</layout_panel>
</layout_stack>
</floater>
</floater>
@@ -2564,7 +2564,7 @@ You already have a landmark for this location.
icon="alert.tga"
name="LandmarkLocationUnknown"
type="alert">
Viewer wasn't able to get region's location. Region might be temporarily unavailable, was removed or landmark failed to load.
Viewer wasn't able to get region's location. Region might be temporarily unavailable or was removed.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -7142,19 +7142,6 @@ Link to this from a web page to give others easy access to this location, or try
</form>
</notification>
<!-- <FS:Zi> FIRE-31645 - Copy SLURL can fail, let the user know -->
<notification
icon="alertmodal.tga"
name="CopySLURLEmpty"
type="alertmodal">
There was a problem copying this SLurl. The destination region might no longer exist.
<form name="form">
<ignore name="ignore"
text="Copying a SLurl failed"/>
</form>
</notification>
<!-- </FS:Zi> -->
<notification
icon="alertmodal.tga"
name="WLSavePresetAlert"
@@ -90,7 +90,7 @@ top="0">
top_pad="1"
left="3"
width="292"
height="157"
height="145"
border_visible="true"
background_visible="true">
@@ -554,6 +554,67 @@
(requires restart)
</text>
<check_box
layout="topleft"
follows="left|top"
top_pad="3"
left="20"
width="150"
height="20"
control_name="FSAutoOrderIMTabs"
name="FSAutoOrderIMTabs"
label="Order IM tabs by type:"
tool_tip="Use automatic tab ordering for IM tabs inside the conversations floater." />
<combo_box
control_name="FSAutoOrderIMTabsPriorities"
enabled_control="FSAutoOrderIMTabs"
layout="topleft"
follows="left|top"
height="16"
left_pad="10"
top_delta="4"
name="FSAutoOrderIMTabsPriorities"
width="180">
<combo_box.item
name="group_conf_im"
label="Groups, Conferences, IMs"
value="210" />
<combo_box.item
name="group_im_conf"
label="Groups, IMs, Conferences"
value="201" />
<combo_box.item
name="conf_group_im"
label="Conferences, Groups, IMs"
value="120" />
<combo_box.item
name="conf_im_group"
label="Conferences, IMs, Groups"
value="021" />
<combo_box.item
name="im_group_conf"
label="IMs, Groups, Conferences"
value="102" />
<combo_box.item
name="im_conf_group"
label="IMs, Conferences, Groups"
value="012" />
</combo_box>
<check_box
layout="topleft"
follows="left|top"
left="30"
width="150"
height="20"
top_pad="0"
control_name="FSAutoOrderIMTabsAtTop"
name="FSAutoOrderIMTabsAtTop"
enabled_control="FSAutoOrderIMTabs"
label="Add new tabs as first"
tool_tip="Add new IM tabs as first in their chat type group." />
<text
name="FSIMTabNameFormat_label"
follows="left|top"
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<line_editor max_length_bytes="3000">
</line_editor>
<chat_editor max_length="3070">
</chat_editor>
@@ -60,6 +60,16 @@
<radio_item label="Verticale" name="radio_vertical"/>
</radio_group>
<text name="req_restart_chattabs" width="140">(Redémarrage requis)</text>
<check_box name="FSAutoOrderIMTabs" label="Trier les onglets IM par type:" tool_tip="Utilisez le classement automatique des onglets pour les onglets de messagerie instantanée dans la fenêtre flottante des conversations."/>
<combo_box name="FSAutoOrderIMTabsPriorities">
<combo_box.item name="group_conf_im" label="Groupes, Conférences, IMs" />
<combo_box.item name="group_im_conf" label="Groupes, IMs, Conférences" />
<combo_box.item name="conf_group_im" label="Conférences, Groupes, IMs" />
<combo_box.item name="conf_im_group" label="Conférences, IMs, Groupes" />
<combo_box.item name="im_group_conf" label="IMs, Groupes, Conférences" />
<combo_box.item name="im_conf_group" label="IMs, Conférences, Groupes" />
</combo_box>
<check_box name="FSAutoOrderIMTabsAtTop" label="Nouveaux onglets au début" tool_tip="Ajouter les nouveaux onglets de messagerie instantanée en tant que premiers dans leur groupe de type de chat."/>
<text name="FSIMTabNameFormat_label" width="180">Format du nom sur les onglets :</text>
<combo_box name="FSIMTabNameFormat">
<combo_box.item label="Nom d'affichage" name="display_name"/>
@@ -1883,7 +1883,7 @@ https://secondlife.com/support/downloads/
この名前は既にブロック/ミュート済みです。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CantModifyContentInNoModTask" >
<notification name="CantModifyContentInNoModTask">
あなたは、このオブジェクトの中身を修正できる権限がありません。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
@@ -2727,8 +2727,8 @@ Webページにリンクすると、他人がこの場所に簡単にアクセ
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="ChatterBoxSessionEventError">
[EVENT]
<!--[REASON]-->
[EVENT]
<!-- [REASON] -->
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="ForceCloseChatterBoxSession">
@@ -4206,7 +4206,7 @@ https://wiki.firestormviewer.org/fs_voice
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NewAONameCantExist">
の名前のアニメーションセットはすでに存在します。
すでにその名前のアニメーションセットは存在しています。
</notification>
<notification name="RemoveAOSet">
リストからAOセット「[AO_SET_NAME]」を削除してもよろしいですか?
@@ -4217,7 +4217,7 @@ https://wiki.firestormviewer.org/fs_voice
移動されたアイテムがないか、「遺失物」フォルダを確認してください。
</notification>
<notification name="AOImportSetAlreadyExists">
の名前のアニメーションセットはすでに存在します。
すでにその名前のアニメーションセットは存在しています。
</notification>
<notification name="AOImportPermissionDenied">
ノートカードを読み取るための十分な権限がありません。
@@ -4,7 +4,7 @@
<panel name="animation_overrider_panel">
<combo_box name="ao_set_selection_combo" tool_tip="編集したいアニメーションを選択してください。"/>
<button name="ao_activate" tool_tip="このアニメーションを今すぐ有効化します。"/>
<check_box name="ao_default" label="デフォルト" tool_tip="このアニメーションセットを、ログイン時に再生されるデフォルトのセットにします。"/>
<check_box name="ao_default" label="デフォルト" tool_tip="このアニメーションセットを、ログイン時に再生されるデフォルトのセットにします。デフォルトのアニメーションセットがない場合は、前回のセッションのアニメーションセットを使用します。"/>
<button name="ao_add" tool_tip="新しいアニメーションセットを追加します。"/>
<button name="ao_remove" tool_tip="このアニメーションセットを削除します。"/>
<check_box name="ao_sit_override" label="座るを上書き" tool_tip="座るアニメーションをオーバーライドする場合は、これをチェックします。"/>
@@ -82,6 +82,16 @@
<text name="req_restart_chattabs">
(要再起動)
</text>
<check_box name="FSAutoOrderIMTabs" label="IMタブを種類別に並べ替える:" tool_tip="会話フローター内のIMタブに自動タブ順序を使用します。"/>
<combo_box name="FSAutoOrderIMTabsPriorities">
<combo_box.item name="group_conf_im" label="グループ、会話、IM"/>
<combo_box.item name="group_im_conf" label="グループ、IM、会話"/>
<combo_box.item name="conf_group_im" label="会話、グループ、IM"/>
<combo_box.item name="conf_im_group" label="会話、IM、グループ"/>
<combo_box.item name="im_group_conf" label="IM、グループ、会話"/>
<combo_box.item name="im_conf_group" label="IM、会話、グループ"/>
</combo_box>
<check_box name="FSAutoOrderIMTabsAtTop" label="新しいタブを先頭に追加する" tool_tip="新しいIMタブをそのチャットタイプのグループの先頭に追加します。"/>
<text name="FSIMTabNameFormat_label">
IMタブの名前のフォーマット:
</text>
@@ -905,6 +905,9 @@ Podczas otwierania pliku w przeglądarce zabrakło pamięci. Plik może być za
<notification name="LandmarkAlreadyExists">
Posiadasz już landmark dla tej lokalizacji.
</notification>
<notification name="LandmarkLocationUnknown">
Przeglądarka nie była w stanie pobrać lokalizacji regionu. Region może być tymczasowo niedostępny lub został usunięty.
</notification>
<notification name="CannotCreateLandmarkNotOwner">
Nie możesz zapamiętać tego miejsca (LM) ponieważ właściciel działki nie pozwala na to.
</notification>
@@ -80,6 +80,16 @@
<text name="req_restart_chattabs">
(wymaga restartu)
</text>
<check_box name="FSAutoOrderIMTabs" label="Sortuj karty IM według typu:" tool_tip="Użyj automatycznego sortowania kart IM wewnątrz okna rozmów." />
<combo_box name="FSAutoOrderIMTabsPriorities">
<combo_box.item name="group_conf_im" label="Grupy, Konferencje, IM" />
<combo_box.item name="group_im_conf" label="Grupy, IM, Konferencje" />
<combo_box.item name="conf_group_im" label="Konferencje, Grupy, IM" />
<combo_box.item name="conf_im_group" label="Konferencje, IM, Grupy" />
<combo_box.item name="im_group_conf" label="IM, Grupy, Konferencje" />
<combo_box.item name="im_conf_group" label="IM, Konferencje, Grupy" />
</combo_box>
<check_box name="FSAutoOrderIMTabsAtTop" label="Nowe karty na początku" tool_tip="Dodawaj nowe karty IM jako pierwsze w swojej grupie typu czatu." />
<text name="FSIMTabNameFormat_label">
Format imion dla kart IM:
</text>
@@ -60,6 +60,16 @@
<radio_item label="垂直" name="radio_vertical" />
</radio_group>
<text name="req_restart_chattabs" width="140">(需要重新啟動)</text>
<check_box name="FSAutoOrderIMTabs" label="按類型排序私聊分頁:" tool_tip="在會話視窗內自動對私聊分頁進行排序。" />
<combo_box name="FSAutoOrderIMTabsPriorities">
<combo_box.item name="group_conf_im" label="群組、會議、私聊" />
<combo_box.item name="group_im_conf" label="群組、私聊、會議" />
<combo_box.item name="conf_group_im" label="會議、群組、私聊" />
<combo_box.item name="conf_im_group" label="會議、私聊、群組" />
<combo_box.item name="im_group_conf" label="私聊、群組、會議" />
<combo_box.item name="im_conf_group" label="私聊、會議、群組" />
</combo_box>
<check_box name="FSAutoOrderIMTabsAtTop" label="新分頁置頂" tool_tip="在對應聊天類型群組中,將新的私聊分頁新增為第一個。" />
<text name="FSIMTabNameFormat_label" width="180">索引標籤名稱格式:</text>
<combo_box name="FSIMTabNameFormat">
<combo_box.item label="顯示名" name="display_name" />