Merge branch 'master' of https://github.com/FirestormViewer/phoenix-firestorm
# Conflicts: # indra/newview/llmeshrepository.cpp # indra/newview/llviewerregion.cpp # indra/newview/llviewerregion.hmaster
commit
0360d8529a
|
|
@ -333,11 +333,21 @@ const std::string LLDiskCache::metaDataToFilepath(const LLUUID& id, LLAssetType:
|
|||
|
||||
const std::string LLDiskCache::getCacheInfo()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> add some instrumentation
|
||||
std::ostringstream cache_info;
|
||||
|
||||
F32 max_in_mb = (F32)mMaxSizeBytes / (1024.0f * 1024.0f);
|
||||
F32 percent_used = ((F32)dirFileSize(sCacheDir) / (F32)mMaxSizeBytes) * 100.0f;
|
||||
|
||||
// <FS:Beq> stall prevention. We still need to make sure this initialised when called at startup.
|
||||
F32 percent_used;
|
||||
if (mStoredCacheSize > 0)
|
||||
{
|
||||
percent_used = ((F32)mStoredCacheSize / (F32)mMaxSizeBytes) * 100.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
percent_used = ((F32)dirFileSize(sCacheDir) / (F32)mMaxSizeBytes) * 100.0f;
|
||||
}
|
||||
// </FS:Beq>
|
||||
cache_info << std::fixed;
|
||||
cache_info << std::setprecision(1);
|
||||
cache_info << "Max size " << max_in_mb << " MB ";
|
||||
|
|
|
|||
|
|
@ -113,10 +113,11 @@ class LLMessageHandlerBridge : public LLHTTPNode
|
|||
void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,
|
||||
const LLSD& context, const LLSD& input) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"];
|
||||
char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str());
|
||||
|
||||
LL_DEBUGS() << "Setting mLastSender " << input["sender"].asString() << LL_ENDL;
|
||||
LL_DEBUGS("Messaging") << "Setting mLastSender " << input["sender"].asString() << LL_ENDL;
|
||||
gMessageSystem->mLastSender = LLHost(input["sender"].asString());
|
||||
gMessageSystem->mPacketsIn += 1;
|
||||
gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]);
|
||||
|
|
@ -2050,6 +2051,7 @@ void LLMessageSystem::dispatch(
|
|||
const std::string& msg_name,
|
||||
const LLSD& message)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create();
|
||||
dispatch(msg_name, message, responsep);
|
||||
}
|
||||
|
|
@ -2060,6 +2062,7 @@ void LLMessageSystem::dispatch(
|
|||
const LLSD& message,
|
||||
LLHTTPNode::ResponsePtr responsep)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
if ((gMessageSystem->mMessageTemplates.find
|
||||
(LLMessageStringTable::getInstance()->getString(msg_name.c_str())) ==
|
||||
gMessageSystem->mMessageTemplates.end()) &&
|
||||
|
|
|
|||
|
|
@ -1651,7 +1651,19 @@ void LLTextBase::draw()
|
|||
bg_rect.intersectWith( text_rect );
|
||||
|
||||
gl_rect_2d( text_rect, bg_color, true );
|
||||
|
||||
// <FS> Additionally set the font color of highlighted text instead of using LabelTextColor
|
||||
const LLColor4& font_color = ll::ui::SearchableControl::getHighlightFontColor();
|
||||
setColor(font_color);
|
||||
// </FS>
|
||||
}
|
||||
// <FS> Set the font color back to LabelTextColor if not highlighted
|
||||
else
|
||||
{
|
||||
const LLColor4& font_color = LLUIColorTable::instance().getColor("LabelTextColor");
|
||||
setColor(font_color);
|
||||
}
|
||||
// </FS>
|
||||
|
||||
bool should_clip = mClip || mScroller != NULL;
|
||||
// <FS:Zi> Fix text bleeding at top edge of scrolling text editors
|
||||
|
|
|
|||
|
|
@ -65,7 +65,15 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv
|
|||
//Getting the version of graphics controller driver via WMI
|
||||
std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
||||
{
|
||||
std::string mDriverVersion;
|
||||
// <FS:Beq> Add caching for WMI query results
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
static auto driver_version = std::string();
|
||||
|
||||
if (!driver_version.empty())
|
||||
{
|
||||
return driver_version; // Return cached version
|
||||
}
|
||||
// </FS:Beq>
|
||||
HRESULT hres;
|
||||
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
|
||||
IWbemLocator *pLoc = NULL;
|
||||
|
|
@ -234,11 +242,11 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
|||
std::string str = ll_convert_wide_to_string(ws);
|
||||
LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL;
|
||||
|
||||
if (mDriverVersion.empty())
|
||||
if (driver_version.empty()) // <FS:Beq/> caching version (also make the varname not stupid)
|
||||
{
|
||||
mDriverVersion = str;
|
||||
driver_version = str; // <FS:Beq/> caching version (also make the varname not stupid)
|
||||
}
|
||||
else if (mDriverVersion != str)
|
||||
else if (driver_version != str) // <FS:Beq/> caching version (also make the varname not stupid)
|
||||
{
|
||||
if (vendor == GPU_ANY)
|
||||
{
|
||||
|
|
@ -274,7 +282,7 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
|||
// supposed to always call CoUninitialize even if init returned false
|
||||
CoUninitialize();
|
||||
|
||||
return mDriverVersion;
|
||||
return driver_version; // <FS:Beq/> caching version of driver query
|
||||
}
|
||||
|
||||
void get_wstring(IDxDiagContainer* containerp, const WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize)
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ set(viewer_SOURCE_FILES
|
|||
dialogstack.cpp
|
||||
exoflickr.cpp
|
||||
exoflickrauth.cpp
|
||||
fsprimfeedauth.cpp
|
||||
exogroupmutelist.cpp
|
||||
floatermedialists.cpp
|
||||
fsareasearch.cpp
|
||||
|
|
@ -164,6 +165,7 @@ set(viewer_SOURCE_FILES
|
|||
fspose.cpp
|
||||
fsposeranimator.cpp
|
||||
fsposingmotion.cpp
|
||||
fsprimfeedauth.cpp
|
||||
fsradar.cpp
|
||||
fsradarentry.cpp
|
||||
fsradarlistctrl.cpp
|
||||
|
|
@ -182,6 +184,8 @@ set(viewer_SOURCE_FILES
|
|||
lfsimfeaturehandler.cpp
|
||||
llflickrconnect.cpp
|
||||
llfloaterflickr.cpp
|
||||
fsprimfeedconnect.cpp
|
||||
fsfloaterprimfeed.cpp
|
||||
llpanelopenregionsettings.cpp
|
||||
# <FS:Ansariel> [Legacy Bake]
|
||||
llagentwearablesfetch.cpp
|
||||
|
|
@ -911,6 +915,7 @@ set(viewer_HEADER_FILES
|
|||
dialogstack.h
|
||||
exoflickr.h
|
||||
exoflickrauth.h
|
||||
fsprimfeedauth.h
|
||||
exogroupmutelist.h
|
||||
floatermedialists.h
|
||||
fsareasearch.h
|
||||
|
|
@ -982,6 +987,7 @@ set(viewer_HEADER_FILES
|
|||
fspose.h
|
||||
fsposeranimator.h
|
||||
fsposingmotion.h
|
||||
fsprimfeedauth.h
|
||||
fsradar.h
|
||||
fsradarentry.h
|
||||
fsradarlistctrl.h
|
||||
|
|
@ -1001,6 +1007,8 @@ set(viewer_HEADER_FILES
|
|||
lfsimfeaturehandler.h
|
||||
llflickrconnect.h
|
||||
llfloaterflickr.h
|
||||
fsprimfeedconnect.h
|
||||
fsfloaterprimfeed.h
|
||||
# <FS:Ansariel> [Legacy Bake]
|
||||
llagentwearablesfetch.h
|
||||
vjlocalmesh.h
|
||||
|
|
|
|||
|
|
@ -254,6 +254,16 @@
|
|||
is_running_function="Floater.IsOpen"
|
||||
is_running_parameters="flickr"
|
||||
/>
|
||||
<command name="primfeed"
|
||||
available_in_toybox="true"
|
||||
icon="Command_Primfeed_Icon"
|
||||
label_ref="Command_Primfeed_Label"
|
||||
tooltip_ref="Command_Primfeed_Tooltip"
|
||||
execute_function="Floater.Toggle"
|
||||
execute_parameters="primfeed"
|
||||
is_running_function="Floater.IsOpen"
|
||||
is_running_parameters="primfeed"
|
||||
/>
|
||||
<command name="speak"
|
||||
available_in_toybox="true"
|
||||
icon="Command_Speak_Icon"
|
||||
|
|
|
|||
|
|
@ -74,11 +74,13 @@
|
|||
<string>RenderShaderLightingMaxLevel</string>
|
||||
<string>RenderShadowDetail</string>
|
||||
<string>RenderShadowResolutionScale</string>
|
||||
<string>RenderSkyAmbientScale</string>
|
||||
<string>RenderSkyAutoAdjustAmbientScale</string>
|
||||
<string>RenderSkyAutoAdjustBlueDensityScale</string>
|
||||
<string>RenderSkyAutoAdjustBlueHorizonScale</string>
|
||||
<string>RenderSkyAutoAdjustSunColorScale</string>
|
||||
<string>RenderSkyAutoAdjustHDRScale</string>
|
||||
<string>RenderSkyAutoAdjustLegacy</string>
|
||||
<string>RenderSkyAutoAdjustProbeAmbiance</string>
|
||||
<string>RenderSkySunlightScale</string>
|
||||
<string>RenderSSAOIrradianceScale</string>
|
||||
|
|
|
|||
|
|
@ -153,6 +153,17 @@
|
|||
<key>Value</key>
|
||||
<string>http://phoenixviewer.com/app/fsdata/grids.xml</string>
|
||||
</map>
|
||||
<key>FSPrimfeedViewerApiKey</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Viewer key for API login.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>xAcXYt8SBius3Lor4wHle8L96PDHYlAZuWYXIYQUdW4b09mjhQUAwiqmWp5UNYXLpq5GSUtuKHuDYLwaueACPkew93l6MRY8jfBKSH09kv0zyGglpky07X7X7Sp4Rzin</string>
|
||||
</map>
|
||||
<key>FSGridBuilderURL</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -18584,6 +18595,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<string>world_map</string>
|
||||
<string>preferences</string>
|
||||
<string>flickr</string>
|
||||
<string>primfeed</string>
|
||||
</array>
|
||||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
|
|
@ -24760,6 +24772,39 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
<key>FSLastSnapshotToPrimfeedHeight</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The height of the last Primfeed snapshot, in px</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>768</integer>
|
||||
</map>
|
||||
<key>FSLastSnapshotToPrimfeedWidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The width of the last Primfeed snapshot, in px</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1024</integer>
|
||||
</map>
|
||||
<key>FSLastSnapshotToPrimfeedResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>At what resolution should snapshots be posted on Primfeed. 0=Current Window, 1=320x240, 2=640x480, 3=800x600, 4=1024x768, 5=1280x1024, 6=1600x1200, 7=Custom</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
<key>FSLastSnapshotToTwitterHeight</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -25046,6 +25091,19 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSNoVersionPopup</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Disables version popup on the Firestorm Login page</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSllOwnerSayToScriptDebugWindowRouting</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -26330,5 +26388,16 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSRepeatedEnvTogglesShared</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether repeated presses of sky preset shortcuts should revert to shared environment</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -1358,6 +1358,83 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPrimfeedOAuthToken</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>contains the secure authentication toke to post to your primfeed account (do not share)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>FSPrimfeedProfileLink</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The profile page for the account associated with the currently linked Primfeed account</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>FSPrimfeedPlan</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The plan type associated with the currently linked Primfeed account</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>FSPrimfeedUsername</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The username associated with the currently linked Primfeed account</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>FSPrimfeedCommercialContent</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Does this post contain commercial content</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPrimfeedAddToPublicGallery</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Should this post go to the public gallery?</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPrimfeedOpenURLOnPost</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>if true open the URL in a browser when the post completes</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSProtectedFolders</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -1369,5 +1446,49 @@
|
|||
<key>Value</key>
|
||||
<array/>
|
||||
</map>
|
||||
<key>FSPrimfeedPhotoRating</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Content rating to be shared with Primfeed.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Integer</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSPrimfeedPhotoResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Last used resolution for Primfeed photos.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array/>
|
||||
</map>
|
||||
<key>FlickrPhotoResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Last used resolution for Primfeed photos.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array/>
|
||||
</map>
|
||||
<key>FlickrPhotoRating</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Content rating to be shared with Flickr.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Integer</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ std::string BugSplatAttributes::to_xml_token(const std::string& input)
|
|||
|
||||
bool BugSplatAttributes::writeToFile(const std::string& file_path)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
|
||||
// Write to a temporary file first
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) :
|
|||
mFilterPhantom(false),
|
||||
mFilterAttachment(false),
|
||||
mFilterMoaP(false),
|
||||
mFilterReflectionProbe(false),
|
||||
mFilterDistance(false),
|
||||
mFilterDistanceMin(0),
|
||||
mFilterDistanceMax(999999),
|
||||
|
|
@ -166,6 +167,7 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) :
|
|||
mBeacons(false),
|
||||
mExcludeAttachment(true),
|
||||
mExcludeTemporary(true),
|
||||
mExcludeReflectionProbe(false),
|
||||
mExcludePhysics(true),
|
||||
mExcludeChildPrims(true),
|
||||
mExcludeNeighborRegions(true),
|
||||
|
|
@ -545,6 +547,11 @@ bool FSAreaSearch::isSearchableObject(LLViewerObject* objectp, LLViewerRegion* o
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mExcludeReflectionProbe && objectp->mReflectionProbe.notNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -908,6 +915,11 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje
|
|||
return;
|
||||
}
|
||||
|
||||
if (mFilterReflectionProbe && !objectp->mReflectionProbe.notNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Find text
|
||||
//-----------------------------------------------------------------------
|
||||
|
|
@ -2217,6 +2229,10 @@ bool FSPanelAreaSearchFilter::postBuild()
|
|||
mCheckboxExcludetemporary->set(true);
|
||||
mCheckboxExcludetemporary->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||
|
||||
mCheckboxExcludeReflectionProbes = getChild<LLCheckBoxCtrl>("exclude_reflection_probes");
|
||||
mCheckboxExcludeReflectionProbes->set(false);
|
||||
mCheckboxExcludeReflectionProbes->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||
|
||||
mCheckboxExcludeChildPrim = getChild<LLCheckBoxCtrl>("exclude_childprim");
|
||||
mCheckboxExcludeChildPrim->set(true);
|
||||
mCheckboxExcludeChildPrim->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||
|
|
@ -2240,6 +2256,9 @@ bool FSPanelAreaSearchFilter::postBuild()
|
|||
mCheckboxMoaP = getChild<LLCheckBoxCtrl>("filter_moap");
|
||||
mCheckboxMoaP->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||
|
||||
mCheckboxReflectionProbe = getChild<LLCheckBoxCtrl>("filter_reflection_probe");
|
||||
mCheckboxReflectionProbe->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||
|
||||
mCheckboxPermCopy = getChild<LLCheckBoxCtrl>("filter_perm_copy");
|
||||
mCheckboxPermCopy->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||
|
||||
|
|
@ -2262,6 +2281,7 @@ void FSPanelAreaSearchFilter::onCommitCheckbox()
|
|||
mFSAreaSearch->setFilterForSale(mCheckboxForSale->get());
|
||||
mFSAreaSearch->setFilterDistance(mCheckboxDistance->get());
|
||||
mFSAreaSearch->setFilterMoaP(mCheckboxMoaP->get());
|
||||
mFSAreaSearch->setFilterReflectionProbe(mCheckboxReflectionProbe->get());
|
||||
|
||||
if (mCheckboxExcludePhysics->get())
|
||||
{
|
||||
|
|
@ -2291,6 +2311,19 @@ void FSPanelAreaSearchFilter::onCommitCheckbox()
|
|||
}
|
||||
mFSAreaSearch->setFilterTemporary(mCheckboxTemporary->get());
|
||||
|
||||
if (mCheckboxExcludeReflectionProbes->get())
|
||||
{
|
||||
mFSAreaSearch->setFilterReflectionProbe(false);
|
||||
mCheckboxReflectionProbe->set(false);
|
||||
mCheckboxReflectionProbe->setEnabled(false);
|
||||
mFSAreaSearch->setExcludeReflectionProbe(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCheckboxReflectionProbe->setEnabled(true);
|
||||
mFSAreaSearch->setExcludeReflectionProbe(false);
|
||||
}
|
||||
|
||||
if (mCheckboxExcludeAttachment->get())
|
||||
{
|
||||
mFSAreaSearch->setFilterAttachment(false);
|
||||
|
|
|
|||
|
|
@ -141,12 +141,14 @@ public:
|
|||
void setFilterPhantom(bool b) { mFilterPhantom = b; }
|
||||
void setFilterAttachment(bool b) { mFilterAttachment = b; }
|
||||
void setFilterMoaP(bool b) { mFilterMoaP = b; }
|
||||
void setFilterReflectionProbe(bool b) { mFilterReflectionProbe = b; }
|
||||
|
||||
void setRegexSearch(bool b) { mRegexSearch = b; }
|
||||
void setBeacons(bool b) { mBeacons = b; }
|
||||
|
||||
void setExcludeAttachment(bool b) { mExcludeAttachment = b; }
|
||||
void setExcludetemporary(bool b) { mExcludeTemporary = b; }
|
||||
void setExcludeReflectionProbe(bool b) { mExcludeReflectionProbe = b; }
|
||||
void setExcludePhysics(bool b) { mExcludePhysics = b; }
|
||||
void setExcludeChildPrims(bool b) { mExcludeChildPrims = b; }
|
||||
void setExcludeNeighborRegions(bool b) { mExcludeNeighborRegions = b; }
|
||||
|
|
@ -230,6 +232,7 @@ private:
|
|||
|
||||
bool mExcludeAttachment;
|
||||
bool mExcludeTemporary;
|
||||
bool mExcludeReflectionProbe;
|
||||
bool mExcludePhysics;
|
||||
bool mExcludeChildPrims;
|
||||
bool mExcludeNeighborRegions;
|
||||
|
|
@ -240,6 +243,7 @@ private:
|
|||
bool mFilterPhantom;
|
||||
bool mFilterAttachment;
|
||||
bool mFilterMoaP;
|
||||
bool mFilterReflectionProbe;
|
||||
|
||||
bool mFilterForSale;
|
||||
S32 mFilterForSaleMin;
|
||||
|
|
@ -382,6 +386,7 @@ private:
|
|||
LLCheckBoxCtrl* mCheckboxLocked;
|
||||
LLCheckBoxCtrl* mCheckboxPhantom;
|
||||
LLCheckBoxCtrl* mCheckboxMoaP;
|
||||
LLCheckBoxCtrl* mCheckboxReflectionProbe;
|
||||
LLCheckBoxCtrl* mCheckboxDistance;
|
||||
LLSpinCtrl* mSpinDistanceMinValue;
|
||||
LLSpinCtrl* mSpinDistanceMaxValue;
|
||||
|
|
@ -393,6 +398,7 @@ private:
|
|||
LLCheckBoxCtrl* mCheckboxExcludeAttachment;
|
||||
LLCheckBoxCtrl* mCheckboxExcludePhysics;
|
||||
LLCheckBoxCtrl* mCheckboxExcludetemporary;
|
||||
LLCheckBoxCtrl* mCheckboxExcludeReflectionProbes;
|
||||
LLCheckBoxCtrl* mCheckboxExcludeChildPrim;
|
||||
LLCheckBoxCtrl* mCheckboxExcludeNeighborRegions;
|
||||
LLCheckBoxCtrl* mCheckboxPermCopy;
|
||||
|
|
|
|||
|
|
@ -1269,6 +1269,22 @@ FSFloaterIM* FSFloaterIM::show(const LLUUID& session_id)
|
|||
if (!gIMMgr->hasSession(session_id))
|
||||
return nullptr;
|
||||
|
||||
// <AS:chanayane> [FIRE-34494] fixes unable to open an IM with someone who started a group chat
|
||||
// Prevent showing non-IM sessions in FSFloaterIM::show()
|
||||
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
|
||||
if (!session || (
|
||||
IM_NOTHING_SPECIAL != session->mType
|
||||
&& IM_SESSION_P2P_INVITE != session->mType
|
||||
&& IM_SESSION_INVITE != session->mType
|
||||
&& IM_SESSION_CONFERENCE_START != session->mType
|
||||
&& IM_SESSION_GROUP_START != session->mType))
|
||||
{
|
||||
LL_WARNS("IMVIEW") << "Attempted to show FSFloaterIM for non-IM session: "
|
||||
<< (session ? std::to_string(session->mType) : "null") << LL_ENDL;
|
||||
return nullptr;
|
||||
}
|
||||
// </AS:chanayane>
|
||||
|
||||
if (!isChatMultiTab())
|
||||
{
|
||||
//hide all
|
||||
|
|
|
|||
|
|
@ -0,0 +1,912 @@
|
|||
/**
|
||||
* @file fsfloaterprimfeed.cpp
|
||||
* @brief Implementation of primfeed floater
|
||||
* @author beq@firestorm
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2025, Beq Janus
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "fsfloaterprimfeed.h"
|
||||
#include "fsprimfeedconnect.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentui.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llimagefiltersmanager.h"
|
||||
#include "llresmgr.h" // LLLocale
|
||||
#include "llsdserialize.h"
|
||||
#include "llloadingindicator.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltrans.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llsnapshotlivepreview.h"
|
||||
#include "llfloaterbigpreview.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include <boost/regex.hpp>
|
||||
#include "llspinctrl.h"
|
||||
|
||||
#include "llviewernetwork.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "fsprimfeedauth.h"
|
||||
#include "llviewernetwork.h"
|
||||
|
||||
static LLPanelInjector<FSPrimfeedPhotoPanel> t_panel_photo("fsprimfeedphotopanel");
|
||||
static LLPanelInjector<FSPrimfeedAccountPanel> t_panel_account("fsprimfeedaccountpanel");
|
||||
|
||||
///////////////////////////
|
||||
// FSPrimfeedPhotoPanel/////
|
||||
///////////////////////////
|
||||
|
||||
FSPrimfeedPhotoPanel::FSPrimfeedPhotoPanel() :
|
||||
mResolutionComboBox(nullptr),
|
||||
mRefreshBtn(nullptr),
|
||||
mWorkingLabel(nullptr),
|
||||
mThumbnailPlaceholder(nullptr),
|
||||
mDescriptionTextBox(nullptr),
|
||||
mLocationCheckbox(nullptr),
|
||||
mRatingComboBox(nullptr),
|
||||
mPostButton(nullptr),
|
||||
mBtnPreview(nullptr),
|
||||
mBigPreviewFloater(nullptr)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", [this](LLUICtrl*, const LLSD&) { onSend(); });
|
||||
mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", [this](LLUICtrl*, const LLSD&) { onClickNewSnapshot(); });
|
||||
mCommitCallbackRegistrar.add("SocialSharing.BigPreview", [this](LLUICtrl*, const LLSD&) { onClickBigPreview(); });
|
||||
mCommitCallbackRegistrar.add("Primfeed.Info",
|
||||
[](LLUICtrl*, const LLSD& param)
|
||||
{
|
||||
const std::string url = param.asString();
|
||||
LL_DEBUGS("primfeed") << "Info button clicked, opening " << url << LL_ENDL;
|
||||
LLWeb::loadURLExternal(url);
|
||||
});
|
||||
}
|
||||
|
||||
FSPrimfeedPhotoPanel::~FSPrimfeedPhotoPanel()
|
||||
{
|
||||
if (mPreviewHandle.get())
|
||||
{
|
||||
mPreviewHandle.get()->die();
|
||||
}
|
||||
|
||||
FSPrimfeedAuth::sPrimfeedAuthPump->stopListening("FSPrimfeedAccountPanel");
|
||||
|
||||
gSavedSettings.setS32("FSLastSnapshotToPrimfeedResolution", getChild<LLComboBox>("resolution_combobox")->getCurrentIndex());
|
||||
gSavedSettings.setS32("FSLastSnapshotToPrimfeedWidth", getChild<LLSpinCtrl>("custom_snapshot_width")->getValue().asInteger());
|
||||
gSavedSettings.setS32("FSLastSnapshotToPrimfeedHeight", getChild<LLSpinCtrl>("custom_snapshot_height")->getValue().asInteger());
|
||||
}
|
||||
|
||||
bool FSPrimfeedPhotoPanel::postBuild()
|
||||
{
|
||||
setVisibleCallback([this](LLUICtrl*, bool visible) { onVisibilityChange(visible); });
|
||||
|
||||
mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
|
||||
mResolutionComboBox->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||
mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
|
||||
mFilterComboBox->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||
mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
|
||||
mBtnPreview = getChild<LLButton>("big_preview_btn");
|
||||
mWorkingLabel = getChild<LLUICtrl>("working_lbl");
|
||||
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
|
||||
mDescriptionTextBox = getChild<LLUICtrl>("photo_description");
|
||||
mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
|
||||
mCommercialCheckbox = getChild<LLUICtrl>("primfeed_commercial_content");
|
||||
mPublicGalleryCheckbox = getChild<LLUICtrl>("primfeed_add_to_public_gallery");
|
||||
mRatingComboBox = getChild<LLUICtrl>("rating_combobox");
|
||||
mPostButton = getChild<LLUICtrl>("post_photo_btn");
|
||||
mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
|
||||
mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
|
||||
|
||||
// Update custom resolution controls with lambdas
|
||||
getChild<LLSpinCtrl>("custom_snapshot_width")->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||
getChild<LLSpinCtrl>("custom_snapshot_height")->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||
getChild<LLCheckBoxCtrl>("keep_aspect_ratio")->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||
|
||||
getChild<LLComboBox>("resolution_combobox")->setCurrentByIndex(gSavedSettings.getS32("FSLastSnapshotToPrimfeedResolution"));
|
||||
getChild<LLSpinCtrl>("custom_snapshot_width")->setValue(gSavedSettings.getS32("FSLastSnapshotToPrimfeedWidth"));
|
||||
getChild<LLSpinCtrl>("custom_snapshot_height")->setValue(gSavedSettings.getS32("FSLastSnapshotToPrimfeedHeight"));
|
||||
|
||||
// Update filter list
|
||||
std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
|
||||
auto* filterbox = static_cast<LLComboBox*>(mFilterComboBox);
|
||||
for (const std::string& filter : filter_list)
|
||||
{
|
||||
filterbox->add(filter);
|
||||
}
|
||||
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
// static
|
||||
void FSFloaterPrimfeed::update()
|
||||
{
|
||||
if (LLFloaterReg::instanceVisible("primfeed"))
|
||||
{
|
||||
LLFloaterSnapshotBase::ImplBase::updatePreviewList(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
S32 FSPrimfeedPhotoPanel::notify(const LLSD& info)
|
||||
{
|
||||
if (info.has("snapshot-updating"))
|
||||
{
|
||||
// Disable the Post button and whatever else while the snapshot is not updated
|
||||
// updateControls();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info.has("snapshot-updated"))
|
||||
{
|
||||
// Enable the send/post/save buttons.
|
||||
updateControls();
|
||||
|
||||
// The refresh button is initially hidden. We show it after the first update,
|
||||
// i.e. after snapshot is taken
|
||||
|
||||
if (LLUICtrl* refresh_button = getRefreshBtn(); !refresh_button->getVisible())
|
||||
{
|
||||
refresh_button->setVisible(true);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::draw()
|
||||
{
|
||||
auto previewp = static_cast<const LLSnapshotLivePreview*>(mPreviewHandle.get());
|
||||
|
||||
// Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
|
||||
auto can_post = !(FSPrimfeedConnect::instance().isTransactionOngoing()) && FSPrimfeedAuth::isAuthorized();
|
||||
|
||||
mCancelButton->setEnabled(can_post);
|
||||
mDescriptionTextBox->setEnabled(can_post);
|
||||
mRatingComboBox->setEnabled(can_post);
|
||||
mResolutionComboBox->setEnabled(can_post);
|
||||
mFilterComboBox->setEnabled(can_post);
|
||||
mRefreshBtn->setEnabled(can_post);
|
||||
mBtnPreview->setEnabled(can_post);
|
||||
mLocationCheckbox->setEnabled(can_post);
|
||||
mPublicGalleryCheckbox->setEnabled(can_post);
|
||||
mCommercialCheckbox->setEnabled(can_post);
|
||||
|
||||
// Reassign the preview floater if we have the focus and the preview exists
|
||||
if (hasFocus() && isPreviewVisible())
|
||||
{
|
||||
attachPreview();
|
||||
}
|
||||
|
||||
// Toggle the button state as appropriate
|
||||
bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
|
||||
mBtnPreview->setToggleState(preview_active);
|
||||
|
||||
// Display the preview if one is available
|
||||
if (previewp && previewp->getThumbnailImage())
|
||||
{
|
||||
const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
|
||||
const S32 thumbnail_w = previewp->getThumbnailWidth();
|
||||
const S32 thumbnail_h = previewp->getThumbnailHeight();
|
||||
|
||||
// calc preview offset within the preview rect
|
||||
const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2;
|
||||
const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2;
|
||||
S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
|
||||
S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
|
||||
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
// Apply floater transparency to the texture unless the floater is focused.
|
||||
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
LLColor4 color = LLColor4::white;
|
||||
gl_draw_scaled_image(offset_x, offset_y, thumbnail_w, thumbnail_h, previewp->getThumbnailImage(), color % alpha);
|
||||
}
|
||||
|
||||
// Update the visibility of the working (computing preview) label
|
||||
mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
|
||||
|
||||
// Enable Post if we have a preview to send and no on going connection being processed
|
||||
mPostButton->setEnabled(can_post && (previewp && previewp->getSnapshotUpToDate()));
|
||||
|
||||
// Draw the rest of the panel on top of it
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
LLSnapshotLivePreview* FSPrimfeedPhotoPanel::getPreviewView()
|
||||
{
|
||||
auto previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
|
||||
return previewp;
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::onVisibilityChange(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
if (mPreviewHandle.get())
|
||||
{
|
||||
LLSnapshotLivePreview* preview = getPreviewView();
|
||||
if (preview)
|
||||
{
|
||||
LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
|
||||
preview->updateSnapshot(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLRect full_screen_rect = getRootView()->getRect();
|
||||
LLSnapshotLivePreview::Params p;
|
||||
p.rect(full_screen_rect);
|
||||
auto previewp = new LLSnapshotLivePreview(p);
|
||||
mPreviewHandle = previewp->getHandle();
|
||||
|
||||
previewp->setContainer(this);
|
||||
previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
|
||||
previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
|
||||
previewp->setThumbnailSubsampled(true); // We want the preview to reflect the *saved* image
|
||||
previewp->setAllowRenderUI(false); // We do not want the rendered UI in our snapshots
|
||||
previewp->setAllowFullScreenPreview(false); // No full screen preview in SL Share mode
|
||||
previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
|
||||
|
||||
updateControls();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::onClickNewSnapshot()
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
previewp->updateSnapshot(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::onClickBigPreview()
|
||||
{
|
||||
// Toggle the preview
|
||||
if (isPreviewVisible())
|
||||
{
|
||||
LLFloaterReg::hideInstance("big_preview");
|
||||
}
|
||||
else
|
||||
{
|
||||
attachPreview();
|
||||
LLFloaterReg::showInstance("big_preview");
|
||||
}
|
||||
}
|
||||
|
||||
bool FSPrimfeedPhotoPanel::isPreviewVisible() const
|
||||
{
|
||||
return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::attachPreview()
|
||||
{
|
||||
if (mBigPreviewFloater)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
mBigPreviewFloater->setPreview(previewp);
|
||||
mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::onSend()
|
||||
{
|
||||
sendPhoto();
|
||||
}
|
||||
|
||||
bool FSPrimfeedPhotoPanel::onPrimfeedConnectStateChange(const LLSD& /*data*/)
|
||||
{
|
||||
if (FSPrimfeedAuth::isAuthorized())
|
||||
{
|
||||
sendPhoto();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::sendPhoto()
|
||||
{
|
||||
auto ratingToString = [&](int rating)
|
||||
{
|
||||
static const std::array<std::string, 4> RATING_NAMES = {
|
||||
"general", // 1
|
||||
"moderate", // 2
|
||||
"adult", // 3
|
||||
"adult_plus" // 4
|
||||
};
|
||||
|
||||
// clamp into [1,4]
|
||||
int idx = llclamp(rating, 1, 4) - 1;
|
||||
return RATING_NAMES[idx];
|
||||
};
|
||||
// Get the description (primfeed has no title/tags etc at this point)
|
||||
std::string description = mDescriptionTextBox->getValue().asString();
|
||||
|
||||
// Get the content rating
|
||||
int content_rating = mRatingComboBox->getValue().asInteger();
|
||||
bool post_to_public_gallery = mPublicGalleryCheckbox->getValue().asBoolean();
|
||||
bool commercial_content = mCommercialCheckbox->getValue().asBoolean();
|
||||
|
||||
// Get the image
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POSTING);
|
||||
LLSD params;
|
||||
params["rating"] = ratingToString(content_rating);
|
||||
params["content"] = description;
|
||||
params["is_commercial"] = commercial_content;
|
||||
params["post_to_public_gallery"] = post_to_public_gallery;
|
||||
// Add the location if required
|
||||
|
||||
if (bool add_location = mLocationCheckbox->getValue().asBoolean(); add_location)
|
||||
{
|
||||
// Get the SLURL for the location
|
||||
LLSLURL slurl;
|
||||
LLAgentUI::buildSLURL(slurl);
|
||||
std::string slurl_string = slurl.getSLURLString();
|
||||
|
||||
params["location"] = slurl_string;
|
||||
}
|
||||
|
||||
FSPrimfeedConnect::instance().uploadPhoto(params, previewp->getFormattedImage().get(),
|
||||
[this](bool success, const std::string& url)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POSTED);
|
||||
static LLCachedControl<bool> open_url_on_post(gSavedPerAccountSettings,
|
||||
"FSPrimfeedOpenURLOnPost", true);
|
||||
if (open_url_on_post)
|
||||
{
|
||||
LLWeb::loadURLExternal(url);
|
||||
}
|
||||
LLSD args;
|
||||
args["PF_POSTURL"] = url;
|
||||
LLNotificationsUtil::add("FSPrimfeedUploadComplete", args);
|
||||
}
|
||||
else
|
||||
{
|
||||
mWorkingLabel->setValue("Error posting to Primfeed");
|
||||
mPostButton->setEnabled(true);
|
||||
}
|
||||
});
|
||||
updateControls();
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::clearAndClose()
|
||||
{
|
||||
mDescriptionTextBox->setValue("");
|
||||
|
||||
if (LLFloater* floater = getParentByType<LLFloater>())
|
||||
{
|
||||
floater->closeFloater();
|
||||
if (mBigPreviewFloater)
|
||||
{
|
||||
mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::updateControls()
|
||||
{
|
||||
// LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
updateResolution(false);
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::updateResolution(bool do_update)
|
||||
{
|
||||
auto combobox = static_cast<LLComboBox*>(mResolutionComboBox);
|
||||
auto filterbox = static_cast<LLComboBox*>(mFilterComboBox);
|
||||
|
||||
std::string sdstring = combobox->getSelectedValue();
|
||||
LLSD sdres;
|
||||
std::stringstream sstream(sdstring);
|
||||
LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
|
||||
|
||||
S32 width = sdres[0];
|
||||
S32 height = sdres[1];
|
||||
|
||||
// Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
|
||||
std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
|
||||
|
||||
if (auto previewp = static_cast<LLSnapshotLivePreview*>(mPreviewHandle.get()); previewp && combobox->getCurrentIndex() >= 0)
|
||||
{
|
||||
checkAspectRatio(width);
|
||||
|
||||
S32 original_width = 0;
|
||||
S32 original_height = 0;
|
||||
previewp->getSize(original_width, original_height);
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
// take resolution from current window size
|
||||
LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x"
|
||||
<< gViewerWindow->getWindowHeightRaw() << LL_ENDL;
|
||||
previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
|
||||
}
|
||||
else if (width == -1 || height == -1)
|
||||
{
|
||||
// take resolution from custom size
|
||||
LLSpinCtrl* width_spinner = getChild<LLSpinCtrl>("custom_snapshot_width");
|
||||
LLSpinCtrl* height_spinner = getChild<LLSpinCtrl>("custom_snapshot_height");
|
||||
S32 custom_width = width_spinner->getValue().asInteger();
|
||||
S32 custom_height = height_spinner->getValue().asInteger();
|
||||
if (checkImageSize(previewp, custom_width, custom_height, true, previewp->getMaxImageSize()))
|
||||
{
|
||||
width_spinner->set((F32)custom_width);
|
||||
height_spinner->set((F32)custom_height);
|
||||
}
|
||||
LL_DEBUGS() << "Setting preview res from custom: " << custom_width << "x" << custom_height << LL_ENDL;
|
||||
previewp->setSize(custom_width, custom_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the resolution from the selected pre-canned drop-down choice
|
||||
LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
|
||||
previewp->setSize(width, height);
|
||||
}
|
||||
|
||||
previewp->getSize(width, height);
|
||||
if ((original_width != width) || (original_height != height))
|
||||
{
|
||||
previewp->setSize(width, height);
|
||||
if (do_update)
|
||||
{
|
||||
previewp->updateSnapshot(true, true);
|
||||
updateControls();
|
||||
}
|
||||
}
|
||||
// Get the old filter, compare to the current one "filter_name" and set if changed
|
||||
std::string original_filter = previewp->getFilter();
|
||||
if (original_filter != filter_name)
|
||||
{
|
||||
previewp->setFilter(filter_name);
|
||||
if (do_update)
|
||||
{
|
||||
previewp->updateSnapshot(false, true);
|
||||
updateControls();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool custom_resolution = static_cast<LLComboBox*>(mResolutionComboBox)->getSelectedValue().asString() == "[i-1,i-1]";
|
||||
getChild<LLSpinCtrl>("custom_snapshot_width")->setEnabled(custom_resolution);
|
||||
getChild<LLSpinCtrl>("custom_snapshot_height")->setEnabled(custom_resolution);
|
||||
getChild<LLCheckBoxCtrl>("keep_aspect_ratio")->setEnabled(custom_resolution);
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::checkAspectRatio(S32 index)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
|
||||
bool keep_aspect = false;
|
||||
|
||||
if (0 == index) // current window size
|
||||
{
|
||||
keep_aspect = true;
|
||||
}
|
||||
else if (-1 == index)
|
||||
{
|
||||
keep_aspect = getChild<LLCheckBoxCtrl>("keep_aspect_ratio")->get();
|
||||
}
|
||||
else // predefined resolution
|
||||
{
|
||||
keep_aspect = false;
|
||||
}
|
||||
|
||||
if (previewp)
|
||||
{
|
||||
previewp->mKeepAspectRatio = keep_aspect;
|
||||
}
|
||||
}
|
||||
|
||||
LLUICtrl* FSPrimfeedPhotoPanel::getRefreshBtn()
|
||||
{
|
||||
return mRefreshBtn;
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::onOpen(const LLSD& key)
|
||||
{
|
||||
if (!FSPrimfeedAuth::isAuthorized())
|
||||
{
|
||||
// Reauthorise if necessary.
|
||||
FSPrimfeedAuth::initiateAuthRequest();
|
||||
LLSD dummy;
|
||||
onPrimfeedConnectStateChange(dummy);
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::uploadCallback(bool success, const LLSD& response)
|
||||
{
|
||||
LLSD args;
|
||||
if (success && response["stat"].asString() == "ok")
|
||||
{
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POSTED);
|
||||
args["PF_POSTURL"] = response["postUrl"];
|
||||
LLNotificationsUtil::add("FSPrimfeedUploadComplete", args);
|
||||
}
|
||||
else
|
||||
{
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POST_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedPhotoPanel::primfeedAuthResponse(bool success, const LLSD& response)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
if (response.has("status") && response["status"].asString() == "reset")
|
||||
{
|
||||
LL_INFOS("Primfeed") << "Primfeed authorization has been reset." << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Complain about failed auth here.
|
||||
LL_WARNS("Primfeed") << "Primfeed authentication failed." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
onPrimfeedConnectStateChange(response);
|
||||
}
|
||||
|
||||
bool FSPrimfeedPhotoPanel::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, bool isWidthChanged, S32 max_value)
|
||||
{
|
||||
S32 w = width;
|
||||
S32 h = height;
|
||||
|
||||
if (previewp && previewp->mKeepAspectRatio)
|
||||
{
|
||||
if (gViewerWindow->getWindowWidthRaw() < 1 || gViewerWindow->getWindowHeightRaw() < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// aspect ratio of the current window
|
||||
F32 aspect_ratio = static_cast<F32>(gViewerWindow->getWindowWidthRaw()) / static_cast<F32>(gViewerWindow->getWindowHeightRaw());
|
||||
|
||||
// change another value proportionally
|
||||
if (isWidthChanged)
|
||||
{
|
||||
height = ll_round(static_cast<F32>(width) / aspect_ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = ll_round(static_cast<F32>(height) * aspect_ratio);
|
||||
}
|
||||
|
||||
// bound w/h by the max_value
|
||||
if (width > max_value || height > max_value)
|
||||
{
|
||||
if (width > height)
|
||||
{
|
||||
width = max_value;
|
||||
height = ll_round(static_cast<F32>(width) / aspect_ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
height = max_value;
|
||||
width = ll_round(static_cast<F32>(height) * aspect_ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (w != width || h != height);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// FSPrimfeedAccountPanel///
|
||||
///////////////////////////
|
||||
|
||||
FSPrimfeedAccountPanel::FSPrimfeedAccountPanel() :
|
||||
mAccountConnectedAsLabel(nullptr),
|
||||
mAccountNameLink(nullptr),
|
||||
mAccountPlan(nullptr),
|
||||
mPanelButtons(nullptr),
|
||||
mConnectButton(nullptr),
|
||||
mDisconnectButton(nullptr)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("SocialSharing.Connect", [this](LLUICtrl*, const LLSD&) { onConnect(); });
|
||||
mCommitCallbackRegistrar.add("SocialSharing.Disconnect", [this](LLUICtrl*, const LLSD&) { onDisconnect(); });
|
||||
|
||||
FSPrimfeedAuth::sPrimfeedAuthPump->listen("FSPrimfeedAccountPanel",
|
||||
[this](const LLSD& data)
|
||||
{
|
||||
bool success = data["success"].asBoolean();
|
||||
primfeedAuthResponse(success, data);
|
||||
return true;
|
||||
});
|
||||
|
||||
setVisibleCallback([this](LLUICtrl*, bool visible) { onVisibilityChange(visible); });
|
||||
}
|
||||
|
||||
bool FSPrimfeedAccountPanel::postBuild()
|
||||
{
|
||||
mAccountConnectedAsLabel = getChild<LLTextBox>("connected_as_label");
|
||||
mAccountNameLink = getChild<LLTextBox>("primfeed_account_name");
|
||||
mAccountPlan = getChild<LLTextBox>("primfeed_account_plan");
|
||||
mPanelButtons = getChild<LLUICtrl>("panel_buttons");
|
||||
mConnectButton = getChild<LLUICtrl>("connect_btn");
|
||||
mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
|
||||
|
||||
LLSD dummy;
|
||||
onPrimfeedConnectStateChange(dummy);
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::draw()
|
||||
{
|
||||
FSPrimfeedConnect::EConnectionState connection_state = FSPrimfeedConnect::instance().getConnectionState();
|
||||
static FSPrimfeedConnect::EConnectionState last_state = FSPrimfeedConnect::PRIMFEED_DISCONNECTED;
|
||||
|
||||
// Update the connection state if it has changed
|
||||
if (connection_state != last_state)
|
||||
{
|
||||
onPrimfeedConnectStateChange(LLSD());
|
||||
last_state = connection_state;
|
||||
}
|
||||
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::primfeedAuthResponse(bool success, const LLSD& response)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
LL_WARNS("Primfeed") << "Primfeed authentication failed." << LL_ENDL;
|
||||
LLWeb::loadURLExternal("https://www.primfeed.com/login");
|
||||
}
|
||||
onPrimfeedConnectStateChange(response);
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::onVisibilityChange(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
// Connected
|
||||
if (FSPrimfeedAuth::isAuthorized())
|
||||
{
|
||||
showConnectedLayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
showDisconnectedLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FSPrimfeedAccountPanel::onPrimfeedConnectStateChange(const LLSD&)
|
||||
{
|
||||
if (FSPrimfeedAuth::isAuthorized() || FSPrimfeedConnect::instance().getConnectionState() == FSPrimfeedConnect::PRIMFEED_CONNECTING)
|
||||
{
|
||||
showConnectedLayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
showDisconnectedLayout();
|
||||
}
|
||||
onPrimfeedConnectInfoChange();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FSPrimfeedAccountPanel::onPrimfeedConnectInfoChange()
|
||||
{
|
||||
std::string clickable_name{ "" };
|
||||
|
||||
static LLCachedControl<std::string> primfeed_username(gSavedPerAccountSettings, "FSPrimfeedUsername");
|
||||
static LLCachedControl<std::string> primfeed_profile_link(gSavedPerAccountSettings, "FSPrimfeedProfileLink");
|
||||
static LLCachedControl<std::string> primfeed_plan(gSavedPerAccountSettings, "FSPrimfeedPlan");
|
||||
|
||||
// Strings of format [http://www.somewebsite.com Click Me] become clickable text
|
||||
if (!primfeed_username().empty())
|
||||
{
|
||||
clickable_name = std::string("[") + std::string(primfeed_profile_link) + " " + std::string(primfeed_username) + "]";
|
||||
}
|
||||
|
||||
mAccountNameLink->setText(clickable_name);
|
||||
mAccountPlan->setText(primfeed_plan());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::showConnectButton()
|
||||
{
|
||||
if (!mConnectButton->getVisible())
|
||||
{
|
||||
mConnectButton->setVisible(true);
|
||||
mDisconnectButton->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::hideConnectButton()
|
||||
{
|
||||
if (mConnectButton->getVisible())
|
||||
{
|
||||
mConnectButton->setVisible(false);
|
||||
mDisconnectButton->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::showDisconnectedLayout()
|
||||
{
|
||||
mAccountConnectedAsLabel->setText(getString("primfeed_disconnected"));
|
||||
mAccountNameLink->setText(std::string(""));
|
||||
mAccountPlan->setText(getString("primfeed_plan_unknown"));
|
||||
showConnectButton();
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::showConnectedLayout()
|
||||
{
|
||||
mAccountConnectedAsLabel->setText(getString("primfeed_connected"));
|
||||
hideConnectButton();
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::onConnect()
|
||||
{
|
||||
FSPrimfeedAuth::initiateAuthRequest();
|
||||
LLSD dummy;
|
||||
onPrimfeedConnectStateChange(dummy);
|
||||
}
|
||||
|
||||
void FSPrimfeedAccountPanel::onDisconnect()
|
||||
{
|
||||
FSPrimfeedAuth::resetAuthStatus();
|
||||
LLSD dummy;
|
||||
onPrimfeedConnectStateChange(dummy);
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// FSFloaterPrimfeed/////
|
||||
////////////////////////
|
||||
|
||||
FSFloaterPrimfeed::FSFloaterPrimfeed(const LLSD& key) :
|
||||
LLFloater(key),
|
||||
mPrimfeedPhotoPanel(nullptr),
|
||||
mStatusErrorText(nullptr),
|
||||
mStatusLoadingText(nullptr),
|
||||
mStatusLoadingIndicator(nullptr),
|
||||
mPrimfeedAccountPanel(nullptr)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("SocialSharing.Cancel", [this](LLUICtrl*, const LLSD&) { onCancel(); });
|
||||
}
|
||||
|
||||
void FSFloaterPrimfeed::onClose(bool app_quitting)
|
||||
{
|
||||
if (auto big_preview_floater = LLFloaterReg::getTypedInstance<LLFloaterBigPreview>("big_preview"))
|
||||
{
|
||||
big_preview_floater->closeOnFloaterOwnerClosing(this);
|
||||
}
|
||||
LLFloater::onClose(app_quitting);
|
||||
}
|
||||
|
||||
void FSFloaterPrimfeed::onCancel()
|
||||
{
|
||||
if (auto big_preview_floater = LLFloaterReg::getTypedInstance<LLFloaterBigPreview>("big_preview"))
|
||||
{
|
||||
big_preview_floater->closeOnFloaterOwnerClosing(this);
|
||||
}
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
bool FSFloaterPrimfeed::postBuild()
|
||||
{
|
||||
// Keep tab of the Photo Panel
|
||||
mPrimfeedPhotoPanel = static_cast<FSPrimfeedPhotoPanel*>(getChild<LLUICtrl>("panel_primfeed_photo"));
|
||||
mPrimfeedAccountPanel = static_cast<FSPrimfeedAccountPanel*>(getChild<LLUICtrl>("panel_primfeed_account"));
|
||||
// Connection status widgets
|
||||
mStatusErrorText = getChild<LLTextBox>("connection_error_text");
|
||||
mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
|
||||
mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
|
||||
|
||||
return LLFloater::postBuild();
|
||||
}
|
||||
|
||||
void FSFloaterPrimfeed::showPhotoPanel()
|
||||
{
|
||||
auto parent = dynamic_cast<LLTabContainer*>(mPrimfeedPhotoPanel->getParent());
|
||||
if (!parent)
|
||||
{
|
||||
LL_WARNS() << "Cannot find panel container" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
parent->selectTabPanel(mPrimfeedPhotoPanel);
|
||||
}
|
||||
|
||||
void FSFloaterPrimfeed::draw()
|
||||
{
|
||||
if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
|
||||
{
|
||||
mStatusErrorText->setVisible(false);
|
||||
mStatusLoadingText->setVisible(false);
|
||||
mStatusLoadingIndicator->setVisible(false);
|
||||
|
||||
FSPrimfeedConnect::EConnectionState connection_state = FSPrimfeedConnect::instance().getConnectionState();
|
||||
std::string status_text;
|
||||
|
||||
if (FSPrimfeedAuth::isAuthorized())
|
||||
{
|
||||
switch (connection_state)
|
||||
{
|
||||
case FSPrimfeedConnect::PRIMFEED_POSTING:
|
||||
{
|
||||
// Posting indicator
|
||||
mStatusLoadingText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialPrimfeedPosting");
|
||||
mStatusLoadingText->setValue(status_text);
|
||||
mStatusLoadingIndicator->setVisible(true);
|
||||
break;
|
||||
}
|
||||
case FSPrimfeedConnect::PRIMFEED_POST_FAILED:
|
||||
{
|
||||
// Error posting to the service
|
||||
mStatusErrorText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialPrimfeedErrorPosting");
|
||||
mStatusErrorText->setValue(status_text);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// LL_WARNS("Prmfeed") << "unexpected state" << connection_state << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (FSPrimfeedAuth::isPendingAuth())
|
||||
{
|
||||
// Show the status text when authorisation is pending
|
||||
mStatusLoadingText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialPrimfeedConnecting");
|
||||
mStatusLoadingText->setValue(status_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show the status text when not authorised
|
||||
mStatusErrorText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialPrimfeedNotAuthorized");
|
||||
mStatusErrorText->setValue(status_text);
|
||||
}
|
||||
}
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void FSFloaterPrimfeed::onOpen(const LLSD& key)
|
||||
{
|
||||
mPrimfeedPhotoPanel->onOpen(key);
|
||||
}
|
||||
|
||||
LLSnapshotLivePreview* FSFloaterPrimfeed::getPreviewView()
|
||||
{
|
||||
if (mPrimfeedPhotoPanel)
|
||||
{
|
||||
return mPrimfeedPhotoPanel->getPreviewView();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* @file fsfloaterprimfeed.cpp
|
||||
* @brief Declaration of primfeed floater
|
||||
* @author beq@firestorm
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2025, Beq Janus
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef FS_FLOATERPRIMFEED_H
|
||||
#define FS_FLOATERPRIMFEED_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
class LLIconCtrl;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLSnapshotLivePreview;
|
||||
class LLFloaterBigPreview;
|
||||
|
||||
/*
|
||||
* (TODO) Beq: Refactor this with Flickr
|
||||
* Primfeed floater is copied heavily from the LLFlaoterFlickr class and deliberately implemetns much of the underlying plumbinng into the connector class.
|
||||
* Once this is bedded in and any initial issues are addressed, it would be sensible to refactor both the flickr and primfeed classes to share a common base.
|
||||
* In particular a ref counted test for the livepreview would eliminate the need for the static update method in the app mainloop.
|
||||
*/
|
||||
class FSPrimfeedPhotoPanel : public LLPanel
|
||||
{
|
||||
public:
|
||||
FSPrimfeedPhotoPanel();
|
||||
~FSPrimfeedPhotoPanel();
|
||||
|
||||
bool postBuild() override;
|
||||
S32 notify(const LLSD& info);
|
||||
void draw() override;
|
||||
|
||||
LLSnapshotLivePreview* getPreviewView();
|
||||
void onVisibilityChange(bool new_visibility);
|
||||
void onClickNewSnapshot();
|
||||
void onClickBigPreview();
|
||||
void onSend();
|
||||
bool onPrimfeedConnectStateChange(const LLSD& data);
|
||||
|
||||
void sendPhoto();
|
||||
void clearAndClose();
|
||||
|
||||
void updateControls();
|
||||
void updateResolution(bool do_update);
|
||||
void checkAspectRatio(S32 index);
|
||||
LLUICtrl* getRefreshBtn();
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
void primfeedAuthResponse(bool success, const LLSD& response);
|
||||
void uploadCallback(bool success, const LLSD& response);
|
||||
|
||||
private:
|
||||
bool isPreviewVisible() const;
|
||||
void attachPreview();
|
||||
|
||||
bool checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, bool isWidthChanged, S32 max_value);
|
||||
|
||||
LLHandle<LLView> mPreviewHandle;
|
||||
|
||||
LLUICtrl * mResolutionComboBox;
|
||||
LLUICtrl * mFilterComboBox;
|
||||
LLUICtrl * mRefreshBtn;
|
||||
LLUICtrl * mWorkingLabel;
|
||||
LLUICtrl * mThumbnailPlaceholder;
|
||||
LLUICtrl * mDescriptionTextBox;
|
||||
LLUICtrl * mLocationCheckbox;
|
||||
|
||||
LLUICtrl * mCommercialCheckbox;
|
||||
LLUICtrl * mPublicGalleryCheckbox;
|
||||
LLUICtrl * mRatingComboBox;
|
||||
LLUICtrl * mPostButton;
|
||||
LLUICtrl * mCancelButton;
|
||||
LLButton * mBtnPreview;
|
||||
|
||||
LLFloaterBigPreview * mBigPreviewFloater;
|
||||
};
|
||||
|
||||
class FSPrimfeedAccountPanel : public LLPanel
|
||||
{
|
||||
public:
|
||||
FSPrimfeedAccountPanel();
|
||||
bool postBuild() override;
|
||||
void draw() override;
|
||||
|
||||
private:
|
||||
void onVisibilityChange(bool new_visibility);
|
||||
void primfeedAuthResponse(bool success, const LLSD& response);
|
||||
bool onPrimfeedConnectStateChange(const LLSD& data);
|
||||
bool onPrimfeedConnectInfoChange();
|
||||
void onConnect();
|
||||
void onDisconnect();
|
||||
|
||||
void showConnectButton();
|
||||
void hideConnectButton();
|
||||
void showDisconnectedLayout();
|
||||
void showConnectedLayout();
|
||||
|
||||
LLTextBox* mAccountConnectedAsLabel;
|
||||
LLTextBox* mAccountNameLink;
|
||||
LLTextBox* mAccountPlan;
|
||||
LLUICtrl* mPanelButtons;
|
||||
LLUICtrl* mConnectButton;
|
||||
LLUICtrl* mDisconnectButton;
|
||||
};
|
||||
|
||||
|
||||
class FSFloaterPrimfeed : public LLFloater
|
||||
{
|
||||
public:
|
||||
explicit FSFloaterPrimfeed(const LLSD& key);
|
||||
static void update();
|
||||
bool postBuild() override;
|
||||
void draw() override;
|
||||
void onClose(bool app_quitting) override;
|
||||
void onCancel();
|
||||
|
||||
void showPhotoPanel();
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
LLSnapshotLivePreview* getPreviewView();
|
||||
|
||||
private:
|
||||
FSPrimfeedPhotoPanel* mPrimfeedPhotoPanel;
|
||||
FSPrimfeedAccountPanel* mPrimfeedAccountPanel;
|
||||
LLTextBox* mStatusErrorText;
|
||||
LLTextBox* mStatusLoadingText;
|
||||
LLUICtrl* mStatusLoadingIndicator;
|
||||
};
|
||||
|
||||
#endif // LL_FSFLOATERPRIMFEED_H
|
||||
|
||||
|
|
@ -923,6 +923,12 @@ void FSPanelLogin::loadLoginPage()
|
|||
// login page (web) content version
|
||||
params["login_content_version"] = gSavedSettings.getString("LoginContentVersion");
|
||||
|
||||
// No version popup
|
||||
if (gSavedSettings.getBOOL("FSNoVersionPopup"))
|
||||
{
|
||||
params["noversionpopup"] = "true";
|
||||
}
|
||||
|
||||
// Make an LLURI with this augmented info
|
||||
std::string url = login_page.scheme().empty()? login_page.authority() : login_page.scheme() + "://" + login_page.authority();
|
||||
LLURI login_uri(LLURI::buildHTTP(url,
|
||||
|
|
|
|||
|
|
@ -190,18 +190,18 @@ public:
|
|||
/// <summary>
|
||||
/// An ordered list of poser joints, clustered by body-area.
|
||||
/// Order is based on ease-of-use.
|
||||
/// Not necessarily exhaustive, just the joints we care to edit without adding UI clutter.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For an implementation of something other than LLJoints, different name(s) may be required.
|
||||
/// A bvhEndSiteValue is only required if the bone has no descendants.
|
||||
/// </remarks>
|
||||
const std::vector<FSPoserJoint> PoserJoints{
|
||||
// head, torso, legs
|
||||
{ "mHead", "", BODY, { "mEyeLeft", "mEyeRight", "mFaceRoot" }, "0.000 0.076 0.000" },
|
||||
{ "mHead", "", BODY, { "mEyeLeft", "mEyeRight", "mFaceRoot", "mSkull" }, "0.000 0.076 0.000" },
|
||||
{ "mNeck", "", BODY, { "mHead" }, "0.000 0.251 -0.010" },
|
||||
{ "mPelvis", "", WHOLEAVATAR, { "mTorso", "mHipLeft", "mHipRight", "mTail1", "mGroin", "mHindLimbsRoot" }, "0.000000 0.000000 0.000000" },
|
||||
{ "mPelvis", "", WHOLEAVATAR, { "mSpine1", "mHipLeft", "mHipRight", "mTail1", "mGroin", "mHindLimbsRoot" }, "0.000000 0.000000 0.000000" },
|
||||
{ "mChest", "", BODY, { "mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot" }, "0.000 0.205 -0.015" },
|
||||
{ "mTorso", "", BODY, { "mChest" }, "0.000 0.084 0.000" },
|
||||
{ "mTorso", "", BODY, { "mSpine3" }, "0.000 0.084 0.000" },
|
||||
{ "mCollarLeft", "mCollarRight", BODY, { "mShoulderLeft" }, "0.085 0.165 -0.021" },
|
||||
{ "mShoulderLeft", "mShoulderRight", BODY, { "mElbowLeft" }, "0.079 0.000 0.000" },
|
||||
{ "mElbowLeft", "mElbowRight", BODY, { "mWristLeft" }, "0.248 0.000 0.000" },
|
||||
|
|
@ -212,10 +212,12 @@ public:
|
|||
{ "mWristRight", "mWristLeft", BODY, { "mHandThumb1Right", "mHandIndex1Right", "mHandMiddle1Right", "mHandRing1Right", "mHandPinky1Right" }, "-0.205 0.000 0.000", "", true },
|
||||
{ "mHipLeft", "mHipRight", BODY, { "mKneeLeft" }, "0.127 -0.041 0.034" },
|
||||
{ "mKneeLeft", "mKneeRight", BODY, { "mAnkleLeft" }, "-0.046 -0.491 -0.001" },
|
||||
{ "mAnkleLeft", "mAnkleRight", BODY, {}, "0.001 -0.468 -0.029", "0.000 -0.061 0.112" },
|
||||
{ "mHipRight", "mHipLeft", BODY, { "mKneeRight" }, "-0.129 -0.041 0.034", "0.000 -0.061 0.112", true },
|
||||
{ "mAnkleLeft", "mAnkleRight", BODY, { "mToeLeft" }, "0.001 -0.468 -0.029" },
|
||||
{ "mToeLeft", "mToeRight", BODY, {}, "0.000 0.109 0.000", "0.000 0.020 0.000" },
|
||||
{ "mHipRight", "mHipLeft", BODY, { "mKneeRight" }, "-0.129 -0.041 0.034", "", true },
|
||||
{ "mKneeRight", "mKneeLeft", BODY, { "mAnkleRight" }, "0.049 -0.491 -0.001", "", true },
|
||||
{ "mAnkleRight", "mAnkleLeft", BODY, {}, "0.000 -0.468 -0.029", "0.000 -0.061 0.112", true },
|
||||
{ "mAnkleRight", "mAnkleLeft", BODY, { "mToeRight" }, "0.000 -0.468 -0.029", "", true },
|
||||
{ "mToeRight", "mToeLeft", BODY, {}, "0.000 0.109 0.000", "0.000 0.020 0.000", true },
|
||||
|
||||
// face
|
||||
{ "mFaceRoot",
|
||||
|
|
@ -225,10 +227,10 @@ public:
|
|||
"mFaceForeheadLeft", "mFaceForeheadCenter", "mFaceForeheadRight",
|
||||
"mFaceEyebrowOuterLeft", "mFaceEyebrowCenterLeft", "mFaceEyebrowInnerLeft",
|
||||
"mFaceEyebrowOuterRight", "mFaceEyebrowCenterRight", "mFaceEyebrowInnerRight",
|
||||
"mFaceEyeLidUpperLeft", "mFaceEyeLidLowerLeft",
|
||||
"mFaceEyeLidUpperRight", "mFaceEyeLidLowerRight",
|
||||
"mFaceEyeLidUpperLeft", "mFaceEyeLidLowerLeft", "mFaceEyecornerInnerLeft",
|
||||
"mFaceEyeLidUpperRight", "mFaceEyeLidLowerRight", "mFaceEyecornerInnerRight",
|
||||
"mFaceEar1Left", "mFaceEar1Right",
|
||||
"mFaceNoseLeft", "mFaceNoseCenter", "mFaceNoseRight",
|
||||
"mFaceNoseBase", "mFaceNoseBridge", "mFaceNoseLeft", "mFaceNoseCenter", "mFaceNoseRight",
|
||||
"mFaceCheekUpperLeft", "mFaceCheekLowerLeft",
|
||||
"mFaceCheekUpperRight", "mFaceCheekLowerRight",
|
||||
"mFaceJaw", "mFaceTeethUpper"
|
||||
|
|
@ -247,14 +249,18 @@ public:
|
|||
{ "mEyeLeft", "mEyeRight", FACE, {}, "-0.036 0.079 0.098", "0.000 0.000 0.025" },
|
||||
{ "mEyeRight", "mEyeLeft", FACE, {}, "0.036 0.079 0.098", "0.000 0.000 0.025", true },
|
||||
{ "mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE, {}, "0.036 0.034 0.073", "0.000 0.005 0.027" },
|
||||
{ "mFaceEyecornerInnerLeft", "mFaceEyecornerInnerRight", FACE, {}, "0.032 0.075 0.017", "0.000 0.016 0.000" },
|
||||
{ "mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE, {}, "0.036 0.034 0.073", "0.000 -0.007 0.024" },
|
||||
{ "mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, "-0.036 0.034 0.073", "0.000 0.005 0.027", true },
|
||||
{ "mFaceEyecornerInnerRight", "mFaceEyecornerInnerLeft", FACE, {}, "0.032 0.075 -0.017", "0.000 0.016 0.000", true },
|
||||
{ "mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, "-0.036 0.034 0.073", "0.000 -0.007 0.024", true },
|
||||
|
||||
{ "mFaceEar1Left", "mFaceEar1Right", FACE, { "mFaceEar2Left" }, "0.080 0.002 0.000", "" },
|
||||
{ "mFaceEar2Left", "mFaceEar2Right", FACE, {}, "0.018 0.025 -0.019", "0.000 0.033 0.000" },
|
||||
{ "mFaceEar1Right", "mFaceEar1Left", FACE, { "mFaceEar2Right" }, "-0.080 0.002 0.000", "", true },
|
||||
{ "mFaceEar2Right", "mFaceEar2Left", FACE, {}, "-0.018 0.025 -0.019", "0.000 0.033 0.000", true },
|
||||
{ "mFaceNoseBase", "", FACE, {}, "-0.016 0.094 0.000", "0.000 0.014 0.000" },
|
||||
{ "mFaceNoseBridge", "", FACE, {}, "0.020 0.091 0.000", "0.008 0.015 0.000" },
|
||||
{ "mFaceNoseLeft", "mFaceNoseRight", FACE, {}, "0.015 -0.004 0.086", "0.004 0.000 0.015" },
|
||||
{ "mFaceNoseCenter", "", FACE, {}, "0.000 0.000 0.102", "0.000 0.000 0.025" },
|
||||
{ "mFaceNoseRight", "mFaceNoseLeft", FACE, {}, "-0.015 -0.004 0.086", "-0.004 0.000 0.015", true },
|
||||
|
|
@ -343,11 +349,39 @@ public:
|
|||
{ "mWing4Right", "mWing4Left", MISC, {}, "-0.173 0.000 -0.171", "-0.132 0.000 -0.146", true },
|
||||
{ "mWing4FanRight", "mWing4FanLeft", MISC, {}, "-0.173 0.000 -0.171", "-0.062 -0.159 -0.068", true },
|
||||
|
||||
// Misc body parts
|
||||
{ "mSkull", "", MISC, {}, "0.079 0.000 0.000", "0.033 0.000 0.000" },
|
||||
{ "mSpine1", "", MISC, { "mSpine2" }, "0.084 0.000 0.000" },
|
||||
{ "mSpine2", "", MISC, { "mTorso", }, "-0.084 0.000 0.000" },
|
||||
{ "mSpine3", "", MISC, { "mSpine4" }, "0.205 -0.015 0.000" },
|
||||
{ "mSpine4", "", MISC, { "mChest", }, "-0.205 0.015 0.000" },
|
||||
|
||||
// Collision Volumes
|
||||
{ "HEAD", "", COL_VOLUMES },
|
||||
{ "NECK", "", COL_VOLUMES },
|
||||
{ "L_CLAVICLE", "R_CLAVICLE", COL_VOLUMES },
|
||||
{ "R_CLAVICLE", "L_CLAVICLE", COL_VOLUMES, {}, "", "", true },
|
||||
{ "CHEST", "", COL_VOLUMES },
|
||||
{ "LEFT_PEC", "RIGHT_PEC", COL_VOLUMES },
|
||||
{ "RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, "", "", true },
|
||||
{ "UPPER_BACK", "", COL_VOLUMES },
|
||||
{ "LEFT_HANDLE", "RIGHT_HANDLE", COL_VOLUMES },
|
||||
{ "RIGHT_HANDLE", "LEFT_HANDLE", COL_VOLUMES, {}, "", "", true },
|
||||
{ "BELLY", "", COL_VOLUMES },
|
||||
{ "PELVIS", "", COL_VOLUMES },
|
||||
{ "BUTT", "", COL_VOLUMES },
|
||||
{ "L_UPPER_ARM", "R_UPPER_ARM", COL_VOLUMES },
|
||||
{ "R_UPPER_ARM", "L_UPPER_ARM", COL_VOLUMES, {}, "", "", true },
|
||||
{ "L_LOWER_ARM", "R_LOWER_ARM", COL_VOLUMES },
|
||||
{ "R_LOWER_ARM", "L_LOWER_ARM", COL_VOLUMES, {}, "", "", true },
|
||||
{ "L_HAND", "R_HAND", COL_VOLUMES },
|
||||
{ "R_HAND", "L_HAND", COL_VOLUMES, {}, "", "", true },
|
||||
{ "L_UPPER_LEG", "R_UPPER_LEG", COL_VOLUMES },
|
||||
{ "R_UPPER_LEG", "L_UPPER_LEG", COL_VOLUMES, {}, "", "", true },
|
||||
{ "L_LOWER_LEG", "R_LOWER_LEG", COL_VOLUMES },
|
||||
{ "R_LOWER_LEG", "L_LOWER_LEG", COL_VOLUMES, {}, "", "", true },
|
||||
{ "L_FOOT", "R_FOOT", COL_VOLUMES },
|
||||
{ "R_FOOT", "L_FOOT", COL_VOLUMES, {}, "", "", true },
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,450 @@
|
|||
/**
|
||||
* @file fsprimfeedauth.cpp
|
||||
* @file fsprimfeedauth.h
|
||||
* @brief Primfeed Authorisation workflow class
|
||||
* @author beq@firestorm
|
||||
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2025, Beq Janus
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handles Primfeed authentication and authorisation through a multi-factor OAuth flow.
|
||||
*
|
||||
* This module integrates with Primfeed’s Third Party Viewers API.
|
||||
* The authentication flow is as follows:
|
||||
* 1. Initiate a login request:
|
||||
* POST https://api.primfeed.com/pf/viewer/create-login-request
|
||||
* Headers:
|
||||
* pf-viewer-api-key: <viewer_api_key>
|
||||
* pf-user-uuid: <avatar_uuid>
|
||||
* Response:
|
||||
* { "requestId": "<64-char string>" }
|
||||
*
|
||||
* 2. Redirect the user to:
|
||||
* https://www.primfeed.com/oauth/viewer?r=<requestId>&v=<viewer_api_key>
|
||||
*
|
||||
* 3. The user is shown an approval screen. When they click Authorize,
|
||||
* an in-world message is sent:
|
||||
* #PRIMFEED_OAUTH: <oauth_token>
|
||||
* We intercept this code through an onChat handle then call onOauthTokenReceived().
|
||||
*
|
||||
* 4. Validate the login request:
|
||||
* POST https://api.primfeed.com/pf/viewer/validate-request
|
||||
* Headers:
|
||||
* Authorization: Bearer <oauth_token>
|
||||
* pf-viewer-api-key: <viewer_api_key>
|
||||
* pf-viewer-request-id: <requestId>
|
||||
* Response: HTTP 204
|
||||
*
|
||||
* 5. Optionally, check user status:
|
||||
* GET https://api.primfeed.com/pf/viewer/user
|
||||
* Headers:
|
||||
* Authorization: Bearer <oauth_token>
|
||||
* pf-viewer-api-key: <viewer_api_key>
|
||||
* Response: { "plan": "free" } (or "pro")
|
||||
*/
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "fsprimfeedauth.h"
|
||||
#include "fsprimfeedconnect.h"
|
||||
#include "llimview.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llfloaterimnearbychathandler.h"
|
||||
#include "llnotificationmanager.h"
|
||||
#include "llagent.h"
|
||||
#include "llevents.h"
|
||||
#include "fscorehttputil.h"
|
||||
#include "llwindow.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "lluri.h"
|
||||
#include "llsdjson.h"
|
||||
#include <string_view>
|
||||
|
||||
using Callback = FSPrimfeedAuth::authorized_callback_t;
|
||||
|
||||
// private instance variable
|
||||
std::shared_ptr<FSPrimfeedAuth> FSPrimfeedAuth::sPrimfeedAuth;
|
||||
std::unique_ptr<LLEventPump> FSPrimfeedAuth::sPrimfeedAuthPump = std::make_unique<LLEventStream>("PrimfeedAuthResponse");
|
||||
|
||||
// Helper callback that unpacks HTTP POST response data.
|
||||
void FSPrimfeedAuthResponse(LLSD const &aData, Callback callback)
|
||||
{
|
||||
LLSD header = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS][LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(
|
||||
aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]);
|
||||
|
||||
const LLSD::Binary &rawData = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
|
||||
std::string result;
|
||||
result.assign(rawData.begin(), rawData.end());
|
||||
|
||||
// Assume JSON response.
|
||||
|
||||
LLSD resultLLSD;
|
||||
if(!result.empty())
|
||||
{
|
||||
resultLLSD = LlsdFromJson(boost::json::parse(result));
|
||||
}
|
||||
callback((status.getType() == HTTP_OK ||
|
||||
status.getType() == HTTP_NO_CONTENT), resultLLSD);
|
||||
}
|
||||
|
||||
void FSPrimfeedAuth::initiateAuthRequest()
|
||||
{
|
||||
// This function is called to initiate the authentication request.
|
||||
// It should be called when the user clicks the "Authenticate" button.
|
||||
// Also triggered on opening the floater.
|
||||
// The actual implementation is in the create() method.
|
||||
|
||||
if (!isAuthorized())
|
||||
{
|
||||
if (sPrimfeedAuth)
|
||||
{
|
||||
LLNotificationsUtil::add("PrimfeedAuthorizationAlreadyInProgress");
|
||||
return;
|
||||
}
|
||||
// If no token stored, begin the login request; otherwise check user status.
|
||||
sPrimfeedAuth = FSPrimfeedAuth::create(
|
||||
[](bool success, const LLSD &response)
|
||||
{
|
||||
LLSD event_data = response;
|
||||
event_data["success"] = success;
|
||||
sPrimfeedAuthPump->post(event_data);
|
||||
// Now that auth is complete, clear the static pointer.
|
||||
sPrimfeedAuth.reset();
|
||||
}
|
||||
);
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("PrimfeedAlreadyAuthorized");
|
||||
}
|
||||
}
|
||||
|
||||
void FSPrimfeedAuth::resetAuthStatus()
|
||||
{
|
||||
sPrimfeedAuth.reset();
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedOAuthToken", "");
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedProfileLink", "");
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedPlan", "");
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedUsername", "");
|
||||
LLSD event_data;
|
||||
event_data["status"] = "reset";
|
||||
event_data["success"] = "false";
|
||||
sPrimfeedAuthPump->post(event_data);
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED);
|
||||
}
|
||||
|
||||
|
||||
FSPrimfeedAuth::FSPrimfeedAuth(authorized_callback_t callback)
|
||||
: mCallback(callback)
|
||||
{
|
||||
mChatMessageConnection = LLNotificationsUI::LLNotificationManager::instance().getChatHandler()->addNewChatCallback(
|
||||
[this](const LLSD &message) {
|
||||
LL_DEBUGS("FSPrimfeedAuth") << "Received chat message: " << message["message"].asString() << LL_ENDL;
|
||||
this->onChatMessage(message);
|
||||
});
|
||||
}
|
||||
|
||||
FSPrimfeedAuth::~FSPrimfeedAuth()
|
||||
{
|
||||
if (mChatMessageConnection.connected())
|
||||
{
|
||||
try
|
||||
{
|
||||
mChatMessageConnection.disconnect();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LL_WARNS("FSPrimfeedAuth") << "Exception during chat connection disconnect: " << e.what() << LL_ENDL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LL_WARNS("FSPrimfeedAuth") << "Unknown exception during chat connection disconnect." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Factory method to create a shared pointer to FSPrimfeedAuth.
|
||||
std::shared_ptr<FSPrimfeedAuth> FSPrimfeedAuth::create(authorized_callback_t callback)
|
||||
{
|
||||
// Ensure only one authentication attempt is in progress.
|
||||
if (sPrimfeedAuth)
|
||||
{
|
||||
// Already in progress; return the existing instance.
|
||||
return sPrimfeedAuth;
|
||||
}
|
||||
auto auth = std::shared_ptr<FSPrimfeedAuth>(new FSPrimfeedAuth(callback));
|
||||
if(!auth)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING);
|
||||
|
||||
// If no token stored, begin the login request; otherwise check user status.
|
||||
if (gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken").empty())
|
||||
{
|
||||
auth->beginLoginRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
auth->checkUserStatus();
|
||||
}
|
||||
return auth;
|
||||
}
|
||||
|
||||
void FSPrimfeedAuth::beginLoginRequest()
|
||||
{
|
||||
// Get our API key and user UUID.
|
||||
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||
std::string user_uuid = gAgent.getID().asString();
|
||||
|
||||
std::string url = "https://api.primfeed.com/pf/viewer/create-login-request";
|
||||
std::string post_data = ""; // No body parameters required.
|
||||
|
||||
// Create the headers object.
|
||||
LLCore::HttpHeaders::ptr_t pHeader(new LLCore::HttpHeaders());
|
||||
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
|
||||
|
||||
pHeader->append("pf-viewer-api-key", viewer_api_key);
|
||||
pHeader->append("pf-user-uuid", user_uuid);
|
||||
|
||||
// Set up HTTP options
|
||||
options->setWantHeaders(true);
|
||||
options->setRetries(0);
|
||||
options->setTimeout(PRIMFEED_CONNECT_TIMEOUT);
|
||||
|
||||
// Capture shared_ptr to self
|
||||
auto self = shared_from_this();
|
||||
|
||||
const auto end(pHeader->end());
|
||||
for (auto it(pHeader->begin()); end != it; ++it)
|
||||
{
|
||||
LL_DEBUGS("Primfeed") << "Header: " << it->first << " = " << it->second << LL_ENDL;
|
||||
}
|
||||
|
||||
// Pass both success and failure callbacks
|
||||
FSCoreHttpUtil::callbackHttpPostRaw(
|
||||
url,
|
||||
post_data,
|
||||
[self](LLSD const &aData) {
|
||||
LL_DEBUGS("FSPrimfeedAuth") << "Login request response(OK): " << aData << LL_ENDL;
|
||||
FSPrimfeedAuthResponse(aData,
|
||||
[self](bool success, const LLSD &response) {
|
||||
self->gotRequestId(success, response);
|
||||
}
|
||||
);
|
||||
},
|
||||
[self](LLSD const &aData) {
|
||||
LL_DEBUGS("FSPrimfeedAuth") << "Login request response(FAIL): " << aData << LL_ENDL;
|
||||
FSPrimfeedAuthResponse(aData,
|
||||
[self](bool success, const LLSD &response) {
|
||||
self->gotRequestId(success, response);
|
||||
}
|
||||
);
|
||||
},
|
||||
pHeader,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
void FSPrimfeedAuth::gotRequestId(bool success, const LLSD &response)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
LLNotificationsUtil::add("PrimfeedLoginRequestFailed");
|
||||
mCallback(false, LLSD());
|
||||
return;
|
||||
}
|
||||
mRequestId = response["requestId"].asString();
|
||||
if (mRequestId.empty())
|
||||
{
|
||||
LLNotificationsUtil::add("PrimfeedLoginRequestFailed");
|
||||
mCallback(false, LLSD());
|
||||
return;
|
||||
}
|
||||
// Open the browser for user approval.
|
||||
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||
std::string auth_url = "https://www.primfeed.com/oauth/viewer?r=" + mRequestId + "&v=" + viewer_api_key;
|
||||
gViewerWindow->getWindow()->spawnWebBrowser(auth_url, true);
|
||||
|
||||
}
|
||||
|
||||
/// This function is called by the chat interceptor when the message
|
||||
/// "#PRIMFEED_OAUTH: <oauth_token>" is intercepted.
|
||||
void FSPrimfeedAuth::onOauthTokenReceived(const std::string_view& oauth_token)
|
||||
{
|
||||
if (oauth_token.empty())
|
||||
{
|
||||
mCallback(false, LLSD());
|
||||
return;
|
||||
}
|
||||
mOauthToken = oauth_token;
|
||||
validateRequest();
|
||||
}
|
||||
|
||||
void FSPrimfeedAuth::onChatMessage(const LLSD& message)
|
||||
{
|
||||
constexpr std::string_view oauth_msg_prefix = "#PRIMFEED_OAUTH: ";
|
||||
const std::string msg = message["message"].asString();
|
||||
if (msg.find(std::string(oauth_msg_prefix)) == 0)
|
||||
{
|
||||
std::string_view oauth_token(msg.data() + oauth_msg_prefix.size(), msg.size() - oauth_msg_prefix.size());
|
||||
LL_DEBUGS("Primfeed") << "Received OAuth token: " << msg << "extracted:<" << oauth_token << ">" << LL_ENDL;
|
||||
onOauthTokenReceived(oauth_token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FSPrimfeedAuth::validateRequest()
|
||||
{
|
||||
// No POST body needed.
|
||||
std::string post_data = "";
|
||||
std::string url = "https://api.primfeed.com/pf/viewer/validate-request";
|
||||
|
||||
// Retrieve the viewer API key.
|
||||
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||
|
||||
// Create and populate the headers.
|
||||
LLCore::HttpHeaders::ptr_t pHeader(new LLCore::HttpHeaders());
|
||||
pHeader->append("Authorization", "Bearer " + mOauthToken);
|
||||
pHeader->append("pf-viewer-api-key", viewer_api_key);
|
||||
pHeader->append("pf-viewer-request-id", mRequestId);
|
||||
|
||||
// Set HTTP options
|
||||
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
|
||||
options->setWantHeaders(true);
|
||||
options->setRetries(0);
|
||||
options->setTimeout(PRIMFEED_CONNECT_TIMEOUT);
|
||||
|
||||
// print out pHeader for debuging using iterating over pHeader and using LL_DEBUGS
|
||||
const auto end(pHeader->end());
|
||||
for (auto it(pHeader->begin()); end != it; ++it)
|
||||
{
|
||||
LL_DEBUGS("Primfeed") << "Header: " << it->first << " = " << it->second << LL_ENDL;
|
||||
}
|
||||
|
||||
auto self = shared_from_this();
|
||||
try
|
||||
{
|
||||
FSCoreHttpUtil::callbackHttpPostRaw(
|
||||
url,
|
||||
post_data,
|
||||
[self](LLSD const &aData) {
|
||||
LL_DEBUGS("FSPrimfeedAuth") << "Validation-request response(OK): " << aData << LL_ENDL;
|
||||
FSPrimfeedAuthResponse(aData,
|
||||
[self](bool success, const LLSD &response) {
|
||||
self->gotValidateResponse(success, response);
|
||||
}
|
||||
);
|
||||
},
|
||||
[self](LLSD const &aData) {
|
||||
LL_INFOS("FSPrimfeedAuth") << "Validation-request response(FAIL): " << aData << LL_ENDL;
|
||||
FSPrimfeedAuthResponse(aData,
|
||||
[self](bool success, const LLSD &response) {
|
||||
self->gotValidateResponse(success, response);
|
||||
}
|
||||
);
|
||||
},
|
||||
pHeader,
|
||||
options
|
||||
);
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
LL_WARNS("Primfeed") << "Primfeed validation failed " << e.what() << LL_ENDL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FSPrimfeedAuth::gotValidateResponse(bool success, const LLSD &response)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
LLNotificationsUtil::add("PrimfeedValidateFailed");
|
||||
mCallback(false, response);
|
||||
return;
|
||||
}
|
||||
checkUserStatus();
|
||||
}
|
||||
|
||||
void FSPrimfeedAuth::checkUserStatus()
|
||||
{
|
||||
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||
|
||||
// Build the base URL without query parameters.
|
||||
std::string url = "https://api.primfeed.com/pf/viewer/user";
|
||||
LL_DEBUGS("Primfeed") << "URL: " << url << LL_ENDL;
|
||||
|
||||
// Create and populate the headers.
|
||||
LLCore::HttpHeaders::ptr_t pHeader(new LLCore::HttpHeaders());
|
||||
pHeader->append("Authorization", "Bearer " + mOauthToken);
|
||||
pHeader->append("pf-viewer-api-key", viewer_api_key);
|
||||
|
||||
// Set HTTP options.
|
||||
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
|
||||
options->setWantHeaders(true);
|
||||
options->setRetries(0);
|
||||
options->setTimeout(PRIMFEED_CONNECT_TIMEOUT);
|
||||
|
||||
// Make the HTTP GET request, passing in the headers and options.
|
||||
FSCoreHttpUtil::callbackHttpGetRaw(
|
||||
url,
|
||||
[this](LLSD const &aData) {
|
||||
LL_DEBUGS("FSPrimfeedAuth") << "Check-user-status response: " << aData << LL_ENDL;
|
||||
FSPrimfeedAuthResponse(aData, [this](bool success, const LLSD &response) {
|
||||
this->gotUserStatus(success, response);
|
||||
});
|
||||
},
|
||||
[this](LLSD const &aData) {
|
||||
LL_INFOS("FSPrimfeedAuth") << "Check-user-status response (failure): " << aData << LL_ENDL;
|
||||
// Optionally, call the same processing for failure or handle separately.
|
||||
FSPrimfeedAuthResponse(aData, [this](bool success, const LLSD &response){
|
||||
this->gotUserStatus(success, response);
|
||||
});
|
||||
},
|
||||
pHeader,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void FSPrimfeedAuth::gotUserStatus(bool success, const LLSD &response)
|
||||
{
|
||||
LL_INFOS("Primfeed") << "User status: " << response << "(" << success << ")" << LL_ENDL;
|
||||
if (success && response.has("plan"))
|
||||
{
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedOAuthToken", mOauthToken);
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedPlan", response["plan"].asString());
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedProfileLink", response["link"].asString());
|
||||
gSavedPerAccountSettings.setString("FSPrimfeedUsername", response["username"].asString());
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTED);
|
||||
mCallback(true, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("PrimfeedUserStatusFailed");
|
||||
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED);
|
||||
mCallback(false, response);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* @file fsprimfeedauth.h
|
||||
* @brief Primfeed Authorisation workflow class
|
||||
* @author beq@firestorm
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2025, Beq Janus
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef FSPRIMFEEDAUTH_H
|
||||
#define FSPRIMFEEDAUTH_H
|
||||
|
||||
#include "llsd.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
/*
|
||||
* Primfeed authentication workflow class.
|
||||
*
|
||||
* This class handles the Primfeed OAuth login flow and provides methods to
|
||||
* check the user status and receive a callback when the authentication
|
||||
* process is complete.
|
||||
* based on the workflow documented at https://docs.primfeed.com/api/third-party-viewers
|
||||
*/
|
||||
class FSPrimfeedAuth : public std::enable_shared_from_this<FSPrimfeedAuth>
|
||||
{
|
||||
public:
|
||||
// Callback type: first parameter indicates success and the second holds any LLSD response.
|
||||
using authorized_callback_t = std::function<void(bool, const LLSD&)>;
|
||||
static std::shared_ptr<FSPrimfeedAuth> create(authorized_callback_t callback);
|
||||
static std::unique_ptr<LLEventPump> sPrimfeedAuthPump;
|
||||
~FSPrimfeedAuth();
|
||||
|
||||
// Should be called by the chat interceptor when an oauth token is received.
|
||||
void onOauthTokenReceived(const std::string_view& oauth_token);
|
||||
void onInstantMessage(const LLSD& message);
|
||||
void onChatMessage(const LLSD& message);
|
||||
|
||||
// Begin the login request flow.
|
||||
void beginLoginRequest();
|
||||
// Check the user status.
|
||||
void checkUserStatus();
|
||||
static bool isPendingAuth(){ return (sPrimfeedAuth != nullptr); }
|
||||
static bool isAuthorized(){ return (!gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken").empty()); }
|
||||
static void initiateAuthRequest();
|
||||
static void resetAuthStatus();
|
||||
|
||||
private:
|
||||
static std::shared_ptr<FSPrimfeedAuth> sPrimfeedAuth;
|
||||
|
||||
explicit FSPrimfeedAuth(authorized_callback_t callback);
|
||||
authorized_callback_t mCallback;
|
||||
std::string mOauthToken;
|
||||
std::string mRequestId;
|
||||
|
||||
// Callback when a login request response is received.
|
||||
void gotRequestId(bool success, const LLSD &response);
|
||||
// Validate the login request.
|
||||
void validateRequest();
|
||||
// Callback when the validate response is received.
|
||||
void gotValidateResponse(bool success, const LLSD &response);
|
||||
// Callback when the user status response is received.
|
||||
void gotUserStatus(bool success, const LLSD &response);
|
||||
|
||||
boost::signals2::connection mInstantMessageConnection;
|
||||
boost::signals2::connection mChatMessageConnection;
|
||||
// Static flag to prevent duplicate authentication attempts.
|
||||
static std::atomic<bool> sAuthorisationInProgress;
|
||||
|
||||
static constexpr U32 PRIMFEED_CONNECT_TIMEOUT = 300; // 5 minute timeout should work
|
||||
};
|
||||
|
||||
#endif // FSPRIMFEEDAUTH_H
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
/**
|
||||
* @file fsprimfeedconnect.cpp
|
||||
* @brief Primfeed connector class
|
||||
* @author beq@firestorm
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2025, Beq Janus
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include "fsprimfeedconnect.h"
|
||||
#include "fsprimfeedauth.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llcoros.h"
|
||||
#include "llsdjson.h"
|
||||
|
||||
// The connector workflow for Primfeed is realtively simple and mostly just builds on top of the established Auth workflow
|
||||
// and the posting endpoint documented at https://docs.primfeed.com/api/third-party-viewers#creating-a-post
|
||||
|
||||
FSPrimfeedConnect::FSPrimfeedConnect() = default;
|
||||
|
||||
void FSPrimfeedConnect::uploadPhoto(const LLSD& params, LLImageFormatted* image, post_callback_t callback)
|
||||
{
|
||||
LL_DEBUGS("primfeed") << "uploadPhoto() called" << LL_ENDL;
|
||||
if (!FSPrimfeedAuth::isAuthorized())
|
||||
{
|
||||
LL_WARNS("primfeed") << "Authorization failed, aborting.\n" << LL_ENDL;
|
||||
callback(false, "");
|
||||
return;
|
||||
}
|
||||
LL_DEBUGS("primfeed") << "Authorization successful" << LL_ENDL;
|
||||
|
||||
mPostCallback = callback;
|
||||
LL_DEBUGS("primfeed") << "Launching upload coroutine" << LL_ENDL;
|
||||
LLCoros::instance().launch(
|
||||
"FSPrimfeedConnect::uploadPhotoCoro",
|
||||
[this, params, image]() { uploadPhotoCoro(params, image); }
|
||||
);
|
||||
}
|
||||
|
||||
void FSPrimfeedConnect::uploadPhotoCoro(const LLSD& params, LLImageFormatted* image)
|
||||
{
|
||||
LL_DEBUGS("primfeed") << "Entered uploadPhotoCoro" << LL_ENDL;
|
||||
setConnectionState(PRIMFEED_POSTING);
|
||||
LL_DEBUGS("primfeed") << "Connection state set to PRIMFEED_POSTING" << LL_ENDL;
|
||||
|
||||
const std::string fmt = (image->getCodec() == EImageCodec::IMG_CODEC_JPEG) ? "jpg" : "png";
|
||||
LL_DEBUGS("primfeed") << "Image format: " << fmt << LL_ENDL;
|
||||
|
||||
const std::string boundary = "----------------------------0123456789abcdef";
|
||||
const std::string sep = "\n";
|
||||
const std::string dash = "--" + boundary;
|
||||
|
||||
LL_DEBUGS("primfeed") << "Building multipart body" << LL_ENDL;
|
||||
LLCore::BufferArray::ptr_t raw(new LLCore::BufferArray());
|
||||
LLCore::BufferArrayStream body(raw.get());
|
||||
auto addPart = [&](const std::string& name, const std::string& val)
|
||||
{
|
||||
LL_DEBUGS("primfeed") << "Adding part: " << name << "=" << val << LL_ENDL;
|
||||
body << dash << sep
|
||||
<< "Content-Disposition: form-data; name=\"" << name << "\"" << sep << sep
|
||||
<< val << sep;
|
||||
};
|
||||
|
||||
addPart("commercial", params["commercial"].asBoolean() ? "true" : "false");
|
||||
addPart("rating", params["rating"].asString());
|
||||
addPart("content", params["content"].asString());
|
||||
addPart("publicGallery", params["post_to_public_gallery"].asBoolean()? "true" : "false");
|
||||
|
||||
if (params.has("location") && !params["location"].asString().empty())
|
||||
{
|
||||
addPart("location", params["location"].asString());
|
||||
}
|
||||
|
||||
LL_DEBUGS("primfeed") << "Adding image file header" << LL_ENDL;
|
||||
body << dash << sep
|
||||
<< "Content-Disposition: form-data; name=\"image\"; filename=\"snapshot." << fmt << "\"" << sep
|
||||
<< "Content-Type: image/" << fmt << sep << sep;
|
||||
|
||||
U8* data = image->getData();
|
||||
S32 size = image->getDataSize();
|
||||
LL_DEBUGS("primfeed") << "Appending image data, size=" << size << LL_ENDL;
|
||||
// yep this seems inefficient, but all other occurrences in the codebase do it this way.
|
||||
for (S32 i = 0; i < size; ++i)
|
||||
{
|
||||
body << data[i];
|
||||
}
|
||||
body << sep;
|
||||
|
||||
body << dash << "--" << sep;
|
||||
LL_DEBUGS("primfeed") << "Multipart body ready" << LL_ENDL;
|
||||
|
||||
// Setup HTTP
|
||||
LL_DEBUGS("primfeed") << "Preparing HTTP request" << LL_ENDL;
|
||||
LLCore::HttpRequest::policy_t policy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter adapter("PrimfeedUpload", policy);
|
||||
LLCore::HttpRequest::ptr_t request(new LLCore::HttpRequest);
|
||||
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions);
|
||||
options->setWantHeaders(true);
|
||||
|
||||
LL_DEBUGS("primfeed") << "Setting HTTP headers" << LL_ENDL;
|
||||
LLCore::HttpHeaders::ptr_t headers(new LLCore::HttpHeaders);
|
||||
std::string token = gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken");
|
||||
std::string apiKey = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||
headers->append("Authorization", "Bearer " + token);
|
||||
headers->append("pf-viewer-api-key", apiKey);
|
||||
headers->append("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||
LL_DEBUGS("primfeed") << "Dumping HTTP headers for POST:" << LL_ENDL;
|
||||
for (auto it = headers->begin(); it != headers->end(); ++it)
|
||||
{
|
||||
LL_DEBUGS("primfeed") << it->first << ": " << it->second << LL_ENDL;
|
||||
}
|
||||
LL_DEBUGS("primfeed") << "Headers set" << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("primfeed") << "Starting HTTP POST" << LL_ENDL;
|
||||
LLSD result = adapter.postRawAndSuspend(request,
|
||||
"https://api.primfeed.com/pf/viewer/post",
|
||||
raw,
|
||||
options,
|
||||
headers);
|
||||
LL_DEBUGS("primfeed") << "HTTP POST complete" << LL_ENDL;
|
||||
|
||||
const LLSD::Binary &rawData = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
|
||||
std::string response_raw;
|
||||
response_raw.assign(rawData.begin(), rawData.end());
|
||||
LLSD result_LLSD;
|
||||
if(!response_raw.empty())
|
||||
{
|
||||
result_LLSD = LlsdFromJson(boost::json::parse(response_raw));
|
||||
}
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]);
|
||||
bool success = (status.getType() == HTTP_OK);
|
||||
LL_DEBUGS("primfeed") << "HTTP status =" << (success?"OK":"FAIL") << " "<< status.getMessage() << LL_ENDL;
|
||||
|
||||
std::string url;
|
||||
if (success)
|
||||
{
|
||||
url = result_LLSD["url"].asString();
|
||||
LL_DEBUGS("primfeed") << "Received URL=" << url << LL_ENDL;
|
||||
}
|
||||
|
||||
LL_DEBUGS("primfeed") << "Invoking callback" << LL_ENDL;
|
||||
mPostCallback(success, url);
|
||||
setConnectionState(success ? PRIMFEED_POSTED : PRIMFEED_POST_FAILED);
|
||||
LL_DEBUGS("primfeed") << "Final state set" << LL_ENDL;
|
||||
}
|
||||
|
||||
// Handle connection state transitions
|
||||
void FSPrimfeedConnect::setConnectionState(EConnectionState state)
|
||||
{
|
||||
LL_DEBUGS("primfeed") << "setConnectionState(" << state << ")" << LL_ENDL;
|
||||
mConnectionState = state;
|
||||
}
|
||||
|
||||
FSPrimfeedConnect::EConnectionState FSPrimfeedConnect::getConnectionState() const
|
||||
{
|
||||
return mConnectionState;
|
||||
}
|
||||
|
||||
bool FSPrimfeedConnect::isTransactionOngoing() const
|
||||
{
|
||||
return (mConnectionState == PRIMFEED_CONNECTING ||
|
||||
mConnectionState == PRIMFEED_POSTING ||
|
||||
mConnectionState == PRIMFEED_DISCONNECTING);
|
||||
}
|
||||
|
||||
void FSPrimfeedConnect::loadPrimfeedInfo()
|
||||
{
|
||||
LL_DEBUGS("primfeed") << "loadPrimfeedInfo() called" << LL_ENDL;
|
||||
// Nothing to do here for Primfeed
|
||||
setConnectionState(PRIMFEED_CONNECTED);
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file fsprimfeedconect.h
|
||||
* @brief Primfeed connector class
|
||||
* @author beq@firestorm
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2025, Beq Janus
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef FS_PRIMFEEDCONNECT_H
|
||||
#define FS_PRIMFEEDCONNECT_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include "llsd.h"
|
||||
#include "llimage.h"
|
||||
#include "fsprimfeedauth.h"
|
||||
#include "llcorehttputil.h"
|
||||
#include "bufferarray.h"
|
||||
#include "llcoros.h"
|
||||
#include "llviewercontrol.h" // for gSavedSettings/gSavedPerAccountSettings
|
||||
#include <functional>
|
||||
|
||||
// Coro based connector designed to interface with floater designed along the same principles as LLFloaterFlickr.cpp
|
||||
|
||||
class FSPrimfeedConnect : public LLSingleton<FSPrimfeedConnect>
|
||||
{
|
||||
LLSINGLETON(FSPrimfeedConnect);
|
||||
public:
|
||||
// Connection states for Primfeed operations
|
||||
enum EConnectionState
|
||||
{
|
||||
PRIMFEED_DISCONNECTED = 0,
|
||||
PRIMFEED_CONNECTING,
|
||||
PRIMFEED_CONNECTED,
|
||||
PRIMFEED_POSTING,
|
||||
PRIMFEED_POSTED,
|
||||
PRIMFEED_POST_FAILED,
|
||||
PRIMFEED_DISCONNECTING
|
||||
};
|
||||
|
||||
// Callback invoked on post completion: success flag and URL (empty on failure)
|
||||
using post_callback_t = std::function<void(bool success, const std::string& url)>;
|
||||
|
||||
// Posts a snapshot to Primfeed; requires FSPrimfeedAuth::isAuthorized()
|
||||
void uploadPhoto(const LLSD& params, LLImageFormatted* image, post_callback_t callback);
|
||||
|
||||
// Retrieve and update account info from Primfeed (not used kept for compatibility)
|
||||
void loadPrimfeedInfo();
|
||||
|
||||
void setConnectionState(EConnectionState state);
|
||||
EConnectionState getConnectionState() const;
|
||||
bool isTransactionOngoing() const;
|
||||
|
||||
private:
|
||||
// Internal coroutine entry-point for uploads
|
||||
void uploadPhotoCoro(const LLSD& params, LLImageFormatted* image);
|
||||
|
||||
// Cached callback until coroutine completes
|
||||
post_callback_t mPostCallback;
|
||||
|
||||
// Current connection/post state
|
||||
EConnectionState mConnectionState = PRIMFEED_DISCONNECTED;
|
||||
};
|
||||
#endif // FS_PRIMFEEDCONNECT_H
|
||||
|
|
@ -235,6 +235,7 @@
|
|||
#include "llfloatersimplesnapshot.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llfloaterflickr.h"
|
||||
#include "fsfloaterprimfeed.h" // <FS:Beq/> Primfeed Floater
|
||||
#include "llsidepanelinventory.h"
|
||||
#include "llatmosphere.h"
|
||||
|
||||
|
|
@ -1751,6 +1752,7 @@ bool LLAppViewer::doFrame()
|
|||
LLFloaterSnapshot::update(); // take snapshots
|
||||
LLFloaterSimpleSnapshot::update();
|
||||
LLFloaterFlickr::update(); // <FS:Beq/> FIRE-35002 - Flickr preview not updating whne opened directly from tool tray icon
|
||||
FSFloaterPrimfeed::update(); // <FS:Beq/> Primfeed support
|
||||
gGLActive = false;
|
||||
}
|
||||
|
||||
|
|
@ -3795,6 +3797,7 @@ bool LLAppViewer::waitForUpdater()
|
|||
|
||||
void LLAppViewer::writeDebugInfo(bool isStatic)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; // <FS:Beq/> improve instrumentation
|
||||
#if LL_WINDOWS && LL_BUGSPLAT
|
||||
// <FS:Beq> Improve Bugsplat tracking by using attributes for certain static data items.
|
||||
const LLSD& info = getViewerInfo();
|
||||
|
|
@ -3823,6 +3826,7 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
|
|||
|
||||
LLSD LLAppViewer::getViewerInfo() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; // <FS:Beq/> improve instrumentation
|
||||
// The point of having one method build an LLSD info block and the other
|
||||
// construct the user-visible About string is to ensure that the same info
|
||||
// is available to a getInfo() caller as to the user opening
|
||||
|
|
@ -4135,6 +4139,7 @@ LLSD LLAppViewer::getViewerInfo() const
|
|||
// info["DISK_CACHE_INFO"] = LLDiskCache::getInstance()->getCacheInfo();
|
||||
if (auto cache = LLDiskCache::getInstance(); cache)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("gvi-getCacheInfo"); // <FS:Beq/> improve instrumentation
|
||||
info["DISK_CACHE_INFO"] = cache->getCacheInfo();
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
|
|
|||
|
|
@ -644,11 +644,13 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
|||
// <FS:Beq> Use the Attributes API on Windows to enhance crash metadata
|
||||
void LLAppViewerWin32::bugsplatAddStaticAttributes(const LLSD& info)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
|
||||
#ifdef LL_BUGSPLAT
|
||||
auto& bugSplatMap = BugSplatAttributes::instance();
|
||||
static bool write_once_after_startup = false;
|
||||
if (!write_once_after_startup )
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("bs-st-att-once")
|
||||
// Only write the attributes that are fixed once after we've started.
|
||||
// note we might update them more than once and some/many may be empty during startup as we want to catch early crashes
|
||||
// once we're started we can assume they don't change for this run.
|
||||
|
|
|
|||
|
|
@ -670,7 +670,14 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> Hide Primfeed OAuth message from chat to prevent accidental leak of secret.
|
||||
const std::string primfeed_oauth = "#PRIMFEED_OAUTH: ";
|
||||
if( chat_msg.mText.compare(0, primfeed_oauth.length(), primfeed_oauth) == 0 && chat_msg.mChatType == CHAT_TYPE_IM && chat_msg.mSourceType == CHAT_SOURCE_OBJECT )
|
||||
{
|
||||
// Don't show the message in chat.
|
||||
return;
|
||||
}
|
||||
// </FS:Beq>
|
||||
nearby_chat->addMessage(chat_msg, true, args);
|
||||
|
||||
if (chat_msg.mSourceType == CHAT_SOURCE_AGENT
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
||||
#include "fsfloaterprimfeed.h" // <FS:Beq> Share to Primfeed
|
||||
#include "llimagefiltersmanager.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcombobox.h"
|
||||
|
|
@ -1463,12 +1464,12 @@ bool LLFloaterSnapshot::isWaitingState()
|
|||
|
||||
// <FS:Beq> FIRE-35002 - Post to flickr broken, improved solution
|
||||
// bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
|
||||
bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized, bool have_flickr)
|
||||
bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized, bool have_socials)
|
||||
// </FS:Beq>
|
||||
{
|
||||
// <FS:Ansariel> Share to Flickr
|
||||
//if (!initialized)
|
||||
if (!initialized && !have_flickr)
|
||||
if (!initialized && !have_socials)
|
||||
// </FS:Ansariel>
|
||||
return false;
|
||||
|
||||
|
|
@ -1487,16 +1488,18 @@ void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
|
|||
{
|
||||
// don't update preview for hidden floater
|
||||
// <FS:Beq> FIRE-35002 - Post to flickr broken
|
||||
LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
|
||||
auto have_flickr = floater_flickr != nullptr;
|
||||
bool have_socials = (
|
||||
LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr") != nullptr ||
|
||||
LLFloaterReg::findTypedInstance<FSFloaterPrimfeed>("primfeed") != nullptr
|
||||
);
|
||||
if ( ((mFloater && mFloater->isInVisibleChain()) ||
|
||||
have_flickr) &&
|
||||
ImplBase::updatePreviewList(true, have_flickr))
|
||||
have_socials) &&
|
||||
ImplBase::updatePreviewList(true, have_socials))
|
||||
// </FS:Beq>
|
||||
{
|
||||
LL_DEBUGS() << "changed" << LL_ENDL;
|
||||
updateControls(mFloater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ public:
|
|||
virtual EStatus getStatus() const { return mStatus; }
|
||||
virtual void setNeedRefresh(bool need);
|
||||
|
||||
static bool updatePreviewList(bool initialized, bool have_flickr = false); // <FS:Beq/> FIRE-35002 - Post to flickr broken, improved solution
|
||||
static bool updatePreviewList(bool initialized, bool have_socials = false); // <FS:Beq/> FIRE-35002 - Post to flickr broken, improved solution
|
||||
|
||||
void setAdvanced(bool advanced) { mAdvanced = advanced; }
|
||||
void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
|
||||
|
|
|
|||
|
|
@ -3943,16 +3943,55 @@ LLUUID LLIMMgr::addSession(
|
|||
//works only for outgoing ad-hoc sessions
|
||||
if (new_session &&
|
||||
((IM_NOTHING_SPECIAL == dialog) || (IM_SESSION_P2P_INVITE == dialog) || (IM_SESSION_CONFERENCE_START == dialog)) &&
|
||||
ids.size())
|
||||
// <AS:chanayane> [FIRE-34494] fix unable to open an IM with someone who started a group chat
|
||||
//ids.size())
|
||||
!ids.empty())
|
||||
// </AS:chanayane>
|
||||
{
|
||||
session = LLIMModel::getInstance()->findAdHocIMSession(ids);
|
||||
if (session)
|
||||
{
|
||||
new_session = false;
|
||||
session_id = session->mSessionID;
|
||||
// <AS:chanayane> [FIRE-34494] fix unable to open an IM with someone who started a group chat
|
||||
// new_session = false;
|
||||
// session_id = session->mSessionID;
|
||||
|
||||
// Protect against wrong session type reuse (e.g., conference reused for IM)
|
||||
if (session->mType != dialog)
|
||||
{
|
||||
LL_WARNS("IMVIEW") << "Discarding mismatched session type reuse: expected "
|
||||
<< dialog << " but found " << session->mType
|
||||
<< " for session " << session->mSessionID
|
||||
<< ". This may indicate improper reuse of a session object." << LL_ENDL;
|
||||
session = nullptr;
|
||||
new_session = true;
|
||||
session_id = computeSessionID(dialog, other_participant_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_session = false;
|
||||
session_id = session->mSessionID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (session && session->mType != dialog)
|
||||
{
|
||||
// Prevent reusing a session of the wrong type
|
||||
session = nullptr;
|
||||
new_session = true;
|
||||
|
||||
// Recompute session ID depending on dialog type
|
||||
if (dialog == IM_SESSION_CONFERENCE_START)
|
||||
{
|
||||
session_id.generate();
|
||||
}
|
||||
else
|
||||
{
|
||||
session_id = computeSessionID(dialog, other_participant_id);
|
||||
}
|
||||
// </AS:chanayane>
|
||||
}
|
||||
|
||||
//Notify observers that a session was added
|
||||
if (new_session)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -346,6 +346,15 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
LL_DEBUGS("LLLogin") << "reason " << reason_response
|
||||
<< " message " << message_response
|
||||
<< LL_ENDL;
|
||||
|
||||
if (response.has("mfa_hash"))
|
||||
{
|
||||
mRequestData["params"]["mfa_hash"] = response["mfa_hash"];
|
||||
mRequestData["params"]["token"] = "";
|
||||
|
||||
saveMFAHash(response);
|
||||
}
|
||||
|
||||
// For the cases of critical message or TOS agreement,
|
||||
// start the TOS dialog. The dialog response will be handled
|
||||
// by the LLLoginInstance::handleTOSResponse() callback.
|
||||
|
|
@ -609,6 +618,24 @@ bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & respon
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLLoginInstance::saveMFAHash(LLSD const& response)
|
||||
{
|
||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||
std::string user_id(LLStartUp::getUserId());
|
||||
|
||||
// Only save mfa_hash for future logins if the user wants their info remembered.
|
||||
if (response.has("mfa_hash") && gSavedSettings.getBOOL("RememberUser") && LLLoginInstance::getInstance()->saveMFA())
|
||||
{
|
||||
gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
|
||||
}
|
||||
else if (!LLLoginInstance::getInstance()->saveMFA())
|
||||
{
|
||||
gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id);
|
||||
}
|
||||
// TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically
|
||||
gSecAPIHandler->syncProtectedMap();
|
||||
}
|
||||
|
||||
std::string construct_start_string()
|
||||
{
|
||||
std::string start;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ public:
|
|||
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
|
||||
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
|
||||
|
||||
void saveMFAHash(LLSD const& response);
|
||||
|
||||
private:
|
||||
typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr;
|
||||
void constructAuthParams(LLPointer<LLCredential> user_credentials);
|
||||
|
|
|
|||
|
|
@ -6215,6 +6215,19 @@ bool LLMeshRepository::meshUploadEnabled()
|
|||
bool LLMeshRepository::meshRezEnabled()
|
||||
{
|
||||
static LLCachedControl<bool> mesh_enabled(gSavedSettings, "MeshEnabled");
|
||||
// <FS:Beq> FIRE-35602 etc - Mesh not appearing after TP/login (opensim only)
|
||||
// For OpenSim there is still an outside chance that mesh rezzing is disabled on the sim/region
|
||||
// restore the old behaviour but keep the bias to mesh_enabled == true in the underlying checks.
|
||||
#ifdef OPENSIM
|
||||
if (LLGridManager::instance().isInOpenSim())
|
||||
{
|
||||
if (LLViewerRegion* region = gAgent.getRegion(); mesh_enabled && region)
|
||||
{
|
||||
return region->meshRezEnabled();
|
||||
}
|
||||
}
|
||||
#endif // OPENSIM
|
||||
// </FS:Beq>
|
||||
return mesh_enabled;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
||||
#include "fsfloaterprimfeed.h" // <FS:Beq> Share to Primfeed
|
||||
|
||||
/**
|
||||
* Provides several ways to save a snapshot.
|
||||
|
|
@ -52,6 +53,7 @@ private:
|
|||
void onSaveToInventory();
|
||||
void onSaveToComputer();
|
||||
void onSendToFlickr(); // <FS:Ansariel> Share to Flickr
|
||||
void onSendToPrimfeed(); // <FS:Beq/> Share to Primfeed
|
||||
|
||||
LLFloaterSnapshotBase* mSnapshotFloater;
|
||||
};
|
||||
|
|
@ -65,6 +67,7 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
|
|||
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
|
||||
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
|
||||
mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this)); // <FS:Ansariel> Share to Flickr
|
||||
mCommitCallbackRegistrar.add("Snapshot.SendToPrimfeed", boost::bind(&LLPanelSnapshotOptions::onSendToPrimfeed, this)); // <FS:Beq/> Share to Primfeed
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -113,11 +116,23 @@ void LLPanelSnapshotOptions::onSendToFlickr()
|
|||
{
|
||||
LLFloaterReg::hideInstance("snapshot");
|
||||
|
||||
LLFloaterFlickr* flickr_floater = dynamic_cast<LLFloaterFlickr*>(LLFloaterReg::getInstance("flickr"));
|
||||
if (flickr_floater)
|
||||
if (auto flickr_floater = LLFloaterReg::getTypedInstance<LLFloaterFlickr>("flickr"))
|
||||
{
|
||||
flickr_floater->showPhotoPanel();
|
||||
}
|
||||
LLFloaterReg::showInstance("flickr");
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
// <FS:Beq> Share to Primfeed
|
||||
void LLPanelSnapshotOptions::onSendToPrimfeed()
|
||||
{
|
||||
LLFloaterReg::hideInstance("snapshot");
|
||||
|
||||
if (auto primfeed_floater = LLFloaterReg::getTypedInstance<FSFloaterPrimfeed>("primfeed"))
|
||||
{
|
||||
primfeed_floater->showPhotoPanel();
|
||||
}
|
||||
LLFloaterReg::showInstance("primfeed");
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
|
|
|||
|
|
@ -8002,19 +8002,20 @@ bool LLSelectMgr::canSelectObject(LLViewerObject* object, bool ignore_select_own
|
|||
// only select my own objects
|
||||
return false;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> FIRE-14593: Option to select only copyable objects
|
||||
if (!object->permCopy() && gSavedSettings.getBOOL("FSSelectCopyableOnly"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> FIRE-17696: Option to select only locked objects
|
||||
if (gSavedSettings.getBOOL("FSSelectLockedOnly") && object->permMove() && !object->isPermanentEnforced())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>// Can't select objects that are not owned by you or group
|
||||
}
|
||||
// <FS:Ansariel> FIRE-14593: Option to select only copyable objects
|
||||
if (!object->permCopy() && gSavedSettings.getBOOL("FSSelectCopyableOnly"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> FIRE-17696: Option to select only locked objects
|
||||
if (gSavedSettings.getBOOL("FSSelectLockedOnly") && object->permMove() && !object->isPermanentEnforced())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Can't select orphans
|
||||
if (object->isOrphaned()) return false;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llfloaterperms.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
||||
#include "fsfloaterprimfeed.h" // <FS:Beq> Share to Primfeed
|
||||
#include "llimagefilter.h"
|
||||
#include "llimagefiltersmanager.h"
|
||||
#include "llimagebmp.h"
|
||||
|
|
|
|||
|
|
@ -1950,9 +1950,9 @@ bool idle_startup()
|
|||
// <FS:Ansariel> Wait for notification confirmation
|
||||
if (STATE_LOGIN_CONFIRM_NOTIFICATON == LLStartUp::getStartupState())
|
||||
{
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
gViewerWindow->getProgressView()->setVisible(false);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
ms_sleep(1);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2298,10 +2298,10 @@ bool idle_startup()
|
|||
//so I just moved nearby history loading a few states further
|
||||
if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
|
||||
{
|
||||
FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance();
|
||||
if (nearby_chat) nearby_chat->loadHistory();
|
||||
if (FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance())
|
||||
nearby_chat->loadHistory();
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// </FS:Ansariel> [FS communication UI]
|
||||
|
||||
// <FS:KC> FIRE-18250: Option to disable default eye movement
|
||||
|
|
@ -2549,13 +2549,14 @@ bool idle_startup()
|
|||
LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
|
||||
LLStatusBar::sendMoneyBalanceRequest();
|
||||
|
||||
do_startup_frame();
|
||||
// <FS:Ansariel> Moved before inventory creation.
|
||||
// request all group information
|
||||
LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Requesting Agent Data during startup" << LL_ENDL;
|
||||
gAgent.sendAgentDataUpdateRequest();
|
||||
display_startup();
|
||||
// </FS:Ansariel>
|
||||
|
||||
do_startup_frame();
|
||||
|
||||
// Inform simulator of our language preference
|
||||
LLAgentLanguage::update();
|
||||
|
||||
|
|
@ -2808,7 +2809,7 @@ bool idle_startup()
|
|||
// Create the inventory views
|
||||
LL_INFOS() << "Creating Inventory Views" << LL_ENDL;
|
||||
LLFloaterReg::getInstance("inventory");
|
||||
//do_startup_frame();
|
||||
do_startup_frame();
|
||||
|
||||
// [RLVa:KB] - Checked: RLVa-1.1.0
|
||||
if (RlvHandler::isEnabled())
|
||||
|
|
@ -2898,7 +2899,7 @@ bool idle_startup()
|
|||
//ok, we're done, set it back to false.
|
||||
gSavedSettings.setBOOL("FSFirstRunAfterSettingsRestore", false);
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// </FS:CR>
|
||||
|
||||
if (gSavedSettings.getBOOL("HelpFloaterOpen"))
|
||||
|
|
@ -3074,7 +3075,7 @@ bool idle_startup()
|
|||
}
|
||||
}
|
||||
#endif // OPENSIM
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// </FS:CR>
|
||||
|
||||
LLStartUp::setStartupState( STATE_PRECACHE );
|
||||
|
|
@ -4972,24 +4973,7 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
|
|||
LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);
|
||||
}
|
||||
|
||||
// Only save mfa_hash for future logins if the user wants their info remembered.
|
||||
if(response.has("mfa_hash")
|
||||
&& gSavedSettings.getBOOL("RememberUser")
|
||||
&& LLLoginInstance::getInstance()->saveMFA())
|
||||
{
|
||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||
std::string user_id(gUserCredential->userID());
|
||||
gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
|
||||
// TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically
|
||||
gSecAPIHandler->syncProtectedMap();
|
||||
}
|
||||
else if (!LLLoginInstance::getInstance()->saveMFA())
|
||||
{
|
||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||
std::string user_id(gUserCredential->userID());
|
||||
gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id);
|
||||
gSecAPIHandler->syncProtectedMap();
|
||||
}
|
||||
LLLoginInstance::getInstance()->saveMFAHash(response);
|
||||
|
||||
// <FS:Ansariel> OpenSim legacy economy support
|
||||
#ifdef OPENSIM
|
||||
|
|
@ -5092,6 +5076,7 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
|
|||
}
|
||||
// </FS:Techwolf Lupindo>
|
||||
|
||||
|
||||
bool success = false;
|
||||
// JC: gesture loading done below, when we have an asset system
|
||||
// in place. Don't delete/clear gUserCredentials until then.
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
#include "llavatarname.h"
|
||||
#include "llavatarnamecache.h"
|
||||
|
||||
#include "llviewernetwork.h" // <FS/> Access to GridManager
|
||||
#include "lfsimfeaturehandler.h" // <FS/> Access to hyperGridURL
|
||||
#include "llworldmapmessage.h" // <FS/> Access to sendNamedRegionRequest
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b)
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
|
@ -98,6 +102,46 @@ void LLTeleportHistory::goToItem(int idx)
|
|||
return;
|
||||
}
|
||||
|
||||
// <FS> [FIRE-35355] OpenSim global position is dependent on the Grid you are on
|
||||
#ifdef OPENSIM
|
||||
if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
if (mItems[mCurrentItem].mRegionID != mItems[idx].mRegionID)
|
||||
{
|
||||
LLSLURL slurl = mItems[idx].mSLURL;
|
||||
std::string grid = slurl.getGrid();
|
||||
std::string current_grid = LFSimFeatureHandler::instance().hyperGridURL();
|
||||
std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);
|
||||
|
||||
// Requesting region information from the server is only required when changing grid
|
||||
if (slurl.isValid() && grid != current_grid)
|
||||
{
|
||||
if (!gatekeeper.empty())
|
||||
{
|
||||
slurl = LLSLURL(gatekeeper + ":" + slurl.getRegion(), slurl.getPosition(), true);
|
||||
}
|
||||
|
||||
if (mRequestedItem != -1)
|
||||
{
|
||||
return; // We already have a request in progress and don't want to spam the server
|
||||
}
|
||||
|
||||
mRequestedItem = idx;
|
||||
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(
|
||||
slurl.getRegion(),
|
||||
boost::bind(&LLTeleportHistory::regionNameCallback, this, idx, _1, _2, _3, _4),
|
||||
slurl.getSLURLString(),
|
||||
true
|
||||
);
|
||||
|
||||
return; // The teleport will occur in the callback with the correct global position
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// </FS>
|
||||
|
||||
// Attempt to teleport to the requested item.
|
||||
gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
|
||||
mRequestedItem = idx;
|
||||
|
|
@ -210,6 +254,22 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
|
|||
mItems[mCurrentItem] = LLTeleportHistoryItem(RlvStrings::getString(RlvStringKeys::Hidden::Parcel), LLVector3d::zero);
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
// <FS> [FIRE-35355] OpenSim global position is dependent on the Grid you are on,
|
||||
// so we need to store the slurl so we can request the global position later
|
||||
#ifdef OPENSIM
|
||||
if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
auto regionp = gAgent.getRegion();
|
||||
if (regionp)
|
||||
{
|
||||
LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos);
|
||||
LLSLURL slurl = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), regionp->getName(), new_pos_local);
|
||||
mItems[mCurrentItem].mSLURL = slurl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// </FS>
|
||||
}
|
||||
|
||||
//dump(); // LO - removing the dump from happening every time we TP.
|
||||
|
|
@ -287,3 +347,35 @@ void LLTeleportHistory::dump() const
|
|||
LL_INFOS() << line.str() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// <FS> [FIRE-35355] Callback for OpenSim so we can teleport to the correct global position on another grid
|
||||
void LLTeleportHistory::regionNameCallback(int idx, U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
|
||||
{
|
||||
if (region_handle)
|
||||
{
|
||||
// Sanity checks again just in case since time has passed since the request was made
|
||||
if (idx < 0 || idx >= (int)mItems.size())
|
||||
{
|
||||
LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx == mCurrentItem)
|
||||
{
|
||||
LL_WARNS() << "Will not teleport to the same location." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLVector3d origin_pos = from_region_handle(region_handle);
|
||||
LLVector3d global_pos(origin_pos + LLVector3d(slurl.getPosition()));
|
||||
|
||||
// Attempt to teleport to the target grids region
|
||||
gAgent.teleportViaLocation(global_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Invalid teleport history region handle" << LL_ENDL;
|
||||
onTeleportFailed();
|
||||
}
|
||||
}
|
||||
// </FS>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include <boost/signals2.hpp>
|
||||
#include "llteleporthistorystorage.h"
|
||||
|
||||
#include "llslurl.h" // <FS/> Access to LLSLURL
|
||||
|
||||
|
||||
/**
|
||||
* An item of the teleport history.
|
||||
|
|
@ -47,8 +49,11 @@ public:
|
|||
LLTeleportHistoryItem()
|
||||
{}
|
||||
|
||||
LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
|
||||
: mTitle(title), mGlobalPos(global_pos)
|
||||
// <FS> [FIRE-35355] OpenSim requires knowing the grid to teleport correctly if changing grids
|
||||
//LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
|
||||
// : mTitle(title), mGlobalPos(global_pos)
|
||||
LLTeleportHistoryItem(std::string title, LLVector3d global_pos, const LLSLURL& slurl = LLSLURL())
|
||||
: mTitle(title), mGlobalPos(global_pos), mSLURL(slurl)
|
||||
{}
|
||||
|
||||
/**
|
||||
|
|
@ -61,6 +66,7 @@ public:
|
|||
std::string mFullTitle; // human-readable location title including coordinates
|
||||
LLVector3d mGlobalPos; // global position
|
||||
LLUUID mRegionID; // region ID for getting the region info
|
||||
LLSLURL mSLURL; // <FS/> [FIRE-35355] slurl for the location required for OpenSim
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -180,6 +186,10 @@ private:
|
|||
*/
|
||||
static std::string getCurrentLocationTitle(bool full, const LLVector3& local_pos_override);
|
||||
|
||||
// <FS> [FIRE-35355] Callback for OpenSim so we can teleport to the correct global position on another grid
|
||||
void regionNameCallback(int idx, U64 handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport);
|
||||
// </FS>
|
||||
|
||||
/**
|
||||
* Actually, the teleport history.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@
|
|||
#include "lggbeamcolormapfloater.h"
|
||||
#include "lggbeammapfloater.h"
|
||||
#include "llfloaterdisplayname.h"
|
||||
#include "fsfloaterprimfeed.h"
|
||||
#include "llfloaterflickr.h"
|
||||
#include "llfloaterscriptrecover.h"
|
||||
#include "llfloatersearchreplace.h"
|
||||
|
|
@ -632,6 +633,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("export_collada", "floater_export_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ColladaExportFloater>);
|
||||
LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>);
|
||||
LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
|
||||
LLFloaterReg::add("primfeed", "floater_primfeed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPrimfeed>);
|
||||
LLFloaterReg::add("fs_asset_blacklist", "floater_fs_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAssetBlacklist>);
|
||||
LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAvatarRenderSettings>);
|
||||
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
|
||||
|
|
|
|||
|
|
@ -2757,6 +2757,28 @@ class LLAdvancedCompressFileTest : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
// <FS:Beq> Primfeed integration test functions (can be removed when the feature is stable)
|
||||
///////////////////
|
||||
// PRIMFEED AUTH //
|
||||
///////////////////
|
||||
#include "fsprimfeedauth.h"
|
||||
class LLAdvancedPrimfeedAuth : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
FSPrimfeedAuth::initiateAuthRequest();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
class LLAdvancedPrimfeedAuthReset : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
FSPrimfeedAuth::resetAuthStatus();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// </FS:Beq>
|
||||
|
||||
/////////////////////////
|
||||
// SHOW DEBUG SETTINGS //
|
||||
|
|
@ -11787,6 +11809,19 @@ class LLWorldEnvSettings : public view_listener_t
|
|||
#endif
|
||||
// </FS:Beq>
|
||||
|
||||
// <FS:Darl> Redundant environment toggles revert to shared environment
|
||||
LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL);
|
||||
LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null;
|
||||
bool repeatedEnvTogglesShared = gSavedSettings.getBOOL("FSRepeatedEnvTogglesShared");
|
||||
|
||||
if(repeatedEnvTogglesShared && ((skyid == LLEnvironment::KNOWN_SKY_SUNRISE && event_name == "sunrise") ||
|
||||
(skyid == LLEnvironment::KNOWN_SKY_MIDDAY && event_name == "noon") ||
|
||||
(skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY && event_name == "legacy noon") ||
|
||||
(skyid == LLEnvironment::KNOWN_SKY_SUNSET && event_name == "sunset") ||
|
||||
(skyid == LLEnvironment::KNOWN_SKY_MIDNIGHT && event_name == "midnight")))
|
||||
event_name = "region";
|
||||
// </FS:Darl>
|
||||
|
||||
if (event_name == "sunrise")
|
||||
{
|
||||
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
||||
|
|
@ -12809,6 +12844,8 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
|
||||
view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
|
||||
view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest");
|
||||
view_listener_t::addMenu(new LLAdvancedPrimfeedAuth(), "Advanced.PrimfeedAuth");
|
||||
view_listener_t::addMenu(new LLAdvancedPrimfeedAuthReset(), "Advanced.PrimfeedAuthReset");
|
||||
view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
|
||||
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
|
||||
view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
|
||||
|
|
|
|||
|
|
@ -6674,6 +6674,7 @@ void process_alert_core(const std::string& message, bool modal)
|
|||
if (text.substr(0, restart_cancelled.length()) == restart_cancelled)
|
||||
{
|
||||
LLFloaterRegionRestarting::close();
|
||||
fs_report_region_restart_to_channel(-1); // <FS:Darl> Announce region restart to a defined chat channel
|
||||
}
|
||||
|
||||
std::string new_msg =LLNotifications::instance().getGlobalString(text);
|
||||
|
|
@ -8742,7 +8743,14 @@ void fs_report_region_restart_to_channel(S32 seconds)
|
|||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_ChatData);
|
||||
msg->addStringFast(_PREHASH_Message, "region_restart_in:" + llformat("%d", seconds));
|
||||
if(seconds >= 0)
|
||||
{
|
||||
msg->addStringFast(_PREHASH_Message, "region_restart_in:" + llformat("%d", seconds));
|
||||
}
|
||||
else // Input is a negative number
|
||||
{
|
||||
msg->addStringFast(_PREHASH_Message, "region_restart_cancelled");
|
||||
}
|
||||
msg->addU8Fast(_PREHASH_Type, CHAT_TYPE_WHISPER);
|
||||
msg->addS32("Channel", channel);
|
||||
gAgent.sendReliableMessage();
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ namespace
|
|||
|
||||
void newRegionEntry(LLViewerRegion& region)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> improve instrumentation
|
||||
LL_INFOS("LLViewerRegion") << "Entering region [" << region.getName() << "]" << LL_ENDL;
|
||||
gDebugInfo["CurrentRegion"] = region.getName();
|
||||
LLAppViewer::instance()->writeDebugInfo();
|
||||
|
|
@ -3983,6 +3984,15 @@ bool LLViewerRegion::bakesOnMeshEnabled() const
|
|||
mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean());
|
||||
}
|
||||
|
||||
// <FS:Beq> FIRE-35602 etc - Mesh not appearing after TP/login (opensim only)
|
||||
#ifdef OPENSIM
|
||||
bool LLViewerRegion::meshRezEnabled() const
|
||||
{
|
||||
return (mSimulatorFeatures.has("MeshRezEnabled") && mSimulatorFeatures["MeshRezEnabled"].asBoolean());
|
||||
}
|
||||
#endif
|
||||
// </FS:Beq>
|
||||
|
||||
bool LLViewerRegion::dynamicPathfindingEnabled() const
|
||||
{
|
||||
return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
|
||||
|
|
|
|||
|
|
@ -355,7 +355,10 @@ public:
|
|||
U8 getCentralBakeVersion() { return mCentralBakeVersion; }
|
||||
|
||||
void getInfo(LLSD& info);
|
||||
|
||||
// <FS:Beq> FIRE-35602 etc - Mesh not appearing after TP/login (opensim only)
|
||||
#ifdef OPENSIM
|
||||
#endif // OPENSIM
|
||||
// </FS:Beq>
|
||||
bool meshUploadEnabled() const;
|
||||
|
||||
bool bakesOnMeshEnabled() const;
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@
|
|||
#include "llfloatertools.h"
|
||||
#include "llfloatersnapshot.h" // <FS:Beq/> for snapshotFrame
|
||||
#include "llfloaterflickr.h" // <FS:Beq/> for snapshotFrame
|
||||
#include "fsfloaterprimfeed.h" // <FS:Beq/> for snapshotFrame
|
||||
#include "llsnapshotlivepreview.h" // <FS:Beq/> for snapshotFrame
|
||||
// #include "llpanelface.h" // <FS:Zi> switchable edit texture/materials panel - include not needed
|
||||
#include "llpathfindingpathtool.h"
|
||||
|
|
@ -8049,12 +8050,12 @@ bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst)
|
|||
}
|
||||
const bool simple_snapshot_visible = LLFloaterReg::instanceVisible("simple_snapshot");
|
||||
const bool flickr_snapshot_visible = LLFloaterReg::instanceVisible("flickr");
|
||||
const bool primfeed_snapshot_visible = LLFloaterReg::instanceVisible("primfeed"); // <FS:Beq/> Primfeed integration
|
||||
const bool snapshot_visible = LLFloaterReg::instanceVisible("snapshot");
|
||||
const bool any_snapshot_visible = simple_snapshot_visible || flickr_snapshot_visible || snapshot_visible;
|
||||
const bool any_snapshot_visible = simple_snapshot_visible || flickr_snapshot_visible || primfeed_snapshot_visible || snapshot_visible; // <FS:Beq/> Primfeed integration
|
||||
if (!show_frame || !any_snapshot_visible || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
LLSnapshotLivePreview * previewView = nullptr;
|
||||
if (snapshot_visible)
|
||||
|
|
@ -8068,6 +8069,13 @@ bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst)
|
|||
auto * floater = dynamic_cast<LLFloaterFlickr*>(LLFloaterReg::findInstance("flickr"));
|
||||
previewView = floater->getPreviewView();
|
||||
}
|
||||
// <FS:Beq> Primfeed integration
|
||||
if (primfeed_snapshot_visible && !previewView)
|
||||
{
|
||||
auto * floater = dynamic_cast<FSFloaterPrimfeed*>(LLFloaterReg::findInstance("primfeed"));
|
||||
previewView = floater->getPreviewView();
|
||||
}
|
||||
// </FS:Beq>
|
||||
if(!previewView)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_skin_panel">
|
||||
<panel name="avatar_skin_color_panel">
|
||||
<texture_picker label="Głowa" name="Head" tool_tip="Kliknij aby wybrać teksturę"/>
|
||||
<texture_picker label="Głowa" name="Head" tool_tip="Kliknij, aby wybrać teksturę"/>
|
||||
<texture_picker label="Górne ciało" name="Upper Body" tool_tip="Kliknij aby wybrać teksturę"/>
|
||||
<texture_picker label="Dolne ciało" name="Lower Body" tool_tip="Kliknij aby wybrać teksturę"/>
|
||||
</panel>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="camera_floater" title="Configurações da câmera">
|
||||
<floater.string name="rotate_tooltip">
|
||||
Girar a câmera em torno do foco
|
||||
</floater.string>
|
||||
<floater.string name="zoom_tooltip">
|
||||
Zoom da câmera em direção ao foco
|
||||
</floater.string>
|
||||
<floater.string name="move_tooltip">
|
||||
Mover a câmera para cima, para baixo, esquerda e direita
|
||||
</floater.string>
|
||||
<floater.string name="free_mode_title">
|
||||
Visualizar Objeto
|
||||
</floater.string>
|
||||
<string name="inactive_combo_text">
|
||||
Use a predefinição
|
||||
</string>
|
||||
<panel name="controls">
|
||||
<panel name="zoom">
|
||||
<joystick_rotate name="cam_rotate_stick" tool_tip="Girar câmera ao redor do foco"/>
|
||||
<button name="roll_left" tool_tip="Girar câmera para esquerda"/>
|
||||
<button name="roll_right" tool_tip="Girar câmera para direita"/>
|
||||
<slider_bar name="zoom_slider" tool_tip="Zoom da câmera para focalizar"/>
|
||||
<joystick_track name="cam_track_stick" tool_tip="Mover a câmera para cima, para baixo, esquerda e direita"/>
|
||||
</panel>
|
||||
</panel>
|
||||
<panel name="buttons_panel">
|
||||
<panel_camera_item name="front_view" tool_tip="Vista frontal"/>
|
||||
<panel_camera_item name="group_view" tool_tip="Visualização de grupo"/>
|
||||
<panel_camera_item name="rear_view" tool_tip="Visão trazeira"/>
|
||||
<panel_camera_item name="object_view" tool_tip="Visualização do objeto"/>
|
||||
<panel_camera_item name="mouselook_view" tool_tip="Visão em primeira pessoa"/>
|
||||
<panel_camera_item name="reset_view" tool_tip="Redefinir visão"/>
|
||||
</panel>
|
||||
<combo_box name="preset_combo">
|
||||
<combo_box.item label="Aplicar predefinição" name="Use preset" />
|
||||
</combo_box>
|
||||
<button name="gear_btn" tool_tip="Predefinições da câmera" />
|
||||
<button label="Posição da câmera" name="camera_position_btn" />
|
||||
<button label="Salvar" name="save_btn" />
|
||||
</floater>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="preview_texture">
|
||||
<floater.string name="Title">
|
||||
Textura: [NAME]
|
||||
</floater.string>
|
||||
<floater.string name="Copy">
|
||||
Copiar para o inventário
|
||||
</floater.string>
|
||||
<floater.string name="DateTime">
|
||||
[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt], [hour24, datetime, slt]:[min, datetime, slt]:[second, datetime, slt] [timezone, datetime, slt]
|
||||
</floater.string>
|
||||
<text name="desc txt">
|
||||
Descrição:
|
||||
</text>
|
||||
<text name="uploader_label">
|
||||
Carregado por:
|
||||
</text>
|
||||
<button label="Perfil" name="openprofile"/>
|
||||
<text name="upload_time_label">
|
||||
Data:
|
||||
</text>
|
||||
<button name="copyuuid" label="Copiar"/>
|
||||
<panel name="dimensions_panel">
|
||||
<text name="aspect_ratio">
|
||||
Visualizar a aparência
|
||||
</text>
|
||||
<combo_box name="combo_aspect_ratio" tool_tip="Pré-visualização com uma determinada proporção de aparência">
|
||||
<combo_item name="Unconstrained">
|
||||
Sem restrição
|
||||
</combo_item>
|
||||
<combo_item name="1:1" tool_tip="Emblema de grupo ou informação adicional de perfil"/>
|
||||
<combo_item name="4:3" tool_tip="Perfil [CURRENT_GRID]"/>
|
||||
<combo_item name="10:7" tool_tip="Classificados e listas de pesquisa, marcos"/>
|
||||
<combo_item name="3:2" tool_tip="Sobre o terreno"/>
|
||||
<combo_item name="16:9" tool_tip="Destacados"/>
|
||||
</combo_box>
|
||||
</panel>
|
||||
<panel name="button_panel">
|
||||
<button label="Aceitar" name="Keep"/>
|
||||
<button label="Descartar" name="Discard"/>
|
||||
<flyout_button label="Salvar..." name="save_tex_btn">
|
||||
<flyout_button.item label="Salvar como TGA" name="save_item_tga"/>
|
||||
<flyout_button.item label="Salvar como PNG" name="save_item_png"/>
|
||||
</flyout_button>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_eyes_panel">
|
||||
<panel name="avatar_eye_color_panel">
|
||||
<texture_picker label="Iris" name="Iris" tool_tip="Toque para escolher uma imagem"/>
|
||||
</panel>
|
||||
<panel name="eyes_main_tab_holder">
|
||||
<accordion name="eyes_main_accordion">
|
||||
<accordion_tab name="eyes_main_tab" title="Olhos"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_gloves_panel">
|
||||
<panel name="avatar_gloves_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="gloves_main_tab_holder">
|
||||
<accordion name="gloves_main_accordion">
|
||||
<accordion_tab name="gloves_main_tab" title="Luvas"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_hair_panel">
|
||||
<panel name="avatar_hair_color_panel">
|
||||
<texture_picker label="Textura" name="Texture" tool_tip="Toque para escolher uma imagem"/>
|
||||
</panel>
|
||||
<accordion name="wearable_accordion">
|
||||
<panel name="hair_color_tab_holder" title="Cor">
|
||||
<accordion name="hair_color_accordion">
|
||||
<accordion_tab name="hair_color_tab" title="Cor"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="hair_style_tab_holder" title="Estilo">
|
||||
<accordion name="hair_style_accordion">
|
||||
<accordion_tab name="hair_style_tab" title="Estilo"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="hair_eyebrows_tab_holder" title="Sobrancelhas">
|
||||
<accordion name="hair_eyebrows_accordion">
|
||||
<accordion_tab name="hair_eyebrows_tab" title="Sobrancelhas"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="hair_facial_tab_holder" title="Faciais">
|
||||
<text name="hair_facial_not_available">
|
||||
As opções de pelos faciais
|
||||
estão disponíveis apenas para avatares masculinos.
|
||||
</text>
|
||||
<accordion name="hair_facial_accordion">
|
||||
<accordion_tab name="hair_facial_tab" title="Faciais"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</accordion>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_jacket_panel">
|
||||
<panel name="avatar_jacket_color_panel">
|
||||
<texture_picker label="Textura superior" name="Upper Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<texture_picker label="Textura inferior" name="Lower Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="jacket_main_tab_holder">
|
||||
<accordion name="jacket_main_accordion">
|
||||
<accordion_tab name="jacket_main_tab" title="Jaqueta"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_pants_panel">
|
||||
<panel name="avatar_pants_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="pants_main_tab_holder">
|
||||
<accordion name="pants_main_accordion">
|
||||
<accordion_tab name="pants_main_tab" title="Calças"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_physics_panel">
|
||||
<tab_container name="wearable_accordion">
|
||||
<panel name="physics_breast_updown_tab_holder" title="Seios - movimento vertical">
|
||||
<text name="physics_breast_updown_not_available">
|
||||
O movimento dos seios está disponível
|
||||
apenas para avatares femininos.
|
||||
</text>
|
||||
<accordion name="physics_breast_updown_accordion">
|
||||
<accordion_tab name="physics_breasts_updown_tab" title="Seios - movimento vertical"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="physics_breast_inout_tab_holder" title="Seios - decote">
|
||||
<text name="physics_breast_inout_not_available">
|
||||
O decote está disponível
|
||||
apenas para avatares femininos.
|
||||
</text>
|
||||
<accordion name="physics_breast_inout_accordion">
|
||||
<accordion_tab name="physics_breasts_inout_tab" title="Seios - decote"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="physics_breast_leftright_tab_holder" title="Seios - movimento horizontal">
|
||||
<text name="physics_breast_leftright_not_available">
|
||||
O movimento dos seios está disponível
|
||||
apenas para avatares femininos.
|
||||
</text>
|
||||
<accordion name="physics_breast_leftright_accordion">
|
||||
<accordion_tab name="physics_breasts_leftright_tab" title="Seios - movimento horizontal"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="physics_belly_tab_holder" title="Barriga - movimento vertical">
|
||||
<accordion name="physics_belly_accordion">
|
||||
<accordion_tab name="physics_belly_tab" title="Barriga - movimento vertical"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="physics_butt_tab_holder" title="Nádegas - movimento vertical">
|
||||
<accordion name="physics_butt_accordion">
|
||||
<accordion_tab name="physics_butt_tab" title="Nádegas - movimento vertical"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="physics_butt_leftright_tab_holder" title="Nádegas - movimento horizontal">
|
||||
<accordion name="physics_butt_leftright_accordion">
|
||||
<accordion_tab name="physics_butt_leftright_tab" title="Nádegas - movimento horizontal"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="physics_advanced_tab_holder" title="Parâmetros avançados">
|
||||
<accordion name="physics_advanced_accordion">
|
||||
<accordion_tab name="physics_advanced_tab" title="Parâmetros avançados"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</tab_container>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_shape_panel">
|
||||
<string name="meters">
|
||||
Metros
|
||||
</string>
|
||||
<string name="feet">
|
||||
Pés
|
||||
</string>
|
||||
<string name="height">
|
||||
Altura:
|
||||
</string>
|
||||
<tab_container name="wearable_accordion">
|
||||
<panel name="shape_body_tab_holder" title="Corpo">
|
||||
<accordion name="shape_body_accordion">
|
||||
<accordion_tab name="shape_body_tab" title="Corpo"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_head_tab_holder" title="Cabeça">
|
||||
<accordion name="shape_head_accordion">
|
||||
<accordion_tab name="shape_head_tab" title="Cabeça"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_eyes_tab_holder" title="Olhos">
|
||||
<accordion name="shape_eyes_accordion">
|
||||
<accordion_tab name="shape_eyes_tab" title="Olhos"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_ears_tab_holder" title="Orelhas">
|
||||
<accordion name="shape_ears_accordion">
|
||||
<accordion_tab name="shape_ears_tab" title="Orelhas"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_nose_tab_holder" title="Nariz">
|
||||
<accordion name="shape_nose_accordion">
|
||||
<accordion_tab name="shape_nose_tab" title="Nariz"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_mouth_tab_holder" title="Boca">
|
||||
<accordion name="shape_mouth_accordion">
|
||||
<accordion_tab name="shape_mouth_tab" title="Boca"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_chin_tab_holder" title="Queixo">
|
||||
<accordion name="shape_chin_accordion">
|
||||
<accordion_tab name="shape_chin_tab" title="Queixo"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_torso_tab_holder" title="Tronco">
|
||||
<accordion name="shape_torso_accordion">
|
||||
<accordion_tab name="shape_torso_tab" title="Tronco"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="shape_legs_tab_holder" title="Pernas">
|
||||
<accordion name="shape_legs_accordion">
|
||||
<accordion_tab name="shape_legs_tab" title="Pernas"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</tab_container>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_shirt_panel">
|
||||
<panel name="avatar_shirt_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor" name="Cor/Matiz" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="shirt_main_tab_holder">
|
||||
<accordion name="shirt_main_accordion">
|
||||
<accordion_tab name="shirt_main_tab" title="Camisa"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_shoes_panel">
|
||||
<panel name="avatar_shoes_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor" name="Cor/Tonalid" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="shoes_main_tab_holder">
|
||||
<accordion name="shoes_main_accordion">
|
||||
<accordion_tab name="shoes_main_tab" title="Sapatos"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_skin_panel">
|
||||
<panel name="avatar_skin_color_panel">
|
||||
<texture_picker label="Cabeça" name="Head" tool_tip="Clique para selecionar a textura"/>
|
||||
<texture_picker label="Parte sup." name="Upper Body" tool_tip="Toque para escolher uma imagem"/>
|
||||
<texture_picker label="Parte inf." name="Lower Body" tool_tip="Toque para escolher uma imagem"/>
|
||||
</panel>
|
||||
<tab_container name="wearable_accordion">
|
||||
<panel name="skin_color_tab_holder" title="Cor da pele">
|
||||
<accordion name="skin_color_accordion">
|
||||
<accordion_tab name="skin_color_tab" title="Cor da pele"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="skin_face_tab_holder" title="Detalhe do rosto">
|
||||
<accordion name="skin_face_accordion">
|
||||
<accordion_tab name="skin_face_tab" title="Detalhe do rosto"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="skin_makeup_holder" title="Maquiagem">
|
||||
<accordion name="skin_makeup_accordion">
|
||||
<accordion_tab name="skin_makeup_tab" title="Maquiagem"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
<panel name="skin_body_holder" title="Detalhe do corpo">
|
||||
<accordion name="skin_body_accordion">
|
||||
<accordion_tab name="skin_body_tab" title="Detalhe do corpo"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</tab_container>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_skirt_panel">
|
||||
<panel name="avatar_skirt_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="skirt_main_tab_holder">
|
||||
<accordion name="skirt_main_accordion">
|
||||
<accordion_tab name="skirt_main_tab" title="Saia"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_socks_panel">
|
||||
<panel name="avatar_socks_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="socks_main_tab_holder">
|
||||
<accordion name="socks_main_accordion">
|
||||
<accordion_tab name="socks_main_tab" title="Meias"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_underpants_panel">
|
||||
<panel name="avatar_underpants_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="underpants_main_tab_holder">
|
||||
<accordion name="underpants_main_accordion">
|
||||
<accordion_tab name="underpants_main_tab" title="Roupa de baixo"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="edit_undershirt_panel">
|
||||
<panel name="avatar_undershirt_color_panel">
|
||||
<texture_picker label="Textura" name="Fabric" tool_tip="Toque para escolher uma imagem"/>
|
||||
<color_swatch label="Cor/Tonalid" name="Color/Tint" tool_tip="Toque para abrir o seletor de cor"/>
|
||||
</panel>
|
||||
<panel name="undershirt_main_tab_holder">
|
||||
<accordion name="undershirt_main_accordion">
|
||||
<accordion_tab name="undershirt_main_tab" title="Camiseta"/>
|
||||
</accordion>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel label="Sonstiges" name="main inventory panel">
|
||||
<panel.string name="ItemcountFetching">
|
||||
Obtendo [ITEM_COUNT] itens... [FILTER]
|
||||
</panel.string>
|
||||
<panel.string name="ItemcountCompleted">
|
||||
[ITEM_COUNT] itens [FILTER]
|
||||
</panel.string>
|
||||
<menu_bar name="inventory_menu_bar">
|
||||
<menu label="Inventário" name="inventory_inventory_menu">
|
||||
<menu_item_call name="inventory_open" label="Abrir"/>
|
||||
<menu_item_call name="inventory_share" label="Compartilhar"/>
|
||||
<menu_item_call name="inventory_new_window" label="Nova janela"/>
|
||||
<menu_item_check name="add_inv_toggle" label="Vestir"/>
|
||||
<menu_item_call name="inventory_show_filters" label="Mostrar filtros"/>
|
||||
<menu_item_call name="inventory_reset_filters" label="Redefinir filtros"/>
|
||||
<menu_item_call name="inventory_close_all_folders" label="Fechar todas as pastas"/>
|
||||
<menu_item_call name="inventory_empty_trash" label="Esvaziar lixeira"/>
|
||||
</menu>
|
||||
<menu label="Criar" name="inventory_create_menu">
|
||||
<menu_item_call name="inventory_new_folder" label="Pasta"/>
|
||||
<menu_item_call name="inventory_new_script" label="Script"/>
|
||||
<menu_item_call name="inventory_new_note" label="Nota"/>
|
||||
<menu_item_call name="inventory_new_gesture" label="Gesto"/>
|
||||
<menu name="inventory_new_clothes" label="Roupa">
|
||||
<menu_item_call name="inventory_new_shirt" label="Camisa"/>
|
||||
<menu_item_call name="inventory_new_pants" label="Calças"/>
|
||||
<menu_item_call name="inventory_new_shoes" label="Sapatos"/>
|
||||
<menu_item_call name="inventory_new_socks" label="Meias"/>
|
||||
<menu_item_call name="inventory_new_jacket" label="Jaqueta"/>
|
||||
<menu_item_call name="inventory_new_skirt" label="Saia"/>
|
||||
<menu_item_call name="inventory_new_gloves" label="Luvas"/>
|
||||
<menu_item_call name="inventory_new_undershirt" label="Camiseta"/>
|
||||
<menu_item_call name="inventory_new_underpants" label="Roupa íntima"/>
|
||||
<menu_item_call name="inventory_new_tattoo" label="Tatuagem"/>
|
||||
<menu_item_call name="inventory_new_alpha" label="Alpha"/>
|
||||
<menu_item_call name="inventory_new_physics" label="Física"/>
|
||||
</menu>
|
||||
<menu name="inventory_new_body_parts" label="Novas partes do corpo">
|
||||
<menu_item_call name="inventory_new_shape" label="Forma"/>
|
||||
<menu_item_call name="inventory_new_skin" label="Pele"/>
|
||||
<menu_item_call name="inventory_new_hair" label="Cabelo"/>
|
||||
<menu_item_call name="inventory_new_eyes" label="Olhos"/>
|
||||
</menu>
|
||||
</menu>
|
||||
<menu label="Ordenar" name="inventory_sort_menu">
|
||||
<menu_item_check name="inventory_sort_by_name" label="Por nome"/>
|
||||
<menu_item_check name="inventory_sort_by_date" label="Por data"/>
|
||||
<menu_item_check name="inventory_sort_folders_by_name" label="Pastas sempre por nome"/>
|
||||
<menu_item_check name="inventory_sort_system_on_top" label="Pastas do sistema sempre acima"/>
|
||||
</menu>
|
||||
<menu label="Pesquisar" name="inventory_search_menu">
|
||||
<menu_item_check name="inventory_search_by_name" label="Por nome"/>
|
||||
<menu_item_check name="inventory_search_by_creator" label="Por criador"/>
|
||||
<menu_item_check name="inventory_search_by_description" label="Por descrição"/>
|
||||
<menu_item_check name="inventory_search_by_uuid" label="Por UUID"/>
|
||||
<menu_item_check name="inventory_search_by_all" label="Por tudo"/>
|
||||
<menu_item_check name="inventory_filter_show_links" label="Exibir links"/>
|
||||
<menu_item_check name="inventory_filter_only_links" label="Exibir apenas links"/>
|
||||
<menu_item_check name="inventory_filter_hide_links" label="Ocultar links"/>
|
||||
<menu_item_check name="inventory_show_partial_results" label="Mostrar resultados parciais"/>
|
||||
</menu>
|
||||
</menu_bar>
|
||||
<layout_stack name="top_stack">
|
||||
<layout_panel name="filter_panel">
|
||||
<filter_editor label="Filtrar" name="inventory search editor" tool_tip="Digite uma ou mais palavras para procurar, separadas por '+'"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
<layout_stack name="ctrl_stack">
|
||||
<layout_panel name="filter_ctrls">
|
||||
<text name="filter_label" value="Filtro:"/>
|
||||
<combo_box name="filter_combo_box">
|
||||
<combo_box.item value="filter_type_all" label="Tudo"/>
|
||||
<combo_box.item value="filter_type_animations" label="Animação"/>
|
||||
<combo_box.item value="filter_type_calling_cards" label="Cartões de chamadas"/>
|
||||
<combo_box.item value="filter_type_clothing" label="Roupas / partes do corpo"/>
|
||||
<combo_box.item value="filter_type_gestures" label="Gestos"/>
|
||||
<combo_box.item value="filter_type_landmarks" label="Landmarks"/>
|
||||
<combo_box.item value="filter_type_notecards" label="Anotações"/>
|
||||
<combo_box.item value="filter_type_objects" label="Objetos"/>
|
||||
<combo_box.item value="filter_type_scripts" label="Scripts"/>
|
||||
<combo_box.item value="filter_type_sounds" label="Sons"/>
|
||||
<combo_box.item value="filter_type_textures" label="Texturas"/>
|
||||
<combo_box.item value="filter_type_snapshots" label="Fotos"/>
|
||||
<combo_box.item value="filter_type_custom" label="Personalizar..."/>
|
||||
</combo_box>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
<panel name="default_inventory_panel">
|
||||
<tab_container name="inventory filter tabs">
|
||||
<inventory_panel label="Inventário" name="All Items"/>
|
||||
<recent_inventory_panel label="Itens recentes" name="Recent Items"/>
|
||||
<worn_inventory_panel label="Em uso" name="Worn Items"/>
|
||||
</tab_container>
|
||||
</panel>
|
||||
<panel name="bottom_panel">
|
||||
<panel name="options_gear_btn_panel">
|
||||
<menu_button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/>
|
||||
</panel>
|
||||
<panel name="add_btn_panel">
|
||||
<button name="add_btn" tool_tip="Adicionar novo item"/>
|
||||
</panel>
|
||||
<panel name="new_inventory_panel">
|
||||
<button name="new_inv_btn" tool_tip="Janela de inventário adicional"/>
|
||||
</panel>
|
||||
<panel name="dummy_panel">
|
||||
<text name="ItemcountText">
|
||||
Itens
|
||||
</text>
|
||||
</panel>
|
||||
<panel name="trash_btn_panel">
|
||||
<dnd_button name="trash_btn" tool_tip="Remover item selecionado"/>
|
||||
</panel>
|
||||
</panel>
|
||||
</panel>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -166,6 +166,7 @@ with the same filename but different name
|
|||
<texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" />
|
||||
<texture name="Command_Poser_Icon" file_name="toolbar_icons/poser.png" preload="true" /> <!-- FS:AR FIRE-30873 -->
|
||||
<texture name="Command_Preferences_Icon" file_name="toolbar_icons/preferences.png" preload="true" />
|
||||
<texture name="Command_Primfeed_Icon" file_name="icons/primfeed_white.png" preload="true" /> <!-- FS:Beq Primfeed support -->
|
||||
<texture name="Command_Profile_Icon" file_name="toolbar_icons/profile.png" preload="true" />
|
||||
<texture name="Command_Report_Abuse_Icon" file_name="toolbar_icons/report_abuse.png" preload="true" />
|
||||
<texture name="Command_Search_Icon" file_name="toolbar_icons/search.png" preload="true" />
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
<check_box name="filter_perm_copy" label="Kopieren"/>
|
||||
<check_box name="filter_perm_modify" label="Bearbeiten"/>
|
||||
<check_box name="filter_perm_transfer" label="Transferieren"/>
|
||||
<check_box name="filter_reflection_probe" label="Reflexionstests" tool_tip="Beinhaltet nur manuelle Tests, nicht automatische. Beinhaltet nur Spiegel-Tests, falls Spiegel in den Grafik-Einstellungen aktiviert sind. Falls kein Reflexionsumfang gesetzt ist oder der Test nicht eingebacken ist, könnten Objekte nicht identifiert werden."/>
|
||||
<check_box name="filter_for_sale" label="Zum Verkauf zwischen" width="150"/>
|
||||
<text name="and">
|
||||
und
|
||||
|
|
@ -92,6 +93,7 @@
|
|||
<check_box name="exclude_attachment" label="Anhänge"/>
|
||||
<check_box name="exclude_physical" label="Physikalisch"/>
|
||||
<check_box name="exclude_temporary" label="Temporär"/>
|
||||
<check_box name="exclude_reflection_probes" label="Reflexionstests"/>
|
||||
<check_box name="exclude_childprim" label="Kind-Primitive"/>
|
||||
<check_box name="exclude_neighbor_region" label="Nachbarregionen"/>
|
||||
<button name="apply" label="Anwenden"/>
|
||||
|
|
|
|||
|
|
@ -14,13 +14,22 @@
|
|||
<string name="header_mHindLimbsRoot">Hintere Glieder</string>
|
||||
<string name="header_mWingsRoot">Flügel</string>
|
||||
<string name="header_mFaceEar1Left">Ohren/Nase</string>
|
||||
<string name="header_mSkull">Körper</string>
|
||||
<string name="header_HEAD">Körper</string>
|
||||
<string name="header_L_UPPER_ARM">Arme</string>
|
||||
<string name="header_L_UPPER_LEG">Beine</string>
|
||||
|
||||
<!-- These are names to appear on the UI for the joints/bones/thingos -->
|
||||
<string name="title_mPelvis">Ganzer Avatar</string>
|
||||
<string name="title_mTorso">Oberkörper</string>
|
||||
<string name="title_mSpine1">Wirbelsäule 1</string>
|
||||
<string name="title_mSpine2">Wirbelsäule 2</string>
|
||||
<string name="title_mSpine3">Wirbelsäule 3</string>
|
||||
<string name="title_mSpine4">Wirbelsäule 4</string>
|
||||
<string name="title_mChest">Brust</string>
|
||||
<string name="title_mNeck">Hals</string>
|
||||
<string name="title_mHead">Kopf</string>
|
||||
<string name="title_mSkull">Schädel</string>
|
||||
<string name="title_mEyeRight">Rechtes Auge</string>
|
||||
<string name="title_mEyeLeft">Linkes Auge</string>
|
||||
<string name="title_mFaceForeheadLeft">Linker Stirnwinkel</string>
|
||||
|
|
@ -32,13 +41,17 @@
|
|||
<string name="title_mFaceEyebrowCenterRight">Mit. rechte Augenbraue</string>
|
||||
<string name="title_mFaceEyebrowInnerRight">In. rechte Augenbraue</string>
|
||||
<string name="title_mFaceEyeLidUpperLeft">Linkes oberes Augenlid</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">In. linker Augenwinkel</string>
|
||||
<string name="title_mFaceEyeLidLowerLeft">Linkes unteres Augenlid</string>
|
||||
<string name="title_mFaceEyeLidUpperRight">Rechtes oberes Augenlid</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">In. rechter Augenwinkel</string>
|
||||
<string name="title_mFaceEyeLidLowerRight">Rechtes unteres Augenlid</string>
|
||||
<string name="title_mFaceEar1Left">Linkes oberes Ohr</string>
|
||||
<string name="title_mFaceEar2Left">Linkes unteres Ohr</string>
|
||||
<string name="title_mFaceEar1Right">Rechtes oberes Ohr</string>
|
||||
<string name="title_mFaceEar2Right">Rechtes unteres Ohr</string>
|
||||
<string name="title_mFaceNoseBase">Basis Nase</string>
|
||||
<string name="title_mFaceNoseBridge">Nosenbrücke</string>
|
||||
<string name="title_mFaceNoseLeft">Nase links</string>
|
||||
<string name="title_mFaceNoseCenter">Nase Mitte</string>
|
||||
<string name="title_mFaceNoseRight">Nase rechts</string>
|
||||
|
|
@ -55,16 +68,12 @@
|
|||
<string name="title_mFaceTongueTip">Zungenspite</string>
|
||||
<string name="title_mFaceJawShaper">Kieferform</string>
|
||||
<string name="title_mFaceForeheadCenter">Stirn Mitte</string>
|
||||
<string name="title_mFaceNoseBase">Nase Basis</string>
|
||||
<string name="title_mFaceTeethUpper">Obere Zähne</string>
|
||||
<string name="title_mFaceLipUpperLeft">Linke obere Lippe</string>
|
||||
<string name="title_mFaceLipUpperRight">Rechte obere Lippe</string>
|
||||
<string name="title_mFaceLipCornerLeft">Linker Mundwinkel</string>
|
||||
<string name="title_mFaceLipCornerRight">Rechter Mundwinkel</string>
|
||||
<string name="title_mFaceLipUpperCenter">Mittlere obere Lippe</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">In. linker Augenwinkel</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">In. rechter Augenwinkel</string>
|
||||
<string name="title_mFaceNoseBridge">Nasenbrücke</string>
|
||||
<string name="title_mCollarLeft">Kragen</string>
|
||||
<string name="title_mShoulderLeft">Ganzer Arm</string>
|
||||
<string name="title_mElbowLeft">Unterarm</string>
|
||||
|
|
@ -140,10 +149,31 @@
|
|||
<string name="title_mHindLimb2Right">Rechts 2</string>
|
||||
<string name="title_mHindLimb3Right">Rechts 3</string>
|
||||
<string name="title_mHindLimb4Right">Rechts 4</string>
|
||||
<string name="title_HEAD">Kopf</string>
|
||||
<string name="title_NECK">Nacken</string>
|
||||
<string name="title_CHEST">Brust</string>
|
||||
<string name="title_BUTT">Hintern</string>
|
||||
<string name="title_BELLY">Bauch</string>
|
||||
<string name="title_LEFT_PEC">Linke Brustmuskeln</string>
|
||||
<string name="title_RIGHT_PEC">Rechte Brustmuskeln</string>
|
||||
<string name="title_L_CLAVICLE">Li. Schlüsselbein</string>
|
||||
<string name="title_R_CLAVICLE">Re .Schlüsselbein</string>
|
||||
<string name="title_L_UPPER_ARM">Linker Obererm</string>
|
||||
<string name="title_R_UPPER_ARM">Rechter Oberarm</string>
|
||||
<string name="title_L_LOWER_ARM">Linker Unterarm</string>
|
||||
<string name="title_R_LOWER_ARM">Rechter Unterarm</string>
|
||||
<string name="title_L_HAND">Linke Hand</string>
|
||||
<string name="title_R_HAND">Rechte Hand</string>
|
||||
<string name="title_UPPER_BACK">Oberer Rücken</string>
|
||||
<string name="title_LEFT_HANDLE">Linke Taille</string>
|
||||
<string name="title_RIGHT_HANDLE">Rechte Taille</string>
|
||||
<string name="title_PELVIS">Becken</string>
|
||||
<string name="title_L_UPPER_LEG">Linker Oberschenkel</string>
|
||||
<string name="title_R_UPPER_LEG">Rechter Oberschenkel</string>
|
||||
<string name="title_L_LOWER_LEG">Linker Unterschenkel</string>
|
||||
<string name="title_R_LOWER_LEG">Rechter Unterschenkel</string>
|
||||
<string name="title_L_FOOT">Linker Fuß</string>
|
||||
<string name="title_R_FOOT">Rechter Fuß</string>
|
||||
<string name="LoadPoseLabel">Pose laden</string>
|
||||
<string name="SavePoseLabel">Pose speichern</string>
|
||||
<string name="LoadDiffLabel">Diff. laden</string>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<floater name="floater_primfeed" title="Auf Primfeed teilen">
|
||||
<panel name="background">
|
||||
<tab_container name="tabs">
|
||||
<panel label="Foto" name="panel_primfeed_photo"/>
|
||||
<panel label="Konto" name="panel_primfeed_account"/>
|
||||
</tab_container>
|
||||
<panel name="connection_status_panel">
|
||||
<text name="connection_error_text">
|
||||
Fehler
|
||||
</text>
|
||||
<text name="connection_loading_text">
|
||||
Laden...
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -104,6 +104,7 @@
|
|||
<menu_item_check label="Gesten" name="Gestures"/>
|
||||
<menu_item_call label="Twitter..." name="Twitter"/>
|
||||
<menu_item_call label="Flickr..." name="Flickr"/>
|
||||
<menu_item_call label="Primfeed..." name="Primfeed"/>
|
||||
<menu_item_call label="Discord..." name="Discord"/>
|
||||
<menu_item_check label="Gesten..." name="Gestures"/>
|
||||
<menu_item_check label="Unterhaltungsprotokoll..." name="Conversation Log..."/>
|
||||
|
|
@ -673,6 +674,8 @@
|
|||
<menu_item_check label="HTTP-Inventar" name="HTTP Inventory"/>
|
||||
<menu_item_call label="Bilder komprimieren" name="Compress Images"/>
|
||||
<menu_item_call label="Datei-Komprimierung testen" name="Compress File Test"/>
|
||||
<menu_item_call label="Primfeed Autorisierungstest" name="primfeed_auth_test"/>
|
||||
<menu_item_call label="Primfeed Autorisierung zurücksetzen" name="primfeed_auth_clear"/>
|
||||
<menu_item_call label="Visual Leak Detector aktivieren" name="Enable Visual Leak Detector"/>
|
||||
<menu_item_check label="Ausgabe Fehlerbeseitigung ausgeben" name="Output Debug Minidump"/>
|
||||
<menu_item_check label="Bei nächster Ausführung Debugkonsole öffnen" name="Console Window"/>
|
||||
|
|
|
|||
|
|
@ -3017,13 +3017,10 @@ Wählen Sie eine kleinere Landfläche.
|
|||
<notification name="SystemMessage">
|
||||
[MESSAGE]
|
||||
</notification>
|
||||
<notification name="FacebookConnect">
|
||||
[MESSAGE]
|
||||
</notification>
|
||||
<notification name="FlickrConnect">
|
||||
[MESSAGE]
|
||||
</notification>
|
||||
<notification name="TwitterConnect">
|
||||
<notification name="PrimfeedConnect">
|
||||
[MESSAGE]
|
||||
</notification>
|
||||
<notification name="PaymentReceived">
|
||||
|
|
@ -5780,6 +5777,9 @@ Flickr-Verifikation fehlgeschlagen. Bitte erneut versuchen sowie den eingegebene
|
|||
<notification name="ExodusFlickrUploadComplete">
|
||||
Das Foto kann jetzt [https://www.flickr.com/photos/me/[ID] hier] betrachtet werden.
|
||||
</notification>
|
||||
<notification name="FSPrimfeedUploadComplete">
|
||||
Der Primfeed-Post kann jetzt [[PF_POSTURL] hier] betrachtet werden.
|
||||
</notification>
|
||||
<!-- </FS:TS> FIRE-5453 -->
|
||||
<notification name="RegionTrackerAdd">
|
||||
Welche Bezeichnung soll für die Region
|
||||
|
|
@ -5874,4 +5874,25 @@ https://wiki.firestormviewer.org/antivirus_whitelisting
|
|||
Bestehende Pose „[POSE_NAME]“ überschreiben?
|
||||
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Okay"/>
|
||||
</notification>
|
||||
<notification name="PrimfeedLoginRequestFailed">
|
||||
Login-Anfrage wurde von Primfeed abgelehnt.
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationFailed">
|
||||
Primfeed-Autorisierung fehlgeschlagen. Die Autorisierungssequenz war nicht vollständig.
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationAlreadyInProgress">
|
||||
Primfeed-Autorisierung läuft bereits. Bitte schließen Sie die Primfeed-Autorisierung in Ihrem Webbrowser ab, bevor Sie es erneut versuchen.
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationSuccessful">
|
||||
Primfeed-Autorisierung abgschlossen. Sie können jetzt Fotos auf Primfeed posten.
|
||||
</notification>
|
||||
<notification name="PrimfeedValidateFailed">
|
||||
Primfeed-Benutzervalidierung fehlgeschlagen. Primfeed ist dieser Account unbekannt oder das Anmelden ist fehlgeschlagen.
|
||||
</notification>
|
||||
<notification name="PrimfeedAlreadyAuthorized">
|
||||
Sie haben dieses Konto bereits mit Primfeed verknüpft. Bitte benutzen Sie den Rücksetzen-Button, um neu zu beginnen.
|
||||
</notification>
|
||||
<notification name="PrimfeedUserStatusFailed">
|
||||
Primfeed-Benutzeranmeldung erfolgreich, allerdings ist die Statusprüfung fehlgeschlagen. Bitte prüfen Sie, ob Primfeed korrekt funktioniert.
|
||||
</notification>
|
||||
</notifications>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<panel name="panel_flickr_account">
|
||||
<string name="flickr_connected" value="Sie sind mit Flickr verbunden als:"/>
|
||||
<string name="flickr_disconnected" value="Nicht mit Flickr verbunden"/>
|
||||
<string name="flickr_disconnected" value="Nicht mit Flickr verbunden."/>
|
||||
<text name="account_caption_label">
|
||||
Nicht mit Flickr verbunden.
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
</combo_box>
|
||||
<slider label="Überblendzeit für Umgebungseinstellungen:" tool_tip="Intervall in Sekunden in dem Änderungen an den Umgebungseinstellungen ineinander überblenden. 0 = direkt ohne Verzögerung" name="manual_environment_change_transition_period"/>
|
||||
<check_box name="EnvironmentPersistAcrossLogin" label="Sitzungsübergreifende Umgebungseinstellungen aktivieren" tool_tip="Stellt die aktuellen Umgebungseinstellungen nach einem erneuten Login wieder her."/>
|
||||
<check_box name="FSRepeatedEnvTogglesShared" label="Tastenkombinationen für Umgebungseinstellungen sind An-Aus-Schalter" tool_tip="Wiederholtes Drücken von Tastenkombinationen schaltet zwischen der gewünschten Einstellung und gemeinsamer Umgebung um."/>
|
||||
</panel>
|
||||
|
||||
<!--Protection-->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<panel name="panel_primfeed_account">
|
||||
<string name="primfeed_connected" value="Sie sind mit Primfeed verbunden als:"/>
|
||||
<string name="primfeed_disconnected" value="Nicht mit Primfeed verbunden."/>
|
||||
<string name="primfeed_plan_unknown" value="Unbekannt"/>
|
||||
<text name="connected_as_label">
|
||||
Nicht mit Primfeed verbunden.
|
||||
</text>
|
||||
<text name="primfeed_account_plan_label">
|
||||
Konto-Typ:
|
||||
</text>
|
||||
<panel name="panel_buttons">
|
||||
<button label="Verbinden..." name="connect_btn"/>
|
||||
<button label="Trennen" name="disconnect_btn"/>
|
||||
<text name="account_learn_more_label">
|
||||
[https://docs.primfeed.com Mehr über Primfeed erfahren]
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<panel name="panel_primfeed_photo">
|
||||
<combo_box name="resolution_combobox" tool_tip="Bildauflösung">
|
||||
<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
|
||||
<combo_box.item label="Benutzerdefiniert" name="Custom"/>
|
||||
</combo_box>
|
||||
<combo_box name="filters_combobox" tool_tip="Bildfilter">
|
||||
<combo_box.item label="Kein Filter" name="NoFilter"/>
|
||||
</combo_box>
|
||||
<check_box label="Seitenverh. behalten" name="keep_aspect_ratio"/>
|
||||
<text name="working_lbl">
|
||||
Aktualisiere...
|
||||
</text>
|
||||
<check_box label="Rahmen anzeigen" name="show_frame" tool_tip="Zeigt einen Rahmen um den Bereich der Aufnahme an. Teile der Szene, die außerhalb des Aufnahmebereichs liegen, werden entsättigt und leicht verschwommen dargestellt."/>
|
||||
<check_box label="Guide anzeigen" name="show_guides" tool_tip="Zeigt Aufnahme-Guide (Drittel-Regel) innerhalb des Aufnahmebereichs an."/>
|
||||
<button label="Aktualisieren" name="new_snapshot_btn" tool_tip="Zum Aktualisieren klicken"/>
|
||||
<button label="Vorschau" name="big_preview_btn" tool_tip="Klicken, um Vorschau ein-/auszuschalten"/>
|
||||
<text name="description_label">
|
||||
Beschreibung:
|
||||
</text>
|
||||
<check_box initial_value="true" label="Standort der Beschreibung hinzufügen" name="add_location_cb"/>
|
||||
<check_box label="Zur öffentl. Galerie hinzufügen" name="primfeed_add_to_public_gallery"/>
|
||||
<check_box label="Kommerzieller Inhalt" name="primfeed_commercial_content"/>
|
||||
<combo_box name="rating_combobox" tool_tip="Primfeed-Inhaltseinstufung">
|
||||
<combo_box.item label="Generell" name="GeneralRating"/>
|
||||
<combo_box.item label="Moderat" name="ModerateRating"/>
|
||||
<combo_box.item label="Adult" name="AdultRating"/>
|
||||
<combo_box.item label="Adult+" name="AdultPlusRating"/>
|
||||
</combo_box>
|
||||
<check_box label="Nach posten in Browser öffnen" tool_tip="Öffnet den Primfeed-Post automatisch im Browser." name="primfeed_open_url_on_post"/>
|
||||
<button label="Teilen" name="post_photo_btn"/>
|
||||
<button label="Abbrechen" name="cancel_photo_btn"/>
|
||||
</panel>
|
||||
|
|
@ -19,6 +19,9 @@
|
|||
<layout_panel name="lp_flickr">
|
||||
<button label="Auf Flickr teilen" name="send_to_flickr_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_primfeed">
|
||||
<button label="Auf Primfeed teilen" name="send_to_primfeed_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_email">
|
||||
<button label="Per E-Mail senden" name="save_to_email_btn"/>
|
||||
</layout_panel>
|
||||
|
|
|
|||
|
|
@ -387,24 +387,6 @@ Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten ha
|
|||
<string name="TestingDisconnect">
|
||||
Verbindungsabbruch wird getestet
|
||||
</string>
|
||||
<string name="SocialFacebookConnecting">
|
||||
Mit Facebook verbinden...
|
||||
</string>
|
||||
<string name="SocialFacebookPosting">
|
||||
Posten...
|
||||
</string>
|
||||
<string name="SocialFacebookDisconnecting">
|
||||
Facebook-Verbindung trennen...
|
||||
</string>
|
||||
<string name="SocialFacebookErrorConnecting">
|
||||
Problem beim Verbinden mit Facebook
|
||||
</string>
|
||||
<string name="SocialFacebookErrorPosting">
|
||||
Problem beim Posten auf Facebook
|
||||
</string>
|
||||
<string name="SocialFacebookErrorDisconnecting">
|
||||
Problem beim Trennen der Facebook-Verbindung
|
||||
</string>
|
||||
<string name="SocialFlickrConnecting">
|
||||
Verbinden mit Flickr...
|
||||
</string>
|
||||
|
|
@ -423,23 +405,17 @@ Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten ha
|
|||
<string name="SocialFlickrErrorDisconnecting">
|
||||
Problem beim Trennen der Flickr-Verbindung
|
||||
</string>
|
||||
<string name="SocialTwitterConnecting">
|
||||
Verbinden mit Twitter...
|
||||
<string name="SocialPrimfeedConnecting">
|
||||
Verbinden mit Primfeed...
|
||||
</string>
|
||||
<string name="SocialTwitterPosting">
|
||||
Posten...
|
||||
<string name="SocialPrimfeedNotAuthorized">
|
||||
Nicht autorisiert...
|
||||
</string>
|
||||
<string name="SocialTwitterDisconnecting">
|
||||
Twitter-Verbindung wird getrennt...
|
||||
<string name="SocialPrimfeedPosting">
|
||||
Teilen...
|
||||
</string>
|
||||
<string name="SocialTwitterErrorConnecting">
|
||||
Problem beim Verbinden mit Twitter
|
||||
</string>
|
||||
<string name="SocialTwitterErrorPosting">
|
||||
Problem beim Posten auf Twitter
|
||||
</string>
|
||||
<string name="SocialTwitterErrorDisconnecting">
|
||||
Problem beim Trennen der Twitter-Verbindung
|
||||
<string name="SocialPrimfeedErrorPosting">
|
||||
Problem beim Posten auf Primfeed
|
||||
</string>
|
||||
<string name="BlackAndWhite">
|
||||
Schwarzweiß
|
||||
|
|
@ -6126,6 +6102,9 @@ Setzen Sie den Editorpfad in Anführungszeichen
|
|||
<string name="Command_Poser_Label">
|
||||
Poser
|
||||
</string>
|
||||
<string name="Command_Primfeed_Label">
|
||||
Primfeed
|
||||
</string>
|
||||
<string name="Command_Appearance_Tooltip">
|
||||
Avatar ändern
|
||||
</string>
|
||||
|
|
@ -6327,6 +6306,9 @@ Setzen Sie den Editorpfad in Anführungszeichen
|
|||
<string name="Command_Poser_Tooltip">
|
||||
Eigenen Avatar und Animeshe posieren
|
||||
</string>
|
||||
<string name="Command_Primfeed_Tooltip">
|
||||
Auf Primfeed posten
|
||||
</string>
|
||||
<string name="Toolbar_Bottom_Tooltip">
|
||||
gegenwärtig in der unteren Symbolleiste
|
||||
</string>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ Dummy Name replaced at run time
|
|||
</text_editor>
|
||||
</panel>
|
||||
<panel
|
||||
height="910"
|
||||
height="920"
|
||||
border="true"
|
||||
label="Firestorm Credits"
|
||||
help_topic="about_fscredits_tab"
|
||||
|
|
@ -131,7 +131,7 @@ The Firestorm Development Team:
|
|||
<text
|
||||
enabled="false"
|
||||
follows="top|left"
|
||||
height="70"
|
||||
height="80"
|
||||
bg_readonly_color="Transparent"
|
||||
left="5"
|
||||
text_color="LtGray"
|
||||
|
|
@ -140,7 +140,7 @@ The Firestorm Development Team:
|
|||
top_pad="4"
|
||||
width="450"
|
||||
wrap="true">
|
||||
Angeldark Raymaker, Ansariel Hiller, ArminWeatherHax, Arrehn Oberlander, Beq Janus, Cinder Roxley, Holy Gavenkrantz, Jessica Lyon, Kadah Coba, Kitty Barnett, Liny Odell, LordGregGreg Back, minerjr, Mobius Ryba, Nicky Dasmijn, PanteraPolnocy, ScentualLust, Selo Jacobus, SimonLsAlt, Tankmaster Finesmith, Techwolf Lupindo, Tonya Souther, Tozh Taurog, Vortex Saito, WoLf Loonie, Wolfspirit Magic, Yay N' Stuff (mygoditsfullofstars), and Zi Ree.
|
||||
Angeldark Raymaker, Ansariel Hiller, ArminWeatherHax, Arrehn Oberlander, Beq Janus, Chanayane, Cinder Roxley, Hecklezz, Holy Gavenkrantz, Jessica Lyon, Kadah Coba, Kitty Barnett, Liny Odell, LordGregGreg Back, minerjr, Mobius Ryba, Nicky Dasmijn, PanteraPolnocy, ScentualLust, Selo Jacobus, SimonLsAlt, Tankmaster Finesmith, Techwolf Lupindo, Tonya Souther, Tozh Taurog, Vortex Saito, WoLf Loonie, Wolfspirit Magic, Yay N' Stuff (mygoditsfullofstars), and Zi Ree.
|
||||
</text>
|
||||
<text
|
||||
follows="top|left"
|
||||
|
|
@ -165,7 +165,7 @@ Additional code generously contributed to Firestorm by:
|
|||
top_pad="4"
|
||||
width="450"
|
||||
wrap="true">
|
||||
Aira Yumi, Albatroz Hird, Alexie Birman, Andromeda Rage, Angus Boyd, Animats, Armin Weatherwax, Ayane Lyla, Casper Warden, Chalice Yao, Chaser Zaks, Chorazin Allen, Cron Stardust, Damian Zhaoying, Dan Threebeards, Darlcat, Dawa Gurbux, Dax Dupont, Denver Maksim, Dragonborn Forzane, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hecklezz, Hitomi Tiponi, humbletim, Inusaito Sayori, Jean Severine, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Lassie, Latif Khalifa, Laurent Bechir, Logue Takacs, Magne Metaverse LLC, Magus Freston, Makidoll, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, minerjr, Mister Acacia, MorganMegan, Morgan Pennent, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, Oren Hurvitz, paperwork, Penny Patton, Peyton Menges, programmtest, Qwerty Venom, rafak360, Rebecca Ashbourne, Revolution Smythe, Romka Swallowtail, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sekkmer, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Tapple Gao, Testicular Slingshot, Thickbrick Sleaford, Ubit Umarov, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, 小滢 Zi Ying, Zwagoth Klaar and others.
|
||||
Aira Yumi, Albatroz Hird, Alexie Birman, Andromeda Rage, Angus Boyd, Animats, Armin Weatherwax, Ayane Lyla, Casper Warden, Chalice Yao, Chaser Zaks, Chorazin Allen, Cron Stardust, Damian Zhaoying, Dan Threebeards, Darlcat, Dawa Gurbux, Dax Dupont, Denver Maksim, Dragonborn Forzane, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hecklezz, Hitomi Tiponi, humbletim, Inusaito Sayori, Jean Severine, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Lassie, Latif Khalifa, Laurent Bechir, Logue Takacs, Magne Metaverse LLC, Magus Freston, Makidoll, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, minerjr, Mister Acacia, MorganMegan, Morgan Pennent, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, olizinha, Oren Hurvitz, paperwork, Penny Patton, Peyton Menges, programmtest, Qwerty Venom, rafak360, Rebecca Ashbourne, Revolution Smythe, Romka Swallowtail, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sekkmer, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Tapple Gao, Testicular Slingshot, Thickbrick Sleaford, Ubit Umarov, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, 小滢 Zi Ying, Zwagoth Klaar and others.
|
||||
</text>
|
||||
<text
|
||||
follows="top|left"
|
||||
|
|
|
|||
|
|
@ -378,6 +378,15 @@
|
|||
name="filter_perm_transfer"
|
||||
label="Transfer"
|
||||
width="100"/>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
top_pad="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="filter_reflection_probe"
|
||||
label="Reflection Probes"
|
||||
tool_tip="Includes manual probes only, not auto-probes. Only includes mirror probes if mirrors are enabled in graphics preferences. If reflection coverage is set to 'none', or the probe is not baked, objects may not be identified."
|
||||
width="100"/>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
height="20"
|
||||
|
|
@ -416,7 +425,7 @@
|
|||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="999999999"
|
||||
min_val="0"
|
||||
min_val="0"
|
||||
name="max_price"
|
||||
top_delta="-4"
|
||||
width="80"/>
|
||||
|
|
@ -525,7 +534,7 @@
|
|||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="999999999"
|
||||
min_val="0"
|
||||
min_val="0"
|
||||
name="max_distance"
|
||||
top_delta="-4"
|
||||
width="80"/>
|
||||
|
|
@ -570,6 +579,14 @@
|
|||
name="exclude_temporary"
|
||||
label="Temporary"
|
||||
width="80"/>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
top_pad="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="exclude_reflection_probes"
|
||||
label="Reflection Probes"
|
||||
width="80"/>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
top_pad="10"
|
||||
|
|
|
|||
|
|
@ -22,9 +22,14 @@ width="430">
|
|||
<!-- These values are all CaSe SeNsiTiVe!! (use all caps plz or you get default behaviour) Whitespace is ignored, that's just for you non-robots-->
|
||||
<string name="joint_transform_mPelvis" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mTorso" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mSpine1" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mSpine2" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mChest" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mSpine3" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mSpine4" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mNeck" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mHead" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mSkull" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mCollarLeft" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mCollarRight" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mShoulderLeft" translate="false">SWAP_ROLL_AND_PITCH NEGATE_ROLL NEGATE_PITCH</string>
|
||||
|
|
@ -39,9 +44,11 @@ width="430">
|
|||
<string name="joint_transform_mHipLeft" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mKneeLeft" translate="false">NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mAnkleLeft" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mToeLeft" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mHipRight" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mKneeRight" translate="false">NEGATE_PITCH NEGATE_ROLL</string>
|
||||
<string name="joint_transform_mAnkleRight" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mToeRight" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceTeethLower" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceTeethUpper" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceLipCornerRight" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
|
|
@ -54,6 +61,8 @@ width="430">
|
|||
<string name="joint_transform_mFaceLipLowerRight" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyeLidUpperLeft" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyeLidUpperRight" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyecornerInnerLeft" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyecornerInnerRight" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyeLidLowerLeft" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyeLidLowerRight" translate="false">NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEyebrowOuterLeft" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
|
|
@ -100,7 +109,28 @@ width="430">
|
|||
<string name="joint_transform_mHandPinky3Right" translate="false">SWAP_X2Z_Y2X_Z2Y NEGATE_PITCH</string>
|
||||
<string name="joint_transform_LEFT_PEC" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_RIGHT_PEC" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_HEAD" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_NECK" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_BELLY" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_CHEST" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_PELVIS" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_UPPER_BACK" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_L_CLAVICLE" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_R_CLAVICLE" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_LEFT_HANDLE" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_RIGHT_HANDLE" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_L_UPPER_ARM" translate="false">SWAP_X2Y_Y2Z_Z2X NEGATE_PITCH NEGATE_YAW</string>
|
||||
<string name="joint_transform_R_UPPER_ARM" translate="false">SWAP_X2Y_Y2Z_Z2X</string>
|
||||
<string name="joint_transform_L_LOWER_ARM" translate="false">SWAP_ROLL_AND_PITCH</string>
|
||||
<string name="joint_transform_R_LOWER_ARM" translate="false">SWAP_ROLL_AND_PITCH</string>
|
||||
<string name="joint_transform_L_HAND" translate="false">SWAP_ROLL_AND_PITCH</string>
|
||||
<string name="joint_transform_R_HAND" translate="false">SWAP_X2Z_Y2X_Z2Y</string>
|
||||
<string name="joint_transform_L_UPPER_LEG" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_R_UPPER_LEG" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_L_LOWER_LEG" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_R_LOWER_LEG" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_L_FOOT" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_R_FOOT" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mTail1" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mTail2" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mTail3" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
|
|
@ -113,6 +143,8 @@ width="430">
|
|||
<string name="joint_transform_mFaceEar2Left" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEar1Right" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceEar2Right" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceNoseBase" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceNoseBridge" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceNoseLeft" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceNoseCenter" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
<string name="joint_transform_mFaceNoseRight" translate="false">SWAP_YAW_AND_ROLL NEGATE_PITCH</string>
|
||||
|
|
@ -144,14 +176,23 @@ width="430">
|
|||
<string name="header_mHindLimbsRoot">Hind Limbs</string>
|
||||
<string name="header_mWingsRoot">Wings</string>
|
||||
<string name="header_mFaceEar1Left">Ears/Nose</string>
|
||||
<string name="header_mSkull">Body</string>
|
||||
<string name="header_HEAD">Body</string>
|
||||
<string name="header_L_UPPER_ARM">Arms</string>
|
||||
<string name="header_L_UPPER_LEG">Legs</string>
|
||||
|
||||
<!-- These are names to appear on the UI for the joints -->
|
||||
<!-- If a name is not here, it does not appear -->
|
||||
<string name="title_mPelvis">Whole Avatar</string>
|
||||
<string name="title_mTorso">Torso</string>
|
||||
<string name="title_mSpine1">Spine 1</string>
|
||||
<string name="title_mSpine2">Spine 2</string>
|
||||
<string name="title_mSpine3">Spine 3</string>
|
||||
<string name="title_mSpine4">Spine 4</string>
|
||||
<string name="title_mChest">Chest</string>
|
||||
<string name="title_mNeck">Neck</string>
|
||||
<string name="title_mHead">Head</string>
|
||||
<string name="title_mSkull">Skull</string>
|
||||
<string name="title_mEyeRight">Right Eye</string>
|
||||
<string name="title_mEyeLeft">Left Eye</string>
|
||||
<string name="title_mFaceForeheadLeft">Forehead Left Side</string>
|
||||
|
|
@ -163,13 +204,17 @@ width="430">
|
|||
<string name="title_mFaceEyebrowCenterRight">Eyebrow Middle Right</string>
|
||||
<string name="title_mFaceEyebrowInnerRight">Eyebrow Inner Right</string>
|
||||
<string name="title_mFaceEyeLidUpperLeft">EyeLid Upper Left</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">Eye Inner Corner Left</string>
|
||||
<string name="title_mFaceEyeLidLowerLeft">EyeLid Lower Left</string>
|
||||
<string name="title_mFaceEyeLidUpperRight">EyeLid Upper Right</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">Eye Inner Corner Right</string>
|
||||
<string name="title_mFaceEyeLidLowerRight">EyeLid Lower Right</string>
|
||||
<string name="title_mFaceEar1Left">Ear Upper Left</string>
|
||||
<string name="title_mFaceEar2Left">Ear Lower Left</string>
|
||||
<string name="title_mFaceEar1Right">Ear Upper Right</string>
|
||||
<string name="title_mFaceEar2Right">Ear Lower Right</string>
|
||||
<string name="title_mFaceNoseBase">Nose Base</string>
|
||||
<string name="title_mFaceNoseBridge">Nose Bridge</string>
|
||||
<string name="title_mFaceNoseLeft">Nose Left</string>
|
||||
<string name="title_mFaceNoseCenter">Nose Middle</string>
|
||||
<string name="title_mFaceNoseRight">Nose Right</string>
|
||||
|
|
@ -186,16 +231,12 @@ width="430">
|
|||
<string name="title_mFaceTongueTip">Tongue Tip</string>
|
||||
<string name="title_mFaceJawShaper">Jaw Shaper</string>
|
||||
<string name="title_mFaceForeheadCenter">Forehead Middle</string>
|
||||
<string name="title_mFaceNoseBase">Nose Base</string>
|
||||
<string name="title_mFaceTeethUpper">Teeth Upper</string>
|
||||
<string name="title_mFaceLipUpperLeft">Lip Upper Left</string>
|
||||
<string name="title_mFaceLipUpperRight">Lip Upper Right</string>
|
||||
<string name="title_mFaceLipCornerLeft">Lip Corner Left</string>
|
||||
<string name="title_mFaceLipCornerRight">Lip Corner Right</string>
|
||||
<string name="title_mFaceLipUpperCenter">Lip Upper Middle</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">Eye corner Inner Left</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">Eye corner Inner Right</string>
|
||||
<string name="title_mFaceNoseBridge">Nose Bridge</string>
|
||||
<string name="title_mCollarLeft">Collar</string>
|
||||
<string name="title_mShoulderLeft">Whole Arm</string>
|
||||
<string name="title_mElbowLeft">Forearm</string>
|
||||
|
|
@ -271,10 +312,31 @@ width="430">
|
|||
<string name="title_mHindLimb2Right">Right 2</string>
|
||||
<string name="title_mHindLimb3Right">Right 3</string>
|
||||
<string name="title_mHindLimb4Right">Right 4</string>
|
||||
<string name="title_HEAD">Head</string>
|
||||
<string name="title_NECK">Neck</string>
|
||||
<string name="title_CHEST">Chest</string>
|
||||
<string name="title_BUTT">Bottom</string>
|
||||
<string name="title_BELLY">Belly</string>
|
||||
<string name="title_LEFT_PEC">Left Pec</string>
|
||||
<string name="title_RIGHT_PEC">Right Pec</string>
|
||||
<string name="title_L_CLAVICLE">Left Clavicle</string>
|
||||
<string name="title_R_CLAVICLE">Right Clavicle</string>
|
||||
<string name="title_L_UPPER_ARM">Left Upper Arm</string>
|
||||
<string name="title_R_UPPER_ARM">Right Upper Arm</string>
|
||||
<string name="title_L_LOWER_ARM">Left Lower Arm</string>
|
||||
<string name="title_R_LOWER_ARM">Right Lower Arm</string>
|
||||
<string name="title_L_HAND">Left Hand</string>
|
||||
<string name="title_R_HAND">Right Hand</string>
|
||||
<string name="title_UPPER_BACK">Upper Back</string>
|
||||
<string name="title_LEFT_HANDLE">Left Waist</string>
|
||||
<string name="title_RIGHT_HANDLE">Right Waist</string>
|
||||
<string name="title_PELVIS">Pelvis</string>
|
||||
<string name="title_L_UPPER_LEG">Left Upper Leg</string>
|
||||
<string name="title_R_UPPER_LEG">Right Upper Leg</string>
|
||||
<string name="title_L_LOWER_LEG">Left Lower Leg</string>
|
||||
<string name="title_R_LOWER_LEG">Right Lower Leg</string>
|
||||
<string name="title_L_FOOT">Left Foot</string>
|
||||
<string name="title_R_FOOT">Right Foot</string>
|
||||
|
||||
<!-- Just to demonstrate there is provision for axis-swapping/Negation per joint for BVH saving. -->
|
||||
<!-- A default of SWAP_X2Y_Y2Z_Z2X is used, which is overridden if anything (even blank) is provided here. -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<floater
|
||||
positioning="cascading"
|
||||
can_close="true"
|
||||
can_resize="false"
|
||||
help_topic="floater_primfeed"
|
||||
layout="topleft"
|
||||
name="floater_primfeed"
|
||||
save_rect="true"
|
||||
single_instance="true"
|
||||
reuse_instance="true"
|
||||
title="Share to Primfeed"
|
||||
height="600"
|
||||
width="272">
|
||||
<panel
|
||||
height="590"
|
||||
width="272"
|
||||
visible="true"
|
||||
name="background"
|
||||
follows="all"
|
||||
top="0"
|
||||
left="0">
|
||||
<tab_container
|
||||
name="tabs"
|
||||
tab_group="1"
|
||||
tab_min_width="70"
|
||||
tab_height="21"
|
||||
tab_position="top"
|
||||
top="7"
|
||||
height="570"
|
||||
follows="all"
|
||||
halign="center">
|
||||
<panel
|
||||
filename="panel_primfeed_photo.xml"
|
||||
class="fsprimfeedphotopanel"
|
||||
follows="all"
|
||||
label="Photo"
|
||||
name="panel_primfeed_photo"/>
|
||||
<panel
|
||||
filename="panel_primfeed_account.xml"
|
||||
class="fsprimfeedaccountpanel"
|
||||
follows="all"
|
||||
label="Account"
|
||||
name="panel_primfeed_account"/>
|
||||
</tab_container>
|
||||
<panel
|
||||
name="connection_status_panel"
|
||||
follows="left|bottom|right"
|
||||
height="24">
|
||||
<text
|
||||
name="connection_error_text"
|
||||
type="string"
|
||||
follows="left|bottom|right"
|
||||
bottom="-5"
|
||||
left="10"
|
||||
width="250"
|
||||
height="20"
|
||||
wrap="true"
|
||||
halign="left"
|
||||
valign="center"
|
||||
text_color="DrYellow"
|
||||
font="SansSerif">
|
||||
Error
|
||||
</text>
|
||||
<loading_indicator
|
||||
follows="left|bottom|right"
|
||||
height="24"
|
||||
width="24"
|
||||
name="connection_loading_indicator"
|
||||
top_delta="-2"
|
||||
left="10"
|
||||
visible="true"/>
|
||||
<text
|
||||
name="connection_loading_text"
|
||||
type="string"
|
||||
follows="left|bottom|right"
|
||||
top_delta="2"
|
||||
left_pad="5"
|
||||
width="250"
|
||||
height="20"
|
||||
wrap="true"
|
||||
halign="left"
|
||||
valign="center"
|
||||
text_color="EmphasisColor"
|
||||
font="SansSerif">
|
||||
Loading...
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -853,6 +853,13 @@
|
|||
function="Floater.Toggle"
|
||||
parameter="flickr"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Primfeed..."
|
||||
name="Primfeed">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Toggle"
|
||||
parameter="primfeed"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Discord..."
|
||||
name="Discord">
|
||||
|
|
@ -5669,6 +5676,18 @@
|
|||
<menu_item_call.on_click
|
||||
function="Advanced.CompressFileTest" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Primfeed Auth Test"
|
||||
name="primfeed_auth_test">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.PrimfeedAuth" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Primfeed Auth Reset"
|
||||
name="primfeed_auth_clear">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.PrimfeedAuthReset" />
|
||||
</menu_item_call>
|
||||
|
||||
<menu_item_call
|
||||
label="Enable Visual Leak Detector"
|
||||
|
|
|
|||
|
|
@ -7911,6 +7911,13 @@ Please select at least one type of content to search (General, Moderate, or Adul
|
|||
type="notifytip">
|
||||
[MESSAGE]
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notify.tga"
|
||||
name="PrimfeedConnect"
|
||||
type="notifytip">
|
||||
[MESSAGE]
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notify.tga"
|
||||
|
|
@ -13970,6 +13977,12 @@ Flickr verification failed. Please try again, and be sure to double check the ve
|
|||
name="ExodusFlickrUploadComplete"
|
||||
type="notifytip">
|
||||
Your snapshot can now be viewed [https://www.flickr.com/photos/me/[ID] here].
|
||||
</notification>
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="FSPrimfeedUploadComplete"
|
||||
type="notifytip">
|
||||
Your Primfeed post can now be viewed [[PF_POSTURL] here].
|
||||
</notification>
|
||||
<!-- </FS:TS> FIRE-5453 -->
|
||||
|
||||
|
|
@ -14693,4 +14706,60 @@ https://wiki.firestormviewer.org/antivirus_whitelisting
|
|||
yestext="Okay"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedLoginRequestFailed"
|
||||
persist="false"
|
||||
log_to_im="true"
|
||||
type="notify">
|
||||
Login request denied by Primfeed.
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedAuthorizationFailed"
|
||||
persist="false"
|
||||
tag="fail"
|
||||
type="alertmodal">
|
||||
Primfeed authorization failed. The authorization sequence was not completed.
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedAuthorizationAlreadyInProgress"
|
||||
persist="false"
|
||||
tag="fail"
|
||||
type="alertmodal">
|
||||
Primfeed authorization is already in progress. Please complete the Primfeed authorization in your web browser before trying again.
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedAuthorizationSuccessful"
|
||||
persist="false"
|
||||
tag="success"
|
||||
type="alertmodal">
|
||||
Primfeed authorization completed. You may now post images to Primfeed.
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedValidateFailed"
|
||||
persist="false"
|
||||
tag="fail"
|
||||
type="alertmodal">
|
||||
Primfeed user validation failed. Primfeed did not recognise this account, or the login failed.
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedAlreadyAuthorized"
|
||||
persist="false"
|
||||
tag="success"
|
||||
type="alertmodal">
|
||||
You have already linked this account to Primfeed. Use the reset button if you wish to start over.
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PrimfeedUserStatusFailed"
|
||||
persist="false"
|
||||
tag="fail"
|
||||
type="alertmodal">
|
||||
Primfeed user login successful, but status checks have failed. Please check the Primfeed is working.
|
||||
</notification>
|
||||
</notifications>
|
||||
|
|
|
|||
|
|
@ -273,7 +273,6 @@
|
|||
<!-- Added combo box to control the background behavior for prims -->
|
||||
<combo_box
|
||||
control_name="FSHudTextShowBackground"
|
||||
enabled_control="FSHudTextUseHoverHighlight"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
|
|
|
|||
|
|
@ -2007,7 +2007,7 @@
|
|||
label_height="0"
|
||||
layout="topleft"
|
||||
left="350"
|
||||
top_pad="5"
|
||||
top_pad="9"
|
||||
name="area_search_beacon_color"
|
||||
tool_tip="Choose area search beacon color"
|
||||
width="44">
|
||||
|
|
|
|||
|
|
@ -218,6 +218,17 @@
|
|||
left="10"
|
||||
width="500"
|
||||
tool_tip="Restores the current environment settings after next login."/>
|
||||
<check_box
|
||||
top_pad="5"
|
||||
control_name="FSRepeatedEnvTogglesShared"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
initial_value="true"
|
||||
name="FSRepeatedEnvTogglesShared"
|
||||
label="Repeated environment keybinds revert to shared environment"
|
||||
left="10"
|
||||
width="500"
|
||||
tool_tip="Causes repeated keybinds (e.g. ctrl+shift+y) to alternate between the requested preset & shared environment"/>
|
||||
</panel>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="540"
|
||||
width="272"
|
||||
layout="topleft"
|
||||
name="panel_primfeed_account">
|
||||
<string
|
||||
name="primfeed_connected"
|
||||
value="You are connected to Primfeed as:" />
|
||||
<string
|
||||
name="primfeed_disconnected"
|
||||
value="Not connected to Primfeed" />
|
||||
<string
|
||||
name="primfeed_plan_unknown"
|
||||
value="Unknown" />
|
||||
<text
|
||||
layout="topleft"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
name="connected_as_label"
|
||||
top="5"
|
||||
type="string">
|
||||
Not connected to Primfeed.
|
||||
</text>
|
||||
<text
|
||||
layout="topleft"
|
||||
top_pad="2"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
name="primfeed_account_name"
|
||||
parse_urls="true"
|
||||
type="string"/>
|
||||
<text
|
||||
layout="topleft"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
name="primfeed_account_plan_label"
|
||||
top_pad="2"
|
||||
type="string">
|
||||
Account type:
|
||||
</text>
|
||||
<text
|
||||
layout="topleft"
|
||||
top_pad="2"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
name="primfeed_account_plan"
|
||||
parse_urls="true"
|
||||
type="string"/>
|
||||
<panel
|
||||
layout="topleft"
|
||||
name="panel_buttons"
|
||||
height="345"
|
||||
left="0">
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
top_pad="9"
|
||||
visible="true"
|
||||
left="10"
|
||||
right="-10"
|
||||
height="23"
|
||||
label="Connect..."
|
||||
name="connect_btn"
|
||||
width="210">
|
||||
<commit_callback function="SocialSharing.Connect"/>
|
||||
</button>
|
||||
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
top_delta="0"
|
||||
left="10"
|
||||
right="-10"
|
||||
height="23"
|
||||
label="Disconnect"
|
||||
name="disconnect_btn"
|
||||
width="210"
|
||||
visible="false">
|
||||
<commit_callback function="SocialSharing.Disconnect"/>
|
||||
</button>
|
||||
<text
|
||||
layout="topleft"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
height="16"
|
||||
left="10"
|
||||
name="account_learn_more_label"
|
||||
top_pad="5"
|
||||
type="string">
|
||||
[https://docs.primfeed.com Learn more about Primfeed]
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="540"
|
||||
width="272"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_primfeed_photo">
|
||||
<combo_box
|
||||
control_name="FSPrimfeedPhotoResolution"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
top="5"
|
||||
left="10"
|
||||
name="resolution_combobox"
|
||||
tool_tip="Image resolution"
|
||||
height="21"
|
||||
width="124">
|
||||
<combo_box.item
|
||||
label="Current Window"
|
||||
name="CurrentWindow"
|
||||
value="[i0,i0]" />
|
||||
<combo_box.item
|
||||
label="320x240"
|
||||
name="320x240"
|
||||
value="[i320,i240]" />
|
||||
<combo_box.item
|
||||
label="640x480"
|
||||
name="640x480"
|
||||
value="[i640,i480]" />
|
||||
<combo_box.item
|
||||
label="800x600"
|
||||
name="800x600"
|
||||
value="[i800,i600]" />
|
||||
<combo_box.item
|
||||
label="1024x768"
|
||||
name="1024x768"
|
||||
value="[i1024,i768]" />
|
||||
<combo_box.item
|
||||
label="1280x1024"
|
||||
name="1280x1024"
|
||||
value="[i1280,i1024]" />
|
||||
<combo_box.item
|
||||
label="1600x1200"
|
||||
name="1600x1200"
|
||||
value="[i1600,i1200]" />
|
||||
<combo_box.item
|
||||
label="Custom"
|
||||
name="Custom"
|
||||
value="[i-1,i-1]" />
|
||||
</combo_box>
|
||||
<combo_box
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
name="filters_combobox"
|
||||
tool_tip="Image filters"
|
||||
top_delta="0"
|
||||
left_pad="4"
|
||||
height="21"
|
||||
width="124">
|
||||
<combo_box.item
|
||||
label="No Filter"
|
||||
name="NoFilter"
|
||||
value="NoFilter" />
|
||||
</combo_box>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="custom_snapshot_width"
|
||||
top_pad="7"
|
||||
width="54" />
|
||||
<text
|
||||
length="1"
|
||||
follows="top|left|right"
|
||||
layout="topleft"
|
||||
height="16"
|
||||
left_pad="3"
|
||||
name="spinner_x_lbl"
|
||||
top_delta="3"
|
||||
width="8"
|
||||
type="string">
|
||||
x
|
||||
</text>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label=""
|
||||
label_width="0"
|
||||
layout="topleft"
|
||||
left_pad="0"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="custom_snapshot_height"
|
||||
top_delta="-3"
|
||||
width="54" />
|
||||
<check_box
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
initial_value="true"
|
||||
label="Keep Aspect ratio"
|
||||
name="keep_aspect_ratio"
|
||||
left_pad="4"
|
||||
height="16"
|
||||
top_delta="4" />
|
||||
<panel
|
||||
height="150"
|
||||
width="250"
|
||||
visible="true"
|
||||
name="thumbnail_placeholder"
|
||||
top_pad="3"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
right="-10"
|
||||
left="10">
|
||||
</panel>
|
||||
<text
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
font="SansSerif"
|
||||
text_color="EmphasisColor"
|
||||
height="14"
|
||||
top_pad="2"
|
||||
left="10"
|
||||
length="1"
|
||||
halign="center"
|
||||
name="working_lbl"
|
||||
type="string"
|
||||
visible="true"
|
||||
width="251">
|
||||
Refreshing...
|
||||
</text>
|
||||
<check_box
|
||||
control_name="FSSnapshotShowCaptureFrame"
|
||||
label="Show capture frame"
|
||||
tool_tip="Show a frame on-screen that surrounds the areas of the snapshot. Parts of the scene that are outside of the snapshot will be de-saturated and slightly blurred."
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="7"
|
||||
width="124"
|
||||
name="show_frame" />
|
||||
<check_box
|
||||
enabled_control="FSSnapshotShowCaptureFrame"
|
||||
control_name="FSSnapshotShowGuides"
|
||||
label="Framing guide"
|
||||
tool_tip="Show framing guide (rule of thirds) inside the snapshot frame."
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
width="60"
|
||||
name="show_guides" />
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
height="1"
|
||||
left="10"
|
||||
name="refresh_border"
|
||||
width="250"
|
||||
top_pad="0" />
|
||||
<button
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
height="23"
|
||||
label="Refresh"
|
||||
left="10"
|
||||
top_pad="5"
|
||||
name="new_snapshot_btn"
|
||||
tool_tip="Click to refresh"
|
||||
visible="true"
|
||||
width="100">
|
||||
<button.commit_callback function="SocialSharing.RefreshPhoto" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|top"
|
||||
layout="topleft"
|
||||
height="23"
|
||||
label="Preview"
|
||||
right="-10"
|
||||
top_delta="0"
|
||||
name="big_preview_btn"
|
||||
tool_tip="Click to toggle preview"
|
||||
is_toggle="true"
|
||||
visible="true"
|
||||
width="100">
|
||||
<button.commit_callback function="SocialSharing.BigPreview" />
|
||||
</button>
|
||||
<text
|
||||
length="1"
|
||||
follows="top|left|right"
|
||||
layout="topleft"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
right="-10"
|
||||
name="description_label"
|
||||
top_pad="5"
|
||||
width="25"
|
||||
type="string">
|
||||
Description:
|
||||
</text>
|
||||
<text_editor
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
height="100"
|
||||
width="249"
|
||||
left="10"
|
||||
length="1"
|
||||
top_pad="0"
|
||||
max_length="5000"
|
||||
name="photo_description"
|
||||
spellcheck="true"
|
||||
type="string"
|
||||
word_wrap="true">
|
||||
</text_editor>
|
||||
<check_box
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
initial_value="false"
|
||||
label="Include location"
|
||||
name="add_location_cb"
|
||||
left="9"
|
||||
height="16"
|
||||
top_pad="8" />
|
||||
<check_box
|
||||
control_name="FSPrimfeedAddToPublicGallery"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
initial_value="false"
|
||||
label="Add to public gallery"
|
||||
name="primfeed_add_to_public_gallery"
|
||||
left="9"
|
||||
height="16"
|
||||
top_pad="8" />
|
||||
<button
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
height="16"
|
||||
image_pressed="Info_Press"
|
||||
image_unselected="Info_Over"
|
||||
name="info_btn_pub_gallery"
|
||||
right="-3"
|
||||
top_delta="-2"
|
||||
width="16"
|
||||
commit_callback.function="Primfeed.Info"
|
||||
commit_callback.parameter="https://docs.primfeed.com/featured-content/public-gallery"
|
||||
/>
|
||||
<check_box
|
||||
enabled_control="FSPrimfeedAddToPublicGallery"
|
||||
control_name="FSPrimfeedCommercialContent"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
initial_value="false"
|
||||
label="Commercial content"
|
||||
name="primfeed_commercial_content"
|
||||
left="9"
|
||||
height="16"
|
||||
top_pad="8" />
|
||||
<button
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
height="16"
|
||||
image_pressed="Info_Press"
|
||||
image_unselected="Info_Over"
|
||||
right="-3"
|
||||
top_delta="-2"
|
||||
name="info_btn_commercial_content"
|
||||
width="16"
|
||||
commit_callback.function="Primfeed.Info"
|
||||
commit_callback.parameter="https://docs.primfeed.com/legal/terms-of-service#commercial-content"
|
||||
/>
|
||||
<combo_box
|
||||
control_name="FSPrimfeedPhotoRating"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
top_pad="8"
|
||||
left="10"
|
||||
name="rating_combobox"
|
||||
tool_tip="Primfeed content rating"
|
||||
height="21"
|
||||
width="235">
|
||||
<combo_box.item
|
||||
label="General"
|
||||
name="GeneralRating"
|
||||
value="1" />
|
||||
<combo_box.item
|
||||
label="Moderate"
|
||||
name="ModerateRating"
|
||||
value="2" />
|
||||
<combo_box.item
|
||||
label="Adult"
|
||||
name="AdultRating"
|
||||
value="3" />
|
||||
<combo_box.item
|
||||
label="Adult+"
|
||||
name="AdultPlusRating"
|
||||
value="4" />
|
||||
</combo_box>
|
||||
<button
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
height="16"
|
||||
image_pressed="Info_Press"
|
||||
image_unselected="Info_Over"
|
||||
right="-3"
|
||||
name="info_btn_ratings"
|
||||
top_delta="0"
|
||||
width="16"
|
||||
commit_callback.function="Primfeed.Info"
|
||||
commit_callback.parameter="https://docs.primfeed.com/help-and-faq/maturity-ratings"
|
||||
/>
|
||||
<check_box
|
||||
control_name="FSPrimfeedOpenURLOnPost"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
initial_value="false"
|
||||
label="Open in browser after posting"
|
||||
tool_tip="Automatically open the Primfeed post in your web browser after posting."
|
||||
name="primfeed_open_url_on_post"
|
||||
left="9"
|
||||
height="16"
|
||||
top_pad="8" />
|
||||
<button
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
top_pad="8"
|
||||
left="10"
|
||||
height="23"
|
||||
label="Share"
|
||||
name="post_photo_btn"
|
||||
width="100">
|
||||
<button.commit_callback function="SocialSharing.SendPhoto" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|top"
|
||||
layout="topleft"
|
||||
height="23"
|
||||
label="Cancel"
|
||||
name="cancel_photo_btn"
|
||||
right="-10"
|
||||
top_delta="0"
|
||||
width="100">
|
||||
<button.commit_callback function="SocialSharing.Cancel" />
|
||||
</button>
|
||||
</panel>
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
animate="false"
|
||||
name="option_buttons"
|
||||
orientation="vertical"
|
||||
height="152"
|
||||
height="157"
|
||||
width="208"
|
||||
left="0"
|
||||
top="9"
|
||||
|
|
@ -52,6 +52,7 @@
|
|||
height="22"
|
||||
image_overlay="Snapshot_Inventory"
|
||||
image_overlay_alignment="left"
|
||||
image_overlay_width="16"
|
||||
image_top_pad="-1"
|
||||
imgoverlay_label_space="10"
|
||||
label="Save to Inventory"
|
||||
|
|
@ -111,6 +112,30 @@
|
|||
function="Snapshot.SendToFlickr"/>
|
||||
</button>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
auto_resize="false"
|
||||
user_resize="false"
|
||||
top_pad="0"
|
||||
height="22"
|
||||
name="lp_primfeed">
|
||||
<button
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
height="22"
|
||||
image_overlay="Command_Primfeed_Icon"
|
||||
image_overlay_alignment="left"
|
||||
image_top_pad="0"
|
||||
imgoverlay_label_space="10"
|
||||
label="Share to Primfeed"
|
||||
layout="topleft"
|
||||
left="9"
|
||||
name="send_to_primfeed_btn"
|
||||
top_pad="0">
|
||||
<button.commit_callback
|
||||
function="Snapshot.SendToPrimfeed"/>
|
||||
</button>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
auto_resize="false"
|
||||
user_resize="false"
|
||||
|
|
@ -145,7 +170,7 @@
|
|||
left="10"
|
||||
length="1"
|
||||
name="fee_hint_lbl"
|
||||
top_pad="7"
|
||||
top_pad="2"
|
||||
width="200"
|
||||
type="string"
|
||||
word_wrap="true">
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ If you feel this is an error, please contact support@secondlife.com</string>
|
|||
<string name="SocialFlickrErrorConnecting">Problem connecting to Flickr</string>
|
||||
<string name="SocialFlickrErrorPosting">Problem posting to Flickr</string>
|
||||
<string name="SocialFlickrErrorDisconnecting">Problem disconnecting from Flickr</string>
|
||||
<string name="SocialPrimfeedConnecting">Connecting to Primfeed...</string>
|
||||
<string name="SocialPrimfeedNotAuthorized">Not Authorized...</string>
|
||||
<string name="SocialPrimfeedPosting">Posting...</string>
|
||||
<string name="SocialPrimfeedErrorPosting">Problem posting to Primfeed</string>
|
||||
|
||||
<!-- SLShare: User Friendly Filter Names Translation -->
|
||||
<string name="BlackAndWhite">Black & White</string>
|
||||
|
|
@ -2771,6 +2775,8 @@ name="Command_360_Capture_Label">360° Snapshot</string>
|
|||
<string name="Command_Beacons_Label">Beacons</string>
|
||||
<string name="Command_Poser_Label">Poser</string>
|
||||
<string name="Command_Poser_Tooltip">Pose your avatar and animated objects</string>
|
||||
<string name="Command_Primfeed_Label">Primfeed</string>
|
||||
<string name="Command_Primfeed_Tooltip">Post directly to your Primfeed account.</string>
|
||||
|
||||
<string
|
||||
name="Command_360_Capture_Tooltip">Capture a 360° equirectangular image</string>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="floater_about" height="610" title="Acerca de [APP_NAME]">
|
||||
<floater name="floater_about" title="Acerca de [APP_NAME]">
|
||||
<floater.string name="AboutHeader">
|
||||
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL]) [BUILD_TYPE]
|
||||
[[VIEWER_RELEASE_NOTES_URL] Notas de la versión]
|
||||
|
|
@ -42,7 +42,7 @@ Calidad de dibujo (Render quality): [RENDERQUALITY]
|
|||
<floater.string name="ErrorFetchingServerReleaseNotesURL">
|
||||
Error obteniendo las notas de la versión de servidor.
|
||||
</floater.string>
|
||||
<tab_container name="about_tab" height="575">
|
||||
<tab_container name="about_tab">
|
||||
<panel label="Información" name="support_panel">
|
||||
<text name="support_intro">
|
||||
Para obtener la información más reciente acerca de Firestorm, visita
|
||||
|
|
@ -58,10 +58,10 @@ Los Linden son,
|
|||
con contribuciones de código de:
|
||||
</text>
|
||||
</panel>
|
||||
<panel label="Créditos de Firestorm" name="fs_credits_panel" height="920">
|
||||
<panel label="Créditos de Firestorm" name="fs_credits_panel">
|
||||
<scroll_container name="fs_credits_scroll_container">
|
||||
<panel name="fs_credits_scroll_container_content_panel">
|
||||
<text name="firestorm_intro" height="120">
|
||||
<text name="firestorm_intro">
|
||||
Firestorm es un proyecto de desarrollo de la comunidad para mejorar la experiencia de uso del Visor de SecondLife(tm). Compilamos contribuciones de varios desarrolladores de la comunidad junto con el código de Linden lab y el nuestro propio para brindarte un visor de calidad, enriquecido con nuevas características y respaldado por un amplio equipo de voluntarios para darte soporte. Firestorm llega a ti a través de The Phoenix Firestorm Project, Inc., una organización sin ánimo de lucro.
|
||||
|
||||
Forman el Equipo de Desarrollo de Firestorm:
|
||||
|
|
|
|||
|
|
@ -13,11 +13,20 @@
|
|||
<string name="header_mHindLimbsRoot">Membres postérieurs</string>
|
||||
<string name="header_mWingsRoot">Ailes</string>
|
||||
<string name="header_mFaceEar1Left">Oreilles/nez</string>
|
||||
<string name="header_mSkull">Corps</string>
|
||||
<string name="header_HEAD">Corps</string>
|
||||
<string name="header_L_UPPER_ARM">Bras</string>
|
||||
<string name="header_L_UPPER_LEG">Jambes</string>
|
||||
<string name="title_mPelvis">Tout l'avatar</string>
|
||||
<string name="title_mTorso">Torse</string>
|
||||
<string name="title_mSpine1">Colonne vertébrale 1</string>
|
||||
<string name="title_mSpine2">Colonne vertébrale 2</string>
|
||||
<string name="title_mSpine3">Colonne vertébrale 3</string>
|
||||
<string name="title_mSpine4">Colonne vertébrale 4</string>
|
||||
<string name="title_mChest">Poitrine</string>
|
||||
<string name="title_mNeck">Cou</string>
|
||||
<string name="title_mHead">Tête</string>
|
||||
<string name="title_mSkull">Crâne</string>
|
||||
<string name="title_mEyeRight">Oeil droit</string>
|
||||
<string name="title_mEyeLeft">Oeil gauche</string>
|
||||
<string name="title_mFaceForeheadLeft">Front, côté gauche</string>
|
||||
|
|
@ -29,13 +38,17 @@
|
|||
<string name="title_mFaceEyebrowCenterRight">Sourcil, milieu droit</string>
|
||||
<string name="title_mFaceEyebrowInnerRight">Sourcil, intérieur droit</string>
|
||||
<string name="title_mFaceEyeLidUpperLeft">Paupière, en haut à gauche</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">Coin interne gauche de l'œil</string>
|
||||
<string name="title_mFaceEyeLidLowerLeft">Paupière, en bas à gauche</string>
|
||||
<string name="title_mFaceEyeLidUpperRight">Paupière, en haut à droite</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">Coin interne droit de l'œil</string>
|
||||
<string name="title_mFaceEyeLidLowerRight">Paupière en bas à droite</string>
|
||||
<string name="title_mFaceEar1Left">Oreille en haut à gauche</string>
|
||||
<string name="title_mFaceEar2Left">Oreille en bas à gauche</string>
|
||||
<string name="title_mFaceEar1Right">Oreille en haut à droite</string>
|
||||
<string name="title_mFaceEar2Right">Oreille en bas à droite</string>
|
||||
<string name="title_mFaceNoseBase">Base du nez</string>
|
||||
<string name="title_mFaceNoseBridge">Arête du nez</string>
|
||||
<string name="title_mFaceNoseLeft">Nez à gauche</string>
|
||||
<string name="title_mFaceNoseCenter">Nez au milieu</string>
|
||||
<string name="title_mFaceNoseRight">Nez à droite</string>
|
||||
|
|
@ -52,16 +65,12 @@
|
|||
<string name="title_mFaceTongueTip">Extrémité de la langue</string>
|
||||
<string name="title_mFaceJawShaper">Forme de la mâchoire</string>
|
||||
<string name="title_mFaceForeheadCenter">Milieu du front</string>
|
||||
<string name="title_mFaceNoseBase">Base du nez</string>
|
||||
<string name="title_mFaceTeethUpper">Dents du haut</string>
|
||||
<string name="title_mFaceLipUpperLeft">Lèvre supérieure à gauche</string>
|
||||
<string name="title_mFaceLipUpperRight">Lèvre supérieure à droite</string>
|
||||
<string name="title_mFaceLipCornerLeft">Coin gauche de la bouche</string>
|
||||
<string name="title_mFaceLipCornerRight">Coin droit de la bouche</string>
|
||||
<string name="title_mFaceLipUpperCenter">Milieu de la lèvre supérieure</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">Coin interne gauche de l'œil</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">Coin interne droit de l'œil</string>
|
||||
<string name="title_mFaceNoseBridge">Arête du nez</string>
|
||||
<string name="title_mCollarLeft">Col</string>
|
||||
<string name="title_mShoulderLeft">Bras entier</string>
|
||||
<string name="title_mElbowLeft">Avant-bras</string>
|
||||
|
|
@ -137,10 +146,31 @@
|
|||
<string name="title_mHindLimb2Right">Droite 2</string>
|
||||
<string name="title_mHindLimb3Right">Droite 3</string>
|
||||
<string name="title_mHindLimb4Right">Droite 4</string>
|
||||
<string name="title_HEAD">Tête</string>
|
||||
<string name="title_NECK">Nuque</string>
|
||||
<string name="title_CHEST">Poitrine</string>
|
||||
<string name="title_BUTT">Fesses</string>
|
||||
<string name="title_BELLY">Ventre</string>
|
||||
<string name="title_LEFT_PEC">Sein gauche</string>
|
||||
<string name="title_RIGHT_PEC">Sein droit</string>
|
||||
<string name="title_L_CLAVICLE">Clavicule gauche</string>
|
||||
<string name="title_R_CLAVICLE">Clavicule droite</string>
|
||||
<string name="title_L_UPPER_ARM">Haut du bras gauche</string>
|
||||
<string name="title_R_UPPER_ARM">Haut du bras droit</string>
|
||||
<string name="title_L_LOWER_ARM">Bas du bras gauche</string>
|
||||
<string name="title_R_LOWER_ARM">Bas du bras droit</string>
|
||||
<string name="title_L_HAND">Main gauche</string>
|
||||
<string name="title_R_HAND">Main droite</string>
|
||||
<string name="title_UPPER_BACK">Haut du dos</string>
|
||||
<string name="title_LEFT_HANDLE">Taille à gauche</string>
|
||||
<string name="title_RIGHT_HANDLE">Taille à droite</string>
|
||||
<string name="title_PELVIS">Bassin</string>
|
||||
<string name="title_L_UPPER_LEG">Haut de la jambe gauche</string>
|
||||
<string name="title_R_UPPER_LEG">Haut de la jambe droite</string>
|
||||
<string name="title_L_LOWER_LEG">Bas de la jambe gauche</string>
|
||||
<string name="title_R_LOWER_LEG">Bas de la jambe droite</string>
|
||||
<string name="title_L_FOOT">Pied gauche</string>
|
||||
<string name="title_R_FOOT">Pied droit</string>
|
||||
<string name="LoadPoseLabel">Charger pose</string>
|
||||
<string name="SavePoseLabel">Enr. pose</string>
|
||||
<string name="LoadDiffLabel">Charger diff</string>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<floater name="floater_primfeed" title="Partager sur Primfeed">
|
||||
<panel name="background">
|
||||
<tab_container name="tabs">
|
||||
<panel label="Photo" name="panel_primfeed_photo"/>
|
||||
<panel label="Compte" name="panel_primfeed_account"/>
|
||||
</tab_container>
|
||||
<panel name="connection_status_panel">
|
||||
<text name="connection_error_text">
|
||||
Erreur
|
||||
</text>
|
||||
<text name="connection_loading_text">
|
||||
Chargement...
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -93,6 +93,7 @@
|
|||
<menu_item_check label="Conversations..." name="Conversations"/>
|
||||
<menu_item_check label="Gestes..." name="Gestures"/>
|
||||
<menu_item_call label="Flickr..." name="Flickr"/>
|
||||
<menu_item_call label="Primfeed..." name="Primfeed"/>
|
||||
<menu_item_call label="Discord..." name="Discord"/>
|
||||
<menu label="Effets de voix" name="VoiceMorphing">
|
||||
<menu_item_check label="Aucun effet de voix" name="NoVoiceMorphing"/>
|
||||
|
|
@ -616,6 +617,8 @@
|
|||
<menu_item_check label="Textures HTTP" name="HTTP Textures"/>
|
||||
<menu_item_call label="Compresser les images" name="Compress Images"/>
|
||||
<menu_item_call label="Test de compression de fichiers" name="Compress File Test" />
|
||||
<menu_item_call label="Test d'authentification Primfeed" name="primfeed_auth_test" />
|
||||
<menu_item_call label="Réinitialisation de l'authentification Primfeed" name="primfeed_auth_clear" />
|
||||
<menu_item_call label="Activer Visual Leak Detector" name="Enable Visual Leak Detector"/>
|
||||
<menu_item_check label="Aperçu du Journal de débogage" name="Output Debug Minidump"/>
|
||||
<menu_item_check label="Ouvrir la console de débogage au prochain lancement" name="Console Window"/>
|
||||
|
|
|
|||
|
|
@ -3065,6 +3065,9 @@ Voulez-vous autoriser [APP_NAME] à poster sur votre compte Flickr?
|
|||
<notification name="ExodusFlickrUploadComplete">
|
||||
Votre photo est visible maintenant [https://www.flickr.com/photos/me/[ID] ici].
|
||||
</notification>
|
||||
<notification name="FSPrimfeedUploadComplete">
|
||||
Votre message Primfeed peut maintenant être consulté [[PF_POSTURL] ici].
|
||||
</notification>
|
||||
<notification name="EventNotification">
|
||||
Avis d'événement :
|
||||
|
||||
|
|
@ -5632,4 +5635,29 @@ Pour obtenir des instructions détaillées sur la manière de mettre [APP_NAME]
|
|||
|
||||
https://wiki.firestormviewer.org/antivirus_whitelisting
|
||||
</notification>
|
||||
<notification label="Confirmer le remplacement de la pose" name="ConfirmPoserOverwrite">
|
||||
Remplacer la pose “[POSE_NAME]”?
|
||||
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Ok"/>
|
||||
</notification>
|
||||
<notification name="PrimfeedLoginRequestFailed">
|
||||
Demande de connexion refusée par Primfeed.
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationFailed">
|
||||
L'autorisation Primfeed a échoué. La séquence d'autorisation n'a pas été achevée.
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationAlreadyInProgress">
|
||||
L'autorisation Primfeed est déjà en cours. Veuillez compléter l'autorisation Primfeed dans votre navigateur web avant de réessayer.
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationSuccessful">
|
||||
Autorisation Primfeed terminée. Vous pouvez maintenant poster des images sur Primfeed.
|
||||
</notification>
|
||||
<notification name="PrimfeedValidateFailed">
|
||||
La validation de l'utilisateur Primfeed a échoué. Primfeed n'a pas reconnu ce compte ou la connexion a échoué.
|
||||
</notification>
|
||||
<notification name="PrimfeedAlreadyAuthorized">
|
||||
Vous avez déjà lié ce compte à Primfeed. Utilisez le bouton de réinitialisation si vous souhaitez recommencer.
|
||||
</notification>
|
||||
<notification name="PrimfeedUserStatusFailed">
|
||||
La connexion de l'utilisateur Primfeed a réussi, mais les vérifications d'état ont échoué. Veuillez vérifier que Primfeed fonctionne.
|
||||
</notification>
|
||||
</notifications>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<panel name="panel_primfeed_account">
|
||||
<string name="primfeed_connected" value="Connecté(e) à Primfeed en tant que :"/>
|
||||
<string name="primfeed_disconnected" value="Non connecté(e) à Primfeed"/>
|
||||
<string name="primfeed_plan_unknown" value="Inconnu"/>
|
||||
<text name="connected_as_label">
|
||||
Non connecté(e) à Primfeed.
|
||||
</text>
|
||||
<text name="primfeed_account_plan_label">
|
||||
Type de compte :
|
||||
</text>
|
||||
<panel name="panel_buttons">
|
||||
<button label="Se connecter..." name="connect_btn"/>
|
||||
<button label="Se déconnecter" name="disconnect_btn"/>
|
||||
<text name="account_learn_more_label">
|
||||
[https://docs.primfeed.com En savoir plus sur Primfeed]
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<panel name="panel_primfeed_photo">
|
||||
<combo_box name="resolution_combobox" tool_tip="Résolution de l'image">
|
||||
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
|
||||
<combo_box.item label="Personnalisée" name="Custom"/>
|
||||
</combo_box>
|
||||
<combo_box name="filters_combobox" tool_tip="Filtres d'image">
|
||||
<combo_box.item label="Pas de filtre" name="NoFilter"/>
|
||||
</combo_box>
|
||||
<check_box label="Garder les proportions" name="keep_aspect_ratio"/>
|
||||
<text name="working_lbl">
|
||||
Rafraichissement...
|
||||
</text>
|
||||
<check_box label="Cadre de la photo" tool_tip="Affiche un cadre à l'écran qui entoure la zones de la photo. Les parties de la scène qui se trouvent en dehors de la photo sont dé-saturées et légèrement floues." name="show_frame"/>
|
||||
<check_box label="Guide de cadrage" tool_tip="Affiche le guide de cadrage (règle des tiers) à l'intérieur du cadre de la photo." name="show_guides"/>
|
||||
<button label="Actualiser" name="new_snapshot_btn" tool_tip="Cliquez pour actualiser"/>
|
||||
<button label="Aperçu" name="big_preview_btn" tool_tip="Cliquez pour afficher l'aperçu"/>
|
||||
<text name="description_label">
|
||||
Description :
|
||||
</text>
|
||||
<check_box label="Inclure l'emplacement" name="add_location_cb"/>
|
||||
<check_box label="Ajouter à la galerie publique" name="primfeed_add_to_public_gallery"/>
|
||||
<check_box label="Contenu commercial" name="primfeed_commercial_content"/>
|
||||
<combo_box name="rating_combobox" tool_tip="Classification du contenu de Primfeed">
|
||||
<combo_box.item label="Général" name="GeneralRating"/>
|
||||
<combo_box.item label="Modéré" name="ModerateRating"/>
|
||||
<combo_box.item label="Adulte" name="AdultRating"/>
|
||||
<combo_box.item label="Adulte+" name="AdultPlusRating"/>
|
||||
</combo_box>
|
||||
<check_box label="Ouvrir dans le navigateur après l'envoi" tool_tip="Ouvrir automatiquement le message Primfeed dans votre navigateur web après l'avoir publié." name="primfeed_open_url_on_post"/>
|
||||
<button label="Partager" name="post_photo_btn"/>
|
||||
<button label="Annuler" name="cancel_photo_btn"/>
|
||||
</panel>
|
||||
|
|
@ -1,13 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel name="panel_snapshot_options">
|
||||
<layout_stack name="option_buttons">
|
||||
<layout_panel name="lp_download"><button label="Sur le disque" name="save_to_computer_btn"/></layout_panel>
|
||||
<layout_panel name="lp_inventory"><button label="Dans l'inventaire" name="save_to_inventory_btn"/></layout_panel>
|
||||
<layout_panel name="lp_profile"><button label="En ligne sur mon profil" name="save_to_profile_btn"/></layout_panel>
|
||||
<layout_panel name="lp_facebook"><button label="En ligne sur Facebook" name="send_to_facebook_btn"/></layout_panel>
|
||||
<layout_panel name="lp_twitter"><button label="En ligne sur Twitter" name="send_to_twitter_btn"/></layout_panel>
|
||||
<layout_panel name="lp_flickr"><button label="En ligne sur Flickr" name="send_to_flickr_btn"/></layout_panel>
|
||||
<layout_panel name="lp_email"><button label="Envoyer par E-mail" name="save_to_email_btn"/></layout_panel>
|
||||
<layout_panel name="lp_download">
|
||||
<button label="Sur le disque" name="save_to_computer_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_inventory">
|
||||
<button label="Dans l'inventaire" name="save_to_inventory_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_profile">
|
||||
<button label="En ligne sur mon profil" name="save_to_profile_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_facebook">
|
||||
<button label="En ligne sur Facebook" name="send_to_facebook_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_twitter">
|
||||
<button label="En ligne sur Twitter" name="send_to_twitter_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_flickr">
|
||||
<button label="En ligne sur Flickr" name="send_to_flickr_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_email">
|
||||
<button label="Envoyer par E-mail" name="save_to_email_btn"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="lp_primfeed">
|
||||
<button label="Partager sur Primfeed" name="send_to_primfeed_btn"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
<text name="fee_hint_lbl">
|
||||
Les frais sont basés sur votre niveau d'abonnement. Plus haut est ce niveau, plus bas sont les frais.
|
||||
|
|
|
|||
|
|
@ -14,13 +14,22 @@
|
|||
<string name="header_mHindLimbsRoot">後ろ足</string>
|
||||
<string name="header_mWingsRoot">羽</string>
|
||||
<string name="header_mFaceEar1Left">耳/鼻</string>
|
||||
<string name="header_mSkull">体</string>
|
||||
<string name="header_HEAD">体</string>
|
||||
<string name="header_L_UPPER_ARM">腕</string>
|
||||
<string name="header_L_UPPER_LEG">脚</string>
|
||||
|
||||
<!-- These are names to appear on the UI for the joints/bones/thingos -->
|
||||
<string name="title_mPelvis">アバター全体</string>
|
||||
<string name="title_mTorso">胴体</string>
|
||||
<string name="title_mSpine1">背骨1</string>
|
||||
<string name="title_mSpine2">背骨2</string>
|
||||
<string name="title_mSpine3">背骨3</string>
|
||||
<string name="title_mSpine4">背骨4</string>
|
||||
<string name="title_mChest">胸部</string>
|
||||
<string name="title_mNeck">首</string>
|
||||
<string name="title_mHead">頭</string>
|
||||
<string name="title_mSkull">頭蓋骨</string>
|
||||
<string name="title_mEyeRight">右目</string>
|
||||
<string name="title_mEyeLeft">左目</string>
|
||||
<string name="title_mFaceForeheadLeft">額の左側</string>
|
||||
|
|
@ -32,8 +41,10 @@
|
|||
<string name="title_mFaceEyebrowCenterRight">右眉毛の中側</string>
|
||||
<string name="title_mFaceEyebrowInnerRight">右眉毛の内側</string>
|
||||
<string name="title_mFaceEyeLidUpperLeft">左の上瞼</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">左の目頭</string>
|
||||
<string name="title_mFaceEyeLidLowerLeft">右の下瞼</string>
|
||||
<string name="title_mFaceEyeLidUpperRight">左の上瞼</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">右の目頭</string>
|
||||
<string name="title_mFaceEyeLidLowerRight">右の下瞼</string>
|
||||
<string name="title_mFaceEar1Left">左耳の上</string>
|
||||
<string name="title_mFaceEar2Left">左耳の下</string>
|
||||
|
|
@ -62,8 +73,6 @@
|
|||
<string name="title_mFaceLipCornerLeft">唇の角左</string>
|
||||
<string name="title_mFaceLipCornerRight">唇の角右</string>
|
||||
<string name="title_mFaceLipUpperCenter">唇の角中央</string>
|
||||
<string name="title_mFaceEyecornerInnerLeft">左目尻の内側</string>
|
||||
<string name="title_mFaceEyecornerInnerRight">右目尻の内側</string>
|
||||
<string name="title_mFaceNoseBridge">鼻橋</string>
|
||||
<string name="title_mCollarLeft">襟</string>
|
||||
<string name="title_mShoulderLeft">腕全体</string>
|
||||
|
|
@ -140,10 +149,31 @@
|
|||
<string name="title_mHindLimb2Right">右2</string>
|
||||
<string name="title_mHindLimb3Right">右3</string>
|
||||
<string name="title_mHindLimb4Right">右4</string>
|
||||
<string name="title_BUTT">お尻</string>
|
||||
<string name="title_HEAD">頭</string>
|
||||
<string name="title_NECK">首</string>
|
||||
<string name="title_CHEST">胸</string>
|
||||
<string name="title_BUTT">尻</string>
|
||||
<string name="title_BELLY">腹</string>
|
||||
<string name="title_LEFT_PEC">左胸筋</string>
|
||||
<string name="title_RIGHT_PEC">右胸筋</string>
|
||||
<string name="title_L_CLAVICLE">左鎖骨</string>
|
||||
<string name="title_R_CLAVICLE">右鎖骨</string>
|
||||
<string name="title_L_UPPER_ARM">左上腕</string>
|
||||
<string name="title_R_UPPER_ARM">右上腕</string>
|
||||
<string name="title_L_LOWER_ARM">左腕</string>
|
||||
<string name="title_R_LOWER_ARM">右腕</string>
|
||||
<string name="title_L_HAND">左手</string>
|
||||
<string name="title_R_HAND">右手</string>
|
||||
<string name="title_UPPER_BACK">上背</string>
|
||||
<string name="title_LEFT_HANDLE">左腰</string>
|
||||
<string name="title_RIGHT_HANDLE">右腰</string>
|
||||
<string name="title_PELVIS">骨盤</string>
|
||||
<string name="title_L_UPPER_LEG">左腿</string>
|
||||
<string name="title_R_UPPER_LEG">右腿</string>
|
||||
<string name="title_L_LOWER_LEG">左脹脛</string>
|
||||
<string name="title_R_LOWER_LEG">右脹脛</string>
|
||||
<string name="title_L_FOOT">左足</string>
|
||||
<string name="title_R_FOOT">右足</string>
|
||||
|
||||
<string name="LoadPoseLabel">ポーズを読み込む</string>
|
||||
<string name="SavePoseLabel">ポーズを保存</string>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<floater name="floater_primfeed" title="Primfeedで共有">
|
||||
<panel name="background">
|
||||
<tab_container name="tabs">
|
||||
<panel label="フォト" name="panel_primfeed_photo"/>
|
||||
<panel label="アカウント" name="panel_primfeed_account"/>
|
||||
</tab_container>
|
||||
<panel name="connection_status_panel">
|
||||
<text name="connection_error_text">
|
||||
エラー
|
||||
</text>
|
||||
<text name="connection_loading_text">
|
||||
読み込んでいます…
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -671,6 +671,8 @@
|
|||
<menu_item_check label="HTTPインベントリ" name="HTTP Inventory"/>
|
||||
<menu_item_call label="圧縮画像" name="Compress Images"/>
|
||||
<menu_item_call label="圧縮ファイルテスト" name="Compress File Test"/>
|
||||
<menu_item_call label="Primfeed認証テスト" name="primfeed_auth_test"/>
|
||||
<menu_item_call label="Primfeed認証をリセット" name="primfeed_auth_clear"/>
|
||||
<menu_item_call label="Visual Leak Detectorを有効にする" name="Enable Visual Leak Detector"/>
|
||||
<menu_item_check label="デバッグ用のミニダンプを出力する" name="Output Debug Minidump"/>
|
||||
<menu_item_check label="次回の起動時にコンソールウィンドウを表示する" name="Console Window"/>
|
||||
|
|
|
|||
|
|
@ -5357,6 +5357,9 @@ http://opensimulator.org/wiki/inventory を使用して問題を修正できま
|
|||
<notification name="ExodusFlickrUploadComplete">
|
||||
スナップショットは[http://www.flickr.com/photos/upload/edit/?ids=[ID] ここ]から閲覧できます。
|
||||
</notification>
|
||||
<notification name="FSPrimfeedUploadComplete">
|
||||
あなたのPrimfeedへの投稿は[[PF_POSTURL] ここ]から閲覧できます。
|
||||
</notification>
|
||||
<!-- </FS:TS> FIRE-5453 -->
|
||||
<notification name="RegionTrackerAdd">
|
||||
リージョン「[REGION]」にどのラベルを使用しますか?
|
||||
|
|
@ -5645,4 +5648,25 @@ https://wiki.firestormviewer.org/antivirus_whitelisting
|
|||
「[POSE_NAME]」を上書きしてもよろしいですか?
|
||||
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="はい"/>
|
||||
</notification>
|
||||
<notification name="PrimfeedLoginRequestFailed">
|
||||
Primfeedへのログインリクエストが拒否されました。
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationFailed">
|
||||
Primfeed認証に失敗しました。認証シーケンスが完了していません。
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationAlreadyInProgress">
|
||||
すでにPrimfeed認証が進行中です。ブラウザでPrimfeed認証を完了してから、もう一度お試しください。
|
||||
</notification>
|
||||
<notification name="PrimfeedAuthorizationSuccessful">
|
||||
Primfeed認証が成功しました。Primfeedに画像を投稿できるようになりました。
|
||||
</notification>
|
||||
<notification name="PrimfeedValidateFailed">
|
||||
Primfeedユーザーの検証に失敗しました。Primfeedはこのアカウントを認識しなかったか、ログインに失敗しました。
|
||||
</notification>
|
||||
<notification name="PrimfeedAlreadyAuthorized">
|
||||
あなたはすでにPrimfeedにリンクされています。リセットボタンを押すことで、最初からやり直すことができます。
|
||||
</notification>
|
||||
<notification name="PrimfeedUserStatusFailed">
|
||||
Primfeedへのユーザログインは成功しましたが、ステータスチェックに失敗しました。Primfeedが機能しているかどうかを確認してください。
|
||||
</notification>
|
||||
</notifications>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<panel name="panel_primfeed_account">
|
||||
<string name="primfeed_connected" value="Primfeedに接続:"/>
|
||||
<string name="primfeed_disconnected" value="Primfeedに接続されていません。"/>
|
||||
<string name="primfeed_plan_unknown" value="不明" />
|
||||
<text name="connected_as_label">
|
||||
Primfeedに接続されていません。
|
||||
</text>
|
||||
<text name="primfeed_account_plan_label">
|
||||
アカウント種別:
|
||||
</text>
|
||||
<panel name="panel_buttons">
|
||||
<button label="接続…" name="connect_btn"/>
|
||||
<button label="切断" name="disconnect_btn"/>
|
||||
<text name="account_learn_more_label">
|
||||
[https://docs.primfeed.com Primfeedについて学ぶ]
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue