merge changes for storm-1580
commit
22dd6acbc9
|
|
@ -219,7 +219,6 @@ set(viewer_SOURCE_FILES
|
|||
llfloateropenobject.cpp
|
||||
llfloaterpay.cpp
|
||||
llfloaterperms.cpp
|
||||
llfloaterpostcard.cpp
|
||||
llfloaterpostprocess.cpp
|
||||
llfloaterpreference.cpp
|
||||
llfloaterproperties.cpp
|
||||
|
|
@ -396,6 +395,12 @@ set(viewer_SOURCE_FILES
|
|||
llpanelprimmediacontrols.cpp
|
||||
llpanelprofile.cpp
|
||||
llpanelprofileview.cpp
|
||||
llpanelsnapshot.cpp
|
||||
llpanelsnapshotinventory.cpp
|
||||
llpanelsnapshotlocal.cpp
|
||||
llpanelsnapshotoptions.cpp
|
||||
llpanelsnapshotpostcard.cpp
|
||||
llpanelsnapshotprofile.cpp
|
||||
llpanelteleporthistory.cpp
|
||||
llpaneltiptoast.cpp
|
||||
llpanelvoiceeffect.cpp
|
||||
|
|
@ -414,6 +419,7 @@ set(viewer_SOURCE_FILES
|
|||
llpopupview.cpp
|
||||
llpolymesh.cpp
|
||||
llpolymorph.cpp
|
||||
llpostcard.cpp
|
||||
llpreview.cpp
|
||||
llpreviewanim.cpp
|
||||
llpreviewgesture.cpp
|
||||
|
|
@ -603,6 +609,7 @@ set(viewer_SOURCE_FILES
|
|||
llwearablelist.cpp
|
||||
llwearabletype.cpp
|
||||
llweb.cpp
|
||||
llwebprofile.cpp
|
||||
llwebsharing.cpp
|
||||
llwind.cpp
|
||||
llwindowlistener.cpp
|
||||
|
|
@ -786,7 +793,6 @@ set(viewer_HEADER_FILES
|
|||
llfloateropenobject.h
|
||||
llfloaterpay.h
|
||||
llfloaterperms.h
|
||||
llfloaterpostcard.h
|
||||
llfloaterpostprocess.h
|
||||
llfloaterpreference.h
|
||||
llfloaterproperties.h
|
||||
|
|
@ -957,6 +963,7 @@ set(viewer_HEADER_FILES
|
|||
llpanelprimmediacontrols.h
|
||||
llpanelprofile.h
|
||||
llpanelprofileview.h
|
||||
llpanelsnapshot.h
|
||||
llpanelteleporthistory.h
|
||||
llpaneltiptoast.h
|
||||
llpanelvoicedevicesettings.h
|
||||
|
|
@ -975,6 +982,7 @@ set(viewer_HEADER_FILES
|
|||
llpolymesh.h
|
||||
llpolymorph.h
|
||||
llpopupview.h
|
||||
llpostcard.h
|
||||
llpreview.h
|
||||
llpreviewanim.h
|
||||
llpreviewgesture.h
|
||||
|
|
@ -1164,6 +1172,7 @@ set(viewer_HEADER_FILES
|
|||
llwearablelist.h
|
||||
llwearabletype.h
|
||||
llweb.h
|
||||
llwebprofile.h
|
||||
llwebsharing.h
|
||||
llwind.h
|
||||
llwindowlistener.h
|
||||
|
|
|
|||
|
|
@ -1605,17 +1605,6 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>CloseSnapshotOnKeep</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Close snapshot window after saving snapshot</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>CmdLineDisableVoice</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -4667,6 +4656,17 @@
|
|||
<string>0.0.0</string>
|
||||
</map>
|
||||
|
||||
<key>LastSnapshotToProfileHeight</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The height of the last profile snapshot, in px</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>768</integer>
|
||||
</map>
|
||||
<key>LastSnapshotToEmailHeight</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -4678,6 +4678,17 @@
|
|||
<key>Value</key>
|
||||
<integer>768</integer>
|
||||
</map>
|
||||
<key>LastSnapshotToProfileWidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The width of the last profile snapshot, in px</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1024</integer>
|
||||
</map>
|
||||
<key>LastSnapshotToEmailWidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -4733,17 +4744,6 @@
|
|||
<key>Value</key>
|
||||
<integer>512</integer>
|
||||
</map>
|
||||
<key>LastSnapshotType</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Select this as next type of snapshot to take (0 = postcard, 1 = texture, 2 = local image)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LeftClickShowMenu</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10608,6 +10608,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotProfileLastResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Take next profile snapshot at this resolution</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotPostcardLastResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ void on_new_single_inventory_upload_complete(
|
|||
const LLSD& server_response,
|
||||
S32 upload_price)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if ( upload_price > 0 )
|
||||
{
|
||||
// this upload costed us L$, update our balance
|
||||
|
|
@ -152,6 +154,7 @@ void on_new_single_inventory_upload_complete(
|
|||
|
||||
gInventory.updateItem(item);
|
||||
gInventory.notifyObservers();
|
||||
success = true;
|
||||
|
||||
// Show the preview panel for textures and sounds to let
|
||||
// user know that the image (or snapshot) arrived intact.
|
||||
|
|
@ -175,6 +178,13 @@ void on_new_single_inventory_upload_complete(
|
|||
|
||||
// remove the "Uploading..." message
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
|
||||
// Let the Snapshot floater know we have finished uploading a snapshot to inventory.
|
||||
LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
|
||||
if (asset_type == LLAssetType::AT_TEXTURE && floater_snapshot)
|
||||
{
|
||||
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
|
||||
}
|
||||
}
|
||||
|
||||
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
|
||||
|
|
|
|||
|
|
@ -1,384 +0,0 @@
|
|||
/**
|
||||
* @file llfloaterpostcard.cpp
|
||||
* @brief Postcard send floater, allows setting name, e-mail address, etc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloaterpostcard.h"
|
||||
|
||||
#include "llfontgl.h"
|
||||
#include "llsys.h"
|
||||
#include "llgl.h"
|
||||
#include "v3dmath.h"
|
||||
#include "lldir.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llui.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llbutton.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewernetwork.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluploaddialog.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llstatusbar.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lleconomy.h"
|
||||
#include "message.h"
|
||||
|
||||
#include "llimagejpeg.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llvfile.h"
|
||||
#include "llvfs.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llassetuploadresponders.h"
|
||||
#include "llagentui.h"
|
||||
|
||||
#include <boost/regex.hpp> //boost.regex lib
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterPostcard
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLFloaterPostcard::LLFloaterPostcard(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mJPEGImage(NULL),
|
||||
mViewerImage(NULL),
|
||||
mHasFirstMsgFocus(false)
|
||||
{
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
LLFloaterPostcard::~LLFloaterPostcard()
|
||||
{
|
||||
mJPEGImage = NULL; // deletes image
|
||||
}
|
||||
|
||||
BOOL LLFloaterPostcard::postBuild()
|
||||
{
|
||||
// pick up the user's up-to-date email address
|
||||
gAgent.sendAgentUserInfoRequest();
|
||||
|
||||
childSetAction("cancel_btn", onClickCancel, this);
|
||||
childSetAction("send_btn", onClickSend, this);
|
||||
|
||||
getChildView("from_form")->setEnabled(FALSE);
|
||||
|
||||
std::string name_string;
|
||||
LLAgentUI::buildFullname(name_string);
|
||||
getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
|
||||
|
||||
// For the first time a user focusess to .the msg box, all text will be selected.
|
||||
getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(onMsgFormFocusRecieved, _1, this));
|
||||
|
||||
getChild<LLUICtrl>("to_form")->setFocus(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global)
|
||||
{
|
||||
// Take the images from the caller
|
||||
// It's now our job to clean them up
|
||||
LLFloaterPostcard* instance = LLFloaterReg::showTypedInstance<LLFloaterPostcard>("postcard", LLSD(img->getID()));
|
||||
|
||||
if (instance) // may be 0 if we're in mouselook mode
|
||||
{
|
||||
instance->mJPEGImage = jpeg;
|
||||
instance->mViewerImage = img;
|
||||
instance->mImageScale = image_scale;
|
||||
instance->mPosTakenGlobal = pos_taken_global;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void LLFloaterPostcard::draw()
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLFloater::draw();
|
||||
|
||||
if(!isMinimized() && mViewerImage.notNull() && mJPEGImage.notNull())
|
||||
{
|
||||
// Force the texture to be 100% opaque when the floater is focused.
|
||||
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
LLRect rect(getRect());
|
||||
|
||||
// first set the max extents of our preview
|
||||
rect.translate(-rect.mLeft, -rect.mBottom);
|
||||
rect.mLeft += 320;
|
||||
rect.mRight -= 10;
|
||||
rect.mTop -= 27;
|
||||
rect.mBottom = rect.mTop - 130;
|
||||
|
||||
// then fix the aspect ratio
|
||||
F32 ratio = (F32)mJPEGImage->getWidth() / (F32)mJPEGImage->getHeight();
|
||||
if ((F32)rect.getWidth() / (F32)rect.getHeight() >= ratio)
|
||||
{
|
||||
rect.mRight = LLRect::tCoordType((F32)rect.mLeft + ((F32)rect.getHeight() * ratio));
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.mBottom = LLRect::tCoordType((F32)rect.mTop - ((F32)rect.getWidth() / ratio));
|
||||
}
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f) % alpha);
|
||||
rect.stretch(-1);
|
||||
}
|
||||
{
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
{
|
||||
glScalef(mImageScale.mV[VX], mImageScale.mV[VY], 1.f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gl_draw_scaled_image(rect.mLeft,
|
||||
rect.mBottom,
|
||||
rect.getWidth(),
|
||||
rect.getHeight(),
|
||||
mViewerImage.get(),
|
||||
LLColor4::white % alpha);
|
||||
}
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterPostcard::onClickCancel(void* data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
LLFloaterPostcard *self = (LLFloaterPostcard *)data;
|
||||
|
||||
self->closeFloater(false);
|
||||
}
|
||||
}
|
||||
|
||||
class LLSendPostcardResponder : public LLAssetUploadResponder
|
||||
{
|
||||
public:
|
||||
LLSendPostcardResponder(const LLSD &post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type):
|
||||
LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
{
|
||||
}
|
||||
// *TODO define custom uploadFailed here so it's not such a generic message
|
||||
void uploadComplete(const LLSD& content)
|
||||
{
|
||||
// we don't care about what the server returns from this post, just clean up the UI
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
}
|
||||
};
|
||||
|
||||
// static
|
||||
void LLFloaterPostcard::onClickSend(void* data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
LLFloaterPostcard *self = (LLFloaterPostcard *)data;
|
||||
|
||||
std::string from(self->getChild<LLUICtrl>("from_form")->getValue().asString());
|
||||
std::string to(self->getChild<LLUICtrl>("to_form")->getValue().asString());
|
||||
|
||||
boost::regex emailFormat("[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}(,[ \t]*[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})*");
|
||||
|
||||
if (to.empty() || !boost::regex_match(to, emailFormat))
|
||||
{
|
||||
LLNotificationsUtil::add("PromptRecipientEmail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.empty() || !boost::regex_match(from, emailFormat))
|
||||
{
|
||||
LLNotificationsUtil::add("PromptSelfEmail");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string subject(self->getChild<LLUICtrl>("subject_form")->getValue().asString());
|
||||
if(subject.empty() || !self->mHasFirstMsgFocus)
|
||||
{
|
||||
LLNotificationsUtil::add("PromptMissingSubjMsg", LLSD(), LLSD(), boost::bind(&LLFloaterPostcard::missingSubjMsgAlertCallback, self, _1, _2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->mJPEGImage.notNull())
|
||||
{
|
||||
self->sendPostcard();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("ErrorProcessingSnapshot");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed)
|
||||
{
|
||||
LLFloaterPostcard *self = (LLFloaterPostcard *)user_data;
|
||||
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
|
||||
if (result)
|
||||
{
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
|
||||
LLNotificationsUtil::add("ErrorUploadingPostcard", args);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only create the postcard once the upload succeeds
|
||||
|
||||
// request the postcard
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage("SendPostcard");
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->addUUID("AssetID", self->mAssetID);
|
||||
msg->addVector3d("PosGlobal", self->mPosTakenGlobal);
|
||||
msg->addString("To", self->getChild<LLUICtrl>("to_form")->getValue().asString());
|
||||
msg->addString("From", self->getChild<LLUICtrl>("from_form")->getValue().asString());
|
||||
msg->addString("Name", self->getChild<LLUICtrl>("name_form")->getValue().asString());
|
||||
msg->addString("Subject", self->getChild<LLUICtrl>("subject_form")->getValue().asString());
|
||||
msg->addString("Msg", self->getChild<LLUICtrl>("msg_form")->getValue().asString());
|
||||
msg->addBOOL("AllowPublish", FALSE);
|
||||
msg->addBOOL("MaturePublish", FALSE);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
self->closeFloater();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterPostcard::updateUserInfo(const std::string& email)
|
||||
{
|
||||
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("postcard");
|
||||
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
|
||||
iter != inst_list.end(); ++iter)
|
||||
{
|
||||
LLFloater* instance = *iter;
|
||||
const std::string& text = instance->getChild<LLUICtrl>("from_form")->getValue().asString();
|
||||
if (text.empty())
|
||||
{
|
||||
// there's no text in this field yet, pre-populate
|
||||
instance->getChild<LLUICtrl>("from_form")->setValue(LLSD(email));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data)
|
||||
{
|
||||
LLFloaterPostcard* self = (LLFloaterPostcard *)data;
|
||||
if(self)
|
||||
{
|
||||
LLTextEditor* msgForm = self->getChild<LLTextEditor>("msg_form");
|
||||
if(msgForm && msgForm == receiver && msgForm->hasFocus() && !(self->mHasFirstMsgFocus))
|
||||
{
|
||||
self->mHasFirstMsgFocus = true;
|
||||
msgForm->setText(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterPostcard::missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if(0 == option)
|
||||
{
|
||||
// User clicked OK
|
||||
if((getChild<LLUICtrl>("subject_form")->getValue().asString()).empty())
|
||||
{
|
||||
// Stuff the subject back into the form.
|
||||
getChild<LLUICtrl>("subject_form")->setValue(getString("default_subject"));
|
||||
}
|
||||
|
||||
if(!mHasFirstMsgFocus)
|
||||
{
|
||||
// The user never switched focus to the messagee window.
|
||||
// Using the default string.
|
||||
getChild<LLUICtrl>("msg_form")->setValue(getString("default_message"));
|
||||
}
|
||||
|
||||
sendPostcard();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterPostcard::sendPostcard()
|
||||
{
|
||||
mTransactionID.generate();
|
||||
mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
|
||||
LLVFile::writeFile(mJPEGImage->getData(), mJPEGImage->getDataSize(), gVFS, mAssetID, LLAssetType::AT_IMAGE_JPEG);
|
||||
|
||||
// upload the image
|
||||
std::string url = gAgent.getRegion()->getCapability("SendPostcard");
|
||||
if(!url.empty())
|
||||
{
|
||||
llinfos << "Send Postcard via capability" << llendl;
|
||||
LLSD body = LLSD::emptyMap();
|
||||
// the capability already encodes: agent ID, region ID
|
||||
body["pos-global"] = mPosTakenGlobal.getValue();
|
||||
body["to"] = getChild<LLUICtrl>("to_form")->getValue().asString();
|
||||
body["from"] = getChild<LLUICtrl>("from_form")->getValue().asString();
|
||||
body["name"] = getChild<LLUICtrl>("name_form")->getValue().asString();
|
||||
body["subject"] = getChild<LLUICtrl>("subject_form")->getValue().asString();
|
||||
body["msg"] = getChild<LLUICtrl>("msg_form")->getValue().asString();
|
||||
LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG));
|
||||
}
|
||||
else
|
||||
{
|
||||
gAssetStorage->storeAssetData(mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)this, FALSE);
|
||||
}
|
||||
|
||||
// give user feedback of the event
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
LLUploadDialog::modalUploadDialog(getString("upload_message"));
|
||||
|
||||
// don't destroy the window until the upload is done
|
||||
// this way we keep the information in the form
|
||||
setVisible(FALSE);
|
||||
|
||||
// also remove any dependency on another floater
|
||||
// so that we can be sure to outlive it while we
|
||||
// need to.
|
||||
LLFloater* dependee = getDependee();
|
||||
if (dependee)
|
||||
dependee->removeDependentFloater(this);
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/**
|
||||
* @file llfloaterpostcard.h
|
||||
* @brief Postcard send floater, allows setting name, e-mail address, etc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERPOSTCARD_H
|
||||
#define LL_LLFLOATERPOSTCARD_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
|
||||
#include "llpointer.h"
|
||||
|
||||
class LLTextEditor;
|
||||
class LLLineEditor;
|
||||
class LLButton;
|
||||
class LLViewerTexture;
|
||||
class LLImageJPEG;
|
||||
|
||||
class LLFloaterPostcard
|
||||
: public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterPostcard(const LLSD& key);
|
||||
virtual ~LLFloaterPostcard();
|
||||
|
||||
virtual BOOL postBuild();
|
||||
virtual void draw();
|
||||
|
||||
static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global);
|
||||
|
||||
static void onClickCancel(void* data);
|
||||
static void onClickSend(void* data);
|
||||
|
||||
static void uploadCallback(const LLUUID& asset_id,
|
||||
void *user_data,
|
||||
S32 result, LLExtStat ext_status);
|
||||
|
||||
static void updateUserInfo(const std::string& email);
|
||||
|
||||
static void onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data);
|
||||
bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void sendPostcard();
|
||||
|
||||
private:
|
||||
|
||||
LLPointer<LLImageJPEG> mJPEGImage;
|
||||
LLPointer<LLViewerTexture> mViewerImage;
|
||||
LLTransactionID mTransactionID;
|
||||
LLAssetID mAssetID;
|
||||
LLVector2 mImageScale;
|
||||
LLVector3d mPosTakenGlobal;
|
||||
bool mHasFirstMsgFocus;
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_LLFLOATERPOSTCARD_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,11 +27,15 @@
|
|||
#ifndef LL_LLFLOATERSNAPSHOT_H
|
||||
#define LL_LLFLOATERSNAPSHOT_H
|
||||
|
||||
#include "llimage.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLSpinCtrl;
|
||||
|
||||
class LLFloaterSnapshot : public LLFloater
|
||||
{
|
||||
LOG_CLASS(LLFloaterSnapshot);
|
||||
|
||||
public:
|
||||
typedef enum e_snapshot_format
|
||||
{
|
||||
|
|
@ -47,20 +51,29 @@ public:
|
|||
/*virtual*/ void draw();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ void onClose(bool app_quitting);
|
||||
/*virtual*/ S32 notify(const LLSD& info);
|
||||
|
||||
static void update();
|
||||
|
||||
static S32 getUIWinHeightLong() {return sUIWinHeightLong ;}
|
||||
static S32 getUIWinHeightShort() {return sUIWinHeightShort ;}
|
||||
static S32 getUIWinWidth() {return sUIWinWidth ;}
|
||||
|
||||
// TODO: create a snapshot model instead
|
||||
static LLFloaterSnapshot* getInstance();
|
||||
static void saveTexture();
|
||||
static void saveLocal();
|
||||
static void preUpdate();
|
||||
static void postUpdate();
|
||||
static void postSave();
|
||||
static void postPanelSwitch();
|
||||
static LLPointer<LLImageFormatted> getImageData();
|
||||
static const LLVector3d& getPosTakenGlobal();
|
||||
static void setAgentEmail(const std::string& email);
|
||||
|
||||
static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
|
||||
|
||||
private:
|
||||
static LLUICtrl* sThumbnailPlaceholder;
|
||||
|
||||
class Impl;
|
||||
Impl& impl;
|
||||
|
||||
static S32 sUIWinHeightLong ;
|
||||
static S32 sUIWinHeightShort ;
|
||||
static S32 sUIWinWidth ;
|
||||
};
|
||||
|
||||
class LLSnapshotFloaterView : public LLFloaterView
|
||||
|
|
|
|||
|
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* @file llpanelsnapshot.cpp
|
||||
* @brief Snapshot panel base class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llpanelsnapshot.h"
|
||||
|
||||
// libs
|
||||
#include "llcombobox.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
// newview
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
#include "llviewercontrol.h" // gSavedSettings
|
||||
|
||||
// virtual
|
||||
BOOL LLPanelSnapshot::postBuild()
|
||||
{
|
||||
getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1));
|
||||
getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
|
||||
getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
|
||||
getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1));
|
||||
|
||||
updateControls(LLSD());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshot::onOpen(const LLSD& key)
|
||||
{
|
||||
S32 old_format = gSavedSettings.getS32("SnapshotFormat");
|
||||
S32 new_format = (S32) getImageFormat();
|
||||
|
||||
gSavedSettings.setS32("SnapshotFormat", new_format);
|
||||
setCtrlsEnabled(true);
|
||||
|
||||
// Switching panels will likely change image format.
|
||||
// Not updating preview right away may lead to errors,
|
||||
// e.g. attempt to send a large BMP image by email.
|
||||
if (old_format != new_format)
|
||||
{
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true));
|
||||
}
|
||||
|
||||
updateCustomResControls();
|
||||
}
|
||||
|
||||
LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
|
||||
{
|
||||
return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
|
||||
}
|
||||
|
||||
LLSpinCtrl* LLPanelSnapshot::getWidthSpinner()
|
||||
{
|
||||
return getChild<LLSpinCtrl>(getWidthSpinnerName());
|
||||
}
|
||||
|
||||
LLSpinCtrl* LLPanelSnapshot::getHeightSpinner()
|
||||
{
|
||||
return getChild<LLSpinCtrl>(getHeightSpinnerName());
|
||||
}
|
||||
|
||||
S32 LLPanelSnapshot::getTypedPreviewWidth() const
|
||||
{
|
||||
return getChild<LLUICtrl>(getWidthSpinnerName())->getValue().asInteger();
|
||||
}
|
||||
|
||||
S32 LLPanelSnapshot::getTypedPreviewHeight() const
|
||||
{
|
||||
return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger();
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::enableAspectRatioCheckbox(BOOL enable)
|
||||
{
|
||||
getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable);
|
||||
}
|
||||
|
||||
LLSideTrayPanelContainer* LLPanelSnapshot::getParentContainer()
|
||||
{
|
||||
LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
|
||||
if (!parent)
|
||||
{
|
||||
llwarns << "Cannot find panel container" << llendl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshot::updateCustomResControls()
|
||||
{
|
||||
LLComboBox* combo = getChild<LLComboBox>(getImageSizeComboName());
|
||||
S32 selected_idx = combo->getFirstSelectedIndex();
|
||||
const bool enable = selected_idx == (combo->getItemCount() - 1); // Current Window or Custom selected
|
||||
|
||||
getChild<LLUICtrl>(getWidthSpinnerName())->setEnabled(enable);
|
||||
getChild<LLSpinCtrl>(getWidthSpinnerName())->setAllowEdit(enable);
|
||||
getChild<LLUICtrl>(getHeightSpinnerName())->setEnabled(enable);
|
||||
getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(enable);
|
||||
enableAspectRatioCheckbox(enable);
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::updateImageQualityLevel()
|
||||
{
|
||||
LLSliderCtrl* quality_slider = getChild<LLSliderCtrl>("image_quality_slider");
|
||||
S32 quality_val = llfloor((F32) quality_slider->getValue().asReal());
|
||||
|
||||
std::string quality_lvl;
|
||||
|
||||
if (quality_val < 20)
|
||||
{
|
||||
quality_lvl = LLTrans::getString("snapshot_quality_very_low");
|
||||
}
|
||||
else if (quality_val < 40)
|
||||
{
|
||||
quality_lvl = LLTrans::getString("snapshot_quality_low");
|
||||
}
|
||||
else if (quality_val < 60)
|
||||
{
|
||||
quality_lvl = LLTrans::getString("snapshot_quality_medium");
|
||||
}
|
||||
else if (quality_val < 80)
|
||||
{
|
||||
quality_lvl = LLTrans::getString("snapshot_quality_high");
|
||||
}
|
||||
else
|
||||
{
|
||||
quality_lvl = LLTrans::getString("snapshot_quality_very_high");
|
||||
}
|
||||
|
||||
getChild<LLTextBox>("image_quality_level")->setTextArg("[QLVL]", quality_lvl);
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::goBack()
|
||||
{
|
||||
LLSideTrayPanelContainer* parent = getParentContainer();
|
||||
if (parent)
|
||||
{
|
||||
parent->openPreviousPanel();
|
||||
parent->getCurrentPanel()->onOpen(LLSD());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::cancel()
|
||||
{
|
||||
goBack();
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-ready", true));
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::onCustomResolutionCommit()
|
||||
{
|
||||
LLSD info;
|
||||
info["w"] = getChild<LLUICtrl>(getWidthSpinnerName())->getValue().asInteger();
|
||||
info["h"] = getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger();
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("custom-res-change", info));
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::onResolutionComboCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
updateCustomResControls();
|
||||
|
||||
LLSD info;
|
||||
info["combo-res-change"]["control-name"] = ctrl->getName();
|
||||
LLFloaterSnapshot::getInstance()->notify(info);
|
||||
}
|
||||
|
||||
void LLPanelSnapshot::onKeepAspectRatioCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean()));
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @file llpanelsnapshot.h
|
||||
* @brief Snapshot panel base class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELSNAPSHOT_H
|
||||
#define LL_LLPANELSNAPSHOT_H
|
||||
|
||||
#include "llfloatersnapshot.h"
|
||||
|
||||
class LLSideTrayPanelContainer;
|
||||
|
||||
/**
|
||||
* Snapshot panel base class.
|
||||
*/
|
||||
class LLPanelSnapshot: public LLPanel
|
||||
{
|
||||
public:
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
virtual std::string getWidthSpinnerName() const = 0;
|
||||
virtual std::string getHeightSpinnerName() const = 0;
|
||||
virtual std::string getAspectRatioCBName() const = 0;
|
||||
virtual std::string getImageSizeComboName() const = 0;
|
||||
|
||||
virtual S32 getTypedPreviewWidth() const;
|
||||
virtual S32 getTypedPreviewHeight() const;
|
||||
virtual LLSpinCtrl* getWidthSpinner();
|
||||
virtual LLSpinCtrl* getHeightSpinner();
|
||||
virtual void enableAspectRatioCheckbox(BOOL enable);
|
||||
virtual LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
|
||||
virtual void updateControls(const LLSD& info) = 0; ///< Update controls from saved settings
|
||||
|
||||
protected:
|
||||
LLSideTrayPanelContainer* getParentContainer();
|
||||
virtual void updateCustomResControls();
|
||||
void updateImageQualityLevel();
|
||||
void goBack(); ///< Switch to the default (Snapshot Options) panel
|
||||
void cancel();
|
||||
|
||||
// common UI callbacks
|
||||
void onCustomResolutionCommit();
|
||||
void onResolutionComboCommit(LLUICtrl* ctrl);
|
||||
void onKeepAspectRatioCommit(LLUICtrl* ctrl);
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELSNAPSHOT_H
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* @file llpanelsnapshotinventory.cpp
|
||||
* @brief The panel provides UI for saving snapshot as an inventory texture.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llcombobox.h"
|
||||
#include "lleconomy.h"
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
#include "llspinctrl.h"
|
||||
|
||||
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
|
||||
#include "llpanelsnapshot.h"
|
||||
#include "llviewercontrol.h" // gSavedSettings
|
||||
|
||||
/**
|
||||
* The panel provides UI for saving snapshot as an inventory texture.
|
||||
*/
|
||||
class LLPanelSnapshotInventory
|
||||
: public LLPanelSnapshot
|
||||
{
|
||||
LOG_CLASS(LLPanelSnapshotInventory);
|
||||
|
||||
public:
|
||||
LLPanelSnapshotInventory();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
private:
|
||||
/*virtual*/ void updateCustomResControls(); ///< Show/hide custom resolution controls (spinners and checkbox)
|
||||
/*virtual*/ std::string getWidthSpinnerName() const { return "inventory_snapshot_width"; }
|
||||
/*virtual*/ std::string getHeightSpinnerName() const { return "inventory_snapshot_height"; }
|
||||
/*virtual*/ std::string getAspectRatioCBName() const { return "inventory_keep_aspect_check"; }
|
||||
/*virtual*/ std::string getImageSizeComboName() const { return "texture_size_combo"; }
|
||||
/*virtual*/ void updateControls(const LLSD& info);
|
||||
|
||||
void onSend();
|
||||
};
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelSnapshotInventory> panel_class("llpanelsnapshotinventory");
|
||||
|
||||
LLPanelSnapshotInventory::LLPanelSnapshotInventory()
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Inventory.Save", boost::bind(&LLPanelSnapshotInventory::onSend, this));
|
||||
mCommitCallbackRegistrar.add("Inventory.Cancel", boost::bind(&LLPanelSnapshotInventory::cancel, this));
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLPanelSnapshotInventory::postBuild()
|
||||
{
|
||||
return LLPanelSnapshot::postBuild();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotInventory::onOpen(const LLSD& key)
|
||||
{
|
||||
getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()));
|
||||
LLPanelSnapshot::onOpen(key);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotInventory::updateCustomResControls()
|
||||
{
|
||||
LLComboBox* combo = getChild<LLComboBox>(getImageSizeComboName());
|
||||
S32 selected_idx = combo->getFirstSelectedIndex();
|
||||
const bool show = selected_idx == (combo->getItemCount() - 1); // Custom selected
|
||||
|
||||
getChild<LLUICtrl>(getWidthSpinnerName())->setVisible(show);
|
||||
getChild<LLUICtrl>(getHeightSpinnerName())->setVisible(show);
|
||||
getChild<LLUICtrl>(getAspectRatioCBName())->setVisible(show);
|
||||
|
||||
// enable controls if possible
|
||||
LLPanelSnapshot::updateCustomResControls();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotInventory::updateControls(const LLSD& info)
|
||||
{
|
||||
const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;
|
||||
getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);
|
||||
}
|
||||
|
||||
void LLPanelSnapshotInventory::onSend()
|
||||
{
|
||||
LLFloaterSnapshot::saveTexture();
|
||||
LLFloaterSnapshot::postSave();
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* @file llpanelsnapshotlocal.cpp
|
||||
* @brief The panel provides UI for saving snapshot to a local folder.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llcombobox.h"
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "llspinctrl.h"
|
||||
|
||||
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
|
||||
#include "llpanelsnapshot.h"
|
||||
#include "llviewercontrol.h" // gSavedSettings
|
||||
|
||||
/**
|
||||
* The panel provides UI for saving snapshot to a local folder.
|
||||
*/
|
||||
class LLPanelSnapshotLocal
|
||||
: public LLPanelSnapshot
|
||||
{
|
||||
LOG_CLASS(LLPanelSnapshotLocal);
|
||||
|
||||
public:
|
||||
LLPanelSnapshotLocal();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
private:
|
||||
/*virtual*/ std::string getWidthSpinnerName() const { return "local_snapshot_width"; }
|
||||
/*virtual*/ std::string getHeightSpinnerName() const { return "local_snapshot_height"; }
|
||||
/*virtual*/ std::string getAspectRatioCBName() const { return "local_keep_aspect_check"; }
|
||||
/*virtual*/ std::string getImageSizeComboName() const { return "local_size_combo"; }
|
||||
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
|
||||
/*virtual*/ void updateControls(const LLSD& info);
|
||||
|
||||
void onFormatComboCommit(LLUICtrl* ctrl);
|
||||
void onQualitySliderCommit(LLUICtrl* ctrl);
|
||||
void onSend();
|
||||
};
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal");
|
||||
|
||||
LLPanelSnapshotLocal::LLPanelSnapshotLocal()
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Local.Save", boost::bind(&LLPanelSnapshotLocal::onSend, this));
|
||||
mCommitCallbackRegistrar.add("Local.Cancel", boost::bind(&LLPanelSnapshotLocal::cancel, this));
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLPanelSnapshotLocal::postBuild()
|
||||
{
|
||||
getChild<LLUICtrl>("image_quality_slider")->setCommitCallback(boost::bind(&LLPanelSnapshotLocal::onQualitySliderCommit, this, _1));
|
||||
getChild<LLUICtrl>("local_format_combo")->setCommitCallback(boost::bind(&LLPanelSnapshotLocal::onFormatComboCommit, this, _1));
|
||||
|
||||
return LLPanelSnapshot::postBuild();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotLocal::onOpen(const LLSD& key)
|
||||
{
|
||||
LLPanelSnapshot::onOpen(key);
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
|
||||
{
|
||||
LLFloaterSnapshot::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
|
||||
|
||||
LLComboBox* local_format_combo = getChild<LLComboBox>("local_format_combo");
|
||||
const std::string id = local_format_combo->getValue().asString();
|
||||
if (id == "PNG")
|
||||
{
|
||||
fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
|
||||
}
|
||||
else if (id == "JPEG")
|
||||
{
|
||||
fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
|
||||
}
|
||||
else if (id == "BMP")
|
||||
{
|
||||
fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP;
|
||||
}
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotLocal::updateControls(const LLSD& info)
|
||||
{
|
||||
LLFloaterSnapshot::ESnapshotFormat fmt =
|
||||
(LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
|
||||
getChild<LLComboBox>("local_format_combo")->selectNthItem((S32) fmt);
|
||||
|
||||
const bool show_quality_ctrls = (fmt == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
|
||||
getChild<LLUICtrl>("image_quality_slider")->setVisible(show_quality_ctrls);
|
||||
getChild<LLUICtrl>("image_quality_level")->setVisible(show_quality_ctrls);
|
||||
|
||||
getChild<LLUICtrl>("image_quality_slider")->setValue(gSavedSettings.getS32("SnapshotQuality"));
|
||||
updateImageQualityLevel();
|
||||
|
||||
const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;
|
||||
getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);
|
||||
}
|
||||
|
||||
void LLPanelSnapshotLocal::onFormatComboCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
// will call updateControls()
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true));
|
||||
}
|
||||
|
||||
void LLPanelSnapshotLocal::onQualitySliderCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
updateImageQualityLevel();
|
||||
|
||||
LLSliderCtrl* slider = (LLSliderCtrl*)ctrl;
|
||||
S32 quality_val = llfloor((F32)slider->getValue().asReal());
|
||||
LLSD info;
|
||||
info["image-quality-change"] = quality_val;
|
||||
LLFloaterSnapshot::getInstance()->notify(info);
|
||||
}
|
||||
|
||||
void LLPanelSnapshotLocal::onSend()
|
||||
{
|
||||
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
|
||||
|
||||
floater->notify(LLSD().with("set-working", true));
|
||||
LLFloaterSnapshot::saveLocal();
|
||||
LLFloaterSnapshot::postSave();
|
||||
goBack();
|
||||
floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
* @file llpanelsnapshotoptions.cpp
|
||||
* @brief Snapshot posting options panel.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lleconomy.h"
|
||||
#include "llpanel.h"
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
|
||||
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
|
||||
|
||||
/**
|
||||
* Provides several ways to save a snapshot.
|
||||
*/
|
||||
class LLPanelSnapshotOptions
|
||||
: public LLPanel
|
||||
{
|
||||
LOG_CLASS(LLPanelSnapshotOptions);
|
||||
|
||||
public:
|
||||
LLPanelSnapshotOptions();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
private:
|
||||
void openPanel(const std::string& panel_name);
|
||||
void onSaveToProfile();
|
||||
void onSaveToEmail();
|
||||
void onSaveToInventory();
|
||||
void onSaveToComputer();
|
||||
};
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelSnapshotOptions> panel_class("llpanelsnapshotoptions");
|
||||
|
||||
LLPanelSnapshotOptions::LLPanelSnapshotOptions()
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Snapshot.SaveToProfile", boost::bind(&LLPanelSnapshotOptions::onSaveToProfile, this));
|
||||
mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this));
|
||||
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
|
||||
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotOptions::onOpen(const LLSD& key)
|
||||
{
|
||||
S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
|
||||
getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost));
|
||||
}
|
||||
|
||||
void LLPanelSnapshotOptions::openPanel(const std::string& panel_name)
|
||||
{
|
||||
LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
|
||||
if (!parent)
|
||||
{
|
||||
llwarns << "Cannot find panel container" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
parent->openPanel(panel_name);
|
||||
parent->getCurrentPanel()->onOpen(LLSD());
|
||||
LLFloaterSnapshot::postPanelSwitch();
|
||||
}
|
||||
|
||||
void LLPanelSnapshotOptions::onSaveToProfile()
|
||||
{
|
||||
openPanel("panel_snapshot_profile");
|
||||
}
|
||||
|
||||
void LLPanelSnapshotOptions::onSaveToEmail()
|
||||
{
|
||||
openPanel("panel_snapshot_postcard");
|
||||
}
|
||||
|
||||
void LLPanelSnapshotOptions::onSaveToInventory()
|
||||
{
|
||||
openPanel("panel_snapshot_inventory");
|
||||
}
|
||||
|
||||
void LLPanelSnapshotOptions::onSaveToComputer()
|
||||
{
|
||||
openPanel("panel_snapshot_local");
|
||||
}
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
/**
|
||||
* @file llpanelsnapshotpostcard.cpp
|
||||
* @brief Postcard sending panel.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llcombobox.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "lltexteditor.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentui.h"
|
||||
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
|
||||
#include "llpanelsnapshot.h"
|
||||
#include "llpostcard.h"
|
||||
#include "llviewercontrol.h" // gSavedSettings
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
/**
|
||||
* Sends postcard via email.
|
||||
*/
|
||||
class LLPanelSnapshotPostcard
|
||||
: public LLPanelSnapshot
|
||||
{
|
||||
LOG_CLASS(LLPanelSnapshotPostcard);
|
||||
|
||||
public:
|
||||
LLPanelSnapshotPostcard();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ S32 notify(const LLSD& info);
|
||||
|
||||
private:
|
||||
/*virtual*/ std::string getWidthSpinnerName() const { return "postcard_snapshot_width"; }
|
||||
/*virtual*/ std::string getHeightSpinnerName() const { return "postcard_snapshot_height"; }
|
||||
/*virtual*/ std::string getAspectRatioCBName() const { return "postcard_keep_aspect_check"; }
|
||||
/*virtual*/ std::string getImageSizeComboName() const { return "postcard_size_combo"; }
|
||||
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; }
|
||||
/*virtual*/ void updateControls(const LLSD& info);
|
||||
|
||||
bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
void sendPostcard();
|
||||
|
||||
void onMsgFormFocusRecieved();
|
||||
void onFormatComboCommit(LLUICtrl* ctrl);
|
||||
void onQualitySliderCommit(LLUICtrl* ctrl);
|
||||
void onTabButtonPress(S32 btn_idx);
|
||||
void onSend();
|
||||
|
||||
bool mHasFirstMsgFocus;
|
||||
std::string mAgentEmail;
|
||||
};
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelSnapshotPostcard> panel_class("llpanelsnapshotpostcard");
|
||||
|
||||
LLPanelSnapshotPostcard::LLPanelSnapshotPostcard()
|
||||
: mHasFirstMsgFocus(false)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Postcard.Send", boost::bind(&LLPanelSnapshotPostcard::onSend, this));
|
||||
mCommitCallbackRegistrar.add("Postcard.Cancel", boost::bind(&LLPanelSnapshotPostcard::cancel, this));
|
||||
mCommitCallbackRegistrar.add("Postcard.Message", boost::bind(&LLPanelSnapshotPostcard::onTabButtonPress, this, 0));
|
||||
mCommitCallbackRegistrar.add("Postcard.Settings", boost::bind(&LLPanelSnapshotPostcard::onTabButtonPress, this, 1));
|
||||
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLPanelSnapshotPostcard::postBuild()
|
||||
{
|
||||
// pick up the user's up-to-date email address
|
||||
gAgent.sendAgentUserInfoRequest();
|
||||
|
||||
std::string name_string;
|
||||
LLAgentUI::buildFullname(name_string);
|
||||
getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
|
||||
|
||||
// For the first time a user focuses to .the msg box, all text will be selected.
|
||||
getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(&LLPanelSnapshotPostcard::onMsgFormFocusRecieved, this));
|
||||
|
||||
getChild<LLUICtrl>("to_form")->setFocus(TRUE);
|
||||
|
||||
getChild<LLUICtrl>("image_quality_slider")->setCommitCallback(boost::bind(&LLPanelSnapshotPostcard::onQualitySliderCommit, this, _1));
|
||||
|
||||
getChild<LLButton>("message_btn")->setToggleState(TRUE);
|
||||
|
||||
return LLPanelSnapshot::postBuild();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotPostcard::onOpen(const LLSD& key)
|
||||
{
|
||||
LLPanelSnapshot::onOpen(key);
|
||||
}
|
||||
|
||||
// virtual
|
||||
S32 LLPanelSnapshotPostcard::notify(const LLSD& info)
|
||||
{
|
||||
if (!info.has("agent-email"))
|
||||
{
|
||||
llassert(info.has("agent-email"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mAgentEmail.empty())
|
||||
{
|
||||
mAgentEmail = info["agent-email"].asString();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotPostcard::updateControls(const LLSD& info)
|
||||
{
|
||||
getChild<LLUICtrl>("image_quality_slider")->setValue(gSavedSettings.getS32("SnapshotQuality"));
|
||||
updateImageQualityLevel();
|
||||
|
||||
const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;
|
||||
getChild<LLUICtrl>("send_btn")->setEnabled(have_snapshot);
|
||||
}
|
||||
|
||||
bool LLPanelSnapshotPostcard::missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if(0 == option)
|
||||
{
|
||||
// User clicked OK
|
||||
if((getChild<LLUICtrl>("subject_form")->getValue().asString()).empty())
|
||||
{
|
||||
// Stuff the subject back into the form.
|
||||
getChild<LLUICtrl>("subject_form")->setValue(getString("default_subject"));
|
||||
}
|
||||
|
||||
if (!mHasFirstMsgFocus)
|
||||
{
|
||||
// The user never switched focus to the message window.
|
||||
// Using the default string.
|
||||
getChild<LLUICtrl>("msg_form")->setValue(getString("default_message"));
|
||||
}
|
||||
|
||||
sendPostcard();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LLPanelSnapshotPostcard::sendPostcard()
|
||||
{
|
||||
std::string to(getChild<LLUICtrl>("to_form")->getValue().asString());
|
||||
std::string subject(getChild<LLUICtrl>("subject_form")->getValue().asString());
|
||||
|
||||
LLSD postcard = LLSD::emptyMap();
|
||||
postcard["pos-global"] = LLFloaterSnapshot::getPosTakenGlobal().getValue();
|
||||
postcard["to"] = to;
|
||||
postcard["from"] = mAgentEmail;
|
||||
postcard["name"] = getChild<LLUICtrl>("name_form")->getValue().asString();
|
||||
postcard["subject"] = subject;
|
||||
postcard["msg"] = getChild<LLUICtrl>("msg_form")->getValue().asString();
|
||||
LLPostCard::send(LLFloaterSnapshot::getImageData(), postcard);
|
||||
|
||||
// Give user feedback of the event.
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
|
||||
LLFloaterSnapshot::postSave();
|
||||
}
|
||||
|
||||
void LLPanelSnapshotPostcard::onMsgFormFocusRecieved()
|
||||
{
|
||||
LLTextEditor* msg_form = getChild<LLTextEditor>("msg_form");
|
||||
if (msg_form->hasFocus() && !mHasFirstMsgFocus)
|
||||
{
|
||||
mHasFirstMsgFocus = true;
|
||||
msg_form->setText(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelSnapshotPostcard::onFormatComboCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
// will call updateControls()
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true));
|
||||
}
|
||||
|
||||
void LLPanelSnapshotPostcard::onQualitySliderCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
updateImageQualityLevel();
|
||||
|
||||
LLSliderCtrl* slider = (LLSliderCtrl*)ctrl;
|
||||
S32 quality_val = llfloor((F32)slider->getValue().asReal());
|
||||
LLSD info;
|
||||
info["image-quality-change"] = quality_val;
|
||||
LLFloaterSnapshot::getInstance()->notify(info); // updates the "SnapshotQuality" setting
|
||||
}
|
||||
|
||||
void LLPanelSnapshotPostcard::onTabButtonPress(S32 btn_idx)
|
||||
{
|
||||
LLButton* buttons[2] = {
|
||||
getChild<LLButton>("message_btn"),
|
||||
getChild<LLButton>("settings_btn"),
|
||||
};
|
||||
|
||||
// Switch between Message and Settings tabs.
|
||||
LLButton* clicked_btn = buttons[btn_idx];
|
||||
LLButton* other_btn = buttons[!btn_idx];
|
||||
LLSideTrayPanelContainer* container =
|
||||
getChild<LLSideTrayPanelContainer>("postcard_panel_container");
|
||||
|
||||
container->selectTab(clicked_btn->getToggleState() ? btn_idx : !btn_idx);
|
||||
//clicked_btn->setEnabled(FALSE);
|
||||
other_btn->toggleState();
|
||||
//other_btn->setEnabled(TRUE);
|
||||
|
||||
lldebugs << "Button #" << btn_idx << " (" << clicked_btn->getName() << ") clicked" << llendl;
|
||||
}
|
||||
|
||||
void LLPanelSnapshotPostcard::onSend()
|
||||
{
|
||||
// Validate input.
|
||||
std::string to(getChild<LLUICtrl>("to_form")->getValue().asString());
|
||||
|
||||
boost::regex email_format("[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}(,[ \t]*[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})*");
|
||||
|
||||
if (to.empty() || !boost::regex_match(to, email_format))
|
||||
{
|
||||
LLNotificationsUtil::add("PromptRecipientEmail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAgentEmail.empty() || !boost::regex_match(mAgentEmail, email_format))
|
||||
{
|
||||
LLNotificationsUtil::add("PromptSelfEmail");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string subject(getChild<LLUICtrl>("subject_form")->getValue().asString());
|
||||
if(subject.empty() || !mHasFirstMsgFocus)
|
||||
{
|
||||
LLNotificationsUtil::add("PromptMissingSubjMsg", LLSD(), LLSD(), boost::bind(&LLPanelSnapshotPostcard::missingSubjMsgAlertCallback, this, _1, _2));
|
||||
return;
|
||||
}
|
||||
|
||||
// Send postcard.
|
||||
sendPostcard();
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file llpanelsnapshotprofile.cpp
|
||||
* @brief Posts a snapshot to My Profile feed.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
// libs
|
||||
#include "llcombobox.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llpanel.h"
|
||||
#include "llspinctrl.h"
|
||||
|
||||
// newview
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llpanelsnapshot.h"
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
#include "llwebprofile.h"
|
||||
|
||||
/**
|
||||
* Posts a snapshot to My Profile feed.
|
||||
*/
|
||||
class LLPanelSnapshotProfile
|
||||
: public LLPanelSnapshot
|
||||
{
|
||||
LOG_CLASS(LLPanelSnapshotProfile);
|
||||
|
||||
public:
|
||||
LLPanelSnapshotProfile();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
private:
|
||||
/*virtual*/ std::string getWidthSpinnerName() const { return "profile_snapshot_width"; }
|
||||
/*virtual*/ std::string getHeightSpinnerName() const { return "profile_snapshot_height"; }
|
||||
/*virtual*/ std::string getAspectRatioCBName() const { return "profile_keep_aspect_check"; }
|
||||
/*virtual*/ std::string getImageSizeComboName() const { return "profile_size_combo"; }
|
||||
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; }
|
||||
/*virtual*/ void updateControls(const LLSD& info);
|
||||
|
||||
void onSend();
|
||||
};
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelSnapshotProfile> panel_class("llpanelsnapshotprofile");
|
||||
|
||||
LLPanelSnapshotProfile::LLPanelSnapshotProfile()
|
||||
{
|
||||
mCommitCallbackRegistrar.add("PostToProfile.Send", boost::bind(&LLPanelSnapshotProfile::onSend, this));
|
||||
mCommitCallbackRegistrar.add("PostToProfile.Cancel", boost::bind(&LLPanelSnapshotProfile::cancel, this));
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLPanelSnapshotProfile::postBuild()
|
||||
{
|
||||
return LLPanelSnapshot::postBuild();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotProfile::onOpen(const LLSD& key)
|
||||
{
|
||||
LLPanelSnapshot::onOpen(key);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelSnapshotProfile::updateControls(const LLSD& info)
|
||||
{
|
||||
const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;
|
||||
getChild<LLUICtrl>("post_btn")->setEnabled(have_snapshot);
|
||||
}
|
||||
|
||||
void LLPanelSnapshotProfile::onSend()
|
||||
{
|
||||
std::string caption = getChild<LLUICtrl>("caption")->getValue().asString();
|
||||
bool add_location = getChild<LLUICtrl>("add_location_cb")->getValue().asBoolean();
|
||||
|
||||
LLWebProfile::uploadImage(LLFloaterSnapshot::getImageData(), caption, add_location);
|
||||
LLFloaterSnapshot::postSave();
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* @file llpostcard.cpp
|
||||
* @brief Sending postcards.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpostcard.h"
|
||||
|
||||
#include "llvfile.h"
|
||||
#include "llvfs.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
#include "message.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llassetuploadresponders.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// misc
|
||||
|
||||
static void postcard_upload_callback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status)
|
||||
{
|
||||
LLSD* postcard_data = (LLSD*)user_data;
|
||||
|
||||
if (result)
|
||||
{
|
||||
// TODO: display the error messages in UI
|
||||
llwarns << "Failed to send postcard: " << LLAssetStorage::getErrorString(result) << llendl;
|
||||
LLPostCard::reportPostResult(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only create the postcard once the upload succeeds
|
||||
|
||||
// request the postcard
|
||||
const LLSD& data = *postcard_data;
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage("SendPostcard");
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->addUUID("AssetID", data["asset-id"].asUUID());
|
||||
msg->addVector3d("PosGlobal", LLVector3d(data["pos-global"]));
|
||||
msg->addString("To", data["to"]);
|
||||
msg->addString("From", data["from"]);
|
||||
msg->addString("Name", data["name"]);
|
||||
msg->addString("Subject", data["subject"]);
|
||||
msg->addString("Msg", data["msg"]);
|
||||
msg->addBOOL("AllowPublish", FALSE);
|
||||
msg->addBOOL("MaturePublish", FALSE);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
LLPostCard::reportPostResult(true);
|
||||
}
|
||||
|
||||
delete postcard_data;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLPostcardSendResponder
|
||||
|
||||
class LLPostcardSendResponder : public LLAssetUploadResponder
|
||||
{
|
||||
LOG_CLASS(LLPostcardSendResponder);
|
||||
|
||||
public:
|
||||
LLPostcardSendResponder(const LLSD &post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type):
|
||||
LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ void uploadComplete(const LLSD& content)
|
||||
{
|
||||
llinfos << "Postcard sent" << llendl;
|
||||
LL_DEBUGS("Snapshots") << "content: " << content << llendl;
|
||||
LLPostCard::reportPostResult(true);
|
||||
}
|
||||
|
||||
/*virtual*/ void uploadFailure(const LLSD& content)
|
||||
{
|
||||
llwarns << "Sending postcard failed: " << content << llendl;
|
||||
LLPostCard::reportPostResult(false);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLPostCard
|
||||
|
||||
LLPostCard::result_callback_t LLPostCard::mResultCallback;
|
||||
|
||||
// static
|
||||
void LLPostCard::send(LLPointer<LLImageFormatted> image, const LLSD& postcard_data)
|
||||
{
|
||||
LLTransactionID transaction_id;
|
||||
LLAssetID asset_id;
|
||||
|
||||
transaction_id.generate();
|
||||
asset_id = transaction_id.makeAssetID(gAgent.getSecureSessionID());
|
||||
LLVFile::writeFile(image->getData(), image->getDataSize(), gVFS, asset_id, LLAssetType::AT_IMAGE_JPEG);
|
||||
|
||||
// upload the image
|
||||
std::string url = gAgent.getRegion()->getCapability("SendPostcard");
|
||||
if (!url.empty())
|
||||
{
|
||||
llinfos << "Sending postcard via capability" << llendl;
|
||||
// the capability already encodes: agent ID, region ID
|
||||
LL_DEBUGS("Snapshots") << "url: " << url << llendl;
|
||||
LL_DEBUGS("Snapshots") << "body: " << postcard_data << llendl;
|
||||
LL_DEBUGS("Snapshots") << "data size: " << image->getDataSize() << llendl;
|
||||
LLHTTPClient::post(url, postcard_data,
|
||||
new LLPostcardSendResponder(postcard_data, asset_id, LLAssetType::AT_IMAGE_JPEG));
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Sending postcard" << llendl;
|
||||
LLSD* data = new LLSD(postcard_data);
|
||||
(*data)["asset-id"] = asset_id;
|
||||
gAssetStorage->storeAssetData(transaction_id, LLAssetType::AT_IMAGE_JPEG,
|
||||
&postcard_upload_callback, (void *)data, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPostCard::reportPostResult(bool ok)
|
||||
{
|
||||
if (mResultCallback)
|
||||
{
|
||||
mResultCallback(ok);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @file llpostcard.h
|
||||
* @brief Sending postcards.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPOSTCARD_H
|
||||
#define LL_LLPOSTCARD_H
|
||||
|
||||
#include "llimage.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
class LLPostCard
|
||||
{
|
||||
LOG_CLASS(LLPostCard);
|
||||
|
||||
public:
|
||||
typedef boost::function<void(bool ok)> result_callback_t;
|
||||
|
||||
static void send(LLPointer<LLImageFormatted> image, const LLSD& postcard_data);
|
||||
static void setPostResultCallback(result_callback_t cb) { mResultCallback = cb; }
|
||||
static void reportPostResult(bool ok);
|
||||
|
||||
private:
|
||||
static result_callback_t mResultCallback;
|
||||
};
|
||||
|
||||
#endif // LL_LLPOSTCARD_H
|
||||
|
|
@ -62,6 +62,13 @@ void LLSideTrayPanelContainer::onOpen(const LLSD& key)
|
|||
getCurrentPanel()->onOpen(key);
|
||||
}
|
||||
|
||||
void LLSideTrayPanelContainer::openPanel(const std::string& panel_name, const LLSD& key)
|
||||
{
|
||||
LLSD combined_key = key;
|
||||
combined_key[PARAM_SUB_PANEL_NAME] = panel_name;
|
||||
onOpen(combined_key);
|
||||
}
|
||||
|
||||
void LLSideTrayPanelContainer::openPreviousPanel()
|
||||
{
|
||||
if(!mDefaultPanelName.empty())
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ public:
|
|||
*/
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
/**
|
||||
* Opens given subpanel.
|
||||
*/
|
||||
void openPanel(const std::string& panel_name, const LLSD& key = LLSD::emptyMap());
|
||||
|
||||
/**
|
||||
* Opens previous panel from panel navigation history.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@
|
|||
#include "llfloateropenobject.h"
|
||||
#include "llfloaterpay.h"
|
||||
#include "llfloaterperms.h"
|
||||
#include "llfloaterpostcard.h"
|
||||
#include "llfloaterpostprocess.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterproperties.h"
|
||||
|
|
@ -245,7 +244,6 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
|
||||
LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("postcard", "floater_postcard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostcard>);
|
||||
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
|
||||
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
|
||||
LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "llvoavatar.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llwebprofile.h"
|
||||
#include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
|
||||
#include "llfilepicker.h"
|
||||
#include "llnotifications.h"
|
||||
|
|
@ -319,6 +320,10 @@ public:
|
|||
std::string cookie = content["set-cookie"].asString();
|
||||
|
||||
LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
|
||||
|
||||
// Set cookie for snapshot publishing.
|
||||
std::string auth_cookie = cookie.substr(0, cookie.find(";")); // strip path
|
||||
LLWebProfile::setAuthCookie(auth_cookie);
|
||||
}
|
||||
|
||||
void completedRaw(
|
||||
|
|
@ -1484,6 +1489,8 @@ void LLViewerMedia::setOpenIDCookie()
|
|||
std::string profile_url = getProfileURL("");
|
||||
LLURL raw_profile_url( profile_url.c_str() );
|
||||
|
||||
LL_DEBUGS("MediaAuth") << "Requesting " << profile_url << llendl;
|
||||
LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << llendl;
|
||||
LLHTTPClient::get(profile_url,
|
||||
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
|
||||
headers);
|
||||
|
|
|
|||
|
|
@ -528,23 +528,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
|
|||
{
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
|
||||
LLPointer<LLImageFormatted> formatted;
|
||||
switch(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat")))
|
||||
{
|
||||
case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
|
||||
formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
|
||||
break;
|
||||
case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
|
||||
formatted = new LLImagePNG;
|
||||
break;
|
||||
case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
|
||||
formatted = new LLImageBMP;
|
||||
break;
|
||||
default:
|
||||
llwarns << "Unknown Local Snapshot format" << llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
LLPointer<LLImageFormatted> formatted = new LLImagePNG;
|
||||
formatted->enableOverSize() ;
|
||||
formatted->encode(raw, 0);
|
||||
formatted->disableOverSize() ;
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@
|
|||
#include "llfloaterland.h"
|
||||
#include "llfloaterregioninfo.h"
|
||||
#include "llfloaterlandholdings.h"
|
||||
#include "llfloaterpostcard.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llhudeffecttrail.h"
|
||||
#include "llhudmanager.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
|
|
@ -6470,7 +6470,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**)
|
|||
msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
|
||||
|
||||
LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
|
||||
LLFloaterPostcard::updateUserInfo(email);
|
||||
LLFloaterSnapshot::setAgentEmail(email);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4020,10 +4020,11 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
|
|||
}
|
||||
|
||||
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
|
||||
BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
|
||||
BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker)
|
||||
{
|
||||
if (!image)
|
||||
{
|
||||
llwarns << "No image to save" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -4043,7 +4044,7 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
|
|||
pick_type = LLFilePicker::FFSAVE_ALL; // ???
|
||||
|
||||
// Get a base file location if needed.
|
||||
if ( ! isSnapshotLocSet())
|
||||
if (force_picker || !isSnapshotLocSet())
|
||||
{
|
||||
std::string proposed_name( sSnapshotBaseName );
|
||||
|
||||
|
|
@ -4083,6 +4084,7 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
|
|||
}
|
||||
while( -1 != err ); // search until the file is not found (i.e., stat() gives an error).
|
||||
|
||||
llinfos << "Saving snapshot to " << filepath << llendl;
|
||||
return image->save(filepath);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ public:
|
|||
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
|
||||
BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
|
||||
void resetSnapshotLoc() const { sSnapshotDir.clear(); }
|
||||
BOOL saveImageNumbered(LLImageFormatted *image);
|
||||
BOOL saveImageNumbered(LLImageFormatted *image, bool force_picker = false);
|
||||
|
||||
// Reset the directory where snapshots are saved.
|
||||
// Client will open directory picker on next snapshot save.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,305 @@
|
|||
/**
|
||||
* @file llwebprofile.cpp
|
||||
* @brief Web profile access.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llwebprofile.h"
|
||||
|
||||
// libs
|
||||
#include "llbufferstream.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llimagepng.h"
|
||||
#include "llplugincookiestore.h"
|
||||
|
||||
// newview
|
||||
#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
|
||||
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
|
||||
|
||||
// third-party
|
||||
#include "reader.h" // JSON
|
||||
|
||||
/*
|
||||
* Workflow:
|
||||
* 1. LLViewerMedia::setOpenIDCookie()
|
||||
* -> GET https://my-demo.secondlife.com/ via LLViewerMediaWebProfileResponder
|
||||
* -> LLWebProfile::setAuthCookie()
|
||||
* 2. LLWebProfile::uploadImage()
|
||||
* -> GET "https://my-demo.secondlife.com/snapshots/s3_upload_config" via ConfigResponder
|
||||
* 3. LLWebProfile::post()
|
||||
* -> POST <config_url> via PostImageResponder
|
||||
* -> redirect
|
||||
* -> GET <redirect_url> via PostImageRedirectResponder
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLWebProfileResponders::ConfigResponder
|
||||
|
||||
class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(LLWebProfileResponders::ConfigResponder);
|
||||
|
||||
public:
|
||||
ConfigResponder(LLPointer<LLImageFormatted> imagep)
|
||||
: mImagep(imagep)
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ void completedRaw(
|
||||
U32 status,
|
||||
const std::string& reason,
|
||||
const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer)
|
||||
{
|
||||
LLBufferStream istr(channels, buffer.get());
|
||||
std::stringstream strstrm;
|
||||
strstrm << istr.rdbuf();
|
||||
const std::string body = strstrm.str();
|
||||
|
||||
if (status != 200)
|
||||
{
|
||||
llwarns << "Failed to get upload config (" << status << ")" << llendl;
|
||||
LLWebProfile::reportImageUploadStatus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
if (!reader.parse(body, root))
|
||||
{
|
||||
llwarns << "Failed to parse upload config: " << reader.getFormatedErrorMessages() << llendl;
|
||||
LLWebProfile::reportImageUploadStatus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// *TODO: 404 = not supported by the grid
|
||||
// *TODO: increase timeout or handle 499 Expired
|
||||
|
||||
// Convert config to LLSD.
|
||||
const Json::Value data = root["data"];
|
||||
const std::string upload_url = root["url"].asString();
|
||||
LLSD config;
|
||||
config["acl"] = data["acl"].asString();
|
||||
config["AWSAccessKeyId"] = data["AWSAccessKeyId"].asString();
|
||||
config["Content-Type"] = data["Content-Type"].asString();
|
||||
config["key"] = data["key"].asString();
|
||||
config["policy"] = data["policy"].asString();
|
||||
config["success_action_redirect"] = data["success_action_redirect"].asString();
|
||||
config["signature"] = data["signature"].asString();
|
||||
config["add_loc"] = data.get("add_loc", "0").asString();
|
||||
config["caption"] = data.get("caption", "").asString();
|
||||
|
||||
// Do the actual image upload using the configuration.
|
||||
LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << llendl;
|
||||
LLWebProfile::post(mImagep, config, upload_url);
|
||||
}
|
||||
|
||||
private:
|
||||
LLPointer<LLImageFormatted> mImagep;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLWebProfilePostImageRedirectResponder
|
||||
class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder);
|
||||
|
||||
public:
|
||||
/*virtual*/ void completedRaw(
|
||||
U32 status,
|
||||
const std::string& reason,
|
||||
const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer)
|
||||
{
|
||||
if (status != 200)
|
||||
{
|
||||
llwarns << "Failed to upload image: " << status << " " << reason << llendl;
|
||||
LLWebProfile::reportImageUploadStatus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
LLBufferStream istr(channels, buffer.get());
|
||||
std::stringstream strstrm;
|
||||
strstrm << istr.rdbuf();
|
||||
const std::string body = strstrm.str();
|
||||
llinfos << "Image uploaded." << llendl;
|
||||
LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << llendl;
|
||||
LLWebProfile::reportImageUploadStatus(true);
|
||||
}
|
||||
|
||||
private:
|
||||
LLPointer<LLImageFormatted> mImagep;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLWebProfileResponders::PostImageResponder
|
||||
class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(LLWebProfileResponders::PostImageResponder);
|
||||
|
||||
public:
|
||||
/*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
|
||||
{
|
||||
// Viewer seems to fail to follow a 303 redirect on POST request
|
||||
// (URLRequest Error: 65, Send failed since rewinding of the data stream failed).
|
||||
// Handle it manually.
|
||||
if (status == 303)
|
||||
{
|
||||
LLSD headers = LLViewerMedia::getHeaders();
|
||||
headers["Cookie"] = LLWebProfile::getAuthCookie();
|
||||
const std::string& redir_url = content["location"];
|
||||
LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl;
|
||||
LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Unexpected POST status: " << status << " " << reason << llendl;
|
||||
LL_DEBUGS("Snapshots") << "headers: [" << content << "]" << llendl;
|
||||
LLWebProfile::reportImageUploadStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Override just to suppress warnings.
|
||||
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
||||
const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLWebProfile
|
||||
|
||||
std::string LLWebProfile::sAuthCookie;
|
||||
LLWebProfile::status_callback_t LLWebProfile::mStatusCallback;
|
||||
|
||||
// static
|
||||
void LLWebProfile::uploadImage(LLPointer<LLImageFormatted> image, const std::string& caption, bool add_location)
|
||||
{
|
||||
// Get upload configuration data.
|
||||
std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config");
|
||||
config_url += "?caption=" + LLURI::escape(caption);
|
||||
config_url += "&add_loc=" + std::string(add_location ? "1" : "0");
|
||||
|
||||
LL_DEBUGS("Snapshots") << "Requesting " << config_url << llendl;
|
||||
LLSD headers = LLViewerMedia::getHeaders();
|
||||
headers["Cookie"] = getAuthCookie();
|
||||
LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLWebProfile::setAuthCookie(const std::string& cookie)
|
||||
{
|
||||
LL_DEBUGS("Snapshots") << "Setting auth cookie: " << cookie << llendl;
|
||||
sAuthCookie = cookie;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url)
|
||||
{
|
||||
if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
|
||||
{
|
||||
llwarns << "Image to upload is not a PNG" << llendl;
|
||||
llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string boundary = "----------------------------0123abcdefab";
|
||||
|
||||
LLSD headers = LLViewerMedia::getHeaders();
|
||||
headers["Cookie"] = getAuthCookie();
|
||||
headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
|
||||
|
||||
std::ostringstream body;
|
||||
|
||||
// *NOTE: The order seems to matter.
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
|
||||
<< config["key"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n"
|
||||
<< config["AWSAccessKeyId"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"acl\"\r\n\r\n"
|
||||
<< config["acl"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n"
|
||||
<< config["Content-Type"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"policy\"\r\n\r\n"
|
||||
<< config["policy"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"signature\"\r\n\r\n"
|
||||
<< config["signature"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n"
|
||||
<< config["success_action_redirect"].asString() << "\r\n";
|
||||
|
||||
body << "--" << boundary << "\r\n"
|
||||
<< "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n"
|
||||
<< "Content-Type: image/png\r\n\r\n";
|
||||
|
||||
// Insert the image data.
|
||||
// *FIX: Treating this as a string will probably screw it up ...
|
||||
U8* image_data = image->getData();
|
||||
for (S32 i = 0; i < image->getDataSize(); ++i)
|
||||
{
|
||||
body << image_data[i];
|
||||
}
|
||||
|
||||
body << "\r\n--" << boundary << "--\r\n";
|
||||
|
||||
// postRaw() takes ownership of the buffer and releases it later.
|
||||
size_t size = body.str().size();
|
||||
U8 *data = new U8[size];
|
||||
memcpy(data, body.str().data(), size);
|
||||
|
||||
// Send request, successful upload will trigger posting metadata.
|
||||
LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLWebProfile::reportImageUploadStatus(bool ok)
|
||||
{
|
||||
if (mStatusCallback)
|
||||
{
|
||||
mStatusCallback(ok);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLWebProfile::getAuthCookie()
|
||||
{
|
||||
// This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine).
|
||||
const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE");
|
||||
return debug_cookie ? debug_cookie : sAuthCookie;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @file llwebprofile.h
|
||||
* @brief Web profile access.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWEBPROFILE_H
|
||||
#define LL_LLWEBPROFILE_H
|
||||
|
||||
#include "llimage.h"
|
||||
|
||||
namespace LLWebProfileResponders
|
||||
{
|
||||
class ConfigResponder;
|
||||
class PostImageResponder;
|
||||
class PostImageRedirectResponder;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLWebProfile
|
||||
*
|
||||
* Manages interaction with, a web service allowing the upload of snapshot images
|
||||
* taken within the viewer.
|
||||
*/
|
||||
class LLWebProfile
|
||||
{
|
||||
LOG_CLASS(LLWebProfile);
|
||||
|
||||
public:
|
||||
typedef boost::function<void(bool ok)> status_callback_t;
|
||||
|
||||
static void uploadImage(LLPointer<LLImageFormatted> image, const std::string& caption, bool add_location);
|
||||
static void setAuthCookie(const std::string& cookie);
|
||||
static void setImageUploadResultCallback(status_callback_t cb) { mStatusCallback = cb; }
|
||||
|
||||
private:
|
||||
friend class LLWebProfileResponders::ConfigResponder;
|
||||
friend class LLWebProfileResponders::PostImageResponder;
|
||||
friend class LLWebProfileResponders::PostImageRedirectResponder;
|
||||
|
||||
static void post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url);
|
||||
static void reportImageUploadStatus(bool ok);
|
||||
static std::string getAuthCookie();
|
||||
|
||||
static std::string sAuthCookie;
|
||||
static status_callback_t mStatusCallback;
|
||||
};
|
||||
|
||||
#endif // LL_LLWEBPROFILE_H
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -547,6 +547,10 @@ with the same filename but different name
|
|||
<texture name="Unknown_Icon" file_name="icons/unknown_icon.png" preload="true" />
|
||||
|
||||
<texture name="Snapshot_Off" file_name="bottomtray/Snapshot_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
|
||||
<texture name="Snapshot_Download" file_name="snapshot_download.png" preload="false" />
|
||||
<texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" />
|
||||
<texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" />
|
||||
<texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" />
|
||||
|
||||
<texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" />
|
||||
|
||||
|
|
|
|||
|
|
@ -5,400 +5,308 @@
|
|||
can_minimize="true"
|
||||
can_close="true"
|
||||
follows="left|top"
|
||||
height="520"
|
||||
height="600"
|
||||
layout="topleft"
|
||||
name="Snapshot"
|
||||
help_topic="snapshot"
|
||||
save_rect="true"
|
||||
save_visibility="true"
|
||||
title="SNAPSHOT PREVIEW"
|
||||
width="245">
|
||||
width="470">
|
||||
<floater.string
|
||||
name="unknown">
|
||||
unknown
|
||||
</floater.string>
|
||||
<radio_group
|
||||
height="70"
|
||||
label="Snapshot type"
|
||||
<string
|
||||
name="postcard_progress_str">
|
||||
Sending Email
|
||||
</string>
|
||||
<string
|
||||
name="profile_progress_str">
|
||||
Posting
|
||||
</string>
|
||||
<string
|
||||
name="inventory_progress_str">
|
||||
Saving to Inventory
|
||||
</string>
|
||||
<string
|
||||
name="local_progress_str">
|
||||
Saving to Computer
|
||||
</string>
|
||||
<string
|
||||
name="profile_succeeded_str">
|
||||
Your Profile Feed has been updated!
|
||||
</string>
|
||||
<string
|
||||
name="postcard_succeeded_str">
|
||||
Email Sent!
|
||||
</string>
|
||||
<string
|
||||
name="inventory_succeeded_str">
|
||||
Saved to Inventory!
|
||||
</string>
|
||||
<string
|
||||
name="local_succeeded_str">
|
||||
Saved to Computer!
|
||||
</string>
|
||||
<string
|
||||
name="profile_failed_str">
|
||||
Failed to update your Profile Feed.
|
||||
</string>
|
||||
<string
|
||||
name="postcard_failed_str">
|
||||
Failed to send email.
|
||||
</string>
|
||||
<string
|
||||
name="inventory_failed_str">
|
||||
Failed to save to inventory.
|
||||
</string>
|
||||
<string
|
||||
name="local_failed_str">
|
||||
Failed to save to computer.
|
||||
</string>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top"
|
||||
height="21"
|
||||
left="10"
|
||||
layout="topleft"
|
||||
name="img_info_border"
|
||||
top="22"
|
||||
width="50"
|
||||
/>
|
||||
<icon
|
||||
follows="top|left"
|
||||
height="18"
|
||||
image_name="Snapshot_Off"
|
||||
layout="topleft"
|
||||
left_delta="-5"
|
||||
mouse_opaque="true"
|
||||
name="refresh_icon"
|
||||
top_delta="3"
|
||||
width="36" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="22"
|
||||
image_overlay="Refresh_Off"
|
||||
layout="topleft"
|
||||
left_delta="31"
|
||||
name="new_snapshot_btn"
|
||||
top_delta="-3"
|
||||
width="23" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
image_overlay="TabIcon_Close_Off"
|
||||
is_toggle="true"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="snapshot_type_radio"
|
||||
top="20"
|
||||
width="205">
|
||||
<!--
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Share to Web"
|
||||
layout="topleft"
|
||||
name="share_to_web"
|
||||
top_pad="0" />
|
||||
-->
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Email"
|
||||
layout="topleft"
|
||||
name="postcard"
|
||||
top_pad="2" />
|
||||
<radio_item
|
||||
height="16"
|
||||
label="My inventory (L$[AMOUNT])"
|
||||
layout="topleft"
|
||||
name="texture"
|
||||
top_pad="2" />
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Save to my computer"
|
||||
layout="topleft"
|
||||
name="local"
|
||||
top_pad="2" />
|
||||
</radio_group>
|
||||
left="240"
|
||||
name="advanced_options_btn"
|
||||
tool_tip="Advanced options"
|
||||
top_delta="0"
|
||||
width="23" />
|
||||
<ui_ctrl
|
||||
height="90"
|
||||
width="125"
|
||||
height="160"
|
||||
width="250"
|
||||
layout="topleft"
|
||||
name="thumbnail_placeholder"
|
||||
top_pad="6"
|
||||
top="50"
|
||||
follows="left|top"
|
||||
left="10"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
font="SansSerifSmall"
|
||||
length="1"
|
||||
left="10">
|
||||
<loading_indicator
|
||||
follows="left|top"
|
||||
height="48"
|
||||
layout="topleft"
|
||||
name="working_indicator"
|
||||
left="101"
|
||||
top="46"
|
||||
visible="false"
|
||||
width="48" />
|
||||
<text
|
||||
follows="left|top|right"
|
||||
font="SansSerifBold"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
length="1"
|
||||
halign="center"
|
||||
name="working_lbl"
|
||||
right="-5"
|
||||
top="98"
|
||||
translate="false"
|
||||
type="string"
|
||||
visible="false"
|
||||
width="130">
|
||||
Working
|
||||
</text>
|
||||
</ui_ctrl>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="21"
|
||||
width="250"
|
||||
layout="topleft"
|
||||
name="img_info_border"
|
||||
top_pad="3"
|
||||
follows="left|top"
|
||||
left_delta="0"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
font="SansSerifSmall"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left_delta="5"
|
||||
halign="left"
|
||||
name="image_res_text"
|
||||
top_delta="5"
|
||||
width="100">
|
||||
[WIDTH] x [HEIGHT] px
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="200"
|
||||
length="1"
|
||||
halign="right"
|
||||
name="file_size_label"
|
||||
top_delta="0"
|
||||
type="string"
|
||||
width="50">
|
||||
[SIZE] KB
|
||||
</text>
|
||||
<panel_container
|
||||
follows="left|top"
|
||||
height="14"
|
||||
height="360"
|
||||
layout="topleft"
|
||||
right="-5"
|
||||
left_delta="0"
|
||||
halign="right"
|
||||
name="file_size_label"
|
||||
top_pad="8"
|
||||
width="195">
|
||||
[SIZE] KB
|
||||
</text>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="22"
|
||||
image_overlay="Refresh_Off"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="new_snapshot_btn"
|
||||
width="23" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Send"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
right="-5"
|
||||
name="send_btn"
|
||||
width="100" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Save (L$[AMOUNT])"
|
||||
layout="topleft"
|
||||
right="-5"
|
||||
name="upload_btn"
|
||||
top_delta="0"
|
||||
width="110" />
|
||||
<flyout_button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Save"
|
||||
layout="topleft"
|
||||
right="-5"
|
||||
name="save_btn"
|
||||
tool_tip="Save image to a file"
|
||||
top_delta="0"
|
||||
width="100">
|
||||
<flyout_button.item
|
||||
label="Save"
|
||||
name="save_item"
|
||||
value="save" />
|
||||
<flyout_button.item
|
||||
label="Save As..."
|
||||
name="saveas_item"
|
||||
value="save as" />
|
||||
</flyout_button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="More"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="more_btn"
|
||||
tool_tip="Advanced options"
|
||||
width="80" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Less"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="less_btn"
|
||||
tool_tip="Advanced options"
|
||||
top_delta="0"
|
||||
width="80" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
right="-5"
|
||||
left_pad="5"
|
||||
name="discard_btn"
|
||||
width="110" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="type_label2"
|
||||
top_pad="5"
|
||||
width="127">
|
||||
Size
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
name="format_label"
|
||||
top_delta="0"
|
||||
width="70">
|
||||
Format
|
||||
</text>
|
||||
<combo_box
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="postcard_size_combo"
|
||||
width="120">
|
||||
<combo_box.item
|
||||
label="Current Window"
|
||||
name="CurrentWindow"
|
||||
value="[i0,i0]" />
|
||||
<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="Custom"
|
||||
name="Custom"
|
||||
value="[i-1,i-1]" />
|
||||
</combo_box>
|
||||
<combo_box
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="texture_size_combo"
|
||||
top_delta="0"
|
||||
width="127">
|
||||
<combo_box.item
|
||||
label="Current Window"
|
||||
name="CurrentWindow"
|
||||
value="[i0,i0]" />
|
||||
<combo_box.item
|
||||
label="Small (128x128)"
|
||||
name="Small(128x128)"
|
||||
value="[i128,i128]" />
|
||||
<combo_box.item
|
||||
label="Medium (256x256)"
|
||||
name="Medium(256x256)"
|
||||
value="[i256,i256]" />
|
||||
<combo_box.item
|
||||
label="Large (512x512)"
|
||||
name="Large(512x512)"
|
||||
value="[i512,i512]" />
|
||||
<combo_box.item
|
||||
label="Custom"
|
||||
name="Custom"
|
||||
value="[i-1,i-1]" />
|
||||
</combo_box>
|
||||
<combo_box
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="local_size_combo"
|
||||
top_delta="0"
|
||||
width="127">
|
||||
<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
|
||||
height="23"
|
||||
label="Format"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
name="local_format_combo"
|
||||
width="70">
|
||||
<combo_box.item
|
||||
label="PNG"
|
||||
name="PNG" />
|
||||
<combo_box.item
|
||||
label="JPEG"
|
||||
name="JPEG" />
|
||||
<combo_box.item
|
||||
label="BMP"
|
||||
name="BMP" />
|
||||
</combo_box>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Width"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="snapshot_width"
|
||||
left="0"
|
||||
name="panel_container"
|
||||
default_panel_name="panel_snapshot_options"
|
||||
top_pad="10"
|
||||
width="95" />
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Height"
|
||||
label_width="40"
|
||||
width="270">
|
||||
<panel
|
||||
class="llpanelsnapshotoptions"
|
||||
filename="panel_snapshot_options.xml"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="panel_snapshot_options"
|
||||
top="0" />
|
||||
<panel
|
||||
class="llpanelsnapshotprofile"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_profile"
|
||||
filename="panel_snapshot_profile.xml" />
|
||||
<panel
|
||||
class="llpanelsnapshotpostcard"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_postcard"
|
||||
filename="panel_snapshot_postcard.xml" />
|
||||
<panel
|
||||
class="llpanelsnapshotinventory"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_inventory"
|
||||
filename="panel_snapshot_inventory.xml" />
|
||||
<panel
|
||||
class="llpanelsnapshotlocal"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_local"
|
||||
filename="panel_snapshot_local.xml" />
|
||||
</panel_container>
|
||||
<panel
|
||||
height="295"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="snapshot_height"
|
||||
top_delta="0"
|
||||
width="95" />
|
||||
<check_box
|
||||
bottom_delta="20"
|
||||
label="Constrain proportions"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="keep_aspect_check" />
|
||||
<slider
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="15"
|
||||
increment="1"
|
||||
initial_value="75"
|
||||
label="Image quality"
|
||||
label_width="124"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
max_val="100"
|
||||
name="image_quality_slider"
|
||||
top_pad="5"
|
||||
width="228" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="13"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="layer_type_label"
|
||||
top_pad="5"
|
||||
width="50">
|
||||
Capture:
|
||||
</text>
|
||||
<combo_box
|
||||
height="23"
|
||||
label="Image Layers"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
name="layer_types"
|
||||
width="145">
|
||||
<combo_box.item
|
||||
label="Colors"
|
||||
name="Colors"
|
||||
value="colors" />
|
||||
<combo_box.item
|
||||
label="Depth"
|
||||
name="Depth"
|
||||
value="depth" />
|
||||
</combo_box>
|
||||
<check_box
|
||||
label="Interface"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
top_pad="10"
|
||||
width="180"
|
||||
name="ui_check" />
|
||||
<check_box
|
||||
label="HUDs"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
top_pad="10"
|
||||
width="180"
|
||||
name="hud_check" />
|
||||
<check_box
|
||||
label="Keep open after saving"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="8"
|
||||
width="180"
|
||||
name="keep_open_check" />
|
||||
<check_box
|
||||
label="Freeze frame (fullscreen)"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="8"
|
||||
width="180"
|
||||
name="freeze_frame_check" />
|
||||
<check_box
|
||||
label="Auto-refresh"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="8"
|
||||
width="180"
|
||||
name="auto_snapshot_check" />
|
||||
left="270"
|
||||
name="advanced_options_panel"
|
||||
top="20"
|
||||
width="200">
|
||||
<text
|
||||
type="string"
|
||||
font="SansSerifSmall"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
halign="left"
|
||||
name="advanced_options_label"
|
||||
right="-10"
|
||||
top="10">
|
||||
ADVANCED OPTIONS
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top|right"
|
||||
height="1"
|
||||
left="10"
|
||||
layout="topleft"
|
||||
name="advanced_options_hr"
|
||||
right="-10"
|
||||
top_pad="5"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="13"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="layer_type_label"
|
||||
top_pad="10"
|
||||
width="50">
|
||||
Capture:
|
||||
</text>
|
||||
<combo_box
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Image Layers"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
name="layer_types"
|
||||
right="-10">
|
||||
<combo_box.item
|
||||
label="Colors"
|
||||
name="Colors"
|
||||
value="colors" />
|
||||
<combo_box.item
|
||||
label="Depth"
|
||||
name="Depth"
|
||||
value="depth" />
|
||||
</combo_box>
|
||||
<check_box
|
||||
label="Interface"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
top_pad="10"
|
||||
width="180"
|
||||
name="ui_check" />
|
||||
<check_box
|
||||
label="HUDs"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
top_pad="10"
|
||||
width="180"
|
||||
name="hud_check" />
|
||||
<check_box
|
||||
label="Freeze frame (fullscreen)"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="8"
|
||||
width="180"
|
||||
name="freeze_frame_check" />
|
||||
<check_box
|
||||
label="Auto-refresh"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="8"
|
||||
width="180"
|
||||
name="auto_snapshot_check" />
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -1,117 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
can_minimize="false"
|
||||
can_resize="true"
|
||||
<panel
|
||||
height="380"
|
||||
layout="topleft"
|
||||
min_height="380"
|
||||
min_width="490"
|
||||
name="Postcard"
|
||||
help_topic="postcard"
|
||||
title="EMAIL SNAPSHOT"
|
||||
name="panel_postcard_message"
|
||||
width="490">
|
||||
<floater.string
|
||||
name="default_subject">
|
||||
Postcard from [SECOND_LIFE].
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="default_message">
|
||||
Check this out!
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="upload_message">
|
||||
Sending...
|
||||
</floater.string>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
bottom="35"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
name="to_label">
|
||||
Recipient's Email:
|
||||
name="to_label"
|
||||
top="10"
|
||||
width="60">
|
||||
To:
|
||||
</text>
|
||||
<line_editor
|
||||
control_name="LastPostcardRecipient"
|
||||
follows="left|top"
|
||||
follows="left|top|right"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_delta="148"
|
||||
left_pad="10"
|
||||
name="to_form"
|
||||
top_delta="-4"
|
||||
width="150" />
|
||||
right="-10"
|
||||
top_delta="-4" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
bottom_delta="23"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
name="from_label">
|
||||
Your Email:
|
||||
name="name_label"
|
||||
width="60">
|
||||
From:
|
||||
</text>
|
||||
<line_editor
|
||||
follows="left|top"
|
||||
follows="left|top|right"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_delta="148"
|
||||
name="from_form"
|
||||
top_delta="-4"
|
||||
width="150" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
bottom_delta="23"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
name="name_label">
|
||||
Your Name:
|
||||
</text>
|
||||
<line_editor
|
||||
follows="left|top"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_delta="148"
|
||||
left_pad="10"
|
||||
max_length_bytes="100"
|
||||
name="name_form"
|
||||
top_delta="-4"
|
||||
width="150" />
|
||||
right="-10"
|
||||
top_delta="-4" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
bottom_delta="23"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
name="subject_label">
|
||||
name="subject_label"
|
||||
width="60">
|
||||
Subject:
|
||||
</text>
|
||||
<line_editor
|
||||
follows="left|top"
|
||||
follows="left|top|right"
|
||||
height="20"
|
||||
label="Type your subject here."
|
||||
layout="topleft"
|
||||
left_delta="148"
|
||||
left_pad="10"
|
||||
max_length_bytes="100"
|
||||
name="subject_form"
|
||||
top_delta="-4"
|
||||
width="150" />
|
||||
right="-10"
|
||||
top_delta="-4" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
bottom_delta="23"
|
||||
follows="top|left"
|
||||
follows="top|left|right"
|
||||
font="SansSerif"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
name="msg_label">
|
||||
name="msg_label"
|
||||
right="-10">
|
||||
Message:
|
||||
</text>
|
||||
<text_editor
|
||||
|
|
@ -123,9 +93,9 @@
|
|||
left_delta="0"
|
||||
max_length="700"
|
||||
name="msg_form"
|
||||
word_wrap="true"
|
||||
right="-10"
|
||||
top_pad="10"
|
||||
width="420">
|
||||
word_wrap="true">
|
||||
Type your message here.
|
||||
</text_editor>
|
||||
<button
|
||||
|
|
@ -136,7 +106,10 @@
|
|||
name="cancel_btn"
|
||||
right="-10"
|
||||
top="350"
|
||||
width="100" />
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Postcard.Cancel" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
|
|
@ -145,5 +118,8 @@
|
|||
left_delta="-106"
|
||||
name="send_btn"
|
||||
top_delta="0"
|
||||
width="100" />
|
||||
</floater>
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Postcard.Send" />
|
||||
</button>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="380"
|
||||
layout="topleft"
|
||||
name="panel_postcard_settings"
|
||||
width="490">
|
||||
<combo_box
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="postcard_size_combo"
|
||||
right="-10"
|
||||
top_pad="10">
|
||||
<combo_box.item
|
||||
label="Current Window"
|
||||
name="CurrentWindow"
|
||||
value="[i0,i0]" />
|
||||
<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="Custom"
|
||||
name="Custom"
|
||||
value="[i-1,i-1]" />
|
||||
</combo_box>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Width"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="postcard_snapshot_width"
|
||||
top_pad="10"
|
||||
width="95" />
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Height"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="postcard_snapshot_height"
|
||||
top_delta="0"
|
||||
width="95" />
|
||||
<check_box
|
||||
bottom_delta="20"
|
||||
follows="left|top"
|
||||
label="Constrain proportions"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="postcard_keep_aspect_check" />
|
||||
<slider
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="15"
|
||||
increment="1"
|
||||
initial_value="75"
|
||||
label="Image quality"
|
||||
label_width="80"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="100"
|
||||
name="image_quality_slider"
|
||||
top_pad="7"
|
||||
width="200" />
|
||||
<text
|
||||
type="string"
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
length="1"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left_pad="-5"
|
||||
halign="left"
|
||||
name="image_quality_level"
|
||||
top_delta="0"
|
||||
width="60">
|
||||
([QLVL])
|
||||
</text>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="380"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_inventory"
|
||||
width="490">
|
||||
<icon
|
||||
follows="top|left"
|
||||
height="18"
|
||||
image_name="Snapshot_Inventory"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
mouse_opaque="true"
|
||||
name="title_icon"
|
||||
top="5"
|
||||
width="18" />
|
||||
<text
|
||||
follows="top|left|right"
|
||||
font="SansSerifBold"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="12"
|
||||
length="1"
|
||||
name="title"
|
||||
right="-10"
|
||||
text_color="white"
|
||||
type="string"
|
||||
top_delta="5">
|
||||
Save to My Inventory
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top|right"
|
||||
height="1"
|
||||
left="10"
|
||||
layout="topleft"
|
||||
name="hr"
|
||||
right="-10"
|
||||
top_pad="5"
|
||||
/>
|
||||
<text
|
||||
bottom="35"
|
||||
follows="top|left|right"
|
||||
font="SansSerif"
|
||||
height="56"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
length="1"
|
||||
name="hint_lbl"
|
||||
top_pad="10"
|
||||
type="string"
|
||||
word_wrap="true">
|
||||
Saving an image to your inventory costs L$[UPLOAD_COST]. To save your image as a texture select one of the square formats.
|
||||
</text>
|
||||
<combo_box
|
||||
follows="top|left|right"
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="texture_size_combo"
|
||||
right="-10"
|
||||
top_pad="10">
|
||||
<combo_box.item
|
||||
label="Current Window"
|
||||
name="CurrentWindow"
|
||||
value="[i0,i0]" />
|
||||
<combo_box.item
|
||||
label="Small (128x128)"
|
||||
name="Small(128x128)"
|
||||
value="[i128,i128]" />
|
||||
<combo_box.item
|
||||
label="Medium (256x256)"
|
||||
name="Medium(256x256)"
|
||||
value="[i256,i256]" />
|
||||
<combo_box.item
|
||||
label="Large (512x512)"
|
||||
name="Large(512x512)"
|
||||
value="[i512,i512]" />
|
||||
<combo_box.item
|
||||
label="Custom"
|
||||
name="Custom"
|
||||
value="[i-1,i-1]" />
|
||||
</combo_box>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Width"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="inventory_snapshot_width"
|
||||
top_pad="10"
|
||||
width="95" />
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Height"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="inventory_snapshot_height"
|
||||
top_delta="0"
|
||||
width="95" />
|
||||
<check_box
|
||||
bottom_delta="20"
|
||||
follows="left|top"
|
||||
label="Constrain proportions"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="inventory_keep_aspect_check" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
name="cancel_btn"
|
||||
right="-10"
|
||||
top="350"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Inventory.Cancel" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Save"
|
||||
layout="topleft"
|
||||
left_delta="-106"
|
||||
name="save_btn"
|
||||
top_delta="0"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Inventory.Save" />
|
||||
</button>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="380"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_local"
|
||||
width="490">
|
||||
<icon
|
||||
follows="top|left"
|
||||
height="18"
|
||||
image_name="Snapshot_Download"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
mouse_opaque="true"
|
||||
name="title_icon"
|
||||
top="5"
|
||||
width="18" />
|
||||
<text
|
||||
follows="top|left|right"
|
||||
font="SansSerifBold"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="12"
|
||||
length="1"
|
||||
name="title"
|
||||
right="-10"
|
||||
text_color="white"
|
||||
type="string"
|
||||
top_delta="4">
|
||||
Save to My Computer
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top|right"
|
||||
height="1"
|
||||
left="10"
|
||||
layout="topleft"
|
||||
name="hr"
|
||||
right="-10"
|
||||
top_pad="5"
|
||||
/>
|
||||
<combo_box
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="local_size_combo"
|
||||
right="-10"
|
||||
top_pad="10">
|
||||
<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>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Width"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="local_snapshot_width"
|
||||
top_pad="10"
|
||||
width="95" />
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Height"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="local_snapshot_height"
|
||||
top_delta="0"
|
||||
width="95" />
|
||||
<check_box
|
||||
bottom_delta="20"
|
||||
follows="left|top"
|
||||
label="Constrain proportions"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="local_keep_aspect_check" />
|
||||
<combo_box
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Format"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="local_format_combo"
|
||||
top_pad="10"
|
||||
width="120">
|
||||
<combo_box.item
|
||||
label="PNG (Lossless)"
|
||||
name="PNG"
|
||||
value="PNG" />
|
||||
<combo_box.item
|
||||
label="JPEG"
|
||||
name="JPEG"
|
||||
value="JPEG" />
|
||||
<combo_box.item
|
||||
label="BMP (Lossless)"
|
||||
name="BMP"
|
||||
value="BMP" />
|
||||
</combo_box>
|
||||
<slider
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="15"
|
||||
increment="1"
|
||||
initial_value="75"
|
||||
label="Image quality"
|
||||
label_width="80"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="100"
|
||||
name="image_quality_slider"
|
||||
top_pad="7"
|
||||
width="200" />
|
||||
<text
|
||||
type="string"
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
length="1"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left_pad="-5"
|
||||
halign="left"
|
||||
name="image_quality_level"
|
||||
top_delta="0"
|
||||
width="60">
|
||||
([QLVL])
|
||||
</text>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
name="cancel_btn"
|
||||
right="-10"
|
||||
top="350"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Local.Cancel" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Save"
|
||||
layout="topleft"
|
||||
left_delta="-106"
|
||||
name="save_btn"
|
||||
top_delta="0"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Local.Save" />
|
||||
</button>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
follows="all"
|
||||
height="240"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_options"
|
||||
width="490">
|
||||
<button
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
height="38"
|
||||
image_overlay="Snapshot_Profile"
|
||||
image_overlay_alignment="left"
|
||||
image_top_pad="-2"
|
||||
imgoverlay_label_space="10"
|
||||
label="Post to My Profile Feed"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="save_to_profile_btn"
|
||||
pad_left="10"
|
||||
right="-10"
|
||||
top="5">
|
||||
<button.commit_callback
|
||||
function="Snapshot.SaveToProfile" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
height="38"
|
||||
image_overlay="Snapshot_Email"
|
||||
image_overlay_alignment="left"
|
||||
image_top_pad="-2"
|
||||
imgoverlay_label_space="10"
|
||||
label="Email"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="save_to_email_btn"
|
||||
pad_left="10"
|
||||
right="-10"
|
||||
top_pad="10">
|
||||
<button.commit_callback
|
||||
function="Snapshot.SaveToEmail" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
height="38"
|
||||
image_overlay="Snapshot_Inventory"
|
||||
image_overlay_alignment="left"
|
||||
image_top_pad="-2"
|
||||
imgoverlay_label_space="10"
|
||||
label="Save to My Inventory (L$[AMOUNT])"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="save_to_inventory_btn"
|
||||
pad_left="10"
|
||||
right="-10"
|
||||
top_pad="10">
|
||||
<button.commit_callback
|
||||
function="Snapshot.SaveToInventory" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
height="38"
|
||||
image_overlay="Snapshot_Download"
|
||||
image_overlay_alignment="left"
|
||||
image_top_pad="-2"
|
||||
imgoverlay_label_space="10"
|
||||
label="Save to My Computer"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="save_to_computer_btn"
|
||||
pad_left="10"
|
||||
right="-10"
|
||||
top_pad="10">
|
||||
<button.commit_callback
|
||||
function="Snapshot.SaveToComputer" />
|
||||
</button>
|
||||
<panel
|
||||
background_visible="true"
|
||||
bg_alpha_color="0.9 1 0.9 1"
|
||||
bottom="-10"
|
||||
follows="left|bottom|right"
|
||||
font="SansSerifLarge"
|
||||
halign="center"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
length="1"
|
||||
name="succeeded_panel"
|
||||
right="-10"
|
||||
type="string"
|
||||
visible="false">
|
||||
<text
|
||||
follows="all"
|
||||
font="SansSerif"
|
||||
halign="center"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left="1"
|
||||
length="1"
|
||||
name="succeeded_lbl"
|
||||
right="-1"
|
||||
text_color="0.2 0.5 0.2 1"
|
||||
top="4"
|
||||
translate="false"
|
||||
type="string">
|
||||
Succeeded
|
||||
</text>
|
||||
</panel>
|
||||
<panel
|
||||
background_visible="true"
|
||||
bg_alpha_color="1 0.9 0.9 1"
|
||||
bottom="-10"
|
||||
follows="left|bottom|right"
|
||||
font="SansSerifLarge"
|
||||
halign="center"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
length="1"
|
||||
name="failed_panel"
|
||||
right="-10"
|
||||
type="string"
|
||||
visible="false">
|
||||
<text
|
||||
follows="all"
|
||||
font="SansSerif"
|
||||
halign="center"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left="1"
|
||||
length="1"
|
||||
name="failed_lbl"
|
||||
right="-1"
|
||||
text_color="0.5 0.2 0.2 1"
|
||||
top="4"
|
||||
translate="false"
|
||||
type="string">
|
||||
Failed
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="380"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_postcard"
|
||||
width="490">
|
||||
<string
|
||||
name="default_subject">
|
||||
Postcard from [SECOND_LIFE].
|
||||
</string>
|
||||
<string
|
||||
name="default_message">
|
||||
Check this out!
|
||||
</string>
|
||||
<string
|
||||
name="upload_message">
|
||||
Sending...
|
||||
</string>
|
||||
<string
|
||||
name="default_subject">
|
||||
Postcard from [SECOND_LIFE].
|
||||
</string>
|
||||
<string
|
||||
name="default_message">
|
||||
Check this out!
|
||||
</string>
|
||||
<icon
|
||||
follows="top|left"
|
||||
height="18"
|
||||
image_name="Snapshot_Email"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
mouse_opaque="true"
|
||||
name="title_icon"
|
||||
top="5"
|
||||
width="18" />
|
||||
<text
|
||||
follows="top|left|right"
|
||||
font="SansSerifBold"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="12"
|
||||
length="1"
|
||||
name="title"
|
||||
right="-10"
|
||||
text_color="white"
|
||||
type="string"
|
||||
top_delta="3">
|
||||
Email
|
||||
</text>
|
||||
<button
|
||||
follows="right|top"
|
||||
height="23"
|
||||
is_toggle="true"
|
||||
label="Message"
|
||||
layout="topleft"
|
||||
name="message_btn"
|
||||
right="-82"
|
||||
top_delta="-7"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="Postcard.Message" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|top"
|
||||
height="23"
|
||||
is_toggle="true"
|
||||
label="Settings"
|
||||
layout="topleft"
|
||||
name="settings_btn"
|
||||
top_delta="0"
|
||||
right="-10"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="Postcard.Settings" />
|
||||
</button>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top|right"
|
||||
height="1"
|
||||
left="10"
|
||||
layout="topleft"
|
||||
name="hr"
|
||||
right="-10"
|
||||
top_pad="5"
|
||||
/>
|
||||
<panel_container
|
||||
follows="all"
|
||||
height="340"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="postcard_panel_container"
|
||||
default_panel_name="panel_postcard_message"
|
||||
top_pad="10"
|
||||
width="490">
|
||||
<panel
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_postcard_message"
|
||||
filename="panel_postcard_message.xml" />
|
||||
<panel
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="panel_postcard_settings"
|
||||
filename="panel_postcard_settings.xml" />
|
||||
</panel_container>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="380"
|
||||
layout="topleft"
|
||||
name="panel_snapshot_profile"
|
||||
width="490">
|
||||
<icon
|
||||
follows="top|left"
|
||||
height="18"
|
||||
image_name="Snapshot_Profile"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
mouse_opaque="true"
|
||||
name="title_icon"
|
||||
top="5"
|
||||
width="18" />
|
||||
<text
|
||||
follows="top|left|right"
|
||||
font="SansSerifBold"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="12"
|
||||
length="1"
|
||||
name="title"
|
||||
right="-10"
|
||||
text_color="white"
|
||||
type="string"
|
||||
top_delta="4">
|
||||
Post to My Profile Feed
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
follows="left|top|right"
|
||||
height="1"
|
||||
left="10"
|
||||
layout="topleft"
|
||||
name="hr"
|
||||
right="-10"
|
||||
top_pad="5"
|
||||
/>
|
||||
<combo_box
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Resolution"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="profile_size_combo"
|
||||
top_pad="10"
|
||||
width="250">
|
||||
<combo_box.item
|
||||
label="Current Window"
|
||||
name="CurrentWindow"
|
||||
value="[i0,i0]" />
|
||||
<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="Custom"
|
||||
name="Custom"
|
||||
value="[i-1,i-1]" />
|
||||
</combo_box>
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Width"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="profile_snapshot_width"
|
||||
top_pad="10"
|
||||
width="95" />
|
||||
<spinner
|
||||
allow_text_entry="false"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="32"
|
||||
label="Height"
|
||||
label_width="40"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
max_val="6016"
|
||||
min_val="32"
|
||||
name="profile_snapshot_height"
|
||||
top_delta="0"
|
||||
width="95" />
|
||||
<check_box
|
||||
bottom_delta="20"
|
||||
label="Constrain proportions"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="profile_keep_aspect_check" />
|
||||
<text
|
||||
length="1"
|
||||
follows="top|left|right"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="12"
|
||||
name="caption_label"
|
||||
right="-10"
|
||||
top_pad="10"
|
||||
type="string">
|
||||
Caption:
|
||||
</text>
|
||||
<text_editor
|
||||
follows="all"
|
||||
height="170"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
length="1"
|
||||
max_length="700"
|
||||
name="caption"
|
||||
right="-10"
|
||||
top_pad="5"
|
||||
type="string"
|
||||
word_wrap="true">
|
||||
</text_editor>
|
||||
<check_box
|
||||
follows="left|bottom"
|
||||
initial_value="true"
|
||||
label="Include location"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="add_location_cb"
|
||||
top_pad="15" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
name="cancel_btn"
|
||||
right="-10"
|
||||
top="350"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="PostToProfile.Cancel" />
|
||||
</button>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Post"
|
||||
layout="topleft"
|
||||
left_delta="-106"
|
||||
name="post_btn"
|
||||
top_delta="0"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="PostToProfile.Send" />
|
||||
</button>
|
||||
</panel>
|
||||
|
|
@ -3724,4 +3724,12 @@ Try enclosing path to the editor with double quotes.
|
|||
<string name="Wrap">Wrap</string>
|
||||
<string name="Preview">Preview</string>
|
||||
<string name="Normal">Normal</string>
|
||||
|
||||
<!-- Snapshot image quality levels -->
|
||||
<string name="snapshot_quality_very_low">Very Low</string>
|
||||
<string name="snapshot_quality_low">Low</string>
|
||||
<string name="snapshot_quality_medium">Medium</string>
|
||||
<string name="snapshot_quality_high">High</string>
|
||||
<string name="snapshot_quality_very_high">Very High</string>
|
||||
|
||||
</strings>
|
||||
|
|
|
|||
Loading…
Reference in New Issue