diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 74f11b3be0760a642ffb64533afa896136eb54f5..05f4e361bfa33f6c1693c1895e543454111f4e6a 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -317,6 +317,7 @@ set(viewer_SOURCE_FILES llfloatertopobjects.cpp llfloatertos.cpp llfloatertoybox.cpp + llfloatertransactionlog.cpp llfloatertranslationsettings.cpp llfloatertwitter.cpp llfloateruipreview.cpp @@ -948,6 +949,7 @@ set(viewer_HEADER_FILES llfloatertopobjects.h llfloatertos.h llfloatertoybox.h + llfloatertransactionlog.h llfloatertranslationsettings.h llfloatertwitter.h llfloateruipreview.h diff --git a/indra/newview/llfloatertransactionlog.cpp b/indra/newview/llfloatertransactionlog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..edd0db44ff517664e80a5bade4125a29048131c0 --- /dev/null +++ b/indra/newview/llfloatertransactionlog.cpp @@ -0,0 +1,103 @@ +/* + * @file llfloatertransactionlog.h + * @brief Transaction log floater + * + * (C) 2014 Cinder Roxley @ Second Life <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloatertransactionlog.h" + +#include "llavataractions.h" +#include "llavatarnamecache.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lltextbase.h" + +LLFloaterTransactionLog::LLFloaterTransactionLog(const LLSD& key) +: LLFloater(key) +, mList(nullptr) +, mTotalText(nullptr) +, mTotal(0) +, mAvatarNameCacheConnection() +{ + mCommitCallbackRegistrar.add("TL.Reset", boost::bind(&LLFloaterTransactionLog::reset, this)); +} + +LLFloaterTransactionLog::~LLFloaterTransactionLog() +{ + if (mAvatarNameCacheConnection.connected()) + mAvatarNameCacheConnection.disconnect(); +} + +BOOL LLFloaterTransactionLog::postBuild() +{ + mList = getChild<LLScrollListCtrl>("transaction_list"); + mList->setDoubleClickCallback(boost::bind(&LLFloaterTransactionLog::onDoubleClick, this)); + mTotalText = getChild<LLTextBase>("total"); + return TRUE; +} + +void LLFloaterTransactionLog::addTransaction(const LLDate& date, const LLUUID& sender, S32 amount) +{ + // drop it + if (!getVisible()) return; + + LLStringUtil::format_map_t args; + args["TOTAL"] = std::to_string(mTotal += amount); + mTotalText->setValue(getString("total_fmt", args)); + + LLSD row; + row["value"] = sender; + row["column"][0]["column"] = "time"; + row["column"][0]["value"] = date.toHTTPDateString(LLStringExplicit("%H:%M:%S"));; + row["column"][2]["column"] = "amount"; + row["column"][2]["value"] = llformat("L$%d", amount); + row["column"][2]["halign"] = LLFontGL::RIGHT; + + mAvatarNameCacheConnection = LLAvatarNameCache::get(sender, boost::bind(&LLFloaterTransactionLog::onAvatarNameCache, this, _1, _2, row)); +} + +void LLFloaterTransactionLog::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLSD& row) +{ + row["column"][1]["column"] = "name"; + row["column"][1]["value"] = av_name.getDisplayName(); + mList->addElement(row); +} + +void LLFloaterTransactionLog::onDoubleClick() +{ + const LLUUID& id = mList->getFirstSelected()->getValue().asUUID(); + LLAvatarActions::showProfile(id); +} + +void LLFloaterTransactionLog::reset() +{ + mList->deleteAllItems(); + mTotal = 0; + LLStringUtil::format_map_t args; + args["TOTAL"] = std::to_string(mTotal); + mTotalText->setValue(getString("total_fmt", args)); +} diff --git a/indra/newview/llfloatertransactionlog.h b/indra/newview/llfloatertransactionlog.h new file mode 100644 index 0000000000000000000000000000000000000000..ff47afe01d79e2da5b1097392ca8ffffc1a50a63 --- /dev/null +++ b/indra/newview/llfloatertransactionlog.h @@ -0,0 +1,59 @@ +/* + * @file llfloatertransactionlog.h + * @brief Transaction log floater + * + * (C) 2014 Cinder Roxley @ Second Life <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LL_FLOATERTRANSACTIONLOG_H +#define LL_FLOATERTRANSACTIONLOG_H + +#include "llfloater.h" + +class LLAvatarName; +class LLScrollListCtrl; +class LLTextBase; + +class LLFloaterTransactionLog : public LLFloater +{ +public: + LLFloaterTransactionLog(const LLSD& key); + BOOL postBuild(); + void addTransaction(const LLDate& date, const LLUUID& sender, S32 amount); + +private: + ~LLFloaterTransactionLog(); + void reset(); + void onDoubleClick(); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLSD& row); + + LLScrollListCtrl* mList; + LLTextBase* mTotalText; + S32 mTotal; + + boost::signals2::connection mAvatarNameCacheConnection; +}; + +#endif // LL_FLOATERTRANSACTIONLOG_H diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index f7964178e1baab5d033ba0ff06cb7c6b2c4cffcd..bf17d6722a0fade6aa1b9cc48765d4843feb45af 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -250,7 +250,8 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mTrackedStatus(LLTracker::TRACKING_NOTHING), mListFriendCombo(NULL), mListLandmarkCombo(NULL), - mListSearchResults(NULL) + mListSearchResults(NULL), + mPanel(nullptr) { gFloaterWorldMap = this; diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 813d2081ce46811333d8ee4e22de58d66e579b9f..87e8a23144b011fa6c650ff40f5c5664f13ffef8 100755 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -50,7 +50,7 @@ // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a // bit from there to give some pad. -const S32 MAX_ITEMS = 42; +const size_t MAX_ITEMS = 50; class LLGiveable : public LLInventoryCollectFunctor { @@ -248,9 +248,9 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, items, LLInventoryModel::EXCLUDE_TRASH, giveable); - S32 count = cats.size(); + size_t count = cats.size(); bool complete = true; - for(S32 i = 0; i < count; ++i) + for(size_t i = 0; i < count; ++i) { if (!gInventory.isCategoryComplete(cats.at(i)->getUUID())) { @@ -447,8 +447,8 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons items, LLInventoryModel::EXCLUDE_TRASH, remove); - S32 count = items.size(); - for(S32 i = 0; i < count; ++i) + size_t count = items.size(); + for(size_t i = 0; i < count; ++i) { gInventory.deleteObject(items.at(i)->getUUID()); } @@ -504,7 +504,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < // MTUBYTES or 18 * count < 1200 => count < 1200/18 => // 66. I've cut it down a bit from there to give some pad. - S32 count = items.size() + cats.size(); + size_t count = items.size() + cats.size(); if (count > MAX_ITEMS) { LLNotificationsUtil::add("TooManyItems"); @@ -521,7 +521,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, LLAgentUI::buildFullname(name); LLUUID transaction_id; transaction_id.generate(); - S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1); + size_t bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1); U8* bucket = new U8[bucket_size]; U8* pos = bucket; U8 type = (U8)cat->getType(); @@ -529,7 +529,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, pos += sizeof(U8); memcpy(pos, &(cat->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ pos += UUID_BYTES; - S32 i; + size_t i; count = cats.size(); for(i = 0; i < count; ++i) { diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index f36960c5f4aae7fefcbd654940d063219905f1dc..369203410a85b8226109b289dde0c2fa89558783 100755 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -59,7 +59,7 @@ #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/local_time_adjustor.hpp> -const S32 LOG_RECALL_SIZE = 2048; +const size_t LOG_RECALL_SIZE = 2048; const std::string LL_IM_TIME("time"); const std::string LL_IM_TEXT("message"); @@ -553,7 +553,7 @@ std::string LLLogChat::oldLogFileName(std::string filename) } // static -void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions) +void LLLogChat::findTranscriptFiles(const std::string& pattern, std::vector<std::string>& list_of_transcriptions) { // get Users log directory std::string dirname = gDirUtilp->getPerAccountChatLogsDir(); @@ -570,7 +570,7 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string LLFILE * filep = LLFile::fopen(fullname, "rb"); if (NULL != filep) { - if(makeLogFileName("chat")== fullname) + if(makeLogFileName("chat") == fullname) { //Add Nearby chat history to the list of transcriptions list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); @@ -580,7 +580,7 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string char buffer[LOG_RECALL_SIZE]; fseek(filep, 0, SEEK_END); // seek to end of file - S32 bytes_to_read = ftell(filep); // get current file pointer + size_t bytes_to_read = ftell(filep); // get current file pointer fseek(filep, 0, SEEK_SET); // seek back to beginning of file // limit the number characters to read from file @@ -749,42 +749,22 @@ void LLLogChat::deleteTranscripts() // static bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) { - std::vector<std::string> list_of_transcriptions; - LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); - - if (list_of_transcriptions.size() > 0) + if (is_group) + { + std::string file_name; + gCacheName->getGroupName(avatar_id, file_name); + file_name = makeLogFileName(file_name); + return gDirUtilp->fileExists(file_name); + } + else { LLAvatarName avatar_name; LLAvatarNameCache::get(avatar_id, &avatar_name); - std::string avatar_user_name = avatar_name.getAccountName(); - if(!is_group) - { - std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); - BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - { - if (std::string::npos != transcript_file_name.find(avatar_user_name)) - { - return true; - } - } - } - else - { - std::string file_name; - gCacheName->getGroupName(avatar_id, file_name); - file_name = makeLogFileName(file_name); - BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - { - if (transcript_file_name == file_name) - { - return true; - } - } - } - + std::string file_name = avatar_name.getAccountName(); + std::replace(file_name.begin(), file_name.end(), '.', '_'); + file_name = makeLogFileName(file_name); + return gDirUtilp->fileExists(file_name); } - - return false; } bool LLLogChat::isNearbyTranscriptExist() diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index ca597599dddcb729f3b3aeee43150b7efbf856c9..e672353826694daa3c94c78659e2c17cf22c6840 100755 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -100,7 +100,7 @@ public: const std::string& from, const LLUUID& from_id, const std::string& line); - static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions); + static void findTranscriptFiles(const std::string& pattern, std::vector<std::string>& list_of_transcriptions); static void getListOfTranscriptFiles(std::vector<std::string>& list); static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 64844c966f1129fec942d0e5bda37f81c5105fd8..bfc0fe027d0e7122d0f64ad92d0e851e169ff380 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -125,6 +125,7 @@ #include "llfloatertopobjects.h" #include "llfloatertos.h" #include "llfloatertoybox.h" +#include "llfloatertransactionlog.h" #include "llfloatertranslationsettings.h" #include "llfloatertwitter.h" #include "llfloateruipreview.h" @@ -305,6 +306,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", &LLFloaterReg::build<LLFloater>); LLFloaterReg::add("top_objects", "floater_top_objects.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTopObjects>); LLFloaterReg::add("toybox", "floater_toybox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterToybox>); + LLFloaterReg::add("transaction_log", "floater_transaction_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTransactionLog>); LLFloaterReg::add("quick_settings", "floater_quick_settings.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<LLFloater>); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d086d4561f084c96b9534fe2131b8405da4065b6..ea77d4d4dfda147364d6740650743ee6e5a56aaf 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -65,6 +65,7 @@ #include "llfloaterprogressview.h" #include "llfloatersidepanelcontainer.h" #include "llfloatersnapshot.h" +#include "llfloatertransactionlog.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llimview.h" @@ -5703,6 +5704,9 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) // make notification loggable payload["from_id"] = source_id; notification = "PaymentReceived"; + + LLFloaterTransactionLog* floater = LLFloaterReg::findTypedInstance<LLFloaterTransactionLog>("transaction_log"); + if (floater) floater->addTransaction(LLDate::now(), source_id, amount); } // Despite using SLURLs, wait until the name is available before diff --git a/indra/newview/skins/default/xui/en/floater_transaction_log.xml b/indra/newview/skins/default/xui/en/floater_transaction_log.xml new file mode 100644 index 0000000000000000000000000000000000000000..321965c7cbdb9c356f4dcff06ba39bde6fb988c0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_transaction_log.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_close="true" + can_drag_on_left="false" + can_minimize="true" + can_resize="true" + height="300" + width="300" + name="floater_transaction_log" + title="Transaction Log" + single_instance="true" + save_rect="true"> + <floater.string + name="total_fmt"> +Total: L$[TOTAL] + </floater.string> + <scroll_list + draw_heading="true" + follows="left|top|bottom|right" + name="transaction_list" + background_visible="true" + fg_unselected_color="ScrollSelectedFGColor" + fg_selected_color="ScrollSelectedFGColor" + column_padding="0" + top="0" + left="4" + right="-4" + bottom="-26"> + <column name="time" width="50" label="Time" /> + <column name="name" dynamicwidth="true" label="Name" /> + <column name="amount" width="70" label="Amount" /> + </scroll_list> + <text + type="string" + length="1" + follows="bottom|right" + font="SansSerif" + height="20" + layout="topleft" + name="total" + top_pad="2" + width="89" + left="129" + halign="right" + value="Total: L$0" /> + <button + label="Reset" + follows="bottom|right" + height="20" + left_pad="3" + name="btn_reset" + width="75"> + <button.commit_callback + function="TL.Reset" /> + </button> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 404c548a5d75c4518b89f0b730b26834a518f40c..88f9fd514736c035f245fab49f6cbdb4974999e4 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -180,6 +180,16 @@ <menu_item_call.on_click function="BuyCurrency" /> </menu_item_call> + <menu_item_check + label="Transaction Log..." + name="transaction_log"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="transaction_log" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="transaction_log" /> + </menu_item_check> <menu_item_call label="Merchant Outbox..." name="MerchantOutbox"> @@ -2191,17 +2201,17 @@ label="Consoles" name="Consoles" tear_off="true"> - <menu_item_check - label="Region Debug Console" - name="Region Debug Console" - shortcut="control|shift|`" - use_mac_ctrl="true"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="region_debug_console" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="region_debug_console" /> + <menu_item_check + label="Region Debug Console" + name="Region Debug Console" + shortcut="control|shift|`" + use_mac_ctrl="true"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="region_debug_console" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="region_debug_console" /> </menu_item_check> <menu_item_check label="Texture Console" diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index 83f28a0ea3db8bf23ec53e8358a59239b07df0b4..c1bea89aeee63285cb64431c2f8c33836833ddf6 100755 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -75,7 +75,7 @@ name="last_interaction" text_color="LtGray_50" value="0s" - width="35" /> + width="38" /> <icon height="16" follows="right"