diff options
Diffstat (limited to 'indra/newview/llpanelclassified.cpp')
-rw-r--r-- | indra/newview/llpanelclassified.cpp | 324 |
1 files changed, 300 insertions, 24 deletions
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 836331b44b..c4684e9827 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -41,6 +41,7 @@ #include "lldir.h" #include "lldispatcher.h" #include "llfloaterreg.h" +#include "llhttpclient.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llparcel.h" @@ -83,6 +84,7 @@ const S32 DECLINE_TO_STATE = 0; //static std::list<LLPanelClassified*> LLPanelClassified::sAllPanels; +std::list<LLPanelClassifiedInfo*> LLPanelClassifiedInfo::sAllPanels; // "classifiedclickthrough" // strings[0] = classified_id @@ -103,10 +105,10 @@ public: S32 teleport_clicks = atoi(strings[1].c_str()); S32 map_clicks = atoi(strings[2].c_str()); S32 profile_clicks = atoi(strings[3].c_str()); - LLPanelClassified::setClickThrough(classified_id, teleport_clicks, - map_clicks, - profile_clicks, - false); + + LLPanelClassifiedInfo::setClickThrough( + classified_id, teleport_clicks, map_clicks, profile_clicks, false); + return true; } }; @@ -497,7 +499,7 @@ void LLPanelClassified::sendClassifiedInfoRequest() if (!url.empty()) { llinfos << "Classified stat request via capability" << llendl; - LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(((LLView*)this)->getHandle(), mClassifiedID)); + LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(mClassifiedID)); } } } @@ -1157,11 +1159,21 @@ LLPanelClassifiedInfo::LLPanelClassifiedInfo() , mScrollContainer(NULL) , mScrollingPanelMinHeight(0) , mScrollingPanelWidth(0) + , mSnapshotStreched(false) + , mTeleportClicksOld(0) + , mMapClicksOld(0) + , mProfileClicksOld(0) + , mTeleportClicksNew(0) + , mMapClicksNew(0) + , mProfileClicksNew(0) + , mSnapshotCtrl(NULL) { + sAllPanels.push_back(this); } LLPanelClassifiedInfo::~LLPanelClassifiedInfo() { + sAllPanels.remove(this); } // static @@ -1184,6 +1196,9 @@ BOOL LLPanelClassifiedInfo::postBuild() mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight(); mScrollingPanelWidth = mScrollingPanel->getRect().getWidth(); + mSnapshotCtrl = getChild<LLTextureCtrl>("classified_snapshot"); + mSnapshotRect = getDefaultSnapshotRect(); + return TRUE; } @@ -1215,6 +1230,9 @@ void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_pare { mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height); } + + mSnapshotRect = getDefaultSnapshotRect(); + stretchSnapshot(); } void LLPanelClassifiedInfo::onOpen(const LLSD& key) @@ -1234,6 +1252,7 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) resetData(); resetControls(); + scrollToTop(); setClassifiedId(key["classified_id"]); setClassifiedName(key["name"]); @@ -1242,6 +1261,19 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); + gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); + + // While we're at it let's get the stats from the new table if that + // capability exists. + std::string url = gAgent.getRegion()->getCapability("SearchStatRequest"); + if (!url.empty()) + { + llinfos << "Classified stat request via capability" << llendl; + LLSD body; + body["classified_id"] = getClassifiedId(); + LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(getClassifiedId())); + } + setInfoLoaded(false); } @@ -1263,14 +1295,22 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t static std::string mature_str = getString("type_mature"); static std::string pg_str = getString("type_pg"); static LLUIString price_str = getString("l$_price"); + static std::string date_fmt = getString("date_fmt"); bool mature = is_cf_mature(c_info->flags); childSetValue("content_type", mature ? mature_str : pg_str); - childSetValue("auto_renew", is_cf_auto_renew(c_info->flags)); + + std::string auto_renew_str = is_cf_auto_renew(c_info->flags) ? + getString("auto_renew_on") : getString("auto_renew_off"); + childSetValue("auto_renew", auto_renew_str); price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing)); childSetValue("price_for_listing", LLSD(price_str)); + std::string date_str = date_fmt; + LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date)); + childSetText("creation_date", date_str); + setInfoLoaded(true); } } @@ -1284,24 +1324,23 @@ void LLPanelClassifiedInfo::resetData() setClassifiedId(LLUUID::null); setSnapshotId(LLUUID::null); mPosGlobal.clearVec(); - childSetValue("category", LLStringUtil::null); - childSetValue("content_type", LLStringUtil::null); + childSetText("category", LLStringUtil::null); + childSetText("content_type", LLStringUtil::null); + childSetText("click_through_text", LLStringUtil::null); + childSetText("price_for_listing", LLStringUtil::null); + childSetText("auto_renew", LLStringUtil::null); + childSetText("creation_date", LLStringUtil::null); + childSetText("click_through_text", LLStringUtil::null); } void LLPanelClassifiedInfo::resetControls() { - if(getAvatarId() == gAgent.getID()) - { - childSetEnabled("edit_btn", TRUE); - childSetVisible("edit_btn", TRUE); - childSetVisible("auto_renew", TRUE); - } - else - { - childSetEnabled("edit_btn", FALSE); - childSetVisible("edit_btn", FALSE); - childSetVisible("auto_renew", FALSE); - } + bool is_self = getAvatarId() == gAgent.getID(); + + childSetEnabled("edit_btn", is_self); + childSetVisible("edit_btn", is_self); + childSetVisible("price_layout_panel", is_self); + childSetVisible("clickthrough_layout_panel", is_self); } void LLPanelClassifiedInfo::setClassifiedName(const std::string& name) @@ -1331,7 +1370,20 @@ void LLPanelClassifiedInfo::setClassifiedLocation(const std::string& location) void LLPanelClassifiedInfo::setSnapshotId(const LLUUID& id) { - childSetValue("classified_snapshot", id); + mSnapshotCtrl->setValue(id); + mSnapshotStreched = false; +} + +void LLPanelClassifiedInfo::draw() +{ + LLPanel::draw(); + + // Stretch in draw because it takes some time to load a texture, + // going to try to stretch snapshot until texture is loaded + if(!mSnapshotStreched) + { + stretchSnapshot(); + } } LLUUID LLPanelClassifiedInfo::getSnapshotId() @@ -1340,6 +1392,62 @@ LLUUID LLPanelClassifiedInfo::getSnapshotId() } // static +void LLPanelClassifiedInfo::setClickThrough( + const LLUUID& classified_id, + S32 teleport, + S32 map, + S32 profile, + bool from_new_table) +{ + llinfos << "Click-through data for classified " << classified_id << " arrived: [" + << teleport << ", " << map << ", " << profile << "] (" + << (from_new_table ? "new" : "old") << ")" << llendl; + + for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter) + { + LLPanelClassifiedInfo* self = *iter; + if (self->getClassifiedId() != classified_id) + { + continue; + } + + // *HACK: Skip LLPanelClassifiedEdit instances: they don't display clicks data. + // Those instances should not be in the list at all. + if (typeid(*self) != typeid(LLPanelClassifiedInfo)) + { + continue; + } + + llinfos << "Updating classified info panel" << llendl; + + // We need to check to see if the data came from the new stat_table + // or the old classified table. We also need to cache the data from + // the two separate sources so as to display the aggregate totals. + + if (from_new_table) + { + self->mTeleportClicksNew = teleport; + self->mMapClicksNew = map; + self->mProfileClicksNew = profile; + } + else + { + self->mTeleportClicksOld = teleport; + self->mMapClicksOld = map; + self->mProfileClicksOld = profile; + } + + static LLUIString ct_str = self->getString("click_through_text_fmt"); + + ct_str.setArg("[TELEPORT]", llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld)); + ct_str.setArg("[MAP]", llformat("%d", self->mMapClicksNew + self->mMapClicksOld)); + ct_str.setArg("[PROFILE]", llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)); + + self->childSetText("click_through_text", ct_str.getString()); + } +} + +// static std::string LLPanelClassifiedInfo::createLocationText( const std::string& original_name, const std::string& sim_name, @@ -1370,6 +1478,60 @@ std::string LLPanelClassifiedInfo::createLocationText( return location_text; } +void LLPanelClassifiedInfo::stretchSnapshot() +{ + // *NOTE dzaporozhan + // Could be moved to LLTextureCtrl + + LLViewerFetchedTexture* texture = mSnapshotCtrl->getTexture(); + + if(!texture) + { + return; + } + + if(0 == texture->getOriginalWidth() || 0 == texture->getOriginalHeight()) + { + // looks like texture is not loaded yet + return; + } + + LLRect rc = mSnapshotRect; + // *HACK dzaporozhan + // LLTextureCtrl uses BTN_HEIGHT_SMALL as bottom for texture which causes + // drawn texture to be smaller than expected. (see LLTextureCtrl::draw()) + // Lets increase texture height to force texture look as expected. + rc.mBottom -= BTN_HEIGHT_SMALL; + + F32 t_width = texture->getFullWidth(); + F32 t_height = texture->getFullHeight(); + + F32 ratio = llmin<F32>( (rc.getWidth() / t_width), (rc.getHeight() / t_height) ); + + t_width *= ratio; + t_height *= ratio; + + rc.setCenterAndSize(rc.getCenterX(), rc.getCenterY(), llfloor(t_width), llfloor(t_height)); + mSnapshotCtrl->setShape(rc); + + mSnapshotStreched = true; +} + +LLRect LLPanelClassifiedInfo::getDefaultSnapshotRect() +{ + // Using scroll container makes getting default rect a hard task + // because rect in postBuild() and in first reshape() is not the same. + // Using snapshot_panel makes it easier to reshape snapshot. + return getChild<LLUICtrl>("snapshot_panel")->getLocalRect(); +} + +void LLPanelClassifiedInfo::scrollToTop() +{ + LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll"); + if (scrollContainer) + scrollContainer->goToTop(); +} + void LLPanelClassifiedInfo::onMapClick() { LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); @@ -1388,6 +1550,7 @@ void LLPanelClassifiedInfo::onTeleportClick() void LLPanelClassifiedInfo::onExit() { LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler } ////////////////////////////////////////////////////////////////////////// @@ -1401,6 +1564,7 @@ LLPanelClassifiedEdit::LLPanelClassifiedEdit() : LLPanelClassifiedInfo() , mIsNew(false) , mCanClose(false) + , mPublishFloater(NULL) { } @@ -1452,6 +1616,8 @@ BOOL LLPanelClassifiedEdit::postBuild() childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this)); childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this)); + mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this)); + return TRUE; } @@ -1461,6 +1627,8 @@ void LLPanelClassifiedEdit::onOpen(const LLSD& key) mIsNew = classified_id.isNull(); + scrollToTop(); + if(mIsNew) { setAvatarId(gAgent.getID()); @@ -1506,6 +1674,9 @@ void LLPanelClassifiedEdit::onOpen(const LLSD& key) enableEditing(false); } + std::string save_btn_label = isNew() ? getString("publish_label") : getString("save_label"); + childSetLabelArg("save_changes_btn", "[LABEL]", save_btn_label); + resetDirty(); setInfoLoaded(false); } @@ -1574,12 +1745,12 @@ void LLPanelClassifiedEdit::resetDirty() getChild<LLUICtrl>("price_for_listing")->resetDirty(); } -void LLPanelClassifiedEdit::setSaveCallback(const commit_callback_t& cb) +void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb) { - getChild<LLButton>("save_changes_btn")->setClickedCallback(cb); + mSaveButtonClickedSignal.connect(cb); } -void LLPanelClassifiedEdit::setCancelCallback(const commit_callback_t& cb) +void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb) { getChild<LLButton>("cancel_btn")->setClickedCallback(cb); } @@ -1599,6 +1770,22 @@ bool LLPanelClassifiedEdit::canClose() return mCanClose; } +void LLPanelClassifiedEdit::draw() +{ + LLPanel::draw(); + + // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback + // does not trigger callbacks when user navigates through images. + stretchSnapshot(); +} + +void LLPanelClassifiedEdit::stretchSnapshot() +{ + LLPanelClassifiedInfo::stretchSnapshot(); + + getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect()); +} + void LLPanelClassifiedEdit::sendUpdate() { LLAvatarClassifiedInfo c_data; @@ -1686,6 +1873,11 @@ S32 LLPanelClassifiedEdit::getPriceForListing() return childGetValue("price_for_listing").asInteger(); } +void LLPanelClassifiedEdit::setPriceForListing(S32 price) +{ + childSetValue("price_for_listing", price); +} + void LLPanelClassifiedEdit::onSetLocationClick() { setPosGlobal(gAgent.getPositionGlobal()); @@ -1729,9 +1921,45 @@ void LLPanelClassifiedEdit::onSaveClick() } } + if(isNew()) + { + mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>( + "publish_classified", LLSD()); + + if(!mPublishFloater) + { + mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>( + "publish_classified", LLSD()); + + mPublishFloater->setPublishClickedCallback(boost::bind + (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this)); + } + + // set spinner value before it has focus or value wont be set + mPublishFloater->setPrice(getPriceForListing()); + mPublishFloater->openFloater(mPublishFloater->getKey()); + mPublishFloater->center(); + } + else + { + doSave(); + } +} + +void LLPanelClassifiedEdit::doSave() +{ mCanClose = true; sendUpdate(); resetDirty(); + + mSaveButtonClickedSignal(this, LLSD()); +} + +void LLPanelClassifiedEdit::onPublishFloaterPublishClicked() +{ + setPriceForListing(mPublishFloater->getPrice()); + + doSave(); } std::string LLPanelClassifiedEdit::getLocationNotice() @@ -1778,4 +2006,52 @@ void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) ctrl->setVisible(FALSE); } +void LLPanelClassifiedEdit::onTextureSelected() +{ + setSnapshotId(mSnapshotCtrl->getValue().asUUID()); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key) + : LLFloater(key) +{ +} + +LLPublishClassifiedFloater::~LLPublishClassifiedFloater() +{ +} + +BOOL LLPublishClassifiedFloater::postBuild() +{ + LLFloater::postBuild(); + + childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false)); + childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false)); + + return TRUE; +} + +void LLPublishClassifiedFloater::setPrice(S32 price) +{ + childSetValue("price_for_listing", price); +} + +S32 LLPublishClassifiedFloater::getPrice() +{ + return childGetValue("price_for_listing").asInteger(); +} + +void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb) +{ + getChild<LLButton>("publish_btn")->setClickedCallback(cb); +} + +void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb) +{ + getChild<LLButton>("cancel_btn")->setClickedCallback(cb); +} + //EOF |