summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCho <cho@lindenlab.com>2013-11-02 01:50:17 +0100
committerCho <cho@lindenlab.com>2013-11-02 01:50:17 +0100
commit0e71fb3c9d82bf2a307431f68f8ec84d223a4887 (patch)
treea6b8291a742154f60cafd8e484ebc3a67fde9987
parent963c97f64a4d1490fe8380805c4de38598adddad (diff)
added Flickr floater for ACME-1136, ACME-1137, ACME-1138, ACME-1140, and ACME-1141
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfacebookconnect.cpp33
-rw-r--r--indra/newview/llflickrconnect.cpp36
-rw-r--r--indra/newview/llfloaterflickr.cpp669
-rw-r--r--indra/newview/llfloaterflickr.h122
-rwxr-xr-xindra/newview/llfloatersnapshot.cpp4
-rwxr-xr-xindra/newview/llfloaterwebcontent.cpp10
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp3
-rw-r--r--indra/newview/lltwitterconnect.cpp33
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/skins/default/xui/en/floater_flickr.xml89
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml23
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_account.xml75
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_photo.xml152
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml20
15 files changed, 1186 insertions, 89 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ac2d3f8ff4..226c739e48 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -229,6 +229,7 @@ set(viewer_SOURCE_FILES
llfloatereditwater.cpp
llfloaterenvironmentsettings.cpp
llfloaterevent.cpp
+ llfloaterflickr.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
@@ -819,6 +820,7 @@ set(viewer_HEADER_FILES
llfloatereditwater.h
llfloaterenvironmentsettings.h
llfloaterevent.h
+ llfloaterflickr.h
llfloaterfonttest.h
llfloatergesture.h
llfloatergodtools.h
diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
index 2434272ef7..99fcab3dc3 100644
--- a/indra/newview/llfacebookconnect.cpp
+++ b/indra/newview/llfacebookconnect.cpp
@@ -28,6 +28,8 @@
#include "llviewerprecompiledheaders.h"
#include "llfacebookconnect.h"
+#include "llflickrconnect.h"
+#include "lltwitterconnect.h"
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
@@ -76,7 +78,7 @@ public:
{
if (tokens.size() >= 2)
{
- if (tokens[0].asString() == "connect" && tokens[1].asString() == "facebook")
+ if (tokens[0].asString() == "connect")
{
// this command probably came from the fbc_web browser, so close it
LLFloater* fbc_web = LLFloaterReg::getInstance("fbc_web");
@@ -85,12 +87,33 @@ public:
fbc_web->closeFloater();
}
- // connect to facebook
- if (query_map.has("code"))
+ if (tokens[1].asString() == "facebook")
{
- LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
+ // connect to facebook
+ if (query_map.has("code"))
+ {
+ LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
+ }
+ return true;
+ }
+ else if (tokens[1].asString() == "flickr")
+ {
+ // connect to flickr
+ if (query_map.has("oauth_token"))
+ {
+ LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
+ }
+ return true;
+ }
+ else if (tokens[1].asString() == "twitter")
+ {
+ // connect to twitter
+ if (query_map.has("oauth_token"))
+ {
+ LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
+ }
+ return true;
}
- return true;
}
}
return false;
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
index ba9be3af24..62c8110ea7 100644
--- a/indra/newview/llflickrconnect.cpp
+++ b/indra/newview/llflickrconnect.cpp
@@ -67,39 +67,6 @@ void toast_user_for_flickr_success()
///////////////////////////////////////////////////////////////////////////////
//
-class LLFlickrConnectHandler : public LLCommandHandler
-{
-public:
- LLFlickrConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (tokens.size() >= 2)
- {
- if (tokens[0].asString() == "connect" && tokens[1].asString() == "flickr")
- {
- // this command probably came from the fbc_web browser, so close it
- LLFloater* fbc_web = LLFloaterReg::getInstance("fbc_web");
- if (fbc_web)
- {
- fbc_web->closeFloater();
- }
-
- // connect to flickr
- if (query_map.has("oauth_token"))
- {
- LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- }
- return false;
- }
-};
-LLFlickrConnectHandler gFlickrConnectHandler;
-
-///////////////////////////////////////////////////////////////////////////////
-//
class LLFlickrConnectResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLFlickrConnectResponder);
@@ -329,7 +296,8 @@ std::string LLFlickrConnect::getFlickrConnectURL(const std::string& route, bool
LLViewerRegion *regionp = gAgent.getRegion();
if (regionp)
{
- url = regionp->getCapability("FlickrConnect");
+ url = "http://pdp15.lindenlab.com/flickr/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
+ //url = regionp->getCapability("FlickrConnect");
url += route;
if (include_read_from_master && mReadFromMaster)
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
new file mode 100644
index 0000000000..290d174619
--- /dev/null
+++ b/indra/newview/llfloaterflickr.cpp
@@ -0,0 +1,669 @@
+/**
+* @file llfloaterflickr.cpp
+* @brief Implementation of llfloaterflickr
+* @author cho@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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 "llfloaterflickr.h"
+
+#include "llagent.h"
+#include "llagentui.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llflickrconnect.h"
+#include "llfloaterreg.h"
+#include "lliconctrl.h"
+#include "llresmgr.h" // LLLocale
+#include "llsdserialize.h"
+#include "llloadingindicator.h"
+#include "llplugincookiestore.h"
+#include "llslurl.h"
+#include "lltrans.h"
+#include "llsnapshotlivepreview.h"
+#include "llviewerregion.h"
+#include "llviewercontrol.h"
+#include "llviewermedia.h"
+
+static LLRegisterPanelClassWrapper<LLFlickrPhotoPanel> t_panel_photo("llflickrphotopanel");
+static LLRegisterPanelClassWrapper<LLFlickrAccountPanel> t_panel_account("llflickraccountpanel");
+
+const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
+const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=flickr&utm_medium=photo&utm_campaign=slshare";
+
+///////////////////////////
+//LLFlickrPhotoPanel///////
+///////////////////////////
+
+LLFlickrPhotoPanel::LLFlickrPhotoPanel() :
+mSnapshotPanel(NULL),
+mResolutionComboBox(NULL),
+mRefreshBtn(NULL),
+mWorkingLabel(NULL),
+mThumbnailPlaceholder(NULL),
+mCaptionTextBox(NULL),
+mLocationCheckbox(NULL),
+mPostButton(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFlickrPhotoPanel::onSend, this));
+ mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFlickrPhotoPanel::onClickNewSnapshot, this));
+}
+
+LLFlickrPhotoPanel::~LLFlickrPhotoPanel()
+{
+ if(mPreviewHandle.get())
+ {
+ mPreviewHandle.get()->die();
+ }
+}
+
+BOOL LLFlickrPhotoPanel::postBuild()
+{
+ setVisibleCallback(boost::bind(&LLFlickrPhotoPanel::onVisibilityChange, this, _2));
+
+ mSnapshotPanel = getChild<LLUICtrl>("snapshot_panel");
+ mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
+ mResolutionComboBox->setCommitCallback(boost::bind(&LLFlickrPhotoPanel::updateResolution, this, TRUE));
+ mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
+ mWorkingLabel = getChild<LLUICtrl>("working_lbl");
+ mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+ mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
+ mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
+ mPostButton = getChild<LLUICtrl>("post_photo_btn");
+ mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
+
+ return LLPanel::postBuild();
+}
+
+void LLFlickrPhotoPanel::draw()
+{
+ LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
+
+ // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
+ bool no_ongoing_connection = !(LLFlickrConnect::instance().isTransactionOngoing());
+ mCancelButton->setEnabled(no_ongoing_connection);
+ mCaptionTextBox->setEnabled(no_ongoing_connection);
+ mResolutionComboBox->setEnabled(no_ongoing_connection);
+ mRefreshBtn->setEnabled(no_ongoing_connection);
+ mLocationCheckbox->setEnabled(no_ongoing_connection);
+
+ // Display the preview if one is available
+ if (previewp && previewp->getThumbnailImage())
+ {
+ const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
+ const S32 thumbnail_w = previewp->getThumbnailWidth();
+ const S32 thumbnail_h = previewp->getThumbnailHeight();
+
+ // calc preview offset within the preview rect
+ const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
+ const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
+
+ // calc preview offset within the floater rect
+ // Hack : To get the full offset, we need to take into account each and every offset of each widgets up to the floater.
+ // This is almost as arbitrary as using a fixed offset so that's what we do here for the sake of simplicity.
+ // *TODO : Get the offset looking through the hierarchy of widgets, should be done in postBuild() so to avoid traversing the hierarchy each time.
+ S32 offset_x = thumbnail_rect.mLeft + local_offset_x - 1;
+ S32 offset_y = thumbnail_rect.mBottom + local_offset_y - 39;
+
+ mSnapshotPanel->localPointToOtherView(offset_x, offset_y, &offset_x, &offset_y, getParentByType<LLFloater>());
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ // Apply floater transparency to the texture unless the floater is focused.
+ F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+ LLColor4 color = LLColor4::white;
+ gl_draw_scaled_image(offset_x, offset_y,
+ thumbnail_w, thumbnail_h,
+ previewp->getThumbnailImage(), color % alpha);
+
+ previewp->drawPreviewRect(offset_x, offset_y) ;
+ }
+
+ // Update the visibility of the working (computing preview) label
+ mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
+
+ // Enable Post if we have a preview to send and no on going connection being processed
+ mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
+
+ // Draw the rest of the panel on top of it
+ LLPanel::draw();
+}
+
+LLSnapshotLivePreview* LLFlickrPhotoPanel::getPreviewView()
+{
+ LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
+ return previewp;
+}
+
+void LLFlickrPhotoPanel::onVisibilityChange(const LLSD& new_visibility)
+{
+ bool visible = new_visibility.asBoolean();
+ if (visible)
+ {
+ if (mPreviewHandle.get())
+ {
+ LLSnapshotLivePreview* preview = getPreviewView();
+ if(preview)
+ {
+ lldebugs << "opened, updating snapshot" << llendl;
+ preview->updateSnapshot(TRUE);
+ }
+ }
+ else
+ {
+ LLRect full_screen_rect = getRootView()->getRect();
+ LLSnapshotLivePreview::Params p;
+ p.rect(full_screen_rect);
+ LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+ mPreviewHandle = previewp->getHandle();
+
+ previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
+ previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
+ //previewp->setSnapshotQuality(98);
+ previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
+
+ updateControls();
+ }
+ }
+}
+
+void LLFlickrPhotoPanel::onClickNewSnapshot()
+{
+ LLSnapshotLivePreview* previewp = getPreviewView();
+ if (previewp)
+ {
+ //setStatus(Impl::STATUS_READY);
+ lldebugs << "updating snapshot" << llendl;
+ previewp->updateSnapshot(TRUE);
+ }
+}
+
+void LLFlickrPhotoPanel::onSend()
+{
+ LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrPhotoPanel"); // just in case it is already listening
+ LLEventPumps::instance().obtain("FlickrConnectState").listen("LLFlickrPhotoPanel", boost::bind(&LLFlickrPhotoPanel::onFlickrConnectStateChange, this, _1));
+
+ // Connect to Flickr if necessary and then post
+ if (LLFlickrConnect::instance().isConnected())
+ {
+ sendPhoto();
+ }
+ else
+ {
+ LLFlickrConnect::instance().checkConnectionToFlickr(true);
+ }
+}
+
+bool LLFlickrPhotoPanel::onFlickrConnectStateChange(const LLSD& data)
+{
+ switch (data.get("enum").asInteger())
+ {
+ case LLFlickrConnect::FLICKR_CONNECTED:
+ sendPhoto();
+ break;
+
+ case LLFlickrConnect::FLICKR_POSTED:
+ LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrPhotoPanel");
+ clearAndClose();
+ break;
+ }
+
+ return false;
+}
+
+void LLFlickrPhotoPanel::sendPhoto()
+{
+ // Get the caption
+ std::string caption = mCaptionTextBox->getValue().asString();
+
+ // Add the location if required
+ bool add_location = mLocationCheckbox->getValue().asBoolean();
+ if (add_location)
+ {
+ // Get the SLURL for the location
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ std::string slurl_string = slurl.getSLURLString();
+
+ // Add query parameters so Google Analytics can track incoming clicks!
+ slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
+
+ // Add it to the caption (pretty crude, but we don't have a better option with photos)
+ if (caption.empty())
+ caption = slurl_string;
+ else
+ caption = caption + " " + slurl_string;
+ }
+
+ // Get the image
+ LLSnapshotLivePreview* previewp = getPreviewView();
+
+ // Post to Flickr
+ LLFlickrConnect::instance().uploadPhoto(previewp->getFormattedImage(), "", caption, "", 1);
+
+ updateControls();
+}
+
+void LLFlickrPhotoPanel::clearAndClose()
+{
+ mCaptionTextBox->setValue("");
+
+ LLFloater* floater = getParentByType<LLFloater>();
+ if (floater)
+ {
+ floater->closeFloater();
+ }
+}
+
+void LLFlickrPhotoPanel::updateControls()
+{
+ LLSnapshotLivePreview* previewp = getPreviewView();
+ BOOL got_bytes = previewp && previewp->getDataSize() > 0;
+ BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
+ LLSnapshotLivePreview::ESnapshotType shot_type = (previewp ? previewp->getSnapshotType() : LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
+
+ // *TODO: Separate maximum size for Web images from postcards
+ lldebugs << "Is snapshot up-to-date? " << got_snap << llendl;
+
+ LLLocale locale(LLLocale::USER_LOCALE);
+ std::string bytes_string;
+ if (got_snap)
+ {
+ LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
+ }
+
+ //getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : getString("unknown")); <---uses localized string
+ getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : "unknown");
+ getChild<LLUICtrl>("file_size_label")->setColor(
+ shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
+ && got_bytes
+ && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
+
+ updateResolution(FALSE);
+}
+
+void LLFlickrPhotoPanel::updateResolution(BOOL do_update)
+{
+ LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
+
+ std::string sdstring = combobox->getSelectedValue();
+ LLSD sdres;
+ std::stringstream sstream(sdstring);
+ LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
+
+ S32 width = sdres[0];
+ S32 height = sdres[1];
+
+ LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
+ if (previewp && combobox->getCurrentIndex() >= 0)
+ {
+ S32 original_width = 0 , original_height = 0 ;
+ previewp->getSize(original_width, original_height) ;
+
+ if (width == 0 || height == 0)
+ {
+ // take resolution from current window size
+ lldebugs << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << llendl;
+ previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
+ }
+ else
+ {
+ // use the resolution from the selected pre-canned drop-down choice
+ lldebugs << "Setting preview res selected from combo: " << width << "x" << height << llendl;
+ previewp->setSize(width, height);
+ }
+
+ checkAspectRatio(width);
+
+ previewp->getSize(width, height);
+
+ if(original_width != width || original_height != height)
+ {
+ previewp->setSize(width, height);
+
+ // hide old preview as the aspect ratio could be wrong
+ lldebugs << "updating thumbnail" << llendl;
+
+ previewp->updateSnapshot(FALSE, TRUE);
+ if(do_update)
+ {
+ lldebugs << "Will update controls" << llendl;
+ updateControls();
+ LLFlickrPhotoPanel::onClickNewSnapshot();
+ }
+ }
+
+ }
+}
+
+void LLFlickrPhotoPanel::checkAspectRatio(S32 index)
+{
+ LLSnapshotLivePreview *previewp = getPreviewView() ;
+
+ BOOL keep_aspect = FALSE;
+
+ if (0 == index) // current window size
+ {
+ keep_aspect = TRUE;
+ }
+ else // predefined resolution
+ {
+ keep_aspect = FALSE;
+ }
+
+ if (previewp)
+ {
+ previewp->mKeepAspectRatio = keep_aspect;
+ }
+}
+
+LLUICtrl* LLFlickrPhotoPanel::getRefreshBtn()
+{
+ return mRefreshBtn;
+}
+
+///////////////////////////
+//LLFlickrAccountPanel//////
+///////////////////////////
+
+LLFlickrAccountPanel::LLFlickrAccountPanel() :
+mAccountCaptionLabel(NULL),
+mAccountNameLabel(NULL),
+mPanelButtons(NULL),
+mConnectButton(NULL),
+mDisconnectButton(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFlickrAccountPanel::onConnect, this));
+ mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFlickrAccountPanel::onDisconnect, this));
+
+ setVisibleCallback(boost::bind(&LLFlickrAccountPanel::onVisibilityChange, this, _2));
+}
+
+BOOL LLFlickrAccountPanel::postBuild()
+{
+ mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
+ mAccountNameLabel = getChild<LLTextBox>("account_name_label");
+ mPanelButtons = getChild<LLUICtrl>("panel_buttons");
+ mConnectButton = getChild<LLUICtrl>("connect_btn");
+ mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
+
+ return LLPanel::postBuild();
+}
+
+void LLFlickrAccountPanel::draw()
+{
+ LLFlickrConnect::EConnectionState connection_state = LLFlickrConnect::instance().getConnectionState();
+
+ //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
+ bool disconnecting = connection_state == LLFlickrConnect::FLICKR_DISCONNECTING;
+ mDisconnectButton->setEnabled(!disconnecting);
+
+ //Disable the 'connect' button when a connection is in progress
+ bool connecting = connection_state == LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS;
+ mConnectButton->setEnabled(!connecting);
+
+ LLPanel::draw();
+}
+
+void LLFlickrAccountPanel::onVisibilityChange(const LLSD& new_visibility)
+{
+ bool visible = new_visibility.asBoolean();
+
+ if(visible)
+ {
+ LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrAccountPanel");
+ LLEventPumps::instance().obtain("FlickrConnectState").listen("LLFlickrAccountPanel", boost::bind(&LLFlickrAccountPanel::onFlickrConnectStateChange, this, _1));
+
+ LLEventPumps::instance().obtain("FlickrConnectInfo").stopListening("LLFlickrAccountPanel");
+ LLEventPumps::instance().obtain("FlickrConnectInfo").listen("LLFlickrAccountPanel", boost::bind(&LLFlickrAccountPanel::onFlickrConnectInfoChange, this));
+
+ //Connected
+ if(LLFlickrConnect::instance().isConnected())
+ {
+ showConnectedLayout();
+ }
+ //Check if connected (show disconnected layout in meantime)
+ else
+ {
+ showDisconnectedLayout();
+ }
+ if ((LLFlickrConnect::instance().getConnectionState() == LLFlickrConnect::FLICKR_NOT_CONNECTED) ||
+ (LLFlickrConnect::instance().getConnectionState() == LLFlickrConnect::FLICKR_CONNECTION_FAILED))
+ {
+ LLFlickrConnect::instance().checkConnectionToFlickr();
+ }
+ }
+ else
+ {
+ LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrAccountPanel");
+ LLEventPumps::instance().obtain("FlickrConnectInfo").stopListening("LLFlickrAccountPanel");
+ }
+}
+
+bool LLFlickrAccountPanel::onFlickrConnectStateChange(const LLSD& data)
+{
+ if(LLFlickrConnect::instance().isConnected())
+ {
+ //In process of disconnecting so leave the layout as is
+ if(data.get("enum").asInteger() != LLFlickrConnect::FLICKR_DISCONNECTING)
+ {
+ showConnectedLayout();
+ }
+ }
+ else
+ {
+ showDisconnectedLayout();
+ }
+
+ return false;
+}
+
+bool LLFlickrAccountPanel::onFlickrConnectInfoChange()
+{
+ LLSD info = LLFlickrConnect::instance().getInfo();
+ std::string clickable_name;
+
+ //Strings of format [http://www.somewebsite.com Click Me] become clickable text
+ if(info.has("link") && info.has("name"))
+ {
+ clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
+ }
+
+ mAccountNameLabel->setText(clickable_name);
+
+ return false;
+}
+
+void LLFlickrAccountPanel::showConnectButton()
+{
+ if(!mConnectButton->getVisible())
+ {
+ mConnectButton->setVisible(TRUE);
+ mDisconnectButton->setVisible(FALSE);
+ }
+}
+
+void LLFlickrAccountPanel::hideConnectButton()
+{
+ if(mConnectButton->getVisible())
+ {
+ mConnectButton->setVisible(FALSE);
+ mDisconnectButton->setVisible(TRUE);
+ }
+}
+
+void LLFlickrAccountPanel::showDisconnectedLayout()
+{
+ mAccountCaptionLabel->setText(getString("flickr_disconnected"));
+ mAccountNameLabel->setText(std::string(""));
+ showConnectButton();
+}
+
+void LLFlickrAccountPanel::showConnectedLayout()
+{
+ LLFlickrConnect::instance().loadFlickrInfo();
+
+ mAccountCaptionLabel->setText(getString("flickr_connected"));
+ hideConnectButton();
+}
+
+void LLFlickrAccountPanel::onConnect()
+{
+ LLFlickrConnect::instance().checkConnectionToFlickr(true);
+
+ //Clear only the flickr browser cookies so that the flickr login screen appears
+ LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com");
+}
+
+void LLFlickrAccountPanel::onDisconnect()
+{
+ LLFlickrConnect::instance().disconnectFromFlickr();
+
+ LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com");
+}
+
+////////////////////////
+//LLFloaterFlickr///////
+////////////////////////
+
+LLFloaterFlickr::LLFloaterFlickr(const LLSD& key) : LLFloater(key),
+ mSocialPhotoPanel(NULL),
+ mStatusErrorText(NULL),
+ mStatusLoadingText(NULL),
+ mStatusLoadingIndicator(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFlickr::onCancel, this));
+}
+
+void LLFloaterFlickr::onCancel()
+{
+ closeFloater();
+}
+
+BOOL LLFloaterFlickr::postBuild()
+{
+ // Keep tab of the Photo Panel
+ mSocialPhotoPanel = static_cast<LLFlickrPhotoPanel*>(getChild<LLUICtrl>("panel_flickr_photo"));
+ // Connection status widgets
+ mStatusErrorText = getChild<LLTextBox>("connection_error_text");
+ mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
+ mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
+ return LLFloater::postBuild();
+}
+
+// static
+void LLFloaterFlickr::preUpdate()
+{
+ LLFloaterFlickr* instance = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
+ if (instance)
+ {
+ //Will set file size text to 'unknown'
+ instance->mSocialPhotoPanel->updateControls();
+ }
+}
+
+// static
+void LLFloaterFlickr::postUpdate()
+{
+ LLFloaterFlickr* instance = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
+ if (instance)
+ {
+ //Will set the file size text
+ instance->mSocialPhotoPanel->updateControls();
+
+ // The refresh button is initially hidden. We show it after the first update,
+ // i.e. after snapshot is taken
+ LLUICtrl * refresh_button = instance->mSocialPhotoPanel->getRefreshBtn();
+
+ if (!refresh_button->getVisible())
+ {
+ refresh_button->setVisible(true);
+ }
+
+ }
+}
+
+void LLFloaterFlickr::draw()
+{
+ if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
+ {
+ mStatusErrorText->setVisible(false);
+ mStatusLoadingText->setVisible(false);
+ mStatusLoadingIndicator->setVisible(false);
+ LLFlickrConnect::EConnectionState connection_state = LLFlickrConnect::instance().getConnectionState();
+ std::string status_text;
+
+ switch (connection_state)
+ {
+ case LLFlickrConnect::FLICKR_NOT_CONNECTED:
+ // No status displayed when first opening the panel and no connection done
+ case LLFlickrConnect::FLICKR_CONNECTED:
+ // When successfully connected, no message is displayed
+ case LLFlickrConnect::FLICKR_POSTED:
+ // No success message to show since we actually close the floater after successful posting completion
+ break;
+ case LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS:
+ // Connection loading indicator
+ mStatusLoadingText->setVisible(true);
+ status_text = LLTrans::getString("SocialFlickrConnecting");
+ mStatusLoadingText->setValue(status_text);
+ mStatusLoadingIndicator->setVisible(true);
+ break;
+ case LLFlickrConnect::FLICKR_POSTING:
+ // Posting indicator
+ mStatusLoadingText->setVisible(true);
+ status_text = LLTrans::getString("SocialFlickrPosting");
+ mStatusLoadingText->setValue(status_text);
+ mStatusLoadingIndicator->setVisible(true);
+ break;
+ case LLFlickrConnect::FLICKR_CONNECTION_FAILED:
+ // Error connecting to the service
+ mStatusErrorText->setVisible(true);
+ status_text = LLTrans::getString("SocialFlickrErrorConnecting");
+ mStatusErrorText->setValue(status_text);
+ break;
+ case LLFlickrConnect::FLICKR_POST_FAILED:
+ // Error posting to the service
+ mStatusErrorText->setVisible(true);
+ status_text = LLTrans::getString("SocialFlickrErrorPosting");
+ mStatusErrorText->setValue(status_text);
+ break;
+ case LLFlickrConnect::FLICKR_DISCONNECTING:
+ // Disconnecting loading indicator
+ mStatusLoadingText->setVisible(true);
+ status_text = LLTrans::getString("SocialFlickrDisconnecting");
+ mStatusLoadingText->setValue(status_text);
+ mStatusLoadingIndicator->setVisible(true);
+ break;
+ case LLFlickrConnect::FLICKR_DISCONNECT_FAILED:
+ // Error disconnecting from the service
+ mStatusErrorText->setVisible(true);
+ status_text = LLTrans::getString("SocialFlickrErrorDisconnecting");
+ mStatusErrorText->setValue(status_text);
+ break;
+ }
+ }
+ LLFloater::draw();
+}
+
diff --git a/indra/newview/llfloaterflickr.h b/indra/newview/llfloaterflickr.h
new file mode 100644
index 0000000000..d98a470d5c
--- /dev/null
+++ b/indra/newview/llfloaterflickr.h
@@ -0,0 +1,122 @@
+/**
+* @file llfloaterflickr.h
+* @brief Header file for llfloaterflickr
+* @author cho@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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_LLFLOATERFLICKR_H
+#define LL_LLFLOATERFLICKR_H
+
+#include "llfloater.h"
+#include "lltextbox.h"
+#include "llviewertexture.h"
+
+class LLIconCtrl;
+class LLCheckBoxCtrl;
+class LLSnapshotLivePreview;
+
+class LLFlickrPhotoPanel : public LLPanel
+{
+public:
+ LLFlickrPhotoPanel();
+ ~LLFlickrPhotoPanel();
+
+ BOOL postBuild();
+ void draw();
+
+ LLSnapshotLivePreview* getPreviewView();
+ void onVisibilityChange(const LLSD& new_visibility);
+ void onClickNewSnapshot();
+ void onSend();
+ bool onFlickrConnectStateChange(const LLSD& data);
+
+ void sendPhoto();
+ void clearAndClose();
+
+ void updateControls();
+ void updateResolution(BOOL do_update);
+ void checkAspectRatio(S32 index);
+ LLUICtrl* getRefreshBtn();
+
+private:
+ LLHandle<LLView> mPreviewHandle;
+
+ LLUICtrl * mSnapshotPanel;
+ LLUICtrl * mResolutionComboBox;
+ LLUICtrl * mRefreshBtn;
+ LLUICtrl * mWorkingLabel;
+ LLUICtrl * mThumbnailPlaceholder;
+ LLUICtrl * mCaptionTextBox;
+ LLUICtrl * mLocationCheckbox;
+ LLUICtrl * mPostButton;
+ LLUICtrl* mCancelButton;
+};
+
+class LLFlickrAccountPanel : public LLPanel
+{
+public:
+ LLFlickrAccountPanel();
+ BOOL postBuild();
+ void draw();
+
+private:
+ void onVisibilityChange(const LLSD& new_visibility);
+ bool onFlickrConnectStateChange(const LLSD& data);
+ bool onFlickrConnectInfoChange();
+ void onConnect();
+ void onUseAnotherAccount();
+ void onDisconnect();
+
+ void showConnectButton();
+ void hideConnectButton();
+ void showDisconnectedLayout();
+ void showConnectedLayout();
+
+ LLTextBox * mAccountCaptionLabel;
+ LLTextBox * mAccountNameLabel;
+ LLUICtrl * mPanelButtons;
+ LLUICtrl * mConnectButton;
+ LLUICtrl * mDisconnectButton;
+};
+
+
+class LLFloaterFlickr : public LLFloater
+{
+public:
+ LLFloaterFlickr(const LLSD& key);
+ BOOL postBuild();
+ void draw();
+ void onCancel();
+
+ static void preUpdate();
+ static void postUpdate();
+
+private:
+ LLFlickrPhotoPanel* mSocialPhotoPanel;
+ LLTextBox* mStatusErrorText;
+ LLTextBox* mStatusLoadingText;
+ LLUICtrl* mStatusLoadingIndicator;
+};
+
+#endif // LL_LLFLOATERFLICKR_H
+
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index ea385d7baf..fa92ed094b 100755
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -32,6 +32,7 @@
#include "llfacebookconnect.h"
#include "llfloaterreg.h"
#include "llfloatersocial.h"
+#include "llfloaterflickr.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llpostcard.h"
@@ -1265,8 +1266,9 @@ void LLFloaterSnapshot::update()
{
LLFloaterSnapshot* inst = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
LLFloaterSocial* floater_social = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social");
+ LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
- if (!inst && !floater_social)
+ if (!inst && !floater_social && !floater_flickr)
return;
BOOL changed = FALSE;
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 5c569b9bf0..4fa2d4cb20 100755
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -30,6 +30,8 @@
#include "lliconctrl.h"
#include "llfloaterreg.h"
#include "llfacebookconnect.h"
+#include "llflickrconnect.h"
+#include "lltwitterconnect.h"
#include "lllayoutstack.h"
#include "llpluginclassmedia.h"
#include "llprogressbar.h"
@@ -297,6 +299,14 @@ void LLFloaterWebContent::onClose(bool app_quitting)
{
LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
}
+ if (!LLFlickrConnect::instance().isConnected())
+ {
+ LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
+ }
+ if (!LLTwitterConnect::instance().isConnected())
+ {
+ LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
+ }
}
LLViewerMedia::proxyWindowClosed(mUUID);
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 7532ebfc57..afd9942e77 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -35,6 +35,7 @@
#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloatersocial.h"
+#include "llfloaterflickr.h"
#include "llimagebmp.h"
#include "llimagej2c.h"
#include "llimagejpeg.h"
@@ -209,6 +210,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail
mSnapshotDelayTimer.setTimerExpirySec(delay);
LLFloaterSnapshot::preUpdate();
LLFloaterSocial::preUpdate();
+ LLFloaterFlickr::preUpdate();
}
// Update thumbnail if requested.
@@ -766,6 +768,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
lldebugs << "done creating snapshot" << llendl;
LLFloaterSnapshot::postUpdate();
LLFloaterSocial::postUpdate();
+ LLFloaterFlickr::postUpdate();
return TRUE;
}
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index 6efcce8127..80142e7073 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -67,39 +67,6 @@ void toast_user_for_twitter_success()
///////////////////////////////////////////////////////////////////////////////
//
-class LLTwitterConnectHandler : public LLCommandHandler
-{
-public:
- LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (tokens.size() >= 2)
- {
- if (tokens[0].asString() == "connect" && tokens[1].asString() == "twitter")
- {
- // this command probably came from the fbc_web browser, so close it
- LLFloater* fbc_web = LLFloaterReg::getInstance("fbc_web");
- if (fbc_web)
- {
- fbc_web->closeFloater();
- }
-
- // connect to twitter
- if (query_map.has("oauth_token"))
- {
- LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- }
- return false;
- }
-};
-LLTwitterConnectHandler gTwitterConnectHandler;
-
-///////////////////////////////////////////////////////////////////////////////
-//
class LLTwitterConnectResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLTwitterConnectResponder);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 4ce049df03..0541da95fc 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -53,13 +53,14 @@
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloaterdeleteenvpreset.h"
+#include "llfloaterdestinations.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditdaycycle.h"
#include "llfloatereditsky.h"
#include "llfloatereditwater.h"
#include "llfloaterenvironmentsettings.h"
#include "llfloaterevent.h"
-#include "llfloaterdestinations.h"
+#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
@@ -305,6 +306,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);
LLFloaterReg::add("social", "floater_social.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSocial>);
+ LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml
new file mode 100644
index 0000000000..441e3ee73d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_flickr.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_close="true"
+ can_resize="false"
+ help_topic="floater_flickr"
+ layout="topleft"
+ name="floater_flickr"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="UPLOAD TO FLICKR"
+ height="482"
+ width="304">
+ <panel
+ height="482"
+ width="304"
+ visible="true"
+ name="background"
+ follows="all"
+ top="0"
+ left="0">
+ <tab_container
+ name="tabs"
+ tab_group="1"
+ tab_min_width="70"
+ tab_height="30"
+ tab_position="top"
+ top="7"
+ height="437"
+ halign="center">
+ <panel
+ filename="panel_flickr_photo.xml"
+ class="llflickrphotopanel"
+ follows="all"
+ label="PHOTO"
+ name="panel_flickr_photo"/>
+ <panel
+ filename="panel_flickr_account.xml"
+ class="llflickraccountpanel"
+ follows="all"
+ label="ACCOUNT"
+ name="panel_flickr_account"/>
+ </tab_container>
+ <panel
+ name="connection_status_panel"
+ follows="left|bottom|right"
+ height="24">
+ <text
+ name="connection_error_text"
+ type="string"
+ follows="left|bottom|right"
+ top="5"
+ left="9"
+ width="250"
+ height="20"
+ wrap="true"
+ halign="left"
+ valign="center"
+ text_color="DrYellow"
+ font="SansSerif">
+ Error
+ </text>
+ <loading_indicator
+ follows="left|bottom|right"
+ height="24"
+ width="24"
+ name="connection_loading_indicator"
+ top="2"
+ left="9"
+ visible="true"/>
+ <text
+ name="connection_loading_text"
+ type="string"
+ follows="left|bottom|right"
+ top="5"
+ left_pad="5"
+ width="250"
+ height="20"
+ wrap="true"
+ halign="left"
+ valign="center"
+ text_color="EmphasisColor"
+ font="SansSerif">
+ Loading...
+ </text>
+ </panel>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index d635b8ee93..19fe706885 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -16,14 +16,6 @@
parameter="agent" />
</menu_item_call>
<menu_item_call
- label="Post to Facebook..."
- name="PostToFacebook">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="social"/>
- </menu_item_call>
- <menu_item_separator/>
- <menu_item_call
label="Appearance..."
name="ChangeOutfit">
<menu_item_call.on_click
@@ -288,6 +280,21 @@
parameter="conversation" />
</menu_item_check>
<menu_item_separator/>
+ <menu_item_call
+ label="Post to Facebook..."
+ name="PostToFacebook">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="social"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Upload to Flickr..."
+ name="UploadToFacebook">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="flickr"/>
+ </menu_item_call>
+ <menu_item_separator/>
<menu
label="Voice morphing"
name="VoiceMorphing"
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_account.xml b/indra/newview/skins/default/xui/en/panel_flickr_account.xml
new file mode 100644
index 0000000000..c76a42904b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_flickr_account.xml
@@ -0,0 +1,75 @@
+<panel
+ height="400"
+ width="304"
+ layout="topleft"
+ name="panel_flickr_account">
+ <string
+ name="flickr_connected"
+ value="You are connected to Flickr as:" />
+ <string
+ name="flickr_disconnected"
+ value="Not connected to Flickr" />
+ <text
+ layout="topleft"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="account_caption_label"
+ top="21"
+ type="string">
+ Not connected to Flickr.
+ </text>
+ <text
+ layout="topleft"
+ top_pad="2"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="account_name_label"
+ parse_urls="true"
+ type="string"/>
+ <panel
+ layout="topleft"
+ name="panel_buttons"
+ height="345"
+ left="9">
+ <button
+ layout="topleft"
+ follows="left|top"
+ top_pad="9"
+ visible="true"
+ height="23"
+ label="Connect..."
+ name="connect_btn"
+ width="210">
+ <commit_callback function="SocialSharing.Connect"/>
+ </button>
+
+ <button
+ layout="topleft"
+ follows="left|top"
+ top_delta="0"
+ height="23"
+ label="Disconnect"
+ name="disconnect_btn"
+ width="210"
+ visible="false">
+ <commit_callback function="SocialSharing.Disconnect"/>
+ </button>
+ <text
+ layout="topleft"
+ length="1"
+ follows="top|left"
+ height="16"
+ left="0"
+ name="account_learn_more_label"
+ top_pad="20"
+ type="string">
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share/ta-p/2149711 Learn about posting to Flickr]
+ </text>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
new file mode 100644
index 0000000000..1fc4927ac2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
@@ -0,0 +1,152 @@
+ <panel
+ height="400"
+ width="304"
+ layout="topleft"
+ name="panel_flickr_photo">
+ <layout_stack
+ layout="topleft"
+ border_size="0"
+ height="392"
+ follows="all"
+ orientation="vertical"
+ name="stack_photo"
+ top="8">
+ <layout_panel
+ name="snapshot_panel"
+ height="367">
+ <combo_box
+ control_name="SocialPhotoResolution"
+ follows="left|top"
+ top="6"
+ left="9"
+ name="resolution_combobox"
+ tool_tip="Image resolution"
+ height="21"
+ width="135">
+ <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>
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ height="14"
+ left="208"
+ length="1"
+ halign="right"
+ name="file_size_label"
+ top="9"
+ type="string"
+ width="50">
+ [SIZE] KB
+ </text>
+ <panel
+ height="150"
+ width="250"
+ visible="true"
+ name="thumbnail_placeholder"
+ top="33"
+ follows="left|top"
+ left="9">
+ </panel>
+ <button
+ follows="left|top"
+ height="23"
+ label="Refresh"
+ left="9"
+ top_pad="5"
+ name="new_snapshot_btn"
+ tool_tip="Click to refresh"
+ visible="true"
+ width="100" >
+ <button.commit_callback
+ function="SocialSharing.RefreshPhoto" />
+ </button>
+ <text
+ follows="left|top"
+ font="SansSerif"
+ text_color="EmphasisColor"
+ height="14"
+ top_pad="-19"
+ left_pad="-20"
+ length="1"
+ halign="center"
+ name="working_lbl"
+ translate="false"
+ type="string"
+ visible="true"
+ width="150">
+ Refreshing...
+ </text>
+ <text
+ length="1"
+ follows="top|left|right"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="caption_label"
+ top_pad="20"
+ type="string">
+ Comment (optional):
+ </text>
+ <text_editor
+ follows="left|top"
+ height="87"
+ width="250"
+ left="9"
+ length="1"
+ max_length="700"
+ name="photo_caption"
+ type="string"
+ word_wrap="true">
+ </text_editor>
+ <check_box
+ follows="left|top"
+ initial_value="true"
+ label="Include location in posting"
+ name="add_location_cb"
+ left="9"
+ height="16"
+ top_pad="8"/>
+ </layout_panel>
+ <layout_panel
+ name="photo_button_panel"
+ height="25">
+ <button
+ follows="left|top"
+ top="0"
+ left="9"
+ height="23"
+ label="Post"
+ name="post_photo_btn"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.SendPhoto" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Cancel"
+ name="cancel_photo_btn"
+ left_pad="15"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.Cancel" />
+ </button>
+ </layout_panel>
+ </layout_stack>
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index df04ddee86..ce09faeac0 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -148,13 +148,19 @@ Please try logging in again in a minute.</string>
<string name="SentToInvalidRegion">You were sent to an invalid region.</string>
<string name="TestingDisconnect">Testing viewer disconnect</string>
- <!-- Facebook Connect and, eventually, other Social Network -->
- <string name="SocialFacebookConnecting">Connecting to Facebook...</string>
- <string name="SocialFacebookPosting">Posting...</string>
- <string name="SocialFacebookDisconnecting">Disconnecting from Facebook...</string>
- <string name="SocialFacebookErrorConnecting">Problem connecting to Facebook</string>
- <string name="SocialFacebookErrorPosting">Problem posting to Facebook</string>
- <string name="SocialFacebookErrorDisconnecting">Problem disconnecting from Facebook</string>
+ <!-- SLShare: Facebook, Flickr, and so on... -->
+ <string name="SocialFacebookConnecting">Connecting to Facebook...</string>
+ <string name="SocialFacebookPosting">Posting...</string>
+ <string name="SocialFacebookDisconnecting">Disconnecting from Facebook...</string>
+ <string name="SocialFacebookErrorConnecting">Problem connecting to Facebook</string>
+ <string name="SocialFacebookErrorPosting">Problem posting to Facebook</string>
+ <string name="SocialFacebookErrorDisconnecting">Problem disconnecting from Facebook</string>
+ <string name="SocialFlickrConnecting">Connecting to Flickr...</string>
+ <string name="SocialFlickrPosting">Posting...</string>
+ <string name="SocialFlickrDisconnecting">Disconnecting from Flickr...</string>
+ <string name="SocialFlickrErrorConnecting">Problem connecting to Flickr</string>
+ <string name="SocialFlickrErrorPosting">Problem posting to Flickr</string>
+ <string name="SocialFlickrErrorDisconnecting">Problem disconnecting from Flickr</string>
<!-- Tooltip -->
<string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar -->