added Flickr floater for ACME-1136, ACME-1137, ACME-1138, ACME-1140, and ACME-1141

meow-7.2.2
Cho 2013-11-02 01:50:17 +01:00
parent 963c97f64a
commit 0e71fb3c9d
15 changed files with 1186 additions and 89 deletions

View File

@ -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

View File

@ -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;

View File

@ -65,39 +65,6 @@ void toast_user_for_flickr_success()
LLNotificationsUtil::add("FlickrConnect", args);
}
///////////////////////////////////////////////////////////////////////////////
//
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
@ -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)

View File

@ -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();
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -65,39 +65,6 @@ void toast_user_for_twitter_success()
LLNotificationsUtil::add("TwitterConnect", args);
}
///////////////////////////////////////////////////////////////////////////////
//
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

View File

@ -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>);

View File

@ -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>

View File

@ -15,14 +15,6 @@
function="ShowAgentProfile"
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">
@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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 -->